From 20239dfb6f5cf110f605a6953225ae87a69f588d Mon Sep 17 00:00:00 2001 From: "mzl@hnxinyouhe.com" Date: Mon, 11 Aug 2025 20:09:28 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E5=9F=BA=E7=A1=80=E5=8A=9F=E8=83=BD=EF=BC=8C=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E8=8F=9C=E5=8D=95=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CorpFeishuAppController.php | 33 ++ app/admin/controller/CountryController.php | 33 ++ app/admin/controller/SystemsController.php | 16 +- app/admin/service/CorpFeishuAppService.php | 70 ++++ app/admin/service/CountryService.php | 31 ++ app/common/controller/ResourceController.php | 66 ++++ app/common/logic/CorpFeishuAppLogic.php | 11 +- app/common/logic/CountryLogic.php | 17 + app/common/logic/PermLogic.php | 148 +------- app/common/logic/ResourceLogic.php | 17 + app/common/model/CorpFeishuApp.php | 42 +-- app/common/model/InquiryLog.php | 2 +- app/common/model/Resource.php | 51 +-- app/common/service/ResourceService.php | 137 ++++---- .../traits/crud/CrudControllerTrait.php | 1 + app/common/traits/crud/CrudServiceTrait.php | 5 +- app/common/utils/Tree.php | 320 ++++++++++++++++++ app/common/validate/CorpFeishuAppValidate.php | 29 ++ app/common/validate/CountryValidate.php | 29 ++ app/common/validate/ResourceValidate.php | 29 ++ app/controller/IndexController.php | 36 +- .../controller/StatisticsController.php | 2 +- config/route.php | 42 ++- 23 files changed, 855 insertions(+), 312 deletions(-) create mode 100644 app/admin/controller/CorpFeishuAppController.php create mode 100644 app/admin/controller/CountryController.php create mode 100644 app/admin/service/CorpFeishuAppService.php create mode 100644 app/admin/service/CountryService.php create mode 100644 app/common/controller/ResourceController.php create mode 100644 app/common/logic/CountryLogic.php create mode 100644 app/common/logic/ResourceLogic.php create mode 100644 app/common/utils/Tree.php create mode 100644 app/common/validate/CorpFeishuAppValidate.php create mode 100644 app/common/validate/CountryValidate.php create mode 100644 app/common/validate/ResourceValidate.php diff --git a/app/admin/controller/CorpFeishuAppController.php b/app/admin/controller/CorpFeishuAppController.php new file mode 100644 index 0000000..59e685d --- /dev/null +++ b/app/admin/controller/CorpFeishuAppController.php @@ -0,0 +1,33 @@ +service = new CorpFeishuAppService(); + } + + /** + * 列表页数据格式化 + * + * @param array $data + * @return array + */ + protected function indexFormat($data) + { + if (isset($data['created_at'])) + $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + if (isset($data['updated_at'])) + $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); + return $data; + } +} \ No newline at end of file diff --git a/app/admin/controller/CountryController.php b/app/admin/controller/CountryController.php new file mode 100644 index 0000000..8cc8458 --- /dev/null +++ b/app/admin/controller/CountryController.php @@ -0,0 +1,33 @@ +service = new CountryService(); + } + + /** + * 列表页数据格式化 + * + * @param array $data + * @return array + */ + // protected function indexFormat($data) + // { + // if (isset($data['created_at'])) + // $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + // if (isset($data['updated_at'])) + // $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); + // return $data; + // } +} \ No newline at end of file diff --git a/app/admin/controller/SystemsController.php b/app/admin/controller/SystemsController.php index 9c300ac..3c062c5 100644 --- a/app/admin/controller/SystemsController.php +++ b/app/admin/controller/SystemsController.php @@ -22,12 +22,12 @@ class SystemsController extends BaseController * @param array $data * @return array */ - // protected function indexFormat($data) - // { - // if (isset($data['created_at'])) - // $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); - // if (isset($data['updated_at'])) - // $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); - // return $data; - // } + protected function indexFormat($data) + { + if (isset($data['created_at'])) + $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + if (isset($data['updated_at'])) + $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); + return $data; + } } \ No newline at end of file diff --git a/app/admin/service/CorpFeishuAppService.php b/app/admin/service/CorpFeishuAppService.php new file mode 100644 index 0000000..e64631b --- /dev/null +++ b/app/admin/service/CorpFeishuAppService.php @@ -0,0 +1,70 @@ +validator; + } + + /** + * 构建查询条件 + */ + protected function buildQueryConfig(Request $request, string $scene = 'index'): array + { + $p = $request->all(); + + $config = []; + $config['model'] = $this->modelClass; + switch ($scene) { + case 'index': + $config['where']['status'] = 1; + $config['order']['sort'] = 'desc'; + $config['order']['id'] = 'desc'; + + $config['with']['corpInfo'][] = 'name'; + $config['with']['systemInfo'][] = 'name'; + break; + case 'show': + $config['where']['id'] = $p['id']; + $config['where']['status'] = 1; + + $config['with']['corpInfo'][] = 'name'; + $config['with']['systemInfo'][] = 'name'; + break; + case 'store': + break; + case 'update': + $config['where']['id'] = $p['id']; + break; + case 'destroy': + $config['where']['id'] = $p['id']; + break; + } + + return $config; + } +} \ No newline at end of file diff --git a/app/admin/service/CountryService.php b/app/admin/service/CountryService.php new file mode 100644 index 0000000..4139d97 --- /dev/null +++ b/app/admin/service/CountryService.php @@ -0,0 +1,31 @@ +validator; + } +} \ No newline at end of file diff --git a/app/common/controller/ResourceController.php b/app/common/controller/ResourceController.php new file mode 100644 index 0000000..4d81058 --- /dev/null +++ b/app/common/controller/ResourceController.php @@ -0,0 +1,66 @@ +service = new ResourceService(); + } + + /** + * 列表页数据格式化 + * + * @param array $data + * @return array + */ + protected function allFormat($data) + { + if (isset($data['created_at'])) + $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + if (isset($data['updated_at'])) + $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); + return $data; + } + + /** + * 资源树形结构 + */ + public function listTree(Request $request) + { + try { + $raw = $this->service->serviceListAll($request); + $data = $this->transformData($raw, method_exists($this, 'allFormat') + ? [$this, 'allFormat'] + : null); + return $this->success($data); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } + + /** + * 菜单 + */ + public function menuList(Request $request) + { + try { + $raw = $this->service->serviceMenuList($request); + $data = $this->transformData($raw, method_exists($this, 'allFormat') + ? [$this, 'allFormat'] + : null); + return $this->success($data); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/common/logic/CorpFeishuAppLogic.php b/app/common/logic/CorpFeishuAppLogic.php index e246316..59838c3 100644 --- a/app/common/logic/CorpFeishuAppLogic.php +++ b/app/common/logic/CorpFeishuAppLogic.php @@ -2,15 +2,16 @@ namespace app\common\logic; +use app\common\traits\crud\CrudLogicTrait; use app\common\model\CorpFeishuApp; class CorpFeishuAppLogic { - + use CrudLogicTrait; - public function getFeishuApp($corpId, $systemId) - { - return CorpFeishuApp::where('corp_id', $corpId)->where('system_id', $systemId)->first(['id', 'corp_id', 'name', 'app_id', 'r_url', 'state']); - } + /** + * 指定当前要操作的模型 + */ + protected string $modelClass = CorpFeishuApp::class; } \ No newline at end of file diff --git a/app/common/logic/CountryLogic.php b/app/common/logic/CountryLogic.php new file mode 100644 index 0000000..0a753ee --- /dev/null +++ b/app/common/logic/CountryLogic.php @@ -0,0 +1,17 @@ +roles as $role) { $all = $all->merge( $role->resources->filter(function ($resource) use($system) { - // var_dump($resource->toArray()); // 只保留需要权限认证的资源(或公共资源) return !$resource->no_auth && ($system->id == $resource->system_id || $resource->system_id == 0); }) @@ -64,151 +63,6 @@ class PermLogic * @param string $parentPath 父级完整路径(用于递归) * @return array */ - public function buildTree_bak($resources, int $parentId = 0, string $parentPath = ''): array - { - $tree = []; - - foreach ($resources as $node) { - // 只处理目录和菜单,不把 permission 当作菜单节点 - if ($node->parent_id !== $parentId || $node->type === 'permission') { - continue; - } - - // —— 拼接当前节点的完整路径 —— - $currentPath = rtrim($parentPath, '/'); - if (!empty($node->url)) { - $urlSegment = ltrim($node->url, '/'); - $currentPath = $currentPath === '' - ? $urlSegment - : "{$currentPath}/{$urlSegment}"; - } - - // —— 递归构建子节点 —— - // 这里只会继续收目录和菜单,permission 永远不会进入此方法 - $children = $this->buildTree($resources, $node->id, $currentPath); - - // —— 本级权限列表 —— - $authList = $resources - ->filter(fn($r) => $r->type === 'permission' && $r->parent_id === $node->id) - ->map(fn($r) => [ - 'id' => $r->id, - 'title' => $r->name, - 'auth_mark' => $r->code, - ]) - ->values() - ->all(); - - // —— 判断是否有子目录或子菜单 —— - $hasChildrenMenu = ! empty($children); - - // —— 计算 component 字段 —— - if ($hasChildrenMenu) { - if ($node->type === 'menu' && !empty($node->url)) { - // menu 类型且自身有 url,用自身 url(加前导 slash) - $componentValue = '/' . ltrim($node->url, '/'); - } else { - // 其它含子项的节点,固定 Layout 组件 - $componentValue = '/index/index'; - } - } else { - // 叶子节点:拼接路径,确保以 slash 开头 - $componentValue = $currentPath !== '' - ? '/' . ltrim($currentPath, '/') - : ''; - } - - $tree[] = [ - 'id' => $node->id, - 'name' => $node->name, - 'path' => $node->url, - 'component' => $componentValue, - 'meta' => [ - 'title' => $node->name, - 'icon' => $node->icon, - 'keepAlive' => true, - 'authList' => $authList, - 'openType' => $node->open_type, - 'isHide' => $node->is_hide == 0 ? false : true, - 'isHideTab' => $node->is_hide_tab == 0 ? false : true - ], - 'children' => $children - ]; - } - - return $tree; - } - public function buildTree_bak2($resources, int $parentId = 0, string $parentPath = ''): array - { - $tree = []; - - foreach ($resources as $node) { - if ($node->parent_id !== $parentId) { - continue; - } - - // —— 拼接当前节点的完整路径 —— - $currentPath = $parentPath; - // 去掉末尾多余 slash - $currentPath = rtrim($currentPath, '/'); - - if (!empty($node->url)) { - // 如果当前节点有 url,则拼接 - $urlSegment = ltrim($node->url, '/'); - $currentPath = $currentPath === '' - ? $urlSegment - : "{$currentPath}/{$urlSegment}"; - } - - // —— 递归构建子节点 —— - $children = []; - if ($node->type === 'directory') { - $children = $this->buildTree($resources, $node->id, $currentPath); - } - - // —— 收集本级的 permission 权限列表 —— - $authList = $resources - ->filter(fn($r) => $r->type === 'permission' && $r->parent_id === $node->id) - ->map(fn($r) => [ - 'id' => $r->id, - 'title' => $r->name, - 'auth_mark' => $r->code, - ]) - ->values() - ->all(); - - // —— 判断是否有子菜单/目录 —— - $hasChildrenMenu = $resources - ->where('parent_id', $node->id) - ->whereIn('type', ['directory', 'menu']) - ->isNotEmpty(); - - // —— 计算 component 字段 —— - if ($hasChildrenMenu) { - // 只要有子项,就一律显示顶层 Layout 组件 - $componentValue = '/index/index'; - } else { - // 叶子节点:如果定义了 url,就使用拼接后的路径;否则用占位符(这里用空串,你可替换) - $componentValue = $currentPath !== '' ? $currentPath : ''; - } - - $tree[] = [ - 'id' => $node->id, - 'name' => $node->name, - 'path' => $node->url, - 'component' => $componentValue, - 'meta' => [ - 'title' => $node->name, - 'icon' => $node->icon, - 'keepAlive' => true, - 'authList' => $authList, - 'openType' => $node->open_type, - ], - 'children' => $children, - ]; - } - - return $tree; - } public function buildTree($resources, int $parentId = 0, string $parentPath = ''): array { $tree = []; @@ -258,7 +112,7 @@ class PermLogic 'meta' => [ 'title' => $node->name, 'icon' => $node->icon, - 'keepAlive' => true, + 'keepAlive' => $node->keep_alive == 1 ? true : false, 'authList' => $authList, 'openType' => $node->open_type, 'isHide' => $node->is_hide == 0 ? false : true, diff --git a/app/common/logic/ResourceLogic.php b/app/common/logic/ResourceLogic.php new file mode 100644 index 0000000..cbcb14e --- /dev/null +++ b/app/common/logic/ResourceLogic.php @@ -0,0 +1,17 @@ +hasOne(Corp::class, 'id', 'corp_id'); + } + + public function systemInfo() + { + return $this->hasOne(Systems::class, 'id', 'system_id'); + } +} \ No newline at end of file diff --git a/app/common/model/InquiryLog.php b/app/common/model/InquiryLog.php index 68926aa..798b267 100644 --- a/app/common/model/InquiryLog.php +++ b/app/common/model/InquiryLog.php @@ -62,7 +62,7 @@ class InquiryLog extends Model public function recipientInfo() { - return $this->hasOne(User::class, 'id', 'recipient'); + return $this->hasOne(User::class, 'id', 'recipient')->where('status', 1); } public function channelInfo() diff --git a/app/common/model/Resource.php b/app/common/model/Resource.php index 6fc54d9..bff7b0a 100644 --- a/app/common/model/Resource.php +++ b/app/common/model/Resource.php @@ -4,20 +4,6 @@ namespace app\common\model; use support\Model; -/** - * resources 资源表:目录/菜单/权限 - * @property integer $id 资源ID(主键) - * @property string $name 资源名称 - * @property string $type 资源类型 - * @property string $code 资源编码(权限标识) - * @property integer $parent_id 父资源ID - * @property string $url 路由 path 或 外链 URL - * @property string $icon 图标,仅目录/菜单有效 - * @property string $open_type 菜单打开方式 - * @property integer $sort 排序 - * @property string $created_at - * @property string $updated_at - */ class Resource extends Model { /** @@ -49,32 +35,15 @@ class Resource extends Model public $timestamps = true; - // 所属系统 - public function system() - { - return $this->belongsTo(Systems::class, 'system_id', 'id'); - } + protected $dateFormat = 'U'; - // 拥有该资源的角色 - public function roles() - { - return $this->belongsToMany(Role::class, 'role_resources', 'resource_id', 'role_id'); - } + /** + * 允许自动填充模型字段 + */ + protected $fillable = ['id', 'system_id', 'name', 'desc', 'type', 'code', 'parent_id', 'url', 'icon', 'open_type', 'is_hide', 'is_hide_tab', 'no_auth', 'is_home', 'instance', 'sort', 'status', 'created_at', 'updated_at']; - // 拥有该资源的用户(特殊补权) - public function users() - { - return $this->belongsToMany(User::class, 'user_resources', 'resource_id', 'user_id'); - } - - // 递归 - public function parent() - { - return $this->belongsTo(self::class, 'parent_id'); - } - - public function children() - { - return $this->hasMany(self::class, 'parent_id'); - } -} + /** + * 不允许自动填充模型字段 + */ + protected $guarded = []; +} \ No newline at end of file diff --git a/app/common/service/ResourceService.php b/app/common/service/ResourceService.php index dce3bb1..7d52eff 100644 --- a/app/common/service/ResourceService.php +++ b/app/common/service/ResourceService.php @@ -2,82 +2,93 @@ namespace app\common\service; -use app\model\User; -use app\model\Role; -use app\model\Resource; +use app\common\validate\ResourceValidate; +use app\common\traits\crud\CrudServiceTrait; +use app\common\model\Resource; +use app\common\utils\Tree; +use support\Request; class ResourceService { - /** - * 获取用户可见菜单树 - */ - public static function getMenuTreeForUser($userId) - { - $menuList = self::getUserMenus($userId); - // 转树 - return self::buildTree($menuList); - } + + use CrudServiceTrait; /** - * 获取用户所有有权限的菜单资源(type=menu) + * 指定当前要操作的模型 */ - public static function getUserMenus($userId) - { - $user = User::with('roles.resources')->find($userId); - if (!$user) return []; - // 合并所有角色下的菜单资源 - $allMenus = []; - foreach ($user->roles as $role) { - foreach ($role->resources as $res) { - if ($res->type === 'menu') { - $allMenus[$res->id] = $res; - } - } - } - return array_values($allMenus); // 去重后返回 - } + protected string $modelClass = Resource::class; /** - * 获取用户所有有权限的按钮/功能权限 code + * 验证器 */ - public static function getButtonPermissionCodesForUser($userId) - { - $user = User::with('roles.resources')->find($userId); - if (!$user) return []; - $codes = []; - foreach ($user->roles as $role) { - foreach ($role->resources as $res) { - if ($res->type === 'button' && $res->code) { - $codes[$res->code] = true; - } - } - } - return array_keys($codes); // 去重后返回权限code数组 - } + protected $validator = ResourceValidate::class; /** - * 递归构建菜单树 - * @param Resource[] $list - * @param int $parentId - * @return array + * 获取验证器 */ - protected static function buildTree($list, $parentId = 0) + public function getValidator() { - $tree = []; - foreach ($list as $item) { - if ($item->parent_id == $parentId) { - $children = self::buildTree($list, $item->id); - $arr = [ - 'id' => $item->id, - 'name' => $item->name, - 'path' => $item->url, - 'icon' => $item->icon ?? null, - 'code' => $item->code, - 'children' => $children, - ]; - $tree[] = $arr; - } + return new $this->validator; + } + + + protected function buildQueryConfig(Request $request, string $scene = 'default'): array + { + $p = $request->all(); + + $config = []; + $config['model'] = $this->modelClass; + switch ($scene) { + case 'default': + $config['where']['status'] = 1; + $config['order']['sort'] = 'asc'; + $config['order']['id'] = 'asc'; + break; + case 'menuList': + $config['where']['status'] = 1; + $config['where']['type'] = ['!=', 'permission']; + $config['order']['sort'] = 'asc'; + $config['order']['id'] = 'asc'; + break; + case 'index': + $config['where']['status'] = 1; + $config['order']['sort'] = 'asc'; + $config['order']['id'] = 'asc'; + break; + case 'show': + $config['where']['id'] = $p['id']; + $config['where']['status'] = 1; + break; + case 'store': + break; + case 'update': + $config['where']['id'] = $p['id']; + break; + case 'destroy': + $config['where']['id'] = $p['id']; + break; } - return $tree; + + return $config; + } + + public function serviceMenuList(Request $request) + { + $config = $this->buildQueryConfig($request, 'menuList'); + $result = $this->logicListAll($config); + return $this->postProcess('MenuList', $result); + } + + + protected function afterServiceListAll($data) + { + $data = Tree::buildWithAuthListAndReference($data->toArray()); + return $data; + } + + protected function afterServiceMenuList($data) + { + $data = Tree::buildWithReference($data->toArray()); + return $data; } } \ No newline at end of file diff --git a/app/common/traits/crud/CrudControllerTrait.php b/app/common/traits/crud/CrudControllerTrait.php index ca30ba3..5960d77 100644 --- a/app/common/traits/crud/CrudControllerTrait.php +++ b/app/common/traits/crud/CrudControllerTrait.php @@ -62,6 +62,7 @@ trait CrudControllerTrait $res = $this->service->serviceStore($request, $data); return $this->success($res, '创建成功'); } catch (\Throwable $e) { + dpr($e); return $this->error($e->getMessage()); } } diff --git a/app/common/traits/crud/CrudServiceTrait.php b/app/common/traits/crud/CrudServiceTrait.php index 344756d..dd4536f 100644 --- a/app/common/traits/crud/CrudServiceTrait.php +++ b/app/common/traits/crud/CrudServiceTrait.php @@ -1,6 +1,7 @@ buildQueryConfig($request, 'default'); $result = $this->logicListAll($config); } - return $this->postProcess('List', $result); + return $this->postProcess('ListAll', $result); } /** 查看单条 */ @@ -188,6 +189,6 @@ trait CrudServiceTrait */ // protected function complexQuery(array $params): array // { - // throw new \LogicException('请在子类实现 complexQuery'); + // throw new BusinessException('请在子类实现 complexQuery'); // } } \ No newline at end of file diff --git a/app/common/utils/Tree.php b/app/common/utils/Tree.php new file mode 100644 index 0000000..6322e36 --- /dev/null +++ b/app/common/utils/Tree.php @@ -0,0 +1,320 @@ + $item) { + if ($item[$pidField] == 0) { + $tree[] = &$items[$id]; + } else { + if (isset($items[$item[$pidField]])) { + $items[$id]['level'] = $items[$item[$pidField]]['level'] + 1; + + if (!isset($items[$item[$pidField]]['children'])) { + $items[$item[$pidField]]['children'] = []; + } + + $items[$item[$pidField]]['children'][] = &$items[$id]; + } + } + } + + return $tree; + } + + /** + * 将树形结构扁平化为列表(带层级前缀) + * + * @param array $tree 树形结构数据 + * @param string $prefix 前缀字符 + * @param string $field 显示字段名 + * @param int $level 层级 + * @return array + */ + public static function flattenWithPrefix(array $tree, string $prefix = '--', string $field = 'name', int $level = 0): array + { + $result = []; + + foreach ($tree as $item) { + $item[$field . '_with_prefix'] = str_repeat($prefix, $item['level']) . $item[$field]; + $result[] = $item; + + if (isset($item['children']) && !empty($item['children'])) { + $children = static::flattenWithPrefix($item['children'], $prefix, $field, $item['level'] + 1); + $result = array_merge($result, $children); + } + } + + return $result; + } + + /** + * 根据父ID查找所有子节点(包括子孙节点) + * + * @param array $data 数据列表 + * @param int $parentId 父级ID + * @param string $pidField 父级字段名 + * @param string $idField ID字段名 + * @return array + */ + public static function findChildren(array $data, int $parentId, string $pidField = 'parent_id', string $idField = 'id'): array + { + $children = []; + + foreach ($data as $item) { + if ($item[$pidField] == $parentId) { + $children[] = $item; + $grandChildren = static::findChildren($data, $item[$idField], $pidField, $idField); + $children = array_merge($children, $grandChildren); + } + } + + return $children; + } + + /** + * 获取指定节点的所有父级节点 + * + * @param array $data 数据列表 + * @param int $id 当前节点ID + * @param string $pidField 父级字段名 + * @param string $idField ID字段名 + * @return array + */ + public static function getParents(array $data, int $id, string $pidField = 'parent_id', string $idField = 'id'): array + { + $parents = []; + + foreach ($data as $item) { + if ($item[$idField] == $id) { + if ($item[$pidField] != 0) { + $parents[] = $item; + $parentParents = static::getParents($data, $item[$pidField], $pidField, $idField); + $parents = array_merge($parents, $parentParents); + } + break; + } + } + + return $parents; + } + + /** + * 获取指定节点的子孙节点ID列表 + * + * @param array $data 数据列表 + * @param int $parentId 父级ID + * @param string $pidField 父级字段名 + * @param string $idField ID字段名 + * @return array + */ + public static function getChildrenIds(array $data, int $parentId, string $pidField = 'parent_id', string $idField = 'id'): array + { + $ids = []; + $children = static::findChildren($data, $parentId, $pidField, $idField); + + foreach ($children as $child) { + $ids[] = $child[$idField]; + } + + return $ids; + } + + /** + * 检查是否有子节点 + * + * @param array $data 数据列表 + * @param int $parentId 父级ID + * @param string $pidField 父级字段名 + * @return bool + */ + public static function hasChildren(array $data, int $parentId, string $pidField = 'parent_id'): bool + { + foreach ($data as $item) { + if ($item[$pidField] == $parentId) { + return true; + } + } + + return false; + } + + + /** + * 构建带有权限列表的资源树(权限不显示在树结构中) + * + * @param array $data 资源数据列表 + * @param int $parentId 父级ID + * @param string $pidField 父级字段名 + * @param string $idField ID字段名 + * @param string $typeField 类型字段名 + * @param string $permissionType 权限类型标识 + * @param int $level 当前层级 + * @return array + */ + public static function buildWithAuthList( + array $data, + int $parentId = 0, + string $pidField = 'parent_id', + string $idField = 'id', + string $typeField = 'type', + string $permissionType = 'permission', + int $level = 0 + ): array { + $tree = []; + + foreach ($data as $item) { + // 只处理指定父级的非权限节点 + if ($item[$pidField] == $parentId && $item[$typeField] != $permissionType) { + $item['level'] = $level; + + // 递归处理子节点(非权限类型) + $children = static::buildWithAuthList($data, $item[$idField], $pidField, $idField, $typeField, $permissionType, $level + 1); + + if (!empty($children)) { + $item['children'] = $children; + } + + // 收集当前节点下的所有权限 + $item['auth_list'] = static::collectDirectPermissions($data, $item[$idField], $pidField, $typeField, $permissionType); + + $tree[] = $item; + } + } + + return $tree; + } + + /** + * 收集指定节点下的直接权限项(只收集直接子节点中的权限) + * + * @param array $data 数据列表 + * @param int $parentId 父级ID + * @param string $pidField 父级字段名 + * @param string $typeField 类型字段名 + * @param string $permissionType 权限类型标识 + * @return array + */ + public static function collectDirectPermissions( + array $data, + int $parentId, + string $pidField = 'parent_id', + string $typeField = 'type', + string $permissionType = 'permission' + ): array { + $permissions = []; + + foreach ($data as $item) { + // 收集直接子节点中的权限类型 + if ($item[$pidField] == $parentId && $item[$typeField] == $permissionType) { + $permissions[] = $item; + } + } + + return $permissions; + } + + /** + * 使用引用方式构建带有权限列表的资源树(权限不显示在树结构中) + * + * @param array $data 资源数据列表 + * @param string $pidField 父级字段名 + * @param string $idField ID字段名 + * @param string $typeField 类型字段名 + * @param string $permissionType 权限类型标识 + * @return array + */ + public static function buildWithAuthListAndReference( + array $data, + string $pidField = 'parent_id', + string $idField = 'id', + string $typeField = 'type', + string $permissionType = 'permission' + ): array { + $items = []; + $tree = []; + + // 建立以id为索引的数组(只包含非权限节点) + foreach ($data as $item) { + if ($item[$typeField] != $permissionType) { + $item['level'] = 0; + $items[$item[$idField]] = $item; + } + } + + // 构建树形结构 + foreach ($items as $id => $item) { + if ($item[$pidField] == 0) { + $tree[] = &$items[$id]; + } else { + if (isset($items[$item[$pidField]])) { + $items[$id]['level'] = $items[$item[$pidField]]['level'] + 1; + + if (!isset($items[$item[$pidField]]['children'])) { + $items[$item[$pidField]]['children'] = []; + } + + $items[$item[$pidField]]['children'][] = &$items[$id]; + } + } + } + + // 为每个节点添加权限列表 + foreach ($items as &$item) { + $item['auth_list'] = static::collectDirectPermissions($data, $item[$idField], $pidField, $typeField, $permissionType); + } + + return $tree; + } +} \ No newline at end of file diff --git a/app/common/validate/CorpFeishuAppValidate.php b/app/common/validate/CorpFeishuAppValidate.php new file mode 100644 index 0000000..d055d65 --- /dev/null +++ b/app/common/validate/CorpFeishuAppValidate.php @@ -0,0 +1,29 @@ + [ + + ], + + 'update' => [ + + ] + ]; +} \ No newline at end of file diff --git a/app/common/validate/CountryValidate.php b/app/common/validate/CountryValidate.php new file mode 100644 index 0000000..d2a413b --- /dev/null +++ b/app/common/validate/CountryValidate.php @@ -0,0 +1,29 @@ + [ + + ], + + 'update' => [ + + ] + ]; +} \ No newline at end of file diff --git a/app/common/validate/ResourceValidate.php b/app/common/validate/ResourceValidate.php new file mode 100644 index 0000000..ea2646e --- /dev/null +++ b/app/common/validate/ResourceValidate.php @@ -0,0 +1,29 @@ + [ + + ], + + 'update' => [ + + ] + ]; +} \ No newline at end of file diff --git a/app/controller/IndexController.php b/app/controller/IndexController.php index 77c5622..6cd6d6a 100644 --- a/app/controller/IndexController.php +++ b/app/controller/IndexController.php @@ -75,27 +75,27 @@ class IndexController public function createResource() { $options = [ - // 'controller' => [ - // 'module' => 'inquiry', - // 'name' => 'country' - // ], + 'controller' => [ + 'module' => 'common', + 'name' => 'resources' + ], 'model' => [ 'module' => 'common', - 'name' => 'email_parsed_result' + 'name' => 'resources' ], - // 'service' => [ - // 'module' => 'inquiry', - // 'name' => 'country' - // ], - // 'logic' => [ - // 'module' => 'inquiry', - // 'name' => 'country' - // ], - // 'validate' => [ - // 'module' => 'inquiry', - // 'name' => 'country' - // ], - 'table' => 'email_parsed_result' + 'service' => [ + 'module' => 'common', + 'name' => 'resources' + ], + 'logic' => [ + 'module' => 'common', + 'name' => 'resources' + ], + 'validate' => [ + 'module' => 'common', + 'name' => 'resources' + ], + 'table' => 'resources' ]; $result = (new Generate($options))->doGenerate(); diff --git a/app/inquiry/controller/StatisticsController.php b/app/inquiry/controller/StatisticsController.php index 0e37719..8412715 100644 --- a/app/inquiry/controller/StatisticsController.php +++ b/app/inquiry/controller/StatisticsController.php @@ -101,7 +101,7 @@ class StatisticsController extends BaseController { $list = InquiryLog::with(["recipientInfo"]) ->where("recipient", ">", 0) - ->whereNotIn('recipient', [1,5,10,11,13,15,16,17,19,74,75,78,141,147]) + ->whereNotIn('recipient', [1,5,10,11,13,155,16,17,19,74,75,78,141,147]) ->select('recipient', Db::raw('COUNT(*) as totals')) ->groupBy('recipient') ->get(); diff --git a/config/route.php b/config/route.php index 7ad0f19..5e1afa6 100644 --- a/config/route.php +++ b/config/route.php @@ -72,13 +72,6 @@ Route::group('/admin', function () { Route::any('/destroy', [app\admin\controller\RoleController::class, 'destroy']); }); - // 用户 - Route::group('/user', function () { - Route::any('/list', [app\admin\controller\UserController::class, 'index']); - Route::any('/show', [app\admin\controller\UserController::class, 'show']); - Route::any('/update', [app\admin\controller\UserController::class, 'update']); - }); - // 公司 Route::group('/corp', function () { Route::any('/list', [app\admin\controller\CorpController::class, 'index']); @@ -88,6 +81,41 @@ Route::group('/admin', function () { Route::any('/destroy', [app\admin\controller\CorpController::class, 'destroy']); }); + // 系统 + Route::group('/systems', function () { + Route::any('/list', [app\admin\controller\SystemsController::class, 'index']); + Route::any('/show', [app\admin\controller\SystemsController::class, 'show']); + Route::any('/store', [app\admin\controller\SystemsController::class, 'store']); + Route::any('/update', [app\admin\controller\SystemsController::class, 'update']); + Route::any('/destroy', [app\admin\controller\SystemsController::class, 'destroy']); + }); + + // 飞书应用 + Route::group('/corp/feishu', function () { + Route::any('/list', [app\admin\controller\CorpFeishuAppController::class, 'index']); + Route::any('/show', [app\admin\controller\CorpFeishuAppController::class, 'show']); + Route::any('/store', [app\admin\controller\CorpFeishuAppController::class, 'store']); + Route::any('/update', [app\admin\controller\CorpFeishuAppController::class, 'update']); + Route::any('/destroy', [app\admin\controller\CorpFeishuAppController::class, 'destroy']); + }); + + // 资源 + Route::group('/resources', function () { + Route::any('/list/tree', [app\common\controller\ResourceController::class, 'listTree']); + Route::any('/show', [app\common\controller\ResourceController::class, 'show']); + Route::any('/store', [app\common\controller\ResourceController::class, 'store']); + Route::any('/update', [app\common\controller\ResourceController::class, 'update']); + Route::any('/destroy', [app\common\controller\ResourceController::class, 'destroy']); + Route::any('/list/menu', [app\common\controller\ResourceController::class, 'menuList']); + }); + + // 用户 + Route::group('/user', function () { + Route::any('/list', [app\admin\controller\UserController::class, 'index']); + Route::any('/show', [app\admin\controller\UserController::class, 'show']); + Route::any('/update', [app\admin\controller\UserController::class, 'update']); + }); + // 询单 Route::group('/inquiry', function () { Route::any('/list', [app\inquiry\controller\InquiryLogController::class, 'index']); From 360aeec0e1ba95011b73af19059ec0ba23a0c10d Mon Sep 17 00:00:00 2001 From: "mzl@hnxinyouhe.com" Date: Tue, 12 Aug 2025 15:26:17 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=90=8E=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/controller/RoleController.php | 99 +++--------------- app/admin/controller/UserController.php | 87 +++++++++++----- app/admin/logic/UserLogic.php | 80 +++++++++++++++ app/admin/service/RoleService.php | 10 ++ app/admin/service/UserService.php | 25 +++++ app/common/controller/ResourceController.php | 16 +++ app/common/controller/UserController.php | 100 +++++++++---------- app/common/logic/ResourceLogic.php | 20 ++++ app/common/logic/RoleLogic.php | 79 ++++++++++++++- app/common/service/ResourceService.php | 19 ++++ config/route.php | 4 + 11 files changed, 372 insertions(+), 167 deletions(-) diff --git a/app/admin/controller/RoleController.php b/app/admin/controller/RoleController.php index 691e070..f73f07d 100644 --- a/app/admin/controller/RoleController.php +++ b/app/admin/controller/RoleController.php @@ -5,6 +5,7 @@ namespace app\admin\controller; use app\common\controller\BaseController; use app\admin\service\RoleService; use app\common\traits\crud\CrudControllerTrait; +use support\Request; class RoleController extends BaseController { @@ -27,91 +28,15 @@ class RoleController extends BaseController return $data; } - // /** - // * 获取角色列表 - // */ - // public function list(Request $request) - // { - // try { - // $params = $request->all(); - // $result = (new RoleService())->getRoleList($params); - // // 定义后处理器 - // $postProcessor = function($formattedData) { - // if (isset($formattedData['created_at'])) - // $formattedData['created_at'] = date('Y-m-d H:i:s', $formattedData['created_at']); - // if (isset($formattedData['updated_at'])) - // $formattedData['updated_at'] = date('Y-m-d H:i:s', $formattedData['updated_at']); - // return $formattedData; - // }; - // return $this->success($this->transformData($result, $postProcessor), '角色列表获取成功'); - // } catch (\Throwable $e) { - // return $this->error($e->getMessage()); - // } - // } - // /** - // * 获取角色详情 - // */ - // public function detail(Request $request) - // { - // try { - // $roleId = $request->get('role_id'); - // if (!$roleId) { - // return $this->error('缺少角色ID', 422); - // } - // $result = (new RoleService())->getRoleDetail($roleId); - // return $this->success($result, '角色详情获取成功'); - // } catch (\Throwable $e) { - // return $this->error($e->getMessage()); - // } - // } - - // /** - // * 增加角色 - // */ - // public function create(Request $request) - // { - // try { - // $data = $this->validate(new RoleValidate(), $request->post(), 'role_create'); - // $result = (new RoleService())->createRole($data); - // return $this->success($result, '角色创建成功'); - // } catch (\think\exception\ValidateException $e) { - // return $this->error($e->getError(), 422); - // } catch (\Throwable $e) { - // return $this->error($e->getMessage()); - // } - // } - - // /** - // * 修改角色 - // */ - // public function update(Request $request) - // { - // try { - // $data = $this->validate(new RoleValidate(), $request->post(), 'role_update'); - // $result = (new RoleService())->updateRole($data); - // return $this->success($result, '角色更新成功'); - // } catch (\think\exception\ValidateException $e) { - // return $this->error($e->getError(), 422); - // } catch (\Throwable $e) { - // return $this->error($e->getMessage()); - // } - // } - - // /** - // * 删除角色 - // */ - // public function delete(Request $request) - // { - // try { - // $roleId = $request->get('role_id'); - // if (!$roleId) { - // return $this->error('缺少角色ID', 422); - // } - // (new RoleService())->deleteRole($roleId); - // return $this->success([], '角色删除成功'); - // } catch (\Throwable $e) { - // return $this->error($e->getMessage()); - // } - // } -} + public function menuResource(Request $request) + { + try { + $data = $this->validate($this->service->getValidator(), $request->post(), 'allocation'); + $res = $this->service->menuResource($request, $data); + return $this->success($res); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/admin/controller/UserController.php b/app/admin/controller/UserController.php index dfcebd7..ae596e3 100644 --- a/app/admin/controller/UserController.php +++ b/app/admin/controller/UserController.php @@ -6,6 +6,7 @@ use app\common\model\Corp; use app\common\traits\crud\CrudControllerTrait; use app\admin\service\UserService; use app\crm\model\Customer; +use support\Request; class UserController extends BaseController { @@ -24,32 +25,66 @@ class UserController extends BaseController * @param array $data * @return array */ - protected function indexFormat($data) - { - if(isset($data['records'])){ - return $data; - } - $data['sex_txt'] = ''; - if (isset($data['sex']) && $data['sex'] == 1){ - $data['sex_txt'] = '男'; - }elseif(isset($data['sex']) && $data['sex'] == 2){ - $data['sex_txt'] = '女'; - } + protected function indexFormat($data) + { + if(isset($data['records'])){ + return $data; + } + $data['sex_txt'] = ''; + if (isset($data['sex']) && $data['sex'] == 1){ + $data['sex_txt'] = '男'; + }elseif(isset($data['sex']) && $data['sex'] == 2){ + $data['sex_txt'] = '女'; + } - switch ($data['status']){ - case 1: - $data['status_txt'] = '正常'; - break; - case 2: - $data['status_txt'] = '离职'; - break; - default: - $data['status_txt'] = ''; - break; - } + switch ($data['status']){ + case 1: + $data['status_txt'] = '正常'; + break; + case 2: + $data['status_txt'] = '离职'; + break; + default: + $data['status_txt'] = ''; + break; + } - $data['corp_name'] = Corp::where('id', $data['corp_id'])->value('name'); - $data['customer_count'] = Customer::where('user_id', $data['id'])->count(); - return $data; - } + $data['corp_name'] = Corp::where('id', $data['corp_id'])->value('name'); + $data['customer_count'] = Customer::where('user_id', $data['id'])->count(); + return $data; + } + + /** + * 授权 + * + * @param Request $request + * @return mixed + */ + public function authorize(Request $request) + { + try { + $data = $this->validate($this->service->getValidator(), $request->post(), 'authorize'); + $res = $this->service->authorize($request, $data); + return $this->success([], '分配成功'); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } + + /** + * 直接授权 + * + * @param Request $request + * @return mixed + */ + public function updateResources(Request $request) + { + try { + $data = $this->validate($this->service->getValidator(), $request->post(), 'updateResources'); + $res = $this->service->updateResources($request, $data); + return $this->success([], '分配成功'); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } } \ No newline at end of file diff --git a/app/admin/logic/UserLogic.php b/app/admin/logic/UserLogic.php index de0d15d..2df041d 100644 --- a/app/admin/logic/UserLogic.php +++ b/app/admin/logic/UserLogic.php @@ -4,6 +4,7 @@ namespace app\admin\logic; use app\common\traits\crud\CrudLogicTrait; use app\common\model\User; +use support\Db; class UserLogic { @@ -14,4 +15,83 @@ class UserLogic */ protected string $modelClass = User::class; + + public function updateRoleAndSystem(array $data): bool + { + $roleIds = $data['role_ids'] ?? []; + $systemIds = $data['system_ids'] ?? []; + $userId = $data['user_id'] ?? 0; + + if (empty($roleId)) { + return false; + } + + Db::beginTransaction(); + try { + Db::table('user_roles')->where('user_id', $userId)->delete(); + if (!empty($roleIds)) { + $insertData = []; + foreach ($roleIds as $roleId) { + $insertData[] = [ + 'role_id' => $roleId, + 'user_id' => $userId + ]; + } + Db::table('user_roles')->insert($insertData); + } + + Db::table('user_systems')->where('user_id', $userId)->delete(); + if (!empty($systemIds)) { + $insertData = []; + foreach ($systemIds as $systemId) { + $insertData[] = [ + 'system_id' => $systemId, + 'user_id' => $userId + ]; + } + Db::table('user_systems')->insert($insertData); + } + + Db::commit(); + return true; + } catch (\Throwable $exception) { + Db::rollBack(); + return false; + } + } + + + public function updateUserResources(array $data): bool + { + $userId = $data['role_id'] ?? 0; + $resources = $data['resources'] ?? []; + + if (empty($userId)) { + return false; + } + + Db::beginTransaction(); + try { + // 删除原有资源关联 + Db::table('user_resources')->where('user_id', $userId)->delete(); + + // 批量插入新角色资源关联 + if (!empty($resources)) { + $insertData = []; + foreach ($resources as $resourceId) { + $insertData[] = [ + 'user_id' => $userId, + 'resource_id' => $resourceId + ]; + } + Db::table('user_resources')->insert($insertData); + } + + Db::commit(); + return true; + } catch (\Throwable $exception) { + Db::rollBack(); + return false; + } + } } \ No newline at end of file diff --git a/app/admin/service/RoleService.php b/app/admin/service/RoleService.php index 248bc3d..af86a04 100644 --- a/app/admin/service/RoleService.php +++ b/app/admin/service/RoleService.php @@ -2,9 +2,11 @@ namespace app\admin\service; +use app\common\logic\RoleLogic; use app\common\validate\RoleValidate; use app\common\traits\crud\CrudServiceTrait; use app\common\model\Role; +use support\Db; class RoleService { @@ -28,4 +30,12 @@ class RoleService { return new $this->validator; } + + /** + * 获取角色资源 + */ + public function menuResource($request, $data) + { + return (new RoleLogic)->updateRoleResources($data); + } } \ No newline at end of file diff --git a/app/admin/service/UserService.php b/app/admin/service/UserService.php index 6926bc5..4ce782a 100644 --- a/app/admin/service/UserService.php +++ b/app/admin/service/UserService.php @@ -2,6 +2,7 @@ namespace app\admin\service; +use app\admin\logic\UserLogic; use app\admin\validate\UserValidate; use app\common\traits\crud\CrudServiceTrait; use app\common\model\User; @@ -75,4 +76,28 @@ class UserService return $config; } + + /** + * 授权 + * + * @param Request $request + * @param array $data + * @return bool + */ + public function authorize(Request $request, array $data = []) + { + return (new UserLogic())->updateRoleAndSystem($data); + } + + /** + * 更新用户资源权限 + * + * @param Request $request + * @param array $data + * @return bool + */ + public function updateResources(Request $request, array $data = []) + { + return (new UserLogic())->updateUserResources($data); + } } \ No newline at end of file diff --git a/app/common/controller/ResourceController.php b/app/common/controller/ResourceController.php index 4d81058..5fd35b9 100644 --- a/app/common/controller/ResourceController.php +++ b/app/common/controller/ResourceController.php @@ -63,4 +63,20 @@ class ResourceController extends BaseController return $this->error($e->getMessage()); } } + + /** + * 菜单 + */ + public function menuTreeList(Request $request) + { + try { + $raw = $this->service->serviceMenuTreeList($request); + $data = $this->transformData($raw, method_exists($this, 'allFormat') + ? [$this, 'allFormat'] + : null); + return $this->success($data); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } } \ No newline at end of file diff --git a/app/common/controller/UserController.php b/app/common/controller/UserController.php index d725166..a69f32b 100644 --- a/app/common/controller/UserController.php +++ b/app/common/controller/UserController.php @@ -9,7 +9,7 @@ class UserController extends BaseController { /** - * 用户信息 + * 用户信息(登录后调用) */ public function info(Request $request) { @@ -23,57 +23,57 @@ class UserController extends BaseController } } - /** - * 用户信息 - */ - public function getUser(Request $request) - { - try { - $uid = $request->user->uid; - $corp_abbr = $request->basic_data['corp_abbr']; - $result = (new UserService())->getUser($uid,$corp_abbr); - return $this->success($result, '获取用户信息'); - } catch (\Throwable $e) { - return $this->error($e->getMessage()); - } - } + // /** + // * 用户信息 + // */ + // public function getUser(Request $request) + // { + // try { + // $uid = $request->user->uid; + // $corp_abbr = $request->basic_data['corp_abbr']; + // $result = (new UserService())->getUser($uid,$corp_abbr); + // return $this->success($result, '获取用户信息'); + // } catch (\Throwable $e) { + // return $this->error($e->getMessage()); + // } + // } - /** - * 编辑用户 - */ - public function edit(Request $request) - { - try { - $uid = $request->user->uid; - $data = $request->all(); - $result = (new UserService())->edit($uid,$data); - unset($result['password']); - unset($result['union_id']); - unset($result['open_id']); - unset($result['tenant_key']); - return $this->success($result, '编辑成功'); - } catch (\Throwable $e) { - return $this->error($e->getMessage()); - } - } + // /** + // * 编辑用户 + // */ + // public function edit(Request $request) + // { + // try { + // $uid = $request->user->uid; + // $data = $request->all(); + // $result = (new UserService())->edit($uid,$data); + // unset($result['password']); + // unset($result['union_id']); + // unset($result['open_id']); + // unset($result['tenant_key']); + // return $this->success($result, '编辑成功'); + // } catch (\Throwable $e) { + // return $this->error($e->getMessage()); + // } + // } - /** - * 修改密码 - * @param Request $request - * @return \support\Response - * @throws \Random\RandomException - */ - public function savePassword(Request $request) - { - try { - $uid = $request->user->uid; - $data = $request->all(); - $result = (new UserService())->savePassword($uid,$data);; - return $this->success($result, '编辑成功'); - } catch (\Throwable $e) { - return $this->error($e->getMessage()); - } - } + // /** + // * 修改密码 + // * @param Request $request + // * @return \support\Response + // * @throws \Random\RandomException + // */ + // public function savePassword(Request $request) + // { + // try { + // $uid = $request->user->uid; + // $data = $request->all(); + // $result = (new UserService())->savePassword($uid,$data);; + // return $this->success($result, '编辑成功'); + // } catch (\Throwable $e) { + // return $this->error($e->getMessage()); + // } + // } } \ No newline at end of file diff --git a/app/common/logic/ResourceLogic.php b/app/common/logic/ResourceLogic.php index cbcb14e..ddf6423 100644 --- a/app/common/logic/ResourceLogic.php +++ b/app/common/logic/ResourceLogic.php @@ -4,6 +4,7 @@ namespace app\common\logic; use app\common\traits\crud\CrudLogicTrait; use app\common\model\Resource; +use support\Request; class ResourceLogic { @@ -14,4 +15,23 @@ class ResourceLogic */ protected string $modelClass = Resource::class; + + public function logicListAllResources(Request $request, array $config) + { + $data = $this->logicListAll($config); + + if ($request->get('role_id')) { + $selected = (new RoleLogic())->getRoleResources($request->get('role_id')); + } else if ($request->get('user_id')) { + $selected = (new RoleLogic())->getUserResources($request->get('user_id')); + } else { + $selected = []; + } + + foreach ($data as &$item) { + $item['selected'] = in_array($item['id'], $selected) ? true : false; + } + + return $data; + } } \ No newline at end of file diff --git a/app/common/logic/RoleLogic.php b/app/common/logic/RoleLogic.php index bd8f121..0898b10 100644 --- a/app/common/logic/RoleLogic.php +++ b/app/common/logic/RoleLogic.php @@ -2,13 +2,84 @@ namespace app\common\logic; -use app\common\model\Role; -use support\exception\BusinessException; -use support\Log; +use support\Db; class RoleLogic { - + /** + * 更新角色资源权限 + * + * @param array $data 包含 role_id 和 resources 的数据 + * @return bool 操作是否成功 + */ + public function updateRoleResources(array $data): bool + { + $roleId = $data['role_id'] ?? 0; + $resources = $data['resources'] ?? []; + + if (empty($roleId)) { + return false; + } + + Db::beginTransaction(); + try { + // 删除原有角色资源关联 + Db::table('role_resources')->where('role_id', $roleId)->delete(); + + // 批量插入新角色资源关联 + if (!empty($resources)) { + $insertData = []; + foreach ($resources as $resourceId) { + $insertData[] = [ + 'role_id' => $roleId, + 'resource_id' => $resourceId + ]; + } + Db::table('role_resources')->insert($insertData); + } + + Db::commit(); + return true; + } catch (\Throwable $exception) { + Db::rollBack(); + return false; + } + } + /** + * 获取角色资源 + * + * @param int $roleId 角色ID + * @return array 资源ID列表 + */ + public function getRoleResources(int $roleId): array + { + if (empty($roleId)) { + return []; + } + + return Db::table('role_resources') + ->where('role_id', $roleId) + ->pluck('resource_id') + ->toArray(); + } + + /** + * 获取用户资源 + * + * @param int $userId 用户ID + * @return array 资源ID列表 + */ + public function getUserResources(int $userId): array + { + if (empty($userId)) { + return []; + } + + return Db::table('user_resources') + ->where('user_id', $userId) + ->pluck('resource_id') + ->toArray(); + } } diff --git a/app/common/service/ResourceService.php b/app/common/service/ResourceService.php index 7d52eff..5c73800 100644 --- a/app/common/service/ResourceService.php +++ b/app/common/service/ResourceService.php @@ -2,6 +2,7 @@ namespace app\common\service; +use app\common\logic\ResourceLogic; use app\common\validate\ResourceValidate; use app\common\traits\crud\CrudServiceTrait; use app\common\model\Resource; @@ -50,6 +51,11 @@ class ResourceService $config['order']['sort'] = 'asc'; $config['order']['id'] = 'asc'; break; + case 'menuTreeList': + $config['where']['status'] = 1; + $config['order']['sort'] = 'asc'; + $config['order']['id'] = 'asc'; + break; case 'index': $config['where']['status'] = 1; $config['order']['sort'] = 'asc'; @@ -79,6 +85,13 @@ class ResourceService return $this->postProcess('MenuList', $result); } + public function serviceMenuTreeList(Request $request) + { + $config = $this->buildQueryConfig($request, 'menuTreeList'); + $result = (new ResourceLogic())->logicListAllResources($request, $config); + return $this->postProcess('MenuTreeList', $result); + } + protected function afterServiceListAll($data) { @@ -91,4 +104,10 @@ class ResourceService $data = Tree::buildWithReference($data->toArray()); return $data; } + + protected function afterServiceMenuTreeList($data) + { + $data = Tree::buildWithReference($data->toArray()); + return $data; + } } \ No newline at end of file diff --git a/config/route.php b/config/route.php index 5e1afa6..880c4a5 100644 --- a/config/route.php +++ b/config/route.php @@ -70,6 +70,7 @@ Route::group('/admin', function () { Route::any('/store', [app\admin\controller\RoleController::class, 'store']); Route::any('/update', [app\admin\controller\RoleController::class, 'update']); Route::any('/destroy', [app\admin\controller\RoleController::class, 'destroy']); + Route::any('/menu/resource', [app\admin\controller\RoleController::class, 'menuResource']); }); // 公司 @@ -107,6 +108,7 @@ Route::group('/admin', function () { Route::any('/update', [app\common\controller\ResourceController::class, 'update']); Route::any('/destroy', [app\common\controller\ResourceController::class, 'destroy']); Route::any('/list/menu', [app\common\controller\ResourceController::class, 'menuList']); + Route::any('/list/menu/tree', [app\common\controller\ResourceController::class, 'menuTreeList']); }); // 用户 @@ -114,6 +116,8 @@ Route::group('/admin', function () { Route::any('/list', [app\admin\controller\UserController::class, 'index']); Route::any('/show', [app\admin\controller\UserController::class, 'show']); Route::any('/update', [app\admin\controller\UserController::class, 'update']); + Route::any('/authorize', [app\admin\controller\UserController::class, 'authorize']); + Route::any('/set/resources', [app\admin\controller\UserController::class, 'updateResources']); }); // 询单