From 7a717a0bbc0eac8e494cd84207482e983ef56a3c Mon Sep 17 00:00:00 2001
From: chen.lin <1442464845@qq.com>
Date: 星期日, 08 二月 2026 17:42:55 +0800
Subject: [PATCH] RCS入库流程优化

---
 rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java |  463 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 442 insertions(+), 21 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
index 8b917c4..266582d 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
@@ -29,6 +29,7 @@
 import com.vincent.rsf.server.manager.entity.*;
 import com.vincent.rsf.server.manager.service.*;
 import com.vincent.rsf.server.manager.service.impl.LocServiceImpl;
+import com.vincent.rsf.server.system.utils.SystemAuthUtils;
 import com.vincent.rsf.server.system.constant.SerialRuleCode;
 import com.vincent.rsf.server.manager.enums.LocStsType;
 import com.vincent.rsf.server.system.utils.SerialRuleUtils;
@@ -44,6 +45,9 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.client.RestTemplate;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
 import java.util.List;
 import java.util.Objects;
 import java.util.Random;
@@ -77,6 +81,8 @@
     private WaitPakinItemService waitPakinItemService;
     @Autowired
     private BasStationService basStationService;
+    @Autowired
+    private LocItemWorkingService locItemWorkingService;
     @Autowired
     private RestTemplate restTemplate;
     @Autowired
@@ -118,8 +124,179 @@
         // 楠岃瘉璁惧绔欑偣
         DeviceSite deviceSite = validateDeviceSite(param);
 
