Browse Source

送样卡记录表同步数据时,完善对于减量数据的维护

lingpeng.li 1 week ago
parent
commit
4671f910cd

+ 67 - 20
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/billetHotsendChangeShift/controller/BilletHotsendChangeShiftController.java

@@ -51,6 +51,7 @@ import org.jeecg.modules.billet.storageBill.entity.StorageBill;
 import org.jeecg.modules.billet.storageBill.service.IStorageBillService;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.web.bind.annotation.*;
@@ -214,14 +215,10 @@ public class BilletHotsendChangeShiftController extends JeecgController<BilletHo
 		}
 		billetHotsendChangeShiftService.updateById(billetHotsendChangeShiftInfo);
 
-		final String URL = "http://localhost:7005/billet/billetOriginalProductRecord/queryBilletRecordByCcmNo?queryType=2&ccmNo=%s&changeShiftId=%s";
-
-
-		// 如果从 1 更新为 2,则触发查询与数据更新逻辑
-		if (oldConfirmStatus != null && oldConfirmStatus == 1
-				&& billetHotsendChangeShift.getConfirmStatus() != null
-				&& billetHotsendChangeShift.getConfirmStatus() == 2) {
+		// 只有从 1 → 2 才触发远程接口同步逻辑
+		if (Objects.equals(oldConfirmStatus, 1) && Objects.equals(billetHotsendChangeShift.getConfirmStatus(), 2)) {
 
+			final String URL = "http://localhost:7005/billet/billetOriginalProductRecord/queryBilletRecordByCcmNo?queryType=2&ccmNo=%s&changeShiftId=%s";
 			String ccmNo = billetHotsendChangeShiftInfo.getCcmNo();
 			String changeShiftId = billetHotsendChangeShiftInfo.getId();
 			String requestUrl = String.format(URL, ccmNo, changeShiftId);
@@ -234,32 +231,31 @@ public class BilletHotsendChangeShiftController extends JeecgController<BilletHo
 
 					Integer confirmStatus = jsonObject.getInteger("confirmStatus");
 					if (confirmStatus != null && confirmStatus == 3) {
-						log.info("ccmNo={} 的数据已确认,跳过新增与更新。", ccmNo);
+//						log.info("ccmNo={} 的数据已确认,跳过新增与更新。", ccmNo);
 						return Result.OK("操作成功!");
 					}
 
 					JSONArray jsonArray = jsonObject.getJSONArray("billetOriginalProductRecordList");
+
+					Set<String> remoteHeatNos = new HashSet<>();
 					List<SampleCardDeliveryRecord> recordsToSave = new ArrayList<>();
 					List<SampleCardDeliveryRecord> recordsToUpdate = new ArrayList<>();
 
+					LocalDate referenceDate = 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();
+						if (referenceDate == null || createLocalDate.isAfter(referenceDate)) {
+							referenceDate = createLocalDate;
+						}
 
-						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())
-								.between(SampleCardDeliveryRecord::getCreateTime,
-										Date.from(createLocalDate.atStartOfDay(ZoneId.systemDefault()).toInstant()),
-										Date.from(createLocalDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).minusNanos(1).toInstant()))
-								.last("LIMIT 1");
+						remoteHeatNos.add(record.getHeatNo());
 
-						SampleCardDeliveryRecord existRecord = sampleCardDeliveryRecordService.getOne(wrapper, false);
+						SampleCardDeliveryRecord existRecord = sampleCardDeliveryRecordService.findExistingRecord(record);
 
 						if (existRecord == null) {
 							record.setId(String.valueOf(IdWorker.getId()));
@@ -270,13 +266,51 @@ public class BilletHotsendChangeShiftController extends JeecgController<BilletHo
 						}
 					}
 
