|
|
@ -298,10 +298,9 @@ public class SampleTrackingServiceImpl implements SampleTrackingService { |
|
|
if (!missingFields.isEmpty()) { |
|
|
if (!missingFields.isEmpty()) { |
|
|
throw new RuntimeException("项目追踪记录缺少以下必填项,无法同步: " + String.join("、", missingFields)); |
|
|
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) { |
|
|
if (npiProjectId == null) { |
|
|
Project insertProject = buildProjectForInsert(trackingProject, operator); |
|
|
Project insertProject = buildProjectForInsert(trackingProject, operator); |
|
|
int insertRows = projectMapper.insert(insertProject); |
|
|
int insertRows = projectMapper.insert(insertProject); |
|
|
@ -345,8 +344,9 @@ public class SampleTrackingServiceImpl implements SampleTrackingService { |
|
|
throw new RuntimeException("项目物料追踪记录缺少以下必填项,无法同步: " + String.join("、", latestPartMissingFields)); |
|
|
throw new RuntimeException("项目物料追踪记录缺少以下必填项,无法同步: " + String.join("、", latestPartMissingFields)); |
|
|
} |
|
|
} |
|
|
latestPart.setProjectId(npiProjectId); |
|
|
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) { |
|
|
if (npiProjectPartId == null) { |
|
|
ProjectPart insertPart = buildProjectPartForInsert(latestPart, operator); |
|
|
ProjectPart insertPart = buildProjectPartForInsert(latestPart, operator); |
|
|
int insertRows = projectPartMapper.insert(insertPart); |
|
|
int insertRows = projectPartMapper.insert(insertPart); |
|
|
@ -525,9 +525,9 @@ public class SampleTrackingServiceImpl implements SampleTrackingService { |
|
|
throw new RuntimeException("请先同步项目物料后再同步打样单"); |
|
|
throw new RuntimeException("请先同步项目物料后再同步打样单"); |
|
|
} |
|
|
} |
|
|
// 若业务键可用,则进一步校验 tracking 与 NPI 指向同一业务记录,避免ID偶合误判 |
|
|
// 若业务键可用,则进一步校验 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)) { |
|
|
if (matchedProjectId != null && !Objects.equals(matchedProjectId, trackingProjectId)) { |
|
|
throw new RuntimeException("请先同步项目后再同步打样单"); |
|
|
throw new RuntimeException("请先同步项目后再同步打样单"); |
|
|
} |
|
|
} |
|
|
@ -861,6 +861,36 @@ public class SampleTrackingServiceImpl implements SampleTrackingService { |
|
|
return missingFields; |
|
|
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) { |
|
|
private Project buildProjectForInsert(ProjectInfoTrackingData trackingProject, String operator) { |
|
|
Project project = new Project(); |
|
|
Project project = new Project(); |
|
|
BeanUtils.copyProperties(trackingProject, project); |
|
|
BeanUtils.copyProperties(trackingProject, project); |
|
|
|