-        // 楠岃瘉缁勬嫋鐘舵��
-        WaitPakin waitPakin = validateWaitPakin(param.getBarcode());
+        // 鎻愬墠瀹氫箟waitPakin锛岄伩鍏嶄綔鐢ㄥ煙闂
+        WaitPakin waitPakin = null;
+
+        // 鍏堥獙璇佺粍鎷栫姸鎬侊紝鑾峰彇缁勬墭鏄庣粏淇℃伅锛堢敤浜庢壒鍙峰尮閰嶅拰鍗曞彿妫�鏌ワ級
+        waitPakin = validateWaitPakin(param.getBarcode());
+        List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(
+                new LambdaQueryWrapper<WaitPakinItem>()
+                        .eq(WaitPakinItem::getPakinId, waitPakin.getId()));
+
+        // 鍏堟鏌ユ槸鍚︽湁鎷f枡鍏ュ簱浠诲姟锛堥渶瑕佸悓鏃跺尮閰嶇鍙峰拰鎵瑰彿锛�
+        Task pickInTask = null;
+        // 妫�鏌ユ槸鍚︽湁鐩樼偣鍏ュ簱浠诲姟锛堥渶瑕佸悓鏃跺尮閰嶇鍙峰拰鎵瑰彿锛�
+        Task checkInTask = null;
+        
+        if (!waitPakinItems.isEmpty()) {
+            // 鑾峰彇缁勬墭鏄庣粏涓殑鎵瑰彿鍒楄〃锛堝幓閲嶏級
+            List<String> batchList = waitPakinItems.stream()
+                    .map(WaitPakinItem::getBatch)
+                    .filter(Objects::nonNull)
+                    .filter(batch -> !batch.trim().isEmpty())
+                    .distinct()
+                    .collect(Collectors.toList());
+            
+            if (!batchList.isEmpty()) {
+                log.info("妫�鏌ョ粍鎵樻槑缁嗘壒鍙� - 鎵瑰彿鍒楄〃锛歿}", batchList);
+                
+                // 鏌ヨ鎷f枡鍏ュ簱浠诲姟锛氱鍙峰尮閰嶄笖鐘舵�佷负1鎴�2
+                List<Task> pickInTasks = taskService.list(new LambdaQueryWrapper<Task>()
+                        .eq(Task::getBarcode, param.getBarcode())
+                        .eq(Task::getTaskType, TaskType.TASK_TYPE_PICK_IN.type)
+                        .in(Task::getTaskStatus, TaskStsType.GENERATE_IN.id, TaskStsType.WCS_EXECUTE_IN.id)
+                        .orderByDesc(Task::getCreateTime));
+                
+                // 閫氳繃TaskItem鐨刡atch瀛楁鍖归厤鎵瑰彿
+                for (Task task : pickInTasks) {
+                    List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>()
+                            .eq(TaskItem::getTaskId, task.getId())
+                            .in(TaskItem::getBatch, batchList));
+                    
+                    if (!taskItems.isEmpty()) {
+                        pickInTask = task;
+                        log.info("鎵惧埌鍖归厤鐨勬嫞鏂欏叆搴撲换鍔★紙绠卞彿鍜屾壒鍙烽兘鍖归厤锛� - 浠诲姟缂栫爜锛歿}锛屾壒鍙凤細{}", 
+                                task.getTaskCode(), batchList);
+                        break;
+                    }
+                }
+                
+                // 鏌ヨ鐩樼偣鍏ュ簱浠诲姟锛氱鍙峰尮閰嶄笖鐘舵�佷负1鎴�2
+                List<Task> checkInTasks = taskService.list(new LambdaQueryWrapper<Task>()
+                        .eq(Task::getBarcode, param.getBarcode())
+                        .eq(Task::getTaskType, TaskType.TASK_TYPE_CHECK_IN.type)
+                        .in(Task::getTaskStatus, TaskStsType.GENERATE_IN.id, TaskStsType.WCS_EXECUTE_IN.id)
+                        .orderByDesc(Task::getCreateTime));
+                
+                // 閫氳繃TaskItem鐨刡atch瀛楁鍖归厤鎵瑰彿
+                for (Task task : checkInTasks) {
+                    List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>()
+                            .eq(TaskItem::getTaskId, task.getId())
+                            .in(TaskItem::getBatch, batchList));
+                    
+                    if (!taskItems.isEmpty()) {
+                        checkInTask = task;
+                        log.info("鎵惧埌鍖归厤鐨勭洏鐐瑰叆搴撲换鍔★紙绠卞彿鍜屾壒鍙烽兘鍖归厤锛� - 浠诲姟缂栫爜锛歿}锛屾壒鍙凤細{}", 
+                                task.getTaskCode(), batchList);
+                        break;
+                    }
+                }
+            }
+        }
+        
+        // 濡傛灉鏄嫞鏂欏叆搴撲换鍔★紝鐩存帴杩斿洖锛屼笉鏍¢獙缁勬墭
+        if (Objects.nonNull(pickInTask)) {
+            log.info("鎷f枡鍏ュ簱浠诲姟锛岀洿鎺ヨ繑鍥烇紝涓嶆牎楠岀粍鎵� - 浠诲姟缂栫爜锛歿}", pickInTask.getTaskCode());
+            
+            // 鏇存柊鍏ュ簱绔欑偣淇℃伅锛堝鏋滀笌褰撳墠鐢宠鐨勭珯鐐逛笉鍚岋級
+            if (StringUtils.isNotBlank(param.getSourceStaNo()) && 
+                !param.getSourceStaNo().equals(pickInTask.getOrgSite())) {
+                log.info("鏇存柊鎷f枡鍏ュ簱浠诲姟鐨勫叆搴撶珯鐐� - 浠诲姟缂栫爜锛歿}锛屽師绔欑偣锛歿}锛屾柊绔欑偣锛歿}", 
+                        pickInTask.getTaskCode(), pickInTask.getOrgSite(), param.getSourceStaNo());
+                pickInTask.setOrgSite(param.getSourceStaNo());
+                if (!taskService.updateById(pickInTask)) {
+                    log.warn("鏇存柊鎷f枡鍏ュ簱浠诲姟鐨勫叆搴撶珯鐐瑰け璐� - 浠诲姟缂栫爜锛歿}", pickInTask.getTaskCode());
+                }
+            }
+            
+            // 杩斿洖鎷f枡鍏ュ簱浠诲姟鐨勪俊鎭�
+            InTaskMsgDto msgDto = new InTaskMsgDto();
+            msgDto.setWorkNo(pickInTask.getTaskCode());
+            msgDto.setTaskId(pickInTask.getId());
+            msgDto.setLocNo(pickInTask.getTargLoc());
+            msgDto.setSourceStaNo(pickInTask.getOrgSite());
+            msgDto.setStaNo(pickInTask.getTargSite());
+            return msgDto;
+        }
+        
+        // 濡傛灉鏄洏鐐瑰叆搴撲换鍔★紝鐩存帴杩斿洖锛屼笉鏍¢獙缁勬墭
+        if (Objects.nonNull(checkInTask)) {
+            log.info("鐩樼偣鍏ュ簱浠诲姟锛岀洿鎺ヨ繑鍥烇紝涓嶆牎楠岀粍鎵� - 浠诲姟缂栫爜锛歿}", checkInTask.getTaskCode());
+            
+            // 鏇存柊鍏ュ簱绔欑偣淇℃伅锛堝鏋滀笌褰撳墠鐢宠鐨勭珯鐐逛笉鍚岋級
+            if (StringUtils.isNotBlank(param.getSourceStaNo()) && 
+                !param.getSourceStaNo().equals(checkInTask.getOrgSite())) {
+                log.info("鏇存柊鐩樼偣鍏ュ簱浠诲姟鐨勫叆搴撶珯鐐� - 浠诲姟缂栫爜锛歿}锛屽師绔欑偣锛歿}锛屾柊绔欑偣锛歿}", 
+                        checkInTask.getTaskCode(), checkInTask.getOrgSite(), param.getSourceStaNo());
+                checkInTask.setOrgSite(param.getSourceStaNo());
+                if (!taskService.updateById(checkInTask)) {
+                    log.warn("鏇存柊鐩樼偣鍏ュ簱浠诲姟鐨勫叆搴撶珯鐐瑰け璐� - 浠诲姟缂栫爜锛歿}", checkInTask.getTaskCode());
+                }
+            }
+            
+            // 杩斿洖鐩樼偣鍏ュ簱浠诲姟鐨勪俊鎭�
+            InTaskMsgDto msgDto = new InTaskMsgDto();
+            msgDto.setWorkNo(checkInTask.getTaskCode());
+            msgDto.setTaskId(checkInTask.getId());
+            msgDto.setLocNo(checkInTask.getTargLoc());
+            msgDto.setSourceStaNo(checkInTask.getOrgSite());
+            msgDto.setStaNo(checkInTask.getTargSite());
+            return msgDto;
+        }
+        
+        // 妫�鏌ュ叾浠栧叆搴撲换鍔$被鍨嬶紙鐢ㄧ鍙锋煡璇紝鐘舵�佷负1鎴�2锛�
+        // 娉ㄦ剰锛氱洏鐐瑰叆搴撳凡鍗曠嫭澶勭悊锛屼笉鍐嶅寘鍚湪姝ゅ垪琛ㄤ腑
+        List<Integer> otherInboundTaskTypes = Arrays.asList(
+                TaskType.TASK_TYPE_IN.type,
+                TaskType.TASK_TYPE_MERGE_IN.type,
+                TaskType.TASK_TYPE_EMPITY_IN.type
+        );
+        
+        Task existingInTask = taskService.getOne(new LambdaQueryWrapper<Task>()
+                .eq(Task::getBarcode, param.getBarcode())
+                .in(Task::getTaskType, otherInboundTaskTypes)
+                .in(Task::getTaskStatus, TaskStsType.GENERATE_IN.id, TaskStsType.WCS_EXECUTE_IN.id)
+                .orderByDesc(Task::getCreateTime)
+                .last("LIMIT 1"));
+        
+        if (Objects.nonNull(existingInTask)) {
+            log.info("鎵惧埌鍖归厤鐨勫叾浠栧叆搴撲换鍔� - 浠诲姟缂栫爜锛歿}锛屼换鍔$被鍨嬶細{}锛岀鍙凤細{}", 
+                    existingInTask.getTaskCode(), existingInTask.getTaskType(), param.getBarcode());
+            
+            // 妫�鏌ョ粍鎵樻槑缁嗘槸鍚︽湁璁㈠崟缂栫爜锛堜换鍔$紪鍙凤級
+            List<WaitPakinItem> itemsWithAsnCode = waitPakinItems.stream()
+                    .filter(item -> StringUtils.isNotBlank(item.getAsnCode()))
+                    .collect(Collectors.toList());
+            
+            if (!itemsWithAsnCode.isEmpty()) {
+                log.info("缁勬墭妗f湁浠诲姟缂栧彿锛屼娇鐢ㄧ幇鏈夊叆搴撲换鍔″崟鍙� - 浠诲姟缂栫爜锛歿}锛岀鍙凤細{}锛屼换鍔$紪鍙锋暟閲忥細{}", 
+                        existingInTask.getTaskCode(), param.getBarcode(), itemsWithAsnCode.size());
+                
+                // 鏇存柊鍏ュ簱绔欑偣淇℃伅锛堝鏋滀笌褰撳墠鐢宠鐨勭珯鐐逛笉鍚岋級
+                if (StringUtils.isNotBlank(param.getSourceStaNo()) && 
+                    !param.getSourceStaNo().equals(existingInTask.getOrgSite())) {
+                    log.info("鏇存柊鍏ュ簱浠诲姟鐨勫叆搴撶珯鐐� - 浠诲姟缂栫爜锛歿}锛屽師绔欑偣锛歿}锛屾柊绔欑偣锛歿}", 
+                            existingInTask.getTaskCode(), existingInTask.getOrgSite(), param.getSourceStaNo());
+                    existingInTask.setOrgSite(param.getSourceStaNo());
+                    if (!taskService.updateById(existingInTask)) {
+                        log.warn("鏇存柊鍏ュ簱浠诲姟鐨勫叆搴撶珯鐐瑰け璐� - 浠诲姟缂栫爜锛歿}", existingInTask.getTaskCode());
+                    }
+                }
+                
+                // 杩斿洖鐜版湁鍏ュ簱浠诲姟鐨勪俊鎭�
+                InTaskMsgDto msgDto = new InTaskMsgDto();
+                msgDto.setWorkNo(existingInTask.getTaskCode());
+                msgDto.setTaskId(existingInTask.getId());
+                msgDto.setLocNo(existingInTask.getTargLoc());
+                msgDto.setSourceStaNo(existingInTask.getOrgSite());
+                msgDto.setStaNo(existingInTask.getTargSite());
+                return msgDto;
+            } else {
+                log.info("缁勬墭妗f病鏈変换鍔$紪鍙凤紝缁х画鍒涘缓鏂颁换鍔� - 绠卞彿锛歿}", param.getBarcode());
+            }
+        } else {
+            log.info("鏈壘鍒板尮閰嶇殑鍏朵粬鍏ュ簱浠诲姟锛岀户缁垱寤烘柊浠诲姟 - 绠卞彿锛歿}", param.getBarcode());
+        }
 
         // 鐢熸垚浠诲姟缂栫爜
         String ruleCode = generateTaskCode();
