31d66103e4
新增今日登录次数统计接口,修复Dashboard显示问题 - 在ISysLoginLogService接口添加countToday方法 - 实现SysLoginLogService中的countToday逻辑 - 更新ISysLoginLogRepository接口 - 添加SysLogHandler中的getTodayLoginCount方法 - 在SystemRouter中配置新路由端点 fix(测试): 更新系统配置URL匹配规则 - 将uat-phase1.spec.ts中的sysconfig改为sys/config docs: 添加E2E测试报告和Dashboard问题诊断文档
9.6 KiB
9.6 KiB
Dashboard数据显示问题诊断报告
问题描述
用户反馈Dashboard页面显示异常:
- 登录次数一直显示为0
- 操作日志一直显示为0
问题根因分析
1. 登录次数显示为0
前端代码分析(Dashboard.vue):
const todayLoginRes: any = await request.get('/logs/login/today/count')
stats.todayLogin = todayLoginRes || 0
后端路由配置(SystemRouter.java):
@Bean
public RouterFunction<ServerResponse> logRoutes(SysLogHandler logHandler) {
return route()
.GET("/api/logs/login", logHandler::getAllLoginLogs)
.GET("/api/logs/login/page", logHandler::getLoginLogsByPage)
.GET("/api/logs/login/count", logHandler::getLoginLogCount)
// 注意:缺少 /api/logs/login/today/count 端点
.build();
}
服务接口分析(ISysLoginLogService.java):
public interface ISysLoginLogService {
Mono<SysLoginLog> findById(Long id);
Flux<SysLoginLog> findAll();
Flux<SysLoginLog> findByUsername(String username);
Flux<SysLoginLog> findByLoginTimeBetween(LocalDateTime startTime, LocalDateTime endTime);
Mono<SysLoginLog> save(SysLoginLog loginLog);
Mono<PageResponse<SysLoginLog>> findLoginLogsByPage(PageRequest pageRequest);
Mono<Long> count();
// 注意:缺少 countToday() 方法
}
问题根因:
- 前端请求
/logs/login/today/count端点 - 后端没有配置这个路由端点
ISysLoginLogService接口缺少countToday()方法- 请求失败导致返回undefined,前端显示为0
2. 操作日志显示为0
前端代码分析(Dashboard.vue):
const operationLogRes: any = await request.get('/logs/operation/count')
stats.operationLog = operationLogRes || 0
后端路由配置(SystemRouter.java):
@Bean
public RouterFunction<ServerResponse> operationLogRoutes(OperationLogHandler operationLogHandler) {
return route()
.GET("/api/logs/operation", operationLogHandler::getAllOperationLogs)
.GET("/api/logs/operation/page", operationLogHandler::getOperationLogsByPage)
.GET("/api/logs/operation/count", operationLogHandler::getOperationLogCount)
// 端点存在
.build();
}
可能原因:
- 数据库中确实没有操作日志记录
- 操作日志拦截器可能没有正确记录日志
- 统计查询可能有问题
修复方案
方案1:添加今日登录统计功能(推荐)
1.1 更新服务接口
文件:ISysLoginLogService.java
public interface ISysLoginLogService {
Mono<SysLoginLog> findById(Long id);
Flux<SysLoginLog> findAll();
Flux<SysLoginLog> findByUsername(String username);
Flux<SysLoginLog> findByLoginTimeBetween(LocalDateTime startTime, LocalDateTime endTime);
Mono<SysLoginLog> save(SysLoginLog loginLog);
Mono<PageResponse<SysLoginLog>> findLoginLogsByPage(PageRequest pageRequest);
Mono<Long> count();
Mono<Long> countToday(); // 新增方法
}
1.2 实现今日登录统计
文件:SysLoginLogService.java
@Override
public Mono<Long> countToday() {
LocalDateTime todayStart = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime todayEnd = todayStart.plusDays(1);
return repository.findByLoginTimeBetween(todayStart, todayEnd)
.count();
}
1.3 添加Repository方法
文件:ISysLoginLogRepository.java
Flux<SysLoginLog> findByLoginTimeBetween(LocalDateTime startTime, LocalDateTime endTime);
1.4 更新Handler
文件:SysLogHandler.java
@Operation(summary = "获取今日登录次数", description = "获取今日登录次数统计")
public Mono<ServerResponse> getTodayLoginCount(ServerRequest request) {
return loginLogService.countToday()
.flatMap(count -> ServerResponse.ok().bodyValue(count));
}
1.5 更新路由配置
文件:SystemRouter.java
@Bean
public RouterFunction<ServerResponse> logRoutes(SysLogHandler logHandler) {
return route()
.GET("/api/logs/login", logHandler::getAllLoginLogs)
.GET("/api/logs/login/page", logHandler::getLoginLogsByPage)
.GET("/api/logs/login/count", logHandler::getLoginLogCount)
.GET("/api/logs/login/today/count", logHandler::getTodayLoginCount) // 新增路由
.build();
}
方案2:使用统一统计API(备选)
2.1 更新前端Dashboard
文件:Dashboard.vue
const fetchStats = async () => {
loading.value = true
try {
// 使用统一的统计API
const statsRes: any = await request.get('/stats/overview')
stats.userCount = statsRes.userCount || 0
stats.roleCount = statsRes.roleCount || 0
stats.todayLogin = statsRes.todayOperationCount || 0 // 注意字段映射
stats.operationLog = statsRes.operationLogCount || 0
} catch (error) {
console.error('Failed to fetch stats:', error)
} finally {
loading.value = false
}
}
2.2 更新StatsHandler
文件:StatsHandler.java
@Operation(summary = "获取系统概览", description = "获取系统统计概览信息")
public Mono<ServerResponse> getOverview(ServerRequest request) {
return Mono.zip(
userService.count(),
roleService.count(),
operationLogService.count(),
loginLogService.countToday(), // 添加今日登录统计
operationLogService.countToday()
).flatMap(tuple -> {
OverviewStats stats = new OverviewStats();
stats.setUserCount(tuple.getT1());
stats.setRoleCount(tuple.getT2());
stats.setOperationLogCount(tuple.getT3());
stats.setTodayLoginCount(tuple.getT4()); // 新增字段
stats.setTodayOperationCount(tuple.getT5());
return ServerResponse.ok().bodyValue(stats);
});
}
public static class OverviewStats {
private Long userCount;
private Long roleCount;
private Long operationLogCount;
private Long todayLoginCount; // 新增字段
private Long todayOperationCount;
// getters and setters...
}
方案3:检查操作日志记录
3.1 检查操作日志拦截器
文件:OperationLogFilter.java
确认拦截器是否正确配置和记录操作日志:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class OperationLogFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getPath().value();
// 排除不需要记录的路径
if (shouldSkipLogging(path)) {
return chain.filter(exchange);
}
// 记录操作日志
return chain.filter(exchange).doFinally(signalType -> {
OperationLog log = new OperationLog();
log.setUsername(getUsername(exchange));
log.setOperation(path);
log.setMethod(request.getMethod().name());
log.setIp(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
log.setStatus(exchange.getResponse().getStatusCode().value());
operationLogService.save(log).subscribe();
});
}
}
3.2 验证数据库
-- 检查操作日志表是否有数据
SELECT COUNT(*) FROM operation_log;
-- 检查今日操作日志
SELECT COUNT(*) FROM operation_log
WHERE created_at >= CURRENT_DATE;
-- 检查最近10条操作日志
SELECT * FROM operation_log
ORDER BY created_at DESC
LIMIT 10;
推荐实施步骤
- 立即修复:实施方案1,添加今日登录统计功能
- 验证操作日志:检查操作日志拦截器和数据库记录
- 长期优化:考虑实施方案2,使用统一统计API简化前端逻辑
测试验证
修复后需要验证:
- Dashboard页面正确显示今日登录次数
- Dashboard页面正确显示操作日志数量
- 执行一些操作后,操作日志数量增加
- 登录后,今日登录次数增加
相关文件清单
需要修改的文件:
novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/ISysLoginLogService.javanovalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysLoginLogService.javanovalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/repository/ISysLoginLogRepository.javanovalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/handler/log/SysLogHandler.javanovalon-manage-api/manage-app/src/main/java/cn/novalon/manage/app/config/SystemRouter.javanovalon-manage-web/src/views/system/Dashboard.vue(可选,如果使用方案2)
需要检查的文件:
novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/interceptor/OperationLogFilter.java- 数据库表
operation_log的数据记录情况