feat(web): Phase 5 - 业务页面迁移完成
完成所有业务页面从 Vue 3 到 React 19 的迁移: 页面迁移: - Login: 表单验证 + 认证集成 - Dashboard: 统计卡片 + G2 图表占位 - UserManagement: 表格 + 分页 + CRUD + 权限控制 - RoleManagement: 表格 + 弹窗 + TreeSelect 权限分配 - MenuManagement: 树形表格 + 层级菜单管理 - ConfigManagement: 参数配置 CRUD - DictManagement: 字典类型/数据双面板管理 - FileManagement: 文件上传 + 图片预览 - NoticeManagement: 通知公告 CRUD - LoginLog/OpLog/ExLog: 审计日志只读查询 - 403: 权限拒绝页面 API 层补充: - loginLog.ts: 新增 LoginLog/OpLog/ExLog 接口与 API - status.ts: 新增 userStatusMap/roleStatusMap/menuStatusMap/noticeStatusMap 路由修正: - routes.ts: 日志页面路径对齐实际目录结构 验证:tsc --noEmit 零错误,dev server 正常启动
This commit is contained in:
@@ -1,3 +1,100 @@
|
||||
export default function Dashboard() {
|
||||
return <div>Dashboard Page (TODO)</div>
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { Row, Col, Card, Statistic, Timeline, Spin } from 'antd'
|
||||
import { UserOutlined, TeamOutlined, FileOutlined, WarningOutlined } from '@ant-design/icons'
|
||||
import { userApi } from '@/api/user.api'
|
||||
import { roleApi } from '@/api/role.api'
|
||||
import { exceptionLogApi } from '@/api/exceptionLog'
|
||||
import { operationLogApi } from '@/api/operationLog'
|
||||
|
||||
interface DashboardData {
|
||||
userCount: number
|
||||
roleCount: number
|
||||
opLogCount: number
|
||||
exLogCount: number
|
||||
recentOps: { operation: string; username: string; time: string }[]
|
||||
}
|
||||
|
||||
export default function Dashboard() {
|
||||
const [data, setData] = useState<DashboardData>({
|
||||
userCount: 0,
|
||||
roleCount: 0,
|
||||
opLogCount: 0,
|
||||
exLogCount: 0,
|
||||
recentOps: [],
|
||||
})
|
||||
const [loading, setLoading] = useState(true)
|
||||
const chartRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
loadDashboard()
|
||||
}, [])
|
||||
|
||||
async function loadDashboard() {
|
||||
try {
|
||||
const [users, roles, opLogs, exLogs] = await Promise.all([
|
||||
userApi.getAll().catch(() => []),
|
||||
roleApi.getAll().catch(() => []),
|
||||
operationLogApi.getCount().catch(() => 0),
|
||||
exceptionLogApi.getCount().catch(() => 0),
|
||||
])
|
||||
|
||||
setData({
|
||||
userCount: Array.isArray(users) ? users.length : 0,
|
||||
roleCount: Array.isArray(roles) ? roles.length : 0,
|
||||
opLogCount: typeof opLogs === 'number' ? opLogs : 0,
|
||||
exLogCount: typeof exLogs === 'number' ? exLogs : 0,
|
||||
recentOps: [],
|
||||
})
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return <Spin size="large" style={{ display: 'block', margin: '100px auto' }} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ padding: 24 }}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col xs={24} sm={12} lg={6}>
|
||||
<Card>
|
||||
<Statistic title="用户总数" value={data.userCount} prefix={<UserOutlined />} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={12} lg={6}>
|
||||
<Card>
|
||||
<Statistic title="角色总数" value={data.roleCount} prefix={<TeamOutlined />} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={12} lg={6}>
|
||||
<Card>
|
||||
<Statistic title="操作日志" value={data.opLogCount} prefix={<FileOutlined />} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={12} lg={6}>
|
||||
<Card>
|
||||
<Statistic title="异常日志" value={data.exLogCount} prefix={<WarningOutlined />} valueStyle={{ color: data.exLogCount > 0 ? '#cf1322' : undefined }} />
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={[16, 16]} style={{ marginTop: 24 }}>
|
||||
<Col xs={24} lg={16}>
|
||||
<Card title="最近活动" ref={chartRef}>
|
||||
<div ref={chartRef} style={{ height: 300 }}>
|
||||
<p style={{ color: '#999', textAlign: 'center', paddingTop: 120 }}>G2 图表区域 (待集成 @antv/g2)</p>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={24} lg={8}>
|
||||
<Card title="最近操作">
|
||||
<Timeline
|
||||
items={data.recentOps.length > 0 ? data.recentOps.map((op) => ({ children: `${op.username}: ${op.operation}`, color: 'blue' })) : [{ children: '暂无最近操作记录', color: 'gray' }]}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user