|
@@ -3,7 +3,10 @@ package com.fs.his.task;
|
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
|
import com.fs.his.domain.FsImportMember;
|
|
import com.fs.his.domain.FsImportMember;
|
|
|
|
|
+import com.fs.his.domain.FsKdzlCallRecord;
|
|
|
import com.fs.his.mapper.FsImportMemberMapper;
|
|
import com.fs.his.mapper.FsImportMemberMapper;
|
|
|
|
|
+import com.fs.his.mapper.FsKdzlCallRecordMapper;
|
|
|
|
|
+import com.fs.kdzl.dto.CallRecord;
|
|
|
import com.fs.kdzl.dto.Custm;
|
|
import com.fs.kdzl.dto.Custm;
|
|
|
import com.fs.kdzl.dto.Property;
|
|
import com.fs.kdzl.dto.Property;
|
|
|
import com.fs.kdzl.service.KdzlService;
|
|
import com.fs.kdzl.service.KdzlService;
|
|
@@ -12,10 +15,7 @@ import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
|
-import java.util.Date;
|
|
|
|
|
-import java.util.List;
|
|
|
|
|
-import java.util.Map;
|
|
|
|
|
|
|
+import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
@Slf4j
|
|
@Slf4j
|
|
@@ -26,6 +26,8 @@ public class KdzlTask {
|
|
|
private KdzlService kdzlService;
|
|
private KdzlService kdzlService;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private FsImportMemberMapper importMemberMapper;
|
|
private FsImportMemberMapper importMemberMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private FsKdzlCallRecordMapper kdzlCallRecordMapper;
|
|
|
|
|
|
|
|
org.slf4j.Logger logger= LoggerFactory.getLogger(getClass());
|
|
org.slf4j.Logger logger= LoggerFactory.getLogger(getClass());
|
|
|
|
|
|
|
@@ -35,17 +37,17 @@ public class KdzlTask {
|
|
|
int loopCount = 0;
|
|
int loopCount = 0;
|
|
|
int maxLoopCount = 100;
|
|
int maxLoopCount = 100;
|
|
|
int batchSize = 500;
|
|
int batchSize = 500;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
while (loopCount < maxLoopCount) {
|
|
while (loopCount < maxLoopCount) {
|
|
|
loopCount++;
|
|
loopCount++;
|
|
|
List<Custm> custms = kdzlService.exportCustomers();
|
|
List<Custm> custms = kdzlService.exportCustomers();
|
|
|
logger.info("本次获取会员信息数量:{},当前循环次数:{}", custms.size(), loopCount);
|
|
logger.info("本次获取会员信息数量:{},当前循环次数:{}", custms.size(), loopCount);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (CollectionUtils.isEmpty(custms)) {
|
|
if (CollectionUtils.isEmpty(custms)) {
|
|
|
logger.info("未获取到会员数据,同步结束");
|
|
logger.info("未获取到会员数据,同步结束");
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
totalCount += custms.size();
|
|
totalCount += custms.size();
|
|
|
logger.info("累计已同步会员数量:{}", totalCount);
|
|
logger.info("累计已同步会员数量:{}", totalCount);
|
|
|
|
|
|
|
@@ -117,9 +119,9 @@ public class KdzlTask {
|
|
|
int endIndex = Math.min(i + batchSize, membersToSave.size());
|
|
int endIndex = Math.min(i + batchSize, membersToSave.size());
|
|
|
List<FsImportMember> batch = membersToSave.subList(i, endIndex);
|
|
List<FsImportMember> batch = membersToSave.subList(i, endIndex);
|
|
|
importMemberMapper.batchInsertOrUpdateFsImportMember(batch);
|
|
importMemberMapper.batchInsertOrUpdateFsImportMember(batch);
|
|
|
- logger.info("分批批量保存会员成功,批次:{}/{}, 数量:{}",
|
|
|
|
|
- (i / batchSize + 1),
|
|
|
|
|
- (membersToSave.size() + batchSize - 1) / batchSize,
|
|
|
|
|
|
|
+ logger.info("分批批量保存会员成功,批次:{}/{}, 数量:{}",
|
|
|
|
|
+ (i / batchSize + 1),
|
|
|
|
|
+ (membersToSave.size() + batchSize - 1) / batchSize,
|
|
|
batch.size());
|
|
batch.size());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -127,19 +129,19 @@ public class KdzlTask {
|
|
|
log.error("批量保存会员失败,数量:{}, 错误: {}", membersToSave.size(), e.getMessage(), e);
|
|
log.error("批量保存会员失败,数量:{}, 错误: {}", membersToSave.size(), e.getMessage(), e);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (custms.size() < 2000) {
|
|
if (custms.size() < 2000) {
|
|
|
logger.info("本次获取数据量小于2000,所有会员数据已同步完毕");
|
|
logger.info("本次获取数据量小于2000,所有会员数据已同步完毕");
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
logger.info("本次获取数据量等于2000,继续获取下一页数据...");
|
|
logger.info("本次获取数据量等于2000,继续获取下一页数据...");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (loopCount >= maxLoopCount) {
|
|
if (loopCount >= maxLoopCount) {
|
|
|
logger.warn("已达到最大循环次数{},强制退出循环,防止死循环", maxLoopCount);
|
|
logger.warn("已达到最大循环次数{},强制退出循环,防止死循环", maxLoopCount);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
logger.info("会员信息同步完成,总共同步数量:{}", totalCount);
|
|
logger.info("会员信息同步完成,总共同步数量:{}", totalCount);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -154,12 +156,12 @@ public class KdzlTask {
|
|
|
loopCount++;
|
|
loopCount++;
|
|
|
List<Custm> highSeasCustms = kdzlService.exportHighSeasCustomers(null);
|
|
List<Custm> highSeasCustms = kdzlService.exportHighSeasCustomers(null);
|
|
|
logger.info("本次获取公海会员信息数量:{},当前循环次数:{}", highSeasCustms.size(), loopCount);
|
|
logger.info("本次获取公海会员信息数量:{},当前循环次数:{}", highSeasCustms.size(), loopCount);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (CollectionUtils.isEmpty(highSeasCustms)) {
|
|
if (CollectionUtils.isEmpty(highSeasCustms)) {
|
|
|
logger.info("未获取到公海会员数据,同步结束");
|
|
logger.info("未获取到公海会员数据,同步结束");
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
totalCount += highSeasCustms.size();
|
|
totalCount += highSeasCustms.size();
|
|
|
logger.info("累计已同步公海会员数量:{}", totalCount);
|
|
logger.info("累计已同步公海会员数量:{}", totalCount);
|
|
|
|
|
|
|
@@ -231,9 +233,9 @@ public class KdzlTask {
|
|
|
int endIndex = Math.min(i + batchSize, membersToSave.size());
|
|
int endIndex = Math.min(i + batchSize, membersToSave.size());
|
|
|
List<FsImportMember> batch = membersToSave.subList(i, endIndex);
|
|
List<FsImportMember> batch = membersToSave.subList(i, endIndex);
|
|
|
importMemberMapper.batchInsertOrUpdateFsImportMember(batch);
|
|
importMemberMapper.batchInsertOrUpdateFsImportMember(batch);
|
|
|
- logger.info("分批批量保存公海会员成功,批次:{}/{}, 数量:{}",
|
|
|
|
|
- (i / batchSize + 1),
|
|
|
|
|
- (membersToSave.size() + batchSize - 1) / batchSize,
|
|
|
|
|
|
|
+ logger.info("分批批量保存公海会员成功,批次:{}/{}, 数量:{}",
|
|
|
|
|
+ (i / batchSize + 1),
|
|
|
|
|
+ (membersToSave.size() + batchSize - 1) / batchSize,
|
|
|
batch.size());
|
|
batch.size());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -241,7 +243,7 @@ public class KdzlTask {
|
|
|
log.error("批量保存公海会员失败,数量:{}, 错误: {}", membersToSave.size(), e.getMessage(), e);
|
|
log.error("批量保存公海会员失败,数量:{}, 错误: {}", membersToSave.size(), e.getMessage(), e);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (highSeasCustms.size() < 2000) {
|
|
if (highSeasCustms.size() < 2000) {
|
|
|
logger.info("本次获取数据量小于2000,所有公海会员数据已同步完毕");
|
|
logger.info("本次获取数据量小于2000,所有公海会员数据已同步完毕");
|
|
|
break;
|
|
break;
|
|
@@ -253,7 +255,124 @@ public class KdzlTask {
|
|
|
if (loopCount >= maxLoopCount) {
|
|
if (loopCount >= maxLoopCount) {
|
|
|
logger.warn("已达到最大循环次数{},强制退出循环,防止死循环", maxLoopCount);
|
|
logger.warn("已达到最大循环次数{},强制退出循环,防止死循环", maxLoopCount);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
logger.info("公海会员信息同步完成,总共同步数量:{}", totalCount);
|
|
logger.info("公海会员信息同步完成,总共同步数量:{}", totalCount);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ public void syncCallRecord() {
|
|
|
|
|
+ logger.info("开始同步通话记录...");
|
|
|
|
|
+ int totalCount = 0;
|
|
|
|
|
+ int batchSize = 500;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 获取数据
|
|
|
|
|
+ List<CallRecord> callRecords = kdzlService.exportCallRecords();
|
|
|
|
|
+ logger.info("本次获取通话记录数量:{}", callRecords.size());
|
|
|
|
|
+
|
|
|
|
|
+ if (CollectionUtils.isEmpty(callRecords)) {
|
|
|
|
|
+ logger.info("未获取到通话记录数据,同步结束");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 查询已存在的数据(批量)
|
|
|
|
|
+ List<FsKdzlCallRecord> existingFsKdzlCallRecordList =
|
|
|
|
|
+ kdzlCallRecordMapper.selectExistingFsKdzlCallRecordList(callRecords);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 过滤出需要插入的新数据
|
|
|
|
|
+ List<FsKdzlCallRecord> callRecordsToSave = new ArrayList<>();
|
|
|
|
|
+
|
|
|
|
|
+ for (CallRecord callRecord : callRecords) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 从已有列表中查找匹配的记录(使用5个字段联合判断)
|
|
|
|
|
+ FsKdzlCallRecord existingFsKdzlCallRecord = existingFsKdzlCallRecordList.parallelStream()
|
|
|
|
|
+ .filter(record ->
|
|
|
|
|
+ Objects.equals(record.getUid(), callRecord.getUid()) &&
|
|
|
|
|
+ Objects.equals(record.getCallTime(), callRecord.getCallTime()) &&
|
|
|
|
|
+ Objects.equals(record.getCaller(), callRecord.getCaller()) &&
|
|
|
|
|
+ Objects.equals(record.getCalled(), callRecord.getCalled()) &&
|
|
|
|
|
+ Objects.equals(record.getType(), callRecord.getType())
|
|
|
|
|
+ )
|
|
|
|
|
+ .findFirst()
|
|
|
|
|
+ .orElse(null);
|
|
|
|
|
+ boolean isNew = (existingFsKdzlCallRecord == null);
|
|
|
|
|
+
|
|
|
|
|
+ if (isNew) {
|
|
|
|
|
+ // 不存在,新增
|
|
|
|
|
+ FsKdzlCallRecord newRecord = new FsKdzlCallRecord();
|
|
|
|
|
+ newRecord.setUid(callRecord.getUid());
|
|
|
|
|
+ newRecord.setCallTime(callRecord.getCallTime());
|
|
|
|
|
+ newRecord.setTalkLen(callRecord.getTalkLen());
|
|
|
|
|
+ newRecord.setStatus(callRecord.getStatus());
|
|
|
|
|
+ newRecord.setType(callRecord.getType());
|
|
|
|
|
+ newRecord.setCaller(callRecord.getCaller());
|
|
|
|
|
+ newRecord.setCalled(callRecord.getCalled());
|
|
|
|
|
+ newRecord.setCustomerId(callRecord.getCustomerId());
|
|
|
|
|
+ newRecord.setCustomerName(callRecord.getCustomerName());
|
|
|
|
|
+
|
|
|
|
|
+ callRecordsToSave.add(newRecord);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("处理通话记录失败,uid: {}, 错误: {}", callRecord.getUid(), e.getMessage(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ logger.info("本次待插入数据:{} 条(已去重)", callRecordsToSave.size());
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 批量插入(移到循环外面)
|
|
|
|
|
+ if (!callRecordsToSave.isEmpty()) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (callRecordsToSave.size() <= batchSize) {
|
|
|
|
|
+ kdzlCallRecordMapper.batchInsertFsKdzlCallRecord(callRecordsToSave);
|
|
|
|
|
+ logger.info("批量保存通话记录成功,数量:{}", callRecordsToSave.size());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 按批次插入(每批500条)
|
|
|
|
|
+ for (int i = 0; i < callRecordsToSave.size(); i += batchSize) {
|
|
|
|
|
+ int endIndex = Math.min(i + batchSize, callRecordsToSave.size());
|
|
|
|
|
+ List<FsKdzlCallRecord> batch = callRecordsToSave.subList(i, endIndex);
|
|
|
|
|
+
|
|
|
|
|
+ kdzlCallRecordMapper.batchInsertFsKdzlCallRecord(batch);
|
|
|
|
|
+ logger.info("分批保存成功,批次:{}/{},数量:{}",
|
|
|
|
|
+ (i / batchSize + 1),
|
|
|
|
|
+ (callRecordsToSave.size() + batchSize - 1) / batchSize,
|
|
|
|
|
+ batch.size()
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ totalCount += callRecordsToSave.size();
|
|
|
|
|
+ logger.info("累计同步通话记录数量:{}", totalCount);
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("批量保存通话记录失败,数量:{}, 错误: {}", callRecordsToSave.size(), e.getMessage(), e);
|
|
|
|
|
+ // 可以在这里做补偿逻辑,比如逐条插入
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 构建组合键(从FsKdzlCallRecord)
|
|
|
|
|
+ */
|
|
|
|
|
+ private String buildCompositeKey(FsKdzlCallRecord record) {
|
|
|
|
|
+ return String.format("%d|%s|%s|%s|%d",
|
|
|
|
|
+ record.getUid(),
|
|
|
|
|
+ record.getCallTime().toString(),
|
|
|
|
|
+ record.getCaller(),
|
|
|
|
|
+ record.getCalled(),
|
|
|
|
|
+ record.getType()
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 构建组合键(从CallRecord)
|
|
|
|
|
+ */
|
|
|
|
|
+ private String buildCompositeKeyFromCallRecord(CallRecord record) {
|
|
|
|
|
+ return String.format("%d|%s|%s|%s|%d",
|
|
|
|
|
+ record.getUid(),
|
|
|
|
|
+ record.getCallTime().toString(),
|
|
|
|
|
+ record.getCaller(),
|
|
|
|
|
+ record.getCalled(),
|
|
|
|
|
+ record.getType()
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|