Files
CN_Tool_client/frontend/src/stores/modules/auth.ts

280 lines
11 KiB
TypeScript
Raw Normal View History

2026-04-13 17:32:58 +08:00
import { defineStore } from 'pinia'
import { type AuthState } from '@/stores/interface'
import { getAuthButtonListApi, getAuthMenuListApi } from '@/api/user/login'
import { getAllBreadcrumbList, getFlatMenuList, getShowMenuList } from '@/utils'
import { AUTH_STORE_KEY } from '@/stores/constant'
import { getLicense } from '@/api/activate'
import type { Activate } from '@/api/activate/interface'
export const useAuthStore = defineStore(AUTH_STORE_KEY, {
state: (): AuthState => ({
authButtonList: {},
authMenuList: [],
showMenuList: [],
flatMenuList: [],
breadcrumbList: {},
2026-04-13 17:32:58 +08:00
routeName: '',
showMenuFlag: localStorage.getItem('showMenuFlag') === 'true',
activateInfo: {} as Activate.ActivationCodePlaintext,
activateInfoLoaded: false
}),
getters: {
authButtonListGet: state => state.authButtonList,
authMenuListGet: state => state.authMenuList,
showMenuListGet: state => state.showMenuList,
flatMenuListGet: state => state.flatMenuList,
breadcrumbListGet: state => state.breadcrumbList,
2026-04-13 17:32:58 +08:00
showMenuFlagGet: state => state.showMenuFlag,
activateInfoGet: state => state.activateInfo,
activateInfoLoadedGet: state => state.activateInfoLoaded
},
actions: {
async getAuthButtonList() {
const { data } = await getAuthButtonListApi()
this.authButtonList = data
},
async getAuthMenuList() {
const { data: menuData } = await getAuthMenuListApi()
this.authMenuList = normalizeBusinessMenus(filterBusinessMenus(menuData))
// 菜单派生数据只在菜单源数据变化时重算,避免每次路由跳转都深拷贝整棵菜单。
this.refreshDerivedMenus()
},
refreshDerivedMenus() {
this.showMenuList = getShowMenuList(this.authMenuList)
this.flatMenuList = getFlatMenuList(this.authMenuList)
this.breadcrumbList = getAllBreadcrumbList(this.authMenuList)
2026-04-13 17:32:58 +08:00
},
async setRouteName(name: string) {
this.routeName = name
},
async resetAuthStore() {
this.authButtonList = {}
this.authMenuList = []
this.showMenuList = []
this.flatMenuList = []
this.breadcrumbList = {}
2026-04-13 17:32:58 +08:00
this.routeName = ''
this.showMenuFlag = false
this.activateInfo = {}
this.activateInfoLoaded = false
localStorage.removeItem('showMenuFlag')
},
async setShowMenu() {
this.showMenuFlag = true
localStorage.setItem('showMenuFlag', 'true')
},
changeModel() {
this.showMenuFlag = false
localStorage.removeItem('showMenuFlag')
},
async setActivateInfo() {
const license_result = await getLicense()
this.activateInfo = normalizeActivateInfo(license_result.data)
this.activateInfoLoaded = true
}
}
})
function filterBusinessMenus(menuList: any[]): any[] {
const excludedNames = new Set([
'home',
'plan',
'singlePlanList',
'preTest',
'autoTest',
'machine',
'testSource',
'testScript',
'controlSource',
'standardDevice',
'device',
'devType',
'errorSystem',
'icd',
'template',
'dictPq',
'base'
])
const excludedComponentPatterns = [
'/home/',
'/plan/',
'/machine/',
'/system/template/',
'/system/dictionary/dictPq/',
'/system/base/'
]
const excludedPathPatterns = [
'/home',
'/plan',
'/machine',
'/system/template',
'/system/dictionary/dictPq',
'/system/base'
]
return menuList.filter(menu => {
if (Array.isArray(menu.children) && menu.children.length > 0) {
menu.children = filterBusinessMenus(menu.children)
}
const component = typeof menu.component === 'string' ? menu.component : ''
const path = typeof menu.path === 'string' ? menu.path : ''
const hasChildren = Array.isArray(menu.children) && menu.children.length > 0
const removedByName = excludedNames.has(menu.name)
const removedByComponent = excludedComponentPatterns.some(pattern => component.includes(pattern))
const removedByPath = excludedPathPatterns.some(pattern => path.includes(pattern))
if (removedByName || removedByComponent || removedByPath) {
return hasChildren
}
return true
})
}
function normalizeBusinessMenus(menuList: any[]): any[] {
return menuList.map(menu => normalizeBusinessMenu(menu))
}
function normalizeBusinessMenu(menu: any): any {
if (Array.isArray(menu.children) && menu.children.length > 0) {
menu.children = normalizeBusinessMenus(menu.children)
}
if (isEventListMenu(menu)) {
// 后端菜单历史配置不统一,前端统一收敛到静态 eventList 页面入口。
menu.path = '/eventList/index'
menu.name = 'eventList'
menu.component = '@/views/event/eventList/index.vue'
}
2026-05-15 16:36:50 +08:00
if (isSteadyDataViewMenu(menu)) {
// 后端菜单可能存在 steady-data-view 等历史写法,前端统一收敛到静态 steadyDataView 页面入口。
menu.path = '/steadyDataView/index'
menu.name = 'steadyDataView'
menu.component = '@/views/steady/steadyDataView/index.vue'
}
if (isSteadyTrendMenu(menu)) {
menu.path = '/steadyTrend/index'
menu.name = 'steadyTrend'
menu.component = '@/views/steady/steadyTrend/index.vue'
}
if (isChecksquareMenu(menu)) {
menu.path = '/checksquare/index'
menu.name = 'checksquare'
menu.component = '@/views/steady/checksquare/index.vue'
}
if (isDbmsMenu(menu)) {
// 数据库运维菜单后端存在 systemMonitor/dbms 等历史路径,统一收敛到当前静态页面入口。
menu.path = '/system-ops/dbms'
menu.name = 'systemOpsDbms'
menu.component = '@/views/system-ops/dbms/index.vue'
}
return menu
}
function isEventListMenu(menu: any): boolean {
const normalizedName = String(menu?.name ?? '').toLowerCase().replace(/[-_]/g, '')
const normalizedPath = String(menu?.path ?? '').toLowerCase().replace(/[-_]/g, '')
const normalizedComponent = String(menu?.component ?? '').toLowerCase().replace(/[-_]/g, '')
const title = String(menu?.meta?.title ?? menu?.title ?? '')
if (normalizedName === 'eventlist') return true
if (normalizedPath.includes('eventlist')) return true
if (normalizedComponent.includes('eventlist')) return true
return title.includes('事件列表') && (title.includes('暂降') || title.includes('暂态'))
}
2026-05-15 16:36:50 +08:00
function isSteadyDataViewMenu(menu: any): boolean {
const normalizedName = String(menu?.name ?? '').toLowerCase().replace(/[-_]/g, '')
const normalizedPath = String(menu?.path ?? '').toLowerCase().replace(/[-_]/g, '')
const normalizedComponent = String(menu?.component ?? '').toLowerCase().replace(/[-_]/g, '')
const title = String(menu?.meta?.title ?? menu?.title ?? '')
if (normalizedName === 'steadydataview') return true
if (normalizedPath.includes('steadydataview')) return true
if (normalizedComponent.includes('steadydataview')) return true
return title.includes('稳态数据')
}
function isSteadyTrendMenu(menu: any): boolean {
const normalizedName = String(menu?.name ?? '').toLowerCase().replace(/[-_]/g, '')
const normalizedPath = String(menu?.path ?? '').toLowerCase().replace(/[-_]/g, '')
const normalizedComponent = String(menu?.component ?? '').toLowerCase().replace(/[-_]/g, '')
const title = String(menu?.meta?.title ?? menu?.title ?? '')
if (normalizedName === 'steadytrend') return true
if (normalizedPath.includes('steadytrend')) return true
if (normalizedComponent.includes('steadytrend')) return true
return title.includes('\u7a33\u6001\u8d8b\u52bf')
}
function isChecksquareMenu(menu: any): boolean {
const normalizedName = String(menu?.name ?? '').toLowerCase().replace(/[-_]/g, '')
const normalizedPath = String(menu?.path ?? '').toLowerCase().replace(/[-_]/g, '')
const normalizedComponent = String(menu?.component ?? '').toLowerCase().replace(/[-_]/g, '')
const title = String(menu?.meta?.title ?? menu?.title ?? '')
if (normalizedName === 'checksquare') return true
if (normalizedPath.includes('checksquare')) return true
if (normalizedComponent.includes('checksquare')) return true
return title.includes('数据验证')
}
function isDbmsMenu(menu: any): boolean {
const normalizedName = String(menu?.name ?? '').toLowerCase().replace(/[-_]/g, '')
const normalizedPath = String(menu?.path ?? '').toLowerCase().replace(/[-_]/g, '')
const normalizedComponent = String(menu?.component ?? '').toLowerCase().replace(/[-_]/g, '')
const title = String(menu?.meta?.title ?? menu?.title ?? '')
if (normalizedName === 'systemopsdbms' || normalizedName === 'dbms') return true
if (normalizedPath.includes('systemmonitor/dbms') || normalizedPath.includes('systemops/dbms')) return true
if (normalizedPath.includes('databasemonitor') || normalizedComponent.includes('databasemonitor')) return true
if (normalizedComponent.includes('systemmonitor/dbms') || normalizedComponent.includes('systemops/dbms')) return true
return title.includes('数据库') && (title.includes('运维') || title.includes('监控'))
}
export function resolveBusinessMenuPath(menu: Menu.MenuOptions): string {
2026-05-15 16:36:50 +08:00
if (isEventListMenu(menu)) return '/eventList/index'
if (isChecksquareMenu(menu)) return '/checksquare/index'
if (isSteadyTrendMenu(menu)) return '/steadyTrend/index'
if (isDbmsMenu(menu)) return '/system-ops/dbms'
2026-05-15 16:36:50 +08:00
return isSteadyDataViewMenu(menu) ? '/steadyDataView/index' : menu.path
}
2026-04-13 17:32:58 +08:00
function normalizeActivateInfo(rawData: unknown): Activate.ActivationCodePlaintext {
if (!rawData || typeof rawData !== 'object' || Array.isArray(rawData)) {
return {}
}
return Object.entries(rawData as Record<string, unknown>).reduce(
(modules, [key, value]) => {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
return modules
}
if (!Object.prototype.hasOwnProperty.call(value, 'permanently')) {
return modules
}
const permanentlyValue = (value as { permanently?: unknown }).permanently
modules[key] = {
permanently: Number(permanentlyValue) === 1 ? 1 : 0
}
return modules
},
{} as Activate.ActivationCodePlaintext
)
}