From a903251c0ddd5d57ca5f1ad6c7d56cb272776d76 Mon Sep 17 00:00:00 2001 From: xlsea Date: Sat, 10 May 2025 01:17:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/custom/dept-tree.vue | 144 +++++++++++++++++ src/components/custom/menu-tree.vue | 28 ++-- src/locales/langs/en-us.ts | 3 +- src/locales/langs/zh-cn.ts | 3 +- src/service/api/system/menu.ts | 8 + src/service/api/system/role.ts | 17 ++ src/typings/api/system.api.d.ts | 22 ++- src/typings/components.d.ts | 1 + src/views/system/role/index.vue | 80 +++++++-- .../role/modules/role-data-scope-drawer.vue | 153 ++++++++++++++++++ .../role/modules/role-operate-drawer.vue | 17 +- 11 files changed, 431 insertions(+), 45 deletions(-) create mode 100644 src/components/custom/dept-tree.vue create mode 100644 src/views/system/role/modules/role-data-scope-drawer.vue diff --git a/src/components/custom/dept-tree.vue b/src/components/custom/dept-tree.vue new file mode 100644 index 00000000..8d208430 --- /dev/null +++ b/src/components/custom/dept-tree.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/src/components/custom/menu-tree.vue b/src/components/custom/menu-tree.vue index d6567f4d..7368cad3 100644 --- a/src/components/custom/menu-tree.vue +++ b/src/components/custom/menu-tree.vue @@ -2,8 +2,7 @@ import { onMounted, ref, useAttrs } from 'vue'; import type { TreeOption, TreeSelectInst, TreeSelectProps } from 'naive-ui'; import { useBoolean } from '@sa/hooks'; -import { fetchGetMenuList } from '@/service/api/system'; -import { handleTree } from '@/utils/common'; +import { fetchGetMenuTreeSelect } from '@/service/api/system'; import SvgIcon from '@/components/custom/svg-icon.vue'; defineOptions({ name: 'MenuTree' }); @@ -18,26 +17,27 @@ const props = withDefaults(defineProps(), { }); const { bool: expandAll } = useBoolean(); -const { bool: cascade } = useBoolean(true); const { bool: checkAll } = useBoolean(); +const expandedKeys = ref([0]); const menuTreeRef = ref(null); const value = defineModel('value', { required: false, default: [] }); const options = defineModel('options', { required: false, default: [] }); +const cascade = defineModel('cascade', { required: false, default: true }); const loading = defineModel('loading', { required: false, default: false }); const attrs: TreeSelectProps = useAttrs(); async function getMenuList() { loading.value = true; - const { error, data } = await fetchGetMenuList(); + const { error, data } = await fetchGetMenuTreeSelect(); if (error) return; options.value = [ { - menuId: 0, - menuName: '根目录', + id: 0, + label: '根目录', icon: 'material-symbols:home-outline-rounded', - children: handleTree(data, { idField: 'menuId', filterFn: item => item.menuType !== 'F' }) + children: data } ] as Api.System.MenuList; loading.value = false; @@ -51,8 +51,11 @@ onMounted(() => { function renderPrefix({ option }: { option: TreeOption }) { const renderLocalIcon = String(option.icon).startsWith('icon-'); - const icon = renderLocalIcon ? undefined : String(option.icon); + let icon = renderLocalIcon ? undefined : String(option.icon ?? 'material-symbols:buttons-alt-outline-rounded'); const localIcon = renderLocalIcon ? String(option.icon).replace('icon-', 'menu-') : undefined; + if (icon === '#') { + icon = 'material-symbols:buttons-alt-outline-rounded'; + } return ; } @@ -109,17 +112,18 @@ defineExpose({ diff --git a/src/locales/langs/en-us.ts b/src/locales/langs/en-us.ts index a689590c..413dccf4 100644 --- a/src/locales/langs/en-us.ts +++ b/src/locales/langs/en-us.ts @@ -188,7 +188,8 @@ const local: App.I18n.Schema = { 'system_oss-config': 'OSS Config', monitor_cache: 'Cache Monitor', monitor_online: 'Online User', - 'user-center': 'User Center' + 'user-center': 'User Center', + system_role: 'Role Management' }, page: { login: { diff --git a/src/locales/langs/zh-cn.ts b/src/locales/langs/zh-cn.ts index 1e7e0f13..19643cf2 100644 --- a/src/locales/langs/zh-cn.ts +++ b/src/locales/langs/zh-cn.ts @@ -188,7 +188,8 @@ const local: App.I18n.Schema = { 'system_oss-config': 'OSS配置', monitor_cache: '缓存监控', monitor_online: '在线用户', - 'user-center': '个人中心' + 'user-center': '个人中心', + system_role: '角色管理' }, page: { login: { diff --git a/src/service/api/system/menu.ts b/src/service/api/system/menu.ts index f05e199e..847f0725 100644 --- a/src/service/api/system/menu.ts +++ b/src/service/api/system/menu.ts @@ -35,6 +35,14 @@ export function fetchDeleteMenu(menuId: CommonType.IdType) { }); } +/** 获取菜单树 */ +export function fetchGetMenuTreeSelect() { + return request({ + url: 'system/menu/treeselect', + method: 'get' + }); +} + /** 获取角色菜单权限 */ export function fetchGetRoleMenuTreeSelect(roleId: CommonType.IdType) { return request({ diff --git a/src/service/api/system/role.ts b/src/service/api/system/role.ts index d22567f3..f1da7745 100644 --- a/src/service/api/system/role.ts +++ b/src/service/api/system/role.ts @@ -52,3 +52,20 @@ export function fetchGetRoleSelect(roleIds?: CommonType.IdType[]) { params: { roleIds } }); } + +/** 获取对应角色部门树列表 */ +export function fetchGetRoleDeptTreeSelect(roleId: CommonType.IdType) { + return request({ + url: `/system/role/deptTree/${roleId}`, + method: 'get' + }); +} + +/** 获取对应角色用户列表 */ +export function fetchGetRoleUserList(params: Api.System.UserSearchParams) { + return request({ + url: `/system/role/authUser/allocatedList`, + method: 'get', + params + }); +} diff --git a/src/typings/api/system.api.d.ts b/src/typings/api/system.api.d.ts index 8f8d6dfe..e61667b8 100644 --- a/src/typings/api/system.api.d.ts +++ b/src/typings/api/system.api.d.ts @@ -48,8 +48,16 @@ declare namespace Api { type RoleOperateParams = CommonType.RecordNullable< Pick< Api.System.Role, - 'roleId' | 'roleName' | 'roleKey' | 'roleSort' | 'menuCheckStrictly' | 'status' | 'remark' - > & { menuIds: CommonType.IdType[] } + | 'roleId' + | 'roleName' + | 'roleKey' + | 'roleSort' + | 'menuCheckStrictly' + | 'deptCheckStrictly' + | 'dataScope' + | 'status' + | 'remark' + > & { menuIds: CommonType.IdType[]; deptIds: CommonType.IdType[] } >; /** role list */ @@ -61,6 +69,12 @@ declare namespace Api { menus: MenuList; }>; + /** role dept tree select */ + type RoleDeptTreeSelect = Common.CommonRecord<{ + checkedKeys: CommonType.IdType[]; + depts: Dept[]; + }>; + /** all role */ type AllRole = Pick; @@ -108,7 +122,9 @@ declare namespace Api { /** user search params */ type UserSearchParams = CommonType.RecordNullable< - Pick & Common.CommonSearchParams + Pick & { + roleId: CommonType.IdType; + } & Common.CommonSearchParams >; /** user operate params */ diff --git a/src/typings/components.d.ts b/src/typings/components.d.ts index 6a54a594..17c56901 100644 --- a/src/typings/components.d.ts +++ b/src/typings/components.d.ts @@ -15,6 +15,7 @@ declare module 'vue' { copy: typeof import('./../components/custom/menu-tree-select copy.vue')['default'] CountTo: typeof import('./../components/custom/count-to.vue')['default'] DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default'] + DeptTree: typeof import('./../components/custom/dept-tree.vue')['default'] DictRadio: typeof import('./../components/custom/dict-radio.vue')['default'] DictSelect: typeof import('./../components/custom/dict-select.vue')['default'] DictTag: typeof import('./../components/custom/dict-tag.vue')['default'] diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 590bf1e2..9d887eb4 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -1,5 +1,7 @@ diff --git a/src/views/system/role/modules/role-data-scope-drawer.vue b/src/views/system/role/modules/role-data-scope-drawer.vue new file mode 100644 index 00000000..4037107f --- /dev/null +++ b/src/views/system/role/modules/role-data-scope-drawer.vue @@ -0,0 +1,153 @@ + + + + + diff --git a/src/views/system/role/modules/role-operate-drawer.vue b/src/views/system/role/modules/role-operate-drawer.vue index 76886c1f..d0483af7 100644 --- a/src/views/system/role/modules/role-operate-drawer.vue +++ b/src/views/system/role/modules/role-operate-drawer.vue @@ -1,5 +1,6 @@