From 2f8e173048d22c5b40612c3538b9c1aa5a5397f6 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期五, 27 三月 2026 13:38:05 +0800
Subject: [PATCH] #乐观锁

---
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java |  844 +++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 615 insertions(+), 229 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
index a3a28ed..875e6d4 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -8,7 +8,6 @@
 import com.fasterxml.jackson.databind.cfg.CoercionAction;
 import com.fasterxml.jackson.databind.cfg.CoercionInputShape;
 import com.vincent.rsf.framework.common.Cools;
-import com.vincent.rsf.framework.common.DateUtils;
 import com.vincent.rsf.server.api.config.RemotesInfoProperties;
 import com.vincent.rsf.server.api.controller.erp.params.TaskInParam;
 import com.vincent.rsf.server.api.entity.CommonResponse;
@@ -34,7 +33,8 @@
 import com.vincent.rsf.server.manager.enums.LocStsType;
 import com.vincent.rsf.server.system.entity.Config;
 import com.vincent.rsf.server.system.service.ConfigService;
-import com.vincent.rsf.server.system.service.impl.ConfigServiceImpl;
+import com.vincent.rsf.server.system.entity.FlowStepInstance;
+import com.vincent.rsf.server.system.service.FlowStepInstanceService;
 import com.vincent.rsf.server.system.utils.SerialRuleUtils;
 import com.vincent.rsf.server.system.utils.SystemAuthUtils;
 import lombok.Synchronized;
@@ -44,6 +44,7 @@
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpMethod;
@@ -97,10 +98,9 @@
     @Autowired
     private BasStationService basStationService;
     @Autowired
-    private TaskService taskService;
-    @Autowired
     private LocItemWorkingService locItemWorkingService;
     @Autowired
+    @Lazy
     private WcsService wcsService;
     @Autowired
     private OutStockService outStockService;
@@ -109,6 +109,7 @@
     @Autowired
     private CheckOrderItemService checkOrderItemService;
     @Autowired
+    @Lazy
     private CheckOrderService checkOrderService;
     @Autowired
     private CheckDiffService checkDiffService;
@@ -122,6 +123,11 @@
     private RestTemplate restTemplate;
     @Autowired
     private RemotesInfoProperties.RcsApi rcsApi;
+    @Autowired
+    @Lazy
+    private FlowStepInstanceService flowStepInstanceService;
+    @Autowired
+    private RemotesInfoProperties.WmsOpenApi wmsOpenApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -163,10 +169,7 @@
             if (!this.save(task)) {
                 throw new CoolException("浠诲姟淇濆瓨澶辫触锛侊紒");
             }
-            if (!locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getCode, task.getTargLoc())
-                    .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, pakin.getBarcode()))) {
-                throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
-            }
+            updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_S.type, pakin.getBarcode(), null, "搴撲綅棰勭害澶辫触锛侊紒", true);
             /**鑾峰彇缁勬嫋鏄庣粏**/
             List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, pakin.getId()));
             if (waitPakinItems.isEmpty()) {
@@ -176,7 +179,7 @@
                 TaskItem taskItem = new TaskItem();
                 BeanUtils.copyProperties(item, taskItem);
                 taskItem.setTaskId(task.getId())
-                        .setOrderType(OrderType.ORDER_IN.type)
+                        .setOrderType(item.getType().equals(OrderType.ORDER_PRE.type)?OrderType.ORDER_PRE.type:OrderType.ORDER_IN.type)
                         .setSource(item.getId())
                         .setTrackCode(item.getTrackCode())
                         .setCreateBy(loginUserId)
@@ -206,13 +209,7 @@
             });
         });
 
-        if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
-                .in(WaitPakin::getId, pakins.getId())
-                .set(WaitPakin::getUpdateBy, loginUserId)
-                .set(WaitPakin::getCreateBy, loginUserId)
-                .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) {
-            throw new CoolException("缁勬墭鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
+        updateWaitPakinsStatus(waitPakins, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val, loginUserId, true, "缁勬墭鐘舵�佷慨鏀瑰け璐ワ紒锛�");
         return R.ok("浠诲姟鐢熸垚瀹屾瘯锛�");
     }
 
@@ -255,14 +252,7 @@
             if (!this.save(task)) {
                 throw new CoolException("浠诲姟淇濆瓨澶辫触锛侊紒");
             }
-            if (!locService.update(new LambdaUpdateWrapper<Loc>()
-                    .eq(Loc::getCode, task.getTargLoc())
-                    .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type)
-                    .set(Loc::getUpdateBy, loginUserId)
-                    .set(Loc::getUpdateTime, new Date())
-                    .set(Loc::getBarcode, pakin.getBarcode()))) {
-                throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
-            }
+            updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_S.type, pakin.getBarcode(), loginUserId, "搴撲綅棰勭害澶辫触锛侊紒", true);
             /**鑾峰彇缁勬嫋鏄庣粏**/
             List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, pakin.getId()));
             if (waitPakinItems.isEmpty()) {
@@ -297,13 +287,7 @@
             });
         });
 
-        if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
-                .in(WaitPakin::getId, pakins.getId())
-                .set(WaitPakin::getUpdateBy, loginUserId)
-                .set(WaitPakin::getCreateBy, loginUserId)
-                .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) {
-            throw new CoolException("缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
+        updateWaitPakinsStatus(waitPakins, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val, loginUserId, true, "缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
         return R.ok("浠诲姟鐢熸垚瀹屾瘯锛�");
     }
 
@@ -400,17 +384,16 @@
             if (Objects.isNull(station) || !station.getUseStatus().equals(LocStsType.LOC_STS_TYPE_O.type)) {
                 throw new CoolException("绔欑偣涓嶅瓨鍦ㄦ垨绔欑偣涓嶅浜庣┖搴撶姸鎬侊紒锛�");
             }
-            station.setUseStatus(LocStsType.LOC_STS_TYPE_R.type);
+            if (!station.getType().equals(0)){
+                station.setUseStatus(LocStsType.LOC_STS_TYPE_R.type);
+            }
 
             if (!basStationService.updateById(station)) {
                  throw new CoolException("绔欑偣鐘舵�佹洿鏂板け璐ワ紒锛�");
              }
 
 
-            if (!locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getCode, task.getTargLoc())
-                    .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, pakin.getBarcode()))) {
-                throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
-            }
+            updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_S.type, pakin.getBarcode(), null, "搴撲綅棰勭害澶辫触锛侊紒", true);
             /**鑾峰彇缁勬嫋鏄庣粏**/
             List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, pakin.getId()));
             if (waitPakinItems.isEmpty()) {
@@ -453,13 +436,7 @@
             });
         });
 
