Commit 5c5776961f62f1600544b80d52fb5202bded8fbc
1 parent
5c60fab8
✨ feat(mes): 添加生产任务状态校验和反馈数据验证逻辑
新增对生产任务状态的校验,确保任务未完成时才能进行报工操作。同时,优化报工数据的验证逻辑,确保输入的数量符合业务要求,提升系统的健壮性和用户体验。
Showing
5 changed files
with
82 additions
and
13 deletions
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 | } | ... | ... |