From 7bd10d34e8a8dc2437ec8551eb511e37634d7306 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期一, 02 十一月 2026 16:51:52 +0800
Subject: [PATCH] feat(mes): 生产计划审批改走协同办公,修复工单领料与产成品入库校验
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java | 98 +++++++++++++++++++++++++++++++++----------------
1 files changed, 66 insertions(+), 32 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 087ce58..c31ce78 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
@@ -76,6 +76,9 @@
public class MesProTaskServiceImpl implements MesProTaskService {
@Resource
+ private cn.iocoder.yudao.module.mes.service.pro.feedback.MesProFeedbackEquipmentService equipmentService;
+
+ @Resource
private cn.iocoder.yudao.module.mes.service.pro.task.schedule.MesProScheduleGuardService scheduleGuard;
@Resource
@@ -135,23 +138,18 @@
scheduleGuard.lock();
// 1. 鏍¢獙鍏宠仈鏁版嵁瀛樺湪
MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderConfirmed(createReqVO.getWorkOrderId());
- var station = workstationService.validateWorkstationExistsAndEnable(createReqVO.getWorkstationId());
- if (!java.util.Objects.equals(station.getProcessId(), createReqVO.getProcessId())) {
- throw exception(cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_TASK_SCHEDULE_INVALID, "宸ヤ綔绔欎笌宸ュ簭涓嶅尮閰�");
- }
- routeService.validateRouteExists(createReqVO.getRouteId());
- processService.validateProcessExistsAndEnable(createReqVO.getProcessId());
+ workstationService.validateWorkstationExistsAndEnable(createReqVO.getWorkstationId());
// 2. 鑷姩纭畾 itemId锛氫紭鍏堝墠绔紶鍏� 鈫� 宸ヨ壓璺嚎宸ュ簭鐨勪骇鍑轰骇鍝� 鈫� 宸ュ崟鎴愬搧
+ // 鏈厤缃伐搴�/宸ヨ壓璺嚎鏃讹紝浠诲姟鐩存帴鎸夊伐鍗曟垚鍝佷骇鍑�
Long itemId = createReqVO.getItemId();
- if (itemId == null) {
+ if (itemId == null && createReqVO.getRouteId() != null && createReqVO.getProcessId() != null) {
MesProRouteProcessDO routeProcess = routeProcessService
.getRouteProcessByRouteIdAndProcessId(createReqVO.getRouteId(), createReqVO.getProcessId());
- if (routeProcess != null && routeProcess.getOutputItemId() != null) {
- itemId = Long.valueOf(routeProcess.getOutputItemId().split(",")[0].trim());
- } else {
- itemId = workOrder.getProductId();
- }
+ itemId = resolveTaskItemId(routeProcess, workOrder.getProductId());
+ }
+ if (itemId == null) {
+ itemId = workOrder.getProductId();
}
MesMdItemDO item = itemService.validateItemExists(itemId);
@@ -205,12 +203,6 @@
if (updateReqVO.getWorkstationId() != null) {
workstationService.validateWorkstationExists(updateReqVO.getWorkstationId());
}
- if (updateReqVO.getRouteId() != null) {
- routeService.validateRouteExists(updateReqVO.getRouteId());
- }
- if (updateReqVO.getProcessId() != null) {
- processService.validateProcessExistsAndEnable(updateReqVO.getProcessId());
- }
MesMdItemDO item;
if (updateReqVO.getItemId() != null) {
item = itemService.validateItemExists(updateReqVO.getItemId());
@@ -226,10 +218,6 @@
.setQuantity(quantity)
.setStartTime(updateReqVO.getStartTime() != null ? updateReqVO.getStartTime() : task.getStartTime())
.setEndTime(updateReqVO.getEndTime() != null ? updateReqVO.getEndTime() : task.getEndTime());
- var station = workstationService.validateWorkstationExistsAndEnable(candidate.getWorkstationId());
- if (!java.util.Objects.equals(station.getProcessId(), candidate.getProcessId())) {
- throw exception(cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_TASK_SCHEDULE_INVALID, "宸ヤ綔绔欎笌宸ュ簭涓嶅尮閰�");
- }
scheduleGuard.validate(workOrderService.validateWorkOrderConfirmed(candidate.getWorkOrderId()), candidate, task.getId());
// 2. 鏇存柊
@@ -250,13 +238,24 @@
private void synchronizeScheduledQuantity(MesProWorkOrderDO order, Long routeId) {
List<MesProRouteProcessDO> required = buildRouteProcessList(routeId, order.getId());
List<MesProTaskDO> tasks = taskMapper.selectListByWorkOrderId(order.getId());
- BigDecimal scheduled = order.getQuantity();
- for (var process : required) {
- BigDecimal amount = tasks.stream().filter(task -> java.util.Objects.equals(task.getProcessId(), process.getProcessId())
- && !java.util.Objects.equals(task.getStatus(), MesProTaskStatusEnum.CANCELED.getStatus()))
+ BigDecimal orderQuantity = order.getQuantity() == null ? BigDecimal.ZERO : order.getQuantity();
+ BigDecimal scheduled;
+ if (CollUtil.isEmpty(required)) {
+ // 鏈厤缃伐搴�/宸ヨ壓璺嚎锛氭暣寮犲伐鍗曞彧鏈変竴涓敓浜ф楠わ紝宸叉帓浜ч噺鎸変换鍔℃暟閲忓悎璁�
+ scheduled = tasks.stream()
+ .filter(task -> !java.util.Objects.equals(task.getStatus(), MesProTaskStatusEnum.CANCELED.getStatus()))
.map(task -> task.getQuantity() == null ? BigDecimal.ZERO : task.getQuantity())
- .reduce(BigDecimal.ZERO, BigDecimal::add);
- scheduled = scheduled.min(amount);
+ .reduce(BigDecimal.ZERO, BigDecimal::add)
+ .min(orderQuantity);
+ } else {
+ scheduled = orderQuantity;
+ for (var process : required) {
+ BigDecimal amount = tasks.stream().filter(task -> java.util.Objects.equals(task.getProcessId(), process.getProcessId())
+ && !java.util.Objects.equals(task.getStatus(), MesProTaskStatusEnum.CANCELED.getStatus()))
+ .map(task -> task.getQuantity() == null ? BigDecimal.ZERO : task.getQuantity())
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ scheduled = scheduled.min(amount);
+ }
}
scheduleWorkOrderMapper.updateById(new MesProWorkOrderDO().setId(order.getId()).setQuantityScheduled(scheduled));
}
@@ -341,12 +340,34 @@
}
return result;
}
- // 2. 鍥為��鍒板伐鑹鸿矾绾挎ā鏉垮伐搴�
+ // 2. 鍥為��鍒板伐鑹鸿矾绾挎ā鏉垮伐搴忥紱鏈厤缃伐鑹鸿矾绾挎椂瑙嗕负鍗曞伐搴忕敓浜�
+ if (routeId == null) {
+ return new java.util.ArrayList<>();
+ }
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;
+ }
+
+ /** 褰撳墠浜у搧鐨勪换鍔′骇鍑猴紝浼樺厛浣跨敤宸ュ簭鐨勪骇鍝佸綊灞為厤缃�� */
+ private Long resolveTaskItemId(MesProRouteProcessDO routeProcess, Long productId) {
+ if (routeProcess == null) {
+ return productId;
+ }
+ if (routeProcess.getId() != null) {
+ List<Long> outputIds = routeProcessService
+ .getOutputItemIdsByRouteProcessId(routeProcess.getId(), productId);
+ if (outputIds != null) {
+ return CollUtil.isNotEmpty(outputIds) ? outputIds.get(0) : productId;
+ }
+ }
+ String outputItemId = routeProcess.getOutputItemId();
+ if (outputItemId != null && !outputItemId.isBlank()) {
+ return Long.valueOf(outputItemId.split(",")[0].trim());
+ }
+ return productId;
}
@Override
@@ -424,7 +445,9 @@
}
@Override
+ @Transactional(rollbackFor = Exception.class)
public void finishTaskByOrderId(Long workOrderId) {
+ equipmentService.lock();
// 1. 璇诲彇宸ュ崟涓嬫墍鏈変换鍔★紝杩囨护鎺夊凡瀹屾垚/宸插彇娑堢殑
List<MesProTaskDO> tasks = taskMapper.selectListByWorkOrderId(workOrderId);
LocalDateTime now = LocalDateTime.now();
@@ -436,10 +459,13 @@
if (CollUtil.isNotEmpty(updateList)) {
taskMapper.updateBatch(updateList);
}
+ equipmentService.afterTaskStateChanged(tasks);
}
@Override
+ @Transactional(rollbackFor = Exception.class)
public void cancelTaskByOrderId(Long workOrderId) {
+ equipmentService.lock();
// 1. 璇诲彇宸ュ崟涓嬫墍鏈変换鍔★紝杩囨护鎺夊凡瀹屾垚/宸插彇娑堢殑
List<MesProTaskDO> tasks = taskMapper.selectListByWorkOrderId(workOrderId);
LocalDateTime now = LocalDateTime.now();
@@ -451,6 +477,7 @@
if (CollUtil.isNotEmpty(updateList)) {
taskMapper.updateBatch(updateList);
}
+ equipmentService.afterTaskStateChanged(tasks);
}
@Override
@@ -554,7 +581,7 @@
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 ? Long.valueOf(rp.getOutputItemId().split(",")[0].trim()) : workOrder.getProductId();
+ Long itemId = resolveTaskItemId(rp, workOrder.getProductId());
cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO item = itemService.validateItemExists(itemId);
MesProTaskDO task = new MesProTaskDO()
.setWorkOrderId(workOrder.getId())
@@ -582,10 +609,12 @@
@Override
@Transactional(rollbackFor = Exception.class)
public void pauseTask(MesProTaskPauseReqVO pauseReqVO) {
+ equipmentService.lock();
// 1. 鏍¢獙浠诲姟瀛樺湪
MesProTaskDO task = validateTaskExists(pauseReqVO.getId());
// 2. 鏍¢獙鐘舵�佹槸鍚﹀厑璁稿仠宸ワ紙濡傚繀椤绘槸 鐢熶骇涓� 鎴� 閮ㄥ垎瀹屾垚锛�
- if (!ObjectUtils.equalsAny(task.getStatus(), MesProTaskStatusEnum.PREPARE.getStatus())) {
+ if (!ObjectUtils.equalsAny(task.getStatus(), MesProTaskStatusEnum.PREPARE.getStatus(),
+ MesProTaskStatusEnum.PRODUCING.getStatus(), MesProTaskStatusEnum.PARTIAL_FINISHED.getStatus())) {
throw exception(PRO_TASK_CANNOT_PAUSE);
}
@@ -602,11 +631,13 @@
.setPauseTime(LocalDateTime.now())
.setPauseUserId(SecurityFrameworkUtils.getLoginUserId());
taskPauseRecordMapper.insert(pauseRecord);
+ equipmentService.afterTaskStateChanged(List.of(task));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void resumeTask(MesProTaskResumeReqVO resumeReqVO) {
+ equipmentService.lock();
// 1. 鏍¢獙浠诲姟瀛樺湪
MesProTaskDO task = validateTaskExists(resumeReqVO.getId());
// 2. 鏍¢獙鐘舵�佸繀椤绘槸宸插仠宸�
@@ -615,8 +646,11 @@
}
// 3. 鎭㈠浠诲姟鐘舵��
- Integer resumeStatus = MesProTaskStatusEnum.PREPARE.getStatus();
+ Integer resumeStatus = task.getProducedQuantity() != null && task.getProducedQuantity().signum() > 0
+ ? MesProTaskStatusEnum.PARTIAL_FINISHED.getStatus() : MesProTaskStatusEnum.PREPARE.getStatus();
taskMapper.updateById(new MesProTaskDO().setId(task.getId()).setStatus(resumeStatus));
+ equipmentService.validateResume(task);
+ equipmentService.afterTaskStateChanged(List.of(task));
// 4. 鏇存柊鏈�鏂扮殑涓�鏉″仠宸ヨ褰�
MesProTaskPauseRecordDO pauseRecord = taskPauseRecordMapper.selectLastUnresumedByTaskId(task.getId());
--
Gitblit v1.9.3