|
|
@@ -10,6 +10,7 @@ import com.fs.aiSipCall.mapper.AiSipCallPhoneMapper;
|
|
|
import com.fs.aiSipCall.param.ApiCallRecordQueryParams;
|
|
|
import com.fs.aiSipCall.service.IAiSipCallPhoneService;
|
|
|
import com.fs.aiSipCall.utils.DateUtils;
|
|
|
+import com.fs.common.core.page.TableDataInfo;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.scheduling.annotation.Async;
|
|
|
@@ -41,6 +42,19 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
return baseMapper.selectAiSipCallPhoneById(id);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public TableDataInfo remoteList(ApiCallRecordQueryParams aiSipCallPhone) {
|
|
|
+ String result = RemoteCommon.sendPost(RemoteCommon.REMOTE_ADDERSS_PREFIX + RemoteCommon.CALL_RECORDS_API,JSONObject.toJSONString(aiSipCallPhone));
|
|
|
+ if(StringUtils.isNotBlank(result)){
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(result);
|
|
|
+ if(jsonObject.getInteger("code") == 0){
|
|
|
+ return JSONObject.parseObject(result, TableDataInfo.class);
|
|
|
+ }else{
|
|
|
+ log.error("获取自动外呼记录接口失败:{}", jsonObject.getString("msg"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
/**
|
|
|
* 查询aiSIP外呼通话记录列表
|
|
|
*
|
|
|
@@ -148,12 +162,12 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
@Async
|
|
|
public CompletableFuture<String> scheduledGetCallRecord() {
|
|
|
if (!isRunning.compareAndSet(false, true)) {
|
|
|
- log.warn("scheduledGetCallRecord 任务正在执行中,请稍后再试");
|
|
|
+ log.error("sip自动外呼同步电话 任务正在执行中,请稍后再试");
|
|
|
return CompletableFuture.completedFuture("任务正在执行中,请稍后再试");
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- log.info("开始执行 scheduledGetCallRecord 异步任务");
|
|
|
+ log.error("sip自动外呼同步电话 开始执行 scheduledGetCallRecord 异步任务");
|
|
|
String todayStartStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date()) + " 00:00:00";
|
|
|
String now = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date());
|
|
|
long startTime = System.currentTimeMillis();
|
|
|
@@ -164,7 +178,7 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
// 获取远程数据
|
|
|
List<AiSipCallPhone> remoteList = fetchAllRemoteCallRecords(paramsList);
|
|
|
if (remoteList.isEmpty()) {
|
|
|
- log.info("scheduledGetCallRecord 异步任务完成,耗时:{}ms, 结果:当天无最新数据", System.currentTimeMillis() - startTime);
|
|
|
+ log.error("sip自动外呼同步电话 异步任务完成,耗时:{}ms, 结果:当天无最新数据", System.currentTimeMillis() - startTime);
|
|
|
return CompletableFuture.completedFuture("当天无最新数据");
|
|
|
}
|
|
|
|
|
|
@@ -173,28 +187,29 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
|
|
|
// 筛选并处理新增和更新数据
|
|
|
String result = processAndSaveData(remoteList, localList);
|
|
|
- log.info("scheduledGetCallRecord 异步任务完成,耗时:{}ms, 结果:{}", System.currentTimeMillis() - startTime, result);
|
|
|
+ log.error("sip自动外呼同步电话 异步任务完成,耗时:{}ms, 结果:{}", System.currentTimeMillis() - startTime, result);
|
|
|
return CompletableFuture.completedFuture(result);
|
|
|
} catch (Exception e) {
|
|
|
- log.error("scheduledGetCallRecord 异步任务执行失败", e);
|
|
|
+ log.error("sip自动外呼同步电话异步任务执行失败", e);
|
|
|
return CompletableFuture.completedFuture("任务执行失败:" + e.getMessage());
|
|
|
} finally {
|
|
|
isRunning.set(false);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 构建当天查询参数 - 使用当天 00:00:00 到当前时间
|
|
|
* @return 查询参数对象列表(支持多时段查询)
|
|
|
*/
|
|
|
private List<ApiCallRecordQueryParams> buildDayQueryParams(String todayStartStr,String now) {
|
|
|
-
|
|
|
+
|
|
|
List<ApiCallRecordQueryParams> paramsList = new ArrayList<>();
|
|
|
-
|
|
|
+
|
|
|
// 如果时间跨度超过 12 小时,分段查询避免遗漏
|
|
|
Date today = DateUtils.parseDate(todayStartStr);
|
|
|
long hoursDiff = (System.currentTimeMillis() - today.getTime()) / (1000 * 60 * 60);
|
|
|
-
|
|
|
+
|
|
|
if (hoursDiff > 12) {
|
|
|
// 分两段查询:00:00-12:00 和 12:00-当前时间
|
|
|
ApiCallRecordQueryParams params1 = createSingleParam(todayStartStr, todayStartStr.substring(0, 10) + " 12:00:00");
|
|
|
@@ -205,10 +220,10 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
// 单段查询:00:00-当前时间
|
|
|
paramsList.add(createSingleParam(todayStartStr, now));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return paramsList;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 创建单个查询参数对象
|
|
|
*/
|
|
|
@@ -221,7 +236,7 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
params.setCalloutTimeEnd(endTime);
|
|
|
return params;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 分页轮询获取所有远程通话记录 (带去重和失败重试)
|
|
|
* @param paramsList 查询参数列表
|
|
|
@@ -232,44 +247,43 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
for (ApiCallRecordQueryParams params : paramsList) {
|
|
|
int currentPage = 1;
|
|
|
boolean hasMore = true;
|
|
|
-
|
|
|
+
|
|
|
while (hasMore) {
|
|
|
params.setPageNum(currentPage);
|
|
|
List<AiSipCallPhone> pageData = fetchSinglePageRecords(params);
|
|
|
-
|
|
|
- // 失败时跳过该页,继续下一页
|
|
|
+
|
|
|
+ // 失败时直接结束
|
|
|
if (pageData == null) {
|
|
|
- log.warn("分页查询第{}页失败,已丢弃该页数据", currentPage);
|
|
|
- currentPage++;
|
|
|
- continue;
|
|
|
+ log.error("sip自动外呼同步电话 分页查询第{}页失败,已丢弃该页数据,停止查询", currentPage);
|
|
|
+ break;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (pageData.isEmpty()) {
|
|
|
- log.info("第{}页无数据,查询结束", currentPage);
|
|
|
+ log.error("sip自动外呼同步电话 第{}页无数据,查询结束", currentPage);
|
|
|
hasMore = false;
|
|
|
} else {
|
|
|
allRecords.addAll(pageData);
|
|
|
- log.debug("第{}页数据:{},累计总数:{}", currentPage, pageData.size(), allRecords.size());
|
|
|
-
|
|
|
+ log.error("sip自动外呼同步电话 第{}页数据:{},累计总数:{}", currentPage, pageData.size(), allRecords.size());
|
|
|
+
|
|
|
// 如果返回数据少于页大小,说明已是最后一页
|
|
|
if (pageData.size() < params.getPageSize()) {
|
|
|
hasMore = false;
|
|
|
}
|
|
|
currentPage++;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 安全限制:最多拉取 50 页
|
|
|
if (currentPage > 50) {
|
|
|
- log.warn("已达到最大页数限制 50 页,停止查询。已获取数据量:{}", allRecords.size());
|
|
|
+ log.error("sip自动外呼同步电话 已达到最大页数限制 50 页,停止查询。已获取数据量:{}", allRecords.size());
|
|
|
hasMore = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- log.info("远程数据获取完成,总计:{} 条", allRecords.size());
|
|
|
+
|
|
|
+ log.error("sip自动外呼同步电话 远程数据获取完成,总计:{} 条", allRecords.size());
|
|
|
return allRecords.isEmpty() ? Collections.emptyList() : allRecords;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 获取单页数据
|
|
|
* @param params 查询参数(需预先设置页码)
|
|
|
@@ -278,25 +292,25 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
private List<AiSipCallPhone> fetchSinglePageRecords(ApiCallRecordQueryParams params) {
|
|
|
try {
|
|
|
String result = RemoteCommon.sendPost(
|
|
|
- RemoteCommon.REMOTE_ADDERSS_PREFIX + RemoteCommon.CALL_RECORDS_API,
|
|
|
- JSONObject.toJSONString(params)
|
|
|
+ RemoteCommon.REMOTE_ADDERSS_PREFIX + RemoteCommon.CALL_RECORDS_API,
|
|
|
+ JSONObject.toJSONString(params)
|
|
|
);
|
|
|
-
|
|
|
+
|
|
|
if (StringUtils.isBlank(result)) {
|
|
|
- log.error("查询第{}页失败:接口返回为空", params.getPageNum());
|
|
|
+ log.error("sip自动外呼同步电话 查询第{}页失败:接口返回为空", params.getPageNum());
|
|
|
return null;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
JSONObject jsonObject = JSONObject.parseObject(result);
|
|
|
Integer code = jsonObject.getInteger("code");
|
|
|
-
|
|
|
+
|
|
|
if (code == null || code != 0) {
|
|
|
String errorMsg = jsonObject.getString("msg") != null
|
|
|
- ? jsonObject.getString("msg") : "未知错误";
|
|
|
- log.error("查询第{}页失败:{}", params.getPageNum(), errorMsg);
|
|
|
+ ? jsonObject.getString("msg") : "未知错误";
|
|
|
+ log.error("sip自动外呼同步电话 查询第{}页失败:{}", params.getPageNum(), errorMsg);
|
|
|
return null;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
Long total = jsonObject.getLong("total");
|
|
|
if (total == null || total <= 0) {
|
|
|
return Collections.emptyList();
|
|
|
@@ -309,7 +323,7 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
|
|
|
return JSONObject.parseArray(rows, AiSipCallPhone.class);
|
|
|
} catch (Exception e) {
|
|
|
- log.error("查询第{}页异常", params.getPageNum(), e);
|
|
|
+ log.error("sip自动外呼同步电话 查询第{}页异常", params.getPageNum(), e);
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
@@ -324,9 +338,9 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
if (remoteList == null || remoteList.isEmpty()) {
|
|
|
return "远程数据列表为空,无需处理";
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (localList == null || localList.isEmpty()) {
|
|
|
- log.warn("本地数据列表为空,所有远程数据都将作为新增处理");
|
|
|
+ log.warn("sip自动外呼同步电话 本地数据列表为空,所有远程数据都将作为新增处理");
|
|
|
return processDataWithStats(remoteList, "新增");
|
|
|
}
|
|
|
|
|
|
@@ -334,11 +348,11 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
Set<String> localIdSet = localList.stream()
|
|
|
.map(AiSipCallPhone::getId)
|
|
|
.collect(Collectors.toSet());
|
|
|
-
|
|
|
+
|
|
|
// 分类数据:新增和更新
|
|
|
List<AiSipCallPhone> insertList = new ArrayList<>();
|
|
|
List<AiSipCallPhone> updateList = new ArrayList<>();
|
|
|
-
|
|
|
+
|
|
|
for (AiSipCallPhone remote : remoteList) {
|
|
|
if (StringUtils.isBlank(remote.getId())) {
|
|
|
continue;
|
|
|
@@ -350,20 +364,20 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- log.info("数据筛选完成 - 预计新增:{},预计更新:{}", insertList.size(), updateList.size());
|
|
|
-
|
|
|
+ log.error("sip自动外呼同步电话 数据筛选完成 - 预计新增:{},预计更新:{}", insertList.size(), updateList.size());
|
|
|
+
|
|
|
StringBuilder resultMsg = new StringBuilder();
|
|
|
if (!insertList.isEmpty()) {
|
|
|
resultMsg.append(processDataWithStats(insertList, "新增"));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (!updateList.isEmpty()) {
|
|
|
if (resultMsg.length() > 0) {
|
|
|
resultMsg.append(",");
|
|
|
}
|
|
|
resultMsg.append(processDataWithStats(updateList, "更新"));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return resultMsg.toString();
|
|
|
}
|
|
|
|
|
|
@@ -374,23 +388,23 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
* @return 处理结果信息
|
|
|
*/
|
|
|
private String processDataWithStats(List<AiSipCallPhone> dataList,String operationType) {
|
|
|
- log.info("开始处理{}Ai 外呼记录数据,数量:{}", operationType, dataList.size());
|
|
|
+ log.error("sip自动外呼同步电话 开始处理{}Ai 外呼记录数据,数量:{}", operationType, dataList.size());
|
|
|
if (dataList.isEmpty()) {
|
|
|
return "无有效数据,无需处理";
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
int batchSize = 500;
|
|
|
int totalSize = dataList.size();
|
|
|
int batchCount = (totalSize + batchSize - 1) / batchSize;
|
|
|
int successCount = 0;
|
|
|
int failCount = 0;
|
|
|
List<int[]> failedBatchRanges = new ArrayList<>();
|
|
|
-
|
|
|
+
|
|
|
for (int i = 0; i < batchCount; i++) {
|
|
|
int fromIndex = i * batchSize;
|
|
|
int toIndex = Math.min(fromIndex + batchSize, totalSize);
|
|
|
List<AiSipCallPhone> batchList = dataList.subList(fromIndex, toIndex);
|
|
|
-
|
|
|
+
|
|
|
try {
|
|
|
if ("新增".equals(operationType)) {
|
|
|
this.saveBatch(batchList);
|
|
|
@@ -398,20 +412,20 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
this.updateBatchById(batchList);
|
|
|
}
|
|
|
successCount += batchList.size();
|
|
|
- log.debug("第{}/{}批{}成功,本批数量:{}", i + 1, batchCount, operationType, batchList.size());
|
|
|
+ log.error("sip自动外呼同步电话 第{}/{}批{}成功,本批数量:{}", i + 1, batchCount, operationType, batchList.size());
|
|
|
} catch (Exception e) {
|
|
|
failCount += batchList.size();
|
|
|
int[] range = {fromIndex, toIndex - 1};
|
|
|
failedBatchRanges.add(range);
|
|
|
- log.error("第{}批数据{}失败,本批数量:{},起始位:{},结束位:{}",
|
|
|
- i + 1, operationType, batchList.size(), fromIndex, toIndex - 1, e);
|
|
|
+ log.error("sip自动外呼同步电话 第{}批数据{}失败,本批数量:{},起始位:{},结束位:{}",
|
|
|
+ i + 1, operationType, batchList.size(), fromIndex, toIndex - 1, e);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
StringBuilder result = new StringBuilder();
|
|
|
result.append(operationType).append("数据处理完成,总计:").append(totalSize).append("条");
|
|
|
result.append(",成功:").append(successCount).append("条");
|
|
|
-
|
|
|
+
|
|
|
if (failCount > 0) {
|
|
|
result.append(",失败:").append(failCount).append("条");
|
|
|
result.append(",失败数据位置:");
|
|
|
@@ -421,7 +435,7 @@ public class AiSipCallPhoneServiceImpl extends ServiceImpl<AiSipCallPhoneMapper,
|
|
|
result.append("[").append(range[0]).append("-").append(range[1]).append("]");
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return result.toString();
|
|
|
}
|
|
|
|