529 lines
13 KiB
Markdown
529 lines
13 KiB
Markdown
# 仪表盘接口设计文档
|
||
|
||
## 概述
|
||
|
||
仪表盘模块提供系统核心数据的统计展示功能,包括用户统计、登录统计、存储统计、活跃度统计等信息的实时展示。
|
||
|
||
## 前端数据需求分析
|
||
|
||
基于前端仪表盘页面代码分析,仪表盘需要以下数据:
|
||
|
||
### 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): 初始版本,定义仪表盘核心接口 |