Commit 5c5776961f62f1600544b80d52fb5202bded8fbc

Authored by YunaiV
1 parent 5c60fab8

✨ feat(mes): 添加生产任务状态校验和反馈数据验证逻辑

新增对生产任务状态的校验,确保任务未完成时才能进行报工操作。同时,优化报工数据的验证逻辑,确保输入的数量符合业务要求,提升系统的健壮性和用户体验。
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java
... ... @@ -55,25 +55,18 @@ public class MesProFeedbackController {
55 55  
56 56 @Resource
57 57 private MesProFeedbackService feedbackService;
58   -
59 58 @Resource
60 59 private MesMdWorkstationService workstationService;
61   -
62 60 @Resource
63 61 private MesProRouteService routeService;
64   -
65 62 @Resource
66 63 private MesProProcessService processService;
67   -
68 64 @Resource
69 65 private MesProWorkOrderService workOrderService;
70   -
71 66 @Resource
72 67 private MesMdItemService itemService;
73   -
74 68 @Resource
75 69 private MesMdUnitMeasureService unitMeasureService;
76   -
77 70 @Resource
78 71 private MesProRouteProcessService routeProcessService;
79 72  
... ... @@ -226,6 +219,7 @@ public class MesProFeedbackController {
226 219 findAndThen(workOrderMap, vo.getWorkOrderId(), wo ->
227 220 vo.setWorkOrderCode(wo.getCode()).setWorkOrderName(wo.getName()));
228 221 // TODO @芋艿:task code 待 pro_task 服务迁移后补充
  222 + // TODO @AI:貌似已经支持,可以跟进下
229 223 // 物料、计量单位
230 224 findAndThen(itemMap, vo.getItemId(), item ->
231 225 vo.setItemCode(item.getCode()).setItemName(item.getName()).setItemSpec(item.getSpecification()));
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
... ... @@ -226,6 +226,7 @@ public interface ErrorCodeConstants {
226 226  
227 227 // ========== MES 生产管理-生产任务(1-040-503-000) ==========
228 228 ErrorCode PRO_TASK_NOT_EXISTS = new ErrorCode(1_040_503_000, "生产任务不存在");
  229 + ErrorCode PRO_TASK_ALREADY_FINISHED = new ErrorCode(1_040_503_001, "生产任务已完成或已取消,不能继续操作");
229 230  
230 231 // ========== MES 生产管理-安灯呼叫配置(1-040-504-000) ==========
231 232 ErrorCode PRO_ANDON_CONFIG_NOT_EXISTS = new ErrorCode(1_040_504_000, "安灯呼叫配置不存在");
... ... @@ -245,6 +246,10 @@ public interface ErrorCodeConstants {
245 246 ErrorCode PRO_FEEDBACK_STATUS_ERROR = new ErrorCode(1_040_506_005, "报工单状态不正确,无法执行此操作");
246 247 ErrorCode PRO_FEEDBACK_WORK_ORDER_NOT_CONFIRMED = new ErrorCode(1_040_506_006, "关联的工单未确认,无法创建报工");
247 248 ErrorCode PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_MISMATCH = new ErrorCode(1_040_506_007, "合格品数量与不良品数量之和必须等于报工数量");
  249 + ErrorCode PRO_FEEDBACK_ROUTE_PROCESS_INVALID = new ErrorCode(1_040_506_008, "未找到对应的工艺工序配置,请检查工艺路线与工序");
  250 + ErrorCode PRO_FEEDBACK_TASK_OR_ORDER_FINISHED = new ErrorCode(1_040_506_009, "当前生产任务或工单已完成,不能继续报工");
  251 + ErrorCode PRO_FEEDBACK_QUANTITY_MUST_POSITIVE = new ErrorCode(1_040_506_010, "报工数量必须大于 0");
  252 + ErrorCode PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED = new ErrorCode(1_040_506_011, "请输入合格品和不良品数量,且合计须大于 0");
248 253  
249 254 // ========== MES 生产管理-生产流转卡(1-040-507-000) ==========
250 255 ErrorCode PRO_CARD_NOT_EXISTS = new ErrorCode(1_040_507_000, "生产流转卡不存在");
... ...
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;
2 2  
3 3 import cn.hutool.core.util.BooleanUtil;
4 4 import cn.hutool.core.util.ObjUtil;
  5 +import cn.hutool.core.util.ObjectUtil;
5 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 8 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
... ... @@ -11,13 +12,17 @@ import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
11 12 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
12 13 import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper;
13 14 import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum;
  15 +import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
14 16 import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
  17 +import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
15 18 import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
16 19 import jakarta.annotation.Resource;
  20 +import org.springframework.context.annotation.Lazy;
17 21 import org.springframework.stereotype.Service;
18 22 import org.springframework.transaction.annotation.Transactional;
19 23 import org.springframework.validation.annotation.Validated;
20 24  
  25 +import java.math.BigDecimal;
21 26 import java.time.LocalDateTime;
22 27  
23 28 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
... ... @@ -42,23 +47,31 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService {
42 47 @Resource
43 48 private MesProRouteProcessService routeProcessService;
44 49  
  50 + @Resource
  51 + private MesMdWorkstationService workstationService;
  52 +
  53 + @Resource
  54 + @Lazy // 避免循环依赖
  55 + private MesProTaskService taskService;
  56 +
45 57 @Override
46 58 public Long createFeedback(MesProFeedbackSaveReqVO createReqVO) {
47   - // 1. 校验工单已确认
48   - workOrderService.validateWorkOrderConfirmed(createReqVO.getWorkOrderId());
49   - // TODO @芋艿:校验 pro_task 存在且未完成(待 pro_task 服务迁移)
  59 + // 1. 校验
  60 + validateFeedbackData(createReqVO);
50 61  
51 62 // 2. 插入
52   - MesProFeedbackDO feedback = BeanUtils.toBean(createReqVO, MesProFeedbackDO.class);
53   - feedback.setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus());
  63 + MesProFeedbackDO feedback = BeanUtils.toBean(createReqVO, MesProFeedbackDO.class)
  64 + .setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus());
54 65 feedbackMapper.insert(feedback);
55 66 return feedback.getId();
56 67 }
57 68  
58 69 @Override
59 70 public void updateFeedback(MesProFeedbackSaveReqVO updateReqVO) {
60   - // 1. 校验存在 + 草稿状态
  71 + // 1.1 校验存在 + 草稿状态
61 72 validateFeedbackStatusPrepare(updateReqVO.getId());
  73 + // 1.2 校验业务数据
  74 + validateFeedbackData(updateReqVO);
62 75  
63 76 // 2. 更新
64 77 MesProFeedbackDO updateObj = BeanUtils.toBean(updateReqVO, MesProFeedbackDO.class);
... ... @@ -173,6 +186,45 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService {
173 186 }
174 187  
175 188 /**
  189 + * 校验报工单的业务数据(创建 & 修改共用)
  190 + *
  191 + * @param reqVO 报工请求
  192 + */
  193 + private void validateFeedbackData(MesProFeedbackSaveReqVO reqVO) {
  194 + // 1. 校验工作站存在
  195 + workstationService.validateWorkstationExists(reqVO.getWorkstationId());
  196 +
  197 + // 2.1 校验工艺路线 + 工序配置有效
  198 + MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId(
  199 + reqVO.getRouteId(), reqVO.getProcessId());
  200 + if (routeProcess == null) {
  201 + throw exception(PRO_FEEDBACK_ROUTE_PROCESS_INVALID);
  202 + }
  203 + // 2.2 校验数量
  204 + boolean checkFlag = Boolean.TRUE.equals(routeProcess.getCheckFlag());
  205 + if (checkFlag) {
  206 + // 需要检验:只需填报工数量,且必须 > 0
  207 + if (reqVO.getFeedbackQuantity() == null
  208 + || reqVO.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) {
  209 + throw exception(PRO_FEEDBACK_QUANTITY_MUST_POSITIVE);
  210 + }
  211 + } else {
  212 + // 不需检验:需填合格品 + 不良品数量,合计 > 0
  213 + BigDecimal qualified = ObjectUtil.defaultIfNull(reqVO.getQualifiedQuantity(), BigDecimal.ZERO);
  214 + BigDecimal unqualified = ObjectUtil.defaultIfNull(reqVO.getUnqualifiedQuantity(), BigDecimal.ZERO);
  215 + if (qualified.add(unqualified).compareTo(BigDecimal.ZERO) <= 0) {
  216 + throw exception(PRO_FEEDBACK_QUALIFIED_UNQUALIFIED_REQUIRED);
  217 + }
  218 + }
  219 +
  220 + // 3. 校验工单已确认
  221 + workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
  222 +
  223 + // 4. 校验任务存在且未终态(已完成/已取消)
  224 + taskService.validateTaskNotFinished(reqVO.getTaskId());
  225 + }
  226 +
  227 + /**
176 228 * 获取指定工艺路线中指定工序的 checkFlag
177 229 *
178 230 * @param routeId 工艺路线编号
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskService.java
... ... @@ -82,6 +82,14 @@ public interface MesProTaskService {
82 82 MesProTaskDO validateTaskExists(Long id);
83 83  
84 84 /**
  85 + * 校验任务存在且未完成(非终态)
  86 + *
  87 + * @param id 编号
  88 + * @return 生产任务
  89 + */
  90 + MesProTaskDO validateTaskNotFinished(Long id);
  91 +
  92 + /**
85 93 * 获得生产任务列表
86 94 *
87 95 * @param ids 编号列表
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java
... ... @@ -29,6 +29,7 @@ import java.util.List;
29 29  
30 30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
31 31 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  32 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_TASK_ALREADY_FINISHED;
32 33 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_TASK_NOT_EXISTS;
33 34  
34 35 /**
... ... @@ -152,6 +153,15 @@ public class MesProTaskServiceImpl implements MesProTaskService {
152 153 }
153 154  
154 155 @Override
  156 + public MesProTaskDO validateTaskNotFinished(Long id) {
  157 + MesProTaskDO task = validateTaskExists(id);
  158 + if (MesProTaskStatusEnum.isEndStatus(task.getStatus())) {
  159 + throw exception(PRO_TASK_ALREADY_FINISHED);
  160 + }
  161 + return task;
  162 + }
  163 +
  164 + @Override
155 165 public List<MesProTaskDO> getTaskList(Collection<Long> ids) {
156 166 return taskMapper.selectByIds(ids);
157 167 }
... ...