feat:大修改
This commit is contained in:
parent
991736f760
commit
b727b0d998
2
auto-imports.d.ts
vendored
2
auto-imports.d.ts
vendored
@ -9,8 +9,10 @@ declare global {
|
|||||||
const EffectScope: typeof import('vue')['EffectScope']
|
const EffectScope: typeof import('vue')['EffectScope']
|
||||||
const addChildDict: typeof import('./src/api/dictApi')['addChildDict']
|
const addChildDict: typeof import('./src/api/dictApi')['addChildDict']
|
||||||
const addChildMenu: typeof import('./src/api/menu')['addChildMenu']
|
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 addParentDict: typeof import('./src/api/dictApi')['addParentDict']
|
||||||
const addParentMenu: typeof import('./src/api/menu')['addParentMenu']
|
const addParentMenu: typeof import('./src/api/menu')['addParentMenu']
|
||||||
|
const assignMenu: typeof import('./src/api/roleApi')['assignMenu']
|
||||||
const computed: typeof import('vue')['computed']
|
const computed: typeof import('vue')['computed']
|
||||||
const createApp: typeof import('vue')['createApp']
|
const createApp: typeof import('vue')['createApp']
|
||||||
const customRef: typeof import('vue')['customRef']
|
const customRef: typeof import('vue')['customRef']
|
||||||
|
19
src/App.vue
19
src/App.vue
@ -12,6 +12,8 @@
|
|||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
import { type GlobalThemeOverrides, dateZhCN, zhCN } from "naive-ui";
|
import { type GlobalThemeOverrides, dateZhCN, zhCN } from "naive-ui";
|
||||||
import InitAxiosInterceptors from "@/components/InitAxiosInterceptors.vue";
|
import InitAxiosInterceptors from "@/components/InitAxiosInterceptors.vue";
|
||||||
|
import { useAppStore } from "@/store/app";
|
||||||
|
import { generateRoutes } from "@/utils/permission";
|
||||||
|
|
||||||
const themeOverrides: GlobalThemeOverrides = {
|
const themeOverrides: GlobalThemeOverrides = {
|
||||||
// 待配置主题色
|
// 待配置主题色
|
||||||
@ -22,6 +24,23 @@ const themeOverrides: GlobalThemeOverrides = {
|
|||||||
'primaryColorSuppl': '#5A95FF' // 介于主色和hover之间的蓝色
|
'primaryColorSuppl': '#5A95FF' // 介于主色和hover之间的蓝色
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
const router = useRouter();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
|
// 等待 Pinia 数据恢复
|
||||||
|
router.isReady().then(() => {
|
||||||
|
const appStore = useAppStore();
|
||||||
|
console.log(appStore.menuApp.menuList, 'appStore.menuApp.menuList');
|
||||||
|
|
||||||
|
if (appStore.menuApp.menuList?.length) {
|
||||||
|
const dynamicRoutes = generateRoutes(appStore.menuApp.menuList);
|
||||||
|
dynamicRoutes.forEach(route => {
|
||||||
|
router.addRoute('Layout', route); // 确保添加到正确的父路由
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重新匹配当前路由,避免 404
|
||||||
|
router.replace(router.currentRoute.value.fullPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang='scss'></style>
|
<style scoped lang='scss'></style>
|
||||||
|
@ -4,7 +4,7 @@ interface UserListQuery {
|
|||||||
roleName?: string;
|
roleName?: string;
|
||||||
page: number;
|
page: number;
|
||||||
pageSize: number;
|
pageSize: number;
|
||||||
userName?:string
|
userName?: string;
|
||||||
}
|
}
|
||||||
interface UserListReturn {
|
interface UserListReturn {
|
||||||
totalCount: number;
|
totalCount: number;
|
||||||
@ -48,10 +48,37 @@ interface EnableRoleQuery {
|
|||||||
userId: string;
|
userId: string;
|
||||||
roleName: string;
|
roleName: string;
|
||||||
}
|
}
|
||||||
export function enableRole(data:EnableRoleQuery) {
|
export function enableRole(data: EnableRoleQuery) {
|
||||||
return http({
|
return http({
|
||||||
url: "/api/v1/AdminRoleControllers/role",
|
url: "/api/v1/AdminRoleControllers/role",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data,
|
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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
1
src/assets/icons/column.svg
Normal file
1
src/assets/icons/column.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1752906479986" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6024" id="mx_n_1752906479987" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M704 300.8H320c-10.666667 0-21.333333 8.533333-21.333333 21.333333v42.666667c0 10.666667 8.533333 21.333333 21.333333 21.333333h149.333333v320c0 10.666667 8.533333 21.333333 21.333334 21.333334h42.666666c10.666667 0 21.333333-8.533333 21.333334-21.333334v-320h149.333333c10.666667 0 21.333333-8.533333 21.333333-21.333333v-42.666667c-2.133333-12.8-10.666667-21.333333-21.333333-21.333333z" fill="#297AFF" p-id="6025"></path><path d="M810.666667 128H213.333333c-46.933333 0-85.333333 38.4-85.333333 85.333333v597.333334c0 46.933333 38.4 85.333333 85.333333 85.333333h320c12.8 0 21.333333-8.533333 21.333334-21.333333v-42.666667c0-12.8-8.533333-21.333333-21.333334-21.333333H256c-23.466667 0-42.666667-19.2-42.666667-42.666667V256c0-23.466667 19.2-42.666667 42.666667-42.666667h512c23.466667 0 42.666667 19.2 42.666667 42.666667v277.333333c0 12.8 8.533333 21.333333 21.333333 21.333334h42.666667c12.8 0 21.333333-8.533333 21.333333-21.333334V213.333333c0-46.933333-38.4-85.333333-85.333333-85.333333z" fill="#297AFF" p-id="6026"></path><path d="M612.266667 800l206.933333-200.533333c8.533333-8.533333 25.6-8.533333 34.133333 0l34.133334 34.133333c8.533333 8.533333 8.533333 23.466667 0 34.133333l-209.066667 202.666667c-2.133333 2.133333-6.4 4.266667-10.666667 6.4l-68.266666 19.2c-8.533333 2.133333-17.066667-6.4-14.933334-14.933333l21.333334-70.4c2.133333-4.266667 4.266667-6.4 6.4-10.666667z" fill="#297AFF" p-id="6027"></path></svg>
|
After Width: | Height: | Size: 1.7 KiB |
1
src/assets/icons/dict.svg
Normal file
1
src/assets/icons/dict.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1752905819007" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4503" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M934.911577 142.847857A140.799859 140.799859 0 0 0 794.111718 0H427.008085a38.399962 38.399962 0 0 0 0 76.799923h63.999936v324.095676a38.399962 38.399962 0 0 0 63.487937 28.671971l85.503914-74.751925 80.895919 74.239926a38.399962 38.399962 0 0 0 26.111974 10.23999 37.887962 37.887962 0 0 0 15.359985-3.071997 38.399962 38.399962 0 0 0 23.039977-35.327965V78.847921h8.703991a63.999936 63.999936 0 0 1 63.999936 63.999936v582.655417H210.944301a147.455853 147.455853 0 0 0-72.703927 19.455981V142.847857A63.999936 63.999936 0 0 1 204.800307 78.847921h30.719969a38.399962 38.399962 0 0 0 0-76.799923H204.800307a140.799859 140.799859 0 0 0-143.359856 140.799859V870.39913a148.991851 148.991851 0 0 0 149.50385 153.599846h685.567314a38.399962 38.399962 0 0 0 0-76.799923c-41.471959 0-51.199949-38.911961-51.199948-71.167929a102.399898 102.399898 0 0 1 51.199948-71.679928 38.399962 38.399962 0 0 0 38.399962-38.399962 36.351964 36.351964 0 0 0 0-7.679992 36.351964 36.351964 0 0 0 0-7.679993z m-225.791774 171.007829L665.599846 274.943725a38.399962 38.399962 0 0 0-51.199948 0l-48.127952 41.983958V78.847921h141.311858z m73.727926 631.295369H210.944301a72.191928 72.191928 0 0 1-72.703927-70.14393 70.655929 70.655929 0 0 1 21.503978-51.199949 72.191928 72.191928 0 0 1 51.199949-21.503978h580.09542a143.359857 143.359857 0 0 0-21.503979 71.679928 190.46381 190.46381 0 0 0 12.799988 71.167929z" p-id="4504"></path></svg>
|
After Width: | Height: | Size: 1.7 KiB |
1
src/assets/icons/menu.svg
Normal file
1
src/assets/icons/menu.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1752906446737" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4093" id="mx_n_1752906446738" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M133.310936 296.552327l757.206115 0c19.781623 0 35.950949-16.169326 35.950949-35.950949 0-19.781623-15.997312-35.950949-35.950949-35.950949L133.310936 224.650428c-19.781623 0-35.950949 16.169326-35.950949 35.950949C97.359987 280.383 113.529313 296.552327 133.310936 296.552327z" fill="#575B66" p-id="4094"></path><path d="M890.51705 476.135058 133.310936 476.135058c-19.781623 0-35.950949 16.169326-35.950949 35.950949 0 19.781623 16.169326 35.950949 35.950949 35.950949l757.206115 0c19.781623 0 35.950949-16.169326 35.950949-35.950949C926.467999 492.304384 910.298673 476.135058 890.51705 476.135058z" fill="#575B66" p-id="4095"></path><path d="M890.51705 727.447673 133.310936 727.447673c-19.781623 0-35.950949 15.997312-35.950949 35.950949s16.169326 35.950949 35.950949 35.950949l757.206115 0c19.781623 0 35.950949-15.997312 35.950949-35.950949S910.298673 727.447673 890.51705 727.447673z" fill="#575B66" p-id="4096"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/assets/icons/system.svg
Normal file
1
src/assets/icons/system.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1752906142706" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8590" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M913.493333 464.426667a53.76 53.76 0 0 0-37.76-39.466667l-13.013333-2.986667a131.413333 131.413333 0 0 1-89.6-156.373333l3.84-12.373333a54.186667 54.186667 0 0 0-15.146667-52.48A369.92 369.92 0 0 0 714.666667 170.666667a372.693333 372.693333 0 0 0-49.92-25.6 53.546667 53.546667 0 0 0-52.906667 13.013333l-9.173333 9.813333a130.773333 130.773333 0 0 1-180.053334 0l-8.746666-9.6a53.546667 53.546667 0 0 0-52.906667-13.013333A370.56 370.56 0 0 0 310.613333 170.666667a369.493333 369.493333 0 0 0-47.146666 30.506666 53.76 53.76 0 0 0-15.36 52.48l3.84 12.373334a131.2 131.2 0 0 1-89.813334 155.946666l-12.8 2.986667a53.76 53.76 0 0 0-37.546666 39.466667 368.426667 368.426667 0 0 0-2.773334 56.32A366.506667 366.506667 0 0 0 111.786667 576 53.973333 53.973333 0 0 0 149.333333 616.533333l12.373334 2.773334a131.413333 131.413333 0 0 1 90.24 156.8l-3.84 12.373333a53.76 53.76 0 0 0 15.36 52.48 362.666667 362.666667 0 0 0 47.146666 30.506667A362.666667 362.666667 0 0 0 360.746667 896a53.76 53.76 0 0 0 52.906666-12.8l8.746667-8.533333a130.986667 130.986667 0 0 1 180.48 0l8.746667 9.386666a53.76 53.76 0 0 0 52.906666 12.8 384 384 0 0 0 50.133334-25.6 366.293333 366.293333 0 0 0 47.146666-30.506666 53.973333 53.973333 0 0 0 15.36-52.48l-3.84-12.8A131.413333 131.413333 0 0 1 863.573333 618.666667l12.373334-2.773334A53.546667 53.546667 0 0 0 913.706667 576a368 368 0 0 0 3.626666-55.466667 371.413333 371.413333 0 0 0-3.84-56.106666zM512 642.133333a130.133333 130.133333 0 1 1 129.706667-130.133333A129.92 129.92 0 0 1 512 642.133333z" p-id="8591"></path></svg>
|
After Width: | Height: | Size: 1.8 KiB |
1
src/assets/icons/user.svg
Normal file
1
src/assets/icons/user.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1752905909586" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5604" width="64" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M512 1022.1056c-282.3168 0-511.232-228.864-511.232-511.0784S229.632 0 512 0c282.3168 0 511.232 228.8128 511.232 511.0272 0 282.2656-228.864 511.0784-511.232 511.0784z m0-926.2592a415.2832 415.2832 0 0 0-415.3856 415.232c0 107.2128 41.0624 204.6464 107.8272 278.3232 60.16-29.1328 38.0416-4.9152 116.736-37.2736 80.5888-33.1264 99.6352-44.6464 99.6352-44.6464l0.768-76.288s-30.1568-22.8864-39.5264-94.72c-18.8928 5.4272-25.088-22.016-26.2144-39.424-1.024-16.896-10.9568-69.4784 12.0832-64.7168-4.7104-35.1744-8.0896-66.8672-6.4-83.6608 5.7344-58.88 62.976-120.5248 151.0912-124.9792 103.68 4.4544 144.7424 66.048 150.528 124.928 1.6384 16.8448-2.048 48.5376-6.7584 83.6096 23.04-4.6592 13.0048 47.872 11.8784 64.7168-1.024 17.408-7.3728 44.7488-26.2144 39.3728-9.4208 71.7824-39.5776 94.464-39.5776 94.464l0.7168 75.9296s19.0976 10.8032 99.6352 43.9296c78.6944 32.3584 56.576 9.5744 116.736 38.7584a413.184 413.184 0 0 0 107.776-278.3744A415.232 415.232 0 0 0 512 95.7952z" p-id="5605"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
@ -1,27 +1,39 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-modal v-model:show="show">
|
<n-modal v-model:show="show">
|
||||||
<n-card style="width: 450px" title="角色库" :bordered="false" size="huge" role="dialog" aria-modal="true">
|
<n-card style="width: 800px" title="角色库" :bordered="false" size="huge" role="dialog" aria-modal="true">
|
||||||
<n-table :bordered="false" :single-line="false">
|
<n-table :bordered="false" :single-line="false">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>角色Code</th>
|
<th>角色Code</th>
|
||||||
<th>角色Name</th>
|
<th>角色Name</th>
|
||||||
<th>操作</th>
|
<th style="text-align: center;">操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="item in list" :key="item.id">
|
<tr v-for="item in list" :key="item.id">
|
||||||
<td>{{ item.name }}</td>
|
<td>{{ item.name }}</td>
|
||||||
<td>{{ item.normalizedName }}</td>
|
<td>{{ item.normalizedName }}</td>
|
||||||
<td>
|
<td align="center">
|
||||||
<n-button type="primary" size="small" @click="chooseRole(item)">选择</n-button>
|
<n-button type="primary" size="small" @click="chooseRole(item)">选择</n-button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr v-show="showNewTr">
|
||||||
|
<td :colspan="3">
|
||||||
|
<n-input-group>
|
||||||
|
<n-input v-model:value="addRole.rolename" placeholder="请输入角色编码(英文)"
|
||||||
|
:style="{ width: '40%' }" size="small" :disabled="loading" clearable />
|
||||||
|
<n-input v-model:value="addRole.normalizedname" placeholder="请输入角色中文"
|
||||||
|
:style="{ width: '40%' }" size="small" :disabled="loading" clearable />
|
||||||
|
<n-button :style="{ width: '20%' }" size="small" type="primary" @click="handleAddNewRole"
|
||||||
|
:disabled="loading">新增</n-button>
|
||||||
|
</n-input-group>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</n-table>
|
</n-table>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="flex-content right">
|
<div class="flex-content right">
|
||||||
<n-button type="primary" size="small">新增角色</n-button>
|
<n-button type="primary" size="small" @click="showNewTr = true">新增角色</n-button>
|
||||||
<n-button @click="show = false" size="small">关 闭</n-button>
|
<n-button @click="show = false" size="small">关 闭</n-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -30,17 +42,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
import { getRoleList } from '@/api/roleApi';
|
import { getRoleList, addNewRole } from '@/api/roleApi';
|
||||||
import { useMessage } from 'naive-ui';
|
import { useMessage } from 'naive-ui';
|
||||||
import type { RoleListReturn } from '@/api/roleApi';
|
import type { RoleListReturn } from '@/api/roleApi';
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: 'choose', row:RoleListReturn): void
|
(event: 'choose', row: RoleListReturn): void
|
||||||
}>()
|
}>()
|
||||||
const show = ref(false);
|
const show = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
const showNewTr = ref(false);
|
||||||
const list = ref([]);
|
const list = ref([]);
|
||||||
const message = useMessage();
|
const message = useMessage();
|
||||||
|
const addRole = ref({
|
||||||
const chooseRole = (row:RoleListReturn) => {
|
rolename: '',
|
||||||
|
normalizedname: ''
|
||||||
|
});
|
||||||
|
const chooseRole = (row: RoleListReturn) => {
|
||||||
emit('choose', toRaw(row));
|
emit('choose', toRaw(row));
|
||||||
show.value = false;
|
show.value = false;
|
||||||
}
|
}
|
||||||
@ -56,6 +73,21 @@ const init = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
init();
|
init();
|
||||||
|
const handleAddNewRole = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
await addNewRole(addRole.value);
|
||||||
|
message.success('新增角色成功!');
|
||||||
|
addRole.value.rolename = void 0;
|
||||||
|
addRole.value.normalizedname = void 0;
|
||||||
|
init();
|
||||||
|
showNewTr.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
message.error(error.message);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
defineExpose({
|
defineExpose({
|
||||||
openDialog
|
openDialog
|
||||||
})
|
})
|
||||||
|
@ -12,13 +12,21 @@ export const useAppStore = defineStore(
|
|||||||
// 设置菜单列表
|
// 设置菜单列表
|
||||||
const setMenuList = (menu: MenuNode[]) => {
|
const setMenuList = (menu: MenuNode[]) => {
|
||||||
menuApp.menuList.length = 0;
|
menuApp.menuList.length = 0;
|
||||||
menu.forEach(item => {
|
menu.forEach((item) => {
|
||||||
menuApp.menuList.push(item);
|
menuApp.menuList.push(item);
|
||||||
})
|
});
|
||||||
|
};
|
||||||
|
// 重置仓库
|
||||||
|
const reset = () => {
|
||||||
|
Object.assign(menuApp, {
|
||||||
|
isExpaned: true, //折叠控制
|
||||||
|
menuList: [],
|
||||||
|
});
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
menuApp,
|
menuApp,
|
||||||
setMenuList
|
setMenuList,
|
||||||
|
reset,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{ persist: true }
|
{ persist: true }
|
||||||
|
@ -33,9 +33,24 @@ export const useUserStore = defineStore(
|
|||||||
const setUserInfo = (data: UserInfo) => {
|
const setUserInfo = (data: UserInfo) => {
|
||||||
Object.assign(userInfo, data);
|
Object.assign(userInfo, data);
|
||||||
};
|
};
|
||||||
|
const reset = () => {
|
||||||
|
Object.assign(userInfo, {
|
||||||
|
birthday: void 0,
|
||||||
|
config: void 0,
|
||||||
|
description: void 0,
|
||||||
|
email: "",
|
||||||
|
id: "",
|
||||||
|
jobCode: void 0,
|
||||||
|
jobName: void 0,
|
||||||
|
menuName: void 0,
|
||||||
|
sex: "",
|
||||||
|
userName: "",
|
||||||
|
});
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
userInfo,
|
userInfo,
|
||||||
setUserInfo
|
setUserInfo,
|
||||||
|
reset,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{ persist: true }
|
{ persist: true }
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
</n-tag>
|
</n-tag>
|
||||||
<p class="time">2025-07-05</p>
|
<p class="time">2025-07-05</p>
|
||||||
</div>
|
</div>
|
||||||
<img src="@/assets/icons/mainproject.svg">
|
<svg-icon color="#4090EF" iconClass="mainproject" width="50px" height="50px"></svg-icon>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -84,11 +84,6 @@ import LsEmpty from '@/components/Ls-UI/LsEmpty.vue';
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<main>
|
<main>
|
||||||
<div class="icon__item">
|
<div class="icon__item">
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<img src="@/assets/icons/order.svg">
|
<svg-icon iconClass="order" color="#FFF" width="25px" height="25px"></svg-icon>
|
||||||
</div>
|
</div>
|
||||||
<p>系统菜单</p>
|
<p>系统菜单</p>
|
||||||
</div>
|
</div>
|
||||||
@ -40,11 +40,6 @@ main {
|
|||||||
height: 30px;
|
height: 30px;
|
||||||
background:$primaryColor;
|
background:$primaryColor;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
img{
|
|
||||||
height: 25px;
|
|
||||||
width: 25px;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
> p{
|
> p{
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
@ -27,8 +27,10 @@ import {
|
|||||||
CaretDownOutline
|
CaretDownOutline
|
||||||
} from '@vicons/ionicons5';
|
} from '@vicons/ionicons5';
|
||||||
import { NIcon } from 'naive-ui';
|
import { NIcon } from 'naive-ui';
|
||||||
|
import { useAppStore } from '@/store/app';
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
function renderIcon(icon: Component) {
|
function renderIcon(icon: Component) {
|
||||||
return () => {
|
return () => {
|
||||||
@ -58,6 +60,8 @@ const options = [
|
|||||||
const handleSelect = (key: string | number) => {
|
const handleSelect = (key: string | number) => {
|
||||||
if (key === 'logout') {
|
if (key === 'logout') {
|
||||||
removeToken();
|
removeToken();
|
||||||
|
userStore.reset();
|
||||||
|
appStore.reset();
|
||||||
router.push('/');
|
router.push('/');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<ls-list-button @search="init" @reset="resetList"></ls-list-button>
|
<ls-list-button @search="init" @reset="resetList"></ls-list-button>
|
||||||
</header>
|
</header>
|
||||||
<main class="table-main" ref="tableMainRef">
|
<main class="table-main" ref="tableMainRef">
|
||||||
<n-data-table v-if="height" :columns="columns" :data="data" :max-height="`${height}px`"
|
<n-data-table v-if="height" :columns="columns" :data="data" :loading="loading" :max-height="`${height}px`"
|
||||||
:min-height="`${height}px`">
|
:min-height="`${height}px`">
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<LsEmpty type="no-data" title="暂无数据" description="Not Found 404"></LsEmpty>
|
<LsEmpty type="no-data" title="暂无数据" description="Not Found 404"></LsEmpty>
|
||||||
@ -48,19 +48,32 @@
|
|||||||
</template>
|
</template>
|
||||||
</n-card>
|
</n-card>
|
||||||
</n-modal>
|
</n-modal>
|
||||||
|
<n-modal v-model:show="addMenuDialog">
|
||||||
|
<n-card style="width: 450px" title="菜单分配" :bordered="false" size="huge" role="dialog" aria-modal="true">
|
||||||
|
<n-select v-model:value="menuChoose.menuCode" multiple :options="menuOptions" @update:value="handleUpdateValue" />
|
||||||
|
<template #footer>
|
||||||
|
<div class="flex-content right">
|
||||||
|
<n-button type="primary" size="small" @click="handleAssignMenu">分 配</n-button>
|
||||||
|
<n-button @click="addMenuDialog = false" size="small">关 闭</n-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</n-card>
|
||||||
|
</n-modal>
|
||||||
<!-- 角色库 -->
|
<!-- 角色库 -->
|
||||||
<LsRoleBase ref="roleRef" @choose="chooseRole"></LsRoleBase>
|
<LsRoleBase ref="roleRef" @choose="chooseRole"></LsRoleBase>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts'>
|
||||||
import { Server } from '@vicons/ionicons5';
|
import { Server } from '@vicons/ionicons5';
|
||||||
import { getUserList, deleteUser, enableRole } from '@/api/roleApi';
|
import { getUserList, deleteUser, enableRole, assignMenu } from '@/api/roleApi';
|
||||||
import { DataTableColumns, NButton, NTag, useDialog, useMessage } from 'naive-ui';
|
import { DataTableColumns, NButton, NTag, SelectOption, useDialog, useMessage } from 'naive-ui';
|
||||||
|
import { getDict } from '@/api/dictApi';
|
||||||
import LsEmpty from '@/components/Ls-UI/LsEmpty.vue';
|
import LsEmpty from '@/components/Ls-UI/LsEmpty.vue';
|
||||||
import LsRoleBase from '@/components/Ls-UI/LsRoleBase.vue';
|
import LsRoleBase from '@/components/Ls-UI/LsRoleBase.vue';
|
||||||
|
|
||||||
const message = useMessage();
|
const message = useMessage();
|
||||||
const tableMainRef = ref<HTMLElement | null>(null);
|
const tableMainRef = ref<HTMLElement | null>(null);
|
||||||
|
const loading = ref(false);
|
||||||
const roleRef = ref<InstanceType<typeof LsRoleBase> | null>(null);
|
const roleRef = ref<InstanceType<typeof LsRoleBase> | null>(null);
|
||||||
const queryInfo = reactive({
|
const queryInfo = reactive({
|
||||||
roleName: void 0,
|
roleName: void 0,
|
||||||
@ -72,11 +85,17 @@ const pagination = reactive<PageController>({
|
|||||||
page: 1,
|
page: 1,
|
||||||
});
|
});
|
||||||
const options = ref([]);
|
const options = ref([]);
|
||||||
|
const menuOptions = ref([])
|
||||||
|
const menuChoose = ref({
|
||||||
|
menuCode: [],
|
||||||
|
menuName: []
|
||||||
|
})
|
||||||
|
|
||||||
const data = ref([]);
|
const data = ref([]);
|
||||||
const height = ref(null);
|
const height = ref(null);
|
||||||
const dialog = useDialog();
|
const dialog = useDialog();
|
||||||
const addRoleDialog = ref(false);
|
const addRoleDialog = ref(false);
|
||||||
|
const addMenuDialog = ref(false);
|
||||||
const operationUuid = ref('');
|
const operationUuid = ref('');
|
||||||
const roleName = ref(''); //授权角色
|
const roleName = ref(''); //授权角色
|
||||||
|
|
||||||
@ -212,7 +231,10 @@ const columns = createColumns({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleMenuAssign(rowData) {
|
handleMenuAssign(rowData) {
|
||||||
message.error(`我点击了${rowData.userName}`);
|
addMenuDialog.value = true;
|
||||||
|
menuChoose.value.menuCode = rowData.menuCode ? rowData.menuCode.split(',') : [];
|
||||||
|
menuChoose.value.menuName = rowData.menuName ? rowData.menuName.split(',') : [];
|
||||||
|
operationUuid.value = rowData.id;
|
||||||
},
|
},
|
||||||
handleAssignJob(rowData) {
|
handleAssignJob(rowData) {
|
||||||
message.error(`我点击了${rowData.userName}`);
|
message.error(`我点击了${rowData.userName}`);
|
||||||
@ -220,6 +242,7 @@ const columns = createColumns({
|
|||||||
})
|
})
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
try {
|
try {
|
||||||
|
loading.value = true;
|
||||||
const { users, totalCount } = await getUserList({
|
const { users, totalCount } = await getUserList({
|
||||||
...pagination,
|
...pagination,
|
||||||
...queryInfo
|
...queryInfo
|
||||||
@ -228,6 +251,8 @@ const init = async () => {
|
|||||||
data.value = users;
|
data.value = users;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error(error.message);
|
message.error(error.message);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const resetList = () => {
|
const resetList = () => {
|
||||||
@ -247,6 +272,7 @@ onMounted(() => {
|
|||||||
const openRoleDialog = () => {
|
const openRoleDialog = () => {
|
||||||
roleRef.value?.openDialog();
|
roleRef.value?.openDialog();
|
||||||
}
|
}
|
||||||
|
// 授权角色
|
||||||
const handleEnableRole = async () => {
|
const handleEnableRole = async () => {
|
||||||
try {
|
try {
|
||||||
const query = {
|
const query = {
|
||||||
@ -260,23 +286,50 @@ const handleEnableRole = async () => {
|
|||||||
message.error(error.message);
|
message.error(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 分配菜单
|
||||||
|
const handleAssignMenu = async () => {
|
||||||
|
try {
|
||||||
|
const req = {
|
||||||
|
id: operationUuid.value,
|
||||||
|
menuCode: menuChoose.value.menuCode.join(','),
|
||||||
|
menuName: menuChoose.value.menuName.join(',')
|
||||||
|
}
|
||||||
|
await assignMenu(req);
|
||||||
|
message.success('分配成功!');
|
||||||
|
addMenuDialog.value = false;
|
||||||
|
init();
|
||||||
|
} catch (error) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const handleUpdateValue = (value: string, option: SelectOption[]) => {
|
||||||
|
menuChoose.value.menuName = option.map(item => item.label)
|
||||||
|
}
|
||||||
// 获取角色
|
// 获取角色
|
||||||
const initRoleList = async () => {
|
const initRoleList = async () => {
|
||||||
try {
|
try {
|
||||||
const result = await getRoleList();
|
const result = await getRoleList();
|
||||||
options.value = result.map(item => {
|
options.value = result.map(item => {
|
||||||
return {
|
return {
|
||||||
label:item.normalizedName,
|
label: item.normalizedName,
|
||||||
value:item.name
|
value: item.name
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const dict = await getDict('menuCode');
|
||||||
|
if (dict && Array.isArray(dict) && dict.length > 0) {
|
||||||
|
menuOptions.value = dict.map(item => {
|
||||||
|
return {
|
||||||
|
label: item.label,
|
||||||
|
value: item.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error(error instanceof Error ? error.message : error);
|
message.error(error instanceof Error ? error.message : error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 赋予角色
|
// 赋予角色
|
||||||
const chooseRole = (row) => {
|
const chooseRole = (row) => {
|
||||||
console.log(row, 'row');
|
|
||||||
roleName.value = row.name;
|
roleName.value = row.name;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -44,8 +44,8 @@
|
|||||||
</template>
|
</template>
|
||||||
<n-input v-model:value="parentForm.path" placeholder="请输入菜单路径" />
|
<n-input v-model:value="parentForm.path" placeholder="请输入菜单路径" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="菜单编码" path="menuCode">
|
<n-form-item label="菜单权限" path="menuCode">
|
||||||
<n-input v-model:value="parentForm.menuCode" placeholder="请输入菜单编码" />
|
<n-select v-model:value="parentForm.menuCode" multiple :options="menuOptions" placeholder="请选择菜单权限" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="菜单图标" path="icon">
|
<n-form-item label="菜单图标" path="icon">
|
||||||
<n-select v-model:value="parentForm.icon" :options="iconOptions" filterable clearable placeholder="请选择图标名称"
|
<n-select v-model:value="parentForm.icon" :options="iconOptions" filterable clearable placeholder="请选择图标名称"
|
||||||
@ -125,8 +125,8 @@
|
|||||||
</template>
|
</template>
|
||||||
<n-input v-model:value="childForm.path" placeholder="请输入菜单路径" />
|
<n-input v-model:value="childForm.path" placeholder="请输入菜单路径" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="菜单编码" path="menuCode">
|
<n-form-item label="菜单权限" path="menuCode">
|
||||||
<n-input v-model:value="childForm.menuCode" placeholder="请输入菜单编码" />
|
<n-select v-model:value="childForm.menuCode" multiple :options="menuOptions" placeholder="请选择菜单权限" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item label="菜单图标" path="icon">
|
<n-form-item label="菜单图标" path="icon">
|
||||||
<n-select v-model:value="childForm.icon" :options="iconOptions" filterable clearable placeholder="请选择图标名称"
|
<n-select v-model:value="childForm.icon" :options="iconOptions" filterable clearable placeholder="请选择图标名称"
|
||||||
@ -192,8 +192,9 @@ import {
|
|||||||
type MenuNode,
|
type MenuNode,
|
||||||
type RawMenu
|
type RawMenu
|
||||||
} from '@/api/menu'
|
} from '@/api/menu'
|
||||||
import { FormInst, FormRules, NButton, NIcon, NSpace, NTag, SelectOption, TreeOption, useDialog, useMessage } from 'naive-ui'
|
import { FormInst, FormRules, NButton, NIcon, NSpace, NTag, SelectOption, TreeOption, useDialog, useMessage } from 'naive-ui';
|
||||||
import SvgIcon from '@/components/SvgIcon.vue'
|
import SvgIcon from '@/components/SvgIcon.vue';
|
||||||
|
import { getMenuName } from './utils'
|
||||||
|
|
||||||
// 状态管理
|
// 状态管理
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@ -203,11 +204,17 @@ const menuTree = ref<TreeOption[]>([])
|
|||||||
const showParentModal = ref(false);
|
const showParentModal = ref(false);
|
||||||
const parentFormRef = ref<FormInst | null>(null);
|
const parentFormRef = ref<FormInst | null>(null);
|
||||||
const menuType = ref<'menu' | 'list'>('menu'); //菜单类型
|
const menuType = ref<'menu' | 'list'>('menu'); //菜单类型
|
||||||
const parentForm = ref<Omit<RawMenu, 'uuid' | 'parentId'>>({
|
const menuOptions = ref([]); //初始化菜单权限
|
||||||
|
const adaptabilityOptions = ref([]);// 适配方式选项
|
||||||
|
interface MenuVO extends Omit<RawMenu, 'menuCode'> {
|
||||||
|
menuCode: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentForm = ref<Omit<MenuVO, 'uuid' | 'parentId'>>({
|
||||||
path: '',
|
path: '',
|
||||||
label: '',
|
label: '',
|
||||||
icon: '',
|
icon: '',
|
||||||
menuCode: '',
|
menuCode: [],
|
||||||
menuName: '',
|
menuName: '',
|
||||||
adaptability: 'pc',
|
adaptability: 'pc',
|
||||||
component: '',
|
component: '',
|
||||||
@ -271,12 +278,12 @@ const renderLabel = (option: IconOption) => {
|
|||||||
// 子级菜单表单相关
|
// 子级菜单表单相关
|
||||||
const showChildModal = ref(false)
|
const showChildModal = ref(false)
|
||||||
const childFormRef = ref<FormInst | null>(null)
|
const childFormRef = ref<FormInst | null>(null)
|
||||||
const childForm = ref<Omit<RawMenu, 'uuid'>>({
|
const childForm = ref<Omit<MenuVO, 'uuid'>>({
|
||||||
parentId: '',
|
parentId: '',
|
||||||
path: '',
|
path: '',
|
||||||
label: '',
|
label: '',
|
||||||
icon: '',
|
icon: '',
|
||||||
menuCode: '',
|
menuCode: [],
|
||||||
menuName: '',
|
menuName: '',
|
||||||
adaptability: 'pc',
|
adaptability: 'pc',
|
||||||
component: '',
|
component: '',
|
||||||
@ -294,30 +301,32 @@ const childRules: FormRules = {
|
|||||||
const isEditChild = ref(false)
|
const isEditChild = ref(false)
|
||||||
const currentChildId = ref('')
|
const currentChildId = ref('')
|
||||||
|
|
||||||
// 适配方式选项
|
// 初始化字典
|
||||||
const adaptabilityOptions = ref([]);
|
const initDict = async () => {
|
||||||
|
try {
|
||||||
getDict("page_adaptability").then((res) => {
|
const [res1, res2] = await Promise.all([getDict("page_adaptability"), getDict('menuCode')]);
|
||||||
console.log('获取适配方式选项', res);
|
adaptabilityOptions.value = res1.map(item => {
|
||||||
adaptabilityOptions.value = res.map(item => {
|
return {
|
||||||
const {label, value, ...rest} = item;
|
label: item.label,
|
||||||
return {
|
value: item.value,
|
||||||
label: label,
|
}
|
||||||
value: value,
|
})
|
||||||
}
|
menuOptions.value = res2.map(item => {
|
||||||
})
|
return {
|
||||||
}).catch((errors) => {
|
label: item.label,
|
||||||
console.log('获取适配方式选项失败', errors);
|
value: item.value
|
||||||
message.error('获取适配方式选项失败');
|
}
|
||||||
})
|
})
|
||||||
|
} catch (error) {
|
||||||
|
message.error(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
// 计算属性
|
// 计算属性
|
||||||
const parentModalTitle = computed(() => (isEditParent.value ? '编辑父级菜单' : '添加父级菜单'))
|
const parentModalTitle = computed(() => (isEditParent.value ? '编辑父级菜单' : '添加父级菜单'))
|
||||||
const childModalTitle = computed(() => (isEditChild.value ? '编辑子级菜单' : '添加子级菜单'))
|
const childModalTitle = computed(() => (isEditChild.value ? '编辑子级菜单' : '添加子级菜单'))
|
||||||
|
|
||||||
// 父级菜单选项
|
// 父级菜单选项
|
||||||
const parentMenuOptions = computed<SelectOption[]>(() => {
|
const parentMenuOptions = computed<SelectOption[]>(() => {
|
||||||
console.log(menuTree.value, 'menuTree.value');
|
|
||||||
return menuTree.value.map(menu => ({
|
return menuTree.value.map(menu => ({
|
||||||
label: menu.label,
|
label: menu.label,
|
||||||
value: menu.key
|
value: menu.key
|
||||||
@ -336,6 +345,7 @@ const { stop } = watch(menuType, (newVal) => {
|
|||||||
})
|
})
|
||||||
// 生命周期钩子
|
// 生命周期钩子
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
initDict();
|
||||||
loadSvgIcons();
|
loadSvgIcons();
|
||||||
fetchMenuData();
|
fetchMenuData();
|
||||||
});
|
});
|
||||||
@ -344,7 +354,6 @@ onBeforeUnmount(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const renderTreeLabel = ({ option }) => {
|
const renderTreeLabel = ({ option }) => {
|
||||||
console.log(option,'option');
|
|
||||||
return h('div', {
|
return h('div', {
|
||||||
style: {
|
style: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -364,7 +373,7 @@ const renderTreeLabel = ({ option }) => {
|
|||||||
h(NTag, {
|
h(NTag, {
|
||||||
type: option?.rawData.status === 'enable' ? 'success' : 'error',
|
type: option?.rawData.status === 'enable' ? 'success' : 'error',
|
||||||
size: 'small'
|
size: 'small'
|
||||||
}, option?.rawData.status === 'enable' ? 'Enabled' : 'Disabled')
|
}, option?.rawData.status === 'enable' ? '启用' : '停用')
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -480,7 +489,7 @@ const handleAddParent = () => {
|
|||||||
path: '',
|
path: '',
|
||||||
label: '',
|
label: '',
|
||||||
icon: '',
|
icon: '',
|
||||||
menuCode: '',
|
menuCode: [],
|
||||||
menuName: '',
|
menuName: '',
|
||||||
adaptability: 'pc',
|
adaptability: 'pc',
|
||||||
component: '',
|
component: '',
|
||||||
@ -499,7 +508,7 @@ const handleEditParent = (menu: MenuNode) => {
|
|||||||
path: menu.path,
|
path: menu.path,
|
||||||
label: menu.label,
|
label: menu.label,
|
||||||
icon: menu.icon,
|
icon: menu.icon,
|
||||||
menuCode: menu.menuCode,
|
menuCode: menu.menuCode ? menu.menuCode.split(',') : [],
|
||||||
menuName: menu.menuName,
|
menuName: menu.menuName,
|
||||||
adaptability: menu.adaptability,
|
adaptability: menu.adaptability,
|
||||||
component: menu.component,
|
component: menu.component,
|
||||||
@ -518,10 +527,16 @@ const handleSubmitParent = () => {
|
|||||||
if (isEditParent.value) {
|
if (isEditParent.value) {
|
||||||
await editParentMenu({
|
await editParentMenu({
|
||||||
uuid: currentParentId.value,
|
uuid: currentParentId.value,
|
||||||
...parentForm.value
|
...parentForm.value,
|
||||||
|
menuCode: parentForm.value.menuCode.join(','),
|
||||||
|
menuName: getMenuName(parentForm.value.menuCode, menuOptions.value)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
await addParentMenu(parentForm.value)
|
await addParentMenu({
|
||||||
|
...parentForm.value,
|
||||||
|
menuCode: parentForm.value.menuCode.join(','),
|
||||||
|
menuName: getMenuName(parentForm.value.menuCode, menuOptions.value)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
showParentModal.value = false;
|
showParentModal.value = false;
|
||||||
message.success('操作成功!');
|
message.success('操作成功!');
|
||||||
@ -540,7 +555,7 @@ const handleAddChild = (parentId: string) => {
|
|||||||
path: '',
|
path: '',
|
||||||
label: '',
|
label: '',
|
||||||
icon: '',
|
icon: '',
|
||||||
menuCode: '',
|
menuCode: [],
|
||||||
menuName: '',
|
menuName: '',
|
||||||
adaptability: 'pc',
|
adaptability: 'pc',
|
||||||
component: '',
|
component: '',
|
||||||
@ -560,7 +575,7 @@ const handleEditChild = (menu: MenuNode) => {
|
|||||||
path: menu.path,
|
path: menu.path,
|
||||||
label: menu.label,
|
label: menu.label,
|
||||||
icon: menu.icon,
|
icon: menu.icon,
|
||||||
menuCode: menu.menuCode,
|
menuCode: menu.menuCode ? menu.menuCode.split(',') : [],
|
||||||
menuName: menu.menuName,
|
menuName: menu.menuName,
|
||||||
adaptability: menu.adaptability,
|
adaptability: menu.adaptability,
|
||||||
component: menu.component,
|
component: menu.component,
|
||||||
@ -579,10 +594,16 @@ const handleSubmitChild = () => {
|
|||||||
if (isEditChild.value) {
|
if (isEditChild.value) {
|
||||||
await eidtChildMenu({
|
await eidtChildMenu({
|
||||||
uuid: currentChildId.value,
|
uuid: currentChildId.value,
|
||||||
...childForm.value
|
...childForm.value,
|
||||||
|
menuCode: childForm.value.menuCode.join(','),
|
||||||
|
menuName: getMenuName(childForm.value.menuCode, menuOptions.value)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
await addChildMenu(childForm.value)
|
await addChildMenu({
|
||||||
|
...childForm.value,
|
||||||
|
menuCode: childForm.value.menuCode.join(','),
|
||||||
|
menuName: getMenuName(childForm.value.menuCode, menuOptions.value)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
showChildModal.value = false;
|
showChildModal.value = false;
|
||||||
message.success('操作成功!');
|
message.success('操作成功!');
|
||||||
|
10
src/views/system/menu/utils.ts
Normal file
10
src/views/system/menu/utils.ts
Normal file
@ -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(',');
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user