From 4803b22ae0f0f5b4e2ae1627a7d1eea38684f02d Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 23 七月 2026 09:07:06 +0800
Subject: [PATCH] feat(mes): 新增工单工序管理和报工功能
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 156 insertions(+), 2 deletions(-)
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 f45fb1b..d19426b 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
@@ -3,6 +3,8 @@
import cn.hutool.core.collection.CollUtil;
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.pro.task.vo.MesProTaskAutoGeneratePreviewRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskAutoGenerateReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
@@ -18,11 +20,19 @@
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO;
+import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
+import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductService;
import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderProcessDO;
+import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderProcessService;
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;
@@ -66,6 +76,15 @@
@Resource
private MesProRouteService routeService;
@Resource
+ @Lazy
+ private MesProRouteProcessService routeProcessService;
+ @Resource
+ @Lazy
+ private MesProRouteProductService routeProductService;
+ @Resource
+ @Lazy
+ private MesProWorkOrderProcessService workOrderProcessService;
+ @Resource
private MesMdAutoCodeRecordService autoCodeRecordService;
@Override
@@ -75,10 +94,23 @@
workstationService.validateWorkstationExists(createReqVO.getWorkstationId());
routeService.validateRouteExists(createReqVO.getRouteId());
processService.validateProcessExistsAndEnable(createReqVO.getProcessId());
- MesMdItemDO item = itemService.validateItemExists(createReqVO.getItemId());
- // 2.1 鏋勫缓浠诲姟 DO锛氳嚜鍔ㄥ~鍏呭鎴蜂俊鎭�
+ // 2. 鑷姩纭畾 itemId锛氫紭鍏堝墠绔紶鍏� 鈫� 宸ヨ壓璺嚎宸ュ簭鐨勪骇鍑轰骇鍝� 鈫� 宸ュ崟鎴愬搧
+ Long itemId = createReqVO.getItemId();
+ if (itemId == null) {
+ MesProRouteProcessDO routeProcess = routeProcessService
+ .getRouteProcessByRouteIdAndProcessId(createReqVO.getRouteId(), createReqVO.getProcessId());
+ if (routeProcess != null && routeProcess.getOutputItemId() != null) {
+ itemId = routeProcess.getOutputItemId();
+ } else {
+ itemId = workOrder.getProductId();
+ }
+ }
+ MesMdItemDO item = itemService.validateItemExists(itemId);
+
+ // 3.1 鏋勫缓浠诲姟 DO锛氳嚜鍔ㄥ~鍏呭鎴蜂俊鎭�
MesProTaskDO task = BeanUtils.toBean(createReqVO, MesProTaskDO.class)
+ .setItemId(itemId) // 纭繚浣跨敤璁$畻鍚庣殑 itemId
.setName(buildTaskName(item, createReqVO.getQuantity()))
.setCode(autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.PRO_TASK_CODE.getCode()))
.setStatus(MesProTaskStatusEnum.PREPARE.getStatus());
@@ -133,6 +165,54 @@
}
}
return item.getName() + "銆�" + quantity + "銆�" + unitName;
+ }
+
+ /**
+ * 纭畾鎺掍骇浣跨敤鐨勫伐鑹鸿矾绾� ID锛氫紭鍏堣姹傛寚瀹� 鈫� 宸ュ崟鍏宠仈 鈫� 浜у搧鍏宠仈
+ */
+ private Long resolveRouteId(Long reqRouteId, MesProWorkOrderDO workOrder) {
+ if (reqRouteId != null) {
+ return reqRouteId;
+ }
+ if (workOrder.getRouteId() != null) {
+ return workOrder.getRouteId();
+ }
+ // 浠庝骇鍝佸叧鑱旂殑宸ヨ壓璺嚎鑾峰彇
+ MesProRouteProductDO routeProduct = routeProductService.getRouteProductByItemId(workOrder.getProductId());
+ if (routeProduct == null) {
+ throw exception(cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_ROUTE_NOT_EXISTS);
+ }
+ return routeProduct.getRouteId();
+ }
+
+ /**
+ * 鏋勫缓宸ュ簭鍒楄〃锛氫紭鍏堜娇鐢ㄥ伐鍗曞凡淇濆瓨鐨勫伐搴� 鈫� 鍥為��鍒板伐鑹鸿矾绾挎ā鏉垮伐搴�
+ */
+ private List<MesProRouteProcessDO> buildRouteProcessList(Long routeId, Long workOrderId) {
+ // 1. 浼樺厛浣跨敤宸ュ崟宸蹭繚瀛樼殑宸ュ簭
+ List<MesProWorkOrderProcessDO> woProcesses = workOrderProcessService
+ .getWorkOrderProcessListByWorkOrderId(workOrderId);
+ if (CollUtil.isNotEmpty(woProcesses)) {
+ List<MesProRouteProcessDO> result = new java.util.ArrayList<>();
+ for (MesProWorkOrderProcessDO wp : woProcesses) {
+ result.add(new MesProRouteProcessDO()
+ .setRouteId(routeId)
+ .setProcessId(wp.getProcessId())
+ .setSort(wp.getSort())
+ .setKeyFlag(wp.getKeyFlag())
+ .setCheckFlag(wp.getCheckFlag())
+ .setBackflushFlag(wp.getBackflushFlag())
+ .setOutputItemId(wp.getOutputItemId())
+ .setColorCode(wp.getColorCode()));
+ }
+ return result;
+ }
+ // 2. 鍥為��鍒板伐鑹鸿矾绾挎ā鏉垮伐搴�
+ List<MesProRouteProcessDO> routeProcesses = routeProcessService.getRouteProcessListByRouteId(routeId);
+ if (CollUtil.isEmpty(routeProcesses)) {
+ throw exception(cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_ROUTE_ENABLE_NO_PROCESS);
+ }
+ return routeProcesses;
}
@Override
@@ -237,4 +317,78 @@
taskMapper.updateProducedQuantity(id, incrProducedQuantity, incrQualifyQuantity, incrUnqualifyQuantity);
}
+ @Override
+ public MesProTaskAutoGeneratePreviewRespVO previewAutoGenerate(MesProTaskAutoGenerateReqVO reqVO) {
+ // 1. 鏍¢獙宸ュ崟宸茬‘璁�
+ MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
+ // 2. 纭畾宸ヨ壓璺嚎锛氫紭鍏堣姹傛寚瀹� 鈫� 宸ュ崟鍏宠仈 鈫� 浜у搧鍏宠仈
+ Long routeId = resolveRouteId(reqVO.getRouteId(), workOrder);
+ MesProRouteDO route = routeService.validateRouteExists(routeId);
+ // 3. 鑾峰彇宸ュ簭鍒楄〃锛氫紭鍏堝伐鍗曞伐搴� 鈫� 宸ヨ壓璺嚎宸ュ簭
+ List<MesProRouteProcessDO> routeProcesses = buildRouteProcessList(routeId, reqVO.getWorkOrderId());
+ // 鎸夊簭鍙锋帓搴�
+ routeProcesses.sort(java.util.Comparator.comparing(MesProRouteProcessDO::getSort, java.util.Comparator.nullsLast(java.util.Comparator.naturalOrder())));
+ // 4. 鏌ヨ宸ュ簭鍚嶇О
+ java.util.Set<Long> processIds = routeProcesses.stream().map(MesProRouteProcessDO::getProcessId).collect(java.util.stream.Collectors.toSet());
+ java.util.Map<Long, cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO> procMap = processService.getProcessMap(processIds);
+ // 5. 缁勮棰勮
+ MesProTaskAutoGeneratePreviewRespVO vo = new MesProTaskAutoGeneratePreviewRespVO()
+ .setWorkOrderId(workOrder.getId())
+ .setRouteId(routeId)
+ .setRouteName(route.getName());
+ java.util.List<MesProTaskAutoGeneratePreviewRespVO.TaskPreview> taskList = new java.util.ArrayList<>();
+ for (MesProRouteProcessDO rp : routeProcesses) {
+ cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO proc = procMap.get(rp.getProcessId());
+ taskList.add(new MesProTaskAutoGeneratePreviewRespVO.TaskPreview()
+ .setProcessId(rp.getProcessId())
+ .setProcessName(proc != null ? proc.getName() : null)
+ .setSort(rp.getSort())
+ .setQuantity(workOrder.getQuantity())
+ .setKeyFlag(rp.getKeyFlag()));
+ }
+ vo.setTaskList(taskList);
+ return vo;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public List<Long> autoGenerateTasks(MesProTaskAutoGenerateReqVO reqVO) {
+ // 1. 鏍¢獙宸ュ崟宸茬‘璁�
+ MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
+ // 2. 纭畾宸ヨ壓璺嚎锛氫紭鍏堣姹傛寚瀹� 鈫� 宸ュ崟鍏宠仈 鈫� 浜у搧鍏宠仈
+ Long routeId = resolveRouteId(reqVO.getRouteId(), workOrder);
+ routeService.validateRouteExists(routeId);
+ // 3. 鏍¢獙鎺掍骇鏁伴噺
+ workOrderService.validateScheduleQuantity(reqVO.getWorkOrderId(), workOrder.getQuantity());
+ // 4. 鑾峰彇宸ュ簭鍒楄〃锛氫紭鍏堝伐鍗曞伐搴� 鈫� 宸ヨ壓璺嚎宸ュ簭
+ List<MesProRouteProcessDO> routeProcesses = buildRouteProcessList(routeId, reqVO.getWorkOrderId());
+ routeProcesses.sort(java.util.Comparator.comparing(MesProRouteProcessDO::getSort, java.util.Comparator.nullsLast(java.util.Comparator.naturalOrder())));
+ // 5. 鏌ヨ宸ュ簭淇℃伅
+ java.util.Set<Long> processIds = routeProcesses.stream().map(MesProRouteProcessDO::getProcessId).collect(java.util.stream.Collectors.toSet());
+ java.util.Map<Long, cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO> procMap = processService.getProcessMap(processIds);
+ // 6. 涓烘瘡涓伐搴忓垱寤轰换鍔�
+ List<Long> taskIds = new java.util.ArrayList<>();
+ for (MesProRouteProcessDO rp : routeProcesses) {
+ cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO proc = procMap.get(rp.getProcessId());
+ Long itemId = rp.getOutputItemId() != null ? rp.getOutputItemId() : workOrder.getProductId();
+ cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO item = itemService.validateItemExists(itemId);
+ MesProTaskDO task = new MesProTaskDO()
+ .setWorkOrderId(workOrder.getId())
+ .setRouteId(routeId)
+ .setProcessId(rp.getProcessId())
+ .setItemId(itemId)
+ .setQuantity(workOrder.getQuantity())
+ .setName(buildTaskName(item, workOrder.getQuantity()))
+ .setCode(autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.PRO_TASK_CODE.getCode()))
+ .setStatus(MesProTaskStatusEnum.PREPARE.getStatus())
+ .setClientId(workOrder.getClientId())
+ .setColorCode(rp.getColorCode());
+ taskMapper.insert(task);
+ taskIds.add(task.getId());
+ }
+ // 7. 鏇存柊宸ュ崟宸叉帓浜ф暟閲�
+ workOrderService.updateScheduledQuantity(workOrder.getId(), workOrder.getQuantity());
+ return taskIds;
+ }
+
}
--
Gitblit v1.9.3