yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateItemController.java
@@ -28,6 +28,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; @@ -91,13 +92,22 @@ } @GetMapping("/list-by-item-and-type") @Operation(summary = "根据物料或工单/任务和检测种类获取可用质检方案") @Operation(summary = "根据物料或工单/任务和检测种类获取可用质检方案(未指定物料/工单/任务时返回该检测种类下全部启用方案)") @PreAuthorize("@ss.hasPermission('mes:qc-template:query')") public CommonResult<List<MesQcTemplateItemOptionRespVO>> getTemplateItemOptionList( @RequestParam(value = "qcType", required = false) Integer qcType, @RequestParam(value = "itemId", required = false) Long itemId, @RequestParam(value = "workOrderId", required = false) Long workOrderId, @RequestParam(value = "taskId", required = false) Long taskId) { // 未指定物料/工单/任务时,按检测种类返回全部启用的质检方案(不限制产品物料关联) if (itemId == null && workOrderId == null && taskId == null && qcType != null) { List<MesQcTemplateItemOptionRespVO> options = templateService.getEnabledTemplateListByType(qcType) .stream().map(template -> new MesQcTemplateItemOptionRespVO() .setTemplateId(template.getId()).setTemplateCode(template.getCode()) .setTemplateName(template.getName())) .collect(Collectors.toList()); return success(options); } List<MesQcTemplateItemDO> list = templateItemService.getTemplateItemList( itemId, qcType, workOrderId, taskId); if (CollUtil.isEmpty(list)) { yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/MesWmProductIssueSaveReqVO.java
@@ -22,8 +22,7 @@ @NotBlank(message = "领料单名称不能为空") private String name; @Schema(description = "生产任务 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "生产任务 ID 不能为空") @Schema(description = "生产任务 ID", example = "1") private Long taskId; @Schema(description = "生产工单 ID", example = "1") yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -393,6 +393,8 @@ ErrorCode QC_NO_TEMPLATE_FOR_ITEM = new ErrorCode(1_040_603_008, "物料【{}】未配置 IQC 检测模板,请先在质量管理中配置"); ErrorCode QC_IQC_SOURCE_DOC_PARAMS_MISSING = new ErrorCode(1_040_603_006, "来源单据类型非空时,来源单据 ID 和来源单据行 ID 不能为空"); ErrorCode QC_IQC_CHECK_RESULT_EMPTY = new ErrorCode(1_040_603_007, "完成检验单前,检测结果必须填写"); ErrorCode QC_IQC_TEMPLATE_IS_DISABLE = new ErrorCode(1_040_603_009, "所选质检方案【{}】已禁用,请重新选择已启用的质检方案"); ErrorCode QC_IQC_TEMPLATE_TYPE_NOT_MATCH = new ErrorCode(1_040_603_010, "所选质检方案【{}】的检测种类不包含来料检验,请重新选择检测种类包含来料检验的质检方案"); // ========== MES 质量管理-来料检验行(1-040-603-100) ========== ErrorCode QC_IQC_LINE_NOT_EXISTS = new ErrorCode(1_040_603_100, "来料检验行不存在"); yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java
@@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcImportExcelVO; import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO; @@ -16,6 +17,7 @@ import cn.iocoder.yudao.module.mes.service.qc.imports.MesQcImportHelper; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.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.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO; import cn.iocoder.yudao.module.mes.dal.mysql.qc.iqc.MesQcIqcMapper; @@ -27,6 +29,7 @@ import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService; import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService; import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService; import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateService; import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService; import cn.iocoder.yudao.module.mes.service.wm.outsourcereceipt.MesWmOutsourceReceiptService; import cn.iocoder.yudao.module.mes.controller.admin.qc.ncr.vo.MesQcNcrSaveReqVO; @@ -65,6 +68,8 @@ @Resource private MesQcTemplateItemService templateItemService; @Resource private MesQcTemplateService templateService; @Resource private MesQcIqcLineService iqcLineService; @Resource private MesQcDefectRecordService defectRecordService; @@ -101,22 +106,25 @@ // 1.2 校验来源单据参数,并验证数据存在 String sourceDocCode = validateAndGetSourceDocCode( createReqVO.getSourceDocType(), createReqVO.getSourceDocId(), createReqVO.getSourceLineId()); // 1.3 根据产品 + IQC 类型查找可用质检方案(支持前端显式指定) List<MesQcTemplateItemDO> templateItems = templateItemService.getTemplateItemList( createReqVO.getItemId(), MesQcTypeEnum.IQC.getType(), null, null); if (CollUtil.isEmpty(templateItems)) { throw exception(QC_NO_TEMPLATE); } MesQcTemplateItemDO templateItem = templateItems.get(0); // 1.3 确定质检方案:显式指定时校验方案本身可用(不要求与产品物料绑定);未指定时按物料已绑定方案兜底 Long templateId; if (createReqVO.getTemplateId() != null) { templateItem = templateItems.stream() .filter(item -> Objects.equals(item.getTemplateId(), createReqVO.getTemplateId())) .findFirst().orElse(null); if (templateItem == null) { throw exception(QC_NO_TEMPLATE); // 指定了方案但不在匹配列表中,拒绝 MesQcTemplateDO template = templateService.getTemplate(createReqVO.getTemplateId()); if (template == null) { throw new ServiceException(QC_TEMPLATE_NOT_EXISTS.getCode(), StrUtil.format( "所选质检方案不存在(ID={}),可能已被删除,请刷新后重新选择质检方案", createReqVO.getTemplateId())); } if (!CommonStatusEnum.isEnable(template.getStatus())) { throw exception(QC_IQC_TEMPLATE_IS_DISABLE, template.getName()); } if (!CollUtil.contains(template.getTypes(), MesQcTypeEnum.IQC.getType())) { throw exception(QC_IQC_TEMPLATE_TYPE_NOT_MATCH, template.getName()); } templateId = template.getId(); } else { templateId = templateItemService.getRequiredTemplateByItemIdAndType( createReqVO.getItemId(), MesQcTypeEnum.IQC.getType()).getTemplateId(); } Long templateId = templateItem.getTemplateId(); // 2. 插入主表 MesQcIqcDO iqc = BeanUtils.toBean(createReqVO, MesQcIqcDO.class) yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateService.java
@@ -90,4 +90,12 @@ */ MesQcTemplateDO validateTemplateExists(Long id); /** * 获得指定检测种类的启用质检方案列表(未指定物料等上下文时的下拉选择) * * @param qcType 检测种类 * @return 质检方案列表 */ List<MesQcTemplateDO> getEnabledTemplateListByType(Integer qcType); } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateServiceImpl.java
@@ -2,6 +2,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 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.template.vo.MesQcTemplatePageReqVO; @@ -17,6 +18,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; @@ -119,5 +121,13 @@ return templateMapper.selectByIds(ids); } @Override public List<MesQcTemplateDO> getEnabledTemplateListByType(Integer qcType) { return templateMapper.selectList().stream() .filter(template -> CommonStatusEnum.isEnable(template.getStatus()) && CollUtil.contains(template.getTypes(), qcType)) .collect(Collectors.toList()); } } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
@@ -91,11 +91,11 @@ validateProductIssueSaveData(createReqVO); // 2. 从 task 自动带入 workOrderId 和 workstationId MesProTaskDO task = taskService.validateTaskExists(createReqVO.getTaskId()); if (createReqVO.getWorkOrderId() == null) { MesProTaskDO task = createReqVO.getTaskId() != null ? taskService.validateTaskExists(createReqVO.getTaskId()) : null; if (task != null && createReqVO.getWorkOrderId() == null) { createReqVO.setWorkOrderId(task.getWorkOrderId()); } if (createReqVO.getWorkstationId() == null) { if (task != null && createReqVO.getWorkstationId() == null) { createReqVO.setWorkstationId(task.getWorkstationId()); } @@ -115,11 +115,11 @@ validateProductIssueSaveData(updateReqVO); // 2. 从 task 自动带入 workOrderId 和 workstationId MesProTaskDO task = taskService.validateTaskExists(updateReqVO.getTaskId()); if (updateReqVO.getWorkOrderId() == null) { MesProTaskDO task = updateReqVO.getTaskId() != null ? taskService.validateTaskExists(updateReqVO.getTaskId()) : null; if (task != null && updateReqVO.getWorkOrderId() == null) { updateReqVO.setWorkOrderId(task.getWorkOrderId()); } if (updateReqVO.getWorkstationId() == null) { if (task != null && updateReqVO.getWorkstationId() == null) { updateReqVO.setWorkstationId(task.getWorkstationId()); } @@ -398,10 +398,10 @@ */ private void validateProductIssueSaveData(MesWmProductIssueSaveReqVO reqVO) { validateCodeUnique(reqVO.getId(), reqVO.getCode()); // 校验 task 存在 MesProTaskDO task = taskService.validateTaskExists(reqVO.getTaskId()); // 校验 task 关联的工单已确认 Long workOrderId = reqVO.getWorkOrderId() != null ? reqVO.getWorkOrderId() : task.getWorkOrderId(); // 校验 task 存在(生产任务非必填,未选时跳过) MesProTaskDO task = reqVO.getTaskId() != null ? taskService.validateTaskExists(reqVO.getTaskId()) : null; // 校验关联的工单已确认 Long workOrderId = reqVO.getWorkOrderId() != null ? reqVO.getWorkOrderId() : (task != null ? task.getWorkOrderId() : null); if (workOrderId != null) { workOrderService.validateWorkOrderConfirmed(workOrderId); }