Files
AIGC/src/main/java/com/example/demo/service/OnlineStatsService.java
blandarebiter 90b5118e45 perf(backend+frontend): 列表API响应体积优化 3.1MB→145KB (↓95.4%)
- 后端: JPQL构造器投影排除LONGTEXT大字段(uploadedImages/videoReferenceImages)
- 后端: DTO层过滤非分镜图类型的base64内联resultUrl
- 前端: 列表缩略图从video改为img loading=lazy,消除172并发请求
- 前端: download函数增加resultUrl懒加载(详情接口兜底)
- 文档: 新增性能优化报告 docs/performance-optimization-report.md
2026-04-10 18:46:37 +08:00

113 lines
3.2 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.example.demo.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* 在线统计服务
* 通过IP地址统计当天访问的独立用户数
*/
@Service
public class OnlineStatsService {
private static final Logger logger = LoggerFactory.getLogger(OnlineStatsService.class);
// 存储当天访问过的IP地址使用Set去重
private final Set<String> todayVisitors = ConcurrentHashMap.newKeySet();
// 记录当前日期,用于判断是否需要重置
private volatile LocalDate currentDate = LocalDate.now();
// 系统启动时间
private final LocalDateTime startTime = LocalDateTime.now();
/**
* 记录访问IP
* @param ip 访问者IP地址
*/
public void recordVisit(String ip) {
if (ip == null || ip.isEmpty()) {
return;
}
// 检查是否需要重置(新的一天)
checkAndResetIfNewDay();
// 添加IP到今日访客列表
todayVisitors.add(ip);
}
/**
* 获取当天在线人数独立IP数
* @return 当天访问的独立IP数量
*/
public int getTodayVisitorCount() {
checkAndResetIfNewDay();
return todayVisitors.size();
}
/**
* 检查是否是新的一天,如果是则重置统计
*/
private void checkAndResetIfNewDay() {
LocalDate today = LocalDate.now();
if (!today.equals(currentDate)) {
synchronized (this) {
if (!today.equals(currentDate)) {
logger.info("新的一天开始,重置在线统计。昨日访客数: {}", todayVisitors.size());
todayVisitors.clear();
currentDate = today;
}
}
}
}
/**
* 每天凌晨0点重置统计
*/
@Scheduled(cron = "0 0 0 * * ?")
public void resetDailyStats() {
logger.info("定时任务:重置每日在线统计。昨日访客数: {}", todayVisitors.size());
todayVisitors.clear();
currentDate = LocalDate.now();
}
/**
* 获取系统运行时间(格式化为 X小时X分
* @return 运行时间字符串
*/
public String getUptime() {
Duration duration = Duration.between(startTime, LocalDateTime.now());
long hours = duration.toHours();
long minutes = duration.toMinutes() % 60;
if (hours > 0) {
return hours + "小时" + minutes + "";
} else {
return minutes + "分钟";
}
}
/**
* 获取统计信息
* @return 包含统计数据的Map
*/
public Map<String, Object> getStats() {
checkAndResetIfNewDay();
Map<String, Object> stats = new ConcurrentHashMap<>();
stats.put("todayVisitors", todayVisitors.size());
stats.put("date", currentDate.toString());
stats.put("uptime", getUptime());
return stats;
}
}