@@ -140,7 +317,7 @@
         updateLocStatus(task.getTargLoc(), waitPakin.getBarcode());
 
         // 鑾峰彇骞堕獙璇佺粍鎷栨槑缁�
-        List<WaitPakinItem> waitPakinItems = getWaitPakinItems(waitPakin.getId());
+        waitPakinItems = getWaitPakinItems(waitPakin.getId());
 
         // 鍒涘缓骞朵繚瀛樹换鍔℃槑缁�
         saveTaskItems(task.getId(), waitPakinItems, param.getUser());
@@ -150,6 +327,7 @@
 
         // 璁剧疆宸ヤ綔鍗曞彿骞惰繑鍥�
         locNo.setWorkNo(ruleCode);
+        locNo.setTaskId(task.getId());
         return locNo;
     }
 
@@ -174,7 +352,7 @@
     private WaitPakin validateWaitPakin(String barcode) {
         WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>()
                 .eq(WaitPakin::getBarcode, barcode)
-                .eq(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_DONE.val));
+                .in(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_DONE.val, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val));
 
         if (Cools.isEmpty(waitPakin)) {
             throw new CoolException("璇锋鏌ョ粍鎷栫姸鎬佹槸鍚﹀畬鎴愶紒锛�");
@@ -231,13 +409,30 @@
 
     /**
      * 鑾峰彇骞堕獙璇佺粍鎷栨槑缁�
+     * 鍙繑鍥炴湭瀹屽叏浣跨敤鐨勬槑缁嗭紙workQty < anfme 鎴� workQty 涓� null锛�
      */
     private List<WaitPakinItem> getWaitPakinItems(Long pakinId) {
-        List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, pakinId));
+        List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>()
+                .eq(WaitPakinItem::getPakinId, pakinId));
+        
         if (waitPakinItems.isEmpty()) {
             throw new CoolException("鏁版嵁閿欒锛氱粍鎷栨槑缁嗕笉瀛樺湪");
         }