-					if (!recordsToSave.isEmpty()) {
-						sampleCardDeliveryRecordService.saveBatch(recordsToSave);
+					// 查询本地同一天、同班次、同班组的数据,用于计算需要删除的记录
+					List<SampleCardDeliveryRecord> localRecords = sampleCardDeliveryRecordService.list(
+							new LambdaQueryWrapper<SampleCardDeliveryRecord>()
+									.eq(SampleCardDeliveryRecord::getCcmNo, ccmNo)
+									.eq(SampleCardDeliveryRecord::getShift, billetHotsendChangeShiftInfo.getShift())
+									.eq(SampleCardDeliveryRecord::getShiftGroup, billetHotsendChangeShiftInfo.getShiftGroup())
+									.between(SampleCardDeliveryRecord::getCreateTime,
+											Date.from(referenceDate.atStartOfDay(ZoneId.systemDefault()).toInstant()),
+											Date.from(referenceDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).minusNanos(1).toInstant()))
+					);
+
+					Set<String> localHeatNos = localRecords.stream()
+							.map(SampleCardDeliveryRecord::getHeatNo)
+							.collect(Collectors.toSet());
+
+					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 (!recordsToUpdate.isEmpty()) {
 						sampleCardDeliveryRecordService.updateBatchById(recordsToUpdate);
 					}
+					if (!heatNosToDelete.isEmpty()) {
+						sampleCardDeliveryRecordService.remove(
+								new LambdaQueryWrapper<SampleCardDeliveryRecord>()
+										.eq(SampleCardDeliveryRecord::getCcmNo, ccmNo)
+										.eq(SampleCardDeliveryRecord::getShift, billetHotsendChangeShiftInfo.getShift())
+										.eq(SampleCardDeliveryRecord::getShiftGroup, billetHotsendChangeShiftInfo.getShiftGroup())
+										.in(SampleCardDeliveryRecord::getHeatNo, heatNosToDelete)
+										.between(SampleCardDeliveryRecord::getCreateTime,
+												Date.from(referenceDate.atStartOfDay(ZoneId.systemDefault()).toInstant()),
+												Date.from(referenceDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).minusNanos(1).toInstant()))
+						);
+					}
 
 				} else {
 					log.warn("接口请求失败:{}", result != null ? result.getMessage() : "null response");
@@ -1802,4 +1836,17 @@ public class BilletHotsendChangeShiftController extends JeecgController<BilletHo
 				break;
 		}
 	}
+
+	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()));
+	}
 }

+ 2 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/sampleCardDeliveryRecord/service/ISampleCardDeliveryRecordService.java

@@ -11,4 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface ISampleCardDeliveryRecordService extends IService<SampleCardDeliveryRecord> {
 
+    SampleCardDeliveryRecord findExistingRecord(SampleCardDeliveryRecord record);
+
 }

+ 22 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/sampleCardDeliveryRecord/service/impl/SampleCardDeliveryRecordServiceImpl.java

@@ -1,5 +1,6 @@
 package org.jeecg.modules.billet.sampleCardDeliveryRecord.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.jeecg.modules.billet.sampleCardDeliveryRecord.entity.SampleCardDeliveryRecord;
 import org.jeecg.modules.billet.sampleCardDeliveryRecord.mapper.SampleCardDeliveryRecordMapper;
 import org.jeecg.modules.billet.sampleCardDeliveryRecord.service.ISampleCardDeliveryRecordService;
@@ -7,6 +8,10 @@ import org.springframework.stereotype.Service;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
+
 /**
  * @Description: 送样卡记录
  * @Author: jeecg-boot
@@ -16,4 +21,21 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 @Service
 public class SampleCardDeliveryRecordServiceImpl extends ServiceImpl<SampleCardDeliveryRecordMapper, SampleCardDeliveryRecord> implements ISampleCardDeliveryRecordService {
 
+    @Override
+    public SampleCardDeliveryRecord findExistingRecord(SampleCardDeliveryRecord record) {
+        LocalDate createDate = record.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+        return this.getOne(
+                new LambdaQueryWrapper<SampleCardDeliveryRecord>()
+                        .eq(SampleCardDeliveryRecord::getCcmNo, record.getCcmNo())
+                        .eq(SampleCardDeliveryRecord::getHeatNo, record.getHeatNo())
+                        .eq(SampleCardDeliveryRecord::getShift, record.getShift())
+                        .eq(SampleCardDeliveryRecord::getShiftGroup, record.getShiftGroup())
+                        .ge(SampleCardDeliveryRecord::getCreateTime,
+                                Date.from(createDate.atStartOfDay(ZoneId.systemDefault()).toInstant()))
+                        .lt(SampleCardDeliveryRecord::getCreateTime,
+                                Date.from(createDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant()))
+                        .last("LIMIT 1"),
+                false
+        );
+    }
 }

+ 133 - 48
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/sampleCardDeliveryRecord/task/SampleCardSyncTask.java

@@ -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()));
+    }
 
 }