| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- import { useStorage } from '@vueuse/core'
- import { acceptHMRUpdate, defineStore } from 'pinia'
- import { ref } from 'vue'
- import router from '@/router'
- import { resolveMenu, resolveRoute } from '@/router/helper'
- import { routeRecordRaw } from '@/router/record'
- import type { MergeMenuMixedOptions } from '@/router/helper'
- import type { MenuProps } from 'naive-ui'
- import type { RouteRecordRaw } from 'vue-router'
- import { parseJwtToken, type JwtPayload } from '@/utils/casdoor/token'
- interface User {
- avatar?: string
- id?: string
- name?: string
- role?: 'admin' | 'user'
- permissions: UserPermissions
- }
- interface UserPermissions {
- isAdmin: boolean
- items: UserPermissionsItems
- }
- interface UserPermissionsItems {
- xlog?: boolean // xlog操作权限
- autoUpdate?: boolean // 自动升级配置页面操作权限
- faultRecord?: boolean // 故障录波操作权限
- }
- const DEFAULT_USER: User = {
- avatar: '',
- id: '2000',
- name: 'FWH User',
- role: 'user',
- permissions: {
- isAdmin: false,
- items: {},
- },
- }
- // 特权菜单定义
- const adminMenuNames: string[] = [
- 'backgroundTask', // 后台任务管理
- ] as const
- const xlogMenuNames: string[] = [
- 'xlogManage', // XLOG管理
- 'xlogTerminal', // XLOG终端
- ] as const
- const autoUpdateMenuNames: string[] = [
- 'autoUpdate', // 自动升级
- 'autoUpdatePackage', // 升级包管理
- 'autoUpdateAPowerVersion', // aPower版本管理
- 'autoUpdateConfig', // 自动升级配置
- 'autoUpdateConfigFile', // 配置文件管理
- ] as const
- const faultRecordMenuNames: string[] = [
- 'faultRecord', // 故障录波主菜单
- 'faultRecordRead', // 故障录波参数读界面
- 'faultRecordWrite', // 故障录波参数写界面
- ] as const
- const parsePermissions = (payload: JwtPayload): User => {
- return {
- avatar: '',
- id: payload.id,
- name: payload.name,
- role: payload.isAdmin ? 'admin' : 'user',
- permissions: {
- isAdmin: payload.isAdmin,
- items: payload.permissions.reduce<UserPermissionsItems>((acc, cur) => {
- switch (cur.name) {
- case 'xlog':
- acc.xlog = true
- break
- case 'autoUpdate':
- acc.autoUpdate = true
- break
- case 'faultRecord':
- acc.faultRecord = true
- break
- }
- return acc
- }, {}),
- },
- }
- }
- export const useUserStore = defineStore('userStore', () => {
- const user = useStorage<User>('user', DEFAULT_USER)
- const token = useStorage<string | undefined>('token', undefined)
- const tokenPayload = useStorage<JwtPayload | undefined>('tokenPayload', undefined, undefined, {
- serializer: {
- read: (v: string) => (v ? (v !== '' ? JSON.parse(v) : undefined) : undefined),
- write: (v: JwtPayload | undefined) => (v ? JSON.stringify(v) : ''),
- },
- })
- const menuList = ref<MenuProps['options']>([])
- const routeList = ref<RouteRecordRaw[]>([])
- const getUserInfo = (): User => {
- return user.value
- }
- const setToken = (value: string | undefined) => {
- token.value = value
- if (value !== undefined) {
- const jwtData = parseJwtToken(value)
- console.log({ jwtData, jwtDataStr: JSON.stringify(jwtData) })
- tokenPayload.value = jwtData
- user.value = parsePermissions(jwtData)
- } else {
- tokenPayload.value = undefined
- user.value = DEFAULT_USER
- }
- }
- async function resolveMenuList() {
- const res = await new Promise<MergeMenuMixedOptions[]>((resolve) => {
- if (tokenPayload.value !== undefined) {
- if (user.value.permissions.isAdmin) {
- resolve(routeRecordRaw)
- } else {
- // const allowedRoutes = tokenPayload.value.roles.map((role) => role.domains).flat()
- // const filterRoutes = (routeRecord: MergeMenuMixedOptions[]) => {
- // return routeRecord
- // .map((route): MergeMenuMixedOptions | undefined => {
- // const selfAllowed =
- // !route.type && route.name && allowedRoutes.includes(route.name as string)
- // if (selfAllowed) return route
- // // 先递归处理 children
- // if (!('children' in route) || route.children === undefined) {
- // return undefined
- // }
- // const result = { ...route }
- // result.children = filterRoutes(route.children)
- // return result
- // })
- // .filter((item): item is MergeMenuMixedOptions => Boolean(item))
- // }
- // resolve(filterRoutes(routeRecordRaw))
- const permissionsItems = user.value.permissions.items
- resolve(
- routeRecordRaw.filter((route) => {
- if (route.type === undefined && typeof route.name === 'string') {
- // 清除admin权限页面
- if (adminMenuNames.includes(route.name)) {
- return false
- }
- // xlog界面控制
- if (permissionsItems.xlog !== true) {
- if (xlogMenuNames.includes(route.name)) {
- return false
- }
- }
- // autoUpdate界面控制
- if (permissionsItems.autoUpdate !== true) {
- if (autoUpdateMenuNames.includes(route.name)) {
- return false
- }
- }
- // faultRecord界面控制
- if (permissionsItems.faultRecord !== true) {
- if (faultRecordMenuNames.includes(route.name)) {
- return false
- }
- }
- }
- return true
- }),
- )
- }
- } else {
- cleanup()
- resolve([])
- }
- // if (token.value?.includes('admin')) {
- // resolve(routeRecordRaw)
- // } else {
- // const allowedRoutes = ['dashboard', 'dataShow', 'notfoundPage', 'about']
- // const filteredRoutes = routeRecordRaw.filter((route) => {
- // return !route.type && route.name && allowedRoutes.includes(route.name as string)
- // })
- // resolve(filteredRoutes)
- // }
- // 暂时没有管理员权限
- // resolve(routeRecordRaw)
- })
- menuList.value = resolveMenu(res) || []
- routeList.value = resolveRoute(res) || []
- }
- function cleanup(redirectPath?: string) {
- router.replace({
- name: 'signin',
- ...(redirectPath ? { query: { r: redirectPath } } : {}),
- })
- token.value = undefined
- if (router.hasRoute('layout')) {
- router.removeRoute('layout')
- }
- menuList.value = []
- routeList.value = []
- }
- return {
- user,
- token,
- tokenPayload,
- menuList,
- routeList,
- resolveMenuList,
- getUserInfo,
- setToken,
- cleanup,
- }
- })
- if (import.meta.hot) {
- import.meta.hot.accept(acceptHMRUpdate(useUserStore, import.meta.hot))
- }
|