根因分析: - 后端菜单配置存在30+个重复路由名(如Record/Enhanced/Charge等) - Vue Router不允许重名路由,addRoute抛出异常 - permission.js的catch直接调用logOut(),导致所有页面重定向到登录页 修复内容: 1. permission.js: addRoute时try-catch重名错误,跳过而非登出 2. permission store: filterAsyncRouter中添加路由名自动去重逻辑 3. 新增src/api/anesthesia.js: 麻醉模块API文件缺失修复 4. 修正test-data.ts中所有错误路由路径,匹配实际菜单配置 验证: workflow-full.spec.ts 20/20通过, login.spec.ts 4/4通过
115 lines
3.4 KiB
JavaScript
Executable File
115 lines
3.4 KiB
JavaScript
Executable File
import router from './router'
|
|
import { ElMessage } from 'element-plus'
|
|
import NProgress from 'nprogress'
|
|
import 'nprogress/nprogress.css'
|
|
import { getToken } from '@/utils/auth'
|
|
import { isHttp, isPathMatch } from '@/utils/validate'
|
|
import { isRelogin } from '@/utils/request'
|
|
import useUserStore from '@/store/modules/user'
|
|
import useLockStore from '@/store/modules/lock'
|
|
import useSettingsStore from '@/store/modules/settings'
|
|
import usePermissionStore from '@/store/modules/permission'
|
|
import useNoticeStore from '@/store/modules/notice'
|
|
import useTagsViewStore from '@/store/modules/tagsView'
|
|
|
|
// 全局变量,用于控制公告弹窗只显示一次
|
|
let hasShownNoticePopup = false
|
|
|
|
NProgress.configure({ showSpinner: false })
|
|
|
|
const whiteList = ['/login', '/register']
|
|
|
|
const isWhiteList = (path) => {
|
|
return whiteList.some(pattern => isPathMatch(pattern, path))
|
|
}
|
|
|
|
router.beforeEach(async (to, from) => {
|
|
NProgress.start()
|
|
if (getToken()) {
|
|
to.meta.title && useSettingsStore().setTitle(to.meta.title)
|
|
const isLock = useLockStore().isLock
|
|
if (to.path === '/login') {
|
|
NProgress.done()
|
|
return { path: '/' }
|
|
}
|
|
if (isWhiteList(to.path)) {
|
|
return true
|
|
}
|
|
if (isLock && to.path !== '/lock') {
|
|
NProgress.done()
|
|
return { path: '/lock' }
|
|
}
|
|
if (!isLock && to.path === '/lock') {
|
|
NProgress.done()
|
|
return { path: '/' }
|
|
}
|
|
if (useUserStore().roles.length === 0) {
|
|
isRelogin.show = true
|
|
try {
|
|
await useUserStore().getInfo()
|
|
isRelogin.show = false
|
|
const accessRoutes = await usePermissionStore().generateRoutes()
|
|
accessRoutes.forEach(route => {
|
|
if (!isHttp(route.path)) {
|
|
if (!router.hasRoute(route.name)) {
|
|
try {
|
|
router.addRoute(route)
|
|
} catch (e) {
|
|
// 路由名重复时跳过,不影响其他路由加载
|
|
console.warn('路由添加跳过(名称重复):', route.name, e.message)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
useNoticeStore().startPolling()
|
|
useTagsViewStore().loadPersistedViews()
|
|
return { ...to, replace: true }
|
|
} catch (err) {
|
|
console.error('路由加载失败:', err)
|
|
await useUserStore().logOut()
|
|
ElMessage.error(err.message || '登录已过期')
|
|
return { path: '/login' }
|
|
}
|
|
}
|
|
return true
|
|
} else {
|
|
if (isWhiteList(to.path)) {
|
|
return true
|
|
}
|
|
NProgress.done()
|
|
return `/login?redirect=${to.fullPath}`
|
|
}
|
|
})
|
|
|
|
router.afterEach(() => {
|
|
NProgress.done()
|
|
|
|
// 登录成功后显示公告弹窗(仅限非登录页面且未显示过)
|
|
const token = getToken()
|
|
const isLoginPage = router.currentRoute.value.path === '/login'
|
|
|
|
if (token && !isLoginPage && !hasShownNoticePopup) {
|
|
setTimeout(() => {
|
|
showNoticePopupGlobally()
|
|
hasShownNoticePopup = true
|
|
}, 1500)
|
|
}
|
|
})
|
|
|
|
// 全局函数:显示公告弹窗
|
|
function showNoticePopupGlobally() {
|
|
try {
|
|
const layouts = document.querySelectorAll('.app-wrapper')
|
|
for (const layout of layouts) {
|
|
const noticePopupRef = layout.__vue_app__?.config.globalProperties.$refs?.noticePopupRef
|
|
if (noticePopupRef && noticePopupRef.showNotice) {
|
|
noticePopupRef.showNotice()
|
|
return
|
|
}
|
|
}
|
|
window.dispatchEvent(new CustomEvent('show-notice-popup'))
|
|
} catch (error) {
|
|
console.error('显示公告弹窗失败:', error)
|
|
}
|
|
}
|