-        return waitPakinItems;
+        
+        // 杩囨护鎺夊凡瀹屽叏浣跨敤鐨勬槑缁嗭紙workQty >= anfme锛�
+        List<WaitPakinItem> availableItems = waitPakinItems.stream()
+                .filter(item -> {
+                    Double workQty = item.getWorkQty() == null ? 0.0 : item.getWorkQty();
+                    Double anfme = item.getAnfme() == null ? 0.0 : item.getAnfme();
+                    return workQty < anfme; // 鍙繑鍥炴湭瀹屽叏浣跨敤鐨勬槑缁�
+                })
+                .collect(Collectors.toList());
+        
+        if (availableItems.isEmpty()) {
+            throw new CoolException("缁勬嫋鏄庣粏宸插叏閮ㄤ娇鐢紝鏃犳硶鍐嶆鍒涘缓浠诲姟");
+        }
+        
+        return availableItems;
     }
 
     /**
@@ -261,6 +456,15 @@
         if (!taskItemService.saveBatch(taskItems)) {
             throw new CoolException("浠诲姟鏄庣粏淇濆瓨澶辫触锛侊紒");
         }
+        
+        // 鏇存柊缁勬墭鏄庣粏鐨勬墽琛屾暟閲忥紝鏍囪鏄庣粏宸茶鎻愬彇浣跨敤
+        waitPakinItems.forEach(item -> {
+            if (!waitPakinItemService.update(new LambdaUpdateWrapper<WaitPakinItem>()
+                    .set(WaitPakinItem::getWorkQty, item.getAnfme())
+                    .eq(WaitPakinItem::getId, item.getId()))) {
+                throw new CoolException("缁勬墭鏄庣粏鎵ц鏁伴噺淇敼澶辫触锛侊紒");
+            }
+        });
     }
 
     /**
@@ -463,11 +667,91 @@
     @Override
     public R receiveExMsg(ExMsgParams params) {
         if (Objects.isNull(params)) {
+            log.error("RCS鍥炶皟涓虹┖锛�");
             return R.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
         }
-        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskCode, params.getSeqNum()));
+        log.info("========== 鎺ユ敹RCS鍥炶皟 ==========");
+        log.info("浠诲姟缂栧彿锛歿}锛屾壒娆″彿锛歿}锛屼簨浠剁被鍨嬶細{}", params.getSeqNum(), params.getBatchNo(), params.getEventType());
+        
+        // 浼樺厛浣跨敤鎵规鍙锋煡璇换鍔′富琛紙鎵规鍙� = 浠诲姟缂栫爜锛屾洿鍙潬锛�
+        String taskCode = params.getBatchNo();
+        String taskNo = params.getSeqNum();
+        String locCode = null; // 搴撲綅浠g爜锛堝搴撲綅浠诲姟鏃朵粠浠诲姟鍙蜂腑鎻愬彇锛�
+        
+        // 濡傛灉鎵规鍙蜂负绌猴紝浣跨敤浠诲姟鍙锋煡璇�
+        if (StringUtils.isBlank(taskCode)) {
+            taskCode = taskNo;
+        }
+        
+        // 澶勭悊鍑哄簱浠诲姟澶氬簱浣嶇殑鎯呭喌锛氫换鍔″彿鏍煎紡鍙兘鏄� "浠诲姟缂栫爜_搴撲綅浠g爜"
+        // 濡傛灉浠诲姟鍙峰寘鍚笅鍒掔嚎锛屾彁鍙栧簱浣嶄唬鐮�
+        if (StringUtils.isNotBlank(taskNo) && taskNo.contains("_")) {
+            locCode = taskNo.substring(taskNo.lastIndexOf("_") + 1);
+            // 濡傛灉鎵规鍙蜂负绌猴紝浠庝换鍔″彿涓彁鍙栧師濮嬩换鍔$紪鐮�
+            if (StringUtils.isBlank(taskCode)) {
+                taskCode = taskNo.substring(0, taskNo.lastIndexOf("_"));
+            }
+            log.info("妫�娴嬪埌澶氬簱浣嶄换鍔★紝鎻愬彇搴撲綅浠g爜锛歿}锛屽師濮嬩换鍔$紪鐮侊細{}", locCode, taskCode);
+        }
+        
+        // 浣跨敤鎵规鍙凤紙浠诲姟缂栫爜锛夋煡璇换鍔′富琛�
+        Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskCode, taskCode));
+        
         if (Objects.isNull(task)) {
-            throw new CoolException("浠诲姟涓嶅瓨鍦ㄥ彲宸茬粨鏉燂紒锛�");
+            log.error("浠诲姟涓嶅瓨鍦ㄦ垨宸茬粨鏉燂紒浠诲姟缂栧彿锛歿}锛屾壒娆″彿锛歿}", taskNo, taskCode);
+            throw new CoolException("浠诲姟涓嶅瓨鍦ㄦ垨宸茬粨鏉燂紒锛佷换鍔$紪鍙凤細" + taskNo + "锛屾壒娆″彿锛�" + taskCode);
+        }
+        
+        // 楠岃瘉鎵规鍙峰拰浠诲姟鍙风殑鍏宠仈鍏崇郴
+        if (StringUtils.isNotBlank(params.getBatchNo()) && !params.getBatchNo().equals(task.getTaskCode())) {
+            log.warn("鎵规鍙蜂笌浠诲姟缂栫爜涓嶅尮閰嶏紒鎵规鍙凤細{}锛屼换鍔$紪鐮侊細{}", params.getBatchNo(), task.getTaskCode());
+        }
+        log.info("鏌ヨ鍒颁换鍔� - 浠诲姟缂栫爜锛歿}锛屼换鍔$被鍨嬶細{}锛屽綋鍓嶇姸鎬侊細{}", 
+                task.getTaskCode(), task.getTaskType(), task.getTaskStatus());
+        
+        // 瀵逛簬澶氬簱浣嶅嚭搴撲换鍔★紝閫氳繃搴撲綅浠g爜绮剧‘鍏宠仈浠诲姟鏄庣粏
+        List<TaskItem> relatedTaskItems = null;
+        if (StringUtils.isNotBlank(locCode)) {
+            // 1. 閫氳繃搴撲綅浠g爜鏌ヨLocItem
+            LocItem locItem = locItemService.getOne(new LambdaQueryWrapper<LocItem>().eq(LocItem::getLocCode, locCode));
+            if (Objects.isNull(locItem)) {
+                log.warn("鏈壘鍒板簱浣嶆槑缁嗭紒搴撲綅浠g爜锛歿}锛屼换鍔$紪鐮侊細{}", locCode, task.getTaskCode());
+            } else {
+                // 2. 閫氳繃浠诲姟ID鍜孡ocItem.id锛堝嵆TaskItem.source锛夋煡璇㈠搴旂殑浠诲姟鏄庣粏
+                relatedTaskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>()
+                        .eq(TaskItem::getTaskId, task.getId())
+                        .eq(TaskItem::getSource, locItem.getId()));
+                if (relatedTaskItems.isEmpty()) {
+                    log.warn("鏈壘鍒板搴旂殑浠诲姟鏄庣粏锛佷换鍔$紪鐮侊細{}锛屽簱浣嶄唬鐮侊細{}锛孡ocItem.id锛歿}", 
+                            task.getTaskCode(), locCode, locItem.getId());
+                } else {
+                    log.info("閫氳繃搴撲綅浠g爜绮剧‘鍏宠仈鍒颁换鍔℃槑缁� - 浠诲姟缂栫爜锛歿}锛屽簱浣嶄唬鐮侊細{}锛屼换鍔℃槑缁嗘暟閲忥細{}", 
+                            task.getTaskCode(), locCode, relatedTaskItems.size());
+                }
+            }
+        }
+        
+        // 楠岃瘉浠诲姟鐘舵�侊細鍙湁宸蹭笅鍙戝埌RCS鐨勪换鍔℃墠鑳借鍥炶皟澶勭悊
+        // 鍏ュ簱浠诲姟锛氱姸鎬� >= WCS_EXECUTE_IN(2) 琛ㄧず宸蹭笅鍙�
+        // 鍑哄簱浠诲姟锛氱姸鎬� >= WCS_EXECUTE_OUT(102) 琛ㄧず宸蹭笅鍙�
+        boolean isValidStatus = false;
+        if (task.getTaskType() < 100) {
+            // 鍏ュ簱浠诲姟
+            if (task.getTaskStatus() >= TaskStsType.WCS_EXECUTE_IN.id) {
+                isValidStatus = true;
+            }
+        } else {
+            // 鍑哄簱浠诲姟
+            if (task.getTaskStatus() >= TaskStsType.WCS_EXECUTE_OUT.id) {
+                isValidStatus = true;
+            }
+        }
+        
+        if (!isValidStatus) {
+            log.error("浠诲姟鐘舵�佷笉姝g‘锛屾棤娉曞鐞嗗洖璋冿紒浠诲姟缂栫爜锛歿}锛屼换鍔$被鍨嬶細{}锛屽綋鍓嶇姸鎬侊細{}锛屾湡鏈涚姸鎬侊細宸蹭笅鍙戝埌RCS", 
+                    task.getTaskCode(), task.getTaskType(), task.getTaskStatus());
+            throw new CoolException("浠诲姟鐘舵�佷笉姝g‘锛屾棤娉曞鐞嗗洖璋冿紒浠诲姟缂栫爜锛�" + task.getTaskCode() + 
+                    "锛屽綋鍓嶇姸鎬侊細" + task.getTaskStatus() + "锛屼换鍔″彲鑳芥湭涓嬪彂鍒癛CS鎴栧凡琚鐞�");
         }
 
         /**鏂欑鎼繍涓紝 淇敼绔欑偣鐘舵��*/
