diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/defect/MesQcDefectRecordController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/defect/MesQcDefectRecordController.java index 929e5d2..e10b39e 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/defect/MesQcDefectRecordController.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/defect/MesQcDefectRecordController.java @@ -28,17 +28,17 @@ public class MesQcDefectRecordController { @Resource private MesQcDefectRecordService defectRecordService; - // TODO @AI:使用 mes:qc-record:create 权限标识先;不要搞太复杂;当然,也写个 todo @芋艿:说下这个情况 + // TODO @芋艿:说下 mes:qc-record 这个权限标识的情况 @PostMapping("/create") @Operation(summary = "创建质检缺陷记录") - @PreAuthorize("@ss.hasPermission('mes:qc-defect-record:create')") + @PreAuthorize("@ss.hasPermission('mes:qc-record:create')") public CommonResult createDefectRecord(@Valid @RequestBody MesQcDefectRecordSaveReqVO createReqVO) { return success(defectRecordService.createDefectRecord(createReqVO)); } @PutMapping("/update") @Operation(summary = "更新质检缺陷记录") - @PreAuthorize("@ss.hasPermission('mes:qc-defect-record:update')") + @PreAuthorize("@ss.hasPermission('mes:qc-record:update')") public CommonResult updateDefectRecord(@Valid @RequestBody MesQcDefectRecordSaveReqVO updateReqVO) { defectRecordService.updateDefectRecord(updateReqVO); return success(true); @@ -47,7 +47,7 @@ public class MesQcDefectRecordController { @DeleteMapping("/delete") @Operation(summary = "删除质检缺陷记录") @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('mes:qc-defect-record:update')") + @PreAuthorize("@ss.hasPermission('mes:qc-record:update')") public CommonResult deleteDefectRecord(@RequestParam("id") Long id) { defectRecordService.deleteDefectRecord(id); return success(true); @@ -55,7 +55,7 @@ public class MesQcDefectRecordController { @GetMapping("/page") @Operation(summary = "获得质检缺陷记录分页") - @PreAuthorize("@ss.hasPermission('mes:qc-defect-record:query')") + @PreAuthorize("@ss.hasPermission('mes:qc-record:query')") public CommonResult> getDefectRecordPage(@Valid MesQcDefectRecordPageReqVO pageReqVO) { PageResult pageResult = defectRecordService.getDefectRecordPage(pageReqVO); return success(BeanUtils.toBean(pageResult, MesQcDefectRecordRespVO.class)); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/defect/MesQcDefectRecordServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/defect/MesQcDefectRecordServiceImpl.java index 0a7b529..b7276b3 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/defect/MesQcDefectRecordServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/defect/MesQcDefectRecordServiceImpl.java @@ -1,27 +1,20 @@ package cn.iocoder.yudao.module.mes.service.qc.defect; -import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.controller.admin.qc.defect.vo.MesQcDefectRecordPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.qc.defect.vo.MesQcDefectRecordSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defect.MesQcDefectRecordDO; -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO; -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO; import cn.iocoder.yudao.module.mes.dal.mysql.qc.defect.MesQcDefectRecordMapper; -import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcMapper; -import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum; import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcLineService; +import cn.iocoder.yudao.module.mes.service.qc.lqc.MesQcIqcService; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -40,9 +33,9 @@ public class MesQcDefectRecordServiceImpl implements MesQcDefectRecordService { @Resource private MesQcDefectRecordMapper defectRecordMapper; - // TODO @AI:不要调用 mapper,调用对方的 service; @Resource - private MesQcIqcMapper iqcMapper; + @Lazy + private MesQcIqcService iqcService; @Resource @Lazy private MesQcIqcLineService iqcLineService; @@ -50,9 +43,8 @@ public class MesQcDefectRecordServiceImpl implements MesQcDefectRecordService { @Override @Transactional(rollbackFor = Exception.class) public Long createDefectRecord(MesQcDefectRecordSaveReqVO createReqVO) { - // 1. 校验主表和行表存在 - validateQcExists(createReqVO.getQcType(), createReqVO.getQcId()); - validateQcLineExists(createReqVO.getQcType(), createReqVO.getLineId()); + // 1. 校验检验单和检验行存在 + validateQcAndLineExists(createReqVO.getQcType(), createReqVO.getQcId(), createReqVO.getLineId()); // 2. 插入 MesQcDefectRecordDO record = BeanUtils.toBean(createReqVO, MesQcDefectRecordDO.class); @@ -102,25 +94,10 @@ public class MesQcDefectRecordServiceImpl implements MesQcDefectRecordService { // ==================== 校验方法 ==================== - // TODO @AI:validateQcExists、validateQcLineExists 合并成一个方法;然后调用对应的 service 方法; - private void validateQcExists(Integer qcType, Long qcId) { + private void validateQcAndLineExists(Integer qcType, Long qcId, Long lineId) { if (Objects.equals(qcType, MesQcTypeEnum.IQC.getType())) { - if (iqcMapper.selectById(qcId) == null) { - throw exception(QC_IQC_NOT_EXISTS); - } - } else { - // 后续扩展:IPQC、OQC、RQC - throw exception(QC_DEFECT_RECORD_QC_TYPE_UNSUPPORTED); - } - } - - // TODO @AI:去掉这个,相信调用方 - private void validateQcLineExists(Integer qcType, Long lineId) { - if (Objects.equals(qcType, MesQcTypeEnum.IQC.getType())) { - MesQcIqcLineDO line = iqcLineService.getIqcLine(lineId); - if (line == null) { - throw exception(QC_IQC_LINE_NOT_EXISTS); - } + iqcService.validateIqcExists(qcId); + iqcLineService.validateIqcLineExists(lineId); } else { // 后续扩展:IPQC、OQC、RQC throw exception(QC_DEFECT_RECORD_QC_TYPE_UNSUPPORTED); @@ -138,91 +115,19 @@ public class MesQcDefectRecordServiceImpl implements MesQcDefectRecordService { // ==================== 缺陷统计 ==================== /** - * 重新计算缺陷统计(行级 + 主表级) + * 重新计算缺陷统计(行级 + 主表级),委托给对应的检验 Service * * @param qcType 检验类型 * @param qcId 检验单 ID */ - @SuppressWarnings("DuplicatedCode") private void recalculateDefectStats(Integer qcType, Long qcId) { - // 1. 查询所有缺陷记录 List records = defectRecordMapper.selectListByQcTypeAndQcId(qcType, qcId); - if (Objects.equals(qcType, MesQcTypeEnum.IQC.getType())) { - // TODO @AI:直接调用 iqcservice 方法;qcId、records - recalculateIqcDefectStats(qcId, records); + iqcService.recalculateDefectStats(qcId, records); } else { // 后续扩展:IPQC、OQC、RQC throw exception(QC_DEFECT_RECORD_QC_TYPE_UNSUPPORTED); } } - /** - * IQC 缺陷统计重算 - */ - private void recalculateIqcDefectStats(Long qcId, List records) { - // 1. 按行汇总缺陷数量,批量更新 - // TODO @AI:1 这块的逻辑,放到 iqcLineService 里,使用 qcId、records; - List lines = iqcLineService.selectListByIqcId(qcId); - List updateLines = new ArrayList<>(); - for (MesQcIqcLineDO line : lines) { - int critical = 0, major = 0, minor = 0; - for (MesQcDefectRecordDO record : records) { - if (ObjUtil.notEqual(record.getLineId(), line.getId())) { - continue; - } - int quantity = ObjUtil.defaultIfNull(record.getQuantity(), 1); - if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.CRITICAL.getType())) { - critical += quantity; - } else if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.MAJOR.getType())) { - major += quantity; - } else if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.MINOR.getType())) { - minor += quantity; - } else { - throw exception(QC_DEFECT_RECORD_LEVEL_UNKNOWN); - } - } - updateLines.add(new MesQcIqcLineDO().setId(line.getId()) - .setCriticalQuantity(critical).setMajorQuantity(major).setMinorQuantity(minor)); - } - iqcLineService.batchUpdateDefectStats(updateLines); - - // 2. 汇总主表的缺陷数量 - // TODO @AI:2-4 这块的逻辑,放到 iqcService 里,使用 qcId、records; - int totalCritical = 0, totalMajor = 0, totalMinor = 0; - for (MesQcDefectRecordDO record : records) { - int quantity = ObjUtil.defaultIfNull(record.getQuantity(), 1); - if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.CRITICAL.getType())) { - totalCritical += quantity; - } else if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.MAJOR.getType())) { - totalMajor += quantity; - } else if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.MINOR.getType())) { - totalMinor += quantity; - } else { - throw exception(QC_DEFECT_RECORD_LEVEL_UNKNOWN); - } - } - - // 3. 计算缺陷率 - MesQcIqcDO iqc = iqcMapper.selectById(qcId); - BigDecimal criticalRate = BigDecimal.ZERO; - BigDecimal majorRate = BigDecimal.ZERO; - BigDecimal minorRate = BigDecimal.ZERO; - if (iqc != null && iqc.getCheckQuantity() != null && iqc.getCheckQuantity() > 0) { - BigDecimal checkQty = BigDecimal.valueOf(iqc.getCheckQuantity()); - criticalRate = BigDecimal.valueOf(totalCritical).multiply(BigDecimal.valueOf(100)) - .divide(checkQty, 2, RoundingMode.HALF_UP); - majorRate = BigDecimal.valueOf(totalMajor).multiply(BigDecimal.valueOf(100)) - .divide(checkQty, 2, RoundingMode.HALF_UP); - minorRate = BigDecimal.valueOf(totalMinor).multiply(BigDecimal.valueOf(100)) - .divide(checkQty, 2, RoundingMode.HALF_UP); - } - - // 4. 更新主表 - MesQcIqcDO updateIqc = new MesQcIqcDO().setId(qcId) - .setCriticalQuantity(totalCritical).setMajorQuantity(totalMajor).setMinorQuantity(totalMinor) - .setCriticalRate(criticalRate).setMajorRate(majorRate).setMinorRate(minorRate); - iqcMapper.updateById(updateIqc); - } - } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineService.java index 10b8906..28e05cd 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineService.java @@ -4,6 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defect.MesQcDefectRecordDO; + import java.util.List; /** @@ -14,6 +16,14 @@ import java.util.List; public interface MesQcIqcLineService { /** + * 校验来料检验行存在 + * + * @param id 编号 + * @return 来料检验行 + */ + MesQcIqcLineDO validateIqcLineExists(Long id); + + /** * 获得来料检验行 * * @param id 编号 @@ -30,14 +40,6 @@ public interface MesQcIqcLineService { PageResult getIqcLinePage(MesQcIqcLinePageReqVO pageReqVO); /** - * 根据来料检验单 ID 查询所有行 - * - * @param iqcId 来料检验单 ID - * @return 行列表 - */ - List selectListByIqcId(Long iqcId); - - /** * 从模板指标自动生成检验行 * * @param iqcId 来料检验单 ID @@ -46,11 +48,12 @@ public interface MesQcIqcLineService { void createLinesFromTemplate(Long iqcId, Long templateId); /** - * 批量更新行的缺陷统计数量 + * 根据缺陷记录重新计算各行的缺陷统计数量 * - * @param lines 待更新的行列表(只需设置 id、criticalQuantity、majorQuantity、minorQuantity) + * @param iqcId 来料检验单 ID + * @param records 缺陷记录列表 */ - void batchUpdateDefectStats(List lines); + void recalculateLineDefectStats(Long iqcId, List records); /** * 根据来料检验单 ID 级联删除所有行 diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineServiceImpl.java index 0cb2720..14066a1 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcLineServiceImpl.java @@ -1,18 +1,26 @@ package cn.iocoder.yudao.module.mes.service.qc.lqc; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defect.MesQcDefectRecordDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcLineDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateIndicatorDO; import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcLineMapper; import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateIndicatorMapper; +import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; /** * MES 来料检验单行 Service 实现类 @@ -29,6 +37,15 @@ public class MesQcIqcLineServiceImpl implements MesQcIqcLineService { private MesQcTemplateIndicatorMapper templateIndicatorMapper; @Override + public MesQcIqcLineDO validateIqcLineExists(Long id) { + MesQcIqcLineDO line = iqcLineMapper.selectById(id); + if (line == null) { + throw exception(QC_IQC_LINE_NOT_EXISTS); + } + return line; + } + + @Override public MesQcIqcLineDO getIqcLine(Long id) { return iqcLineMapper.selectById(id); } @@ -39,11 +56,6 @@ public class MesQcIqcLineServiceImpl implements MesQcIqcLineService { } @Override - public List selectListByIqcId(Long iqcId) { - return iqcLineMapper.selectListByIqcId(iqcId); - } - - @Override public void createLinesFromTemplate(Long iqcId, Long templateId) { List indicators = templateIndicatorMapper.selectListByTemplateId(templateId); List lines = convertList(indicators, indicator -> new MesQcIqcLineDO() @@ -57,9 +69,34 @@ public class MesQcIqcLineServiceImpl implements MesQcIqcLineService { } @Override - public void batchUpdateDefectStats(List lines) { + public void recalculateLineDefectStats(Long iqcId, List records) { + List lines = iqcLineMapper.selectListByIqcId(iqcId); + if (CollUtil.isEmpty(lines)) { + return; + } + List updateLines = new ArrayList<>(lines.size()); for (MesQcIqcLineDO line : lines) { - iqcLineMapper.updateById(line); + int critical = 0, major = 0, minor = 0; + for (MesQcDefectRecordDO record : records) { + if (ObjUtil.notEqual(record.getLineId(), line.getId())) { + continue; + } + int quantity = ObjUtil.defaultIfNull(record.getQuantity(), 1); + if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.CRITICAL.getType())) { + critical += quantity; + } else if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.MAJOR.getType())) { + major += quantity; + } else if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.MINOR.getType())) { + minor += quantity; + } else { + throw exception(QC_DEFECT_RECORD_LEVEL_UNKNOWN); + } + } + updateLines.add(new MesQcIqcLineDO().setId(line.getId()) + .setCriticalQuantity(critical).setMajorQuantity(major).setMinorQuantity(minor)); + } + for (MesQcIqcLineDO updateLine : updateLines) { + iqcLineMapper.updateById(updateLine); } } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcService.java index d84a14d..613a745 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcService.java @@ -3,9 +3,12 @@ package cn.iocoder.yudao.module.mes.service.qc.lqc; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defect.MesQcDefectRecordDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO; import jakarta.validation.Valid; +import java.util.List; + /** * MES 来料检验单(IQC) Service 接口 * @@ -43,6 +46,14 @@ public interface MesQcIqcService { void deleteIqc(Long id); /** + * 校验来料检验单存在 + * + * @param id 编号 + * @return 来料检验单 + */ + MesQcIqcDO validateIqcExists(Long id); + + /** * 获得来料检验单 * * @param id 编号 @@ -58,4 +69,12 @@ public interface MesQcIqcService { */ PageResult getIqcPage(MesQcIqcPageReqVO pageReqVO); + /** + * 根据缺陷记录重新计算主表的缺陷统计(含行级下沉) + * + * @param iqcId 来料检验单 ID + * @param records 缺陷记录列表 + */ + void recalculateDefectStats(Long iqcId, List records); + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcServiceImpl.java index 70f99e5..93145a5 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/lqc/MesQcIqcServiceImpl.java @@ -6,10 +6,12 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defect.MesQcDefectRecordDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.lqc.MesQcIqcDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO; import cn.iocoder.yudao.module.mes.dal.mysql.qc.lqc.MesQcIqcMapper; +import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum; import cn.iocoder.yudao.module.mes.enums.qc.MesQcIqcStatusEnum; import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; import cn.iocoder.yudao.module.mes.service.qc.defect.MesQcDefectRecordService; @@ -19,6 +21,11 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import java.util.Objects; + import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; @@ -121,6 +128,15 @@ public class MesQcIqcServiceImpl implements MesQcIqcService { defectRecordService.deleteByQcTypeAndQcId(MesQcTypeEnum.IQC.getType(), id); } + @Override + public MesQcIqcDO validateIqcExists(Long id) { + MesQcIqcDO iqc = iqcMapper.selectById(id); + if (iqc == null) { + throw exception(QC_IQC_NOT_EXISTS); + } + return iqc; + } + /** * 校验来料检验单存在且为草稿状态 * @@ -128,10 +144,7 @@ public class MesQcIqcServiceImpl implements MesQcIqcService { * @return 来料检验单 */ private MesQcIqcDO validateIqcStatusPrepare(Long id) { - MesQcIqcDO iqc = iqcMapper.selectById(id); - if (iqc == null) { - throw exception(QC_IQC_NOT_EXISTS); - } + MesQcIqcDO iqc = validateIqcExists(id); if (ObjUtil.notEqual(iqc.getStatus(), MesQcIqcStatusEnum.PREPARE.getType())) { throw exception(QC_IQC_NOT_PREPARE); } @@ -158,4 +171,45 @@ public class MesQcIqcServiceImpl implements MesQcIqcService { return iqcMapper.selectPage(pageReqVO); } + @Override + public void recalculateDefectStats(Long iqcId, List records) { + // 1. 行级缺陷统计 + iqcLineService.recalculateLineDefectStats(iqcId, records); + + // 2.1 汇总主表的缺陷数量 + int totalCritical = 0, totalMajor = 0, totalMinor = 0; + for (MesQcDefectRecordDO record : records) { + int quantity = ObjUtil.defaultIfNull(record.getQuantity(), 1); + if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.CRITICAL.getType())) { + totalCritical += quantity; + } else if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.MAJOR.getType())) { + totalMajor += quantity; + } else if (Objects.equals(record.getLevel(), MesQcDefectLevelEnum.MINOR.getType())) { + totalMinor += quantity; + } else { + throw exception(QC_DEFECT_RECORD_LEVEL_UNKNOWN); + } + } + // 2.2 计算缺陷率 + MesQcIqcDO iqc = validateIqcExists(iqcId); + BigDecimal criticalRate = BigDecimal.ZERO; + BigDecimal majorRate = BigDecimal.ZERO; + BigDecimal minorRate = BigDecimal.ZERO; + if (iqc.getCheckQuantity() != null && iqc.getCheckQuantity() > 0) { + BigDecimal checkQty = BigDecimal.valueOf(iqc.getCheckQuantity()); + criticalRate = BigDecimal.valueOf(totalCritical).multiply(BigDecimal.valueOf(100)) + .divide(checkQty, 2, RoundingMode.HALF_UP); + majorRate = BigDecimal.valueOf(totalMajor).multiply(BigDecimal.valueOf(100)) + .divide(checkQty, 2, RoundingMode.HALF_UP); + minorRate = BigDecimal.valueOf(totalMinor).multiply(BigDecimal.valueOf(100)) + .divide(checkQty, 2, RoundingMode.HALF_UP); + } + + // 3. 更新主表 + MesQcIqcDO updateIqc = new MesQcIqcDO().setId(iqcId) + .setCriticalQuantity(totalCritical).setMajorQuantity(totalMajor).setMinorQuantity(totalMinor) + .setCriticalRate(criticalRate).setMajorRate(majorRate).setMinorRate(minorRate); + iqcMapper.updateById(updateIqc); + } + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateServiceImpl.java index 15cca8e..ed2fbd6 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateServiceImpl.java @@ -25,8 +25,11 @@ import org.springframework.validation.annotation.Validated; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.findFirst; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; /** @@ -116,15 +119,11 @@ public class MesQcTemplateServiceImpl implements MesQcTemplateService { return null; } // 1.2 批量查模板,筛选 types 包含给定 qcType 的第一个 - // TODO @AI:convertSet; - List templateIds = templateItems.stream() - .map(MesQcTemplateItemDO::getTemplateId).distinct().toList(); - List templates = templateMapper.selectByIds(templateIds); - - // 2. 筛选 types 包含给定 qcType 的第一个 TODO @AI:findOne; - return templates.stream() - .filter(t -> CollUtil.contains(t.getTypes(), qcType)) - .findFirst().orElse(null); + List templates = templateMapper.selectByIds( + convertSet(templateItems, MesQcTemplateItemDO::getTemplateId)); + + // 2. 筛选 types 包含给定 qcType 的第一个 + return findFirst(templates, template -> CollUtil.contains(template.getTypes(), qcType)); } @Override