2026-02-05 10:24:40 +08:00
|
|
|
|
// 导入自定义布局
|
|
|
|
|
|
import LoginLayout from './layouts/LoginLayout.vue'
|
|
|
|
|
|
// 导入默认布局(必须保留,否则其他页面会404)
|
|
|
|
|
|
import DefaultLayout from '@vuepress/theme-default/layouts/Layout.vue'
|
|
|
|
|
|
|
2025-09-29 16:51:36 +08:00
|
|
|
|
import { defineClientConfig } from 'vuepress/client'
|
|
|
|
|
|
import { createPinia } from 'pinia'
|
2026-02-05 10:24:40 +08:00
|
|
|
|
// 1. 补全所有缺失的核心导入(适配docs根目录的store/utils)
|
|
|
|
|
|
import { useUserStore } from './store/modules/user'
|
|
|
|
|
|
import { showToast, getUserInfo } from '../utils/request' // 新增getUserInfo
|
|
|
|
|
|
// 核心修改:导入全局常量SITE_BASE
|
|
|
|
|
|
import { SITE_BASE } from './constants.js';
|
|
|
|
|
|
// 原有组件导入(位置不变,无需修改)
|
2025-09-29 16:51:36 +08:00
|
|
|
|
import WithAuth from './components/WithAuth.vue'
|
|
|
|
|
|
import Login from './components/Login.vue'
|
|
|
|
|
|
import helperHTML from './components/helperHTML.vue'
|
|
|
|
|
|
import longPic from './components/longPic.vue'
|
|
|
|
|
|
|
|
|
|
|
|
export default defineClientConfig({
|
2026-02-05 10:24:40 +08:00
|
|
|
|
// 新增:注册布局
|
|
|
|
|
|
layouts: {
|
|
|
|
|
|
Layout: DefaultLayout, // 默认布局
|
|
|
|
|
|
LoginLayout: LoginLayout // 登录页布局
|
|
|
|
|
|
},
|
|
|
|
|
|
// 2. 解构出router(路由守卫必须用)
|
|
|
|
|
|
enhance({ app, router }) {
|
2025-09-29 16:51:36 +08:00
|
|
|
|
const pinia = createPinia()
|
|
|
|
|
|
app.use(pinia)
|
2026-02-05 10:24:40 +08:00
|
|
|
|
// 全局注册组件(原有逻辑,无问题)
|
2025-09-29 16:51:36 +08:00
|
|
|
|
app.component('WithAuth', WithAuth)
|
|
|
|
|
|
app.component('Login', Login)
|
|
|
|
|
|
app.component('helperHTML', helperHTML)
|
|
|
|
|
|
app.component('longPic', longPic)
|
2026-02-05 10:24:40 +08:00
|
|
|
|
|
|
|
|
|
|
// 权限指令v-auth:修复this指向+Pinia实例化问题
|
|
|
|
|
|
app.directive('auth', {
|
|
|
|
|
|
mounted(el, binding) {
|
|
|
|
|
|
// 3. Pinia仓库必须执行实例化(核心修复)
|
|
|
|
|
|
const userStore = useUserStore()
|
|
|
|
|
|
const requiredRoles = binding.value
|
|
|
|
|
|
if (!requiredRoles) return
|
|
|
|
|
|
// 未登录/无权限直接隐藏
|
|
|
|
|
|
if (!userStore.isLogin) {
|
|
|
|
|
|
el.style.display = 'none'
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
let hasPermission = false
|
|
|
|
|
|
if (typeof requiredRoles === 'string') {
|
|
|
|
|
|
hasPermission = userStore.hasRole(requiredRoles)
|
|
|
|
|
|
} else if (Array.isArray(requiredRoles)) {
|
|
|
|
|
|
hasPermission = requiredRoles.some(role => userStore.hasRole(role))
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!hasPermission) el.style.display = 'none'
|
|
|
|
|
|
},
|
|
|
|
|
|
updated(el, binding) {
|
|
|
|
|
|
// 4. 修复this指向问题:直接复用mounted逻辑,不用this
|
|
|
|
|
|
this.mounted.call(this, el, binding)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 全局路由守卫:VuePress 2.x 适配版(白名单+未登录跳登录)
|
|
|
|
|
|
const whiteList = ['/login.html'] // 无需登录的页面
|
2026-02-06 10:12:08 +08:00
|
|
|
|
if (typeof window !== 'undefined') {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2026-02-05 10:24:40 +08:00
|
|
|
|
// 隐藏登录功能
|
2026-02-06 10:12:08 +08:00
|
|
|
|
router.beforeEach(async (to, from, next) => {
|
2026-02-05 10:24:40 +08:00
|
|
|
|
const userStore = useUserStore()
|
2026-02-06 10:12:08 +08:00
|
|
|
|
const isLogin = userStore.isLogin
|
|
|
|
|
|
|
|
|
|
|
|
// 白名单页面,直接放行
|
|
|
|
|
|
if (whiteList.includes(to.path)) {
|
|
|
|
|
|
next()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
if (typeof window == 'undefined') {
|
|
|
|
|
|
next()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
// 未登录:跳登录页并记录跳转前地址(适配base: /dma_handbook/)
|
|
|
|
|
|
// 替换client.js中路由守卫的未登录跳转代码
|
|
|
|
|
|
if (!isLogin) {
|
|
|
|
|
|
showToast('请先登录后访问')
|
|
|
|
|
|
// 核心修复:直接使用to.fullPath(已包含SITE_BASE),无需手动拼接
|
|
|
|
|
|
let redirectPath = to.fullPath
|
|
|
|
|
|
// 兜底校验:极端情况若fullPath未带SITE_BASE,手动拼接(防止地址栏手动修改)
|
|
|
|
|
|
if (!redirectPath.startsWith(SITE_BASE)) {
|
|
|
|
|
|
redirectPath = `${SITE_BASE}${redirectPath.replace(/^\//, '')}` // 去掉开头的/,避免双斜杠
|
|
|
|
|
|
}
|
|
|
|
|
|
// 编码后拼接登录页地址
|
|
|
|
|
|
const redirect = encodeURIComponent(redirectPath)
|
|
|
|
|
|
window.location.href = `${SITE_BASE}login.html?redirect=${redirect}`
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
// 核心修改:仅【已登录 + 未拉取过用户信息】时,才调用接口
|
|
|
|
|
|
if (!userStore.isUserInfoFetched) {
|
|
|
|
|
|
await getUserInfo(userStore)
|
|
|
|
|
|
// 拉取成功后,更新标记为true(本次会话不再重复调用)
|
|
|
|
|
|
userStore.setUserInfoFetched(true)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 已登录,正常放行
|
|
|
|
|
|
next()
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-09-29 16:51:36 +08:00
|
|
|
|
},
|
2026-02-05 10:24:40 +08:00
|
|
|
|
setup() {},
|
2025-09-29 16:51:36 +08:00
|
|
|
|
})
|