角色管理页面接口完成

This commit is contained in:
2026-08-27 09:52:44 +08:00
parent f5176ada20
commit d4be566459
2 changed files with 192 additions and 104 deletions
+94 -94
View File
@@ -44,10 +44,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/changeledger', path: '/changeledger',
component: 'layout.base', component: 'layout.base',
meta: { meta: {
title: 'changeledger', title: '变更台账',
i18nKey: 'route.changeledger',
icon: 'tabler:table', icon: 'tabler:table',
order: 3 order: 3,
i18nKey: 'route.changeledger'
}, },
children: [ children: [
{ {
@@ -55,9 +55,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/changeledger/mychanges', path: '/changeledger/mychanges',
component: 'view.changeledger_mychanges', component: 'view.changeledger_mychanges',
meta: { meta: {
title: 'changeledger_mychanges', title: '我发起的变更',
i18nKey: 'route.changeledger_mychanges', icon: '',
icon: '' i18nKey: 'route.changeledger_mychanges'
} }
}, },
{ {
@@ -65,9 +65,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/changeledger/workshopchanges', path: '/changeledger/workshopchanges',
component: 'view.changeledger_workshopchanges', component: 'view.changeledger_workshopchanges',
meta: { meta: {
title: 'changeledger_workshopchanges', title: '本车间变更',
i18nKey: 'route.changeledger_workshopchanges', icon: '',
icon: '' i18nKey: 'route.changeledger_workshopchanges'
} }
} }
] ]
@@ -77,10 +77,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/changestatistics', path: '/changestatistics',
component: 'layout.base$view.changestatistics', component: 'layout.base$view.changestatistics',
meta: { meta: {
title: 'changestatistics', title: '本部门变更统计',
i18nKey: 'route.changestatistics',
icon: 'ix:barchart', icon: 'ix:barchart',
order: 3 order: 3,
i18nKey: 'route.changestatistics'
} }
}, },
{ {
@@ -88,10 +88,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/docs', path: '/docs',
component: 'layout.base', component: 'layout.base',
meta: { meta: {
title: 'docs', title: '资料管理',
i18nKey: 'route.docs',
icon: 'mage:book', icon: 'mage:book',
order: 4 order: 4,
i18nKey: 'route.docs'
}, },
children: [ children: [
{ {
@@ -99,9 +99,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/docs/archives', path: '/docs/archives',
component: 'view.docs_archives', component: 'view.docs_archives',
meta: { meta: {
title: 'docs_archives', title: '资料档案库',
i18nKey: 'route.docs_archives', icon: '',
icon: '' i18nKey: 'route.docs_archives'
} }
}, },
{ {
@@ -109,9 +109,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/docs/query', path: '/docs/query',
component: 'view.docs_query', component: 'view.docs_query',
meta: { meta: {
title: 'docs_query', title: '变更归档查询',
i18nKey: 'route.docs_query', icon: '',
icon: '' i18nKey: 'route.docs_query'
} }
} }
] ]
@@ -121,10 +121,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/factoryoverview', path: '/factoryoverview',
component: 'layout.base$view.factoryoverview', component: 'layout.base$view.factoryoverview',
meta: { meta: {
title: 'factoryoverview', title: '全工厂统计概览',
i18nKey: 'route.factoryoverview',
icon: 'ix:barchart', icon: 'ix:barchart',
order: 3 order: 3,
i18nKey: 'route.factoryoverview'
} }
}, },
{ {
@@ -132,10 +132,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/home', path: '/home',
component: 'layout.base$view.home', component: 'layout.base$view.home',
meta: { meta: {
title: 'home', title: '首页',
i18nKey: 'route.home',
icon: 'ant-design:home-outlined', icon: 'ant-design:home-outlined',
order: 1 order: 1,
i18nKey: 'route.home'
} }
}, },
{ {
@@ -144,10 +144,10 @@ export const generatedRoutes: GeneratedRoute[] = [
component: 'layout.blank$view.login', component: 'layout.blank$view.login',
props: true, props: true,
meta: { meta: {
title: 'login', title: '登录',
i18nKey: 'route.login',
constant: true, constant: true,
hideInMenu: true hideInMenu: true,
i18nKey: 'route.login'
} }
}, },
{ {
@@ -155,7 +155,7 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my', path: '/my',
component: 'layout.base', component: 'layout.base',
meta: { meta: {
title: 'my', title: '我的操作台',
i18nKey: 'route.my', i18nKey: 'route.my',
icon: 'heroicons:computer-desktop', icon: 'heroicons:computer-desktop',
order: 2 order: 2
@@ -166,9 +166,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/closeconfirm', path: '/my/closeconfirm',
component: 'view.my_closeconfirm', component: 'view.my_closeconfirm',
meta: { meta: {
title: 'my_closeconfirm', title: '关闭确认',
i18nKey: 'route.my_closeconfirm', icon: '',
icon: '' i18nKey: 'route.my_closeconfirm'
} }
}, },
{ {
@@ -176,9 +176,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/datachangecenter', path: '/my/datachangecenter',
component: 'view.my_datachangecenter', component: 'view.my_datachangecenter',
meta: { meta: {
title: 'my_datachangecenter', title: '变更数据中心',
i18nKey: 'route.my_datachangecenter', icon: '',
icon: '' i18nKey: 'route.my_datachangecenter'
} }
}, },
{ {
@@ -186,9 +186,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/effect', path: '/my/effect',
component: 'view.my_effect', component: 'view.my_effect',
meta: { meta: {
title: 'my_effect', title: '变更投入和效果',
i18nKey: 'route.my_effect', icon: '',
icon: '' i18nKey: 'route.my_effect'
} }
}, },
{ {
@@ -196,9 +196,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/highrisk', path: '/my/highrisk',
component: 'view.my_highrisk', component: 'view.my_highrisk',
meta: { meta: {
title: 'my_highrisk', title: '本专业高风险',
i18nKey: 'route.my_highrisk', icon: '',
icon: '' i18nKey: 'route.my_highrisk'
} }
}, },
{ {
@@ -206,10 +206,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/highriskdetail', path: '/my/highriskdetail',
component: 'view.my_highriskdetail', component: 'view.my_highriskdetail',
meta: { meta: {
title: 'my_highriskdetail', title: '高风险场景详情',
i18nKey: 'route.my_highriskdetail',
icon: '', icon: '',
hideInMenu: true hideInMenu: true,
i18nKey: 'route.my_highriskdetail'
} }
}, },
{ {
@@ -217,9 +217,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/initiatechange', path: '/my/initiatechange',
component: 'view.my_initiatechange', component: 'view.my_initiatechange',
meta: { meta: {
title: 'my_initiatechange', title: '发起变更',
i18nKey: 'route.my_initiatechange', icon: '',
icon: '' i18nKey: 'route.my_initiatechange'
} }
}, },
{ {
@@ -227,9 +227,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/mydraft', path: '/my/mydraft',
component: 'view.my_mydraft', component: 'view.my_mydraft',
meta: { meta: {
title: 'my_mydraft', title: '我的草稿',
i18nKey: 'route.my_mydraft', icon: '',
icon: '' i18nKey: 'route.my_mydraft'
} }
}, },
{ {
@@ -237,9 +237,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/mytask', path: '/my/mytask',
component: 'view.my_mytask', component: 'view.my_mytask',
meta: { meta: {
title: 'my_mytask', title: '我的任务',
i18nKey: 'route.my_mytask', icon: '',
icon: '' i18nKey: 'route.my_mytask'
} }
}, },
{ {
@@ -247,9 +247,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/pending', path: '/my/pending',
component: 'view.my_pending', component: 'view.my_pending',
meta: { meta: {
title: 'my_pending', title: '待我处理',
i18nKey: 'route.my_pending', icon: '',
icon: '' i18nKey: 'route.my_pending'
} }
}, },
{ {
@@ -257,9 +257,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/pendingchange', path: '/my/pendingchange',
component: 'view.my_pendingchange', component: 'view.my_pendingchange',
meta: { meta: {
title: 'my_pendingchange', title: '待投用变更',
i18nKey: 'route.my_pendingchange', icon: '',
icon: '' i18nKey: 'route.my_pendingchange'
} }
}, },
{ {
@@ -267,9 +267,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/process', path: '/my/process',
component: 'view.my_process', component: 'view.my_process',
meta: { meta: {
title: 'my_process', title: '流程演示',
i18nKey: 'route.my_process', icon: '',
icon: '' i18nKey: 'route.my_process'
} }
}, },
{ {
@@ -277,10 +277,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/processdetail', path: '/my/processdetail',
component: 'view.my_processdetail', component: 'view.my_processdetail',
meta: { meta: {
title: 'my_processdetail', title: '流程演示详情',
i18nKey: 'route.my_processdetail',
icon: '', icon: '',
hideInMenu: true hideInMenu: true,
i18nKey: 'route.my_processdetail'
} }
}, },
{ {
@@ -288,9 +288,9 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/my/pssr', path: '/my/pssr',
component: 'view.my_pssr', component: 'view.my_pssr',
meta: { meta: {
title: 'my_pssr', title: 'PSSR监督',
i18nKey: 'route.my_pssr', icon: '',
icon: '' i18nKey: 'route.my_pssr'
} }
} }
] ]
@@ -300,10 +300,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/report', path: '/report',
component: 'layout.base$view.report', component: 'layout.base$view.report',
meta: { meta: {
title: 'report', title: '统计报表',
i18nKey: 'route.report',
icon: 'ix:barchart', icon: 'ix:barchart',
order: 3 order: 3,
i18nKey: 'route.report'
} }
}, },
{ {
@@ -311,10 +311,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/riskstatistics', path: '/riskstatistics',
component: 'layout.base$view.riskstatistics', component: 'layout.base$view.riskstatistics',
meta: { meta: {
title: 'riskstatistics', title: '安全与风险统计',
i18nKey: 'route.riskstatistics',
icon: 'ix:barchart', icon: 'ix:barchart',
order: 3 order: 3,
i18nKey: 'route.riskstatistics'
} }
}, },
{ {
@@ -322,10 +322,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/signstatistics', path: '/signstatistics',
component: 'layout.base$view.signstatistics', component: 'layout.base$view.signstatistics',
meta: { meta: {
title: 'signstatistics', title: '质量会签统计',
i18nKey: 'route.signstatistics',
icon: 'ix:barchart', icon: 'ix:barchart',
order: 3 order: 3,
i18nKey: 'route.signstatistics'
} }
}, },
{ {
@@ -333,10 +333,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/systemmanage', path: '/systemmanage',
component: 'layout.base', component: 'layout.base',
meta: { meta: {
title: 'systemmanage', title: '系统设置',
i18nKey: 'route.systemmanage',
icon: 'uil:setting', icon: 'uil:setting',
order: 5 order: 5,
i18nKey: 'route.systemmanage'
}, },
children: [ children: [
{ {
@@ -344,10 +344,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/systemmanage/role', path: '/systemmanage/role',
component: 'view.systemmanage_role', component: 'view.systemmanage_role',
meta: { meta: {
title: 'systemmanage_role', title: '角色管理',
i18nKey: 'route.systemmanage_role',
icon: '', icon: '',
order: 2 order: 2,
i18nKey: 'route.systemmanage_role'
} }
}, },
{ {
@@ -355,10 +355,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/systemmanage/setting', path: '/systemmanage/setting',
component: 'view.systemmanage_setting', component: 'view.systemmanage_setting',
meta: { meta: {
title: 'systemmanage_setting', title: '系统配置',
i18nKey: 'route.systemmanage_setting',
icon: '', icon: '',
order: 4 order: 4,
i18nKey: 'route.systemmanage_setting'
} }
}, },
{ {
@@ -366,10 +366,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/systemmanage/template', path: '/systemmanage/template',
component: 'view.systemmanage_template', component: 'view.systemmanage_template',
meta: { meta: {
title: 'systemmanage_template', title: '审批模板管理',
i18nKey: 'route.systemmanage_template',
icon: '', icon: '',
order: 3 order: 3,
i18nKey: 'route.systemmanage_template'
} }
}, },
{ {
@@ -377,10 +377,10 @@ export const generatedRoutes: GeneratedRoute[] = [
path: '/systemmanage/user', path: '/systemmanage/user',
component: 'view.systemmanage_user', component: 'view.systemmanage_user',
meta: { meta: {
title: 'systemmanage_user', title: '架构及用户管理',
i18nKey: 'route.systemmanage_user',
icon: '', icon: '',
order: 1 order: 1,
i18nKey: 'route.systemmanage_user'
} }
} }
] ]
+98 -10
View File
@@ -4,7 +4,7 @@ import { useAppStore } from '@/store/modules/app';
import { Icon } from '@iconify/vue' import { Icon } from '@iconify/vue'
import { useThemeStore } from '@/store/modules/theme'; import { useThemeStore } from '@/store/modules/theme';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { NButton } from 'naive-ui'; import { NButton, NIcon } from 'naive-ui';
import { roleListApi, editRoleApi } from '@/service/api/role'; import { roleListApi, editRoleApi } from '@/service/api/role';
const router = useRouter(); const router = useRouter();
@@ -12,6 +12,9 @@ const appStore = useAppStore();
const themeStore = useThemeStore(); const themeStore = useThemeStore();
const gap = computed(() => (appStore.isMobile ? 0 : 16)); const gap = computed(() => (appStore.isMobile ? 0 : 16));
const routeTree = ref<any[]>([]);
const allPaths = ref<string[]>([]);
const defaultCheckedKeys = ref<string[]>([]);
const loading = ref<boolean>(false); const loading = ref<boolean>(false);
const btnLoading = ref<boolean>(false); const btnLoading = ref<boolean>(false);
const formRef = ref<any>(null); const formRef = ref<any>(null);
@@ -94,6 +97,12 @@ const getList = async () => {
// 设置权限 // 设置权限
const handleSetPermission = (row: any) => { const handleSetPermission = (row: any) => {
currentRole.value = JSON.parse(JSON.stringify(row)); currentRole.value = JSON.parse(JSON.stringify(row));
// 所有权限
if(currentRole.value?.perms.length===1 && currentRole.value?.perms[0] === '*'){
defaultCheckedKeys.value = allPaths.value;
}else{
defaultCheckedKeys.value = currentRole.value?.perms || [];
}
permissionModal.value = true; permissionModal.value = true;
} }
// 编辑角色 // 编辑角色
@@ -125,15 +134,82 @@ const saveRole = (e: MouseEvent) => {
// 保存权限 // 保存权限
const savePermission = async () => { const savePermission = async () => {
btnLoading.value = true; btnLoading.value = true;
setTimeout(() => { currentRole.value.perms = defaultCheckedKeys.value;
try {
await editRoleApi(currentRole.value);
window.$message?.success('操作成功') window.$message?.success('操作成功')
btnLoading.value = false; btnLoading.value = false;
permissionModal.value = false; permissionModal.value = false;
}, 1000) getList();
} finally {
btnLoading.value = false;
}
}
// 更新选中权限
const updateCheckedKeys = (keys: string[]) => {
defaultCheckedKeys.value = keys;
} }
// 复制title到顶层
const copyTitleToTop = (node:any) => {
// 创建新节点,复制原节点所有属性
const newNode = { ...node }
// 如果存在 meta.title,则复制到顶层
if (node.meta?.title) {
newNode.title = node.meta.title
} else {
// 可选:没有 title 时用 name 代替
newNode.title = node.name || ''
}
// 如果有 children,递归处理每个子节点
if (Array.isArray(newNode.children) && newNode.children.length > 0) {
newNode.children = newNode.children.map((child:any) => copyTitleToTop(child))
}
return newNode
}
// 获取所有路由路径
const getAllPaths = (tree:any) => {
let paths:string[] = []
tree.forEach((node:any) => {
if (node.path) paths.push(node.path)
if (Array.isArray(node.children) && node.children.length) {
paths = paths.concat(getAllPaths(node.children))
}
})
return paths
}
// 获取所有路由
const getAllRoutes = () => {
const filtered = router.getRoutes().filter((item:any) => {
// 条件1:有name且非常量
if (item.name === undefined || item.meta?.constant === true) return false;
// 条件2path中斜杠数量 < 2(即只有一级)
const path = item.path || '';
const slashCount = (path.match(/\//g) || []).length;
if (slashCount >= 2) return false;
return true;
})
const tree = filtered.map((item:any) => copyTitleToTop(item));
routeTree.value = tree;
allPaths.value = getAllPaths(tree);
}
// tree自定义渲染图标
const renderIcon = (node:any) => {
// 如果节点没有 children 或 children 为空数组,则不显示图标
if (!node.option.children || node.option.children.length === 0) {
return null; // 返回 null 表示不渲染任何图标
}
// 有子节点:返回 undefined 表示使用默认展开图标,也可自定义
return h(Icon,{
icon: node.option.expanded ? 'bi:caret-down-fill' : 'bi:caret-right-fill',
class: 'size-12px',
});
};
onMounted(() => { onMounted(() => {
const allRoutes = router.getRoutes(); getAllRoutes();
getList() getList()
}) })
</script> </script>
@@ -192,12 +268,24 @@ onMounted(() => {
<!-- 设置权限抽屉 --> <!-- 设置权限抽屉 -->
<NDrawer v-model:show="permissionModal" :width="502" placement="right"> <NDrawer v-model:show="permissionModal" :width="502" placement="right">
<NDrawerContent :title="`设置权限-${currentRole.name}`" closable> <NDrawerContent :title="`设置权限-${currentRole.name}`" closable>
<template #footer> <NTree
<div class="flex justify-end gap-[10px]"> block-line
<NButton @click="permissionModal = false">取消</NButton> cascade
<NButton type="primary" :loading="btnLoading" @click="savePermission">保存</NButton> checkable
</div> key-field="path"
</template> label-field="title"
:selectable="false"
:data="routeTree"
:default-checked-keys="defaultCheckedKeys"
@update:checked-keys="updateCheckedKeys"
:render-switcher-icon="renderIcon"
/>
<template #footer>
<div class="flex justify-end gap-[10px]">
<NButton @click="permissionModal = false">取消</NButton>
<NButton type="primary" :loading="btnLoading" @click="savePermission">保存</NButton>
</div>
</template>
</NDrawerContent> </NDrawerContent>
</NDrawer> </NDrawer>
</NCard> </NCard>