53 lines
3.4 KiB
TypeScript
53 lines
3.4 KiB
TypeScript
import { createRouter, createWebHistory } from 'vue-router'
|
|||
|
|
import AppLayout from '@/layouts/AppLayout.vue'
|
||
|
|
import { useAuthStore } from '@/stores/auth'
|
||
|
|
import { getFirstAccessiblePath } from '@/navigation/clientNavigation'
|
||
|
|
|
||
|
|
const router = createRouter({
|
||
|
|
history: createWebHistory(),
|
||
|
|
routes: [
|
||
|
|
{ path: '/login', name: 'login', component: () => import('@/views/LoginView.vue'), meta: { title: '登录' } },
|
||
|
|
{ path: '/register', name: 'register', component: () => import('@/views/RegisterView.vue'), meta: { title: '企业注册' } },
|
||
|
|
{
|
||
|
|
path: '/',
|
||
|
|
component: AppLayout,
|
||
|
|
meta: { requiresAuth: true },
|
||
|
|
children: [
|
||
|
|
{ path: '', name: 'dashboard', component: () => import('@/views/DashboardView.vue'), meta: { title: '业务总览', description: '企业账户与头程业务概览', permission: 'dashboard:view' } },
|
||
|
|
{ path: 'account/profile', name: 'account-profile', component: () => import('@/views/AccountProfileView.vue'), meta: { title: '我的信息', description: '维护个人联系方式和登录密码', permission: 'account:profile:view' } },
|
||
|
|
{ path: 'company/profile', name: 'company-profile', component: () => import('@/views/CompanyProfileView.vue'), meta: { title: '企业资料', description: '维护企业基本信息、联系人和资质文件', permission: 'company:profile:view' } },
|
||
|
|
{ path: 'organization/members', name: 'members', component: () => import('@/views/MembersView.vue'), meta: { title: '企业成员', description: '管理本企业成员账号、状态和角色', permission: 'company:member:list' } },
|
||
|
|
{ path: 'organization/roles', name: 'roles', component: () => import('@/views/RolesView.vue'), meta: { title: '角色管理', description: '建立符合企业分工的成员角色', permission: 'company:role:list' } },
|
||
|
|
{ path: 'organization/permissions', name: 'permissions', component: () => import('@/views/PermissionsView.vue'), meta: { title: '菜单权限', description: '为本企业角色分配菜单及操作权限', permission: 'company:permission:list' } },
|
||
|
|
{ path: 'orders/first-leg', name: 'first-leg-orders', component: () => import('@/views/FirstLegOrdersView.vue'), meta: { title: '头程订单', description: '创建、查询并跟进本企业头程订单', permission: 'order:first-leg:list' } },
|
||
|
|
{ path: 'forbidden', name: 'forbidden', component: () => import('@/views/ForbiddenView.vue'), meta: { title: '无权访问', description: '当前账号没有访问该页面的权限' } },
|
||
|
|
],
|
||
|
|
},
|
||
|
|
{ path: '/:pathMatch(.*)*', redirect: '/' },
|
||
|
|
],
|
||
|
|
})
|
||
|
|
|
||
|
|
router.beforeEach(async (to) => {
|
||
|
|
document.title = to.meta.title ? `${to.meta.title} - 虫虫出海客户工作台` : '虫虫出海客户工作台'
|
||
|
|
const auth = useAuthStore()
|
||
|
|
if (!auth.sessionRestored) {
|
||
|
|
try {
|
||
|
|
await auth.restoreSession()
|
||
|
|
} catch {
|
||
|
|
return { name: 'login', query: { redirect: to.fullPath } }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (to.meta.requiresAuth && !auth.isAuthenticated) {
|
||
|
|
return { name: 'login', query: { redirect: to.fullPath } }
|
||
|
|
}
|
||
|
|
if ((to.name === 'login' || to.name === 'register') && auth.isAuthenticated) {
|
||
|
|
return getFirstAccessiblePath(auth.permissionCodes)
|
||
|
|
}
|
||
|
|
const permission = typeof to.meta.permission === 'string' ? to.meta.permission : undefined
|
||
|
|
if (auth.isAuthenticated && permission && !auth.hasPermission(permission)) {
|
||
|
|
return { name: 'forbidden', query: { from: to.fullPath } }
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
export default router
|