From b727b0d9985b8ee35eb6fc2fe0b9febd22d62190 Mon Sep 17 00:00:00 2001 From: fangyunong Date: Sat, 19 Jul 2025 16:12:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=A4=A7=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- auto-imports.d.ts | 2 + src/App.vue | 19 ++++ src/api/roleApi.ts | 31 +++++- src/assets/icons/column.svg | 1 + src/assets/icons/dict.svg | 1 + src/assets/icons/menu.svg | 1 + src/assets/icons/system.svg | 1 + src/assets/icons/user.svg | 1 + src/components/Ls-UI/LsRoleBase.vue | 48 +++++++-- src/store/app.ts | 14 ++- src/store/user.ts | 17 +++- .../home/compoents/MainDashBoradProxy.vue | 7 +- .../home/compoents/SubDashBoardQuick.vue | 7 +- src/views/layout/components/LayoutHeader.vue | 4 + src/views/role/pages/Auth.vue | 67 +++++++++++-- src/views/system/menu/index.vue | 97 +++++++++++-------- src/views/system/menu/utils.ts | 10 ++ 17 files changed, 257 insertions(+), 71 deletions(-) create mode 100644 src/assets/icons/column.svg create mode 100644 src/assets/icons/dict.svg create mode 100644 src/assets/icons/menu.svg create mode 100644 src/assets/icons/system.svg create mode 100644 src/assets/icons/user.svg create mode 100644 src/views/system/menu/utils.ts diff --git a/auto-imports.d.ts b/auto-imports.d.ts index a950714..6bcb7af 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -9,8 +9,10 @@ declare global { const EffectScope: typeof import('vue')['EffectScope'] const addChildDict: typeof import('./src/api/dictApi')['addChildDict'] const addChildMenu: typeof import('./src/api/menu')['addChildMenu'] + const addNewRole: typeof import('./src/api/roleApi')['addNewRole'] const addParentDict: typeof import('./src/api/dictApi')['addParentDict'] const addParentMenu: typeof import('./src/api/menu')['addParentMenu'] + const assignMenu: typeof import('./src/api/roleApi')['assignMenu'] const computed: typeof import('vue')['computed'] const createApp: typeof import('vue')['createApp'] const customRef: typeof import('vue')['customRef'] diff --git a/src/App.vue b/src/App.vue index f488556..8c6a1c6 100644 --- a/src/App.vue +++ b/src/App.vue @@ -12,6 +12,8 @@ diff --git a/src/api/roleApi.ts b/src/api/roleApi.ts index afd4397..e5808d6 100644 --- a/src/api/roleApi.ts +++ b/src/api/roleApi.ts @@ -4,7 +4,7 @@ interface UserListQuery { roleName?: string; page: number; pageSize: number; - userName?:string + userName?: string; } interface UserListReturn { totalCount: number; @@ -48,10 +48,37 @@ interface EnableRoleQuery { userId: string; roleName: string; } -export function enableRole(data:EnableRoleQuery) { +export function enableRole(data: EnableRoleQuery) { return http({ url: "/api/v1/AdminRoleControllers/role", method: "POST", data, }); } + +// 添加新角色 +interface NewRoleReq{ + rolename:string + normalizedname:string +} +export function addNewRole(params:NewRoleReq){ + return http({ + url:'/api/v1/AdminRoleControllers/role', + method:'POST', + params + }) +} + +interface MenuRequest { + id: string; + menuName: string; + menuCode: string; +} +// 分配菜单权限 +export function assignMenu(data:MenuRequest) { + return http({ + url: "/api/v1/AdminRoleControllers/menu", + method: "POST", + data, + }); +} diff --git a/src/assets/icons/column.svg b/src/assets/icons/column.svg new file mode 100644 index 0000000..482ba13 --- /dev/null +++ b/src/assets/icons/column.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/dict.svg b/src/assets/icons/dict.svg new file mode 100644 index 0000000..2dcc30d --- /dev/null +++ b/src/assets/icons/dict.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/menu.svg b/src/assets/icons/menu.svg new file mode 100644 index 0000000..88f07f3 --- /dev/null +++ b/src/assets/icons/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/system.svg b/src/assets/icons/system.svg new file mode 100644 index 0000000..135e1ca --- /dev/null +++ b/src/assets/icons/system.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/user.svg b/src/assets/icons/user.svg new file mode 100644 index 0000000..521b7a0 --- /dev/null +++ b/src/assets/icons/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Ls-UI/LsRoleBase.vue b/src/components/Ls-UI/LsRoleBase.vue index 5fd2608..40a978a 100644 --- a/src/components/Ls-UI/LsRoleBase.vue +++ b/src/components/Ls-UI/LsRoleBase.vue @@ -1,27 +1,39 @@ diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue index 2390aec..2179eaa 100644 --- a/src/views/system/menu/index.vue +++ b/src/views/system/menu/index.vue @@ -44,8 +44,8 @@ - - + + - - + + ([]) const showParentModal = ref(false); const parentFormRef = ref(null); const menuType = ref<'menu' | 'list'>('menu'); //菜单类型 -const parentForm = ref>({ +const menuOptions = ref([]); //初始化菜单权限 +const adaptabilityOptions = ref([]);// 适配方式选项 +interface MenuVO extends Omit { + menuCode: string[]; +} + +const parentForm = ref>({ path: '', label: '', icon: '', - menuCode: '', + menuCode: [], menuName: '', adaptability: 'pc', component: '', @@ -271,12 +278,12 @@ const renderLabel = (option: IconOption) => { // 子级菜单表单相关 const showChildModal = ref(false) const childFormRef = ref(null) -const childForm = ref>({ +const childForm = ref>({ parentId: '', path: '', label: '', icon: '', - menuCode: '', + menuCode: [], menuName: '', adaptability: 'pc', component: '', @@ -294,30 +301,32 @@ const childRules: FormRules = { const isEditChild = ref(false) const currentChildId = ref('') -// 适配方式选项 -const adaptabilityOptions = ref([]); - -getDict("page_adaptability").then((res) => { - console.log('获取适配方式选项', res); - adaptabilityOptions.value = res.map(item => { - const {label, value, ...rest} = item; - return { - label: label, - value: value, - } - }) -}).catch((errors) => { - console.log('获取适配方式选项失败', errors); - message.error('获取适配方式选项失败'); -}) - +// 初始化字典 +const initDict = async () => { + try { + const [res1, res2] = await Promise.all([getDict("page_adaptability"), getDict('menuCode')]); + adaptabilityOptions.value = res1.map(item => { + return { + label: item.label, + value: item.value, + } + }) + menuOptions.value = res2.map(item => { + return { + label: item.label, + value: item.value + } + }) + } catch (error) { + message.error(error.message); + } +} // 计算属性 const parentModalTitle = computed(() => (isEditParent.value ? '编辑父级菜单' : '添加父级菜单')) const childModalTitle = computed(() => (isEditChild.value ? '编辑子级菜单' : '添加子级菜单')) // 父级菜单选项 const parentMenuOptions = computed(() => { - console.log(menuTree.value, 'menuTree.value'); return menuTree.value.map(menu => ({ label: menu.label, value: menu.key @@ -336,6 +345,7 @@ const { stop } = watch(menuType, (newVal) => { }) // 生命周期钩子 onMounted(() => { + initDict(); loadSvgIcons(); fetchMenuData(); }); @@ -344,7 +354,6 @@ onBeforeUnmount(() => { }) const renderTreeLabel = ({ option }) => { - console.log(option,'option'); return h('div', { style: { display: 'flex', @@ -364,7 +373,7 @@ const renderTreeLabel = ({ option }) => { h(NTag, { type: option?.rawData.status === 'enable' ? 'success' : 'error', size: 'small' - }, option?.rawData.status === 'enable' ? 'Enabled' : 'Disabled') + }, option?.rawData.status === 'enable' ? '启用' : '停用') ]) } /** @@ -480,7 +489,7 @@ const handleAddParent = () => { path: '', label: '', icon: '', - menuCode: '', + menuCode: [], menuName: '', adaptability: 'pc', component: '', @@ -499,7 +508,7 @@ const handleEditParent = (menu: MenuNode) => { path: menu.path, label: menu.label, icon: menu.icon, - menuCode: menu.menuCode, + menuCode: menu.menuCode ? menu.menuCode.split(',') : [], menuName: menu.menuName, adaptability: menu.adaptability, component: menu.component, @@ -518,10 +527,16 @@ const handleSubmitParent = () => { if (isEditParent.value) { await editParentMenu({ uuid: currentParentId.value, - ...parentForm.value + ...parentForm.value, + menuCode: parentForm.value.menuCode.join(','), + menuName: getMenuName(parentForm.value.menuCode, menuOptions.value) }) } else { - await addParentMenu(parentForm.value) + await addParentMenu({ + ...parentForm.value, + menuCode: parentForm.value.menuCode.join(','), + menuName: getMenuName(parentForm.value.menuCode, menuOptions.value) + }) } showParentModal.value = false; message.success('操作成功!'); @@ -540,7 +555,7 @@ const handleAddChild = (parentId: string) => { path: '', label: '', icon: '', - menuCode: '', + menuCode: [], menuName: '', adaptability: 'pc', component: '', @@ -560,7 +575,7 @@ const handleEditChild = (menu: MenuNode) => { path: menu.path, label: menu.label, icon: menu.icon, - menuCode: menu.menuCode, + menuCode: menu.menuCode ? menu.menuCode.split(',') : [], menuName: menu.menuName, adaptability: menu.adaptability, component: menu.component, @@ -579,10 +594,16 @@ const handleSubmitChild = () => { if (isEditChild.value) { await eidtChildMenu({ uuid: currentChildId.value, - ...childForm.value + ...childForm.value, + menuCode: childForm.value.menuCode.join(','), + menuName: getMenuName(childForm.value.menuCode, menuOptions.value) }) } else { - await addChildMenu(childForm.value) + await addChildMenu({ + ...childForm.value, + menuCode: childForm.value.menuCode.join(','), + menuName: getMenuName(childForm.value.menuCode, menuOptions.value) + }) } showChildModal.value = false; message.success('操作成功!'); diff --git a/src/views/system/menu/utils.ts b/src/views/system/menu/utils.ts new file mode 100644 index 0000000..758e2fa --- /dev/null +++ b/src/views/system/menu/utils.ts @@ -0,0 +1,10 @@ +export function getMenuName(value:string[], options) { + let result = [] + if(value.length === 0) return ''; + for(let i = 0; i < value.length; i++){ + const val = value[i] as string; + const label = options.find(item => item.value === val); + result.push(label); + } + return result.join(','); +}