From b41fbee3628c8b11fc162fbd6b23fd454356b9a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Sat, 25 Apr 2026 15:15:12 +0800 Subject: [PATCH] =?UTF-8?q?refactor(inspection):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=85=A5=E5=BA=93=E6=A3=80=E9=AA=8C=E4=BB=BB=E5=8A=A1=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E9=A1=B9=E6=8F=90=E4=BA=A4=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 提取当前用户和时间,统一设置记录创建信息 - 批量保存和更新检验项,提升数据库操作效率 - 批量保存和更新样本数据,避免重复调用单条保存 - 使用集合分别存储新增和更新的数据,简化数据处理流程 refactor(material-sync): 优化物料同步逻辑和查询性能 - 过滤物料类别编码为空的记录并去重物料列表 - 分批查询数据库,避免SQL语句中IN子句过长 - 批量处理新增和更新的物料数据,提升同步效率 - 详细记录新增和更新的物料数量日志信息 - 优化异常处理,返回包含异常信息的失败结果 --- ...comingInspectionTaskControllerService.java | 76 +++++-- .../processor/QCMaterialSyncProcessor.java | 189 ++++++++++-------- 2 files changed, 167 insertions(+), 98 deletions(-) diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/IncomingInspectionTaskControllerService.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/IncomingInspectionTaskControllerService.java index a5cf530b..5bf444cb 100644 --- a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/IncomingInspectionTaskControllerService.java +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/IncomingInspectionTaskControllerService.java @@ -21,6 +21,7 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -769,7 +770,13 @@ public class IncomingInspectionTaskControllerService { return samplingPlanInspection.getCodeLetterId(); } + @Transactional public void submitCheckItem(QmsIncomingInspectionTaskTodoCheckSubmitQO request) { + LocalDateTime now = LocalDateTime.now(); + Long userId = UserUtil.getUserId(); + String userName = UserUtil.getUserName(); + + // 1. 保存/更新检验记录 QmsIncomingInspectionTaskRecord record = new QmsIncomingInspectionTaskRecord() .setId(request.getId()) .setTaskId(request.getTaskId()) @@ -778,35 +785,70 @@ public class IncomingInspectionTaskControllerService { .setUnqualifiedQty(request.getUnqualifiedQty()) .setInspectionQty(request.getInspectionQty()) .setQualified(Objects.equals(request.getQualifiedQty(), request.getInspectionQty())) - .setCreateUserId(UserUtil.getUserId()) - .setCreateUserName(UserUtil.getUserName()) - .setCreateTime(LocalDateTime.now()); + .setCreateUserId(userId) + .setCreateUserName(userName) + .setCreateTime(now); incomingInspectionTaskRecordService.saveOrUpdate(record); - request.getItems().forEach(item -> { + + // 2. 收集所有检验项实体,区分新增和更新 + List allItemEntities = new ArrayList<>(); + List insertItems = new ArrayList<>(); + List updateItems = new ArrayList<>(); + + for (QmsIncomingInspectionTaskTodoCheckSubmitItemQO item : request.getItems()) { QmsIncomingInspectionTaskRecordItem ditem = new QmsIncomingInspectionTaskRecordItem() .setId(item.getId()) .setRecordId(record.getId()) .setRemark(item.getRemark()) .setInspectionStandardItemContentId(item.getInspectionStandardItemContentId()); - incomingInspectionTaskRecordItemService.saveOrUpdate(ditem); - item.getDatas().forEach(data -> { + allItemEntities.add(ditem); + if (item.getId() == null) { + insertItems.add(ditem); + } else { + updateItems.add(ditem); + } + } + + // 3. 批量保存/更新检验项 + if (!insertItems.isEmpty()) { + incomingInspectionTaskRecordItemService.saveBatch(insertItems); + } + if (!updateItems.isEmpty()) { + incomingInspectionTaskRecordItemService.updateBatchById(updateItems); + } + + // 4. 收集所有样本数据实体,区分新增和更新 + List insertDatas = new ArrayList<>(); + List updateDatas = new ArrayList<>(); + + List itemQOs = request.getItems(); + for (int i = 0; i < itemQOs.size(); i++) { + QmsIncomingInspectionTaskRecordItem ditem = allItemEntities.get(i); + for (QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO data : itemQOs.get(i).getDatas()) { + String imageIds = CollectionUtil.isEmpty(data.getImages()) ? null + : StrUtil.join(",", data.getImages().stream().map(FileUploadVO::getId).toList()); QmsIncomingInspectionTaskRecordItemData ddata = new QmsIncomingInspectionTaskRecordItemData() .setId(data.getId()) .setTaskId(record.getTaskId()) .setItemId(ditem.getId()) .setQualified(data.getQualified()) .setMeasuredValue(data.getMeasuredValue()) - .setImages( - StrUtil.join(",", - data.getImages() - .stream() - .map(FileUploadVO::getId) - .toList() - ) - ); - incomingInspectionTaskRecordItemDataService.saveOrUpdate(ddata); - }); - }); + .setImages(imageIds); + if (data.getId() == null) { + insertDatas.add(ddata); + } else { + updateDatas.add(ddata); + } + } + } + + // 5. 批量保存/更新样本数据 + if (!insertDatas.isEmpty()) { + incomingInspectionTaskRecordItemDataService.saveBatch(insertDatas); + } + if (!updateDatas.isEmpty()) { + incomingInspectionTaskRecordItemDataService.updateBatchById(updateDatas); + } } /** diff --git a/nflg-wms-scheduled/src/main/java/com/nflg/wms/scheduled/processor/QCMaterialSyncProcessor.java b/nflg-wms-scheduled/src/main/java/com/nflg/wms/scheduled/processor/QCMaterialSyncProcessor.java index ac171a27..889741b9 100644 --- a/nflg-wms-scheduled/src/main/java/com/nflg/wms/scheduled/processor/QCMaterialSyncProcessor.java +++ b/nflg-wms-scheduled/src/main/java/com/nflg/wms/scheduled/processor/QCMaterialSyncProcessor.java @@ -1,5 +1,6 @@ package com.nflg.wms.scheduled.processor; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.nflg.wms.common.pojo.dto.MaterialMainListByDateDTO; @@ -17,8 +18,11 @@ import tech.powerjob.worker.log.OmsLogger; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * 从主物料同步物料到QMS @@ -44,97 +48,120 @@ public class QCMaterialSyncProcessor implements BasicProcessor { // 从主物料系统查询指定日期范围的物料列表 List materials = bomMaterialService.getListByDate(startDateTime, endDateTime); - if (CollectionUtil.isEmpty(materials)) { log.info("没有需要同步的物料"); - } else { + return new ProcessResult(true); + } - Long userId = UserUtil.getUserId(); - String operator = UserUtil.getUserName(); - LocalDateTime now = LocalDateTime.now(); + Long userId = UserUtil.getUserId(); + String operator = UserUtil.getUserName(); + LocalDateTime now = LocalDateTime.now(); - // 过滤掉物料类别编码为空的记录 - List validMaterials = materials.stream() - .filter(dto -> { - if (StrUtil.isBlank(dto.getMaterialCategoryCode())) { - log.warn("物料类别编码为空:{}", dto.getMaterialNo()); - return false; - } - return true; - }) - .collect(java.util.stream.Collectors.toList()); - - if (CollectionUtil.isEmpty(validMaterials)) { - log.info("没有需要同步的物料"); - } else { - - // 批量查询已存在的物料,构建 materialNo -> QmsQcMaterial 映射 - List materialNos = validMaterials.stream() - .map(MaterialMainListByDateDTO::getMaterialNo) - .collect(java.util.stream.Collectors.toList()); - Map existMaterialMap = qcMaterialService.lambdaQuery() - .in(QmsQcMaterial::getMaterialNo, materialNos) - .list() - .stream() - .collect(java.util.stream.Collectors.toMap(QmsQcMaterial::getMaterialNo, m -> m)); - - List insertList = new java.util.ArrayList<>(); - List updateList = new java.util.ArrayList<>(); - - for (MaterialMainListByDateDTO materialDTO : validMaterials) { - QmsQcMaterial existMaterial = existMaterialMap.get(materialDTO.getMaterialNo()); - if (existMaterial == null) { - // 待新增 - QmsQcMaterial newMaterial = new QmsQcMaterial() - .setMaterialNo(materialDTO.getMaterialNo()) - .setMaterialName(materialDTO.getMaterialName()) - .setMaterialDesc(materialDTO.getMaterialDesc()) - .setMaterialSpecifications(materialDTO.getMaterialSpecifications()) - .setDrawingNo(materialDTO.getDrawingNo()) - .setDrawingNoVer(materialDTO.getDrawingNoVersion()) - .setMaterialTexture(materialDTO.getMaterialTexture()) - .setMaterialCategoryCode(materialDTO.getMaterialCategoryCode()) - .setMaterialCategoryCodePathName(materialDTO.getMaterialCategoryFullName()) - .setIsStandardMaintained(false) - .setMaterialDescIsUpgrade(false) - .setCreatedType(1) // 1=系统同步 - .setCreateBy(userId) - .setCreateByName(operator) - .setCreateTime(now); - insertList.add(newMaterial); - } else { - // 待更新 - boolean descChanged = !StrUtil.equals(existMaterial.getMaterialDesc(), materialDTO.getMaterialDesc()); - existMaterial.setMaterialName(materialDTO.getMaterialName()) - .setMaterialDesc(materialDTO.getMaterialDesc()) - .setMaterialDescIsUpgrade(descChanged) - .setMaterialSpecifications(materialDTO.getMaterialSpecifications()) - .setDrawingNo(materialDTO.getDrawingNo()) - .setDrawingNoVer(materialDTO.getDrawingNoVersion()) - .setMaterialCategoryCode(materialDTO.getMaterialCategoryCode()) - .setMaterialCategoryCodePathName(materialDTO.getMaterialCategoryFullName()) - .setUpdateBy(userId) - .setUpdateByName(operator) - .setUpdateTime(now); - updateList.add(existMaterial); + // 过滤掉物料类别编码为空的记录,并按 materialNo 去重 + List validMaterials = materials.stream() + .filter(dto -> { + if (StrUtil.isBlank(dto.getMaterialCategoryCode())) { + log.warn("物料类别编码为空:{}", dto.getMaterialNo()); + return false; } - } + return true; + }) + .collect(Collectors.toMap( + MaterialMainListByDateDTO::getMaterialNo, + dto -> dto, + (existing, replacement) -> existing)) + .values() + .stream() + .toList(); - // 批量新增 - if (CollectionUtil.isNotEmpty(insertList)) { - log.info("开始新增物料,数量:{}", insertList.size()); - qcMaterialService.saveBatch(insertList); - } - // 批量更新 - if (CollectionUtil.isNotEmpty(updateList)) { - log.info("开始更新物料,数量:{}", updateList.size()); - qcMaterialService.updateBatchById(updateList); - } + if (CollectionUtil.isEmpty(validMaterials)) { + log.info("没有需要同步的物料"); + return new ProcessResult(true); + } + + // 批量查询已存在的物料,构建 materialNo -> QmsQcMaterial 映射(分批查询避免 IN 子句过长) + List materialNos = validMaterials.stream() + .map(MaterialMainListByDateDTO::getMaterialNo) + .toList(); + Map existMaterialMap = batchQueryExistMaterials(materialNos); + + List insertList = new ArrayList<>(); + List updateList = new ArrayList<>(); + + for (MaterialMainListByDateDTO materialDTO : validMaterials) { + QmsQcMaterial existMaterial = existMaterialMap.get(materialDTO.getMaterialNo()); + if (existMaterial == null) { + // 待新增 + QmsQcMaterial newMaterial = new QmsQcMaterial() + .setMaterialNo(materialDTO.getMaterialNo()) + .setMaterialName(materialDTO.getMaterialName()) + .setMaterialDesc(materialDTO.getMaterialDesc()) + .setMaterialSpecifications(materialDTO.getMaterialSpecifications()) + .setDrawingNo(materialDTO.getDrawingNo()) + .setDrawingNoVer(materialDTO.getDrawingNoVersion()) + .setMaterialTexture(materialDTO.getMaterialTexture()) + .setMaterialCategoryCode(materialDTO.getMaterialCategoryCode()) + .setMaterialCategoryCodePathName(materialDTO.getMaterialCategoryFullName()) + .setIsStandardMaintained(false) + .setMaterialDescIsUpgrade(false) + .setCreatedType(1) // 1=系统同步 + .setCreateBy(userId) + .setCreateByName(operator) + .setCreateTime(now); + insertList.add(newMaterial); + } else { + // 待更新 + boolean descChanged = !StrUtil.equals(existMaterial.getMaterialDesc(), materialDTO.getMaterialDesc()); + existMaterial.setMaterialName(materialDTO.getMaterialName()) + .setMaterialDesc(materialDTO.getMaterialDesc()) + .setMaterialDescIsUpgrade(descChanged) + .setMaterialSpecifications(materialDTO.getMaterialSpecifications()) + .setDrawingNo(materialDTO.getDrawingNo()) + .setDrawingNoVer(materialDTO.getDrawingNoVersion()) + .setMaterialTexture(materialDTO.getMaterialTexture()) + .setMaterialCategoryCode(materialDTO.getMaterialCategoryCode()) + .setMaterialCategoryCodePathName(materialDTO.getMaterialCategoryFullName()) + .setUpdateBy(userId) + .setUpdateByName(operator) + .setUpdateTime(now); + updateList.add(existMaterial); } } + + // 批量新增 + if (CollectionUtil.isNotEmpty(insertList)) { + log.info("开始新增物料,数量:{}", insertList.size()); + qcMaterialService.saveBatch(insertList); + } + // 批量更新 + if (CollectionUtil.isNotEmpty(updateList)) { + log.info("开始更新物料,数量:{}", updateList.size()); + qcMaterialService.updateBatchById(updateList); + } + return new ProcessResult(true); } catch (Exception ex) { - return new ProcessResult(false, "同步物料失败"); + return new ProcessResult(false, "同步物料失败: " + ex.getMessage()); } } + + /** + * 分批查询已存在的物料,避免 IN 子句过长 + */ + private Map batchQueryExistMaterials(List materialNos) { + Map result = new LinkedHashMap<>(); + // 每批500条,避免SQL IN子句过长 + CollUtil.split(materialNos, 500).forEach(batch -> { + Map batchMap = qcMaterialService.lambdaQuery() + .in(QmsQcMaterial::getMaterialNo, batch) + .list() + .stream() + .collect(Collectors.toMap( + QmsQcMaterial::getMaterialNo, + m -> m, + (existing, replacement) -> existing)); + result.putAll(batchMap); + }); + return result; + } }