|
@@ -10,6 +10,7 @@ import org.jeecg.common.api.vo.Result;
|
|
|
import org.jeecg.common.util.DateUtils;
|
|
|
import org.jeecg.modules.billet.sampleCardDeliveryRecord.entity.SampleCardDeliveryRecord;
|
|
|
import org.jeecg.modules.billet.sampleCardDeliveryRecord.service.ISampleCardDeliveryRecordService;
|
|
|
+import org.springframework.dao.DuplicateKeyException;
|
|
|
import org.springframework.scheduling.annotation.Scheduled;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
import org.springframework.web.client.RestTemplate;
|
|
@@ -17,6 +18,7 @@ import org.springframework.web.client.RestTemplate;
|
|
|
import java.time.LocalDate;
|
|
|
import java.time.ZoneId;
|
|
|
import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@Slf4j
|
|
|
@Component
|
|
@@ -26,78 +28,161 @@ public class SampleCardSyncTask {
|
|
|
private final RestTemplate restTemplate;
|
|
|
private final ISampleCardDeliveryRecordService sampleCardDeliveryRecordService;
|
|
|
|
|
|
- // 请求接口的地址
|
|
|
- private static final String URL = "http://localhost:7005/billet/billetOriginalProductRecord/queryBilletRecordByCcmNo?queryType=1&ccmNo=";
|
|
|
|
|
|
@Scheduled(fixedRate = 10000) // 每10秒执行一次
|
|
|
public void syncSampleCardRecords() {
|
|
|
for (String ccmNo : Arrays.asList("5", "6")) {
|
|
|
try {
|
|
|
- String requestUrl = URL + ccmNo;
|
|
|
- Result result = restTemplate.getForObject(requestUrl, Result.class);
|
|
|
+ String requestUrl = String.format("http://localhost:7005/billet/billetOriginalProductRecord/queryBilletRecordByCcmNo?queryType=1&ccmNo=%s", ccmNo);
|
|
|
+ Result<?> result = restTemplate.getForObject(requestUrl, Result.class);
|
|
|
|
|
|
- if (result != null && result.isSuccess()) {
|
|
|
- JSONObject jsonObject = new JSONObject((Map) result.getResult());
|
|
|
+ if (result == null || !result.isSuccess()) {
|
|
|
+ log.warn("接口请求失败:{}", result != null ? result.getMessage() : "null response");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- // 新增判断 confirmStatus 是否为3
|
|
|
- Integer confirmStatus = jsonObject.getInteger("confirmStatus");
|
|
|
- if (confirmStatus != null && confirmStatus == 3) {
|
|
|
-// log.info("ccmNo={} 的数据已确认(confirmStatus=3),跳过新增与更新。", ccmNo);
|
|
|
- continue; // 跳过本次循环
|
|
|
- }
|
|
|
+ Object resultData = result.getResult();
|
|
|
+ if (!(resultData instanceof Map)) {
|
|
|
+ log.warn("接口返回数据格式错误,非 Map 类型");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONObject jsonObject = new JSONObject((Map<String, Object>) resultData);
|
|
|
+
|
|
|
+ // 判断是否已确认,跳过
|
|
|
+ Integer confirmStatus = jsonObject.getInteger("confirmStatus");
|
|
|
+ if (confirmStatus != null && confirmStatus == 3) {
|
|
|
+// log.info("ccmNo={} 的数据已确认,跳过本次处理", ccmNo);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- JSONArray jsonArray = jsonObject.getJSONArray("billetOriginalProductRecordList");
|
|
|
+ JSONArray jsonArray = jsonObject.getJSONArray("billetOriginalProductRecordList");
|
|
|
+ if (jsonArray == null || jsonArray.isEmpty()) {
|
|
|
+// log.info("ccmNo={} 没有需要同步的数据", ccmNo);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- List<SampleCardDeliveryRecord> recordsToSave = new ArrayList<>();
|
|
|
- List<SampleCardDeliveryRecord> recordsToUpdate = new ArrayList<>();
|
|
|
+ // 解析远程数据
|
|
|
+ Set<String> remoteHeatNos = new HashSet<>();
|
|
|
+ Map<String, SampleCardDeliveryRecord> remoteRecordMap = new HashMap<>();
|
|
|
+ LocalDate latestCreateDate = null;
|
|
|
+ String remoteShift = null;
|
|
|
+ String remoteShiftGroup = null;
|
|
|
+
|
|
|
+ for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
+ JSONObject json = jsonArray.getJSONObject(i);
|
|
|
+ SampleCardDeliveryRecord record = json.toJavaObject(SampleCardDeliveryRecord.class);
|
|
|
+
|
|
|
+ Date createDate = DateUtils.str2Date(json.getString("createTime"), DateUtils.datetimeFormat.get());
|
|
|
+ LocalDate createLocalDate = createDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
+ record.setCreateTime(createDate); // 补充 set 回 createTime,供后续使用
|
|
|
+
|
|
|
+ // 获取远程班次信息
|
|
|
+ if (i == 0) {
|
|
|
+ remoteShift = record.getShift();
|
|
|
+ remoteShiftGroup = record.getShiftGroup();
|
|
|
+ latestCreateDate = createLocalDate;
|
|
|
+ }
|
|
|
|
|
|
- for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
- JSONObject json = jsonArray.getJSONObject(i);
|
|
|
- SampleCardDeliveryRecord record = json.toJavaObject(SampleCardDeliveryRecord.class);
|
|
|
+ // 更新最大日期
|
|
|
+ if (latestCreateDate == null || createLocalDate.isAfter(latestCreateDate)) {
|
|
|
+ latestCreateDate = createLocalDate;
|
|
|
+ }
|
|
|
|
|
|
- Date createDate = DateUtils.str2Date(json.getString("createTime"), DateUtils.datetimeFormat.get());
|
|
|
- LocalDate createLocalDate = createDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
+ String heatNo = record.getHeatNo();
|
|
|
+ remoteHeatNos.add(heatNo);
|
|
|
+ remoteRecordMap.put(heatNo, record);
|
|
|
+ }
|
|
|
|
|
|
- LambdaQueryWrapper<SampleCardDeliveryRecord> wrapper = new LambdaQueryWrapper<>();
|
|
|
- wrapper.eq(SampleCardDeliveryRecord::getCcmNo, record.getCcmNo())
|
|
|
- .eq(SampleCardDeliveryRecord::getHeatNo, record.getHeatNo())
|
|
|
- .eq(SampleCardDeliveryRecord::getShift, record.getShift())
|
|
|
- .eq(SampleCardDeliveryRecord::getShiftGroup, record.getShiftGroup())
|
|
|
+ if (remoteShift == null || remoteShiftGroup == null) {
|
|
|
+ log.warn("远程数据缺失班次信息,跳过本次处理");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询本地相同班次、相同铸机、同一天的数据
|
|
|
+ List<SampleCardDeliveryRecord> localRecords = sampleCardDeliveryRecordService.list(
|
|
|
+ new LambdaQueryWrapper<SampleCardDeliveryRecord>()
|
|
|
+ .eq(SampleCardDeliveryRecord::getCcmNo, ccmNo)
|
|
|
+ .eq(SampleCardDeliveryRecord::getShift, remoteShift)
|
|
|
+ .eq(SampleCardDeliveryRecord::getShiftGroup, remoteShiftGroup)
|
|
|
.between(SampleCardDeliveryRecord::getCreateTime,
|
|
|
- Date.from(createLocalDate.atStartOfDay(ZoneId.systemDefault()).toInstant()),
|
|
|
- Date.from(createLocalDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).minusNanos(1).toInstant()))
|
|
|
- .last("LIMIT 1");
|
|
|
-
|
|
|
- SampleCardDeliveryRecord existRecord = sampleCardDeliveryRecordService.getOne(wrapper, false);
|
|
|
-
|
|
|
- if (existRecord == null) {
|
|
|
- record.setId(String.valueOf(IdWorker.getId()));
|
|
|
- recordsToSave.add(record);
|
|
|
- } else {
|
|
|
- record.setId(existRecord.getId());
|
|
|
- recordsToUpdate.add(record);
|
|
|
- }
|
|
|
- }
|
|
|
+ Date.from(latestCreateDate.atStartOfDay(ZoneId.systemDefault()).toInstant()),
|
|
|
+ Date.from(latestCreateDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).minusNanos(1).toInstant()))
|
|
|
+ );
|
|
|
|
|
|
- if (!recordsToSave.isEmpty()) {
|
|
|
- sampleCardDeliveryRecordService.saveBatch(recordsToSave);
|
|
|
-// log.info("成功新增 SampleCardDeliveryRecord {} 条,ccmNo={}", recordsToSave.size(), ccmNo);
|
|
|
+ Set<String> localHeatNos = localRecords.stream()
|
|
|
+ .map(SampleCardDeliveryRecord::getHeatNo)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ List<SampleCardDeliveryRecord> recordsToSave = new ArrayList<>();
|
|
|
+ List<SampleCardDeliveryRecord> recordsToUpdate = new ArrayList<>();
|
|
|
+
|
|
|
+ for (String heatNo : remoteHeatNos) {
|
|
|
+ SampleCardDeliveryRecord record = remoteRecordMap.get(heatNo);
|
|
|
+
|
|
|
+ SampleCardDeliveryRecord existRecord = sampleCardDeliveryRecordService.findExistingRecord(record);
|
|
|
+
|
|
|
+ if (existRecord == null) {
|
|
|
+ record.setId(String.valueOf(IdWorker.getId()));
|
|
|
+ recordsToSave.add(record);
|
|
|
+ } else {
|
|
|
+ record.setId(existRecord.getId());
|
|
|
+ recordsToUpdate.add(record);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- if (!recordsToUpdate.isEmpty()) {
|
|
|
- sampleCardDeliveryRecordService.updateBatchById(recordsToUpdate);
|
|
|
-// log.info("成功更新 SampleCardDeliveryRecord {} 条,ccmNo={}", recordsToUpdate.size(), ccmNo);
|
|
|
+ // 删除多余记录(本地有但远程没有的 heatNo)
|
|
|
+ Set<String> heatNosToDelete = new HashSet<>(localHeatNos);
|
|
|
+ heatNosToDelete.removeAll(remoteHeatNos);
|
|
|
+
|
|
|
+ int successCount = 0;
|
|
|
+ for (SampleCardDeliveryRecord record : recordsToSave) {
|
|
|
+ try {
|
|
|
+ sampleCardDeliveryRecordService.saveOrUpdate(record, buildUniqueKeyWrapper(record));
|
|
|
+ successCount++;
|
|
|
+ } catch (DuplicateKeyException e) {
|
|
|
+ log.warn("唯一键冲突跳过保存:heatNo={}, ccmNo={}", record.getHeatNo(), record.getCcmNo());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("保存记录出错:{}", record, e);
|
|
|
}
|
|
|
+ }
|
|
|
+ if (successCount > 0) {
|
|
|
+// log.info("成功新增 SampleCardDeliveryRecord {} 条,ccmNo={}", successCount, ccmNo);
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
- log.warn("接口请求失败:{}", result != null ? result.getMessage() : "null response");
|
|
|
+ if (!recordsToUpdate.isEmpty()) {
|
|
|
+ sampleCardDeliveryRecordService.updateBatchById(recordsToUpdate);
|
|
|
+// log.info("成功更新 SampleCardDeliveryRecord {} 条,ccmNo={}", recordsToUpdate.size(), ccmNo);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!heatNosToDelete.isEmpty()) {
|
|
|
+ List<String> idsToDelete = localRecords.stream()
|
|
|
+ .filter(r -> heatNosToDelete.contains(r.getHeatNo()))
|
|
|
+ .map(SampleCardDeliveryRecord::getId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ sampleCardDeliveryRecordService.removeByIds(idsToDelete);
|
|
|
+ log.info("成功删除 SampleCardDeliveryRecord {} 条,ccmNo={}, shift={}, shiftGroup={}",
|
|
|
+ idsToDelete.size(), ccmNo, remoteShift, remoteShiftGroup);
|
|
|
}
|
|
|
+
|
|
|
} catch (Exception e) {
|
|
|
log.error("同步 SampleCardDeliveryRecord 出错,ccmNo={}", ccmNo, e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ private LambdaQueryWrapper<SampleCardDeliveryRecord> buildUniqueKeyWrapper(SampleCardDeliveryRecord record) {
|
|
|
+ LocalDate createDate = record.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
+
|
|
|
+ return new LambdaQueryWrapper<SampleCardDeliveryRecord>()
|
|
|
+ .eq(SampleCardDeliveryRecord::getCcmNo, record.getCcmNo())
|
|
|
+ .eq(SampleCardDeliveryRecord::getHeatNo, record.getHeatNo())
|
|
|
+ .eq(SampleCardDeliveryRecord::getShift, record.getShift())
|
|
|
+ .eq(SampleCardDeliveryRecord::getShiftGroup, record.getShiftGroup())
|
|
|
+ .between(SampleCardDeliveryRecord::getCreateTime,
|
|
|
+ Date.from(createDate.atStartOfDay(ZoneId.systemDefault()).toInstant()),
|
|
|
+ Date.from(createDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).minusNanos(1).toInstant()));
|
|
|
+ }
|
|
|
|
|
|
}
|