@@ -493,21 +777,40 @@
                 if (!task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type)) {
                     BasStation station = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, task.getOrgSite()));
                     if (Objects.isNull(station)) {
+                        log.error("鍏ュ簱绔欑偣涓嶅瓨鍦� - 绔欑偣鍚嶇О锛歿}锛屼换鍔$紪鐮侊細{}", task.getOrgSite(), task.getTaskCode());
                         throw new CoolException("鏁版嵁閿欒锛岀珯鐐逛笉瀛樺湪锛侊紒");
                     }
+                    log.info("鏌ヨ鍒板叆搴撶珯鐐� - 绔欑偣鍚嶇О锛歿}锛岀珯鐐圭被鍨嬶細{}锛屽綋鍓嶇姸鎬侊細{}", 
+                            station.getStationName(), station.getType(), station.getUseStatus());
                     if (station.getType().equals(StationTypeEnum.STATION_TYPE_NORMAL.type)) {
+                        log.info("鏇存柊鍏ュ簱绔欑偣鐘舵�� - 绔欑偣鍚嶇О锛歿}锛屾柊鐘舵�侊細{}", station.getStationName(), LocStsType.LOC_STS_TYPE_O.type);
                         station.setUseStatus(LocStsType.LOC_STS_TYPE_O.type);
                         if (!basStationService.updateById(station)) {
+                            log.error("鍏ュ簱绔欑偣鐘舵�佷慨鏀瑰け璐� - 绔欑偣鍚嶇О锛歿}", station.getStationName());
                             throw new CoolException("绔欑偣鐘舵�佷慨鏀瑰け璐ワ紒锛�");
                         }
+                        log.info("鍏ュ簱绔欑偣鐘舵�佹洿鏂版垚鍔� - 绔欑偣鍚嶇О锛歿}", station.getStationName());
                     }
                 }
 
