feat: 新增监控页面、部门管理占位与单元测试

- 新增系统监控模块(在线用户、定时任务、数据监控、服务器监控、缓存监控)
- 新增部门管理占位页面
- 路由注册新增模块与懒加载
- DefaultLayout 侧边菜单与布局优化
- 新增前端单元测试与后端 RoleUpdateRequest 测试
This commit is contained in:
张翔
2026-05-06 14:18:17 +08:00
parent bd21e2d1f7
commit 5dc53f57cc
30 changed files with 2071 additions and 4 deletions
@@ -0,0 +1,192 @@
import { describe, it, expect } from 'vitest'
import type { RawMenuItem } from '@/api/menu'
const menuTypeMap: Record<string, 'directory' | 'menu' | 'button'> = {
M: 'directory',
C: 'menu',
F: 'button',
}
function buildPath(raw: RawMenuItem): string {
if (raw.menuType === 'M') return ''
if (raw.menuType === 'F') return ''
const perm = raw.perms || ''
const pathMap: Record<string, string> = {
'system:user:list': '/users',
'system:role:list': '/roles',
'system:menu:list': '/menus',
'system:dept:list': '/sys/dept',
'system:dict:list': '/dict',
'system:config:list': '/sys/config',
'system:notice:list': '/notice',
'system:file:list': '/files',
'audit:login:list': '/loginlog',
'audit:login-log:list': '/loginlog',
'audit:operation:list': '/oplog',
'audit:operation-log:list': '/oplog',
'audit:exception:list': '/exceptionlog',
'audit:exception-log:list': '/exceptionlog',
'monitor:online:list': '/monitor/online',
'monitor:job:list': '/monitor/job',
'monitor:data:list': '/monitor/data',
'monitor:server:list': '/monitor/server',
'monitor:cache:list': '/monitor/cache',
}
return pathMap[perm] || ''
}
function inferIcon(raw: RawMenuItem): string {
const perm = raw.perms || ''
const iconMap: Record<string, string> = {
'system:user:list': 'user',
'system:role:list': 'role',
'system:menu:list': 'menu',
'system:dept:list': 'menu',
'system:dict:list': 'dict',
'system:config:list': 'config',
'system:notice:list': 'notice',
'system:file:list': 'file',
'audit:login:list': 'loginlog',
'audit:login-log:list': 'loginlog',
'audit:operation:list': 'oplog',
'audit:operation-log:list': 'oplog',
'audit:exception:list': 'exceptionlog',
'audit:exception-log:list': 'exceptionlog',
'monitor:online:list': 'user',
'monitor:job:list': 'menu',
'monitor:data:list': 'config',
'monitor:server:list': 'config',
'monitor:cache:list': 'config',
}
return iconMap[perm] || ''
}
function makeRaw(overrides: Partial<RawMenuItem> = {}): RawMenuItem {
return {
id: '1',
createBy: null,
updateBy: null,
createdAt: '2026-01-01T00:00:00',
updatedAt: '2026-01-01T00:00:00',
deletedAt: null,
menuName: '测试菜单',
parentId: '0',
orderNum: 1,
menuType: 'C',
perms: null,
component: null,
status: 0,
children: [],
...overrides,
}
}
describe('menu utils', () => {
describe('buildPath', () => {
it('should return empty string for directory type (M)', () => {
const raw = makeRaw({ menuType: 'M' })
expect(buildPath(raw)).toBe('')
})
it('should return empty string for button type (F)', () => {
const raw = makeRaw({ menuType: 'F' })
expect(buildPath(raw)).toBe('')
})
it('should map system:user:list to /users', () => {
const raw = makeRaw({ menuType: 'C', perms: 'system:user:list' })
expect(buildPath(raw)).toBe('/users')
})
it('should map system:role:list to /roles', () => {
const raw = makeRaw({ menuType: 'C', perms: 'system:role:list' })
expect(buildPath(raw)).toBe('/roles')
})
it('should map system:dept:list to /sys/dept', () => {
const raw = makeRaw({ menuType: 'C', perms: 'system:dept:list' })
expect(buildPath(raw)).toBe('/sys/dept')
})
it('should map audit:login:list to /loginlog', () => {
const raw = makeRaw({ menuType: 'C', perms: 'audit:login:list' })
expect(buildPath(raw)).toBe('/loginlog')
})
it('should map audit:login-log:list to /loginlog (alternate key)', () => {
const raw = makeRaw({ menuType: 'C', perms: 'audit:login-log:list' })
expect(buildPath(raw)).toBe('/loginlog')
})
it('should map audit:operation:list to /oplog', () => {
const raw = makeRaw({ menuType: 'C', perms: 'audit:operation:list' })
expect(buildPath(raw)).toBe('/oplog')
})
it('should map audit:exception:list to /exceptionlog', () => {
const raw = makeRaw({ menuType: 'C', perms: 'audit:exception:list' })
expect(buildPath(raw)).toBe('/exceptionlog')
})
it('should map monitor:online:list to /monitor/online', () => {
const raw = makeRaw({ menuType: 'C', perms: 'monitor:online:list' })
expect(buildPath(raw)).toBe('/monitor/online')
})
it('should map monitor:cache:list to /monitor/cache', () => {
const raw = makeRaw({ menuType: 'C', perms: 'monitor:cache:list' })
expect(buildPath(raw)).toBe('/monitor/cache')
})
it('should return empty string for unknown permission', () => {
const raw = makeRaw({ menuType: 'C', perms: 'unknown:perm:list' })
expect(buildPath(raw)).toBe('')
})
it('should return empty string when perms is null', () => {
const raw = makeRaw({ menuType: 'C', perms: null })
expect(buildPath(raw)).toBe('')
})
})
describe('inferIcon', () => {
it('should return user icon for system:user:list', () => {
const raw = makeRaw({ perms: 'system:user:list' })
expect(inferIcon(raw)).toBe('user')
})
it('should return role icon for system:role:list', () => {
const raw = makeRaw({ perms: 'system:role:list' })
expect(inferIcon(raw)).toBe('role')
})
it('should return loginlog icon for audit:login:list', () => {
const raw = makeRaw({ perms: 'audit:login:list' })
expect(inferIcon(raw)).toBe('loginlog')
})
it('should return empty string for unknown permission', () => {
const raw = makeRaw({ perms: 'unknown:perm:list' })
expect(inferIcon(raw)).toBe('')
})
it('should return empty string when perms is null', () => {
const raw = makeRaw({ perms: null })
expect(inferIcon(raw)).toBe('')
})
})
describe('menuTypeMap', () => {
it('should map M to directory', () => {
expect(menuTypeMap['M']).toBe('directory')
})
it('should map C to menu', () => {
expect(menuTypeMap['C']).toBe('menu')
})
it('should map F to button', () => {
expect(menuTypeMap['F']).toBe('button')
})
})
})