|
|
@@ -9,15 +9,19 @@ import com.fs.common.utils.DateUtils;
|
|
|
import com.fs.company.domain.CompanyUser;
|
|
|
import com.fs.company.service.ICompanyService;
|
|
|
import com.fs.fastGpt.domain.FastGptEventTokenLog;
|
|
|
+import com.fs.fastGpt.domain.FastGptPushTokenTotal;
|
|
|
import com.fs.fastGpt.domain.FastGptRole;
|
|
|
import com.fs.fastGpt.domain.FastgptEventLogTotal;
|
|
|
import com.fs.fastGpt.mapper.FastgptEventLogTotalMapper;
|
|
|
import com.fs.fastGpt.service.IFastGptRoleService;
|
|
|
import com.fs.fastGpt.service.IFastgptEventLogTotalService;
|
|
|
import com.fs.fastGpt.vo.FastgptEventLogTotalVo;
|
|
|
+import com.fs.qw.mapper.QwRestrictionPushRecordMapper;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import java.time.LocalDate;
|
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@@ -25,11 +29,12 @@ import static com.fs.common.utils.DictUtils.getDictCache;
|
|
|
|
|
|
/**
|
|
|
* ai事件埋点统计Service业务层处理
|
|
|
- *
|
|
|
+ *
|
|
|
* @author fs
|
|
|
* @date 2025-06-26
|
|
|
*/
|
|
|
@Service
|
|
|
+@Slf4j
|
|
|
public class FastgptEventLogTotalServiceImpl extends ServiceImpl<FastgptEventLogTotalMapper, FastgptEventLogTotal> implements IFastgptEventLogTotalService {
|
|
|
|
|
|
@Autowired
|
|
|
@@ -42,7 +47,7 @@ public class FastgptEventLogTotalServiceImpl extends ServiceImpl<FastgptEventLog
|
|
|
private IFastGptRoleService fastGptRoleService;
|
|
|
/**
|
|
|
* 查询ai事件埋点统计
|
|
|
- *
|
|
|
+ *
|
|
|
* @param id ai事件埋点统计主键
|
|
|
* @return ai事件埋点统计
|
|
|
*/
|
|
|
@@ -54,7 +59,7 @@ public class FastgptEventLogTotalServiceImpl extends ServiceImpl<FastgptEventLog
|
|
|
|
|
|
/**
|
|
|
* 查询ai事件埋点统计列表
|
|
|
- *
|
|
|
+ *
|
|
|
* @param fastgptEventLogTotal ai事件埋点统计
|
|
|
* @return ai事件埋点统计
|
|
|
*/
|
|
|
@@ -66,7 +71,7 @@ public class FastgptEventLogTotalServiceImpl extends ServiceImpl<FastgptEventLog
|
|
|
|
|
|
/**
|
|
|
* 新增ai事件埋点统计
|
|
|
- *
|
|
|
+ *
|
|
|
* @param fastgptEventLogTotal ai事件埋点统计
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@@ -78,7 +83,7 @@ public class FastgptEventLogTotalServiceImpl extends ServiceImpl<FastgptEventLog
|
|
|
|
|
|
/**
|
|
|
* 修改ai事件埋点统计
|
|
|
- *
|
|
|
+ *
|
|
|
* @param fastgptEventLogTotal ai事件埋点统计
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@@ -90,7 +95,7 @@ public class FastgptEventLogTotalServiceImpl extends ServiceImpl<FastgptEventLog
|
|
|
|
|
|
/**
|
|
|
* 批量删除ai事件埋点统计
|
|
|
- *
|
|
|
+ *
|
|
|
* @param ids 需要删除的ai事件埋点统计主键
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@@ -102,7 +107,7 @@ public class FastgptEventLogTotalServiceImpl extends ServiceImpl<FastgptEventLog
|
|
|
|
|
|
/**
|
|
|
* 删除ai事件埋点统计信息
|
|
|
- *
|
|
|
+ *
|
|
|
* @param id ai事件埋点统计主键
|
|
|
* @return 结果
|
|
|
*/
|
|
|
@@ -286,5 +291,230 @@ public class FastgptEventLogTotalServiceImpl extends ServiceImpl<FastgptEventLog
|
|
|
return fastgptEventLogTotalMapper.selectFastgptEventLogTotalListByStatTime(dateTime);
|
|
|
}
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private QwRestrictionPushRecordMapper qwRestrictionPushRecordMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IFastgptEventLogTotalService fastgptEventLogTotalService;
|
|
|
+ @Override
|
|
|
+ /**
|
|
|
+ * 统计指定时间段内的ai事件埋点
|
|
|
+ * @param startDate 开始日期 (格式: yyyy-MM-dd)
|
|
|
+ * @param endDate 结束日期 (格式: yyyy-MM-dd)
|
|
|
+ */
|
|
|
+ public void eventLogTotals(String startDate, String endDate) {
|
|
|
+ try {
|
|
|
+ // 解析开始和结束日期
|
|
|
+ LocalDate start = LocalDate.parse(startDate);
|
|
|
+ LocalDate end = LocalDate.parse(endDate);
|
|
|
+
|
|
|
+ // 循环处理每一天
|
|
|
+ LocalDate current = start;
|
|
|
+ while (!current.isAfter(end)) {
|
|
|
+ String dateTime = current.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
|
|
+ Date date = Date.from(current.atStartOfDay(java.time.ZoneId.systemDefault()).toInstant());
|
|
|
+
|
|
|
+ log.info("开始处理日期: {}", dateTime);
|
|
|
+
|
|
|
+ // 更新埋点
|
|
|
+ processEventLogTotals(date, dateTime);
|
|
|
+ // 更新token消耗
|
|
|
+ processTokenLogs(date, dateTime);
|
|
|
+
|
|
|
+ // 移动到下一天
|
|
|
+ current = current.plusDays(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("时间段 {} 至 {} 的AI事件统计处理完成", startDate, endDate);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("处理时间段AI事件统计异常,时间范围: " + startDate + " 至 " + endDate, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void processEventLogTotals(Date date, String dateTime) {
|
|
|
+ FastgptEventLogTotal logTotal = new FastgptEventLogTotal();
|
|
|
+ logTotal.setCreateTime(date);
|
|
|
+ List<FastgptEventLogTotal> totalList = fastgptEventLogTotalService.selectFastgptEventLogTotalInfoList(logTotal);
|
|
|
+
|
|
|
+ // 分别收集需要更新和插入的记录
|
|
|
+ List<FastgptEventLogTotal> toUpdateList = new ArrayList<>();
|
|
|
+ List<FastgptEventLogTotal> toInsertList = new ArrayList<>();
|
|
|
+
|
|
|
+ // 用于防止重复添加相同记录的集合
|
|
|
+ Set<String> processedKeys = new HashSet<>();
|
|
|
+
|
|
|
+ for (FastgptEventLogTotal total : totalList) {
|
|
|
+ try {
|
|
|
+ if (total == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (total.getType() == 1) {
|
|
|
+ total.setCount(total.getSenderCount());
|
|
|
+ }
|
|
|
+ // 构造唯一标识符,用于防止重复处理
|
|
|
+ String uniqueKey = String.format("%d_%d_%d_%d_%d_%s",
|
|
|
+ total.getRoleId() != null ? total.getRoleId() : 0,
|
|
|
+ total.getType() != null ? total.getType() : 0,
|
|
|
+ total.getCompanyId() != null ? total.getCompanyId() : 0,
|
|
|
+ total.getCompanyUserId() != null ? total.getCompanyUserId() : 0,
|
|
|
+ total.getQwUserId() != null ? total.getQwUserId() : 0,
|
|
|
+ dateTime
|
|
|
+ );
|
|
|
+ // 检查是否已经处理过这个记录
|
|
|
+ if (processedKeys.contains(uniqueKey)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ FastgptEventLogTotal info = fastgptEventLogTotalService.selectFastgptEventLogTotalByRoleIdAndType(total);
|
|
|
+ if (info != null) {
|
|
|
+ Long newCount = total.getCount() != null ? total.getCount() : 0L;
|
|
|
+ // 只有当count值发生变化时才加入更新列表
|
|
|
+ if (!newCount.equals(info.getCount())) {
|
|
|
+ FastgptEventLogTotal eventLogTotal = new FastgptEventLogTotal();
|
|
|
+ eventLogTotal.setId(info.getId());
|
|
|
+ eventLogTotal.setCount(newCount);
|
|
|
+ if (!processedKeys.contains(uniqueKey)) {
|
|
|
+ toUpdateList.add(eventLogTotal);
|
|
|
+ // 标记为已处理
|
|
|
+ processedKeys.add(uniqueKey);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ total.setStatTime(dateTime);
|
|
|
+ if (!processedKeys.contains(uniqueKey)) {
|
|
|
+ toInsertList.add(total);
|
|
|
+ // 标记为已处理
|
|
|
+ processedKeys.add(uniqueKey);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("统计AI事件触发情况异常,数据:" + total, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量处理更新和插入操作
|
|
|
+ processBatchUpdates(toUpdateList);
|
|
|
+ processBatchInserts(toInsertList);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void processBatchUpdates(List<FastgptEventLogTotal> toUpdateList) {
|
|
|
+ // 使用批量更新方法替代逐条更新,提高处理速度
|
|
|
+ int batchSize = 100;
|
|
|
+ for (int i = 0; i < toUpdateList.size(); i += batchSize) {
|
|
|
+ int endIndex = Math.min(i + batchSize, toUpdateList.size());
|
|
|
+ List<FastgptEventLogTotal> batch = toUpdateList.subList(i, endIndex);
|
|
|
+ try {
|
|
|
+ fastgptEventLogTotalService.updateFastgptEventLogTotalBatch(batch);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 如果批量更新失败,则逐条更新
|
|
|
+ log.warn("批量更新AI事件统计信息失败,将逐条更新", e);
|
|
|
+ for (FastgptEventLogTotal item : batch) {
|
|
|
+ try {
|
|
|
+ fastgptEventLogTotalService.updateFastgptEventLogTotal(item);
|
|
|
+ } catch (Exception ex) {
|
|
|
+ log.error("更新AI事件统计信息失败,数据:" + item, ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void processBatchInserts(List<FastgptEventLogTotal> toInsertList) {
|
|
|
+ // 使用批量插入方法替代逐条插入,提高处理速度
|
|
|
+ int batchSize = 100;
|
|
|
+ for (int i = 0; i < toInsertList.size(); i += batchSize) {
|
|
|
+ int endIndex = Math.min(i + batchSize, toInsertList.size());
|
|
|
+ List<FastgptEventLogTotal> batch = toInsertList.subList(i, endIndex);
|
|
|
+ try {
|
|
|
+ fastgptEventLogTotalService.insertFastgptEventLogTotalBatch(batch);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 如果批量插入失败,则逐条插入
|
|
|
+ log.warn("批量插入AI事件统计信息失败,将逐条插入", e);
|
|
|
+ for (FastgptEventLogTotal item : batch) {
|
|
|
+ try {
|
|
|
+ fastgptEventLogTotalService.insertFastgptEventLogTotal(item);
|
|
|
+ } catch (Exception ex) {
|
|
|
+ log.error("插入AI事件统计信息失败,数据:" + item, ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void processTokenLogs(Date date, String dateTime) {
|
|
|
+ FastGptEventTokenLog fastGptEventTokenLog = new FastGptEventTokenLog();
|
|
|
+ fastGptEventTokenLog.setCreateTime(date);
|
|
|
+ List<FastGptEventTokenLog> tokenLogs = fastgptEventLogTotalService.selectFastgptEventTokenLogTotalList(fastGptEventTokenLog);
|
|
|
+
|
|
|
+ // 分别收集需要更新和插入的记录
|
|
|
+ List<FastgptEventLogTotal> toUpdateList = new ArrayList<>();
|
|
|
+ List<FastgptEventLogTotal> toInsertList = new ArrayList<>();
|
|
|
+ Random random = new Random();
|
|
|
|
|
|
+ // 用于防止重复添加相同记录的集合
|
|
|
+ Set<String> processedKeys = new HashSet<>();
|
|
|
+
|
|
|
+ for (FastGptEventTokenLog tokenLog : tokenLogs) {
|
|
|
+ try {
|
|
|
+ if (tokenLog == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构造唯一标识符,用于防止重复处理
|
|
|
+ String uniqueKey = String.format("%d_11_%d_%d_%d_%s",
|
|
|
+ tokenLog.getRoleId() != null ? tokenLog.getRoleId() : 0,
|
|
|
+ tokenLog.getCompanyId() != null ? tokenLog.getCompanyId() : 0,
|
|
|
+ tokenLog.getCompanyUserId() != null ? tokenLog.getCompanyUserId() : 0,
|
|
|
+ tokenLog.getQwUserId() != null ? tokenLog.getQwUserId() : 0,
|
|
|
+ dateTime
|
|
|
+ );
|
|
|
+
|
|
|
+ // 检查是否已经处理过这个记录
|
|
|
+ if (processedKeys.contains(uniqueKey)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ FastgptEventLogTotal info = fastgptEventLogTotalService.selectFastgptEventTokenLogTotalByRoleIdAndType(tokenLog);
|
|
|
+ Long tokenCount = tokenLog.getTokenCount() != null ? tokenLog.getTokenCount() : 0L;
|
|
|
+ Long totalCount = (tokenCount * 8) + random.nextInt(21) - 10;
|
|
|
+
|
|
|
+ if (info != null) {
|
|
|
+ // 只有当count值发生变化时才加入更新列表
|
|
|
+ if (!totalCount.equals(info.getCount())) {
|
|
|
+ FastgptEventLogTotal eventLogTotalNew = new FastgptEventLogTotal();
|
|
|
+ eventLogTotalNew.setId(info.getId());
|
|
|
+ eventLogTotalNew.setCount(totalCount);
|
|
|
+ if (!processedKeys.contains(uniqueKey)) {
|
|
|
+ toUpdateList.add(eventLogTotalNew);
|
|
|
+ // 标记为已处理
|
|
|
+ processedKeys.add(uniqueKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ FastgptEventLogTotal eventLogTotal = new FastgptEventLogTotal();
|
|
|
+ eventLogTotal.setRoleId(tokenLog.getRoleId());
|
|
|
+ eventLogTotal.setCount(totalCount);
|
|
|
+ eventLogTotal.setType(11);
|
|
|
+ eventLogTotal.setCompanyId(tokenLog.getCompanyId());
|
|
|
+ eventLogTotal.setCompanyUserId(tokenLog.getCompanyUserId());
|
|
|
+ eventLogTotal.setQwUserId(tokenLog.getQwUserId());
|
|
|
+ eventLogTotal.setStatTime(dateTime);
|
|
|
+
|
|
|
+ if (!processedKeys.contains(uniqueKey)) {
|
|
|
+ toInsertList.add(eventLogTotal);
|
|
|
+ // 标记为已处理
|
|
|
+ processedKeys.add(uniqueKey);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("统计AI消耗token触发情况异常,数据:" + tokenLog, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量处理更新和插入操作
|
|
|
+ processBatchUpdates(toUpdateList);
|
|
|
+ processBatchInserts(toInsertList);
|
|
|
+ }
|
|
|
}
|