-        if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
-                .in(WaitPakin::getId, ids)
-                .set(WaitPakin::getUpdateBy, loginUserId)
-                .set(WaitPakin::getCreateBy, loginUserId)
-                .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) {
-            throw new CoolException("缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
+        updateWaitPakinsStatus(waitPakins, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val, loginUserId, true, "缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
         return R.ok("浠诲姟鐢熸垚瀹屾瘯锛�");
     }
 
@@ -494,12 +471,13 @@
             throw new CoolException("绔欑偣鐘舵�佷笉涓虹┖闂�");
         }
 
-        List<Long> areaList = basStation.getCrossZoneArea();
-        if (!areaList.contains(Long.parseLong(area))) {
+        if (!basStation.getCrossZoneArea().contains(Integer.parseInt(area))) {
             throw new CoolException("褰撳墠绔欑偣涓嶆敮鎸佺洰鏍囧簱鍖�");
         }
         if (!Cools.isEmpty(basStation.getContainerType())) {
-            List<Long> longs1 = basStation.getContainerType();
+            List<Long> longs1 = basStation.getContainerType().stream()
+                    .map(Integer::longValue)
+                    .collect(Collectors.toList());
             List<BasContainer> containers = basContainerService.list(
                     new LambdaQueryWrapper<BasContainer>()
                             .in(BasContainer::getContainerType, longs1)
@@ -558,7 +536,9 @@
             throw new CoolException("绔欑偣鐘舵�佷笉涓虹┖闂�");
         }
         if (!Cools.isEmpty(basStation.getContainerType())) {
-            List<Long> longs1 = basStation.getContainerType();
+            List<Long> longs1 = basStation.getContainerType().stream()
+                    .map(Integer::longValue)
+                    .collect(Collectors.toList());
             List<BasContainer> containers = basContainerService.list(
                     new LambdaQueryWrapper<BasContainer>()
                             .in(BasContainer::getContainerType, longs1)
@@ -612,7 +592,9 @@
             }
             warehouseAreasList.add(warehouseArea);
         } else {
-            List<Long> areaList = basStation.getCrossZoneArea();
+            List<Long> areaList = basStation.getCrossZoneArea().stream()
+                    .map(Integer::longValue)
+                    .collect(Collectors.toList());
             if (areaList.isEmpty()) {
                 throw new CoolException("褰撳墠绔欑偣搴撳尯鏈厤缃�");
             }
@@ -678,10 +660,7 @@
                     throw new CoolException("浠诲姟淇濆瓨澶辫触锛侊紒");
                 }
 
-                if (!locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getCode, task.getTargLoc())
-                        .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, pakin.getBarcode()))) {
-                    throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
-                }
+                updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_S.type, pakin.getBarcode(), null, "搴撲綅棰勭害澶辫触锛侊紒", true);
                 /**鑾峰彇缁勬嫋鏄庣粏**/
                 List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, pakin.getId()));
                 if (waitPakinItems.isEmpty()) {
@@ -723,13 +702,7 @@
                 continue;
             }
 
