refactor: 重构权限服务类

This commit is contained in:
Ying
2023-07-03 10:08:34 +08:00
parent 8becf0ef36
commit 4e377def8d
42 changed files with 1679 additions and 1524 deletions

View File

@@ -10,13 +10,12 @@
// +----------------------------------------------------------------------
namespace app;
use app\admin\library\Auth;
use app\admin\enums\AdminEnum;
use app\admin\service\AuthService;
use support\Log;
use support\Response;
use think\helper\Str;
define('AdminSession', 'AdminLogin');
class AdminController extends BaseController
{
/**
@@ -47,7 +46,7 @@ class AdminController extends BaseController
* 权限验证类
* @var object
*/
public object $auth;
public object $authService;
/**
* 当前表字段
@@ -109,7 +108,7 @@ class AdminController extends BaseController
public function __construct()
{
parent::__construct();
$this->auth = Auth::instance();
$this->authService = AuthService::instance();
}
/**
@@ -195,7 +194,7 @@ class AdminController extends BaseController
$data = $this->model->find($id);
// 限制数据调用
if (!$this->auth->SuperAdmin() && $this->dataLimit
if (!$this->authService->SuperAdmin() && $this->dataLimit
&& in_array($this->dataLimitField, $this->model->getFields())) {
if ($data[$this->dataLimitField] != get_admin_id()) {
return $this->error('没有权限');
@@ -236,7 +235,7 @@ class AdminController extends BaseController
try {
$list = $this->model->whereIn('id', $id)->select();
foreach ($list as $item) {
if (!$this->auth->SuperAdmin() && $this->dataLimit
if (!$this->authService->SuperAdmin() && $this->dataLimit
&& in_array($this->dataLimitField, $this->model->getFields())) {
if ($item[$this->dataLimitField] != get_admin_id()) {
continue;
@@ -266,7 +265,7 @@ class AdminController extends BaseController
if (request()->isAjax()) {
$where[] = ['id', '=', input('id')];
if (!$this->auth->SuperAdmin() && $this->dataLimit
if (!$this->authService->SuperAdmin() && $this->dataLimit
&& in_array($this->dataLimitField, $this->model->getFields())) {
$where[] = [$this->dataLimitField, '=', get_admin_id()];
}
@@ -485,7 +484,7 @@ class AdminController extends BaseController
}
// 限制个人数据权限
$superAdmin = $this->auth->SuperAdmin();
$superAdmin = $this->authService->SuperAdmin();
if (!$superAdmin && $this->dataLimit) {
if (in_array($this->dataLimitField, $this->tableFields)) {
$where[] = [$this->dataLimitField, '=', get_admin_id()];
@@ -533,7 +532,7 @@ class AdminController extends BaseController
*/
public function logout(): Response
{
request()->session()->set(AdminSession, null);
request()->session()->set(AdminEnum::ADMIN_SESSION, null);
return $this->success('退出成功!', '/');
}

View File

@@ -308,7 +308,7 @@ class Index extends AdminController
$columns = ['用户注册' => 'create_time', '用户登录' => 'login_time', '邀请注册' => 'invite_id'];
foreach ($columns as $index => $field) {
$time = str_replace('invite_id', 'create_time', $field);
$resultList[$index] = \app\common\model\system\User::where($time, 'between time', [$dateBefore, $dateAfter])
$resultList[$index] = User::where($time, 'between time', [$dateBefore, $dateAfter])
->when($condition, function ($query) use ($condition, $time, $field) {
$query->field("FROM_UNIXTIME($time, '$condition') as day,count(*) as count");
if ($field == 'invite_id') {

View File

@@ -2,12 +2,11 @@
namespace app\admin\controller;
use app\admin\service\LoginService;
use app\common\exception\OperateException;
use support\Response;
use Webman\Event\Event;
use app\AdminController;
use app\common\model\system\Admin;
use app\common\model\system\AdminLog;
use Psr\SimpleCache\InvalidArgumentException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
@@ -29,16 +28,16 @@ class Login extends AdminController
/**
* 登录函数
* @return Response
* @throws InvalidArgumentException
* @throws OperateException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function index(): \support\Response
public function index(): Response
{
// 禁止重复访问
$session = get_admin_info();
if (isset($session['id'])) {
$adminInfo = get_admin_info();
if (isset($adminInfo['id'])) {
return $this->redirect('/admin/index');
}
@@ -46,103 +45,17 @@ class Login extends AdminController
$user = request()->post('name');
$pwd = request()->post('pwd');
$captcha = request()->post('captcha');
if ((isset($session['count']) && $session['count'] >= 5)
&& (isset($session['time']) && $session['time'] >= strtotime('- 5 minutes'))) {
return $this->displayResponse('错误次数过多,请稍后再试!');
}
validate(\app\common\validate\system\Admin::class)->scene('login')->check([
'name' => $user,
'pwd' => $pwd,
]);
// 验证码
if (isset($session['isCaptcha'])) {
if (!$captcha || !$this->captchaCheck($captcha)) {
return $this->displayResponse('验证码错误!');
}
}
// 验证表单令牌
if (!request()->checkToken('__token__', request()->all())) {
return $this->displayResponse('表单令牌错误!', ['token' => token()]);
} else {
$result = Admin::checkLogin($user, $pwd);
if (empty($result)) {
$session['time'] = time();
$session['isCaptcha'] = true;
$session['count'] = isset($session['count']) ? $session['count'] + 1 : 1;
request()->session()->set(AdminSession, $session);
// 执行登录失败事件
Event::emit('adminLoginError', request()->all());
return $this->displayResponse('用户名或密码错误!', ['token' => token()]);
}
if ($result['status'] !== 1) {
return $this->displayResponse('账号已被禁用!');
}
$result->login_ip = request()->getRealIp();
$result->login_time = time();
$result->count = $result->count + 1;
try {
$result->save();
$session = array_merge($session, $result->toArray());
request()->session()->set(AdminSession, $session);
} catch (\Throwable $th) {
return $this->error($th->getMessage());
}
Event::emit('adminLoginSuccess', $result->toArray());
return $this->displayResponse('登录成功!', [] , $this->JumpUrl);
}
LoginService::accountLogin($user, $pwd, $captcha, $adminInfo);
return $this->success('登录成功!', $this->JumpUrl);
}
return view('login/index', [
'captcha' => $session['isCaptcha'] ?? false,
]);
}
/**
* 退出登录
* @param string $msg
* @param array $data
* @param string $url
* @return Response
*/
private function displayResponse(string $msg = 'error', array $data = [], string $url = ''): Response
{
$this->adminLoginLog($msg, $url ? 1 : 0);
return empty($url) ? $this->error($msg, $url, $data) : $this->success($msg, $url);
}
/**
* 写入登录日志
* @param string $error
* @param int $status
*/
private function adminLoginLog(string $error, int $status = 0)
{
$name = \request()->input('name');
$userAgent = \request()->header('user-agent');
$nickname = $this->model->where('name', $name)->value('nickname');
if (preg_match('/.*?\((.*?)\).*?/', $userAgent, $matches)) {
$user_os = substr($matches[1], 0, strpos($matches[1], ';'));
} else {
$user_os = '未知';
}
$user_browser = preg_replace('/[^(]+\((.*?)[^)]+\) .*?/', '$1', $userAgent);
$data = [
'user_ip' => request()->getRealIp(),
'user_agent' => $userAgent,
'user_os' => $user_os,
'user_browser' => $user_browser,
'name' => $name,
'nickname' => $nickname ?? '未知',
'error' => $error,
'status' => $status,
];
AdminLog::create($data);
}
}

View File

@@ -13,7 +13,10 @@ declare(strict_types=1);
namespace app\admin\controller\system;
use app\admin\enums\AdminEnum;
use app\admin\service\AdminService;
use app\AdminController;
use app\common\exception\OperateException;
use app\common\model\system\AdminNotice;
use app\common\model\system\Jobs;
use app\common\model\system\Department;
@@ -63,64 +66,20 @@ class Admin extends AdminController
/**
* 获取资源列表
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function index()
public function index(): Response
{
$this->jobs = Jobs::select()->toArray();
$this->group = AdminGroupModel::select()->toArray();
$this->department = Department::getListTree();
// 判断isAjax
if (request()->isAjax()) {
// 获取数据
$post = \request()->all();
$page = (int)request()->input('page') ?? 1;
$limit = (int)request()->input('limit') ?? 10;
$status = !empty($post['status']) ? $post['status'] - 1 : 1;
// 生成查询条件
$where = array();
if (!empty($post['name'])) {
$where[] = ['name', 'like', '%' . $post['name'] . '%'];
}
if (!empty($post['dep'])) {
$where[] = ['department_id', 'find in set', $post['dep']];
}
if (!empty($post['group_id'])) {
$where[] = ['group_id', 'find in set', $post['group_id']];
}
// 生成查询数据
$where[] = ['status', '=', $status];
$count = $this->model->where($where)->count();
$page = ($count <= $limit) ? 1 : $page;
$list = $this->model->where($where)->order("id asc")->withoutField('pwd')->limit((int)$limit)->page((int)$page)->select()->toArray();
// 循环处理数据
foreach ($list as $key => $value) {
$groupIDs = explode(',', $value['group_id']);
foreach ($groupIDs as $field => $id) {
// 查找组
$result = list_search($this->group, ['id' => $id]);
if (!empty($result)) {
$list[$key]['group'][$field] = $result;
}
}
if (!empty($list[$key]['group'])) {
$list[$key]['group'] = list_sort_by($list[$key]['group'], 'id');
}
$authNodes = $this->auth->getRulesNode($value['id']);
$list[$key][AUTH_RULES] = $authNodes[$this->auth->authPrivate];
$authNodes = $this->auth->getRulesNode($value['id'], AUTH_CATE);
$list[$key][AUTH_CATE] = $authNodes[$this->auth->authPrivate];
}
$params = request()->all();
list('count' => $count, 'list' => $list) = AdminService::dataList($params);
return $this->success('查询成功', null, $list, $count);
}
@@ -134,39 +93,15 @@ class Admin extends AdminController
/**
* 添加管理员
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
* @throws OperateException
*/
public function add(): \support\Response
public function add(): Response
{
if (request()->isPost()) {
// 验证数据
$post = request()->post();
$post = request_validate_rules($post, get_class($this->model));
if (!is_array($post)) {
return $this->error($post);
}
$where[] = ['name', '=', $post['name']];
$where[] = ['email', '=', $post['email']];
if ($this->model->whereOr($where)->find()) {
return $this->error('该用户名或邮箱已被注册!');
}
// 管理员加密
$post['pwd'] = encryptPwd($post['pwd']);
$post['create_ip'] = request()->getRealIp();
$data = $this->model->create($post);
if (!is_empty($data['id'])) {
$access['admin_id'] = $data['id'];
$access['group_id'] = $data['group_id'];
AdminAccessModel::insert($access);
return $this->success('添加管理员成功!');
} else {
return $this->error('添加管理员失败!');
}
validate(\app\common\validate\system\Admin::class)->scene('add')->check($post);
AdminService::add($post);
return $this->success('添加管理员成功');
}
// 获取用户组
@@ -175,117 +110,67 @@ class Admin extends AdminController
/**
* 更新管理员
* @return Response
* @throws OperateException
*/
public function edit()
public function edit(): Response
{
if (request()->isPost()) {
$id = request()->input('id');
if (!empty($id) && is_numeric($id)) {
// 验证数据
$post = request()->all();
$retError = request_validate_rules($post, get_class($this->model), 'edit');
if (!is_array($retError)) {
return $this->error($retError);
}
if (isset($post['pwd']) && !empty($post['pwd'])) {
$post['pwd'] = encryptPwd($post['pwd']);
} else {
// 清空避免被覆盖
unset($post['pwd']);
}
if ($this->model->update($post)) {
$access['group_id'] = $post['group_id'];
AdminAccessModel::where('admin_id', $id)->update($access);
return $this->success('更新管理员成功!');
}
}
validate(\app\common\validate\system\Admin::class)->scene('edit')->check($post);
AdminService::edit($post);
return $this->success('更新管理员成功');
}
return $this->error('更新管理员失败');
}
/**
* 获取用户权限树
* @access public
* getAdminRules
*/
public function getPermissions()
{
return $this->authService->getPermissionsMenu();
}
/**
* 获取节点数据
* @access public
*/
public function getRuleCateTree()
{
$type = input('type', AdminEnum::ADMIN_AUTH_RULES);
return $this->authService->getRuleCatesTree($type, $this->authService->authPrivate);
}
/**
* 编辑权限
* @access public
* @return Response
* @throws OperateException
*/
public function editRules(): Response
{
return $this->updateRuleCates();
$adminId = input('admin_id', 0);
AdminService::updateRulesNodes($adminId, AdminEnum::ADMIN_AUTH_RULES);
return $this->success('更新权限成功!');
}
/**
* 编辑栏目权限
* @access public
* @return Response
* @throws OperateException
*/
public function editCates(): Response
{
return $this->updateRuleCates(AUTH_CATE);
}
/**
* 更新权限函数
* @access protected
* @param string $type
* @return Response
*/
protected function updateRuleCates(string $type = AUTH_RULES): Response
{
$admin_id = input('admin_id');
$rules = request()->post($type) ?? [];
$access = $this->auth->getRulesNode($admin_id, $type);
$rules = array_diff($rules, $access[$this->auth->authGroup]);
// 权限验证
if (!$this->auth->checkRuleOrCateNodes($rules, $type, $this->auth->authPrivate)) {
return $this->error('没有权限!');
}
// 获取个人节点
$differ = array_diff($access[$this->auth->authPrivate], $access[$this->auth->authGroup]);
$current = [];
if (!$this->auth->superAdmin()) {
$current = $this->auth->getRulesNode();
$current = array_diff($differ, $current[$this->auth->authPrivate]);
}
$rules = array_unique(array_merge($rules, $current));
$AdminAccessModel = new AdminAccessModel();
$data = ["$type" => implode(',', $rules)];
if ($AdminAccessModel->update($data, ['admin_id' => $admin_id])) {
$adminId = input('admin_id', 0);
AdminService::updateRulesNodes($adminId, AdminEnum::ADMIN_AUTH_CATES);
return $this->success('更新权限成功!');
}
return $this->error('更新权限失败!');
}
/**
* 获取用户权限树
* getAdminRules
* @return mixed
*/
public function getPermissions(): mixed
{
$list = [];
if (\request()->isAjax()) {
$type = input('type', 'menu');
$group = input('group', 0);
if ($type == 'menu') {
return $this->auth->getRulesMenu();
} else {
try {
$list = $this->auth->getRuleCatesTree($type, $group ? $this->auth->authGroup : $this->auth->authPrivate);
} catch (\Exception $e) {
return $this->error($e->getMessage());
}
return $list;
}
}
return $list;
}
/**
* 模版页面
* @return Response
@@ -295,157 +180,6 @@ class Admin extends AdminController
return view('/system/admin/theme');
}
/**
* 消息模板
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function bells(): Response
{
$list = [];
$count = [];
$array = ['notice', 'message', 'todo'];
$type = input('type', 'notice');
if (\request()->isAjax()) {
$page = input('page', 1);
$limit = input('limit', 3);
// 计算最大页码
$data = AdminNotice::with(['admin'])->where(['type' => $type, 'admin_id' => get_admin_id()])
->order('id', 'desc')->paginate(['list_rows' => $limit, 'page' => $page])->toArray();
return $this->success('获取成功', '', $data);
}
foreach ($array as $item) {
$where = [
['type', '=', $item],
['admin_id', '=', get_admin_id()]
];
$count[$item] = AdminNotice::where($where)->where('status', 0)->count();
$list[$item] = AdminNotice::with(['admin'])->withoutField('content')->where($where)->limit(3)->order('id desc')->select()->toArray();
}
return view('/system/admin/bells', [
'list' => $list,
'count' => $count
]);
}
/**
* 阅读消息
* @return response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function readNotice(): Response
{
$id = input('id', 0);
$type = input('type', 'notice');
if (!empty($id)) {
$detail = AdminNotice::with(['admin'])->where(['id' => $id, 'admin_id' => get_admin_id()])->find();
if (empty($detail)) {
return $this->error('404 Not Found');
}
// 默认已读
if ($type !== 'todo') {
$detail->status = 1;
$detail->save();
}
}
return $this->view('/system/admin/' . $type, [
'detail' => $detail ?? []
]);
}
/**
* 更新即时消息
* @return Response|void
*/
public function saveNotice()
{
if (\request()->post()) {
$post = request()->post();
$post['send_id'] = get_admin_id();
$post['type'] = 'message';
$post['send_ip'] = request()->getRealIp();
$post['create_time'] = time();
try {
AdminNotice::sendNotice($post, 'none');
} catch (\Exception $e) {
return $this->error('发送失败:' . $e->getMessage());
}
return $this->success('发送成功');
} else if (\request()->isAjax()) {
$id = input('id', 0);
$status = input('status', 1);
try {
if (empty($id)) {
throw new Exception('参数错误');
}
AdminNotice::where(['id' => $id, 'admin_id' => get_admin_id()])->update(['status' => $status]);
} catch (Exception $e) {
return $this->error('更新失败');
}
return $this->success('更新成功');
}
}
/**
* 清空消息
* @return Response|void
*/
public function clearNotice()
{
if (\request()->isAjax()) {
$type = input('type', 'notice');
$where = [
['type', '=', $type],
['status', '=', 1],
['admin_id', '=', get_admin_id()]
];
try {
AdminNotice::where($where)->delete();
} catch (Exception $e) {
return $this->error('清空失败');
}
return $this->success('清空成功');
}
}
/**
* 全部消息已读
* @return Response|void
*/
public function readAllNotice()
{
if (\request()->isAjax()) {
$type = input('type', 'notice');
$where = [
['type', '=', $type],
['admin_id', '=', get_admin_id()]
];
try {
AdminNotice::where($where)->update(['status' => 1]);
} catch (Exception $e) {
return $this->error('操作失败');
}
return $this->success('全部已读成功');
}
}
/**
* 个人中心
* @param Request $request
@@ -454,7 +188,7 @@ class Admin extends AdminController
* @throws DbException
* @throws ModelNotFoundException
*/
public function center(Request $request): \support\Response
public function center(Request $request): Response
{
if (request()->isPost()) {
$post = request()->post();
@@ -548,7 +282,7 @@ class Admin extends AdminController
* @throws DbException
* @throws ModelNotFoundException
*/
public function pwd(): \support\Response
public function pwd(): Response
{
if (request()->isPost()) {
@@ -576,10 +310,9 @@ class Admin extends AdminController
/**
* 语言配置
* @return mixed
* @throws \think\Exception
* @return Response
*/
public function language()
public function language(): Response
{
$language = input('l');
$env = base_path() . '/.env';
@@ -590,13 +323,14 @@ class Admin extends AdminController
if (write_file($env, $content)) {
return json(['success']);
}
return json(['error']);
}
/**
* 更改状态
* @return \support\Response
* @return Response
*/
public function status()
public function status(): Response
{
$id = input('id');
if ($id == 1) {
@@ -613,14 +347,14 @@ class Admin extends AdminController
/**
* 删除管理员
* @return mixed
* @throws \think\db\exception\DbException
* @return Response
* @throws DbException
*/
public function del()
public function del(): Response
{
$id = input('id');
!is_array($id) && ($id = array($id));
if (!empty($id) && is_array($id)) {
if (!empty($id)) {
// 过滤权限
if (in_array("1", $id)) {
@@ -641,21 +375,20 @@ class Admin extends AdminController
/**
* 清理系统缓存
* @return \support\Response
* @return Response
*/
public function clear(): \support\Response
public function clear(): Response
{
if (request()->isAjax()) {
$type = input('type');
try {
// 清理内容
if ($type == 'all' || $type == 'content') {
$session = session(AdminSession);
\support\Cache::clear();
request()->session()->set(AdminSession, $session);
$session = session(AdminEnum::ADMIN_SESSION);
Cache::clear();
request()->session()->set(AdminEnum::ADMIN_SESSION, $session);
}
// 清理模板

View File

@@ -11,8 +11,15 @@
// +----------------------------------------------------------------------
namespace app\admin\controller\system;
use app\admin\enums\AdminEnum;
use app\admin\service\AdminGroupService;
use app\AdminController;
use app\common\exception\OperateException;
use app\common\model\system\AdminGroup as AdminGroupModel;
use support\Response;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use Webman\Http\Request;
/**
@@ -31,40 +38,21 @@ class AdminGroup extends AdminController
/**
* 获取资源列表
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function index()
public function index(): Response
{
if (request()->isAjax()) {
$param = \request()->all();
$param['page'] = input('page');
$param['limit'] = input('limit');
// 查询条件
$where = array();
if (!empty($param['title'])) {
$where[] = ['title','like','%'.$param['title'].'%'];
}
if (!empty($param['alias'])) {
$where[] = ['alias','like','%'.$param['alias'].'%'];
}
if (!empty($param['content'])) {
$where[] = ['content','like','%'.$param['content'].'%'];
$params = \request()->all();
list($count, $list) = AdminGroupService::dataList($params);
return $this->success('查询成功', '/', $list, $count);
}
// 查询数据
$count = $this->model->where($where)->count();
$limit = is_empty($param['limit']) ? 10 : (int)$param['limit'];
$page = ($count <= $limit) ? 1 : $param['page'];
$list = $this->model->where($where)->order("id asc")->limit((int)$limit)->page((int)$page)->select()->toArray();
foreach ($list as $key => $value) {
$list[$key]['title'] = __($value['title']);
}
return $this->success('查询成功', null, $list, $count);
}
return view('/system/admin/group',['group'=>$this->model->getListGroup()]);
return view('/system/admin/group', [
'group' => $this->model->getListGroup()
]);
}
/**
@@ -73,19 +61,14 @@ class AdminGroup extends AdminController
public function add()
{
if (request()->isPost()) {
// 接收数据
$post = request()->post();
$post = request_validate_rules($post, get_class($this->model));
if (empty($post) || !is_array($post)) {
return $this->error($post);
}
if ($this->model->create($post)) {
validate(\app\common\validate\system\AdminGroup::class)->scene('add')->check($post);
AdminGroupService::add($post);
return $this->success('添加角色成功!');
}else {
}
return $this->error('添加角色失败!');
}
}
}
/**
* 编辑角色
@@ -94,91 +77,66 @@ class AdminGroup extends AdminController
{
if (request()->isPost()) {
$post = request()->post();
$post = request_validate_rules($post, get_class($this->model));
if (empty($post) || !is_array($post)) {
return $this->error($post);
}
if ($this->model->update($post)) {
validate(\app\common\validate\system\AdminGroup::class)->scene('edit')->check($post);
AdminGroupService::edit($post);
return $this->success('更新角色成功!');
}else {
return $this->error('更新角色失败');
}
return $this->error('更新角色失败!');
}
/**
* 权限函数接口
* @access public
*/
public function getRuleCateTree()
{
$type = input('type', AdminEnum::ADMIN_AUTH_RULES);
return $this->authService->getRuleCatesTree($type, $this->authService->authGroup);
}
/**
* 更新权限
* @return Response
* @throws OperateException
*/
public function editRules()
public function editRules(): Response
{
if (request()->isPost()) {
$id = input('id');
if (!is_empty($id) && is_numeric($id)) {
$rules = request()->post('rules') ?? [];
$array = [
'id'=>$id,
'rules'=>implode(',',$rules)
];
if (!$this->auth->checkRuleOrCateNodes($rules)) {
return $this->error('没有权限!');
}
if ($this->model->update($array)) {
$id = input('id', 0);
$post = request()->post();
$rules = input(AdminEnum::ADMIN_AUTH_RULES, []);
validate(\app\common\validate\system\AdminGroup::class)->scene('edit')->check($post);
AdminGroupService::editRules((int)$id, $rules);
return $this->success('更新权限成功!');
}
}
return $this->error('更新权限失败!');
}
}
/**
* 更新栏目
* @return Response
* @throws OperateException
*/
public function editCates()
public function editCates(): Response
{
if (request()->isPost()) {
$id = input('id');
if (!is_empty($id) && is_numeric($id)) {
$cates = request()->post('cates') ?? [];
$array = [
'id'=>$id,
'cates'=>implode(',',$cates)
];
if (!$this->auth->checkRuleOrCateNodes($cates,AUTH_CATE)) {
return $this->error('没有权限!');
}
if ($this->model->update($array)) {
return $this->success('更新栏目权限成功!');
}
}
return $this->error('更新栏目权限失败!');
}
$id = input('id', 0);
$cates = input(AdminEnum::ADMIN_AUTH_CATES, []);
$post = request()->post();
validate(\app\common\validate\system\AdminGroup::class)->scene('edit')->check($post);
AdminGroupService::editCates($id, $cates);
return $this->success('更新权限成功!');
}
/**
* 删除角色/用户组
*/
public function del()
public function del(): Response
{
$id = input('id');
if (!empty($id) && is_numeric($id)) {
$id = input('id', 0);
validate(\app\common\validate\system\AdminGroup::class)->scene('edit')->check(request()->all());
if ($id == 1) {
return $this->error('系统内置禁止删除!');
}
if ($this->model::destroy($id)) {
} else if ($this->model::destroy($id)) {
return $this->success('删除角色成功!');
}
}
return $this->error('删除角色失败,请检查您的参数!');
}

View File

@@ -11,8 +11,11 @@
// +----------------------------------------------------------------------
namespace app\admin\controller\system;
use app\admin\service\AdminRuleService;
use app\AdminController;
use app\common\model\system\AdminRules as AdminRuleModel;
use support\Response;
use think\db\exception\DbException;
use Webman\Http\Request;
/**
@@ -31,34 +34,14 @@ class AdminRules extends AdminController
/**
* 获取资源列表
*
* return Response
*/
public function index()
public function index(): Response
{
if (request()->isAjax()) {
// 查询参数
$where = array();
$post['title'] = input('title');
$post['router'] = input('router');
if (!empty($post['title'])) {
$where[] = ['title','like','%'.$post['title'].'%'];
}
if (!empty($post['router'])) {
$where[] = ['router','like','%'.$post['router'].'%'];
}
// 获取总数
$total = $this->model->where($where)->count();
$list = $this->model->where($where)->order('sort asc')->select()->toArray();
foreach ($list as $key => $value) {
$list[$key]['title'] = __($value['title']);
}
list($count, $list) = AdminRuleService::dataList(request()->all());
$rules = list_to_tree($list,'id','pid','children',0);
return $this->success('获取成功', '/',$rules, $total);
return $this->success('获取成功', '/',$rules, $count);
}
return view('/system/admin/rules');
@@ -66,46 +49,42 @@ class AdminRules extends AdminController
/**
* 添加节点数据
* @return Response
*/
public function add()
public function add(): Response
{
if (request()->isPost()) {
$post = \request()->post();
$post = request_validate_rules($post, get_class($this->model));
if (empty($post) || !is_array($post)) {
return $this->error($post);
}
validate(\app\common\validate\system\AdminRules::class . '.add')->check($post);
if ($this->model->create($post)) {
return $this->success('添加菜单成功!');
}else {
}
}
return $this->error('添加菜单失败!');
}
}
}
/**
* 编辑节点数据
* @return Response
*/
public function edit()
public function edit(): Response
{
if (request()->isPost()) {
$post = \request()->post();
$post = request_validate_rules($post, get_class($this->model));
if (empty($post) || !is_array($post)) {
return $this->error($post);
}
validate(\app\common\validate\system\AdminRules::class . '.edit')->check($post);
if ($this->model->update($post)) {
return $this->success('更新菜单成功!');
}else {
}
}
return $this->error('更新菜单失败');
}
}
}
/**
* 删除节点数据
* @return Response
* @throws DbException
*/
public function del()
public function del(): Response
{
$id = input('id');
if (!empty($id)) {

View File

@@ -63,17 +63,12 @@ class Company extends AdminController
/**
* 添加公司信息
* @return Response
*/
public function add ()
public function add(): Response
{
if (request()->isPost()) {
$post = request()->post();
$post = request_validate_rules($post,get_class($this->model));
if (empty($post) || !is_array($post)) {
$this->error($post);
}
if ($this->model->create($post)) {
return $this->success();
}
@@ -88,17 +83,16 @@ class Company extends AdminController
/**
* 编辑公司信息
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function edit()
public function edit(): Response
{
$id = input('id');
if (request()->isPost()) {
$post = request()->post();
$post = request_validate_rules($post,get_class($this->model));
if (empty($post) || !is_array($post)) {
$this->error($post);
}
if ($this->model->update($post)) {
return $this->success();
}
@@ -106,7 +100,9 @@ class Company extends AdminController
}
$data = $this->model->find($id);
return view('/system/company/add',['data'=> $data]);
return view('/system/company/add', [
'data' => $data
]);
}
}

View File

@@ -81,23 +81,20 @@ class Department extends AdminController
/**
* 添加部门数据
* @return Response
*/
public function add()
public function add(): Response
{
if (request()->isPost()) {
$post = request()->post();
$post = request_validate_rules($post, get_class($this->model));
if (empty($post) || !is_array($post)) {
return $this->error($post);
}
validate(\app\common\validate\system\Department::class.'.add')->check($post);
if ($this->model->create($post)) {
return $this->success('添加部门成功!');
}else {
}
}
return $this->error('添加部门失败!');
}
}
}
/**
* 编辑部门数据
@@ -106,25 +103,24 @@ class Department extends AdminController
{
if (request()->isPost()) {
$post = request()->post();
$post = request_validate_rules($post, get_class($this->model));
if (empty($post) || !is_array($post)) {
return $this->error($post);
}
validate(\app\common\validate\system\Department::class.'.edit')->check($post);
if ($this->model->update($post)) {
return $this->success('更新部门成功!');
}else {
}
}
return $this->error('更新部门失败');
}
}
}
/**
* 删除部门数据
* @return Response
* @throws DbException
*/
public function del()
public function del(): Response
{
$id = input('id');
if (!empty($id) && is_numeric($id)) {
if ($id > 0) {
// 查询子部门
if ($this->model->where('pid',$id)->count()) {
return $this->error('当前部门存在子部门!');

View File

@@ -14,6 +14,10 @@ namespace app\admin\controller\system;
use app\AdminController;
use app\common\model\system\Jobs as JobsModel;
use support\Response;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use Webman\Http\Request;
/**
@@ -32,8 +36,12 @@ class Jobs extends AdminController
/**
* 获取资源列表
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function index()
public function index(): Response
{
if (request()->isAjax()) {
@@ -76,17 +84,13 @@ class Jobs extends AdminController
{
if (request()->isPost()) {
$post = request()->post();
$post = request_validate_rules($post, get_class($this->model));
if (empty($post) || !is_array($post)) {
return $this->error($post);
}
if ($this->model->create($post)) {
return $this->success('添加岗位成功!');
}else {
}
}
return $this->error('添加岗位失败!');
}
}
}
/**
* 编辑岗位数据
@@ -95,25 +99,21 @@ class Jobs extends AdminController
{
if (request()->isPost()) {
$post = request()->post();
$post = request_validate_rules($post, get_class($this->model));
if (empty($post) || !is_array($post)) {
return $this->error($post);
}
if ($this->model->update($post)) {
return $this->success('更新岗位成功!');
}else {
}
}
return $this->error('更新岗位失败');
}
}
}
/**
* 删除岗位数据
* @return Response
*/
public function del()
public function del(): Response
{
$id = input('id');
if (!empty($id) && is_numeric($id)) {
if ($id > 0) {
if ($this->model::destroy($id)) {
return $this->success('删除岗位成功!');
}

View File

@@ -19,7 +19,6 @@ use system\File;
use system\Http;
use system\ZipArchives;
use app\AdminController;
use app\admin\library\Auth;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

View File

@@ -12,7 +12,9 @@ declare (strict_types=1);
namespace app\admin\controller\system;
use app\admin\service\UserService;
use app\AdminController;
use app\common\exception\OperateException;
use app\common\library\Ip2Region;
use app\common\model\system\User as UserModel;
use app\common\model\system\UserGroup as UserGroupModel;
@@ -43,122 +45,53 @@ class User extends AdminController
* @throws DbException
* @throws ModelNotFoundException
*/
public function index(): \support\Response
public function index(): Response
{
$userGroup = UserGroupModel::select()->toArray();
if (request()->isAjax()) {
// 获取数据
$post = \request()->all();
$page = (int)input('page') ?? 1;
$limit = (int)input('limit') ?? 10;
$status = !empty($post['status']) ? (int)$post['status'] - 1 : 1;
// 生成查询条件
$where = array();
if (!empty($post['nickname'])) {
$where[] = ['nickname', 'like', '%' . $post['nickname'] . '%'];
}
if (!empty($post['group_id'])) {
$where[] = ['group_id', 'find in set', $post['group_id']];
}
// 生成查询数据
$where[] = ['status', '=', $status];
$count = $this->model->where($where)->count();
$page = ($count <= $limit) ? 1 : $page;
$list = $this->model->where($where)->order("id asc")->limit((int)$limit)->page((int)$page)->select();
// 循环处理数据
foreach ($list as $key => $value) {
$value->hidden(['pwd', 'salt']);
$region = Ip2Region::instance()->memorySearch($value['login_ip']);
$region = explode('|', $region['region']);
$list[$key]['region'] = $region;
$result = list_search($userGroup, ['id' => $value['group_id']]);
if (!empty($result)) {
$list[$key]['group'] = $result['title'];
}
}
// TODO..
return $this->success('查询成功', "", $list, $count);
$post = request()->all();
list($count, $list) = UserService::dataList($post);
return $this->success('查询成功', "/", $list, $count);
}
return view('/system/user/index', [
'UserGroup' => $userGroup,
'UserGroup' => UserGroupModel::select()->toArray()
]);
}
/**
* 添加会员
* @return Response
* @throws OperateException
*/
public function add()
public function add(): Response
{
if (request()->isPost()) {
$post = request()->post();
// 禁止重复注册
$whereName[] = ['nickname', '=', $post['nickname']];
$whereEmail[] = ['email', '=', $post['email']];
if ($this->model->whereOr([$whereName, $whereEmail])->findOrEmpty()->toArray()) {
return $this->error('该用户ID或邮箱已经存在');
}
// 生成密码
$salt = Random::alpha();
$post['salt'] = $salt;
$post['pwd'] = encryptPwd($post['pwd'], $post['salt']);
if ($this->model->create($post)) {
validate(\app\common\validate\system\User::class)->scene('add')->check($post);
UserService::add($post);
return $this->success('注册成功!');
}
return $this->error('注册失败!');
}
}
/**
* 编辑会员
* @return Response
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
* @throws OperateException
*/
public function edit()
public function edit(): Response
{
if (request()->isPost()) {
$post = \request()->post();
// 查询数据
$data = $this->model->find($post['id']);
if ($data['nickname'] != $post['nickname']) {
$whereName[] = ['nickname', '=', $post['nickname']];
if ($this->model->where($whereName)->find()) {
return $this->error('该用户ID已经存在');
}
}
if ($data['email'] != $post['email']) {
$whereEmail[] = ['email', '=', $post['email']];
if ($this->model->where($whereEmail)->find()) {
return $this->error('该用户邮箱已经存在!');
}
}
// 为空则去掉密码
if (empty($post['pwd'])) {
unset($post['pwd']);
} else {
$salt = Random::alpha();
$post['salt'] = $salt;
$post['pwd'] = encryptPwd($post['pwd'], $post['salt']);
}
if ($this->model->update($post)) {
$post = request()->post();
validate(\app\common\validate\system\User::class)->scene('edit')->check($post);
UserService::edit($post);
return $this->success('更新成功!');
}
return $this->error('更新失败!');
}
}
/**
* 删除会员

View File

@@ -0,0 +1,42 @@
<?php
namespace app\admin\enums;
/**
* 管理员枚举类
* @package app\admin\enums
* UserYM
* Date2020/2/10
*/
class AdminEnum
{
/**
* 管理员状态
* @var array
*/
const ADMIN_SESSION = 'AdminLogin';
/**
* 管理员登录错误事件
* @var string
*/
const ADMIN_LOGIN_ERROR = 'adminLoginError';
/**
* 管理员登录成功事件
* @var string
*/
const ADMIN_LOGIN_SUCCESS = 'adminLoginSuccess';
/**
* 管理员权限规则
* @var string
*/
const ADMIN_AUTH_RULES = 'rules';
/**
* 管理员栏目规则
* @var string
*/
const ADMIN_AUTH_CATES = 'cates';
}

View File

@@ -0,0 +1,35 @@
<?php
namespace app\admin\enums;
/**
* 管理员通知枚举类
* @package app\admin\enums
*/
class AdminNoticeEnum
{
// 系统通知
const NOTICE = 'notice';
// 站内消息
const MESSAGE = 'message';
// 待办事项
const TODO = 'todo';
// 未读
const STATUS_UNREAD = 0;
// 已读
const STATUS_READ = 1;
// 通知类型集合
const COLLECTION = [self::NOTICE, self::MESSAGE, self::TODO,];
// 枚举集合
const ENUM = [
self::NOTICE => '系统通知',
self::MESSAGE => '站内消息',
self::TODO => '待办事项',
];
}

View File

@@ -1,6 +1,7 @@
<?php
namespace app\admin\middleware\system;
use app\admin\enums\AdminEnum;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;
@@ -14,9 +15,9 @@ class AdminLogin implements MiddlewareInterface
{
public function process(Request $request, callable $handler) : Response
{
$AdminLogin = \request()->session()->get(AdminSession);
$AdminLogin = \request()->session()->get(AdminEnum::ADMIN_SESSION);
if (!isset($AdminLogin['_security'])) {
$request->session()->delete(AdminSession);
$request->session()->delete(AdminEnum::ADMIN_SESSION);
return response(request_error(), 404);
}
return $handler($request);

View File

@@ -2,10 +2,9 @@
namespace app\admin\middleware\system;
use app\admin\enums\AdminEnum;
use app\admin\service\AuthService;
use support\View;
use app\admin\library\Auth;
use app\common\library\ResultCode;
use app\common\model\system\Admin as AdminModel;
use app\common\model\system\SystemLog;
use Psr\SimpleCache\InvalidArgumentException;
use think\db\exception\DataNotFoundException;
@@ -45,57 +44,32 @@ class AdminPermissions implements MiddlewareInterface
*/
public function process(Request $request, callable $handler): Response
{
// 控制器鉴权
$app = request()->getApp();
$controller = request()->getController();
$action = request()->getAction();
$AdminLogin = request()->session()->get(AdminSession);
$method = '/' . $controller . '/' . $action;
$AdminLogin = request()->session()->get(AdminEnum::ADMIN_SESSION);
if (!isset($AdminLogin['id']) && strtolower($controller) !== 'login') {
return redirect(url('/login/index'));
}
// 获取管理员信息
$request->adminInfo = $AdminLogin;
$request->adminId = $AdminLogin['id'] ?? 0;
// 获取权限列表
$class = new \ReflectionClass($request->controller);
$properties = $class->getDefaultProperties();
$this->noNeedLogin = $properties['noNeedLogin'] ?? $this->noNeedLogin;
// 控制器鉴权
$method = '/' . $controller . '/' . $action;
// 开始校验菜单权限
$authService = AuthService::instance();
if (!in_array('*', $this->noNeedLogin)
&& !in_array(strtolower($method), array_map('strtolower', $this->noNeedLogin))) {
if (!Auth::instance()->SuperAdmin() && !Auth::instance()->check($method, get_admin_id())) {
if (request()->isAjax()) {
return json(['code' => 101, 'msg' => '没有权限']);
} else {
return $this->abortPage('没有权限!', 401);
}
}
}
/**
* Admin应用
* 控制器权限分发
*/
if (\request()->isPost()) {
$id = input('id');
if ($controller == 'system/Admin') {
if ($data = AdminModel::getById($id)) {
$group_id = input('group_id');
$group_id = !empty($group_id) ? $group_id . ',' . $data['group_id'] : $data['group_id'];
$group_id = array_unique(explode(',', $group_id));
if (!Auth::instance()->checkRulesForGroup($group_id)) {
return json(ResultCode::AUTH_ERROR);
}
}
}
if ($controller == 'system/AdminGroup') {
if (!empty($id) && $id >= 1) {
if (!Auth::instance()->checkRulesForGroup((array)$id)) {
return json(ResultCode::AUTH_ERROR);
}
}
$superAdmin = $authService->superAdmin();
if (!$superAdmin && !$authService->permissions($method, $AdminLogin['id'])) {
return request()->isAjax() ? json(['code' => 101, 'msg' => '没有权限']) : $this->abortPage('没有权限!', 401);
}
}
@@ -103,7 +77,7 @@ class AdminPermissions implements MiddlewareInterface
View::assign('app', $app);
View::assign('controller', $controller);
View::assign('action', $action);
View::assign('AdminLogin', $AdminLogin);
View::assign(AdminEnum::ADMIN_SESSION, $AdminLogin);
self::writeAdminRequestLogs();
return $handler($request);
}
@@ -111,9 +85,6 @@ class AdminPermissions implements MiddlewareInterface
/**
* 写入后台操作日志
* @throws InvalidArgumentException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function writeAdminRequestLogs()
{

View File

@@ -0,0 +1,169 @@
<?php
declare (strict_types=1);
// +----------------------------------------------------------------------
// | swiftAdmin 极速开发框架 [基于WebMan开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
// +----------------------------------------------------------------------
// | swiftAdmin.net High Speed Development Framework
// +----------------------------------------------------------------------
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
// +----------------------------------------------------------------------
namespace app\admin\service;
use app\admin\enums\AdminEnum;
use app\common\exception\OperateException;
use app\common\model\system\AdminGroup as AdminGroupModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
/**
* 管理员角色服务
* Class AdminGroupService
*/
class AdminGroupService
{
/**
* 获取管理员列表
* @param array $params
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function dataList(array $params = []): array
{
$page = $params['page'] ?? 1;
$limit = $params['limit'] ?? 10;
$where = [];
if (!empty($param['title'])) {
$where[] = ['title', 'like', '%' . $param['title'] . '%'];
}
if (!empty($param['alias'])) {
$where[] = ['alias', 'like', '%' . $param['alias'] . '%'];
}
if (!empty($param['content'])) {
$where[] = ['content', 'like', '%' . $param['content'] . '%'];
}
$model = new AdminGroupModel();
// 查询数据
$count = $model->where($where)->count();
$page = ($count <= $limit) ? 1 : $page;
$list = $model->where($where)->order("id asc")->limit($limit)->page($page)->select()->toArray();
return [$count, $list];
}
/**
* @param array $params
* @return bool
* @throws OperateException
*/
public static function add(array $params = []): bool
{
$model = new AdminGroupModel();
$where[] = ['title', '=', $params['title']];
$where[] = ['alias', '=', $params['alias']];
$result = $model->whereOr($where)->findOrEmpty()->toArray();
if (!empty($result)) {
throw new OperateException('该角色名称或角色别名已被注册');
}
Db::startTrans();
try {
$model->create($params);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
throw new OperateException($e->getMessage());
}
return true;
}
/**
* 编辑管理员
* @param array $params
* @return bool
* @throws OperateException
*/
public static function edit(array $params): bool
{
$model = new AdminGroupModel();
$where[] = ['title', '=', $params['title']];
$where[] = ['alias', '=', $params['alias']];
$result = $model->whereOr($where)->findOrEmpty()->toArray();
if (!empty($result) && $result['id'] != $params['id']) {
throw new OperateException('该角色名称或角色别名已被注册');
}
Db::startTrans();
try {
$model->update($params);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
throw new OperateException($e->getMessage());
}
return true;
}
/**
* 编辑角色权限
* @param int $id
* @param array $rules
* @return bool
* @throws OperateException
*/
public static function editRules(int $id, array $rules = []): bool
{
$authService = AuthService::instance();
if (!$authService->checkRuleOrCateNodes($rules, AdminEnum::ADMIN_AUTH_RULES)) {
throw new OperateException('没有权限!');
}
Db::startTrans();
try {
$rules = implode(',', $rules);
AdminGroupModel::update(['rules' => $rules], ['id' => $id]);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
throw new OperateException($e->getMessage());
}
return true;
}
/**
* 编辑角色权限
* @param int $id
* @param array $cates
* @return bool
* @throws OperateException
*/
public static function editCates(int $id, array $cates = []): bool
{
$authService = AuthService::instance();
if (!$authService->checkRuleOrCateNodes($cates, AdminEnum::ADMIN_AUTH_CATES)) {
throw new OperateException('没有权限!');
}
Db::startTrans();
try {
$cates = implode(',', $cates);
AdminGroupModel::update(['cates' => $cates], ['id' => $id]);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
throw new OperateException($e->getMessage());
}
return true;
}
}

View File

@@ -0,0 +1,176 @@
<?php
declare (strict_types=1);
// +----------------------------------------------------------------------
// | swiftAdmin 极速开发框架 [基于WebMan开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
// +----------------------------------------------------------------------
// | swiftAdmin.net High Speed Development Framework
// +----------------------------------------------------------------------
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
// +----------------------------------------------------------------------
namespace app\admin\service;
use app\admin\enums\AdminNoticeEnum;
use app\common\exception\OperateException;
use app\common\model\system\AdminNotice;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use Webman\Event\Event;
class AdminNoticeService
{
/**
* 获取消息列表
* @param int $adminId
* @return array
* @throws DbException
*/
public static function dataList(int $adminId): array
{
$type = input('type', AdminNoticeEnum::TODO);
$page = input('page', 1);
$limit = input('limit', 10);
$title = input('title', '');
if ($type == 'send') {
$where[] = ['type', '=', AdminNoticeEnum::MESSAGE];
$where[] = ['send_id', '=', $adminId];
} else {
$where[] = ['type', '=', $type];
$where[] = ['admin_id', '=', $adminId];
}
$status = input('status', 'all');
if ($status !== 'all') {
$where[] = ['status', '=', $status];
}
if (!empty($title)) {
$where[] = ['title', 'like', '%' . $title . '%'];
}
$count = AdminNotice::where($where)->count();
$list = AdminNotice::with(['admin'])->where($where)
->order('id', 'desc')
->limit((int)$limit)
->page((int)$page)
->select()->toArray();
return [$count, $list];
}
/**
* 获取管理员通知列表
* @param int $adminId
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function bells(int $adminId): array
{
$collection = AdminNoticeEnum::COLLECTION;
foreach ($collection as $item) {
$where = [
['type', '=', $item],
['admin_id', '=', $adminId],
];
$count[$item] = AdminNotice::where($where)->where('status', 0)->count();
$list[$item] = AdminNotice::with(['admin'])->withoutField('content')->where($where)->limit(3)->order('id desc')->select()->toArray();
}
return [$count ?? [], $list ?? []];
}
/**
* 获取管理员通知列表
* @param int $adminId
* @return array
* @throws DbException
*/
public static function getBells(int $adminId): array
{
$type = input('type', AdminNoticeEnum::NOTICE);
$page = input('page', 1);
$limit = input('limit', 3);
$where[] = ['type', '=', $type];
$where[] = ['admin_id', '=', $adminId];
return AdminNotice::with(['admin'])->where($where)
->order('id', 'desc')
->paginate(['list_rows' => $limit, 'page' => $page])
->toArray();
}
/**
* 添加消息
* @param array $data
* @param string $type
* @return bool
* @throws OperateException
*/
public static function add(array $data = [], string $type = ''): bool
{
if (!$data) {
return false;
}
try {
$model = new AdminNotice();
$type == 'array' ? $model->saveAll($data) : $model->create($data);
} catch (\Exception $e) {
throw new OperateException($e->getMessage());
}
// 钩子消息推送
Event::emit('sendAdminNotice', $data);
return true;
}
/**
* 获取管理员通知详情
* @param $id
* @param $adminId
* @return array
* @throws OperateException
*/
public static function getDetail($id, $adminId): array
{
$detail = AdminNotice::with(['admin'])->where(['id' => $id])->findOrEmpty()->toArray();
if (empty($detail)) {
throw new OperateException('数据不存在');
}
if (!in_array($adminId,[$detail['admin_id'],$detail['send_id']])){
throw new OperateException('非法访问');
}
if ($detail['type'] !== AdminNoticeEnum::TODO && $detail['admin_id'] == $adminId) {
AdminNotice::update(['status' => 1], ['id' => $id]);
}
return $detail;
}
/**
* 删除消息
* @param int $id
* @param int $adminId
* @return bool
* @throws OperateException
*/
public static function delete(int $id = 0, int $adminId = 0): bool
{
$detail = AdminNotice::where('id', $id)->findOrEmpty()->toArray();
if (empty($detail)) {
throw new OperateException('数据不存在');
}
$receive = $detail['send_id'] == $adminId && $detail['status'] == 1;
if ($detail['admin_id'] != $adminId || $receive) {
throw new OperateException('无权删除');
}
AdminNotice::destroy($id);
return true;
}
}

View File

@@ -0,0 +1,47 @@
<?php
declare (strict_types=1);
// +----------------------------------------------------------------------
// | swiftAdmin 极速开发框架 [基于WebMan开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
// +----------------------------------------------------------------------
// | swiftAdmin.net High Speed Development Framework
// +----------------------------------------------------------------------
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
// +----------------------------------------------------------------------
namespace app\admin\service;
use app\common\model\system\AdminRules;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
class AdminRuleService
{
/**
* 获取资源列表
* @param array $params
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function dataList(array $params): array
{
$where = array();
if (!empty($params['title'])) {
$where[] = ['title','like','%'.$params['title'].'%'];
}
if (!empty($params['router'])) {
$where[] = ['router','like','%'.$params['router'].'%'];
}
$model = new AdminRules();
$count = $model->where($where)->count();
$list = $model->where($where)->order('sort asc')->select()->toArray();
foreach ($list as $key => $value) {
$list[$key]['title'] = __($value['title']);
}
return [$count, $list];
}
}

View File

@@ -0,0 +1,195 @@
<?php
declare (strict_types=1);
// +----------------------------------------------------------------------
// | swiftAdmin 极速开发框架 [基于WebMan开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
// +----------------------------------------------------------------------
// | swiftAdmin.net High Speed Development Framework
// +----------------------------------------------------------------------
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
// +----------------------------------------------------------------------
namespace app\admin\service;
use app\admin\enums\AdminEnum;
use app\common\exception\OperateException;
use app\common\model\system\Admin;
use app\common\model\system\AdminAccess;
use app\common\model\system\AdminAccess as AdminAccessModel;
use app\common\model\system\AdminGroup as AdminGroupModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
/**
* 管理员服务
* Class AdminService
*/
class AdminService
{
/**
* 获取管理员列表
* @param array $params
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function dataList(array $params = []): array
{
$page = $params['page'] ?? 1;
$limit = $params['limit'] ?? 10;
$status = !empty($params['status']) ? $params['status'] - 1 : 1;
$where[] = ['status', '=', $status];
if (!empty($params['name'])) {
$where[] = ['name', 'like', '%' . $params['name'] . '%'];
}
if (!empty($params['dep'])) {
$where[] = ['branch_id', 'find in set', $params['dep']];
}
if (!empty($params['group_id'])) {
$where[] = ['group_id', 'find in set', $params['group_id']];
}
$model = new Admin();
$count = $model->where($where)->count();
$page = ($count <= $limit) ? 1 : $page;
$adminList = $model->where($where)->order("id asc")->withoutField('pwd')->limit($limit)->page($page)->select()->toArray();
$authService = AuthService::instance();
foreach ($adminList as $key => $value) {
$groupId = trim($value['group_id']);
$itemGroup = (new AdminGroupModel)->where('id', 'in', $groupId)->select()->toArray();
$adminList[$key]['group'] = $itemGroup;
// 排序
if (!empty($adminList[$key]['group'])) {
$adminList[$key]['group'] = list_sort_by($adminList[$key]['group'], 'id');
}
$authNodes = $authService->getRulesNode($value['id']);
$adminList[$key][AdminEnum::ADMIN_AUTH_RULES] = $authNodes[$authService->authPrivate];
$authNodes = $authService->getRulesNode($value['id'], AdminEnum::ADMIN_AUTH_RULES);
$adminList[$key][AdminEnum::ADMIN_AUTH_CATES] = $authNodes[$authService->authPrivate];
}
return [
'count' => $count,
'list' => $adminList
];
}
/**
* @param array $params
* @return bool
* @throws OperateException
*/
public static function add(array $params = []): bool
{
$model = new Admin();
$where[] = ['name', '=', $params['name']];
$where[] = ['email', '=', $params['email']];
$result = $model->whereOr($where)->findOrEmpty()->toArray();
if (!empty($result)) {
throw new OperateException('该用户名或邮箱已被注册!');
}
// 管理员加密
$params['pwd'] = encryptPwd($params['pwd']);
$params['create_ip'] = request()->getRealIp();
Db::startTrans();
try {
$data = $model->create($params);
$access['admin_id'] = $data['id'];
$access['group_id'] = $data['group_id'];
AdminAccessModel::insert($access);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
throw new OperateException($e->getMessage());
}
return true;
}
/**
* 编辑管理员
* @param array $params
* @return bool
* @throws OperateException
*/
public static function edit(array $params): bool
{
if (!empty($params['pwd'])) {
$params['pwd'] = encryptPwd($params['pwd']);
}
foreach ($params as $key => $value) {
if (empty($value)) {
unset($params[$key]);
}
}
Db::startTrans();
try {
$model = new Admin();
$model->update($params);
$access['group_id'] = $params['group_id'];
AdminAccessModel::update($access, ['admin_id' => $params['id']]);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
throw new OperateException($e->getMessage());
}
return true;
}
/**
* 更新权限节点
* @param $adminId
* @param string $ruleType
* @return bool
* @throws OperateException
*/
public static function updateRulesNodes($adminId, string $ruleType): bool
{
if (!$adminId) {
throw new OperateException('参数错误!');
}
$authService = AuthService::instance();
$params = request()->post($ruleType, []);
$access = $authService->getRulesNode($adminId, $ruleType);
$rules = array_diff($params, $access[$authService->authGroup]);
if (!$authService->checkRuleOrCateNodes($rules, $ruleType, $authService->authPrivate)) {
throw new OperateException('没有权限!');
}
$differ = array_diff($access[$authService->authPrivate], $access[$authService->authGroup]);
$curNodes = [];
if (!$authService->superAdmin()) {
$curNodes = $authService->getRulesNode();
$curNodes = array_diff($differ, $curNodes[$authService->authPrivate]);
}
Db::startTrans();
try {
$value = array_unique(array_merge($rules, $curNodes));
$data[$ruleType] = implode(',', $value);
AdminAccessModel::update($data, ['admin_id' => $adminId]);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
throw new OperateException($e->getMessage());
}
return true;
}
}

View File

@@ -0,0 +1,54 @@
<?php
declare (strict_types=1);
// +----------------------------------------------------------------------
// | swiftAdmin 极速开发框架 [基于WebMan开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
// +----------------------------------------------------------------------
// | swiftAdmin.net High Speed Development Framework
// +----------------------------------------------------------------------
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
// +----------------------------------------------------------------------
namespace app\admin\service;
use app\common\model\system\Attachment;
class AttachmentService
{
/**
* 获取资源列表
* @param array $params
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function dataList(array $params = []): array
{
$page = (int)$params['page'] ?: 1;
$limit = (int)$params['limit'] ?: 10;
$type = $params['type'] ?? '';
$where = [];
if (!empty($type)) {
$where[] = ['type', '=', $type];
}
if (!empty($params['filename'])) {
$where[] = ['filename', 'like', '%' . $params['filename'] . '%'];
}
$model = new Attachment();
$count = $model->where($where)->count();
$page = ($count <= $limit) ? 1 : $page;
$list = $model->where($where)->order("id desc")->limit((int)$limit)->page((int)$page)->select()->toArray();
$prefix = cdn_Prefix();
foreach ($list as $index => $item) {
if (!empty($prefix)) {
$list[$index]['url'] = $prefix . $item['url'];
}
}
return [$count, $list];
}
}

View File

@@ -9,34 +9,30 @@ declare (strict_types=1);
// +----------------------------------------------------------------------
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
// +----------------------------------------------------------------------
namespace app\admin\library;
namespace app\admin\service;
use app\admin\enums\AdminEnum;
use app\common\model\system\Admin;
use app\common\model\system\AdminAccess;
use app\common\model\system\Admin as AdminModel;
use app\common\model\system\AdminRules as AdminRulesModel;
use app\common\model\system\AdminGroup as AdminGroupModel;
use app\common\model\system\AdminRules as AdminRulesModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use Webman\Event\Event;
/**
* 后台模块验证
* 后台权限验证
* @package app\admin\service
* Class AuthService
*/
class Auth
class AuthService
{
/**
* 数据库实例
* @var mixed
* @var object
*/
protected mixed $model;
/**
* 管理员数据
* @var mixed
*/
private mixed $admin;
protected object $model;
/**
* 分组标记
@@ -64,28 +60,26 @@ class Auth
protected string $_error = '';
/**
* @var mixed
* @var ?object 对象实例
*/
private mixed $groupIDs;
// 对象实例
protected static $instance = null;
protected static ?object $instance = null;
/**
* 类构造函数
* class constructor.
*/
public function __construct($config = [])
public function __construct()
{
$this->model = new Admin();
}
/**
* 初始化
* @access public
* @param array $options 参数
* @return object
* @return object|null
*/
public static function instance($options = [])
public static function instance(array $options = []): ?object
{
if (is_null(self::$instance)) {
self::$instance = new static($options);
@@ -97,17 +91,17 @@ class Auth
/**
* 检查权限
* @param string|array $name 需要验证的规则列表,支持逗号分隔的权限规则或索引数组
* @param int $admin_id 认证用户的id
* @param mixed $name 需要验证的规则列表,支持逗号分隔的权限规则或索引数组
* @param int $adminId 认证用户的id
* @param int $type 认证类型
* @param string $mode 执行check的模式
* @param string $relation 如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
* @param string $relation 如果为 'or' 表示满足任一条规则即通过验证;如果为 and则表示需满足所有规则才能通过验证
* @return bool 通过验证返回true;失败返回false
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function check($name, int $admin_id = 0, int $type = 1, string $mode = 'url', string $relation = 'or'): bool
public function permissions(mixed $name, int $adminId = 0, int $type = 1, string $mode = 'url', string $relation = 'or'): bool
{
// 转换格式
if (is_string($name)) {
@@ -124,7 +118,7 @@ class Auth
$REQUEST = unserialize(strtolower(serialize(request()->all())));
}
foreach ($this->getAuthList($admin_id) as $auth) {
foreach ($this->getAuthList($adminId) as $auth) {
// 非鉴权接口
$router = strtolower($auth['router']);
@@ -133,6 +127,17 @@ class Auth
continue;
}
// 校验正则模式
if (!empty($auth['condition'])) {
$rule = $condition = '';
$user = $this->getUserInfo();
$command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule);
@(eval('$condition=(' . $command . ');'));
if ($condition) {
$authList[] = $router;
}
}
// URL参数模式
$query = preg_replace('/^.+\?/U', '', $router);
if ('url' == $mode && $query != $router) {
@@ -162,91 +167,27 @@ class Auth
return false;
}
/**
* 获取权限节点
* @param mixed $admin_id
* @param string $type
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getRulesNode(mixed $admin_id = 0, string $type = AUTH_RULES): array
{
// 私有节点
$authGroup = $authPrivate = [];
$admin_id = $admin_id > 1 ? $admin_id: session('AdminLogin.id');
$authNodes = AdminAccess::where('admin_id', $admin_id)->find();
if (!empty($authNodes[$type])) {
$authPrivate = explode(',', $authNodes[$type]);
}
// 用户组节点
if (!empty($authNodes['group_id'])) {
$groupNodes = AdminGroupModel::whereIn('id', $authNodes['group_id'])->select()->toArray();
foreach ($groupNodes as $value) {
$nodes = !empty($value[$type]) ? explode(',', $value[$type]) : [];
$authGroup = array_unique(array_merge($authGroup, $nodes));
$authPrivate = array_unique(array_merge($authPrivate, $nodes));
}
}
// 返回数据集
$array[$this->authGroup] = $authGroup;
$array[$this->authPrivate] = $authPrivate;
return $array;
}
/**
* 获取权限菜单
* @access public
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getRulesMenu()
{
$authNodes = $this->getRulesNode();
$list = $this->getAuthList(session('AdminLogin.id'), $authNodes);
foreach ($list as $key => $value) {
$list[$key]['title'] = __($value['title']);
$list[$key]['router'] = url($value['router']);
}
if ($this->superAdmin()) {
$authNodes['supersAdmin'] = true;
}
$authNodes['authorities'] = list_to_tree($list);
return json_encode($authNodes, JSON_UNESCAPED_UNICODE);
}
/**
* 查询权限列表
* @param $admin_id
* @param array $nodes
* @param mixed $adminId 用户id
* @param array $nodes 已获取节点
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getAuthList($admin_id, array $nodes = []): array
public function getAuthList(mixed $adminId = 0, array $nodes = []): array
{
// 查找节点
$where[] = ['status', '=', 1];
if (!$this->superAdmin()) {
$auth_nodes = !empty($nodes) ? $nodes : $this->getRulesNode($admin_id);
return AdminRulesModel::where(function ($query) use ($where, $auth_nodes) {
if (empty($auth_nodes[$this->authPrivate])) {
$authNodes = !empty($nodes) ? $nodes : $this->getRulesNode($adminId);
return AdminRulesModel::where(function ($query) use ($where, $authNodes) {
if (empty($authNodes[$this->authPrivate])) {
$where[] = ['auth', '=', '0'];
$query->where($where);
} else {
$where[] = ['id', 'in', $auth_nodes[$this->authPrivate]];
$where[] = ['id', 'in', $authNodes[$this->authPrivate]];
$query->where($where)->whereOr('auth', '0');
}
})->order('sort asc')->select()->toArray();
@@ -256,161 +197,208 @@ class Auth
}
/**
* 查询权限节点
* @access public
* @param mixed|null $type
* @param mixed|null $class
* @param bool $tree
* @return mixed
* 获取权限菜单
* @return string
* @throws DataNotFoundException
* @throws DbException
*/
public function getPermissionsMenu(): string
{
$authNodes = $this->getRulesNode();
$nodeLists = $this->getAuthList(get_admin_id(), $authNodes);
foreach ($nodeLists as $key => $value) {
$nodeLists[$key]['title'] = __($value['title']);
if ($value['router'] != '#') {
$nodeLists[$key]['router'] = (string)url($value['router']);
}
}
$this->superAdmin() && $authNodes['supersAdmin'] = true;
$authNodes['authorities'] = list_to_tree($nodeLists);
return json_encode($authNodes, JSON_UNESCAPED_UNICODE);
}
/**
* 管理组分级鉴权
* @param array $operationIds
* @return bool
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getRuleCatesTree(mixed $type = null, mixed $class = null, bool $tree = true)
public function checkRulesForGroup(array $operationIds = []): bool
{
$list = [];
if (is_array($type) && $type) {
$class = $type['class'] ?? $this->authGroup;
$type = $type['type'] ?? AUTH_RULES;
if ($this->superAdmin()) {
return true;
}
$group_id = $this->getUserInfo()['group_id'];
$adminGroupIds = explode(',', $group_id);
$adminGroupList = AdminGroupModel::where('id', 'in', $adminGroupIds)->select()->toArray();
// 查询操作组
$operationList = AdminGroupModel::where('id', 'in', $operationIds)->select()->toArray();
foreach ($operationList as $item) {
foreach ($adminGroupList as $child) {
if ($item['pid'] < $child['id']
|| $item['pid'] == $child['pid']) {
return false;
}
}
}
return true;
}
/**
* 查询权限节点
* @access public
* @param $type
* @param $class
* @param bool $tree
* @return array|false|string
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getRuleCatesTree($type, $class, bool $tree = true)
{
if (is_array($type) && $type) {
$type = $type['type'] ?? AdminEnum::ADMIN_AUTH_RULES;
$class = $type['class'] ?? $this->authGroup;
}
$class = $class != $this->authGroup ? $this->authPrivate : $class;
$auth_nodes = $this->getRulesNode(session('AdminLogin.id'), $type);
if ($type && $type == AUTH_RULES) {
$authNodes = $this->getRulesNode(get_admin_id(), $type);
$where[] = ['status', '=', 1];
if ($type && $type == AdminEnum::ADMIN_AUTH_RULES) {
if (!$this->superAdmin()) {
$list = AdminRulesModel::where(function ($query) use ($where, $auth_nodes, $class) {
if (empty($auth_nodes[$class])) {
$menuList = AdminRulesModel::where(function ($query) use ($where, $authNodes, $class) {
if (empty($authNodes[$class])) {
$where[] = ['auth', '=', '0'];
$query->where($where);
} else {
$where[] = ['id', 'in', $auth_nodes[$class]];
$where[] = ['id', 'in', $authNodes[$class]];
$query->where($where)->whereOr('auth', '0');
}
})->order('sort asc')->select()->toArray();
} else {
$list = AdminRulesModel::where($where)->order('sort asc')->select()->toArray();
$menuList = AdminRulesModel::where($where)->order('sort asc')->select()->toArray();
}
} else {
/**
* 栏目二次开发接口
* @param $list
* @param $menuList
*/
if (!$this->superAdmin()) {
if (!empty($auth_nodes[$class])) {
$list = Event::emit('cmsCategoryPermissions', [
if (!$this->superAdmin() && !empty($authNodes[$class])) {
$menuList = Event::emit('cmsCategoryPermissions', [
'field' => $this->authFields,
'nodes' => $auth_nodes[$class]
'nodes' => $authNodes[$class]
], true);
}
} else {
$list = Event::emit('cmsCategoryPermissions', [
$menuList = Event::emit('cmsCategoryPermissions', [
'field' => $this->authFields
], true);
}
}
return $tree ? ($list ? json_encode(list_to_tree($list)) : json_encode([])) : $list;
return $tree ? ($menuList ? json_encode(list_to_tree($menuList)) : json_encode([])) : $menuList;
}
/**
* 校验节点避免越权
* @access public
* @param null $rules
* @param string|null $type
* @param $rules
* @param string $type
* @param string $class
* @return bool
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function checkRuleOrCateNodes($rules = null, string $type = null, string $class = 'pri'): bool
{
if (!$this->superAdmin() && !empty($rules)) {
$type = !empty($type) ? $type : AUTH_RULES;
$class = !empty($class) ? $class : $this->authGroup;
$class = $class != $this->authGroup ? $this->authPrivate : $class;
$auth_nodes = $this->getRulesNode(session('AdminLogin.id'), $type);
$differ = array_unique(array_merge($rules, $auth_nodes[$class]));
if (count($differ) > count($auth_nodes[$class])) {
return false;
}
}
return true;
}
/**
* 超级管理员
* @access public
* @return bool
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function superAdmin(): bool
{
$groupIDs = AdminModel::field('group_id')->find(session('AdminLogin.id'));
$groupIDs = explode(',', $groupIDs['group_id']);
$this->groupIDs = $groupIDs;
if (session('AdminLogin.id') == 1 || in_array(1, $groupIDs)) {
return true;
}
return false;
}
/**
* 管理组分级鉴权
* @param array $groupIDs
* @return bool
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function checkRulesForGroup(array $groupIDs = []): bool
public function checkRuleOrCateNodes($rules, string $type, string $class = 'pri'): bool
{
if ($this->superAdmin()) {
return true;
}
// 查询数据
$list = AdminGroupModel::select()->toArray();
foreach ($list as $value) {
// 循环处理组PID
if (in_array($value['id'], $groupIDs)) {
foreach ($this->groupIDs as $id) {
$self = list_search($list, ['id' => $id]);
if (!empty($self) &&
($value['pid'] < $self['id'] || $value['pid'] == $self['pid'])) {
$type = !empty($type) ? $type : AdminEnum::ADMIN_AUTH_RULES;
$class = !empty($class) ? $class : $this->authGroup;
$class = $class != $this->authGroup ? $this->authPrivate : $class;
$authNodes = $this->getRulesNode(get_admin_id(), $type);
$differ = array_unique(array_merge($rules, $authNodes[$class]));
if (count($differ) > count($authNodes[$class])) {
return false;
}
}
}
}
return true;
}
/**
* 获取用户信息
* @param $admin_id
* 获取权限节点
* @param mixed $adminId 管理员id
* @param string $type 节点类型
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getAdminInfo($admin_id): array
public function getRulesNode(mixed $adminId = 0, string $type = AdminEnum::ADMIN_AUTH_RULES): array
{
$admin_id = $admin_id ?? get_admin_id();
static $AdminArray = [];
$user = Db::name('admin');
// 获取用户表主键
$_pk = is_string($user->getPk()) ? $user->getPk() : 'id';
if (!isset($AdminArray[$admin_id])) {
$AdminArray[$admin_id] = $user->where($_pk, $admin_id)->find();
$authGroup = $authPrivate = [];
$adminId = $adminId > 0 ? $adminId : get_admin_id();
$authNodes = AdminAccess::where('admin_id', $adminId)->findOrEmpty()->toArray();
// 私有节点
if (!empty($authNodes[$type])) {
$authPrivate = explode(',', $authNodes[$type]);
}
return $AdminArray[$admin_id];
// 用户组节点
if (!empty($authNodes['group_id'])) {
$groupNodes = (new AdminGroupModel)->whereIn('id', $authNodes['group_id'])->select()->toArray();
foreach ($groupNodes as $value) {
$nodes = !empty($value[$type]) ? explode(',', $value[$type]) : [];
$authGroup = array_merge($authGroup, $nodes);
$authPrivate = array_merge($authPrivate, $nodes);
}
$authGroup = array_unique($authGroup);
$authPrivate = array_unique($authPrivate);
}
return [
$this->authGroup => $authGroup,
$this->authPrivate => $authPrivate,
];
}
/**
* 超级管理员
* @param int $adminId
* @param int $type
* @return bool
*/
public function superAdmin(int $adminId = 0, int $type = 1): bool
{
$adminId = $adminId > 1 ? $adminId : get_admin_id();
$adminInfo = $this->getUserInfo($adminId);
$adminGroup = explode(',', $adminInfo['group_id']);
if ($adminInfo['id'] == $type || array_search($type, $adminGroup)) {
return true;
}
return false;
}
/**
* 获取用户信息
* @param int $adminId
* @return array
*/
public function getUserInfo(int $adminId = 0): array
{
$_pk = is_string($this->model->getPk()) ? $this->model->getPk() : 'id';
return $this->model->where($_pk, $adminId)->findOrEmpty()->toArray();
}
/**
@@ -424,12 +412,10 @@ class Auth
/**
* 设置错误
* @param string $error 信息信息
* @return void
* @param string $error
*/
protected function setError(string $error): void
{
$this->_error = $error;
}
}

View File

@@ -0,0 +1,122 @@
<?php
declare (strict_types=1);
// +----------------------------------------------------------------------
// | swiftAdmin 极速开发框架 [基于WebMan开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
// +----------------------------------------------------------------------
// | swiftAdmin.net High Speed Development Framework
// +----------------------------------------------------------------------
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
// +----------------------------------------------------------------------
namespace app\admin\service;
use app\admin\enums\AdminEnum;
use app\common\exception\OperateException;
use app\common\library\ResultCode;
use app\common\model\system\Admin;
use app\common\model\system\AdminLog;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use Webman\Event\Event;
class LoginService
{
/**
* 管理员登录
* @param string $name
* @param string $pwd
* @param string $captcha
* @param array $adminInfo
* @return bool
* @throws OperateException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function accountLogin(string $name, string $pwd, string $captcha = '', array $adminInfo = []): bool
{
$countLimit = isset($adminInfo['count']) && $adminInfo['count'] >= 5;
$minuteLimit = isset($adminInfo['time']) && $adminInfo['time'] >= strtotime('- 5 minutes');
if ($countLimit && $minuteLimit) {
throw new OperateException('错误次数过多,请稍后再试!');
}
// 验证码
if (isset($adminInfo['isCaptcha']) && !self::captchaCheck($captcha)) {
throw new OperateException('验证码错误!');
}
$result = Admin::checkLogin($name, $pwd);
if (empty($result)) {
$adminInfo['time'] = time();
$adminInfo['isCaptcha'] = true;
$adminInfo['count'] = isset($adminInfo['count']) ? $adminInfo['count'] + 1 : 1;
request()->session()->set(AdminEnum::ADMIN_SESSION, $adminInfo);
Event::emit(AdminEnum::ADMIN_LOGIN_ERROR, request()->all());
self::writeAdminLogs($name, ResultCode::USPWDERROR['msg']);
throw new OperateException(ResultCode::USPWDERROR['msg'], ResultCode::USPWDERROR['code']);
}
if ($result['status'] !== 1) {
throw new OperateException(ResultCode::STATUSEXCEPTION['msg'], ResultCode::STATUSEXCEPTION['code']);
}
try {
$data['login_ip'] = request()->getRealIp();
$data['login_time'] = time();
$data['count'] = $result['count'] + 1;
Admin::update($data, ['id' => $result['id']]);
$adminInfo = array_merge($adminInfo, $result->toArray());
request()->session()->set(AdminEnum::ADMIN_SESSION, $adminInfo);
self::writeAdminLogs($name, ResultCode::LOGINSUCCESS['msg'], 1);
Event::emit(AdminEnum::ADMIN_LOGIN_SUCCESS, $adminInfo);
} catch (\Throwable $th) {
throw new OperateException($th->getMessage());
}
return true;
}
/**
* 检查验证码
* @param string $text
* @return bool
*/
protected static function captchaCheck(string $text): bool
{
$captcha = $text ?? \request()->post('captcha');
if (strtolower($captcha) !== request()->session()->get('captcha')) {
return false;
}
return true;
}
/**
* 记录登录日志
* @param string $name
* @param string $error
* @param int $status
* @return void
*/
public static function writeAdminLogs(string $name, string $error, int $status = 0): void
{
$userAgent = request()->header('user-agent');
$nickname = (new Admin)->where('name', $name)->value('nickname');
preg_match('/.*?\((.*?)\).*?/', $userAgent, $matches);
$user_os = isset($matches[1]) ? substr($matches[1], 0, strpos($matches[1], ';')) : 'unknown';
$user_browser = preg_replace('/[^(]+\((.*?)[^)]+\) .*?/', '$1', $userAgent);
$data['name'] = $name;
$data['nickname'] = $nickname ?? 'unknown';
$data['user_ip'] = request()->getRealIp();
$data['user_agent'] = $userAgent;
$data['user_os'] = $user_os;
$data['user_browser'] = $user_browser;
$data['error'] = $error;
$data['status'] = $status;
AdminLog::create($data);
}
}

View File

@@ -0,0 +1,146 @@
<?php
declare (strict_types=1);
// +----------------------------------------------------------------------
// | swiftAdmin 极速开发框架 [基于WebMan开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
// +----------------------------------------------------------------------
// | swiftAdmin.net High Speed Development Framework
// +----------------------------------------------------------------------
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
// +----------------------------------------------------------------------
namespace app\admin\service;
use app\common\exception\OperateException;
use app\common\library\Ip2Region;
use app\common\model\system\User;
use app\common\model\system\UserGroup;
use system\Random;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
class UserService
{
/**
*
* @param array $params
* @param array $conditions
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public static function dataList(array $params = [], array $conditions = []): array
{
$page = (int)$params['page'] ?: 1;
$limit = (int)$params['limit'] ?: 10;
$status = !empty($params['status']) ? $params['status']-1:1;
if (!empty($params['nickname'])) {
$where[] = ['nickname','like','%'.$params['nickname'].'%'];
}
if (!empty($params['group_id'])) {
$where[] = ['group_id','find in set',$params['group_id']];
}
$where[]=['status','=',$status];
$conditions = array_merge($conditions, $where ?? []);
$model = new User();
$count = $model->where($conditions)->count();
$page = ($count <= $limit) ? 1 : $page;
$list = $model->where($conditions)->order("id asc")->limit($limit)->page($page)->select();
// 循环处理数据
$userGroup = (new UserGroup)->select()->toArray();
foreach ($list as $key => $value) {
$value->hidden(['pwd', 'salt']);
try {
$region = Ip2Region::instance()->memorySearch($value['login_ip']);
} catch (\Exception $e) {
$region = ['region' => '未知|未知|未知'];
}
$region = explode('|',$region['region']);
$list[$key]['region'] = $region;
$result = list_search($userGroup,['id'=> $value['group_id']]);
if (!empty($result)) {
$list[$key]['group'] = $result['title'];
}
}
return [$count, $list];
}
/**
* @param array $params
* @return bool
* @throws OperateException
*/
public static function add(array $params): bool
{
$model = new User();
$whereName[] = ['nickname','=',$params['nickname']];
$whereEmail[] = ['email','=',$params['email']];
$data = $model->whereOr([$whereName,$whereEmail])->findOrEmpty()->toArray();
if(!empty($data)) {
throw new OperateException('该用户ID或邮箱已经存在');
}
Db::startTrans();
try {
$model->create($params);
} catch (\Exception $e) {
Db::rollback();
throw new OperateException('添加失败!');
}
return true;
}
/**
* @param array $params
* @return bool
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
* @throws OperateException
*/
public static function edit(array $params): bool
{
$model = new User();
$data = $model->where('id', $params['id'])->findOrEmpty()->toArray();
if ($data['nickname'] != $params['nickname']) {
$whereName[] = ['nickname','=',$params['nickname']];
if($model->where($whereName)->find()) {
throw new OperateException('用户ID已经存在');
}
}
if ($data['email'] != $params['email']) {
$whereEmail[] = ['email','=',$params['email']];
if($model->where($whereEmail)->find()) {
throw new OperateException('用户邮箱已经存在!');
}
}
if (!empty($params['pwd'])) {
$salt = Random::alpha();
$params['salt'] = $salt;
$params['pwd'] = encryptPwd($params['pwd'],$params['salt']);
} else {
unset($params['pwd']);
}
Db::startTrans();
try {
$model->update($params);
} catch (\Exception $e) {
Db::rollback();
throw new OperateException('添加失败!');
}
return true;
}
}

View File

@@ -79,7 +79,7 @@
</a>
</li>
<li class="layui-nav-item" lay-unselect>
<a href="javascript:;" sa-event="bells" lay-text="{:__('消息中心')}" data-url="{:url('/system/admin/bells',[],false)}">
<a href="javascript:;" sa-event="bells" lay-text="{:__('消息中心')}" data-url="{:url('/system/AdminNotice/bells',[],false)}">
<i class="layui-icon fa-bell-o"></i>
<!-- 如果有新消息,则显示小圆点 -->
<neq name="notice_count" value="0">

View File

@@ -203,11 +203,9 @@
var that = $(this), _form = that.parents('form'),
name = $('input[name="name"]').val(),
pwd = $('input[name="pwd"]').val(),
captcha = $('input[name="captcha"]').val(),
__token__ = $('input[name="__token__"]').val();
layer.msg("{:__('数据提交中...')}",'warning');
captcha = $('input[name="captcha"]').val();
that.prop('disabled', true);
$_ajax(that,{name: name, pwd: pwd, captcha: captcha,__token__:__token__});
$_ajax(that,{name: name, pwd: pwd, captcha: captcha});
return false;
})
@@ -342,38 +340,31 @@
var _form = that.attr('lay-filter'),
_urls = $('.'+_form).attr('action');
$.ajax({
type: "POST",
url: _urls,
data: data,
success: function (res) {
if(res.code == 200){
if(res.code === 200){
layer.msg(res.msg);
if (jump === undefined) {
window.location = res.url; // 跳转到主页
}
}else {
layer.error(res.msg);
that.prop('disabled', false);
$("#captchaImg,#captchaImg2,#captchaImg3").attr('src',captchaUrl+'?rand='+Math.random()).parents('.layui-form-item').show();
if (res.data.token) {
$('input[name=__token__]').val(res.data.token);
}
return false;
}
},
error: function() {
that.prop('disabled', false);
layer.msg("{:__('好像是网络出错了...')}",'error');
layer.msg("{:__('好像是网络出错了...')}");
}
})
return false;
}
/**
@@ -383,7 +374,7 @@
var array = ['login','register','forget'],
event = $(this).attr("sa-event-type");
for (var i in array) {
if (array[i] != event) {
if (array[i] !== event) {
$('#' + array[i]).css('display','none');
}
}

View File

@@ -1,262 +0,0 @@
<include file="/public/header" />
<link href="__STATICADMIN__css/message.css" rel="stylesheet" type="text/css" />
<div class="layui-tab layui-tab-brief" >
<ul class="layui-tab-title" style="text-align: center;">
<li class="layui-this" id="msg" >{:__('通知')}({$count['notice']})</li>
<li>{:__('私信')}({$count['message']})</li>
<li>{:__('待办')}({$count['todo']})</li>
</ul>
<div class="layui-tab-content" style="padding: 5px 0px;">
<div class="layui-tab-item layui-show">
<ul id="notice" class="layui-instant-list" >
<volist name="list['notice']" id="vo">
<a data-id="{$vo.id}" data-type="notice" class="layui-instant-list-item active_{$vo.status}" href="javascript:;">
<img class="layui-instant-item-icon" src="__ADMINIMAGES__message.png">
<div class="layui-instant-item-right">
<h2 class="layui-instant-item-title">{$vo.title}</h2>
<p class="layui-instant-item-text">{$vo.create_time}</p>
</div>
</a>
</volist>
</ul>
<!-- // 列表为空 -->
<div class="layui-instant-list-empty" <empty name="$list['notice']"> style="display:black;" <else/> style="display:none;" </empty> >
<img src="__ADMINIMAGES__noting.png"><div>{:__('没有通知')}</div>
</div>
<!-- // 底部操作 -->
<notempty name="$list['notice']">
<div class="layui-instant-footer">
<a href="javascript:;" class="instant-clear" data-type="notice">{:__('清空通知')}</a>
<span>|</span>
<a href="javascript:;" class="instant-reads" data-type="notice">{:__('全部已读')}</a>
</div>
</notempty>
</div>
<div class="layui-tab-item">
<ul id="message" class="layui-instant-list" >
<volist name="list['message']" id="vo">
<a data-id="{$vo.id}" data-type="message" class="layui-instant-list-item active_{$vo.status}" href="javascript:;">
<img class="layui-instant-item-icon" src="{$vo.face|default='__ADMINIMAGES__head.png'}" >
<div class="layui-instant-item-right">
<h2 class="layui-instant-item-title">{$vo.title}</h2>
<p class="layui-instant-item-text">{$vo.create_time}</p>
</div>
</a>
</volist>
</ul>
<!-- // 列表为空 -->
<div class="layui-instant-list-empty" <empty name="$list['message']"> style="display:black;" <else/> style="display:none;" </empty> >
<img src="__ADMINIMAGES__noting.png"><div>{:__('没有私信')}</div>
</div>
<notempty name="$list['message']">
<div class="layui-instant-footer">
<a href="javascript:;" class="instant-clear" data-type="message">{:__('清空私信')}</a>
<span>|</span>
<a href="javascript:;" class="instant-reads" data-type="message">{:__('全部已读')}</a>
</div>
</notempty>
</div>
<div class="layui-tab-item">
<ul id="todo" class="layui-instant-list" >
<volist name="list['todo']" id="vo">
<a data-id="{$vo.id}" data-type="todo" class="layui-instant-list-item active_{$vo.status}" href="javascript:;">
<div class="layui-instant-item-right">
<eq name="$vo['status']" value="0">
<span class="layui-badge pull-right">{:__('待完成')}</span>
<else/>
<eq name="$vo['status']" value="3">
<span class="layui-badge layui-bg-green pull-right">{:__('进行中')}</span>
<else/>
<span class="layui-badge layui-bg-gray pull-right">{:__('已完成')}</span>
</eq>
</eq>
<h2 class="layui-instant-item-title">{$vo.title}</h2>
<p class="layui-instant-item-text">{$vo.create_time}</p>
</div>
</a>
</volist>
</ul>
<!-- // 列表为空 -->
<div class="layui-instant-list-empty" <empty name="$list['todo']"> style="display:black;" <else/> style="display:none;" </empty> >
<img src="__ADMINIMAGES__noting.png"><div>{:__('没有待办')}</div>
</div>
<notempty name="$list['todo']">
<div class="layui-instant-footer">
<a href="javascript:;" class="instant-clear" data-type="todo">{:__('清空待办')}</a>
<span>|</span>
<a href="javascript:;" class="instant-reads" data-type="todo">{:__('全部完成')}</a>
</div>
</notempty>
</div>
</div>
</div>
<include file="/public/footer" />
<script>
layui.use(['element'], function () {
let $ = layui.jquery;
let layer = layui.layer;
let flow = layui.flow;
let instantItem = {
notice: {
title: '{:__('我的通知')}',
anim: 2,
},
message: {
title: '{:__('我的私信')}',
anim: 0,
},
todo: {
title: '{:__('我的待办')}',
anim: 0,
},
};
// 执行通知流加载
$.each(instantItem, function (index, type) {
flow.load({
elem: '#' + index,
done: function (page, next) {
let list = [];
let url = "{:url('/system/admin/bells')}?type=" + index + "&page=" + page;
$.get(url, function (res) {
let data = res.data;
if (page >= 2) {
layui.each(data.data, function (key, item) {
let html = '';
switch (index) {
case 'notice':
html += '<a data-id="' + item.id + '" data-type="notice" class="layui-instant-list-item active_' + item.status + '" href="javascript:;">';
html += '<img class="layui-instant-item-icon" src="__ADMINIMAGES__message.png">';
html += '<div class="layui-instant-item-right">';
html += '<h2 class="layui-instant-item-title">' + item.title + '</h2>';
html += '<p class="layui-instant-item-text">' + item.create_time + '</p>';
html += '</div>';
html += '</a>';
break;
case 'message':
html += '<a data-id="' + item.id + '" data-type="message" class="layui-instant-list-item active_' + item.status + '" href="javascript:;">';
html += '<img class="layui-instant-item-icon" src="' + item.face + '">';
html += '<div class="layui-instant-item-right">';
html += '<h2 class="layui-instant-item-title">' + item.title + '</h2>';
html += '<p class="layui-instant-item-text">' + item.create_time + '</p>';
html += '</div>';
html += '</a>';
break;
case 'todo':
html += '<a data-id="' + item.id + '" data-type="todo" class="layui-instant-list-item active_' + item.status + '" href="javascript:;">';
html += '<div class="layui-instant-item-right">';
if (item.status === 0) {
html += '<span class="layui-badge pull-right">待完成</span>';
} else if (item.status === 3) {
html += '<span class="layui-badge layui-bg-green pull-right">进行中</span>';
} else {
html += '<span class="layui-badge layui-bg-gray pull-right">已完成</span>';
}
html += '<h2 class="layui-instant-item-title">' + item.title + '</h2>';
html += '<p class="layui-instant-item-text">' + item.create_time + '</p>';
html += '</div>';
html += '</a>';
break;
default:
break;
}
list.push(html);
});
}
next(list.join(''), page < data.last_page);
});
}
});
});
// 打开新窗口
$('.layui-instant-list').on('click', '.layui-instant-list-item', function () {
let that = this;
$(that).addClass('active_open');
$(that).removeClass('active_0').addClass('active_1');
let id = $(that).attr('data-id');
let type = $(that).attr('data-type');
let openURL = "{:url('/system/admin/readNotice')}?type=" + type + "&id=" + id;
parent.layer.open({
id: type + id,
type: 2,
title: instantItem[type].title,
shade: 0,
maxmin: true,
isOutAnim: false,
area: ['600px', '400px'],
offset: type === 'notice' ? 'rb' : 'none', // 可选位置
anim: instantItem[type].anim, // 可选动画
content: [openURL, 'no'],
success: function (layero, index) {
$('body').on('click', '.active_open', function (e) {
parent.layer.close(index);
$(that).removeClass('active_open');
})
}
});
});
// 清空消息点击事件
$('.instant-clear').click(function (obj) {
var that = $(this), type = that.data('type');
var findElem = $('#' + type);
// 删除元素
that.parent().prev().prev().remove();
that.parent().prev().show();
that.parent().remove();
// 替换标题
findElem.text(findElem.text().replace(/\([^\)]*\)/,''));
// 执行AJAX请求...
$.ajax({
url: "{:url('/system/admin/clearNotice')}",
type: 'post',
data: {type: type},
success: function (res) {
if (res.code === 200) {
layer.msg(res.msg);
} else {
layer.error(res.msg);
}
}
});
});
// 一键已读
$('.instant-reads').click(function (obj) {
var that = $(this), type = that.data('type');
// 执行AJAX请求...
$.ajax({
url: "{:url('/system/admin/readAllNotice')}",
type: 'post',
data: {type: type},
success: function (res) {
if (res.code === 200) {
layer.msg(res.msg);
$('.layui-instant-list-item').removeClass('active_0').addClass('active_1');
} else {
layer.error(res.msg);
}
}
});
});
});
</script>

View File

@@ -165,7 +165,7 @@
}
jquery.ajax({
url:'{:url("/system/Admin/getPermissions")}',
url:'{:url("/system/AdminGroup/getRuleCateTree")}',
type:'post',
dataType:'json',
data:{
@@ -237,7 +237,7 @@
}
jquery.ajax({
url:'{:url("/system/Admin/getPermissions")}',
url:'{:url("/system/AdminGroup/getRuleCateTree")}',
type:'post',
dataType:'json',
data:{
@@ -292,9 +292,7 @@
})
}
})
}
});
</script>

View File

@@ -358,7 +358,7 @@
event = tableThis.event;
layui.$.ajax({
url:'{:url("/system/Admin/getPermissions")}',
url:'{:url("/system/Admin/getRuleCateTree")}',
type:'post',
dataType:'json',
data:{
@@ -383,7 +383,7 @@
// 增加节点数据
post.field[event] = tree.getChecked('authTree', true);
// 开始POST提交数据
layui.$.post("{:url('/system/admin/edit" + event + "')}",
layui.$.post("{:url('/system/Admin/edit" + event + "')}",
post.field, function (res) {
if (res.code === 200) {
// 更新本地规则

View File

@@ -1,54 +0,0 @@
<include file="/public/header" />
<link href="__STATICADMIN__css/message.css" rel="stylesheet" type="text/css" />
<!-- // 重定位Style -->
<style>
.face {
margin-bottom: 3px;
}
</style>
<div id="instant-content" class="layui-card">
<div class="layui-card-body">
<div class="layui-panel">
<div class="layui-card-header">
<div class="title"><span class="titles"><img src="{$detail.face|default=''}" class="face" width="20"> </span>{$detail.nickname|default='隐藏用户'}</div>
<div class="time"><span class="times">时间:</span>{$detail.create_time}</div>
</div>
<div id="layui-info">{$detail.content|raw}</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
<button type="button" class="layui-btn layui-btn-normal" lay-open data-title="回复私信" data-url="#replyForms" data-area="500px,350px" >回复</button>
<button type="button" class="layui-btn layui-btn-danger" sa-event="closeDialog" >关闭</button>
</div>
</div>
</div>
<script type="text/html" id="replyForms">
<div class="layui-fluid layui-bg-white" >
<form action="{:url('/system/admin/saveNotice')}" class="layui-form">
<input type="text" name="type" value="message" hidden>
<input type="text" name="admin_id" value="{$detail.send_id}" hidden>
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red; ">* </span>{:__('')}</label>
<div class="layui-input-block" >
<input type="text" name="title" class="layui-input" lay-verify="required" value="" placeholder="请输入私信标题">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red; ">* </span>{:__('')}</label>
<div class="layui-input-block">
<textarea name="content" class="layui-textarea" lay-verify="required" placeholder="请输入私信内容"></textarea>
</div>
</div>
<div class="layui-footer layui-form-item layui-center " >
<button class="layui-btn layui-btn-primary" type="button" sa-event="closePageDialog" >{:__('取消')}</button>
<button class="layui-btn" lay-filter="submitPage" lay-submit>{:__('提交')}</button>
</div>
</form>
</div>
</script>
<include file="/public/footer" />

View File

@@ -1,26 +0,0 @@
<include file="/public/header" />
<link href="__STATICADMIN__css/message.css" rel="stylesheet" type="text/css" />
<!-- // 重定位Style -->
<style></style>
<div id="instant-content" class="layui-card">
<div class="layui-card-body">
<div class="layui-panel">
<div class="layui-card-header">
<div class="title"><span class="titles">🔔 </span>{$detail.title}</div>
<div class="time"><span class="times">时间:</span>{$detail.create_time}</div>
</div>
<div id="layui-info">{$detail.content|raw}</div>
<div class="layui-banner">
<p>本消息属系统通知,来源于业务流程管理系统,请勿回复</p>
<p>在系统使用过程中,如果有问题请联系网站运维组:## </p>
</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
<button type="button" class="layui-btn layui-btn-danger" sa-event="closeDialog" >关闭</button>
</div>
</div>
</div>
<include file="/public/footer" />

View File

@@ -21,7 +21,7 @@
</div>
<div class="layui-inline" >
<!-- // 默认搜索 -->
<button class="layui-btn icon-btn"
<button class="layui-btn icon-btn" type="submit"
lay-filter="treeSearch" lay-submit><i class="layui-icon layui-icon-search"></i>{:__('搜索')}
</button>
<!-- // 打开添加页面 -->
@@ -336,17 +336,8 @@
jquery.post(_pageUrl,
post.field, function(res){
if (res.code === 200) {
layer.msg(res.msg);
// 更新列数据
if (typeof(tableThis) !== 'undefined') {
if (tableThis.event === 'edit')
tableThis.update(JSON.parse(JSON.stringify(post.field)));
}else { // 添加则更新列表
renderTable(tableURL);
}
treeTable.reloadData('lay-tableList');
// 调用接口更新菜单
top.layui.admin.reloadLayout();

View File

@@ -1,32 +0,0 @@
<include file="/public/header" />
<link href="__STATICADMIN__css/message.css" rel="stylesheet" type="text/css" />
<!-- // 重定位Style -->
<style>
.face {
margin-bottom: 3px;
}
</style>
<div id="instant-content" class="layui-card">
<div class="layui-card-body">
<div class="layui-panel">
<div class="layui-card-header">
<div class="title">{$detail.title}</div>
<div class="time"><span class="times">任务创建于:</span>{$detail.create_time}</div>
</div>
<div id="layui-info">{$detail.content|raw}</div>
<div class="layui-banner">
<p>本消息属系统工作流待办流程管理</p>
<p>在系统使用过程中,如果有问题请联系网站运维组 </p>
</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
<button type="button" class="layui-btn layui-btn-checked" lay-ajax data-url="{:url('/system/admin/saveNotice')}?id={$detail.id}&status=3" >进行中</button>
<button type="button" class="layui-btn layui-btn-primary" lay-ajax data-url="{:url('/system/admin/saveNotice')}?id={$detail.id}&status=1" >已完成</button>
<button type="button" class="layui-btn layui-btn-danger" sa-event="closeDialog" >关闭</button>
</div>
</div>
</div>
<include file="/public/footer" />

View File

@@ -0,0 +1,36 @@
<include file="/public/header" />
<div class="layui-fluid layui-bg-white">
<form action="{:url('/system/AdminNotice/add')}" class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red; ">* </span>{:__('收件人')}</label>
<div class="layui-input-block">
<select name="admin_id" lay-verify="required" lay-search>
<option value=""></option>
<volist name="adminList" id="vo">
<option value="{$vo.id}">{$vo.name}</option>
</volist>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red; ">* </span>{:__('标题')}</label>
<div class="layui-input-block">
<input type="text" name="title" class="layui-input" lay-verify="required" value="" placeholder="请输入私信标题">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red; ">* </span>{:__('回复内容')}</label>
<div class="layui-input-block">
<textarea name="content" class="layui-textarea" placeholder="请输入私信内容"></textarea>
</div>
</div>
<div class="layui-footer layui-form-item layui-center ">
<button class="layui-btn layui-btn-primary" type="button" sa-event="closePageDialog">{:__('取消')}
</button>
<button class="layui-btn" lay-filter="submitIframe" lay-submit>{:__('提交')}</button>
</div>
</form>
</div>
<include file="/public/footer" />

View File

@@ -237,14 +237,7 @@
post.field, function(res){
if (res.code === 200) {
layer.msg(res.msg);
// 更新列数据
if (typeof(tableThis) !== 'undefined') {
if (tableThis.event === 'edit')
tableThis.update(JSON.parse(JSON.stringify(post.field)));
}else { // 添加则更新列表
renderTable(tableURL);
}
treeTable.reloadData('lay-tableList');
// 关闭当前窗口
layer.close(colletction.index);
}

View File

@@ -3,6 +3,9 @@
namespace app\common\model\system;
use Psr\SimpleCache\InvalidArgumentException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Model;
use app\common\library\ParseData;
use think\model\concern\SoftDelete;
@@ -81,6 +84,9 @@ class User extends Model
* @param array $data
* @return string
* @throws InvalidArgumentException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getAvatarAttr(string $value, array $data): string
{

View File

@@ -1,9 +1,11 @@
<?php
declare (strict_types=1);
namespace app\common\validate\system;
use app\admin\service\AuthService;
use think\Validate;
use app\common\model\system\Admin as AdminModel;
class Admin extends Validate
{
@@ -16,6 +18,7 @@ class Admin extends Validate
protected $rule = [
'name' => 'require|min:2|max:12|chsAlphaNum',
'pwd|密码' => 'require|min:6|max:64',
'group_id' => 'require|checkGroup',
];
@@ -34,10 +37,35 @@ class Admin extends Validate
'pwd.require' => '密码不能为空',
'pwd.min' => '密码不能少于6个字符',
'pwd.max' => '密码不能超过64个字符',
'group_id.require' => '请选择用户组',
'group_id.checkGroup' => '无权限操作',
];
// 测试验证场景
protected $scene = [
'edit' => ['name']
'add' => ['name', 'pwd', 'group_id'],
'edit' => ['name', 'group_id'],
'login' => ['name', 'pwd'],
];
/**
* 验证用户组权限
* @param $value
* @return bool
*/
protected function checkGroup($value): bool
{
$id = request()->get('id', 0);
$result = AdminModel::where('id', $id)->findOrEmpty()->toArray();
if (empty($result)) {
return true;
}
$group_id = !empty($value) ? $value . ',' . $result['group_id'] : $result['group_id'];
$group_id = array_unique(explode(',', $group_id));
$authService = AuthService::instance();
if (!$authService->checkRulesForGroup($group_id)) {
return false;
}
return true;
}
}

View File

@@ -1,8 +1,9 @@
<?php
declare (strict_types=1);
namespace app\common\validate\system;
use app\admin\service\AuthService;
use think\Validate;
use app\common\model\system\AdminGroup as AdminGroupModel;
@@ -15,6 +16,7 @@ class AdminGroup extends Validate
* @var array
*/
protected $rule = [
'id' => 'require|checkGroup',
'pid' => 'notEqId',
];
@@ -27,6 +29,13 @@ class AdminGroup extends Validate
*/
protected $message = [
'pid.notEqId' => '选择上级分类错误!',
'id.require' => '请选择用户组',
'id.checkGroup' => '无权限操作',
];
protected $scene = [
'add' => ['pid'],
'edit' => ['id', 'pid'],
];
/**
@@ -51,4 +60,22 @@ class AdminGroup extends Validate
return true;
}
/**
* 验证用户组权限
* @param $value
* @param $rule
* @param $data
* @return bool
*/
protected function checkGroup($value, $rule, $data): bool
{
$authService = AuthService::instance();
$value = explode(',', $value);
if (!$authService->checkRulesForGroup($value)) {
return false;
}
return true;
}
}

View File

@@ -1,5 +1,5 @@
<?php
declare (strict_types = 1);
namespace app\common\validate\system;

View File

@@ -56,20 +56,30 @@ class User extends Validate
/**
* 自定义验证规则
* @param $value
* @return string|bool
* @return bool
* @throws InvalidArgumentException
*/
protected function checkName($value): string|bool
protected function checkName($value): bool
{
$notAllow = saenv('user_reg_notallow');
$notAllow = explode(',', $notAllow);
if (in_array($value, $notAllow)) {
return '用户名不合法!';
return false;
}
return true;
}
public function sceneAdd(): User
{
return $this->only(['nickname', 'pwd', 'email', 'mobile']);
}
public function sceneEdit(): User
{
return $this->only(['nickname', 'email']);
}
public function sceneRegister(): User
{
return $this->only(['nickname', 'pwd']);

View File

@@ -7,10 +7,8 @@ use app\common\model\system\UserThird;
use app\common\model\system\Config;
use think\helper\Str;
use support\Cache;
use webman\Event\Event;
// 权限常量
const AUTH_CATE = 'cates';
const AUTH_RULES = 'rules';
// +----------------------------------------------------------------------
// | 常规助手函数
// +----------------------------------------------------------------------
@@ -35,9 +33,9 @@ if (!function_exists('hook')) {
* @param bool $array
* @return mixed
*/
function hook($event, $params = '', bool $array = true)
function hook($event, mixed $params = '', bool $array = true): mixed
{
$result = \webman\Event\Event::emit($event, $params, true);
$result = Event::emit($event, $params, true);
return $array ? $result : join('', $result);
}
}
@@ -1119,14 +1117,14 @@ if (!function_exists('check_admin_auth')) {
*/
function check_admin_auth($method): bool
{
if (\app\admin\library\Auth::instance()->SuperAdmin()) {
if (\app\admin\service\AuthService::instance()->SuperAdmin()) {
return true;
}
$app = '/' . request()->app;
$pattern = '#^' . $app . '#';
$method = preg_replace($pattern, '', $method, 1);
return \app\admin\library\Auth::instance()->check($method, get_admin_id());
return \app\admin\service\AuthService::instance()->permissions($method, get_admin_id());
}
}

View File

@@ -190,7 +190,7 @@ class Third extends HomeController
'ref' => input('ref', request()->server('HTTP_REFERER', '/')),
];
return $this->redirect("/third/login?" . http_build_query($buildQuery));
return $this->redirect("/index/third/login?" . http_build_query($buildQuery));
}
return $this->error('请先登录');

View File

@@ -308,12 +308,13 @@ class User extends HomeController
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
* @throws OperateException
*/
public function viewMessage(Request $request): Response
{
$id = input('id', 0);
$result = UserService::viewMessage($id, $request->userId);
return view('message_view', [
return view('/user/message_view', [
'msgInfo' => $result['msgInfo'],
'unread' => $result['unread'],
]);