-                if (!taskService.update(new LambdaUpdateWrapper<Task>()
-                        .lt(Task::getTaskStatus, TaskStsType.COMPLETE_IN.id)
-                        .eq(Task::getTaskCode, task.getTaskCode())
-                        .set(Task::getTaskStatus, TaskStsType.COMPLETE_IN.id))) {
-                    throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+                log.info("鍑嗗鏇存柊鍏ュ簱浠诲姟鐘舵�� - 浠诲姟缂栫爜锛歿}锛屽綋鍓嶇姸鎬侊細{}锛岀洰鏍囩姸鎬侊細{}", 
+                        task.getTaskCode(), task.getTaskStatus(), TaskStsType.COMPLETE_IN.id);
+                
+                // 濡傛灉浠诲姟鐘舵�佸凡缁忓ぇ浜庣瓑浜庣洰鏍囩姸鎬侊紝璺宠繃鏇存柊
+                if (task.getTaskStatus() >= TaskStsType.COMPLETE_IN.id) {
+                    log.warn("鍏ュ簱浠诲姟鐘舵�佸凡澶т簬绛変簬鐩爣鐘舵�侊紝璺宠繃鏇存柊 - 浠诲姟缂栫爜锛歿}锛屽綋鍓嶇姸鎬侊細{}锛岀洰鏍囩姸鎬侊細{}", 
+                            task.getTaskCode(), task.getTaskStatus(), TaskStsType.COMPLETE_IN.id);
+                } else {
+                    boolean updated = taskService.update(new LambdaUpdateWrapper<Task>()
+                            .lt(Task::getTaskStatus, TaskStsType.COMPLETE_IN.id)
+                            .eq(Task::getTaskCode, task.getTaskCode())
+                            .set(Task::getTaskStatus, TaskStsType.COMPLETE_IN.id));
+                    if (!updated) {
+                        log.error("鍏ュ簱浠诲姟鐘舵�佷慨鏀瑰け璐� - 浠诲姟缂栫爜锛歿}锛屽綋鍓嶇姸鎬侊細{}锛岀洰鏍囩姸鎬侊細{}锛屽彲鑳戒换鍔$姸鎬佸凡澶т簬绛変簬鐩爣鐘舵��", 
+                                task.getTaskCode(), task.getTaskStatus(), TaskStsType.COMPLETE_IN.id);
+                        throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛佸綋鍓嶄换鍔$姸鎬侊細" + task.getTaskStatus() + "锛岀洰鏍囩姸鎬侊細" + TaskStsType.COMPLETE_IN.id);
+                    }
+                    log.info("鍏ュ簱浠诲姟鐘舵�佹洿鏂版垚鍔� - 浠诲姟缂栫爜锛歿}", task.getTaskCode());
                 }
             } else if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)
                     || task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
