package com.vincent.rsf.server.system.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.vincent.rsf.framework.common.R; import com.vincent.rsf.server.common.domain.BaseParam; import com.vincent.rsf.server.common.domain.PageParam; import com.vincent.rsf.server.common.utils.ExcelUtil; import com.vincent.rsf.server.system.entity.AiCallLog; import com.vincent.rsf.server.system.service.AiCallLogService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @RestController public class AiCallLogController extends BaseController { @Autowired private AiCallLogService aiCallLogService; @PreAuthorize("hasAuthority('system:aiCallLog:list')") @PostMapping("/aiCallLog/page") public R page(@RequestBody Map map) { BaseParam baseParam = buildParam(map, BaseParam.class); PageParam pageParam = new PageParam<>(baseParam, AiCallLog.class); com.baomidou.mybatisplus.core.conditions.query.QueryWrapper wrapper = pageParam.buildWrapper(true); wrapper.eq("tenant_id", getTenantId()); return R.ok().add(aiCallLogService.page(pageParam, wrapper)); } @PreAuthorize("hasAuthority('system:aiCallLog:list')") @GetMapping("/aiCallLog/{id}") public R get(@PathVariable("id") Long id) { AiCallLog callLog = getTenantRecord(id); if (callLog == null) { return R.error("record not found"); } return R.ok().add(callLog); } @PreAuthorize("hasAuthority('system:aiCallLog:list')") @PostMapping("/aiCallLog/export") public void export(@RequestBody Map map, HttpServletResponse response) throws Exception { ExcelUtil.build(ExcelUtil.create(aiCallLogService.list(new LambdaQueryWrapper() .eq(AiCallLog::getTenantId, getTenantId())), AiCallLog.class), response); } @PreAuthorize("hasAuthority('system:aiCallLog:list')") @GetMapping("/ai/call-log/list") public R customList() { return R.ok().add(aiCallLogService.list(new LambdaQueryWrapper() .eq(AiCallLog::getTenantId, getTenantId()) .orderByDesc(AiCallLog::getCreateTime, AiCallLog::getId))); } @PreAuthorize("hasAuthority('system:aiCallLog:list')") @GetMapping("/ai/call-log/stats") public R stats() { List logs = aiCallLogService.list(new LambdaQueryWrapper() .eq(AiCallLog::getTenantId, getTenantId()) .orderByDesc(AiCallLog::getCreateTime, AiCallLog::getId)); long total = logs.size(); long successCount = logs.stream().filter(item -> Integer.valueOf(1).equals(item.getResult())).count(); long failCount = logs.stream().filter(item -> Integer.valueOf(0).equals(item.getResult())).count(); long modelCount = logs.stream().map(AiCallLog::getModelCode).filter(item -> item != null && !item.trim().isEmpty()).distinct().count(); long routeCount = logs.stream().map(AiCallLog::getRouteCode).filter(item -> item != null && !item.trim().isEmpty()).distinct().count(); long totalSpend = logs.stream().map(AiCallLog::getSpendTime).filter(item -> item != null && item > 0L).mapToLong(Long::longValue).sum(); long spendCount = logs.stream().map(AiCallLog::getSpendTime).filter(item -> item != null && item > 0L).count(); Date now = new Date(); long last24hCount = logs.stream() .map(AiCallLog::getCreateTime) .filter(item -> item != null && now.getTime() - item.getTime() <= 24L * 60L * 60L * 1000L) .count(); Map payload = new LinkedHashMap<>(); payload.put("total", total); payload.put("successCount", successCount); payload.put("failCount", failCount); payload.put("successRate", total <= 0 ? 0D : (successCount * 100D) / total); payload.put("avgSpendTime", spendCount <= 0 ? 0L : totalSpend / spendCount); payload.put("modelCount", modelCount); payload.put("routeCount", routeCount); payload.put("last24hCount", last24hCount); return R.ok().add(payload); } private AiCallLog getTenantRecord(Long id) { if (id == null) { return null; } return aiCallLogService.getOne(new LambdaQueryWrapper() .eq(AiCallLog::getTenantId, getTenantId()) .eq(AiCallLog::getId, id) .last("limit 1")); } }