feat: 接入权限接口

This commit is contained in:
xy
2026-09-24 08:31:21 +08:00
parent 93fb5fd2c4
commit e5b5412322
24 changed files with 2398 additions and 1738 deletions
+57 -124
View File
@@ -4,31 +4,12 @@ import ClinicalLayout from '@/layouts/ClinicalLayout.vue'
import ChangePasswordView from '@/views/auth/ChangePasswordView.vue'
import ForbiddenView from '@/views/auth/ForbiddenView.vue'
import LoginView from '@/views/auth/LoginView.vue'
import DocumentPermissionsView from '@/views/management/document-permissions/index.vue'
import DocumentsView from '@/views/management/documents/index.vue'
import ReportsView from '@/views/management/reports/index.vue'
import SettingsView from '@/views/management/settings/index.vue'
import UserPermissionsView from '@/views/management/users/index.vue'
import ConsentTasksView from '@/views/workbench/signing/index.vue'
import DashboardView from '@/views/workbench/home/index.vue'
import MenuResourceView from '@/views/management/MenuResourceView.vue'
import { useLoginStore } from '@/stores/login'
import { readStoredAuthSession } from '@/utils/auth-storage'
import { mockFlags } from '@/utils/mock-flags'
const authorizedLandingRoutes = [
{ name: 'workbench-home', permission: 'sign:task:query' },
{ name: 'workbench-signing', permission: 'sign:task:query' },
{ name: 'management-documents', permission: 'sign:template:query' },
{ name: 'management-reports', permission: 'report:signing:query' },
{ name: 'management-users', permission: 'system:user:query' },
{ name: 'management-document-permissions', permission: 'sign:template:permission:query' },
] as const
function firstAuthorizedRoute(loginStore: ReturnType<typeof useLoginStore>) {
return (
authorizedLandingRoutes.find((route) => loginStore.hasPermission(route.permission))?.name ??
'forbidden'
)
function firstAuthorizedPath(loginStore: ReturnType<typeof useLoginStore>) {
return loginStore.firstAuthorizedPath ?? '/forbidden'
}
const router = createRouter({
@@ -56,79 +37,29 @@ const router = createRouter({
path: '/',
name: 'clinical',
component: ClinicalLayout,
redirect: '/workbench/home',
redirect: '/dashboard',
meta: { requiresAuth: true },
children: [
{
path: 'workbench',
redirect: '/workbench/home',
children: [
{
path: 'home',
name: 'workbench-home',
component: DashboardView,
meta: { title: '首页', group: '工作台', permission: 'sign:task:query' },
},
{
path: 'signing',
name: 'workbench-signing',
component: ConsentTasksView,
meta: { title: '签署工作台', group: '工作台', permission: 'sign:task:query' },
},
],
},
{
path: 'management',
redirect: '/management/documents',
children: [
{
path: 'documents',
name: 'management-documents',
component: DocumentsView,
meta: { title: '文档库管理', group: '管理', permission: 'sign:template:query' },
},
{
path: 'reports',
name: 'management-reports',
component: ReportsView,
meta: { title: '报表分析', group: '管理', permission: 'report:signing:query' },
},
{
path: 'users',
name: 'management-users',
component: UserPermissionsView,
meta: {
title: '用户与权限',
group: '管理',
permission: 'system:user:query',
},
},
{
path: 'document-permissions',
name: 'management-document-permissions',
component: DocumentPermissionsView,
meta: {
title: '文档权限',
group: '管理',
permission: 'sign:template:permission:query',
},
},
{
path: 'settings',
name: 'management-settings',
component: SettingsView,
meta: { title: '系统设置', group: '管理' },
},
],
path: ':pathMatch(.*)*',
name: 'menu-resource',
component: MenuResourceView,
meta: { requiresAuth: true },
},
],
},
{ path: '/dashboard', redirect: '/workbench/home' },
{ path: '/consent-tasks', redirect: '/workbench/signing' },
{ path: '/documents', redirect: '/management/documents' },
{ path: '/reports', redirect: '/management/reports' },
{ path: '/settings', redirect: '/management/settings' },
{ path: '/:pathMatch(.*)*', redirect: '/workbench/home' },
{ path: '/workbench/home', redirect: '/dashboard' },
{ path: '/workbench/signing', redirect: '/sign/workbench' },
{ path: '/management/users', redirect: '/system/org' },
{ path: '/management/roles', redirect: '/system/role' },
{ path: '/management/documents', redirect: '/doc/library' },
{ path: '/management/reports', redirect: '/report/index' },
{ path: '/management/settings', redirect: '/system/setting' },
{ path: '/management/document-permissions', redirect: '/system/role' },
{ path: '/consent-tasks', redirect: '/sign/workbench' },
{ path: '/documents', redirect: '/doc/library' },
{ path: '/reports', redirect: '/report/index' },
{ path: '/settings', redirect: '/system/setting' },
],
})
@@ -141,11 +72,9 @@ router.beforeEach(async (to) => {
return true
}
return {
name: loginStore.user?.passwordChangeRequired
? 'change-password'
: firstAuthorizedRoute(loginStore),
}
return loginStore.user?.passwordChangeRequired
? { name: 'change-password' }
: firstAuthorizedPath(loginStore)
}
if (to.meta.requiresAuth && !loginStore.isLoggedIn) {
@@ -155,38 +84,42 @@ router.beforeEach(async (to) => {
}
}
if (to.meta.requiresAuth) {
try {
const user = await loginStore.ensureCurrentUser()
if (user?.passwordChangeRequired && to.name !== 'change-password') {
return { name: 'change-password' }
}
if (!user?.passwordChangeRequired && to.name === 'change-password') {
return { name: firstAuthorizedRoute(loginStore) }
}
if (to.name === 'management-settings' && !mockFlags.settings) {
return { name: 'forbidden' }
}
const requiredPermission = to.meta.permission as string | string[] | undefined
if (requiredPermission && !loginStore.hasPermission(requiredPermission)) {
return { name: firstAuthorizedRoute(loginStore) }
}
return true
} catch {
loginStore.clearSession()
return {
name: 'login',
query: { redirect: to.fullPath },
}
}
if (!to.meta.requiresAuth) {
return true
}
return true
try {
const user = await loginStore.ensureCurrentUser()
if (user?.passwordChangeRequired && to.name !== 'change-password') {
return { name: 'change-password' }
}
if (!user?.passwordChangeRequired && to.name === 'change-password') {
return firstAuthorizedPath(loginStore)
}
if (to.name === 'menu-resource') {
const resource = loginStore.menuForPath(to.path)
if (
!resource ||
resource.resourceType !== 'MENU' ||
resource.status !== 'ENABLED' ||
!resource.code ||
!loginStore.hasPermission(resource.code)
) {
return firstAuthorizedPath(loginStore)
}
}
return true
} catch {
loginStore.clearSession()
return {
name: 'login',
query: { redirect: to.fullPath },
}
}
})
export default router