@@ -515,28 +818,100 @@
                     || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)
                     || task.getTaskType().equals(TaskType.TASK_TYPE_EMPITY_OUT.type)) {
 
-
                 /**淇敼鍑哄簱绔欑偣鐘舵��*/
                 BasStation station = basStationService.getOne(new LambdaQueryWrapper<BasStation>()
                         .eq(BasStation::getStationName, task.getTargSite()));
                 if (Objects.isNull(station)) {
+                    log.error("鍑哄簱绔欑偣涓嶅瓨鍦� - 绔欑偣鍚嶇О锛歿}锛屼换鍔$紪鐮侊細{}", task.getTargSite(), task.getTaskCode());
                     throw new CoolException("鏁版嵁閿欒锛岀珯鐐逛笉瀛樺湪锛侊紒");
                 }
+                log.info("鏌ヨ鍒板嚭搴撶珯鐐� - 绔欑偣鍚嶇О锛歿}锛岀珯鐐圭被鍨嬶細{}锛屽綋鍓嶇姸鎬侊細{}", 
+                        station.getStationName(), station.getType(), station.getUseStatus());
                 if (station.getType().equals(StationTypeEnum.STATION_TYPE_NORMAL.type)) {
+                    log.info("鏇存柊鍑哄簱绔欑偣鐘舵�� - 绔欑偣鍚嶇О锛歿}锛屾柊鐘舵�侊細{}", station.getStationName(), LocStsType.LOC_STS_TYPE_F.type);
                     station.setUseStatus(LocStsType.LOC_STS_TYPE_F.type);
                     if (!basStationService.updateById(station)) {
+                        log.error("鍑哄簱绔欑偣鐘舵�佷慨鏀瑰け璐� - 绔欑偣鍚嶇О锛歿}", station.getStationName());
                         throw new CoolException("绔欑偣鐘舵�佷慨鏀瑰け璐ワ紒锛�");
                     }
+                    log.info("鍑哄簱绔欑偣鐘舵�佹洿鏂版垚鍔� - 绔欑偣鍚嶇О锛歿}", station.getStationName());
                 }
-
-                if (!taskService.update(new LambdaUpdateWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode())
-                        .lt(Task::getTaskStatus, TaskStsType.COMPLETE_OUT.id)
-                        .set(Task::getTaskStatus, TaskStsType.COMPLETE_OUT.id))) {
-                    throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+                log.info("鍑嗗鏇存柊鍑哄簱浠诲姟鐘舵�� - 浠诲姟缂栫爜锛歿}锛屽綋鍓嶇姸鎬侊細{}锛岀洰鏍囩姸鎬侊細{}", 
+                        task.getTaskCode(), task.getTaskStatus(), TaskStsType.COMPLETE_OUT.id);
+                
+                // 濡傛灉浠诲姟鐘舵�佸凡缁忓ぇ浜庣瓑浜庣洰鏍囩姸鎬侊紝璺宠繃鏇存柊
+                if (task.getTaskStatus() >= TaskStsType.COMPLETE_OUT.id) {
+                    log.warn("鍑哄簱浠诲姟鐘舵�佸凡澶т簬绛変簬鐩爣鐘舵�侊紝璺宠繃鏇存柊 - 浠诲姟缂栫爜锛歿}锛屽綋鍓嶇姸鎬侊細{}锛岀洰鏍囩姸鎬侊細{}", 
+                            task.getTaskCode(), task.getTaskStatus(), TaskStsType.COMPLETE_OUT.id);
+                } else {
+                    boolean updated = taskService.update(new LambdaUpdateWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode())
+                            .lt(Task::getTaskStatus, TaskStsType.COMPLETE_OUT.id)
+                            .set(Task::getTaskStatus, TaskStsType.COMPLETE_OUT.id));
+                    if (!updated) {
+                        log.error("鍑哄簱浠诲姟鐘舵�佷慨鏀瑰け璐� - 浠诲姟缂栫爜锛歿}锛屽綋鍓嶇姸鎬侊細{}锛岀洰鏍囩姸鎬侊細{}锛屽彲鑳戒换鍔$姸鎬佸凡澶т簬绛変簬鐩爣鐘舵��", 
+                                task.getTaskCode(), task.getTaskStatus(), TaskStsType.COMPLETE_OUT.id);
+                        throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛佸綋鍓嶄换鍔$姸鎬侊細" + task.getTaskStatus() + "锛岀洰鏍囩姸鎬侊細" + TaskStsType.COMPLETE_OUT.id);
+                    }
+                    log.info("鍑哄簱浠诲姟鐘舵�佹洿鏂版垚鍔� - 浠诲姟缂栫爜锛歿}", task.getTaskCode());
+                    
+                    // 鍏ㄧ増鍑哄簱鍦≧CS鍥炶皟鍚庣洿鎺ュ鐞嗗苟璁剧疆涓�200
+                    if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) {
+                        log.info("鍏ㄧ増鍑哄簱浠诲姟锛屽紑濮嬪鐞嗗簱瀛樺苟鏇存柊鐘舵�佷负200 - 浠诲姟缂栫爜锛歿}", task.getTaskCode());
+                        try {
+                            // 閲嶆柊鏌ヨ浠诲姟浠ヨ幏鍙栨渶鏂扮姸鎬侊紙198锛�
+                            task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode()));
+                            
+                            // 璋冪敤completeTask澶勭悊搴撳瓨锛堜細璁剧疆涓�199锛�
+                            List<Task> taskList = new ArrayList<>();
+                            taskList.add(task);
+                            taskService.completeTask(taskList);
+                            
+                            // 閲嶆柊鏌ヨ浠诲姟浠ヨ幏鍙栨渶鏂扮姸鎬侊紙199锛�
+                            task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode()));
+                            
+                            // 濡傛灉鐘舵�佸凡缁忔槸199锛岀户缁鐞嗗苟璁剧疆涓�200
+                            if (task.getTaskStatus().equals(TaskStsType.WAVE_SEED.id)) {
+                                Long loginUserId = SystemAuthUtils.getLoginUserId();
+                                if (loginUserId == null) {
+                                    log.warn("鏃犳硶鑾峰彇绯荤粺鐢ㄦ埛ID锛屼娇鐢ㄩ粯璁ゅ��1");
+                                    loginUserId = 1L;
+                                }
+                                
+                                // 鍒犻櫎浣滀笟涓簱瀛樿褰曪紙LocItemWorking锛�
+                                locItemWorkingService.remove(new LambdaQueryWrapper<LocItemWorking>()
+                                        .eq(LocItemWorking::getTaskId, task.getId()));
+                                
+                                // 鏇存柊浠诲姟鐘舵�佷负搴撳瓨鏇存柊瀹屾垚锛�200锛�
+                                boolean finalUpdated = taskService.update(new LambdaUpdateWrapper<Task>()
+                                        .eq(Task::getTaskCode, task.getTaskCode())
+                                        .eq(Task::getTaskStatus, TaskStsType.WAVE_SEED.id)
+                                        .set(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id)
+                                        .set(Task::getUpdateBy, loginUserId)
+                                        .set(Task::getUpdateTime, new Date()));
+                                
+                                if (!finalUpdated) {
+                                    log.warn("鍏ㄧ増鍑哄簱浠诲姟鐘舵�佹洿鏂颁负200澶辫触锛屽彲鑳界姸鎬佸凡鍙樻洿 - 浠诲姟缂栫爜锛歿}锛屽綋鍓嶇姸鎬侊細{}", 
+                                            task.getTaskCode(), task.getTaskStatus());
+                                } else {
+                                    log.info("鍏ㄧ増鍑哄簱浠诲姟鐘舵�佸凡鏇存柊涓�200锛堝簱瀛樻洿鏂板畬鎴愶級 - 浠诲姟缂栫爜锛歿}", task.getTaskCode());
+                                }
+                            } else {
+                                log.warn("鍏ㄧ増鍑哄簱浠诲姟鐘舵�佷笉鏄�199锛屾棤娉曟洿鏂颁负200 - 浠诲姟缂栫爜锛歿}锛屽綋鍓嶇姸鎬侊細{}", 
+                                        task.getTaskCode(), task.getTaskStatus());
+                            }
+                        } catch (Exception e) {
+                            log.error("鍏ㄧ増鍑哄簱浠诲姟澶勭悊澶辫触 - 浠诲姟缂栫爜锛歿}锛岄敊璇細{}", task.getTaskCode(), e.getMessage(), e);
+                            // 涓嶆姏鍑哄紓甯革紝閬垮厤褰卞搷RCS鍥炶皟鐨勬甯歌繑鍥�
+                        }
+                    }
                 }
             }
