diff --git a/app/AdminController.php b/app/AdminController.php index 64b9beb..51a5c15 100644 --- a/app/AdminController.php +++ b/app/AdminController.php @@ -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('退出成功!', '/'); } diff --git a/app/admin/controller/Index.php b/app/admin/controller/Index.php index 1049047..d7ef86b 100644 --- a/app/admin/controller/Index.php +++ b/app/admin/controller/Index.php @@ -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') { diff --git a/app/admin/controller/Login.php b/app/admin/controller/Login.php index b3318a1..ff87cff 100644 --- a/app/admin/controller/Login.php +++ b/app/admin/controller/Login.php @@ -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); - } } \ No newline at end of file diff --git a/app/admin/controller/system/Admin.php b/app/admin/controller/system/Admin.php index 22dc99e..33f8640 100644 --- a/app/admin/controller/system/Admin.php +++ b/app/admin/controller/system/Admin.php @@ -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,115 +110,65 @@ 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('更新管理员成功!'); - } - } + $post = request()->all(); + 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); + } + /** * 编辑权限 - * @return Response + * @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('更新权限成功!'); } /** * 编辑栏目权限 - * @return Response + * @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])) { - 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; + $adminId = input('admin_id', 0); + AdminService::updateRulesNodes($adminId, AdminEnum::ADMIN_AUTH_CATES); + return $this->success('更新权限成功!'); } /** @@ -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); } // 清理模板 diff --git a/app/admin/controller/system/AdminGroup.php b/app/admin/controller/system/AdminGroup.php index 773828b..3944ed5 100644 --- a/app/admin/controller/system/AdminGroup.php +++ b/app/admin/controller/system/AdminGroup.php @@ -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; /** @@ -22,165 +29,116 @@ use Webman\Http\Request; */ class AdminGroup extends AdminController { - // 初始化函数 + // 初始化函数 public function __construct() { parent::__construct(); - $this->model = new AdminGroupModel(); - } + $this->model = new AdminGroupModel(); + } /** * 获取资源列表 + * @throws DataNotFoundException + * @throws DbException + * @throws ModelNotFoundException */ - public function index() + public function index(): Response { - if (request()->isAjax()) { + if (request()->isAjax()) { + $params = \request()->all(); + list($count, $list) = AdminGroupService::dataList($params); + return $this->success('查询成功', '/', $list, $count); + } - $param = \request()->all(); - $param['page'] = input('page'); - $param['limit'] = input('limit'); + return view('/system/admin/group', [ + 'group' => $this->model->getListGroup() + ]); + } - // 查询条件 - $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'].'%']; - } - - // 查询数据 - $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()]); - } - - /** - * 添加角色 - */ + /** + * 添加角色 + */ 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)) { - return $this->success('添加角色成功!'); - }else { - return $this->error('添加角色失败!'); - } - } - } + if (request()->isPost()) { + $post = request()->post(); + validate(\app\common\validate\system\AdminGroup::class)->scene('add')->check($post); + AdminGroupService::add($post); + return $this->success('添加角色成功!'); + } - /** - * 编辑角色 - */ + return $this->error('添加角色失败!'); + } + + /** + * 编辑角色 + */ public function edit() { - 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('更新角色失败'); - } - } - } + if (request()->isPost()) { + $post = request()->post(); + validate(\app\common\validate\system\AdminGroup::class)->scene('edit')->check($post); + AdminGroupService::edit($post); + return $this->success('更新角色成功!'); + } - /** - * 更新权限 - */ - public function editRules() - { - if (request()->isPost()) { + return $this->error('更新角色失败!'); + } - $id = input('id'); + /** + * 权限函数接口 + * @access public + */ + public function getRuleCateTree() + { + $type = input('type', AdminEnum::ADMIN_AUTH_RULES); + return $this->authService->getRuleCatesTree($type, $this->authService->authGroup); + } - if (!is_empty($id) && is_numeric($id)) { + /** + * 更新权限 + * @return Response + * @throws OperateException + */ + public function editRules(): Response + { + $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('更新权限成功!'); + } - $rules = request()->post('rules') ?? []; - $array = [ - 'id'=>$id, - 'rules'=>implode(',',$rules) - ]; + /** + * 更新栏目 + * @return Response + * @throws OperateException + */ + public function editCates(): Response + { + $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('更新权限成功!'); + } - if (!$this->auth->checkRuleOrCateNodes($rules)) { - return $this->error('没有权限!'); - } + /** + * 删除角色/用户组 + */ + public function del(): Response + { + $id = input('id', 0); + validate(\app\common\validate\system\AdminGroup::class)->scene('edit')->check(request()->all()); + if ($id == 1) { + return $this->error('系统内置禁止删除!'); + } else if ($this->model::destroy($id)) { + return $this->success('删除角色成功!'); + } - if ($this->model->update($array)) { - return $this->success('更新权限成功!'); - } - } - - return $this->error('更新权限失败!'); - } - } - - /** - * 更新栏目 - */ - public function editCates() - { - 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('更新栏目权限失败!'); - } - } - - /** - * 删除角色/用户组 - */ - public function del() - { - $id = input('id'); - if (!empty($id) && is_numeric($id)) { - if ($id == 1) { - return $this->error('系统内置禁止删除!'); - } - if ($this->model::destroy($id)) { - return $this->success('删除角色成功!'); - } - } - - return $this->error('删除角色失败,请检查您的参数!'); - } + return $this->error('删除角色失败,请检查您的参数!'); + } } diff --git a/app/admin/controller/system/AdminRules.php b/app/admin/controller/system/AdminRules.php index 0f6f5d8..455a6c0 100644 --- a/app/admin/controller/system/AdminRules.php +++ b/app/admin/controller/system/AdminRules.php @@ -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']); - } - - $rules = list_to_tree($list,'id','pid','children',0); - return $this->success('获取成功', '/',$rules, $total); - + list($count, $list) = AdminRuleService::dataList(request()->all()); + $rules = list_to_tree($list,'id','pid','children',0); + return $this->success('获取成功', '/',$rules, $count); } return view('/system/admin/rules'); @@ -66,47 +49,43 @@ class AdminRules extends AdminController /** * 添加节点数据 + * @return Response */ - 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)) { - return $this->success('添加菜单成功!'); - }else { - return $this->error('添加菜单失败!'); - } - } + public function add(): Response + { + if (request()->isPost()) { + $post = \request()->post(); + validate(\app\common\validate\system\AdminRules::class . '.add')->check($post); + if ($this->model->create($post)) { + return $this->success('添加菜单成功!'); + } + } + return $this->error('添加菜单失败!'); } /** * 编辑节点数据 + * @return Response */ - public function edit() - { - 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('更新菜单失败'); - } - } + public function edit(): Response + { + if (request()->isPost()) { + $post = \request()->post(); + validate(\app\common\validate\system\AdminRules::class . '.edit')->check($post); + if ($this->model->update($post)) { + return $this->success('更新菜单成功!'); + } + } + return $this->error('更新菜单失败'); } - /** - * 删除节点数据 - */ - public function del() - { + /** + * 删除节点数据 + * @return Response + * @throws DbException + */ + public function del(): Response + { $id = input('id'); if (!empty($id)) { // 查询子节点 diff --git a/app/admin/controller/system/Company.php b/app/admin/controller/system/Company.php index 8cbec69..4c46948 100644 --- a/app/admin/controller/system/Company.php +++ b/app/admin/controller/system/Company.php @@ -25,9 +25,9 @@ use Webman\Http\Request; * Class Company * @package app\admin\controller\system */ -class Company extends AdminController +class Company extends AdminController { - + // 初始化函数 public function __construct() { @@ -50,7 +50,7 @@ class Company extends AdminController $post = input(); $where = array(); if (!empty($post['title'])) { - $where[] = ['title','like','%'.$post['title'].'%']; + $where[] = ['title', 'like', '%' . $post['title'] . '%']; } // 生成查询数据 @@ -58,55 +58,51 @@ class Company extends AdminController return $this->success('查询成功', null, $list, count($list)); } - return view('/system/company/index'); + return view('/system/company/index'); } /** * 添加公司信息 + * @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)){ + if (request()->isPost()) { + $post = request()->post(); + if ($this->model->create($post)) { return $this->success(); } return $this->error(); } - - return view('/system/company/add',[ - 'data'=> $this->getTableFields() + + return view('/system/company/add', [ + 'data' => $this->getTableFields() ]); } /** * 编辑公司信息 + * @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)){ + if ($this->model->update($post)) { return $this->success(); } return $this->error(); } $data = $this->model->find($id); - return view('/system/company/add',['data'=> $data]); + return view('/system/company/add', [ + 'data' => $data + ]); } } \ No newline at end of file diff --git a/app/admin/controller/system/Department.php b/app/admin/controller/system/Department.php index f2111c4..9f982d3 100644 --- a/app/admin/controller/system/Department.php +++ b/app/admin/controller/system/Department.php @@ -81,22 +81,19 @@ class Department extends AdminController /** * 添加部门数据 + * @return Response */ - public function add() - { + public function add(): Response + { + if (request()->isPost()) { + $post = request()->post(); + validate(\app\common\validate\system\Department::class.'.add')->check($post); + if ($this->model->create($post)) { + return $this->success('添加部门成功!'); + } + } - 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('添加部门失败!'); - } - } + return $this->error('添加部门失败!'); } /** @@ -104,27 +101,26 @@ class Department extends AdminController */ public function edit() { - 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('更新部门失败'); - } - } + if (request()->isPost()) { + $post = request()->post(); + validate(\app\common\validate\system\Department::class.'.edit')->check($post); + if ($this->model->update($post)) { + return $this->success('更新部门成功!'); + } + } + + return $this->error('更新部门失败'); } - /** - * 删除部门数据 - */ - public function del() - { + /** + * 删除部门数据 + * @return Response + * @throws DbException + */ + 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('当前部门存在子部门!'); diff --git a/app/admin/controller/system/Jobs.php b/app/admin/controller/system/Jobs.php index 147e1cd..141aa1d 100644 --- a/app/admin/controller/system/Jobs.php +++ b/app/admin/controller/system/Jobs.php @@ -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; /** @@ -29,11 +33,15 @@ class Jobs extends AdminController parent::__construct(); $this->model = new JobsModel(); } - + /** * 获取资源列表 + * @return Response + * @throws DataNotFoundException + * @throws DbException + * @throws ModelNotFoundException */ - public function index() + public function index(): Response { if (request()->isAjax()) { @@ -76,16 +84,12 @@ 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('添加岗位失败!'); } } + + 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 $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('删除岗位成功!'); } diff --git a/app/admin/controller/system/Plugin.php b/app/admin/controller/system/Plugin.php index bd945e8..7b6a60f 100644 --- a/app/admin/controller/system/Plugin.php +++ b/app/admin/controller/system/Plugin.php @@ -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; diff --git a/app/admin/controller/system/User.php b/app/admin/controller/system/User.php index 2b67b40..33a6e63 100644 --- a/app/admin/controller/system/User.php +++ b/app/admin/controller/system/User.php @@ -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,121 +45,52 @@ 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)) { - return $this->success('注册成功!'); - } - - return $this->error('注册失败!'); + 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)) { - return $this->success('更新成功!'); - } - - return $this->error('更新失败!'); + $post = request()->post(); + validate(\app\common\validate\system\User::class)->scene('edit')->check($post); + UserService::edit($post); + return $this->success('更新成功!'); } + return $this->error('更新失败!'); } /** diff --git a/app/admin/enums/AdminEnum.php b/app/admin/enums/AdminEnum.php new file mode 100644 index 0000000..b8331b8 --- /dev/null +++ b/app/admin/enums/AdminEnum.php @@ -0,0 +1,42 @@ + '系统通知', + self::MESSAGE => '站内消息', + self::TODO => '待办事项', + ]; +} \ No newline at end of file diff --git a/app/admin/middleware/system/AdminLogin.php b/app/admin/middleware/system/AdminLogin.php index 54da5be..a7f6444 100644 --- a/app/admin/middleware/system/AdminLogin.php +++ b/app/admin/middleware/system/AdminLogin.php @@ -1,6 +1,7 @@ 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); diff --git a/app/admin/middleware/system/AdminPermissions.php b/app/admin/middleware/system/AdminPermissions.php index dd7d5d0..d834674 100644 --- a/app/admin/middleware/system/AdminPermissions.php +++ b/app/admin/middleware/system/AdminPermissions.php @@ -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() { diff --git a/app/admin/service/AdminGroupService.php b/app/admin/service/AdminGroupService.php new file mode 100644 index 0000000..0140fe0 --- /dev/null +++ b/app/admin/service/AdminGroupService.php @@ -0,0 +1,169 @@ + 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; + } +} \ No newline at end of file diff --git a/app/admin/service/AdminNoticeService.php b/app/admin/service/AdminNoticeService.php new file mode 100644 index 0000000..2d1b471 --- /dev/null +++ b/app/admin/service/AdminNoticeService.php @@ -0,0 +1,176 @@ + 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; + } +} \ No newline at end of file diff --git a/app/admin/service/AdminRuleService.php b/app/admin/service/AdminRuleService.php new file mode 100644 index 0000000..46184f6 --- /dev/null +++ b/app/admin/service/AdminRuleService.php @@ -0,0 +1,47 @@ + 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]; + } +} \ No newline at end of file diff --git a/app/admin/service/AdminService.php b/app/admin/service/AdminService.php new file mode 100644 index 0000000..95f7907 --- /dev/null +++ b/app/admin/service/AdminService.php @@ -0,0 +1,195 @@ + 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; + } +} \ No newline at end of file diff --git a/app/admin/service/AttachmentService.php b/app/admin/service/AttachmentService.php new file mode 100644 index 0000000..09c0a58 --- /dev/null +++ b/app/admin/service/AttachmentService.php @@ -0,0 +1,54 @@ + 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]; + } +} \ No newline at end of file diff --git a/app/admin/library/Auth.php b/app/admin/service/AuthService.php similarity index 54% rename from app/admin/library/Auth.php rename to app/admin/service/AuthService.php index f81ce42..aae081b 100644 --- a/app/admin/library/Auth.php +++ b/app/admin/service/AuthService.php @@ -9,34 +9,30 @@ declare (strict_types=1); // +---------------------------------------------------------------------- // | Author: meystack 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) { - $where[] = ['status', '=', 1]; + $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', [ - 'field' => $this->authFields, - 'nodes' => $auth_nodes[$class] - ], true); - } + if (!$this->superAdmin() && !empty($authNodes[$class])) { + $menuList = Event::emit('cmsCategoryPermissions', [ + 'field' => $this->authFields, + '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'])) { - return false; - } - } - } + $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; } - -} +} \ No newline at end of file diff --git a/app/admin/service/LoginService.php b/app/admin/service/LoginService.php new file mode 100644 index 0000000..d50f71e --- /dev/null +++ b/app/admin/service/LoginService.php @@ -0,0 +1,122 @@ + 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); + } +} \ No newline at end of file diff --git a/app/admin/service/UserService.php b/app/admin/service/UserService.php new file mode 100644 index 0000000..0fa16fc --- /dev/null +++ b/app/admin/service/UserService.php @@ -0,0 +1,146 @@ + 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; + } + +} \ No newline at end of file diff --git a/app/admin/view/index/index.html b/app/admin/view/index/index.html index 8e2637f..92dc40d 100644 --- a/app/admin/view/index/index.html +++ b/app/admin/view/index/index.html @@ -79,7 +79,7 @@
  • - + diff --git a/app/admin/view/login/index.html b/app/admin/view/login/index.html index 8e55ca5..554020b 100644 --- a/app/admin/view/login/index.html +++ b/app/admin/view/login/index.html @@ -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'); } } diff --git a/app/admin/view/system/admin/bells.html b/app/admin/view/system/admin/bells.html deleted file mode 100644 index 23dcf73..0000000 --- a/app/admin/view/system/admin/bells.html +++ /dev/null @@ -1,262 +0,0 @@ - - -
    - -
      -
    • {:__('通知')}({$count['notice']})
    • -
    • {:__('私信')}({$count['message']})
    • -
    • {:__('待办')}({$count['todo']})
    • -
    - -
    -
    - - - -
    style="display:black;" style="display:none;" > -
    {:__('没有通知')}
    -
    - - - - - -
    - -
    - - - - -
    style="display:black;" style="display:none;" > -
    {:__('没有私信')}
    -
    - - - -
    - -
    - - - -
    style="display:black;" style="display:none;" > -
    {:__('没有待办')}
    -
    - - - -
    - -
    -
    - - - - \ No newline at end of file diff --git a/app/admin/view/system/admin/group.html b/app/admin/view/system/admin/group.html index dfe5625..c029242 100644 --- a/app/admin/view/system/admin/group.html +++ b/app/admin/view/system/admin/group.html @@ -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 @@ }) } }) - } - }); diff --git a/app/admin/view/system/admin/index.html b/app/admin/view/system/admin/index.html index 45f5662..21efb49 100644 --- a/app/admin/view/system/admin/index.html +++ b/app/admin/view/system/admin/index.html @@ -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) { // 更新本地规则 diff --git a/app/admin/view/system/admin/message.html b/app/admin/view/system/admin/message.html deleted file mode 100644 index 41ff1e7..0000000 --- a/app/admin/view/system/admin/message.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - -
    -
    -
    -
    -
    {$detail.nickname|default='隐藏用户'}
    -
    时间:{$detail.create_time}
    -
    -
    {$detail.content|raw}
    -
    - - -
    -
    - - - - diff --git a/app/admin/view/system/admin/notice.html b/app/admin/view/system/admin/notice.html deleted file mode 100644 index 26ff0cf..0000000 --- a/app/admin/view/system/admin/notice.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - -
    -
    -
    -
    -
    🔔 {$detail.title}
    -
    时间:{$detail.create_time}
    -
    -
    {$detail.content|raw}
    -
    -

    本消息属系统通知,来源于业务流程管理系统,请勿回复

    -

    在系统使用过程中,如果有问题请联系网站运维组:##

    -
    -
    - - -
    -
    - - diff --git a/app/admin/view/system/admin/rules.html b/app/admin/view/system/admin/rules.html index 624a92e..f10b531 100644 --- a/app/admin/view/system/admin/rules.html +++ b/app/admin/view/system/admin/rules.html @@ -21,7 +21,7 @@
    - @@ -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(); diff --git a/app/admin/view/system/admin/todo.html b/app/admin/view/system/admin/todo.html deleted file mode 100644 index 29ac29d..0000000 --- a/app/admin/view/system/admin/todo.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - -
    -
    -
    -
    -
    {$detail.title}
    -
    任务创建于:{$detail.create_time}
    -
    -
    {$detail.content|raw}
    -
    -

    本消息属系统工作流待办流程管理

    -

    在系统使用过程中,如果有问题请联系网站运维组

    -
    -
    - - -
    -
    - - \ No newline at end of file diff --git a/app/admin/view/system/admin_notice/add.html b/app/admin/view/system/admin_notice/add.html new file mode 100644 index 0000000..0fae671 --- /dev/null +++ b/app/admin/view/system/admin_notice/add.html @@ -0,0 +1,36 @@ + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + + +
    +
    + \ No newline at end of file diff --git a/app/admin/view/system/department/index.html b/app/admin/view/system/department/index.html index 6c64ed2..877f17e 100644 --- a/app/admin/view/system/department/index.html +++ b/app/admin/view/system/department/index.html @@ -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); } diff --git a/app/common/model/system/User.php b/app/common/model/system/User.php index 45cf77e..e69a902 100644 --- a/app/common/model/system/User.php +++ b/app/common/model/system/User.php @@ -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 { diff --git a/app/common/validate/system/Admin.php b/app/common/validate/system/Admin.php index 9a73405..fbf7bc6 100644 --- a/app/common/validate/system/Admin.php +++ b/app/common/validate/system/Admin.php @@ -1,43 +1,71 @@ ['规则1','规则2'...] + * 格式:'字段名' => ['规则1','规则2'...] * * @var array */ - protected $rule = [ - 'name' => 'require|min:2|max:12|chsAlphaNum', - 'pwd|密码' => 'require|min:6|max:64', + protected $rule = [ + 'name' => 'require|min:2|max:12|chsAlphaNum', + 'pwd|密码' => 'require|min:6|max:64', + 'group_id' => 'require|checkGroup', ]; /** * 定义错误信息 - * 格式:'字段名.规则名' => '错误信息' + * 格式:'字段名.规则名' => '错误信息' * * @var array */ - protected $message = [ - 'name.require' => '用户名不能为空', - 'name.min' => '用户名不能少于2个字符', - 'name.max' => '用户名不能超过12个字符', - 'name.filters' => '用户名包含禁止注册字符', - 'name.chsAlphaNum' => '用户名只能是汉字、字母和数字', - 'pwd.require' => '密码不能为空', - 'pwd.min' => '密码不能少于6个字符', - 'pwd.max' => '密码不能超过64个字符', + protected $message = [ + 'name.require' => '用户名不能为空', + 'name.min' => '用户名不能少于2个字符', + 'name.max' => '用户名不能超过12个字符', + 'name.filters' => '用户名包含禁止注册字符', + 'name.chsAlphaNum' => '用户名只能是汉字、字母和数字', + '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; + } } diff --git a/app/common/validate/system/AdminGroup.php b/app/common/validate/system/AdminGroup.php index 2e55a54..dfffce2 100644 --- a/app/common/validate/system/AdminGroup.php +++ b/app/common/validate/system/AdminGroup.php @@ -1,8 +1,9 @@ ['规则1','规则2'...] + * 格式:'字段名' => ['规则1','规则2'...] * * @var array - */ - protected $rule = [ - 'pid' => 'notEqId', + */ + protected $rule = [ + 'id' => 'require|checkGroup', + 'pid' => 'notEqId', ]; - - + + /** * 定义错误信息 - * 格式:'字段名.规则名' => '错误信息' + * 格式:'字段名.规则名' => '错误信息' * * @var array - */ - protected $message = [ - 'pid.notEqId' => '选择上级分类错误!', + */ + protected $message = [ + 'pid.notEqId' => '选择上级分类错误!', + 'id.require' => '请选择用户组', + 'id.checkGroup' => '无权限操作', + ]; + + protected $scene = [ + 'add' => ['pid'], + 'edit' => ['id', 'pid'], ]; /** @@ -36,7 +45,7 @@ class AdminGroup extends Validate * @param $data * @return bool */ - protected function notEqId($value, $rules ,$data): bool + protected function notEqId($value, $rules, $data): bool { if ($value == $data['id']) { return false; @@ -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; + } } diff --git a/app/common/validate/system/AdminRules.php b/app/common/validate/system/AdminRules.php index 79bc108..00661f8 100644 --- a/app/common/validate/system/AdminRules.php +++ b/app/common/validate/system/AdminRules.php @@ -1,5 +1,5 @@ ['规则1','规则2'...] * * @var array - */ + */ protected $rule = [ 'pid' => 'notEqId', ]; - - + + /** * 定义错误信息 * 格式:'字段名.规则名' => '错误信息' * * @var array - */ + */ protected $message = [ - 'pid.notEqId' => '选择上级分类错误!', + 'pid.notEqId' => '选择上级分类错误!', ]; /** @@ -43,4 +43,4 @@ class AdminRules extends Validate return true; } -} +} \ No newline at end of file diff --git a/app/common/validate/system/User.php b/app/common/validate/system/User.php index 0d3fd16..8442630 100644 --- a/app/common/validate/system/User.php +++ b/app/common/validate/system/User.php @@ -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']); @@ -84,4 +94,4 @@ class User extends Validate { return $this->only(['mobile', 'captcha']); } -} +} \ No newline at end of file diff --git a/app/functions.php b/app/functions.php index 7574950..e284828 100644 --- a/app/functions.php +++ b/app/functions.php @@ -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()); } } diff --git a/app/index/controller/Third.php b/app/index/controller/Third.php index 191a979..9b7fef3 100644 --- a/app/index/controller/Third.php +++ b/app/index/controller/Third.php @@ -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('请先登录'); diff --git a/app/index/controller/User.php b/app/index/controller/User.php index 7f88b25..c16111f 100644 --- a/app/index/controller/User.php +++ b/app/index/controller/User.php @@ -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'], ]);