This commit is contained in:
Leo
2026-01-03 12:20:09 +08:00
parent 4ba1f6a572
commit e9747e6af2
4 changed files with 292 additions and 2 deletions

View File

@@ -0,0 +1,21 @@
package com.ruoyi.jarvis.domain.dto;
import lombok.Data;
import java.util.Date;
/**
* 评论接口调用历史记录
*/
@Data
public class CommentCallHistory {
/** 产品类型 */
private String productType;
/** IP地址 */
private String ip;
/** 创建时间 */
private Date createTime;
}

View File

@@ -3,6 +3,7 @@ package com.ruoyi.jarvis.service;
import com.ruoyi.jarvis.domain.Comment;
import com.ruoyi.jarvis.domain.dto.CommentStatistics;
import com.ruoyi.jarvis.domain.dto.CommentApiStatistics;
import com.ruoyi.jarvis.domain.dto.CommentCallHistory;
import java.util.List;
import java.util.Map;
@@ -47,6 +48,21 @@ public interface ICommentService {
*/
void recordApiCall(String apiType, String productType, boolean success);
/**
* 记录接口调用历史带IP
*/
void recordApiCallHistory(String productType, String ip);
/**
* 获取接口调用历史记录
*/
List<CommentCallHistory> getApiCallHistory(int pageNum, int pageSize);
/**
* 获取使用统计(今天/7天/30天/累计)
*/
Map<String, Long> getUsageStatistics();
/**
* 获取接口调用统计
*/

View File

@@ -3,8 +3,10 @@ package com.ruoyi.jarvis.service.impl;
import com.ruoyi.jarvis.domain.Comment;
import com.ruoyi.jarvis.domain.dto.CommentApiStatistics;
import com.ruoyi.jarvis.domain.dto.CommentStatistics;
import com.ruoyi.jarvis.domain.dto.CommentCallHistory;
import com.ruoyi.jarvis.mapper.CommentMapper;
import com.ruoyi.jarvis.service.ICommentService;
import com.alibaba.fastjson2.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -27,6 +29,8 @@ public class CommentServiceImpl implements ICommentService {
private static final String PRODUCT_TYPE_MAP_PREFIX_TB = "product_type_map_tb";
private static final String API_CALL_STAT_PREFIX = "comment:api:stat:";
private static final String API_CALL_TODAY_PREFIX = "comment:api:today:";
private static final String API_CALL_HISTORY_KEY = "comment:api:history:list";
private static final int MAX_HISTORY_SIZE = 1000; // 最多保留1000条历史记录
@Autowired
private CommentMapper commentMapper;
@@ -278,5 +282,153 @@ public class CommentServiceImpl implements ICommentService {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(new Date());
}
@Override
public void recordApiCallHistory(String productType, String ip) {
if (stringRedisTemplate == null) {
return;
}
try {
CommentCallHistory history = new CommentCallHistory();
history.setProductType(productType);
history.setIp(ip);
history.setCreateTime(new Date());
String historyJson = JSON.toJSONString(history);
// 使用List存储历史记录从左侧推入
stringRedisTemplate.opsForList().leftPush(API_CALL_HISTORY_KEY, historyJson);
// 限制列表大小只保留最近MAX_HISTORY_SIZE条
stringRedisTemplate.opsForList().trim(API_CALL_HISTORY_KEY, 0, MAX_HISTORY_SIZE - 1);
} catch (Exception e) {
log.error("记录接口调用历史失败", e);
}
}
@Override
public List<CommentCallHistory> getApiCallHistory(int pageNum, int pageSize) {
List<CommentCallHistory> historyList = new ArrayList<>();
if (stringRedisTemplate == null) {
return historyList;
}
try {
long start = (pageNum - 1) * pageSize;
long end = start + pageSize - 1;
List<String> jsonList = stringRedisTemplate.opsForList().range(API_CALL_HISTORY_KEY, start, end);
if (jsonList != null) {
for (String json : jsonList) {
try {
CommentCallHistory history = JSON.parseObject(json, CommentCallHistory.class);
historyList.add(history);
} catch (Exception e) {
log.warn("解析历史记录失败: " + json, e);
}
}
}
} catch (Exception e) {
log.error("获取接口调用历史失败", e);
}
return historyList;
}
@Override
public Map<String, Long> getUsageStatistics() {
Map<String, Long> statistics = new HashMap<>();
statistics.put("today", 0L);
statistics.put("last7Days", 0L);
statistics.put("last30Days", 0L);
statistics.put("total", 0L);
if (stringRedisTemplate == null) {
return statistics;
}
try {
String today = getTodayDate();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date todayDate = sdf.parse(today);
Calendar calendar = Calendar.getInstance();
// 统计今天
long todayCount = 0;
String todayPattern = API_CALL_TODAY_PREFIX + "jd:*:" + today;
Set<String> todayKeys = stringRedisTemplate.keys(todayPattern);
if (todayKeys != null) {
for (String key : todayKeys) {
String count = stringRedisTemplate.opsForValue().get(key);
if (count != null) {
todayCount += Long.parseLong(count);
}
}
}
statistics.put("today", todayCount);
// 统计近7天
long last7DaysCount = 0;
calendar.setTime(todayDate);
for (int i = 0; i < 7; i++) {
String dateStr = sdf.format(calendar.getTime());
String pattern = API_CALL_TODAY_PREFIX + "jd:*:" + dateStr;
Set<String> keys = stringRedisTemplate.keys(pattern);
if (keys != null) {
for (String key : keys) {
String count = stringRedisTemplate.opsForValue().get(key);
if (count != null) {
last7DaysCount += Long.parseLong(count);
}
}
}
calendar.add(Calendar.DAY_OF_MONTH, -1);
}
statistics.put("last7Days", last7DaysCount);
// 统计近30天
long last30DaysCount = 0;
calendar.setTime(todayDate);
for (int i = 0; i < 30; i++) {
String dateStr = sdf.format(calendar.getTime());
String pattern = API_CALL_TODAY_PREFIX + "jd:*:" + dateStr;
Set<String> keys = stringRedisTemplate.keys(pattern);
if (keys != null) {
for (String key : keys) {
String count = stringRedisTemplate.opsForValue().get(key);
if (count != null) {
last30DaysCount += Long.parseLong(count);
}
}
}
calendar.add(Calendar.DAY_OF_MONTH, -1);
}
statistics.put("last30Days", last30DaysCount);
// 统计累计从统计key获取
long totalCount = 0;
String totalPattern = API_CALL_STAT_PREFIX + "jd:*";
Set<String> totalKeys = stringRedisTemplate.keys(totalPattern);
if (totalKeys != null) {
for (String key : totalKeys) {
// 排除success和fail后缀的key
if (!key.endsWith(":success") && !key.endsWith(":fail")) {
String count = stringRedisTemplate.opsForValue().get(key);
if (count != null) {
totalCount += Long.parseLong(count);
}
}
}
}
statistics.put("total", totalCount);
} catch (Exception e) {
log.error("获取使用统计失败", e);
}
return statistics;
}
}