docs(dashboard): 新增仪表盘监控相关技术文档
This commit is contained in:
parent
61b8494839
commit
3dbcf80402
236
doc/dashborad/仪表盘接口实现清单.md
Normal file
236
doc/dashborad/仪表盘接口实现清单.md
Normal file
@ -0,0 +1,236 @@
|
||||
# 仪表盘接口实现清单
|
||||
|
||||
## 需要实现的接口总览
|
||||
|
||||
后端需要实现以下3个核心接口来支持前端仪表盘功能:
|
||||
|
||||
### 1. 获取仪表盘统计数据
|
||||
- **接口**: `GET /coder/dashboard/getStatistics`
|
||||
- **权限**: `dashboard:view`
|
||||
- **功能**: 获取用户、登录、存储、活跃度等核心统计数据
|
||||
|
||||
### 2. 获取登录趋势数据
|
||||
- **接口**: `GET /coder/dashboard/getLoginTrend`
|
||||
- **权限**: `dashboard:view`
|
||||
- **功能**: 获取最近N天的登录趋势图表数据
|
||||
|
||||
### 3. 获取完整仪表盘数据(推荐)
|
||||
- **接口**: `GET /coder/dashboard/getAllData`
|
||||
- **权限**: `dashboard:view`
|
||||
- **功能**: 一次性获取所有仪表盘数据,减少前端请求次数
|
||||
|
||||
## 实现优先级
|
||||
|
||||
### 🔴 高优先级(必须实现)
|
||||
1. **getAllData接口** - 前端仪表盘主要依赖此接口
|
||||
2. **用户统计数据** - 核心统计卡片必需
|
||||
3. **登录趋势数据** - 登录趋势图表必需
|
||||
|
||||
### 🟡 中优先级(建议实现)
|
||||
4. **存储统计数据** - 存储相关统计卡片
|
||||
5. **今日活跃统计** - 活跃度统计卡片
|
||||
|
||||
### 🟢 低优先级(可选实现)
|
||||
6. **单独的统计接口** - 可根据需要拆分实现
|
||||
7. **高级缓存策略** - 性能优化
|
||||
8. **实时数据推送** - WebSocket实时更新
|
||||
|
||||
## 核心数据结构
|
||||
|
||||
### 前端期望的数据格式
|
||||
```typescript
|
||||
interface DashboardData {
|
||||
userStats: {
|
||||
totalUsers: number // 总用户数
|
||||
todayNewUsers: number // 今日新增
|
||||
activeUsers: number // 活跃用户
|
||||
onlineUsers: number // 在线用户
|
||||
}
|
||||
loginStats: {
|
||||
todayLogins: number // 今日登录
|
||||
totalLogins: number // 累计登录
|
||||
loginTrend: Array<{ // 登录趋势
|
||||
date: string // 日期
|
||||
count: number // 登录次数
|
||||
label: string // 显示标签
|
||||
}>
|
||||
}
|
||||
storageStats: {
|
||||
totalFiles: number // 总文件数
|
||||
totalImages: number // 总图片数
|
||||
totalSize: string // 总大小
|
||||
todayUploads: number // 今日上传
|
||||
storageUsage: number // 使用率%
|
||||
availableSpace: string // 可用空间
|
||||
}
|
||||
dailyActivityStats: {
|
||||
todayVisits: number // 今日访问
|
||||
todayOperations: number // 今日操作
|
||||
activeUsers: number // 活跃用户
|
||||
newContent: number // 新增内容
|
||||
apiCalls: number // API调用
|
||||
avgResponseTime: number // 平均响应时间
|
||||
}
|
||||
systemStatus?: {
|
||||
diskUsage: number // 磁盘使用率%
|
||||
memoryUsage: number // 内存使用率%
|
||||
cpuUsage: number // CPU使用率%
|
||||
systemHealth: string // 系统健康状态
|
||||
uptime: string // 运行时间
|
||||
lastBackup: string // 最后备份时间
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 数据来源映射
|
||||
|
||||
### 用户统计 (userStats)
|
||||
- `totalUsers`: `SELECT COUNT(*) FROM sys_login_user`
|
||||
- `todayNewUsers`: `SELECT COUNT(*) FROM sys_login_user WHERE DATE(create_time) = CURDATE()`
|
||||
- `activeUsers`: `SELECT COUNT(DISTINCT user_id) FROM sys_login_log WHERE login_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)`
|
||||
- `onlineUsers`: 通过Sa-Token获取当前在线会话数
|
||||
|
||||
### 登录统计 (loginStats)
|
||||
- `todayLogins`: `SELECT COUNT(*) FROM sys_login_log WHERE DATE(login_time) = CURDATE() AND status = 'success'`
|
||||
- `totalLogins`: `SELECT COUNT(*) FROM sys_login_log WHERE status = 'success'`
|
||||
- `loginTrend`: `SELECT DATE(login_time) as date, COUNT(*) as count FROM sys_login_log WHERE login_time >= DATE_SUB(NOW(), INTERVAL 7 DAY) GROUP BY DATE(login_time)`
|
||||
|
||||
### 存储统计 (storageStats)
|
||||
- `totalFiles`: `SELECT COUNT(*) FROM sys_file`
|
||||
- `totalImages`: `SELECT COUNT(*) FROM sys_picture`
|
||||
- `totalSize`: `SELECT SUM(file_size) FROM sys_file` (转换为GB/MB格式)
|
||||
- `todayUploads`: `SELECT COUNT(*) FROM sys_file WHERE DATE(create_time) = CURDATE()`
|
||||
- `storageUsage`: 计算已用空间百分比
|
||||
- `availableSpace`: 计算剩余可用空间
|
||||
|
||||
### 今日活跃统计 (dailyActivityStats)
|
||||
- `todayVisits`: `SELECT COUNT(*) FROM sys_oper_log WHERE DATE(oper_time) = CURDATE()`
|
||||
- `todayOperations`: `SELECT COUNT(*) FROM sys_oper_log WHERE DATE(oper_time) = CURDATE() AND business_type != 'SELECT'`
|
||||
- `activeUsers`: 与用户统计中的activeUsers相同
|
||||
- `newContent`: 今日新增的内容数量(文件、图片等)
|
||||
- `apiCalls`: `SELECT COUNT(*) FROM sys_oper_log WHERE DATE(oper_time) = CURDATE()`
|
||||
- `avgResponseTime`: `SELECT AVG(cost_time) FROM sys_oper_log WHERE DATE(oper_time) = CURDATE()`
|
||||
|
||||
|
||||
|
||||
## 建议的实现步骤
|
||||
|
||||
### 第一阶段:基础统计功能
|
||||
1. ✅ 创建 `DashboardController`
|
||||
2. ✅ 创建 `DashboardService`
|
||||
3. ✅ 实现用户统计查询
|
||||
4. ✅ 实现登录统计查询
|
||||
5. ✅ 实现 `getAllData` 接口
|
||||
6. ✅ 前端集成测试
|
||||
|
||||
### 第二阶段:扩展功能
|
||||
1. ✅ 实现存储统计查询
|
||||
2. ✅ 实现活跃度统计查询
|
||||
3. ✅ 实现登录趋势图表数据
|
||||
4. ✅ 添加缓存支持
|
||||
|
||||
### 第三阶段:性能优化
|
||||
1. ✅ 添加Redis缓存支持
|
||||
2. ✅ 优化数据库查询
|
||||
3. ✅ 实现定时统计任务
|
||||
4. ✅ 添加监控日志
|
||||
|
||||
## 性能优化建议
|
||||
|
||||
### 缓存策略
|
||||
- 统计数据:5分钟缓存
|
||||
- 趋势数据:1小时缓存
|
||||
|
||||
### 数据库优化
|
||||
- 添加必要索引
|
||||
- 使用聚合查询
|
||||
- 考虑分表策略
|
||||
|
||||
### 查询优化
|
||||
```sql
|
||||
-- 建议的索引
|
||||
CREATE INDEX idx_user_create_time ON sys_login_user(create_time);
|
||||
CREATE INDEX idx_login_log_time_status ON sys_login_log(login_time, status);
|
||||
CREATE INDEX idx_oper_log_time ON sys_oper_log(oper_time);
|
||||
CREATE INDEX idx_file_create_time ON sys_file(create_time);
|
||||
```
|
||||
|
||||
## 权限配置
|
||||
|
||||
需要在权限系统中添加以下权限:
|
||||
|
||||
```sql
|
||||
-- 权限数据插入
|
||||
INSERT INTO sys_menu (menu_name, perms, menu_type) VALUES
|
||||
('仪表盘查看', 'dashboard:view', 'F');
|
||||
```
|
||||
|
||||
## API测试用例
|
||||
|
||||
### 测试接口连通性
|
||||
```bash
|
||||
# 获取完整仪表盘数据
|
||||
curl -X GET \
|
||||
"http://localhost:18099/coder/dashboard/getAllData" \
|
||||
-H "Authorization: your-token-value"
|
||||
|
||||
# 获取登录趋势
|
||||
curl -X GET \
|
||||
"http://localhost:18099/coder/dashboard/getLoginTrend?days=7" \
|
||||
-H "Authorization: your-token-value"
|
||||
```
|
||||
|
||||
### 验证数据格式
|
||||
确保返回的JSON格式与前端类型定义完全匹配。
|
||||
|
||||
## 前端集成要点
|
||||
|
||||
### 1. 替换Mock数据
|
||||
```typescript
|
||||
// 原来的mock调用
|
||||
const dashboardData = ref<DashboardData>(generateMockDashboardData())
|
||||
|
||||
// 替换为API调用
|
||||
const loadDashboardData = async () => {
|
||||
const { data } = await getAllDashboardData()
|
||||
dashboardData.value = data
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 错误处理
|
||||
```typescript
|
||||
try {
|
||||
const { data } = await getAllDashboardData()
|
||||
dashboardData.value = data
|
||||
} catch (error) {
|
||||
coiMsgError('获取仪表盘数据失败')
|
||||
// 可选:降级到mock数据
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 数据刷新
|
||||
```typescript
|
||||
// 手动刷新
|
||||
const refreshData = async () => {
|
||||
await loadDashboardData()
|
||||
coiMsgSuccess('数据已刷新')
|
||||
}
|
||||
|
||||
// 自动刷新(可选)
|
||||
setInterval(loadDashboardData, 5 * 60 * 1000) // 每5分钟刷新
|
||||
```
|
||||
|
||||
## 部署检查清单
|
||||
|
||||
- [ ] 后端接口实现完成
|
||||
- [ ] 权限配置正确
|
||||
- [ ] 数据库索引已创建
|
||||
- [ ] 缓存配置已启用
|
||||
- [ ] 前端API集成完成
|
||||
- [ ] 接口联调测试通过
|
||||
- [ ] 性能测试通过
|
||||
- [ ] 权限测试通过
|
||||
|
||||
---
|
||||
|
||||
**总结**: 实现这3个接口即可完全支持前端仪表盘功能,其中`getAllData`接口是核心,建议优先实现。
|
||||
529
doc/dashborad/仪表盘接口设计文档.md
Normal file
529
doc/dashborad/仪表盘接口设计文档.md
Normal file
@ -0,0 +1,529 @@
|
||||
# 仪表盘接口设计文档
|
||||
|
||||
## 概述
|
||||
|
||||
仪表盘模块提供系统核心数据的统计展示功能,包括用户统计、登录统计、存储统计、活跃度统计等信息的实时展示。
|
||||
|
||||
## 前端数据需求分析
|
||||
|
||||
基于前端仪表盘页面代码分析,仪表盘需要以下数据:
|
||||
|
||||
### 1. 核心统计卡片数据
|
||||
- **用户统计**: 总用户数、今日新增用户、活跃用户数、在线用户数
|
||||
- **登录统计**: 今日登录次数、累计登录次数
|
||||
- **存储统计**: 总文件数、总图片数、总存储大小、今日上传数
|
||||
- **今日活跃**: 今日访问量、今日操作数、活跃用户数、新增内容数
|
||||
|
||||
### 2. 登录趋势图表数据
|
||||
- 最近7天的登录趋势数据
|
||||
- 每日登录次数统计
|
||||
- 趋势分析数据
|
||||
|
||||
## 权限说明
|
||||
|
||||
仪表盘接口需要相应的权限才能访问:
|
||||
|
||||
| 操作 | 权限码 | 说明 |
|
||||
|------|--------|------|
|
||||
| 查看仪表盘统计 | `dashboard:view` | 查看仪表盘统计数据权限 |
|
||||
|
||||
## 接口设计
|
||||
|
||||
### 1. 获取仪表盘统计数据
|
||||
|
||||
**接口地址**: `GET /coder/dashboard/getStatistics`
|
||||
|
||||
**接口描述**: 获取仪表盘核心统计数据
|
||||
|
||||
**是否需要认证**: 是
|
||||
|
||||
**权限要求**: `dashboard:view`
|
||||
|
||||
**请求头**:
|
||||
```
|
||||
Authorization: your-token-value
|
||||
```
|
||||
|
||||
**请求参数**: 无
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 200,
|
||||
"msg": "SUCCESS",
|
||||
"data": {
|
||||
"userStats": {
|
||||
"totalUsers": 1286,
|
||||
"todayNewUsers": 23,
|
||||
"activeUsers": 856,
|
||||
"onlineUsers": 142
|
||||
},
|
||||
"loginStats": {
|
||||
"todayLogins": 468,
|
||||
"totalLogins": 45672
|
||||
},
|
||||
"storageStats": {
|
||||
"totalFiles": 8924,
|
||||
"totalImages": 3420,
|
||||
"totalSize": "2.3 GB",
|
||||
"todayUploads": 67,
|
||||
"storageUsage": 67.5,
|
||||
"availableSpace": "1.2 GB"
|
||||
},
|
||||
"dailyActivityStats": {
|
||||
"todayVisits": 1247,
|
||||
"todayOperations": 856,
|
||||
"activeUsers": 142,
|
||||
"newContent": 23,
|
||||
"apiCalls": 3420,
|
||||
"avgResponseTime": 235
|
||||
}
|
||||
},
|
||||
"traceId": "trace-123456"
|
||||
}
|
||||
```
|
||||
|
||||
**数据结构说明**:
|
||||
|
||||
#### UserStats 用户统计
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| totalUsers | Integer | 总用户数 |
|
||||
| todayNewUsers | Integer | 今日新增用户数 |
|
||||
| activeUsers | Integer | 活跃用户数 |
|
||||
| onlineUsers | Integer | 当前在线用户数 |
|
||||
|
||||
#### LoginStats 登录统计
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| todayLogins | Integer | 今日登录次数 |
|
||||
| totalLogins | Integer | 累计登录次数 |
|
||||
|
||||
#### StorageStats 存储统计
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| totalFiles | Integer | 总文件数 |
|
||||
| totalImages | Integer | 总图片数 |
|
||||
| totalSize | String | 总存储大小(格式化) |
|
||||
| todayUploads | Integer | 今日上传文件数 |
|
||||
| storageUsage | Double | 存储使用率(百分比) |
|
||||
| availableSpace | String | 可用空间(格式化) |
|
||||
|
||||
#### DailyActivityStats 今日活跃统计
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| todayVisits | Integer | 今日访问量 |
|
||||
| todayOperations | Integer | 今日操作数 |
|
||||
| activeUsers | Integer | 活跃用户数 |
|
||||
| newContent | Integer | 新增内容数 |
|
||||
| apiCalls | Integer | API调用次数 |
|
||||
| avgResponseTime | Integer | 平均响应时间(毫秒) |
|
||||
|
||||
**调用示例**:
|
||||
|
||||
```bash
|
||||
curl -X GET \
|
||||
http://localhost:18099/coder/dashboard/getStatistics \
|
||||
-H "Authorization: your-token-value"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. 获取登录趋势数据
|
||||
|
||||
**接口地址**: `GET /coder/dashboard/getLoginTrend`
|
||||
|
||||
**接口描述**: 获取最近7天的登录趋势数据
|
||||
|
||||
**是否需要认证**: 是
|
||||
|
||||
**权限要求**: `dashboard:view`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | 默认值 |
|
||||
|--------|------|------|------|--------|
|
||||
| days | Integer | 否 | 查询天数 | 7 |
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 200,
|
||||
"msg": "SUCCESS",
|
||||
"data": {
|
||||
"loginTrend": [
|
||||
{
|
||||
"date": "2024-01-15",
|
||||
"count": 324,
|
||||
"label": "1月15日"
|
||||
},
|
||||
{
|
||||
"date": "2024-01-16",
|
||||
"count": 298,
|
||||
"label": "1月16日"
|
||||
},
|
||||
{
|
||||
"date": "2024-01-17",
|
||||
"count": 412,
|
||||
"label": "1月17日"
|
||||
},
|
||||
{
|
||||
"date": "2024-01-18",
|
||||
"count": 356,
|
||||
"label": "1月18日"
|
||||
},
|
||||
{
|
||||
"date": "2024-01-19",
|
||||
"count": 287,
|
||||
"label": "1月19日"
|
||||
},
|
||||
{
|
||||
"date": "2024-01-20",
|
||||
"count": 198,
|
||||
"label": "1月20日"
|
||||
},
|
||||
{
|
||||
"date": "2024-01-21",
|
||||
"count": 468,
|
||||
"label": "1月21日"
|
||||
}
|
||||
]
|
||||
},
|
||||
"traceId": "trace-123456"
|
||||
}
|
||||
```
|
||||
|
||||
**数据结构说明**:
|
||||
|
||||
#### LoginTrendItem 登录趋势项
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| date | String | 日期(YYYY-MM-DD格式) |
|
||||
| count | Integer | 当日登录次数 |
|
||||
| label | String | 显示标签(用于图表展示) |
|
||||
|
||||
**调用示例**:
|
||||
|
||||
```bash
|
||||
curl -X GET \
|
||||
"http://localhost:18099/coder/dashboard/getLoginTrend?days=7" \
|
||||
-H "Authorization: your-token-value"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 获取完整仪表盘数据
|
||||
|
||||
**接口地址**: `GET /coder/dashboard/getAllData`
|
||||
|
||||
**接口描述**: 一次性获取仪表盘所有数据(聚合接口)
|
||||
|
||||
**是否需要认证**: 是
|
||||
|
||||
**权限要求**: `dashboard:view`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | 默认值 |
|
||||
|--------|------|------|------|--------|
|
||||
| includeTrend | Boolean | 否 | 是否包含趋势数据 | true |
|
||||
| trendDays | Integer | 否 | 趋势数据天数 | 7 |
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 200,
|
||||
"msg": "SUCCESS",
|
||||
"data": {
|
||||
"userStats": {
|
||||
"totalUsers": 1286,
|
||||
"todayNewUsers": 23,
|
||||
"activeUsers": 856,
|
||||
"onlineUsers": 142
|
||||
},
|
||||
"loginStats": {
|
||||
"todayLogins": 468,
|
||||
"totalLogins": 45672,
|
||||
"loginTrend": [
|
||||
{
|
||||
"date": "2024-01-15",
|
||||
"count": 324,
|
||||
"label": "1月15日"
|
||||
}
|
||||
]
|
||||
},
|
||||
"storageStats": {
|
||||
"totalFiles": 8924,
|
||||
"totalImages": 3420,
|
||||
"totalSize": "2.3 GB",
|
||||
"todayUploads": 67,
|
||||
"storageUsage": 67.5,
|
||||
"availableSpace": "1.2 GB"
|
||||
},
|
||||
"dailyActivityStats": {
|
||||
"todayVisits": 1247,
|
||||
"todayOperations": 856,
|
||||
"activeUsers": 142,
|
||||
"newContent": 23,
|
||||
"apiCalls": 3420,
|
||||
"avgResponseTime": 235
|
||||
}
|
||||
},
|
||||
"traceId": "trace-123456"
|
||||
}
|
||||
```
|
||||
|
||||
**调用示例**:
|
||||
|
||||
```bash
|
||||
curl -X GET \
|
||||
"http://localhost:18099/coder/dashboard/getAllData?includeTrend=true&trendDays=7" \
|
||||
-H "Authorization: your-token-value"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 数据来源分析
|
||||
|
||||
### 用户统计数据来源
|
||||
- **总用户数**: 查询 `sys_login_user` 表总记录数
|
||||
- **今日新增用户**: 查询 `sys_login_user` 表当日创建的记录数
|
||||
- **活跃用户数**: 查询最近30天有登录记录的用户数
|
||||
- **在线用户数**: 查询当前有效会话的用户数(通过Sa-Token获取)
|
||||
|
||||
### 登录统计数据来源
|
||||
- **今日登录次数**: 查询 `sys_login_log` 表当日成功登录记录数
|
||||
- **累计登录次数**: 查询 `sys_login_log` 表总成功登录记录数
|
||||
- **登录趋势**: 查询 `sys_login_log` 表按日期分组的登录统计
|
||||
|
||||
### 存储统计数据来源
|
||||
- **总文件数**: 查询 `sys_file` 表总记录数
|
||||
- **总图片数**: 查询 `sys_picture` 表总记录数
|
||||
- **存储大小**: 查询 `sys_file` 表文件大小字段求和
|
||||
- **今日上传数**: 查询 `sys_file` 表当日上传的文件数
|
||||
|
||||
### 今日活跃统计数据来源
|
||||
- **今日访问量**: 查询 `sys_oper_log` 表当日访问记录数
|
||||
- **今日操作数**: 查询 `sys_oper_log` 表当日操作记录数
|
||||
- **API调用次数**: 查询 `sys_oper_log` 表API调用统计
|
||||
- **平均响应时间**: 查询 `sys_oper_log` 表响应时间字段平均值
|
||||
|
||||
---
|
||||
|
||||
## 建议的数据库查询优化
|
||||
|
||||
### 1. 索引优化
|
||||
```sql
|
||||
-- 用户表索引
|
||||
CREATE INDEX idx_user_create_time ON sys_login_user(create_time);
|
||||
CREATE INDEX idx_user_status ON sys_login_user(user_status);
|
||||
|
||||
-- 登录日志索引
|
||||
CREATE INDEX idx_login_log_date ON sys_login_log(login_time);
|
||||
CREATE INDEX idx_login_log_status ON sys_login_log(status);
|
||||
|
||||
-- 操作日志索引
|
||||
CREATE INDEX idx_oper_log_date ON sys_oper_log(oper_time);
|
||||
CREATE INDEX idx_oper_log_type ON sys_oper_log(business_type);
|
||||
|
||||
-- 文件表索引
|
||||
CREATE INDEX idx_file_create_time ON sys_file(create_time);
|
||||
CREATE INDEX idx_file_size ON sys_file(file_size);
|
||||
```
|
||||
|
||||
### 2. 缓存策略
|
||||
- **统计数据缓存**: 使用Redis缓存统计结果,每5分钟更新一次
|
||||
- **趋势数据缓存**: 登录趋势数据每小时更新一次
|
||||
|
||||
### 3. 查询优化
|
||||
- 使用聚合查询减少数据库访问次数
|
||||
- 对于大表查询,考虑分表或定时统计
|
||||
- 使用合适的时间范围避免全表扫描
|
||||
|
||||
---
|
||||
|
||||
## 错误码说明
|
||||
|
||||
| 错误码 | 错误信息 | 说明 |
|
||||
|--------|----------|------|
|
||||
| 400 | 参数错误 | 请求参数格式不正确 |
|
||||
| 401 | 当前会话未登录 | 未登录或Token无效 |
|
||||
| 403 | 权限不足 | 没有查看仪表盘的权限 |
|
||||
| 500 | 统计数据获取失败 | 服务器内部错误 |
|
||||
|
||||
---
|
||||
|
||||
## 实现建议
|
||||
|
||||
### 1. Controller 层实现
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/coder/dashboard")
|
||||
@Tag(name = "仪表盘管理", description = "仪表盘统计数据接口")
|
||||
public class DashboardController {
|
||||
|
||||
@GetMapping("/getStatistics")
|
||||
@Operation(summary = "获取仪表盘统计数据")
|
||||
@SaCheckPermission("dashboard:view")
|
||||
public R<DashboardStatistics> getStatistics() {
|
||||
// 实现统计数据获取逻辑
|
||||
}
|
||||
|
||||
@GetMapping("/getLoginTrend")
|
||||
@Operation(summary = "获取登录趋势数据")
|
||||
@SaCheckPermission("dashboard:view")
|
||||
public R<LoginTrendData> getLoginTrend(@RequestParam(defaultValue = "7") Integer days) {
|
||||
// 实现登录趋势数据获取逻辑
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/getAllData")
|
||||
@Operation(summary = "获取完整仪表盘数据")
|
||||
@SaCheckPermission("dashboard:view")
|
||||
public R<CompleteDashboardData> getAllData(
|
||||
@RequestParam(defaultValue = "true") Boolean includeTrend,
|
||||
@RequestParam(defaultValue = "7") Integer trendDays
|
||||
) {
|
||||
// 实现完整数据获取逻辑
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Service 层实现建议
|
||||
- `DashboardService`: 主要业务逻辑
|
||||
- `DashboardStatisticsService`: 统计数据计算
|
||||
- `CacheService`: 缓存管理
|
||||
|
||||
### 3. 数据传输对象 (DTO)
|
||||
- `DashboardStatisticsVo`: 统计数据响应对象
|
||||
- `LoginTrendVo`: 登录趋势响应对象
|
||||
- `CompleteDashboardVo`: 完整仪表盘数据响应对象
|
||||
|
||||
### 4. 缓存键定义
|
||||
```java
|
||||
public class DashboardCacheConstants {
|
||||
public static final String DASHBOARD_STATISTICS = "dashboard:statistics";
|
||||
public static final String LOGIN_TREND = "dashboard:login_trend:";
|
||||
public static final String USER_ONLINE_COUNT = "dashboard:online_users";
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 前端集成指南
|
||||
|
||||
### 1. API客户端配置
|
||||
在前端项目中创建仪表盘API模块:
|
||||
|
||||
```typescript
|
||||
// src/service/api/dashboard/index.ts
|
||||
import { request } from '../../http'
|
||||
import type { DashboardData, LoginTrendData } from './types'
|
||||
|
||||
// 获取仪表盘统计数据
|
||||
export function getDashboardStatistics() {
|
||||
return request.Get<Service.ResponseResult<DashboardData>>('/coder/dashboard/getStatistics')
|
||||
}
|
||||
|
||||
// 获取登录趋势数据
|
||||
export function getLoginTrend(days: number = 7) {
|
||||
return request.Get<Service.ResponseResult<LoginTrendData>>(`/coder/dashboard/getLoginTrend?days=${days}`)
|
||||
}
|
||||
|
||||
// 获取完整仪表盘数据
|
||||
export function getAllDashboardData(params?: {
|
||||
includeTrend?: boolean
|
||||
trendDays?: number
|
||||
}) {
|
||||
return request.Get<Service.ResponseResult<DashboardData>>('/coder/dashboard/getAllData', { params })
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 类型定义
|
||||
```typescript
|
||||
// src/service/api/dashboard/types.ts
|
||||
export interface UserStats {
|
||||
totalUsers: number
|
||||
todayNewUsers: number
|
||||
activeUsers: number
|
||||
onlineUsers: number
|
||||
}
|
||||
|
||||
export interface LoginStats {
|
||||
todayLogins: number
|
||||
totalLogins: number
|
||||
loginTrend?: Array<{
|
||||
date: string
|
||||
count: number
|
||||
label: string
|
||||
}>
|
||||
}
|
||||
|
||||
export interface StorageStats {
|
||||
totalFiles: number
|
||||
totalImages: number
|
||||
totalSize: string
|
||||
todayUploads: number
|
||||
storageUsage: number
|
||||
availableSpace: string
|
||||
}
|
||||
|
||||
export interface DailyActivityStats {
|
||||
todayVisits: number
|
||||
todayOperations: number
|
||||
activeUsers: number
|
||||
newContent: number
|
||||
apiCalls: number
|
||||
avgResponseTime: number
|
||||
}
|
||||
|
||||
export interface DashboardData {
|
||||
userStats: UserStats
|
||||
loginStats: LoginStats
|
||||
storageStats: StorageStats
|
||||
dailyActivityStats: DailyActivityStats
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 前端页面集成
|
||||
更新现有的仪表盘页面以使用真实API:
|
||||
|
||||
```typescript
|
||||
// src/views/dashboard/monitor/index.vue
|
||||
import { getAllDashboardData } from '@/service/api/dashboard'
|
||||
|
||||
// 替换mockData的使用
|
||||
const loadDashboardData = async () => {
|
||||
try {
|
||||
const { data } = await getAllDashboardData({
|
||||
includeTrend: true,
|
||||
trendDays: 7
|
||||
})
|
||||
dashboardData.value = data
|
||||
} catch (error) {
|
||||
console.error('获取仪表盘数据失败:', error)
|
||||
coiMsgError('获取仪表盘数据失败')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **性能考虑**: 统计查询可能较耗时,建议使用缓存和异步更新
|
||||
2. **权限控制**: 不同角色可能需要查看不同的统计维度
|
||||
3. **数据准确性**: 实时数据和缓存数据的平衡
|
||||
4. **扩展性**: 预留接口扩展空间,支持更多统计维度
|
||||
5. **数据安全**: 敏感统计数据的访问控制
|
||||
6. **并发处理**: 大量用户同时访问仪表盘的性能优化
|
||||
7. **定时任务**: 考虑使用定时任务预计算统计数据
|
||||
|
||||
---
|
||||
|
||||
## 更新日志
|
||||
|
||||
- **v1.0.0** (2025-01-23): 初始版本,定义仪表盘核心接口
|
||||
Loading…
Reference in New Issue
Block a user