From db46314b9c56256a31c9114bd45d9bd63368cbd8 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 29 七月 2026 18:06:22 +0800
Subject: [PATCH] feat(crm): 实现CRM客户管理查看全部权限功能
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java | 196 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 194 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..bf04d45 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,26 +3,40 @@
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.dv.machinery.MesDvMachineryDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationMachineDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
import cn.iocoder.yudao.module.mes.dal.mysql.pro.task.MesProTaskMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper;
import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum;
import cn.iocoder.yudao.module.mes.enums.pro.MesProTaskStatusEnum;
+import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryService;
import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
+import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationMachineService;
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;
@@ -30,9 +44,11 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
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.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_TASK_ALREADY_FINISHED;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_TASK_HAS_FEEDBACK;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_TASK_NOT_EXISTS;
@@ -66,7 +82,21 @@
@Resource
private MesProRouteService routeService;
@Resource
+ @Lazy
+ private MesProRouteProcessService routeProcessService;
+ @Resource
+ @Lazy
+ private MesProRouteProductService routeProductService;
+ @Resource
+ @Lazy
+ private MesProWorkOrderProcessService workOrderProcessService;
+ @Resource
private MesMdAutoCodeRecordService autoCodeRecordService;
+ @Resource
+ private MesMdWorkstationMachineService workstationMachineService;
+ @Resource
+ @Lazy
+ private MesDvMachineryService machineryService;
@Override
public Long createTask(MesProTaskSaveReqVO createReqVO) {
@@ -75,10 +105,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 +176,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 +328,105 @@
taskMapper.updateProducedQuantity(id, incrProducedQuantity, incrQualifyQuantity, incrUnqualifyQuantity);
}
+ @Override
+ public Integer calculateDuration(Long workstationId, BigDecimal quantity) {
+ if (quantity == null || quantity.compareTo(BigDecimal.ZERO) <= 0) {
+ return 0;
+ }
+ // 1. 鏌ヨ宸ヤ綔绔欑粦瀹氱殑璁惧
+ List<MesMdWorkstationMachineDO> machines = workstationMachineService
+ .getWorkstationMachineListByWorkstationId(workstationId);
+ if (CollUtil.isEmpty(machines)) {
+ return 0;
+ }
+ // 2. 鑾峰彇璁惧璇︽儏锛岃绠楁�绘晥鐜�
+ Set<Long> machineryIds = convertSet(machines, MesMdWorkstationMachineDO::getMachineryId);
+ List<MesDvMachineryDO> machineryList = machineryService.getMachineryList(machineryIds);
+ BigDecimal totalEfficiency = BigDecimal.ZERO;
+ for (MesDvMachineryDO m : machineryList) {
+ BigDecimal efficiency = m.getProductionEfficiency() != null ? m.getProductionEfficiency() : BigDecimal.ZERO;
+ Integer belt = m.getConveyorBelt() != null && m.getConveyorBelt() > 0 ? m.getConveyorBelt() : 1;
+ totalEfficiency = totalEfficiency.add(efficiency.multiply(BigDecimal.valueOf(belt)));
+ }
+ if (totalEfficiency.compareTo(BigDecimal.ZERO) <= 0) {
+ return 0;
+ }
+ // 3. 鐢熶骇鏃堕暱锛堝皬鏃讹級 = ceil(鎺掍骇鏁伴噺 / 鎬绘晥鐜�)锛屾晥鐜囧崟浣嶄负姣忓皬鏃朵骇閲�
+ return quantity.divide(totalEfficiency, 0, java.math.RoundingMode.CEILING).intValue();
+ }
+
+ @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