style(diskMonitor): 统一磁盘监控页面样式规范

- 添加页面边距、表格样式和按钮样式约定到 AGENTS.md 文档
- 为任务详情抽屉组件添加卡片样式和表格结构优化
- 重构任务表格组件,增加搜索功能和列设置选项
- 移除独立的策略表单组件,整合到汇总页面
- 优化监控摘要组件的网格布局和样式
- 重新设计目标对话框的表单分组和禁用状态处理
- 统一所有组件使用 card、table-main 等标准类名
- 添加文件编码规范要求确保 UTF-8 编码一致性
This commit is contained in:
2026-04-30 09:02:57 +08:00
parent 287de846a6
commit 398a2cf1dc
16 changed files with 1179 additions and 608 deletions

View File

@@ -5,8 +5,9 @@ import { ElNotification } from 'element-plus'
import { useUserStore } from '@/stores/modules/user'
import { useAuthStore } from '@/stores/modules/auth'
// 引入 views 文件夹下所有 vue 文件
const modules = import.meta.glob('@/views/**/*.vue')
const VIEWS_ALIAS_PREFIX = '@/views'
const VIEWS_SRC_PREFIX = '/src/views'
const STATIC_ROUTE_NAMES = new Set([
'layout',
'login',
@@ -14,6 +15,7 @@ const STATIC_ROUTE_NAMES = new Set([
'tools',
'toolWaveform',
'toolMmsMapping',
'toolAddData',
'systemMonitor',
'diskMonitor',
'403',
@@ -24,7 +26,7 @@ const STATIC_ROUTE_NAMES = new Set([
let isInitializing = false
/**
* 清除已有的动态路由
* 清除已有的动态路由,避免重复注入。
*/
const clearDynamicRoutes = () => {
const routes = router.getRoutes()
@@ -36,13 +38,19 @@ const clearDynamicRoutes = () => {
}
/**
* 根据菜单 component 路径查找对应的页面模块
* 兼容两种仓库写法:
* 1. /foo/bar.vue
* 2. /foo/bar/index.vue
* 统一菜单 component 配置格式,只允许映射到 views 目录
*/
const resolveComponentModule = (path: string) => {
let normalizedPath = path.trim()
const normalizeComponentPath = (path: string) => {
let normalizedPath = path.trim().replace(/\\/g, '/')
if (normalizedPath.startsWith(VIEWS_ALIAS_PREFIX)) {
normalizedPath = normalizedPath.slice(VIEWS_ALIAS_PREFIX.length)
} else if (normalizedPath.startsWith(VIEWS_SRC_PREFIX)) {
normalizedPath = normalizedPath.slice(VIEWS_SRC_PREFIX.length)
} else if (normalizedPath.startsWith('src/views')) {
normalizedPath = normalizedPath.slice('src/views'.length)
}
if (!normalizedPath.startsWith('/')) {
normalizedPath = '/' + normalizedPath
}
@@ -53,13 +61,31 @@ const resolveComponentModule = (path: string) => {
normalizedPath = normalizedPath.slice(0, -1)
}
const candidatePaths = [`/src/views${normalizedPath}.vue`, `/src/views${normalizedPath}/index.vue`]
return normalizedPath
}
/**
* 根据菜单 component 路径查找对应页面模块。
* 兼容菜单资源里常见的多种写法,避免因为前缀或 index 差异导致误判。
*/
const resolveComponentModule = (path: string) => {
const normalizedPath = normalizeComponentPath(path)
const viewPath = normalizedPath.endsWith('/index') ? normalizedPath.slice(0, -'/index'.length) : normalizedPath
const candidatePaths = Array.from(
new Set([
`${VIEWS_ALIAS_PREFIX}${normalizedPath}.vue`,
`${VIEWS_ALIAS_PREFIX}${normalizedPath}/index.vue`,
`${VIEWS_ALIAS_PREFIX}${viewPath}/index.vue`,
`${VIEWS_SRC_PREFIX}${normalizedPath}.vue`,
`${VIEWS_SRC_PREFIX}${normalizedPath}/index.vue`,
`${VIEWS_SRC_PREFIX}${viewPath}/index.vue`
])
)
for (const candidatePath of candidatePaths) {
const moduleLoader = modules[candidatePath]
if (moduleLoader) {
if (candidatePath in modules) {
return {
moduleLoader,
moduleLoader: modules[candidatePath],
resolvedPath: candidatePath
}
}
@@ -72,7 +98,7 @@ const resolveComponentModule = (path: string) => {
}
/**
* @description 初始化动态路由
* 初始化动态路由
*/
export const initDynamicRouter = async () => {
if (isInitializing) return Promise.reject(new Error('Dynamic router initialization in progress'))
@@ -83,15 +109,13 @@ export const initDynamicRouter = async () => {
const unresolvedRoutes: Array<{ name?: string; path?: string; component?: string; candidates: string[] }> = []
try {
// 1. 获取菜单列表 && 按钮权限列表
await authStore.getAuthMenuList()
await authStore.getAuthButtonList()
// 2. 判断当前用户有没有菜单权限
if (!authStore.authMenuListGet.length) {
ElNotification({
title: '无权限访问',
message: '当前账号无任何菜单权限,请联系系统管理员',
message: '当前账号无任何菜单权限,请联系系统管理员',
type: 'warning',
duration: 3000
})
@@ -102,21 +126,17 @@ export const initDynamicRouter = async () => {
return Promise.reject('No permission')
}
// 3. 清理之前的动态路由
clearDynamicRoutes()
// 4. 添加动态路由
for (const item of authStore.flatMenuListGet) {
// 删除 children 避免冗余嵌套
if (item.children) delete item.children
// 处理组件映射
// 动态菜单组件必须先映射成真实页面模块,否则 addRoute 后会直接落到 404。
if (item.component && typeof item.component === 'string') {
const { moduleLoader, resolvedPath } = resolveComponentModule(item.component)
if (moduleLoader) {
item.component = moduleLoader
} else {
// 动态路由组件一旦解析失败,对应菜单会落入 404这里必须打印清楚候选路径。
unresolvedRoutes.push({
name: item.name,
path: item.path,
@@ -127,7 +147,6 @@ export const initDynamicRouter = async () => {
}
}
// 类型守卫:确保满足 RouteRecordRaw 接口要求
if (
typeof item.path === 'string' &&
(typeof item.component === 'function' || typeof item.redirect === 'string')
@@ -147,7 +166,6 @@ export const initDynamicRouter = async () => {
console.error('[dynamic-router] unresolved route components', unresolvedRoutes)
}
} catch (error) {
// 当按钮 || 菜单请求出错时,重定向到登陆页
userStore.setAccessToken('')
userStore.setRefreshToken('')
userStore.setExp(0)