diff --git a/src/main/java/com/xujie/sys/modules/sampletracking/mapper/SampleTrackingMapper.java b/src/main/java/com/xujie/sys/modules/sampletracking/mapper/SampleTrackingMapper.java index 313d5898..e100906a 100644 --- a/src/main/java/com/xujie/sys/modules/sampletracking/mapper/SampleTrackingMapper.java +++ b/src/main/java/com/xujie/sys/modules/sampletracking/mapper/SampleTrackingMapper.java @@ -49,7 +49,9 @@ public interface SampleTrackingMapper { ProjectInfoTrackingData selectProjectInfoTrackingById(@Param("projectId") Integer projectId); - Integer selectNpiProjectIdBySiteAndProjectNo(@Param("site") String site, @Param("projectNo") String projectNo); + Integer selectNpiProjectIdBySiteBuNoAndProjectNo(@Param("site") String site, + @Param("buNo") String buNo, + @Param("projectNo") String projectNo); void updateNpiProjectFromTracking(ProjectInfoTrackingData data); diff --git a/src/main/java/com/xujie/sys/modules/sampletracking/service/impl/SampleTrackingServiceImpl.java b/src/main/java/com/xujie/sys/modules/sampletracking/service/impl/SampleTrackingServiceImpl.java index edde99a3..bff0508f 100644 --- a/src/main/java/com/xujie/sys/modules/sampletracking/service/impl/SampleTrackingServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/sampletracking/service/impl/SampleTrackingServiceImpl.java @@ -298,10 +298,9 @@ public class SampleTrackingServiceImpl implements SampleTrackingService { if (!missingFields.isEmpty()) { throw new RuntimeException("项目追踪记录缺少以下必填项,无法同步: " + String.join("、", missingFields)); } - // 优先按“trackingId == npiId”的目标查 NPI: - // 若已存在则更新,不存在则插入,后续再统一做 tracking ID 对齐。 - Project existedNpiProject = projectMapper.selectById(trackingProjectId); - Integer npiProjectId = existedNpiProject == null ? null : existedNpiProject.getProjectId(); + // 同步判定优先使用业务键(site + buNo + projectNo),这样可以避免“同项目不同ID”重复插入。 + // 若业务键未命中,再回退到 trackingId == npiId 的历史兼容策略。 + Integer npiProjectId = resolveMatchedNpiProjectId(trackingProjectId, trackingProject); if (npiProjectId == null) { Project insertProject = buildProjectForInsert(trackingProject, operator); int insertRows = projectMapper.insert(insertProject); @@ -345,8 +344,9 @@ public class SampleTrackingServiceImpl implements SampleTrackingService { throw new RuntimeException("项目物料追踪记录缺少以下必填项,无法同步: " + String.join("、", latestPartMissingFields)); } latestPart.setProjectId(npiProjectId); - ProjectPart existedNpiPart = projectPartMapper.selectById(trackingProjectPartId); - Integer npiProjectPartId = existedNpiPart == null ? null : existedNpiPart.getId(); + // 物料同步同样优先按业务键(site + projectId + testPartNo)定位,命中后执行更新。 + // 仅在业务键未命中时,才按 trackingId == npiId 兼容旧数据。 + Integer npiProjectPartId = resolveMatchedNpiProjectPartId(trackingProjectPartId, npiProjectId, latestPart); if (npiProjectPartId == null) { ProjectPart insertPart = buildProjectPartForInsert(latestPart, operator); int insertRows = projectPartMapper.insert(insertPart); @@ -525,9 +525,9 @@ public class SampleTrackingServiceImpl implements SampleTrackingService { throw new RuntimeException("请先同步项目物料后再同步打样单"); } // 若业务键可用,则进一步校验 tracking 与 NPI 指向同一业务记录,避免ID偶合误判 - if (!isBlank(trackingProject.getSite()) && !isBlank(trackingProject.getProjectNo())) { - Integer matchedProjectId = sampleTrackingMapper.selectNpiProjectIdBySiteAndProjectNo( - trackingProject.getSite(), trackingProject.getProjectNo()); + if (!isBlank(trackingProject.getSite()) && !isBlank(trackingProject.getBuNo()) && !isBlank(trackingProject.getProjectNo())) { + Integer matchedProjectId = sampleTrackingMapper.selectNpiProjectIdBySiteBuNoAndProjectNo( + trackingProject.getSite(), trackingProject.getBuNo(), trackingProject.getProjectNo()); if (matchedProjectId != null && !Objects.equals(matchedProjectId, trackingProjectId)) { throw new RuntimeException("请先同步项目后再同步打样单"); } @@ -861,6 +861,36 @@ public class SampleTrackingServiceImpl implements SampleTrackingService { return missingFields; } + private Integer resolveMatchedNpiProjectId(Integer trackingProjectId, ProjectInfoTrackingData trackingProject) { + if (trackingProject != null + && !isBlank(trackingProject.getSite()) + && !isBlank(trackingProject.getBuNo()) + && !isBlank(trackingProject.getProjectNo())) { + Integer matchedByBusinessKey = sampleTrackingMapper.selectNpiProjectIdBySiteBuNoAndProjectNo( + trackingProject.getSite().trim(), trackingProject.getBuNo().trim(), trackingProject.getProjectNo().trim()); + if (matchedByBusinessKey != null) { + return matchedByBusinessKey; + } + } + Project existedByTrackingId = projectMapper.selectById(trackingProjectId); + return existedByTrackingId == null ? null : existedByTrackingId.getProjectId(); + } + + private Integer resolveMatchedNpiProjectPartId(Integer trackingProjectPartId, + Integer npiProjectId, + ProjectPartTrackingData trackingPart) { + if (trackingPart != null && npiProjectId != null + && !isBlank(trackingPart.getSite()) && !isBlank(trackingPart.getTestPartNo())) { + Integer matchedByBusinessKey = sampleTrackingMapper.selectNpiProjectPartIdBySiteProjectAndPartNo( + trackingPart.getSite().trim(), npiProjectId, trackingPart.getTestPartNo().trim()); + if (matchedByBusinessKey != null) { + return matchedByBusinessKey; + } + } + ProjectPart existedByTrackingId = projectPartMapper.selectById(trackingProjectPartId); + return existedByTrackingId == null ? null : existedByTrackingId.getId(); + } + private Project buildProjectForInsert(ProjectInfoTrackingData trackingProject, String operator) { Project project = new Project(); BeanUtils.copyProperties(trackingProject, project); diff --git a/src/main/resources/mapper/sampletracking/SampleTrackingMapper.xml b/src/main/resources/mapper/sampletracking/SampleTrackingMapper.xml index 16cac21b..928ef3fe 100644 --- a/src/main/resources/mapper/sampletracking/SampleTrackingMapper.xml +++ b/src/main/resources/mapper/sampletracking/SampleTrackingMapper.xml @@ -361,10 +361,11 @@ WHERE a.id = #{projectId} - SELECT TOP 1 id FROM plm_project_info WHERE site = #{site} + AND bu_no = #{buNo} AND project_no = #{projectNo} ORDER BY id DESC