问题 1(创作者登录后还能看到「工作台」)根因:tagsView.delAllVisitedViews() 会「保留 affix 标签」, 它判断的是 userInfo 是否还在,而 userStore.reset() 是先清标签、后清 userInfo —— 顺序反了, 写死路由表里 affix 的「工作台」标签就跨账号活了下来。整页刷新时不复现,所以只有"退出后不刷新直接登录" 才看得到(PM 复现不到就是这个原因)。修法与加固: - userStore.reset():先清账号信息再清标签,并调 permissionStore.clearRoutes() 一并清菜单状态 - permissionStore 增加 routersOwner(当前菜单属于哪个账号)+ clearRoutes();守卫发现账号变了会先 resetRouter() 摘掉上一个账号动态加的路由,再重建(避免两套菜单并存、也避免创作者还能直接进 /dashboard) - 守卫里"菜单拉取失败沿用上次缓存"这条:换账号后不再沿用(宁可先给空菜单) 问题 2(创作者入驻/审核):真实 UI 全流程(新增→审核→开通→凭据→登录落地)本身能跑通, 但复现出「审核」按钮对**所有状态**都显示 —— 后端状态机是 通过可从 pending/rejected/frozen 发起、 驳回只允许 pending、冻结只允许 approved,对「已通过」的行点审核提交必然 200003 红错。修法: - 已通过的行不再显示「审核」(保留 冻结/重置密码/开通账号) - 审核弹窗里的「驳回」只对 pending 显示,其余状态只能通过 顺带修:views/common/DashboardView 取列表时 res 可能为 undefined(拦截器把业务错误吞成 undefined), 账号切换瞬间会抛 Cannot read properties of undefined,已加可选链。
105 lines
3.0 KiB
TypeScript
105 lines
3.0 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { asyncRouterMap, constantRouterMap } from '@/router'
|
|
import {
|
|
generateRoutesByFrontEnd,
|
|
generateRoutesByServer,
|
|
flatMultiLevelRoutes
|
|
} from '@/utils/routerHelper'
|
|
import { store } from '../index'
|
|
import { cloneDeep } from 'lodash-es'
|
|
|
|
export interface PermissionState {
|
|
routers: AppRouteRecordRaw[]
|
|
addRouters: AppRouteRecordRaw[]
|
|
isAddRouters: boolean
|
|
menuTabRouters: AppRouteRecordRaw[]
|
|
/** 当前这套菜单属于哪个账号:账号变了必须重建,不能沿用上一个账号的路由 */
|
|
routersOwner: string
|
|
}
|
|
|
|
export const usePermissionStore = defineStore('permission', {
|
|
state: (): PermissionState => ({
|
|
routers: [],
|
|
addRouters: [],
|
|
isAddRouters: false,
|
|
menuTabRouters: [],
|
|
routersOwner: ''
|
|
}),
|
|
getters: {
|
|
getRouters(): AppRouteRecordRaw[] {
|
|
return this.routers
|
|
},
|
|
getAddRouters(): AppRouteRecordRaw[] {
|
|
return flatMultiLevelRoutes(cloneDeep(this.addRouters))
|
|
},
|
|
getIsAddRouters(): boolean {
|
|
return this.isAddRouters
|
|
},
|
|
getMenuTabRouters(): AppRouteRecordRaw[] {
|
|
return this.menuTabRouters
|
|
},
|
|
getRoutersOwner(): string {
|
|
return this.routersOwner
|
|
}
|
|
},
|
|
actions: {
|
|
generateRoutes(
|
|
type: 'server' | 'frontEnd' | 'static',
|
|
routers?: AppCustomRouteRecordRaw[] | string[]
|
|
): Promise<unknown> {
|
|
return new Promise<void>((resolve) => {
|
|
let routerMap: AppRouteRecordRaw[] = []
|
|
if (type === 'server') {
|
|
// 模拟后端过滤菜单
|
|
routerMap = generateRoutesByServer(routers as AppCustomRouteRecordRaw[])
|
|
} else if (type === 'frontEnd') {
|
|
// 模拟前端过滤菜单
|
|
routerMap = generateRoutesByFrontEnd(cloneDeep(asyncRouterMap), routers as string[])
|
|
} else {
|
|
// 直接读取静态路由表
|
|
routerMap = cloneDeep(asyncRouterMap)
|
|
}
|
|
// 动态路由,404一定要放到最后面
|
|
this.addRouters = routerMap.concat([
|
|
{
|
|
path: '/:path(.*)*',
|
|
redirect: '/404',
|
|
name: '404Page',
|
|
meta: {
|
|
hidden: true,
|
|
breadcrumb: false
|
|
}
|
|
}
|
|
])
|
|
// 渲染菜单的所有路由
|
|
this.routers = cloneDeep(constantRouterMap).concat(routerMap)
|
|
resolve()
|
|
})
|
|
},
|
|
setIsAddRouters(state: boolean): void {
|
|
this.isAddRouters = state
|
|
},
|
|
setMenuTabRouters(routers: AppRouteRecordRaw[]): void {
|
|
this.menuTabRouters = routers
|
|
},
|
|
setRoutersOwner(owner: string): void {
|
|
this.routersOwner = owner
|
|
},
|
|
/** 登出 / 切换账号时清空菜单与路由状态(由 userStore.reset 调用) */
|
|
clearRoutes(): void {
|
|
this.routers = []
|
|
this.addRouters = []
|
|
this.menuTabRouters = []
|
|
this.isAddRouters = false
|
|
this.routersOwner = ''
|
|
}
|
|
},
|
|
persist: {
|
|
paths: ['routers', 'addRouters', 'menuTabRouters', 'routersOwner']
|
|
}
|
|
})
|
|
|
|
export const usePermissionStoreWithOut = () => {
|
|
return usePermissionStore(store)
|
|
}
|