-            if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
-                    .in(WaitPakin::getId, ids)
-                    .set(WaitPakin::getUpdateBy, loginUserId)
-                    .set(WaitPakin::getCreateBy, loginUserId)
-                    .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) {
-                throw new CoolException("缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-            }
+            updateWaitPakinsStatus(waitPakins, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val, loginUserId, true, "缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
             return R.ok("浠诲姟鐢熸垚瀹屾瘯锛�");
         }
         String msg = "鏈壘搴撲綅" + Arrays.toString(errMsg);
@@ -759,7 +732,7 @@
                     //绉诲簱
                     moveInStock(task, loginUserId);
                 } else if (task.getTaskType().equals(TaskType.TASK_TYPE_EMPTY_IN.type)) {
-                    //绉诲簱
+                    //绌烘澘鍏ュ簱
                     complateInstockE(task, loginUserId);
                 } else if (task.getTaskType().equals(TaskType.TASK_TYPE_CROSS_DOCKING_OUT.type)) {
                     //瓒婂簱
@@ -780,14 +753,14 @@
     @Transactional(rollbackFor = Exception.class)
     public Task taskToTop(Long id, Long loginUserId) throws Exception {
         List<Integer> longs = Arrays.asList(TaskStsType.GENERATE_IN.id, TaskStsType.GENERATE_OUT.id);
-        Task tasks = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getId, id).in(Task::getTaskStatus, longs));
+        Task tasks = this.getOne(new LambdaQueryWrapper<Task>().eq(Task::getId, id).in(Task::getTaskStatus, longs));
         if (Objects.isNull(tasks)) {
             throw new CoolException("浠诲姟宸插鎵ц鐘舵�佷笉鍙竴閿疆椤讹紒锛�");
         }
         //鍒ゆ柇娴呭簱浣嶄换鍔★紝淇敼浠诲姟浼樺厛绾�
         modiftyTaskSort(tasks, loginUserId);
 
-        if (!taskService.updateById(tasks)) {
+        if (!this.updateById(tasks)) {
             throw new CoolException("缃《澶辫触锛侊紒");
         }
         return null;
@@ -803,26 +776,128 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Task operateComplete(Long id, Long loginUserId) {
-        List<Integer> longs = Arrays.asList(TaskStsType.GENERATE_IN.id, TaskStsType.GENERATE_OUT.id);
-        Task task = taskService.getOne(new LambdaQueryWrapper<Task>()
-                .eq(Task::getId, id)
-                .in(Task::getTaskStatus, longs));
-
+        Task task = getById(id);
         if (Objects.isNull(task)) {
-            throw new CoolException("鏁版嵁閿欒锛氬綋鍓嶄换鍔′笉鍙墽琛屽畬缁撴搷浣滐紒锛�");
+            throw new CoolException("鏁版嵁閿欒锛氫换鍔′笉瀛樺湪锛侊紒");
         }
-
+        if (task.getTaskStatus() != null && TERMINAL_OR_WAITING_STATUS.contains(task.getTaskStatus())) {
+            throw new CoolException("浠诲姟宸插浜庣粓鎬佹垨绛夊緟搴撳瓨鏇存柊锛屾棤闇�瀹岀粨");
+        }
+        List<FlowStepInstance> steps = flowStepInstanceService.list(
+                new LambdaQueryWrapper<FlowStepInstance>()
+                        .eq(FlowStepInstance::getTaskNo, task.getTaskCode())
+                        .orderByAsc(FlowStepInstance::getStepOrder));
+        int maxCompletedOrder = steps.stream()
+                .filter(s -> s.getStepOrder() != null && s.getStatus() != null && s.getStatus() == 3)
+                .mapToInt(FlowStepInstance::getStepOrder)
+                .max().orElse(-1);
+        for (FlowStepInstance step : steps) {
+            if (step.getStepOrder() != null && step.getStepOrder() > maxCompletedOrder) {
+                step.setStatus((short) 5);
+                flowStepInstanceService.updateById(step);
+            }
+        }
         modiftyTaskSort(task, loginUserId);
-        //
-//        if (task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type)) {
-//            task.setTaskStatus(TaskStsType.COMPLETE_OUT.id);
-//        } else {
-        task.setTaskStatus(task.getTaskType() < 100 ? TaskStsType.COMPLETE_IN.id : task.getTaskType()==101? TaskStsType.COMPLETE_OUT.id:TaskStsType.AWAIT.id);
-//        }
-        if (!this.updateById(task)) {
-            throw new CoolException("瀹屾垚浠诲姟澶辫触");
+        applyTransferEndStatus(task);
+        // applyTransferEndStatus 鏈尮閰嶅埌鐨勪换鍔$被鍨嬶紙鏈疆涓� 98/196/198/9999锛夋椂鍏滃簳缃粓鎬�
+        if (task.getTaskStatus() == null || (!task.getTaskStatus().equals(TaskStsType.COMPLETE_IN.id)
+                && !task.getTaskStatus().equals(TaskStsType.AWAIT.id)
+                && !task.getTaskStatus().equals(TaskStsType.COMPLETE_OUT.id)
+                && !task.getTaskStatus().equals(TaskStsType.MISSION_TRANSFER.id))) {
+            task.setTaskStatus(task.getTaskType() != null && task.getTaskType() < 100
+                    ? TaskStsType.COMPLETE_IN.id
+                    : Integer.valueOf(101).equals(task.getTaskType()) ? TaskStsType.COMPLETE_OUT.id : TaskStsType.AWAIT.id);
+            updateById(task);
         }
         return task;
+    }
+    @Override
+    public void applyTransferEndStatus(Task task) {
+        if (TaskType.TASK_TYPE_IN.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_PICK_IN.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_CHECK_IN.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_EMPTY_IN.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_MERGE_IN.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_LOC_MOVE.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_OUT.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_PICK_AGAIN_OUT.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_MERGE_OUT.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_CHECK_OUT.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_CROSS_DOCKING_OUT.type.equals(task.getTaskType())
+                || TaskType.TASK_TYPE_EMPTY_OUT.type.equals(task.getTaskType())) {
+            task.setTaskStatus(TaskStsType.MISSION_TRANSFER.id);
+        } else {
+            return;
+        }
+        updateById(task);
+    }
+
+    /** 缁堟�佹垨绛夊緟瀹氭椂浠诲姟鏇存柊搴撳瓨鐨勭姸鎬併��9999锛屼笉灞曠ず瀹岀粨鎸夐挳 */
+    private static final Set<Integer> TERMINAL_OR_WAITING_STATUS = new HashSet<>(Arrays.asList(
+            TaskStsType.COMPLETE_IN.id, TaskStsType.REPORT_IN.id, TaskStsType.UPDATED_IN.id,
+            TaskStsType.COMPLETE_OUT.id, TaskStsType.WAVE_SEED.id, TaskStsType.UPDATED_OUT.id,
+            TaskStsType.MISSION_TRANSFER.id, TaskStsType.MISSION_TRANSFER_END.id));
+
+    /** 缁堟��/9999 鏃犳寜閽紱鐘舵�佸湪姝ラ涓壘涓嶅埌鎴栨棤涓嬩竴姝ワ紙鏈�鍚庝竴姝ワ級鍒欐棤瀹岀粨鎸夐挳 */
+    @Override
+    public void fillCanComplete(List<Task> tasks) {
+        if (tasks == null || tasks.isEmpty()) {
+            return;
+        }
+        Set<Integer> terminalSet = TERMINAL_OR_WAITING_STATUS;
+        List<String> codes = tasks.stream().map(Task::getTaskCode).filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        if (codes.isEmpty()) {
+            tasks.forEach(t -> {
+                t.setCanComplete(Boolean.FALSE);
+                t.setCanCancel(Boolean.FALSE);
+                if (t.getTaskStatus() != null && t.getTaskStatus().equals(TaskStsType.MISSION_INITIAL.id) && !isPhase2InboundType(t.getTaskType())) {
+                    t.setCanCancel(Boolean.TRUE);
+                }
+            });
+            return;
+        }
+        List<FlowStepInstance> steps = codes.size() == 1
+                ? flowStepInstanceService.list(new LambdaQueryWrapper<FlowStepInstance>().eq(FlowStepInstance::getTaskNo, codes.get(0)).orderByAsc(FlowStepInstance::getStepOrder))
+                : flowStepInstanceService.list(new LambdaQueryWrapper<FlowStepInstance>().in(FlowStepInstance::getTaskNo, codes).orderByAsc(FlowStepInstance::getStepOrder));
+        Map<String, List<FlowStepInstance>> stepsByTaskNo = steps.stream().collect(Collectors.groupingBy(FlowStepInstance::getTaskNo));
+        for (Task task : tasks) {
+            if (task.getTaskStatus() != null && terminalSet.contains(task.getTaskStatus())) {
+                task.setCanComplete(Boolean.FALSE);
+                task.setCanCancel(Boolean.FALSE);
+                continue;
+            }
+            // taskStatus=0锛堣矾寰勮鍒掍腑锛夊彲鍙栨秷锛涗簩闃舵鍏ュ簱锛堟嫞鏂�/鐩樼偣/骞舵澘鍏ュ簱锛変笉鍙彇娑�
+            if (task.getTaskStatus() != null && task.getTaskStatus().equals(TaskStsType.MISSION_INITIAL.id)) {
+                task.setCanCancel(!isPhase2InboundType(task.getTaskType()));
+                task.setCanComplete(Boolean.FALSE);
+                continue;
+            }
+            List<FlowStepInstance> taskSteps = stepsByTaskNo.get(task.getTaskCode());
+            if (taskSteps == null || taskSteps.isEmpty()) {
+                task.setCanComplete(Boolean.FALSE);
+                task.setCanCancel(Boolean.FALSE);
+                continue;
+            }
+            FlowStepInstance match = taskSteps.stream()
+                    .filter(s -> s.getWmsNowTaskStatus() != null && s.getWmsNowTaskStatus().equals(task.getTaskStatus()))
+                    .findFirst().orElse(null);
+            if (match == null) {
+                task.setCanComplete(Boolean.FALSE);
+                task.setCanCancel(Boolean.FALSE);
+                continue;
+            }
+            boolean isLastStep = match.getWmsNextTaskStatus() == null || match.getWmsNextTaskStatus().equals(TaskStsType.MISSION_TRANSFER.id);
+            task.setCanComplete(!isLastStep);
+            task.setCanCancel(!isLastStep && !isPhase2InboundType(task.getTaskType()));
+        }
+    }
+
+    /** 浜岄樁娈靛叆搴擄細鎷f枡鍏ュ簱銆佺洏鐐瑰叆搴撱�佸苟鏉垮叆搴擄紝涓嶅彲鍙栨秷 */
+    private boolean isPhase2InboundType(Integer taskType) {
+        if (taskType == null) return false;
+        return taskType.equals(TaskType.TASK_TYPE_PICK_IN.type)
+                || taskType.equals(TaskType.TASK_TYPE_CHECK_IN.type)
+                || taskType.equals(TaskType.TASK_TYPE_MERGE_IN.type);
     }
 
     /**
@@ -850,7 +925,7 @@
                 throw new CoolException("鏁版嵁閿欒锛屽簱浣嶄笉瀛樺湪锛侊紒");
             }
             if (loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_S.type) || loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_R.type)) {
-                Task serviceOne = taskService.getOne(new LambdaQueryWrapper<Task>()
+                Task serviceOne = this.getOne(new LambdaQueryWrapper<Task>()
                         .eq(Task::getOrgLoc, loc.getCode())
                         .or()
                         .eq(Task::getTargLoc, loc.getCode()));
@@ -927,7 +1002,7 @@
         }
 
         List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
-
+        String type = LocStsType.LOC_STS_TYPE_F.type;
         if (!taskItems.isEmpty()) {
             //绉诲簱鏈夊彲鑳芥槸绌烘澘
             try {
@@ -940,33 +1015,16 @@
             if (!locItemService.remove(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocCode, task.getOrgLoc()))) {
                 throw new CoolException("婧愬簱浣嶆槑缁嗗垹闄ゅけ璐ワ紒");
             }
+        } else {
+            type = LocStsType.LOC_STS_TYPE_D.type;
         }
 
         /**淇敼搴撲綅鐘舵�佷负F.鍦ㄥ簱*/
-        if (!locService.update(new LambdaUpdateWrapper<Loc>()
-                .set(Loc::getBarcode, task.getBarcode())
-                .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type)
-                .set(Loc::getUpdateBy, loginUserId)
-                .set(Loc::getUpdateTime, new Date())
-                .eq(Loc::getCode, task.getTargLoc()))) {
-            throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
+        updateLocByCode(task.getTargLoc(), type, task.getBarcode(), loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
 
-        if (!locService.update(new LambdaUpdateWrapper<Loc>()
-                .set(Loc::getBarcode, null)
-                .set(Loc::getUpdateBy, loginUserId)
-                .set(Loc::getUpdateTime, new Date())
-                .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
-                .eq(Loc::getCode, task.getOrgLoc()))) {
-            throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
+        updateLocByCode(task.getOrgLoc(), LocStsType.LOC_STS_TYPE_O.type, null, loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
 
-        if (!this.update(new LambdaUpdateWrapper<Task>().eq(Task::getId, task.getId())
-                .set(Task::getUpdateBy, loginUserId)
-                .set(Task::getUpdateTime, new Date())
-                .set(Task::getTaskStatus, TaskStsType.UPDATED_IN.id))) {
-            throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
+        updateTaskSnapshot(task, TaskStsType.UPDATED_IN.id, loginUserId, "浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
 
     }
 
@@ -990,12 +1048,14 @@
                 } else if (task.getTaskType().equals(TaskType.TASK_TYPE_CROSS_DOCKING_OUT.type)) {
                     //109.澶囪揣
                     complateOutStockDocking(task, loginUserId);
-                } else if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
+                } else if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) {
                     //107.鐩�
-                    pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK);
-                } else if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) {
-                    //103.鎷i��
-                    pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_PICK);
+//                    pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_CHECK);
+                    complateOutStock2(task, loginUserId);
+//                } else if () {
+//                    //103.鎷i��
+////                    pickOrCheckTask(task.getId(), Constants.TASK_TYPE_OUT_PICK);
+//                    complateOutStock2(task, loginUserId);
                 } else {
                     complateOutStock(task, loginUserId);
                 }
@@ -1044,7 +1104,7 @@
                     .eq(LocItemWorking::getTaskId, taskItem.getTaskId())
                     .eq(LocItemWorking::getFieldsIndex, taskItem.getFieldsIndex())
                     .eq(StringUtils.isNotEmpty(taskItem.getBatch()), LocItemWorking::getBatch, taskItem.getBatch())
-                    .eq(LocItemWorking::getMatnrId, taskItem.getMatnrId()));
+                    .eq(LocItemWorking::getMatnrId, taskItem.getMatnrId()).last("limit 1"));
             if (Objects.isNull(locWorking)) {
                continue;
             }
