From de4ca61aa27d7f284a03aebd801bcc3d6a75bc6a Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期四, 21 五月 2026 15:03:35 +0800
Subject: [PATCH] 修改生产订单中的工艺路线项目是否生产后,更新生产工单数据
---
src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java | 308 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 297 insertions(+), 11 deletions(-)
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
index 90b1ba1..75d0696 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderRoutingOperationServiceImpl.java
@@ -1,20 +1,306 @@
package com.ruoyi.production.service.impl;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.production.mapper.ProductionOrderRoutingOperationMapper;
-import com.ruoyi.production.pojo.ProductionOrderRoutingOperation;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.framework.web.domain.R;
+import com.ruoyi.production.mapper.*;
+import com.ruoyi.production.util.TaskPlanQuantityUtil;
+import com.ruoyi.technology.mapper.*;
+import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.ProductionOrderRoutingOperationService;
+import com.ruoyi.production.service.ProductionProductMainService;
+import com.ruoyi.technology.pojo.*;
+import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
-/**
- * <p>
- * 鐢熶骇璁㈠崟宸ヨ壓璺嚎宸ュ簭琛� 鏈嶅姟瀹炵幇绫�
- * </p>
- *
- * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
- * @since 2026-04-21 03:55:52
- */
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
@Service
-public class ProductionOrderRoutingOperationServiceImpl extends ServiceImpl<ProductionOrderRoutingOperationMapper, ProductionOrderRoutingOperation> implements ProductionOrderRoutingOperationService {
+@Transactional(rollbackFor = Exception.class)
+@RequiredArgsConstructor
+public class ProductionOrderRoutingOperationServiceImpl extends ServiceImpl<ProductionOrderRoutingOperationMapper, ProductionOrderRoutingOperation>
+ implements ProductionOrderRoutingOperationService {
+ private final ProductionOrderRoutingOperationMapper productionOrderRoutingOperationMapper;
+ private final ProductionOperationTaskMapper productionOperationTaskMapper;
+ private final ProductionProductMainMapper productionProductMainMapper;
+ private final ProductionProductMainService productionProductMainService;
+ private final TechnologyOperationParamMapper technologyOperationParamMapper;
+ private final TechnologyParamMapper technologyParamMapper;
+ private final ProductionOrderRoutingOperationParamMapper productionOrderRoutingOperationParamMapper;
+ private final ProductionOrderMapper productionOrderMapper;
+ private final ProductionOrderRoutingMapper productionOrderRoutingMapper;
+ private final ProductionOrderBomMapper productionOrderBomMapper;
+ private final ProductionBomStructureMapper productionBomStructureMapper;
+ private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper;
+
+ @Override
+ public R addRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+ // 鏂板宸ヨ壓璺嚎
+ int insert = productionOrderRoutingOperationMapper.insert(productionOrderRoutingOperation);
+ //宸ュ簭鍏宠仈鐨勫弬鏁伴渶瑕佸悓姝ユ柊澧�
+ List<TechnologyOperationParam> technologyOperationParams = technologyOperationParamMapper.selectList(Wrappers.<TechnologyOperationParam>lambdaQuery()
+ .eq(TechnologyOperationParam::getTechnologyOperationId, productionOrderRoutingOperation.getTechnologyOperationId()));
+ // 鍙傛暟涓庡墠缃潯浠舵牎楠�
+ if (CollectionUtils.isNotEmpty(technologyOperationParams)){
+ ArrayList<ProductionOrderRoutingOperationParam> productionOrderRoutingOperationParams = new ArrayList<>();
+ // 閬嶅巻澶勭悊鏁版嵁骞剁粍瑁呯粨鏋�
+ for (TechnologyOperationParam technologyOperationParam : technologyOperationParams) {
+ TechnologyParam technologyParam = technologyParamMapper.selectById(technologyOperationParam.getTechnologyParamId());
+ ProductionOrderRoutingOperationParam productionOrderRoutingOperationParam = new ProductionOrderRoutingOperationParam();
+ productionOrderRoutingOperationParam.setProductionOrderId(productionOrderRoutingOperation.getProductionOrderId());
+ productionOrderRoutingOperationParam.setProductionOrderRoutingOperationId(productionOrderRoutingOperation.getId());
+ productionOrderRoutingOperationParam.setParamCode(technologyParam.getParamCode());
+ productionOrderRoutingOperationParam.setParamName(technologyParam.getParamName());
+ productionOrderRoutingOperationParam.setParamType(technologyParam.getParamType());
+ productionOrderRoutingOperationParam.setParamFormat(technologyParam.getParamFormat());
+ productionOrderRoutingOperationParam.setUnit(technologyParam.getUnit());
+ productionOrderRoutingOperationParam.setIsRequired(technologyParam.getIsRequired());
+ productionOrderRoutingOperationParam.setRemark(technologyParam.getRemark());
+ productionOrderRoutingOperationParam.setParamId(technologyParam.getId());
+ productionOrderRoutingOperationParam.setTechnologyOperationId(productionOrderRoutingOperation.getTechnologyOperationId());
+ productionOrderRoutingOperationParams.add(productionOrderRoutingOperationParam);
+ }
+ productionOrderRoutingOperationParamMapper.insert(productionOrderRoutingOperationParams);
+ }
+ String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+ if (insert > 0) {
+ ProductionOperationTask lastTask = productionOperationTaskMapper.selectOne(
+ Wrappers.<ProductionOperationTask>lambdaQuery()
+ .likeRight(ProductionOperationTask::getWorkOrderNo, "GD" + datePrefix)
+ .orderByDesc(ProductionOperationTask::getWorkOrderNo)
+ .last("limit 1"));
+ int sequenceNumber = 1;
+ if (lastTask != null && lastTask.getWorkOrderNo() != null) {
+ String lastNo = lastTask.getWorkOrderNo();
+ if (lastNo.startsWith("GD" + datePrefix)) {
+ String seqStr = lastNo.substring(("GD" + datePrefix).length());
+ try {
+ sequenceNumber = Integer.parseInt(seqStr) + 1;
+ } catch (NumberFormatException e) {
+ sequenceNumber = 1;
+ }
+ }
+ }
+ String workOrderNoStr = "GD" + String.format("%s%03d", datePrefix, sequenceNumber);
+ ProductionOperationTask productionOperationTask = new ProductionOperationTask();
+ productionOperationTask.setProductionOrderRoutingOperationId(productionOrderRoutingOperation.getId());
+ productionOperationTask.setProductionOrderId(productionOrderRoutingOperation.getProductionOrderId());
+ productionOperationTask.setPlanQuantity(BigDecimal.ZERO);
+ productionOperationTask.setCompleteQuantity(BigDecimal.ZERO);
+ productionOperationTask.setWorkOrderNo(workOrderNoStr);
+ productionOperationTask.setStatus(1);
+ productionOperationTaskMapper.insert(productionOperationTask);
+ }
+ return R.ok();
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public R updateRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+ Long operationId = productionOrderRoutingOperation.getId();
+
+ // 鏇存柊宸ヨ壓璺嚎宸ュ簭
+ productionOrderRoutingOperationMapper.updateById(productionOrderRoutingOperation);
+
+ // 閲嶆柊鏌ヨ瀹屾暣璁板綍锛堝墠绔彲鑳芥病鏈変紶閫掓墍鏈夊瓧娈碉紝濡� productionOrderId锛�
+ ProductionOrderRoutingOperation updatedOperation = productionOrderRoutingOperationMapper.selectById(operationId);
+ if (updatedOperation == null) {
+ throw new ServiceException("宸ヨ壓璺嚎宸ュ簭涓嶅瓨鍦�");
+ }
+
+ // 鏌ヨ鏄惁瀛樺湪宸ュ崟
+ ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectOne(
+ new LambdaQueryWrapper<ProductionOperationTask>()
+ .eq(ProductionOperationTask::getProductionOrderRoutingOperationId, operationId)
+ .last("limit 1"));
+
+ // 鏍规嵁鏄惁闇�瑕佺敓浜ц繘琛屽鐞�
+ Boolean isProduction = updatedOperation.getIsProduction();
+
+ if (Boolean.TRUE.equals(isProduction)) {
+ // 闇�瑕佺敓浜э細妫�鏌ュ伐鍗曟槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯鐢熸垚
+ if (productionOperationTask == null) {
+ ProductionOperationTask task = new ProductionOperationTask();
+ task.setProductionOrderRoutingOperationId(updatedOperation.getId());
+ task.setProductionOrderId(updatedOperation.getProductionOrderId());
+ // 鑾峰彇鐢熶骇璁㈠崟
+ ProductionOrder productionOrder = productionOrderMapper.selectById(updatedOperation.getProductionOrderId());
+ if (productionOrder == null) {
+ throw new ServiceException("鐢熶骇璁㈠崟涓嶅瓨鍦�");
+ }
+
+ // 鑾峰彇璁㈠崟BOM
+ ProductionOrderBom orderBom = productionOrderBomMapper.selectOne(
+ Wrappers.<ProductionOrderBom>lambdaQuery()
+ .eq(ProductionOrderBom::getProductionOrderId, productionOrder.getId()));
+
+ // 纭畾鏍逛骇鍝佽鏍糏D
+ Long rootProductModelId = orderBom != null && orderBom.getProductModelId() != null
+ ? orderBom.getProductModelId()
+ : productionOrder.getProductModelId();
+
+ // 鑾峰彇BOM缁撴瀯鍒楄〃
+ List<ProductionBomStructure> orderBomStructureList = orderBom == null || orderBom.getId() == null
+ ? Collections.emptyList()
+ : productionBomStructureMapper.selectList(
+ Wrappers.<ProductionBomStructure>lambdaQuery()
+ .eq(ProductionBomStructure::getProductionOrderBomId, orderBom.getId())
+ .orderByAsc(ProductionBomStructure::getId));
+
+ // 鏋勫缓宸ュ簭闇�姹傞噺鏄犲皠
+ Map<String, BigDecimal> operationDemandedQuantityMap =
+ TaskPlanQuantityUtil.buildOperationDemandedQuantityMap(orderBomStructureList, rootProductModelId);
+
+ // 鑾峰彇宸ヨ壓璺嚎宸ュ簭锛堢敤浜庤绠楄鍒掓暟閲忥級
+ TechnologyRoutingOperation sourceOperation = technologyRoutingOperationMapper.selectById(
+ updatedOperation.getTechnologyRoutingOperationId());
+ // 灏嗗師鏉ョ殑绉佹湁鏂规硶鏇挎崲涓鸿皟鐢ㄥ伐鍏风被
+ BigDecimal planQuantity = TaskPlanQuantityUtil.resolveTaskPlanQuantity(
+ sourceOperation,
+ operationDemandedQuantityMap,
+ productionOrder,
+ rootProductModelId);
+ task.setPlanQuantity(planQuantity);
+ task.setCompleteQuantity(BigDecimal.ZERO);
+ task.setWorkOrderNo(generateNextTaskNo());
+ task.setStatus(2);
+ productionOperationTaskMapper.insert(task);
+ }
+ } else {
+ // 涓嶉渶瑕佺敓浜э細妫�鏌ュ伐鍗曟槸鍚﹀瓨鍦�
+ if (productionOperationTask != null) {
+ validateTaskCanRemove(productionOperationTask);
+ // 娌℃湁鎶ュ伐锛屽垯鍒犻櫎宸ュ崟
+ productionOperationTaskMapper.deleteById(productionOperationTask.getId());
+ }
+ }
+
+ return R.ok();
+ }
+
+ private void validateTaskCanRemove(ProductionOperationTask task) {
+ if (task == null || task.getId() == null) {
+ return;
+ }
+ if (defaultDecimal(task.getCompleteQuantity()).compareTo(BigDecimal.ZERO) > 0) {
+ throw new ServiceException("宸ュ簭宸蹭骇鐢熸姤宸ヨ褰曪紝鏃犳硶鏍规嵁 BOM 鍙樻洿鍒犻櫎瀵瑰簲宸ュ簭蹇収");
+ }
+ long reportCount = productionProductMainMapper.selectCount(
+ Wrappers.<ProductionProductMain>lambdaQuery()
+ .eq(ProductionProductMain::getProductionOperationTaskId, task.getId()));
+ if (reportCount > 0) {
+ throw new ServiceException("宸ュ簭宸蹭骇鐢熸姤宸ヨ褰曪紝鏃犳硶鏍规嵁 BOM 鍙樻洿鍒犻櫎瀵瑰簲宸ュ崟");
+ }
+ }
+
+ private BigDecimal defaultDecimal(BigDecimal value) {
+ return value == null ? BigDecimal.ZERO : value;
+ }
+
+ @Override
+ public R deleteRouteItem(Long id) {
+ // 鍒犻櫎宸ヨ壓璺嚎
+ try {
+ // 鏌ヨ骞跺噯澶囦笟鍔℃暟鎹�
+ ProductionOperationTask productionOperationTask = productionOperationTaskMapper.selectOne(
+ new LambdaQueryWrapper<ProductionOperationTask>()
+ .eq(ProductionOperationTask::getProductionOrderRoutingOperationId, id)
+ .last("limit 1"));
+ // 鍙傛暟涓庡墠缃潯浠舵牎楠�
+ if (productionOperationTask == null) {
+ throw new RuntimeException("鍒犻櫎澶辫触锛氭湭鎵惧埌鍏宠仈鐨勭敓浜у伐鍗�");
+ }
+ if (productionOperationTask.getCompleteQuantity() != null
+ && BigDecimal.ZERO.compareTo(productionOperationTask.getCompleteQuantity()) < 0) {
+ throw new RuntimeException("鍒犻櫎澶辫触锛氳宸ュ崟宸插紑濮嬬敓浜э紝璇峰厛鍒犻櫎鐢熶骇鎶ュ伐");
+ }
+ List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(
+ new LambdaQueryWrapper<ProductionProductMain>()
+ .eq(ProductionProductMain::getProductionOperationTaskId, productionOperationTask.getId()));
+ // 閬嶅巻澶勭悊鏁版嵁骞剁粍瑁呯粨鏋�
+ for (ProductionProductMain main : productionProductMains) {
+ productionProductMainService.removeProductMain(main.getId());
+ }
+ Long productionOrderId = productionOperationTask.getProductionOrderId();
+ Long routingId = null;
+ ProductionOrderRoutingOperation deleteItem = productionOrderRoutingOperationMapper.selectById(id);
+ if (deleteItem != null) {
+ routingId = deleteItem.getOrderRoutingId();
+ }
+ productionOperationTaskMapper.delete(new LambdaQueryWrapper<ProductionOperationTask>()
+ .eq(ProductionOperationTask::getProductionOrderRoutingOperationId, id));
+ productionOrderRoutingOperationMapper.deleteById(id);
+ if (routingId != null) {
+ List<ProductionOrderRoutingOperation> operationList = productionOrderRoutingOperationMapper.selectList(
+ Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
+ .eq(ProductionOrderRoutingOperation::getOrderRoutingId, routingId)
+ .eq(ProductionOrderRoutingOperation::getProductionOrderId, productionOrderId)
+ .orderByAsc(ProductionOrderRoutingOperation::getDragSort));
+ for (int i = 0; i < operationList.size(); i++) {
+ ProductionOrderRoutingOperation item = operationList.get(i);
+ if (!Integer.valueOf(i + 1).equals(item.getDragSort())) {
+ item.setDragSort(i + 1);
+ // 鎸佷箙鍖栨垨杈撳嚭澶勭悊缁撴灉
+ productionOrderRoutingOperationMapper.updateById(item);
+ }
+ }
+ }
+ return R.ok();
+ } catch (Exception e) {
+ throw new RuntimeException("鍒犻櫎鐢熶骇宸ヨ壓璺嚎澶辫触锛�" + e.getMessage());
+ }
+ }
+
+ @Override
+ public int sortRouteItem(ProductionOrderRoutingOperation productionOrderRoutingOperation) {
+ // 鎺掑簭宸ヨ壓璺嚎
+ ProductionOrderRoutingOperation oldItem = productionOrderRoutingOperationMapper.selectById(productionOrderRoutingOperation.getId());
+ List<ProductionOrderRoutingOperation> operationList = productionOrderRoutingOperationMapper.selectList(
+ Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
+ .eq(ProductionOrderRoutingOperation::getOrderRoutingId, oldItem.getOrderRoutingId())
+ .orderByAsc(ProductionOrderRoutingOperation::getDragSort));
+ Integer targetPosition = productionOrderRoutingOperation.getDragSort();
+ if (targetPosition != null && targetPosition >= 1) {
+ operationList.removeIf(item -> item.getId().equals(oldItem.getId()));
+ operationList.add(targetPosition - 1, oldItem);
+ for (int i = 0; i < operationList.size(); i++) {
+ ProductionOrderRoutingOperation item = operationList.get(i);
+ int dragSort = i + 1;
+ if (!Integer.valueOf(dragSort).equals(item.getDragSort())) {
+ item.setDragSort(dragSort);
+ productionOrderRoutingOperationMapper.updateById(item);
+ }
+ }
+ return 1;
+ }
+ return 0;
+ }
+
+ private String generateNextTaskNo() {
+ // 鐢熸垚涓嬩竴涓敓浜у伐鍗曞彿
+ String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+ String prefix = "GD" + datePrefix;
+ ProductionOperationTask lastTask = productionOperationTaskMapper.selectOne(
+ Wrappers.<ProductionOperationTask>lambdaQuery()
+ .likeRight(ProductionOperationTask::getWorkOrderNo, prefix)
+ .orderByDesc(ProductionOperationTask::getWorkOrderNo)
+ .last("limit 1"));
+ int sequence = 1;
+ if (lastTask != null && lastTask.getWorkOrderNo() != null && lastTask.getWorkOrderNo().startsWith(prefix)) {
+ try {
+ sequence = Integer.parseInt(lastTask.getWorkOrderNo().substring(prefix.length())) + 1;
+ } catch (NumberFormatException ignored) {
+ sequence = 1;
+ }
+ }
+ return prefix + String.format("%03d", sequence);
+ }
}
--
Gitblit v1.9.3