ad2f49de11
- request.ts: 优化401处理,避免登录接口误判过期 - router/index.ts: 路由守卫增加用户信息获取 - stores/user.ts: fetchUserInfo增强错误处理,login前先清理旧状态 - Login.vue: 使用await router.push,避免重复报错 - user_service.py: bootstrap superuser密码同步
175 lines
5.7 KiB
TypeScript
175 lines
5.7 KiB
TypeScript
import { createRouter, createWebHistory } from 'vue-router'
|
|
import { useUserStore } from '@/stores/user'
|
|
|
|
const routes = [
|
|
{
|
|
path: '/login',
|
|
name: 'Login',
|
|
component: () => import('@/views/auth/Login.vue'),
|
|
meta: { public: true },
|
|
},
|
|
{
|
|
path: '/',
|
|
name: 'Layout',
|
|
component: () => import('@/components/Layout.vue'),
|
|
redirect: '/dashboard',
|
|
children: [
|
|
{
|
|
path: 'dashboard',
|
|
name: 'Dashboard',
|
|
component: () => import('@/views/dashboard/Dashboard.vue'),
|
|
meta: { title: '首页', icon: 'HomeFilled', roles: ['superadmin', 'admin', 'project_manager', 'labeler', 'reviewer', 'guest'], keepAlive: true },
|
|
},
|
|
{
|
|
path: 'datasource',
|
|
name: 'DataSource',
|
|
component: () => import('@/views/datasource/DataSource.vue'),
|
|
meta: { title: '数据源管理', icon: 'DataLine', roles: ['superadmin', 'admin', 'project_manager', 'labeler', 'reviewer', 'guest'] },
|
|
},
|
|
{
|
|
path: 'metadata',
|
|
name: 'Metadata',
|
|
component: () => import('@/views/metadata/Metadata.vue'),
|
|
meta: { title: '数据资产', icon: 'FolderOpened', roles: ['superadmin', 'admin', 'project_manager', 'labeler', 'reviewer', 'guest'] },
|
|
},
|
|
{
|
|
path: 'category',
|
|
name: 'Category',
|
|
component: () => import('@/views/category/Category.vue'),
|
|
meta: { title: '分类分级标准', icon: 'Collection', roles: ['superadmin', 'admin', 'project_manager', 'labeler', 'reviewer', 'guest'] },
|
|
},
|
|
{
|
|
path: 'project',
|
|
name: 'Project',
|
|
component: () => import('@/views/project/Project.vue'),
|
|
meta: { title: '项目管理', icon: 'List', roles: ['superadmin', 'admin', 'project_manager'] },
|
|
},
|
|
{
|
|
path: 'task',
|
|
name: 'Task',
|
|
component: () => import('@/views/task/Task.vue'),
|
|
meta: { title: '我的任务', icon: 'EditPen', roles: ['superadmin', 'admin', 'project_manager', 'labeler', 'reviewer'] },
|
|
},
|
|
{
|
|
path: 'classification',
|
|
name: 'Classification',
|
|
component: () => import('@/views/classification/Classification.vue'),
|
|
meta: { title: '分类分级结果', icon: 'DocumentChecked', roles: ['superadmin', 'admin', 'project_manager', 'labeler', 'reviewer', 'guest'] },
|
|
},
|
|
{
|
|
path: 'report',
|
|
name: 'Report',
|
|
component: () => import('@/views/report/Report.vue'),
|
|
meta: { title: '报表统计', icon: 'TrendCharts', roles: ['superadmin', 'admin', 'project_manager'] },
|
|
},
|
|
{
|
|
path: 'masking',
|
|
name: 'Masking',
|
|
component: () => import('@/views/masking/Masking.vue'),
|
|
meta: { title: '数据脱敏', icon: 'Hide', roles: ['superadmin', 'admin', 'project_manager'] },
|
|
},
|
|
{
|
|
path: 'watermark',
|
|
name: 'Watermark',
|
|
component: () => import('@/views/watermark/Watermark.vue'),
|
|
meta: { title: '水印溯源', icon: 'Memo', roles: ['superadmin', 'admin', 'project_manager'] },
|
|
},
|
|
{
|
|
path: 'unstructured',
|
|
name: 'Unstructured',
|
|
component: () => import('@/views/unstructured/Unstructured.vue'),
|
|
meta: { title: '非结构化文件', icon: 'Document', roles: ['superadmin', 'admin', 'project_manager', 'labeler', 'reviewer', 'guest'] },
|
|
},
|
|
{
|
|
path: 'schema-change',
|
|
name: 'SchemaChange',
|
|
component: () => import('@/views/schema_change/SchemaChange.vue'),
|
|
meta: { title: 'Schema变更', icon: 'Refresh', roles: ['superadmin', 'admin', 'project_manager'] },
|
|
},
|
|
{
|
|
path: 'compliance',
|
|
name: 'Compliance',
|
|
component: () => import('@/views/compliance/Compliance.vue'),
|
|
meta: { title: '合规检查', icon: 'CircleCheck', roles: ['superadmin', 'admin', 'project_manager'] },
|
|
},
|
|
{
|
|
path: 'lineage',
|
|
name: 'Lineage',
|
|
component: () => import('@/views/lineage/Lineage.vue'),
|
|
meta: { title: '数据血缘', icon: 'Share', roles: ['superadmin', 'admin', 'project_manager'] },
|
|
},
|
|
{
|
|
path: 'alerts',
|
|
name: 'Alerts',
|
|
component: () => import('@/views/alert/Alert.vue'),
|
|
meta: { title: '告警与工单', icon: 'Warning', roles: ['superadmin', 'admin', 'project_manager'] },
|
|
},
|
|
{
|
|
path: 'api-assets',
|
|
name: 'ApiAssets',
|
|
component: () => import('@/views/api_asset/APIAsset.vue'),
|
|
meta: { title: 'API资产扫描', icon: 'Connection', roles: ['superadmin', 'admin', 'project_manager'] },
|
|
},
|
|
{
|
|
path: 'system',
|
|
name: 'System',
|
|
component: () => import('@/views/system/System.vue'),
|
|
meta: { title: '系统管理', icon: 'Setting', roles: ['superadmin', 'admin'] },
|
|
},
|
|
],
|
|
},
|
|
{
|
|
path: '/:pathMatch(.*)*',
|
|
redirect: '/',
|
|
},
|
|
]
|
|
|
|
const router = createRouter({
|
|
history: createWebHistory(),
|
|
routes,
|
|
})
|
|
|
|
router.beforeEach(async (to, from, next) => {
|
|
const userStore = useUserStore()
|
|
|
|
// Public routes (login)
|
|
if (to.meta.public) {
|
|
next()
|
|
return
|
|
}
|
|
|
|
// Not logged in
|
|
if (!userStore.token) {
|
|
next('/login')
|
|
return
|
|
}
|
|
|
|
if (!userStore.userInfo) {
|
|
try {
|
|
const userInfo = await userStore.fetchUserInfo()
|
|
if (!userInfo) {
|
|
userStore.logout()
|
|
next('/login')
|
|
return
|
|
}
|
|
} catch {
|
|
next('/login')
|
|
return
|
|
}
|
|
}
|
|
|
|
// Check role permissions
|
|
const allowedRoles = to.meta.roles as string[] | undefined
|
|
if (allowedRoles && allowedRoles.length > 0) {
|
|
const hasPermission = userStore.hasAnyRole(allowedRoles)
|
|
if (!hasPermission) {
|
|
next(to.path === '/dashboard' ? '/login' : '/dashboard')
|
|
return
|
|
}
|
|
}
|
|
|
|
next()
|
|
})
|
|
|
|
export default router
|