From 5c5776961f62f1600544b80d52fb5202bded8fbc Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 17 Mar 2026 23:42:05 +0800 Subject: [PATCH] ✨ feat(mes): 添加生产任务状态校验和反馈数据验证逻辑 --- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java | 8 +------- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java | 5 +++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskService.java | 8 ++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java | 10 ++++++++++ 5 files changed, 82 insertions(+), 13 deletions(-) diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java index a712901..c7ab6b9 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java @@ -55,25 +55,18 @@ public class MesProFeedbackController { @Resource private MesProFeedbackService feedbackService; - @Resource private MesMdWorkstationService workstationService; - @Resource private MesProRouteService routeService; - @Resource private MesProProcessService processService; - @Resource private MesProWorkOrderService workOrderService; - @Resource private MesMdItemService itemService; - @Resource private MesMdUnitMeasureService unitMeasureService; - @Resource private MesProRouteProcessService routeProcessService; @@ -226,6 +219,7 @@ public class MesProFeedbackController { findAndThen(workOrderMap, vo.getWorkOrderId(), wo -> vo.setWorkOrderCode(wo.getCode()).setWorkOrderName(wo.getName())); // TODO @芋艿:task code 待 pro_task 服务迁移后补充 + // TODO @AI:貌似已经支持,可以跟进下 // 物料、计量单位 findAndThen(itemMap, vo.getItemId(), item -> vo.setItemCode(item.getCode()).setItemName(item.getName()).setItemSpec(item.getSpecification())); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java index 7b5444c..096dc6f 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java @@ -226,6 +226,7 @@ public interface ErrorCodeConstants { // ========== MES 生产管理-生产任务(1-040-503-000) ========== ErrorCode PRO_TASK_NOT_EXISTS = new ErrorCode(1_040_503_000, "生产任务不存在"); + ErrorCode PRO_TASK_ALREADY_FINISHED = new ErrorCode(1_040_503_001, "生产任务已完成或已取消,不能继续操作"); // ========== MES 生产管理-安灯呼叫配置(1-040-504-000) ========== ErrorCode PRO_ANDON_CONFIG_NOT_EXISTS = new ErrorCode(1_040_504_000, "安灯呼叫配置不存在"); @@ -245,6 +246,10 @@ public interface ErrorCodeConstants { ErrorCode PRO_FEEDBACK_STATUS_ERROR = new ErrorCode(1_040_506_005, "报工单状态不正确,无法执行此操作"); ErrorCode PRO_FEEDBACK_WORK_ORDER_NOT_CONFIRMED = new ErrorCode(1_040_506_006, "关联的工单未确认,无法创建报工"); ErrorCode PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_MISMATCH = new ErrorCode(1_040_506_007, "合格品数量与不良品数量之和必须等于报工数量"); + ErrorCode PRO_FEEDBACK_ROUTE_PROCESS_INVALID = new ErrorCode(1_040_506_008, "未找到对应的工艺工序配置,请检查工艺路线与工序"); + ErrorCode PRO_FEEDBACK_TASK_OR_ORDER_FINISHED = new ErrorCode(1_040_506_009, "当前生产任务或工单已完成,不能继续报工"); + ErrorCode PRO_FEEDBACK_QUANTITY_MUST_POSITIVE = new ErrorCode(1_040_506_010, "报工数量必须大于 0"); + ErrorCode PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED = new ErrorCode(1_040_506_011, "请输入合格品和不良品数量,且合计须大于 0"); // ========== MES 生产管理-生产流转卡(1-040-507-000) ========== ErrorCode PRO_CARD_NOT_EXISTS = new ErrorCode(1_040_507_000, "生产流转卡不存在"); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java index e7680b4..6d1e77a 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.service.pro.feedback; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; @@ -11,13 +12,17 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper; import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum; +import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService; import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService; +import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService; import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; 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.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -42,23 +47,31 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { @Resource private MesProRouteProcessService routeProcessService; + @Resource + private MesMdWorkstationService workstationService; + + @Resource + @Lazy // 避免循环依赖 + private MesProTaskService taskService; + @Override public Long createFeedback(MesProFeedbackSaveReqVO createReqVO) { - // 1. 校验工单已确认 - workOrderService.validateWorkOrderConfirmed(createReqVO.getWorkOrderId()); - // TODO @芋艿:校验 pro_task 存在且未完成(待 pro_task 服务迁移) + // 1. 校验 + validateFeedbackData(createReqVO); // 2. 插入 - MesProFeedbackDO feedback = BeanUtils.toBean(createReqVO, MesProFeedbackDO.class); - feedback.setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus()); + MesProFeedbackDO feedback = BeanUtils.toBean(createReqVO, MesProFeedbackDO.class) + .setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus()); feedbackMapper.insert(feedback); return feedback.getId(); } @Override public void updateFeedback(MesProFeedbackSaveReqVO updateReqVO) { - // 1. 校验存在 + 草稿状态 + // 1.1 校验存在 + 草稿状态 validateFeedbackStatusPrepare(updateReqVO.getId()); + // 1.2 校验业务数据 + validateFeedbackData(updateReqVO); // 2. 更新 MesProFeedbackDO updateObj = BeanUtils.toBean(updateReqVO, MesProFeedbackDO.class); @@ -173,6 +186,45 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { } /** + * 校验报工单的业务数据(创建 & 修改共用) + * + * @param reqVO 报工请求 + */ + private void validateFeedbackData(MesProFeedbackSaveReqVO reqVO) { + // 1. 校验工作站存在 + workstationService.validateWorkstationExists(reqVO.getWorkstationId()); + + // 2.1 校验工艺路线 + 工序配置有效 + MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId( + reqVO.getRouteId(), reqVO.getProcessId()); + if (routeProcess == null) { + throw exception(PRO_FEEDBACK_ROUTE_PROCESS_INVALID); + } + // 2.2 校验数量 + boolean checkFlag = Boolean.TRUE.equals(routeProcess.getCheckFlag()); + if (checkFlag) { + // 需要检验:只需填报工数量,且必须 > 0 + if (reqVO.getFeedbackQuantity() == null + || reqVO.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) { + throw exception(PRO_FEEDBACK_QUANTITY_MUST_POSITIVE); + } + } else { + // 不需检验:需填合格品 + 不良品数量,合计 > 0 + BigDecimal qualified = ObjectUtil.defaultIfNull(reqVO.getQualifiedQuantity(), BigDecimal.ZERO); + BigDecimal unqualified = ObjectUtil.defaultIfNull(reqVO.getUnqualifiedQuantity(), BigDecimal.ZERO); + if (qualified.add(unqualified).compareTo(BigDecimal.ZERO) <= 0) { + throw exception(PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED); + } + } + + // 3. 校验工单已确认 + workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId()); + + // 4. 校验任务存在且未终态(已完成/已取消) + taskService.validateTaskNotFinished(reqVO.getTaskId()); + } + + /** * 获取指定工艺路线中指定工序的 checkFlag * * @param routeId 工艺路线编号 diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskService.java index 10addca..adfdbfe 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskService.java @@ -82,6 +82,14 @@ public interface MesProTaskService { MesProTaskDO validateTaskExists(Long id); /** + * 校验任务存在且未完成(非终态) + * + * @param id 编号 + * @return 生产任务 + */ + MesProTaskDO validateTaskNotFinished(Long id); + + /** * 获得生产任务列表 * * @param ids 编号列表 diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java index 742026f..d4fe5bf 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java @@ -29,6 +29,7 @@ import java.util.List; 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.PRO_TASK_ALREADY_FINISHED; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_TASK_NOT_EXISTS; /** @@ -152,6 +153,15 @@ public class MesProTaskServiceImpl implements MesProTaskService { } @Override + public MesProTaskDO validateTaskNotFinished(Long id) { + MesProTaskDO task = validateTaskExists(id); + if (MesProTaskStatusEnum.isEndStatus(task.getStatus())) { + throw exception(PRO_TASK_ALREADY_FINISHED); + } + return task; + } + + @Override public List getTaskList(Collection ids) { return taskMapper.selectByIds(ids); } -- libgit2 0.21.4