@@ -1067,7 +1127,7 @@
         locItemWorkingService.remove(new LambdaQueryWrapper<LocItemWorking>().eq(LocItemWorking::getTaskId, task.getId()));
 
         task.setTaskStatus(TaskStsType.UPDATED_IN.id).setUpdateTime(new Date()).setUpdateBy(loginUserId);
-        if (!taskService.updateById(task)) {
+        if (!this.updateById(task)) {
             throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
         }
 
@@ -1124,10 +1184,57 @@
         locItemWorkingService.remove(new LambdaQueryWrapper<LocItemWorking>().eq(LocItemWorking::getTaskId, task.getId()));
 
         task.setTaskStatus(TaskStsType.UPDATED_IN.id).setUpdateTime(new Date()).setUpdateBy(loginUserId);
-        if (!taskService.updateById(task)) {
+        if (!this.updateById(task)) {
             throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
         }
+        // 鐩樼偣鍐嶅叆搴撲换鍔$粨鏉燂細灏嗗叧鑱旂殑鐩樼偣宸紓鍗曠疆涓哄凡瀹℃牳
+        if (TaskType.TASK_TYPE_CHECK_IN.type.equals(task.getTaskType())) {
+            markCheckDiffApprovedWhenCheckInDone(task);
+        }
+    }
 
+    /**
+     * 鐩樼偣鍐嶅叆搴撳畬鎴愬悗锛屽皢鏈崟瀵瑰簲鐨勫樊寮傛槑缁嗙疆涓哄凡瀹℃牳锛屽叏閮ㄦ槑缁嗗凡瀹℃牳鍚庡樊寮傚崟鏈韩缃负宸插鏍革紙鏈夊崟鎸� orderId锛屾棤鍗曟寜 鍑哄簱浠诲姟鍙� orderCode锛�
+     */
+    @Override
+    public void markCheckDiffApprovedWhenCheckInDone(Task checkInTask) {
+        Task outTask = this.getOne(new LambdaQueryWrapper<Task>()
+                .eq(Task::getBarcode, checkInTask.getBarcode())
+                .eq(Task::getTaskType, TaskType.TASK_TYPE_CHECK_OUT.type)
+                .last("limit 1"));
+        if (outTask == null) {
+            return;
+        }
+        List<TaskItem> inItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, checkInTask.getId()));
+        Long orderId = inItems.isEmpty() ? null : inItems.get(0).getOrderId();
+        CheckDiff checkDiff = null;
+        if (orderId != null && !orderId.equals(0L)) {
+            checkDiff = checkDiffService.getOne(new LambdaQueryWrapper<CheckDiff>().eq(CheckDiff::getOrderId, orderId).last("limit 1"));
+        } else {
+            checkDiff = checkDiffService.getOne(new LambdaQueryWrapper<CheckDiff>()
+                    .eq(CheckDiff::getOrderCode, outTask.getTaskCode())
+                    .and(w -> w.isNull(CheckDiff::getOrderId).or().eq(CheckDiff::getOrderId, 0))
+                    .last("limit 1"));
+        }
+        if (checkDiff == null) {
+            return;
+        }
+        List<TaskItem> outItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, outTask.getId()));
+        List<Long> outTaskItemIds = outItems.stream().map(TaskItem::getId).filter(Objects::nonNull).collect(Collectors.toList());
+        if (!outTaskItemIds.isEmpty()) {
+            checkDiffItemService.update(new LambdaUpdateWrapper<CheckDiffItem>()
+                    .eq(CheckDiffItem::getCheckId, checkDiff.getId())
+                    .in(CheckDiffItem::getTaskItemId, outTaskItemIds)
+                    .set(CheckDiffItem::getExceStatus, CheckDiffExceStatus.CHECK_DIFF_EXCE_STATUS_END.val));
+        }
+        long unApprovedCount = checkDiffItemService.count(new LambdaQueryWrapper<CheckDiffItem>()
+                .eq(CheckDiffItem::getCheckId, checkDiff.getId())
+                .ne(CheckDiffItem::getExceStatus, CheckDiffExceStatus.CHECK_DIFF_EXCE_STATUS_END.val));
+        if (unApprovedCount == 0 && !CheckDiffExceStatus.CHECK_DIFF_EXCE_STATUS_END.val.equals(checkDiff.getExceStatus())) {
+            checkDiffService.update(new LambdaUpdateWrapper<CheckDiff>()
+                    .eq(CheckDiff::getId, checkDiff.getId())
+                    .set(CheckDiff::getExceStatus, CheckDiffExceStatus.CHECK_DIFF_EXCE_STATUS_END.val));
+        }
     }
 
     /**
@@ -1140,32 +1247,28 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public R removeTask(Long[] ids, Long loginUserId) {
-        List<Integer> longs = Arrays.asList(TaskStsType.GENERATE_IN.id, TaskStsType.GENERATE_OUT.id);
         List<Integer> list = Arrays.asList(TaskType.TASK_TYPE_IN.type, TaskType.TASK_TYPE_OUT.type, TaskType.TASK_TYPE_PICK_AGAIN_OUT.type,
                 TaskType.TASK_TYPE_CHECK_OUT.type, TaskType.TASK_TYPE_EMPTY_IN.type, TaskType.TASK_TYPE_LOC_MOVE.type,
-                TaskType.TASK_TYPE_EMPTY_OUT.type, TaskType.TASK_TYPE_MERGE_OUT.type);
+                TaskType.TASK_TYPE_EMPTY_OUT.type, TaskType.TASK_TYPE_MERGE_OUT.type,
+                TaskType.TASK_TYPE_PICK_IN.type, TaskType.TASK_TYPE_CHECK_IN.type);
         List<Task> tasks = this.list(new LambdaQueryWrapper<Task>()
                 .in(Task::getTaskType, list)
-                .in(Task::getId, ids)
-                .in(Task::getTaskStatus, longs));
+                .in(Task::getId, ids));
         if (tasks.isEmpty()) {
-            throw new CoolException("浠诲姟宸插鎵ц鐘舵�佷笉鍙彇娑堬紒锛�");
+            throw new CoolException("浠诲姟涓嶅瓨鍦ㄦ垨绫诲瀷涓嶅厑璁稿彇娑堬紒锛�");
+        }
+        fillCanComplete(tasks);
+        List<Task> notCancelable = tasks.stream().filter(t -> !Boolean.TRUE.equals(t.getCanCancel())).collect(Collectors.toList());
+        if (!notCancelable.isEmpty()) {
+            throw new CoolException("閮ㄥ垎浠诲姟涓嶅彲鍙栨秷锛堟嫞鏂�/鐩樼偣/骞舵澘鍏ュ簱涓轰簩闃舵浠诲姟涓嶅彲鍙栨秷锛涘叾浠栦粎 taskStatus=0 鎴栨祦绋嬫湭鍒� 9999 鏃跺彲鍙栨秷锛夛紒锛�");
         }
         for (Task task : tasks) {
             //鍙栨秷绉诲簱浠诲姟
             if (task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type) && task.getTaskStatus().equals(TaskStsType.GENERATE_IN.id)) {
-                if (!locService.update(new LambdaUpdateWrapper<Loc>()
-                        .eq(Loc::getCode, task.getOrgLoc())
-                        .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type))) {
-                    throw new CoolException("婧愬簱浣嶇姸鎬佷慨鏀瑰け璐ワ紒锛�");
-                }
-                if (!locService.update(new LambdaUpdateWrapper<Loc>()
-                        .eq(Loc::getCode, task.getTargLoc())
-                        .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type))) {
-                    throw new CoolException("绉诲簱鐩爣搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-                }
+                updateLocByCode(task.getOrgLoc(), LocStsType.LOC_STS_TYPE_F.type, null, null, "婧愬簱浣嶇姸鎬佷慨鏀瑰け璐ワ紒锛�", false);
+                updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_O.type, null, null, "绉诲簱鐩爣搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", false);
 
-                Task outTask = taskService.getById(task.getParentId());
+                Task outTask = this.getById(task.getParentId());
                 if (!Objects.isNull(outTask)) {
                     LocToTaskParams params = new LocToTaskParams();
                     params.setOrgLoc(task.getOrgLoc()).setSiteNo(task.getOrgSite());
@@ -1190,11 +1293,7 @@
                             throw new CoolException("鏄庣粏鏁伴噺淇敼澶辫触锛侊紒");
                         }
 
-                        if (!checkOrderService.update(new LambdaUpdateWrapper<WkOrder>()
-                                .eq(WkOrder::getId, taskItem.getOrderId())
-                                .setSql("work_qty = work_qty - " + taskItem.getAnfme()))) {
-                            throw new CoolException("鐩樼偣鍗曟墽琛屾暟閲忎慨鏀瑰け璐ワ紒锛�");
-                        }
+                        updateWkOrderWorkQty(taskItem.getOrderId(), -taskItem.getAnfme(), null, "鐩樼偣鍗曟墽琛屾暟閲忎慨鏀瑰け璐ワ紒锛�");
 
                         CheckDiffItem serviceOne = checkDiffItemService.getOne(new LambdaQueryWrapper<CheckDiffItem>().eq(CheckDiffItem::getTaskItemId, taskItem.getId()));
 
@@ -1206,12 +1305,41 @@
                             }
                         }
                     });
+                    List<Long> orderIds = taskItems.stream()
+                            .map(TaskItem::getOrderId)
+                            .filter(Objects::nonNull)
+                            .filter(id -> !id.equals(0L))
+                            .distinct()
+                            .collect(Collectors.toList());
+                    for (Long orderId : orderIds) {
+                        updateWkOrderExceStatus(orderId, CheckExceStatus.CHECK_ORDER_STATUS_UN_EXCE.val, null, "鐩樼偣鍗曠姸鎬佷慨鏀瑰け璐ワ紒锛�");
+                    }
                 }
 
-                if (!locService.update(new LambdaUpdateWrapper<Loc>()
-                        .eq(Loc::getCode, task.getOrgLoc())
-                        .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type))) {
-                    throw new CoolException("婧愬簱浣嶇姸鎬佷慨鏀瑰け璐ワ紒锛�");
+                updateLocByCode(task.getOrgLoc(), LocStsType.LOC_STS_TYPE_F.type, null, null, "婧愬簱浣嶇姸鎬佷慨鏀瑰け璐ワ紒锛�", false);
+            }
+
+            // 鍑哄簱绫讳换鍔″彇娑堟椂锛屽洖閫�璺緞瑙勫垝闃舵鍗犵敤鐨勭洰鏍囩珯鐐癸紙S鈫扥锛�
+            if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)
+                    || task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
+                    || task.getTaskType().equals(TaskType.TASK_TYPE_MERGE_OUT.type)
+                    || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)
+                    || task.getTaskType().equals(TaskType.TASK_TYPE_EMPTY_OUT.type)) {
+                if (!Cools.isEmpty(task.getTargSite())) {
+                    LambdaQueryWrapper<BasStation> stationWrapper = new LambdaQueryWrapper<BasStation>()
+                            .eq(BasStation::getStationName, task.getTargSite())
+                            .eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_S.type);
+                    if (!Cools.isEmpty(task.getBarcode())) {
+                        stationWrapper.eq(BasStation::getBarcode, task.getBarcode());
+                    }
+                    BasStation targStation = basStationService.getOne(stationWrapper);
+                    if (targStation != null) {
+                        targStation.setUseStatus(LocStsType.LOC_STS_TYPE_O.type);
+                        targStation.setBarcode(null);
+                        if (!basStationService.updateById(targStation)) {
+                            throw new CoolException("閲婃斁鐩爣绔欑偣澶辫触锛侊紒");
+                        }
+                    }
                 }
             }
 
@@ -1233,7 +1361,9 @@
                 if (null == basStation) {
                     throw new CoolException("绔欑偣鐘舵�侀敊璇紒锛�");
                 }
-                basStation.setUseStatus(LocStsType.LOC_STS_TYPE_F.type);
+                if (!basStation.getType().equals(0)){
+                    basStation.setUseStatus(LocStsType.LOC_STS_TYPE_F.type);
+                }
                 if (!basStationService.updateById(basStation)) {
                     throw new CoolException("鏇存柊绔欑偣鐘舵�佸け璐ワ紒锛�");
                 }
@@ -1373,7 +1503,7 @@
         Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>()
                 .eq(Loc::getCode, task.getOrgLoc()));
         if (Objects.isNull(loc)) {
-            throw new CoolException("娌℃湁绌哄簱浣嶏紒锛�");
+            throw new CoolException("婧愬簱浣嶄笉瀛樺湪锛侊紒");
         }
 
         String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_TASK_CODE, task);
@@ -1419,9 +1549,9 @@
                 if (taskItem.getFieldsIndex().equals(working.getFieldsIndex())) {
                     Double minQty = taskItem.getAnfme();
                     if (!task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) {
-                        minQty = Math.round((working.getAnfme() - taskItem.getQty()) * 1000000) / 1000000.0;
+                        minQty = Math.round((working.getAnfme() - taskItem.getAnfme()) * 1000000) / 1000000.0;
                     }
-                    if (minQty.compareTo(0.0) >= 0) {
+                    if (!minQty.equals(0D) && minQty>0D) {
                         taskItem.setAnfme(minQty);
                         if (!taskItemService.updateById(taskItem)) {
                             throw new CoolException("浠诲姟鏄庣粏淇敼澶辫触锛侊紒");
@@ -1488,6 +1618,141 @@
             throw new CoolException("搴撲綅棰勭害鍏ュ簱澶辫触锛侊紒");
         }
         return task;
+    }
+
+    /**
+     * @author Ryan
+     * @date 2025/5/20
+     * @description: 瀹屾垚鍑哄簱浠诲姟锛屾洿鏂板嚭搴撳簱瀛樹俊鎭�
+     * @version 1.0
+     */
+    @Synchronized
+    @Transactional(rollbackFor = Exception.class)
+    public void complateOutStock2(Task task, Long loginUserId) throws Exception {
+        if (Objects.isNull(task)) {
+            throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, task.getOrgLoc()));
+        if (Objects.isNull(loc)) {
+            throw new CoolException("搴撲綅涓嶅瓨鍦紒锛�");
+        }
+        if (!loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_R.type)) {
+            throw new CoolException("搴撲綅鐘舵�佷笉澶勭悊浜嶳.鍑哄簱棰勭害锛侊紒");
+        }
+
+        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
+        if (taskItems.isEmpty()) {
+            throw new CoolException("浠诲姟鏄庣粏涓嶅瓨鍦紒锛�");
+        }
+
+        List<LocItem> locItems = locItemService.list(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocId, loc.getId()));
+        if (locItems.isEmpty()) {
+            throw new CoolException("搴撲綅鏄庣粏涓嶅瓨鍦紒锛�");
+        }
+
+//        List<LocItemWorking> workings = new ArrayList<>();
+//        for (LocItem item : locItems) {
+//            LocItemWorking working = new LocItemWorking();
+//            BeanUtils.copyProperties(item, working);
+//            working.setId(null)
+//                    .setTaskId(task.getId())
+//                    .setLocItemId(item.getId())
+//                    .setUpdateBy(loginUserId)
+//                    .setUpdateTime(new Date());
+//            workings.add(working);
+//        }
+//
+//        if (!locItemWorkingService.saveBatch(workings)) {
+//            throw new CoolException("涓存椂搴撳瓨淇濆瓨澶辫触锛侊紒");
+//        }
+
+        try {
+            //鏇存柊搴撲綅鏄庣粏
+            subtractLocItem(loc);
+        } catch (Exception e) {
+            logger.error("<UNK>", e);
+            throw new CoolException(e.getMessage());
+        }
+
+        //娣诲姞鍑哄叆搴撹褰曚俊鎭�
+        Map<Short, List<TaskItem>> listMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getWkType));
+        /***鑾峰彇搴撳瓨鍑哄簱鍊硷紝濡傛灉涓虹┖琛ㄧず姝e父鍗曟嵁鍑哄簱锛岄潪绌鸿〃鏄庢槸搴撳瓨鍑哄簱
+         * 1. 搴撳瓨鍑哄簱娌℃湁鍗曟嵁淇℃伅锛屽崟鎹俊鎭粯璁や负绌�
+         * 2. 鍗曟嵁搴撳瓨闇�閫氳繃娉㈡鏌ヨ鍘熷鍗曟嵁淇℃伅锛屽皢鍗曟嵁淇℃伅濉叆stock涓�
+         * */
+        List<TaskItem> list = listMap.get(Short.parseShort(OrderWorkType.ORDER_WORK_TYPE_STOCK_OUT.type));
+        if (Objects.isNull(list) || list.isEmpty()) {
+            Map<Long, List<TaskItem>> maps = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getSource));
+            maps.keySet().forEach(key -> {
+                if (task.getResource().equals(TaskResouceType.TASK_RESOUCE_WAVE_TYPE.val)) {
+                    WaveItem waveItem = waveItemService.getById(key);
+                    if (Objects.isNull(waveItem)) {
+                        throw new CoolException("娉㈡鏄庣粏涓嶅瓨鍦紒锛�");
+                    }
+//                    try {
+//                        saveOutStockItem(maps.get(key), null, waveItem, null, loginUserId);
+//                    } catch (Exception e) {
+//                        throw new CoolException(e.getMessage());
+//                    }
+                } else if (task.getResource().equals(TaskResouceType.TASK_RESOUCE_ORDER_TYPE.val)) {
+                    WkOrderItem orderItem = asnOrderItemService.getById(key);
+                    if (Objects.isNull(orderItem)) {
+                        throw new CoolException("鍗曟嵁鏄庣粏涓嶅瓨鍦紒锛�");
+                    }
+                    try {
+                        saveOutStockItem(maps.get(key), orderItem,  loginUserId);
+                    } catch (Exception e) {
+                        throw new CoolException(e.getMessage());
+                    }
+                } else if (task.getResource().equals(TaskResouceType.TASK_RESOUCE_CHECK_TYPE.val)) {
+                    WkOrderItem orderItem = asnOrderItemService.getById(key);
+                    if (Objects.isNull(orderItem)) {
+                        throw new CoolException("鍗曟嵁鏄庣粏涓嶅瓨鍦紒锛�");
+                    }
+                    try {
+                        saveOutStockItem(maps.get(key), null, null, orderItem, loginUserId);
+                    } catch (Exception e) {
+                        throw new CoolException(e.getMessage());
+                    }
+                } else {
+
+                }
+            });
+        } else {
+            try {
+                saveOutStockItem(taskItems, null, null, null, loginUserId);
+            } catch (Exception e) {
+                throw new CoolException(e.getMessage());
+            }
+        }
+
+        /**淇敼涓哄簱浣嶇姸鎬佷负O.绌哄簱*/
+        updateLocSnapshot(loc, LocStsType.LOC_STS_TYPE_O.type, null, loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
+
+        updateTaskSnapshot(task, TaskStsType.WAVE_SEED.id, loginUserId, "搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
+
+//        if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
+//            if (!this.update(new LambdaUpdateWrapper<Task>()
+//                    .eq(Task::getId, task.getId())
+//                    .set(Task::getUpdateBy, loginUserId)
+//                    .set(Task::getUpdateTime, new Date())
+//                    .set(Task::getTaskStatus, TaskStsType.WAVE_SEED.id))) {
+//                throw new CoolException("搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
+//            }
+//        } else {
+//            if (!this.update(new LambdaUpdateWrapper<Task>()
+//                    .eq(Task::getId, task.getId())
+//                    .set(Task::getUpdateBy, loginUserId)
+//                    .set(Task::getUpdateTime, new Date())
+//                    .set(Task::getTaskStatus, TaskStsType.WAVE_SEED.id))) {
+//                throw new CoolException("搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
+//            }
+////            //鍏ㄦ澘鍑哄簱锛屽垹闄や复鏃跺簱瀛�
+////            if (!locItemWorkingService.remove(new LambdaQueryWrapper<LocItemWorking>().eq(LocItemWorking::getTaskId, task.getId()))) {
+////                throw new CoolException("涓存椂搴撳瓨娓呴櫎澶辫触锛侊紒");
+////            }
+//        }
+
     }
 
     /**
@@ -1597,22 +1862,9 @@
         }
 
         /**淇敼涓哄簱浣嶇姸鎬佷负O.绌哄簱*/
-        if (!locService.update(new LambdaUpdateWrapper<Loc>()
-                .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
-                .set(Loc::getBarcode, null)
-                .set(Loc::getUpdateBy, loginUserId)
-                .set(Loc::getUpdateTime, new Date())
-                .eq(Loc::getId, loc.getId()))) {
-            throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
+        updateLocSnapshot(loc, LocStsType.LOC_STS_TYPE_O.type, null, loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
 
-        if (!this.update(new LambdaUpdateWrapper<Task>()
-                .eq(Task::getId, task.getId())
-                .set(Task::getUpdateBy, loginUserId)
-                .set(Task::getUpdateTime, new Date())
-                .set(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id))) {
-            throw new CoolException("搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
-        }
+        updateTaskSnapshot(task, TaskStsType.UPDATED_OUT.id, loginUserId, "搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
 
 //        if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
 //            if (!this.update(new LambdaUpdateWrapper<Task>()
@@ -1713,22 +1965,24 @@
         }
 
         /**淇敼涓哄簱浣嶇姸鎬佷负O.绌哄簱*/
-        if (!locService.update(new LambdaUpdateWrapper<Loc>()
-                .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type)
-                .set(Loc::getBarcode, loc.getBarcode())
-                .set(Loc::getUpdateBy, loginUserId)
-                .set(Loc::getUpdateTime, new Date())
-                .eq(Loc::getId, loc.getId()))) {
-            throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
+        updateLocSnapshot(loc, LocStsType.LOC_STS_TYPE_S.type, loc.getBarcode(), loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
 
-        if (!this.update(new LambdaUpdateWrapper<Task>()
-                .eq(Task::getId, task.getId())
-                .set(Task::getUpdateBy, loginUserId)
-                .set(Task::getUpdateTime, new Date())
-                .set(Task::getTargLoc, task.getOrgLoc())
-                .set(Task::getTaskStatus, TaskStsType.COMPLETE_IN.id))) {
+        Task update = new Task();
+        update.setId(task.getId());
+        update.setVersion(task.getVersion());
+        update.setUpdateBy(loginUserId);
+        update.setUpdateTime(new Date());
+        update.setTargLoc(task.getOrgLoc());
+        update.setTaskStatus(TaskStsType.COMPLETE_IN.id);
+        if (!this.updateById(update)) {
             throw new CoolException("搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
+        }
+        task.setUpdateBy(loginUserId);
+        task.setUpdateTime(update.getUpdateTime());
+        task.setTargLoc(task.getOrgLoc());
+        task.setTaskStatus(TaskStsType.COMPLETE_IN.id);
+        if (update.getVersion() != null) {
+            task.setVersion(update.getVersion());
         }
     }
 
@@ -1753,22 +2007,9 @@
         }
 
         /**淇敼涓哄簱浣嶇姸鎬佷负O.绌哄簱*/
-        if (!locService.update(new LambdaUpdateWrapper<Loc>()
-                .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
-                .set(Loc::getBarcode, null)
-                .set(Loc::getUpdateBy, loginUserId)
-                .set(Loc::getUpdateTime, new Date())
-                .eq(Loc::getId, loc.getId()))) {
-            throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
+        updateLocSnapshot(loc, LocStsType.LOC_STS_TYPE_O.type, null, loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
 
-        if (!this.update(new LambdaUpdateWrapper<Task>()
-                .eq(Task::getId, task.getId())
-                .set(Task::getUpdateBy, loginUserId)
-                .set(Task::getUpdateTime, new Date())
-                .set(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id))) {
-            throw new CoolException("搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
-        }
+        updateTaskSnapshot(task, TaskStsType.UPDATED_OUT.id, loginUserId, "搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
     }
 
     /**
@@ -1862,7 +2103,7 @@
             return R.error("浠诲姟缂栫爜涓嶈兘涓虹┖锛侊紒");
         }
         List<Integer> integers = Arrays.asList(TaskStsType.GENERATE_IN.id, TaskStsType.GENERATE_OUT.id);
-        List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>()
+        List<Task> tasks = this.list(new LambdaQueryWrapper<Task>()
                 .in(Task::getId, ids)
                 .in(Task::getTaskStatus, integers)
                 .orderByDesc(Task::getSort));
@@ -1876,7 +2117,7 @@
             }
         }
 
-        taskService.pubTaskToWcs(tasks);
+        this.pubTaskToWcs(tasks);
 
         return R.ok();
     }
@@ -1910,12 +2151,16 @@
             /**鍒ゆ柇鏄惁鍏夌數绔欑偣锛岄潪鍏夊簵绔欑偣闇�绠℃帶绔欑偣鐘舵��*/
             if (!Objects.isNull(station) && station.getType().equals(StationTypeEnum.STATION_TYPE_NORMAL.type)) {
                 if (task.getTaskType() <= TaskType.TASK_TYPE_CHECK_IN.type && !task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type)) {
-                    station.setUseStatus(LocStsType.LOC_STS_TYPE_R.type);
+                    if (!station.getType().equals(0)){
+                        station.setUseStatus(LocStsType.LOC_STS_TYPE_R.type);
+                    }
                     if (!basStationService.updateById(station)) {
                         throw new CoolException("绔欑偣鐘舵�佹洿鏂板け璐ワ紒锛�");
                     }
                 } else if (task.getTaskType() >= TaskType.TASK_TYPE_OUT.type) {
-                    station.setUseStatus(LocStsType.LOC_STS_TYPE_S.type);
+                    if (!station.getType().equals(0)){
+                        station.setUseStatus(LocStsType.LOC_STS_TYPE_S.type);
+                    }
                     if (!basStationService.updateById(station)) {
                         throw new CoolException("绔欑偣鐘舵�佹洿鏂板け璐ワ紒锛�");
                     }
@@ -1998,10 +2243,7 @@
                                 throw new CoolException("绔欑偣涓嶅瓨鍦紒锛�");
                             }
 
-                            if (!taskService.update(new LambdaUpdateWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode())
-                                    .set(Task::getTaskStatus, TaskStsType.WCS_EXECUTE_IN.id))) {
-                                throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-                            }
+                            updateTaskSnapshot(task, TaskStsType.WCS_EXECUTE_IN.id, null, "浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
                             /**鎺掗櫎绉诲簱鍔熻兘*/
                             if (!task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type)) {
                                 /**濡傛灉鏄櫘閫氱珯鐐癸紝淇敼绔欑偣鐘舵�佷负鍑哄簱棰勭害*/
@@ -2022,10 +2264,7 @@
                                 throw new CoolException("绔欑偣涓嶅瓨鍦紒锛�");
                             }
 
-                            if (!taskService.update(new LambdaUpdateWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode())
-                                    .set(Task::getTaskStatus, TaskStsType.WCS_EXECUTE_OUT.id))) {
-                                throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-                            }
+                            updateTaskSnapshot(task, TaskStsType.WCS_EXECUTE_OUT.id, null, "浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
                             /**濡傛灉鏄櫘閫氱珯鐐癸紝淇敼绔欑偣鐘舵�佷负鍏ュ簱棰勭害*/
                             if (curSta.getType().equals(StationTypeEnum.STATION_TYPE_NORMAL.type)) {
                                 curSta.setUseStatus(LocStsType.LOC_STS_TYPE_S.type);
@@ -2103,12 +2342,8 @@
             removeReceiptStock(pakinItem, loginUserId);
         });
         /**淇敼搴撲綅鐘舵�佷负F.鍦ㄥ簱*/
-        if (!locService.update(new LambdaUpdateWrapper<Loc>().set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type).eq(Loc::getCode, task.getTargLoc()))) {
-            throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
-        if (!this.update(new LambdaUpdateWrapper<Task>().eq(Task::getId, task.getId()).set(Task::getTaskStatus, TaskStsType.UPDATED_IN.id))) {
-            throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
+        updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_F.type, null, null, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", false);
+        updateTaskSnapshot(task, TaskStsType.UPDATED_IN.id, null, "浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
     }
 
     /**
@@ -2133,12 +2368,8 @@
         }
 
         /**淇敼搴撲綅鐘舵�佷负"D", "绌烘澘"*/
-        if (!locService.update(new LambdaUpdateWrapper<Loc>().set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_D.type).eq(Loc::getCode, task.getTargLoc()))) {
-            throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
-        if (!this.update(new LambdaUpdateWrapper<Task>().eq(Task::getId, task.getId()).set(Task::getTaskStatus, TaskStsType.UPDATED_IN.id))) {
-            throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
+        updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_D.type, null, null, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", false);
+        updateTaskSnapshot(task, TaskStsType.UPDATED_IN.id, null, "浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
     }
 
     /**
@@ -2151,32 +2382,35 @@
      */
     @Transactional(rollbackFor = Exception.class)
     public synchronized void removeReceiptStock(WaitPakinItem pakinItem, Long loginUserId) {
-        WarehouseAreasItem itemServiceOne = warehouseAreasItemService.getOne(new LambdaQueryWrapper<WarehouseAreasItem>()
-                .eq(WarehouseAreasItem::getId, pakinItem.getSource()));
-        if (Objects.isNull(itemServiceOne)) {
-            throw new CoolException("鏁版嵁閿欒锛氳鏌ョ湅璇疯揣鍖哄簱瀛樻槸鍚﹀瓨鍦紒锛�");
-        }
-        Double workQty = Math.round((itemServiceOne.getWorkQty() - pakinItem.getAnfme()) * 1000000) / 1000000.0;
-        Double qty = Math.round((itemServiceOne.getQty() + pakinItem.getAnfme()) * 1000000) / 1000000.0;
-        itemServiceOne.setWorkQty(workQty).setQty(qty);
-
-        if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
-                .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val)
-                .set(WaitPakin::getUpdateBy, loginUserId)
-                .eq(WaitPakin::getId, pakinItem.getPakinId()))) {
-            throw new CoolException("缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
-        }
-
-        if (qty.compareTo(itemServiceOne.getAnfme()) == 0.00) {
-            if (!warehouseAreasItemService.removeById(itemServiceOne.getId())) {
-                throw new CoolException("鏀惰揣鍖虹墿鏂欏垹闄ゅけ璐ワ紒锛�");
+        if (pakinItem.getType().equals(OrderType.ORDER_PRE.type)){
+            updateWaitPakinById(pakinItem.getPakinId(), PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val, loginUserId, "缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+        }else {
+            WarehouseAreasItem itemServiceOne = warehouseAreasItemService.getOne(new LambdaQueryWrapper<WarehouseAreasItem>()
+                    .eq(WarehouseAreasItem::getId, pakinItem.getSource()));
+            if (Objects.isNull(itemServiceOne)) {
+                log.error("鏁版嵁閿欒锛氳鏌ョ湅璇疯揣鍖哄簱瀛樻槸鍚﹀瓨鍦紒锛�"+pakinItem.getPakinId());
+                return;
+//            throw new CoolException("锛�");
+//            throw new CoolException("鏁版嵁閿欒锛氳鏌ョ湅璇疯揣鍖哄簱瀛樻槸鍚﹀瓨鍦紒锛�");
             }
-        } else {
-            itemServiceOne.setUpdateBy(loginUserId).setUpdateTime(null);
-            if (!warehouseAreasItemService.updateById(itemServiceOne)) {
-                throw new CoolException("鏀惰揣鍖哄簱瀹屾垚鏁伴噺淇敼澶辫触锛侊紒");
+            Double workQty = Math.round((itemServiceOne.getWorkQty() - pakinItem.getAnfme()) * 1000000) / 1000000.0;
+            Double qty = Math.round((itemServiceOne.getQty() + pakinItem.getAnfme()) * 1000000) / 1000000.0;
+            itemServiceOne.setWorkQty(workQty).setQty(qty);
+
+            updateWaitPakinById(pakinItem.getPakinId(), PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val, loginUserId, "缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+
+            if (qty.compareTo(itemServiceOne.getAnfme()) == 0.00) {
+                if (!warehouseAreasItemService.removeById(itemServiceOne.getId())) {
+                    throw new CoolException("鏀惰揣鍖虹墿鏂欏垹闄ゅけ璐ワ紒锛�");
+                }
+            } else {
+                itemServiceOne.setUpdateBy(loginUserId).setUpdateTime(null);
+                if (!warehouseAreasItemService.updateById(itemServiceOne)) {
+                    throw new CoolException("鏀惰揣鍖哄簱瀹屾垚鏁伴噺淇敼澶辫触锛侊紒");
+                }
             }
         }
+
     }
 
     /**
@@ -2293,4 +2527,156 @@
             }
         }
     }
+
+    private void updateLocByCode(String locCode, String useStatus, String barcode, Long loginUserId, String errorMessage, boolean updateBarcode) {
+        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, locCode), false);
+        if (Objects.isNull(loc)) {
+            throw new CoolException("搴撲綅涓嶅瓨鍦紒锛�");
+        }
+        updateLocSnapshot(loc, useStatus, barcode, loginUserId, errorMessage, updateBarcode);
+    }
+
+    private void updateLocSnapshot(Loc loc, String useStatus, String barcode, Long loginUserId, String errorMessage, boolean updateBarcode) {
+        Loc update = new Loc();
+        update.setId(loc.getId());
+        update.setVersion(loc.getVersion());
+        update.setUseStatus(useStatus);
+        if (updateBarcode) {
+            update.setBarcode(barcode);
+        }
+        if (loginUserId != null) {
+            update.setUpdateBy(loginUserId);
+            update.setUpdateTime(new Date());
+        }
+        if (!locService.updateById(update)) {
+            throw new CoolException(errorMessage);
+        }
+        loc.setUseStatus(useStatus);
+        if (updateBarcode) {
+            loc.setBarcode(barcode);
+        }
+        if (loginUserId != null) {
+            loc.setUpdateBy(loginUserId);
+            loc.setUpdateTime(update.getUpdateTime());
+        }
+        if (update.getVersion() != null) {
+            loc.setVersion(update.getVersion());
+        }
+    }
+
+    private void updateWaitPakinById(Long pakinId, Short ioStatus, Long loginUserId, String errorMessage) {
+        WaitPakin waitPakin = waitPakinService.getById(pakinId);
+        if (Objects.isNull(waitPakin)) {
+            throw new CoolException("缁勬嫋涓嶅瓨鍦紒锛�");
+        }
+        updateWaitPakinSnapshot(waitPakin, ioStatus, loginUserId, false, errorMessage);
+    }
+
+    private void updateWaitPakinsStatus(List<WaitPakin> waitPakins, Short ioStatus, Long loginUserId, boolean updateCreateBy, String errorMessage) {
+        for (WaitPakin waitPakin : waitPakins) {
+            updateWaitPakinSnapshot(waitPakin, ioStatus, loginUserId, updateCreateBy, errorMessage);
+        }
+    }
+
+    private void updateWaitPakinSnapshot(WaitPakin waitPakin, Short ioStatus, Long loginUserId, boolean updateCreateBy, String errorMessage) {
+        WaitPakin update = new WaitPakin();
+        update.setId(waitPakin.getId());
+        update.setVersion(waitPakin.getVersion());
+        update.setIoStatus(ioStatus);
+        if (updateCreateBy && loginUserId != null) {
+            update.setCreateBy(loginUserId);
+        }
+        if (loginUserId != null) {
+            update.setUpdateBy(loginUserId);
+            update.setUpdateTime(new Date());
+        }
+        if (!waitPakinService.updateById(update)) {
+            throw new CoolException(errorMessage);
+        }
+        waitPakin.setIoStatus(ioStatus);
+        if (loginUserId != null) {
+            waitPakin.setUpdateBy(loginUserId);
+            waitPakin.setUpdateTime(update.getUpdateTime());
+        }
+        if (update.getVersion() != null) {
+            waitPakin.setVersion(update.getVersion());
+        }
+    }
+
+    private void updateWkOrderExceStatus(Long orderId, Short exceStatus, Long loginUserId, String errorMessage) {
+        WkOrder order = checkOrderService.getById(orderId);
+        if (Objects.isNull(order)) {
+            return;
+        }
+        WkOrder update = new WkOrder();
+        update.setId(order.getId());
+        update.setVersion(order.getVersion());
+        update.setExceStatus(exceStatus);
+        if (loginUserId != null) {
+            update.setUpdateBy(loginUserId);
+            update.setUpdateTime(new Date());
+        }
+        if (!checkOrderService.updateById(update)) {
+            throw new CoolException(errorMessage);
+        }
+        order.setExceStatus(exceStatus);
+        if (loginUserId != null) {
+            order.setUpdateBy(loginUserId);
+            order.setUpdateTime(update.getUpdateTime());
+        }
+        if (update.getVersion() != null) {
+            order.setVersion(update.getVersion());
+        }
+    }
+
+    private void updateWkOrderWorkQty(Long orderId, Double delta, Long loginUserId, String errorMessage) {
+        WkOrder order = checkOrderService.getById(orderId);
+        if (Objects.isNull(order)) {
+            throw new CoolException("鐩樼偣鍗曚笉瀛樺湪锛侊紒");
+        }
+        double currentWorkQty = Objects.isNull(order.getWorkQty()) ? 0.0 : order.getWorkQty();
+        double nextWorkQty = Math.round((currentWorkQty + delta) * 10000) / 10000.0;
+
+        WkOrder update = new WkOrder();
+        update.setId(order.getId());
+        update.setVersion(order.getVersion());
+        update.setWorkQty(nextWorkQty);
+        if (loginUserId != null) {
+            update.setUpdateBy(loginUserId);
+            update.setUpdateTime(new Date());
+        }
+        if (!checkOrderService.updateById(update)) {
+            throw new CoolException(errorMessage);
+        }
+        order.setWorkQty(nextWorkQty);
+        if (loginUserId != null) {
+            order.setUpdateBy(loginUserId);
+            order.setUpdateTime(update.getUpdateTime());
+        }
+        if (update.getVersion() != null) {
+            order.setVersion(update.getVersion());
+        }
+    }
+
+    private void updateTaskSnapshot(Task task, Integer taskStatus, Long loginUserId, String errorMessage) {
+        Task update = new Task();
+        update.setId(task.getId());
+        update.setVersion(task.getVersion());
+        update.setTaskStatus(taskStatus);
+        if (loginUserId != null) {
+            update.setUpdateBy(loginUserId);
+            update.setUpdateTime(new Date());
+        }
+        if (!this.updateById(update)) {
+            throw new CoolException(errorMessage);
+        }
+        task.setTaskStatus(taskStatus);
+        if (loginUserId != null) {
+            task.setUpdateBy(loginUserId);
+            task.setUpdateTime(update.getUpdateTime());
+        }
+        if (update.getVersion() != null) {
+            task.setVersion(update.getVersion());
+        }
+    }
 }

--
Gitblit v1.9.1