+        } else {
+            log.warn("鏈鐞嗙殑浜嬩欢绫诲瀷 - 浜嬩欢绫诲瀷锛歿}锛屼换鍔$紪鐮侊細{}锛屼换鍔$被鍨嬶細{}", 
+                    params.getEventType(), task.getTaskCode(), task.getTaskType());
         }
-        log.info(JSONObject.toJSONString(params));
+        log.info("========== 浠诲姟鎵ц閫氱煡涓婃姤澶勭悊瀹屾垚 ==========");
+        log.info("澶勭悊缁撴灉锛歿}", JSONObject.toJSONString(params));
         return R.ok(JSONObject.toJSONString(params));
     }
 
@@ -549,7 +924,7 @@
     @Override
     public R pubWcsTask(WcsTaskParams params) {
         String rcsUrl = rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.pubTask;
-        log.info("浠诲姟涓嬪彂锛岃姹傚湴鍧�锛� {}锛� 璇锋眰鍙傛暟锛� {}", rcsUrl, JSONObject.toJSONString(params));
+        log.info("浠诲姟涓嬪彂锛岃姹傚湴鍧�3锛� {}锛� 璇锋眰鍙傛暟锛� {}", rcsUrl, JSONObject.toJSONString(params));
         HttpHeaders headers = new HttpHeaders();
         headers.add("Content-Type", "application/json");
         headers.add("api-version", "v2.0");
@@ -868,6 +1243,7 @@
         int deviceNo = 0;
         Loc loc = new Loc();
         InTaskMsgDto inTaskMsgDto = new InTaskMsgDto();
+        locTypeDto.setLocType1(18);
         List<Loc> loc1 = locService.list(new LambdaQueryWrapper<Loc>()
                 .eq(Loc::getAreaId, area)
                 .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
@@ -923,4 +1299,49 @@
         inTaskMsgDto.setLocNo(locNo);
         return inTaskMsgDto;
     }
+
+    /**
+     * @author Ryan
+     * @date 2026/2/6
+     * @description: 鐢宠鍏ュ簱浠诲姟锛屽垎閰嶅簱浣�
+     * @version 1.0
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R allocateLocation(String barcode, String staNo, Integer type) {
+        log.info("========== 寮�濮嬬敵璇峰叆搴撲换鍔★紝鍒嗛厤搴撲綅 ==========");
+        log.info("鏂欑鐮侊細{}锛屽叆搴撶珯鐐癸細{}锛屽叆搴撶被鍨嬶細{}", barcode, staNo, type);
+
+        // 鏋勫缓 TaskInParam 鍙傛暟锛屼笌 /wcs/create/in/task 鎺ュ彛鍙傛暟涓�鑷�
+        TaskInParam param = new TaskInParam();
+        param.setBarcode(barcode);
+        param.setSourceStaNo(staNo);
+        param.setIoType(TaskType.TASK_TYPE_IN.type); // 鍏ュ簱绫诲瀷
+        param.setLocType1(type); // 搴撲綅绫诲瀷锛堥珮浣庢娴嬩俊鍙凤級
+        param.setUser(1L); // 榛樿鐢ㄦ埛ID锛屽彲浠ユ牴鎹疄闄呴渶姹傝皟鏁�
+
+        // 璋冪敤 createInTask 鏂规硶锛屽垱寤哄畬鏁寸殑鍏ュ簱浠诲姟
+        // 璇ユ柟娉曚細鎵ц浠ヤ笅娴佺▼锛�
+        // 1. 楠岃瘉璁惧绔欑偣
+        // 2. 楠岃瘉缁勬嫋鐘舵��
+        // 3. 鐢熸垚浠诲姟缂栫爜
+        // 4. 鑾峰彇搴撲綅鍙�
+        // 5. 鍒涘缓骞朵繚瀛樹换鍔�
+        // 6. 鏇存柊搴撲綅鐘舵��
+        // 7. 鑾峰彇骞堕獙璇佺粍鎷栨槑缁�
+        // 8. 鍒涘缓骞朵繚瀛樹换鍔℃槑缁�
+        // 9. 鏇存柊缁勬墭鐘舵��
+        InTaskMsgDto msgDto = createInTask(param);
+        //RCS宸茬粡鍦ㄨ緭閫佺嚎涓婏紝鎵�浠ヤ笉闇�瑕佷笅鍙戜换鍔�
+        taskService.updateById(new Task(){{setId(msgDto.getTaskId());setTaskStatus(2);}});
+        log.info("========== RCS-鐢宠鍏ュ簱浠诲姟鎴愬姛 ==========");
+        log.info("RCS-杩斿洖 浠诲姟缂栫爜锛歿}锛屽簱浣嶅彿锛歿}", msgDto.getWorkNo(), msgDto.getLocNo());
+
+        // 杩斿洖缁撴灉锛屽彧杩斿洖搴撲綅鍙凤紙鏍规嵁鎺ュ彛鏂囨。瑕佹眰锛�
+        JSONObject result = new JSONObject();
+        result.put("locNo", msgDto.getLocNo());
+        result.put("batchNo", msgDto.getWorkNo());
+        result.put("taskNo", msgDto.getWorkNo());
+        return R.ok(result);
+    }
 }

--
Gitblit v1.9.1