From e9543f18fbe81fb492df941fdc6fce59424f8f49 Mon Sep 17 00:00:00 2001
From: chen.lin <1442464845@qq.com>
Date: 星期四, 05 二月 2026 08:39:36 +0800
Subject: [PATCH] RCS对接

---
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java  |   70 ++++
 rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/WmsRcsService.java                  |    3 
 rsf-server/src/main/java/com/vincent/rsf/server/api/entity/constant/RcsConstant.java           |    7 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java           |    9 
 rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/RcsPubTaskParams.java         |    9 
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaitPakinServiceImpl.java |    7 
 rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java         |  192 ++++++++++++
 rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java        |  137 ++++++++-
 rsf-open-api/src/main/java/com/vincent/rsf/openApi/controller/WmsRcsController.java            |   18 +
 rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java           |   72 ++++
 rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java      |  279 +++++++++++++++++-
 rsf-admin/src/page/task/TaskList.jsx                                                           |    2 
 rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/TaskReportParams.java         |   29 +
 rsf-server/src/main/java/com/vincent/rsf/server/api/entity/params/WcsTaskParams.java           |    8 
 rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/constant/RcsConstant.java            |    2 
 15 files changed, 775 insertions(+), 69 deletions(-)

diff --git a/rsf-admin/src/page/task/TaskList.jsx b/rsf-admin/src/page/task/TaskList.jsx
index 4555b41..70f5161 100644
--- a/rsf-admin/src/page/task/TaskList.jsx
+++ b/rsf-admin/src/page/task/TaskList.jsx
@@ -357,7 +357,7 @@
         }
     }
     return (
-        (record.taskStatus == 1 || record.taskStatus == 101) && (record.taskType == 1 || record.taskType == 101 || record.taskType == 10 || record.taskType == 107 || record.taskType == 103 || record.taskType == 11) ?
+        (record.taskStatus == 1 || record.taskStatus == 101 || record.taskStatus == 199) && (record.taskType == 1 || record.taskType == 101 || record.taskType == 10 || record.taskType == 107 || record.taskType == 103 || record.taskType == 11) ?
             <ConfirmButton
                 onConfirm={clickCancel}
                 startIcon={<CancelIcon />}
diff --git a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/controller/WmsRcsController.java b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/controller/WmsRcsController.java
index e6099eb..4a4dcb8 100644
--- a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/controller/WmsRcsController.java
+++ b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/controller/WmsRcsController.java
@@ -7,9 +7,11 @@
 import com.vincent.rsf.openApi.entity.params.LocSiteParams;
 import com.vincent.rsf.openApi.entity.params.RcsPubTaskParams;
 import com.vincent.rsf.openApi.entity.params.SyncRcsLocsParam;
+import com.vincent.rsf.openApi.entity.params.TaskReportParams;
 import com.vincent.rsf.openApi.service.WmsRcsService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -19,6 +21,7 @@
 import java.util.Map;
 import java.util.Objects;
 
+@Slf4j
 @RestController
 @Api("RCS璋冨害浜や簰鎺ュ彛")
 @RequestMapping("/rcs")
@@ -97,5 +100,20 @@
         return wmsRcsService.modifyLocOrSite(params);
     }
 
+    /**
+     * @author Ryan
+     * @date 2026/2/3
+     * @description: RCS鍥炶皟鎺ュ彛
+     * @version 1.0
+     */
+    @ApiOperation("RCS鍥炶皟鎺ュ彛")
+    @PostMapping("/api/open/task/report")
+    public CommonResponse reportTask(@RequestBody TaskReportParams params) {
+        log.debug("RCS鍥炶皟锛歿}", params);
+        if (Objects.isNull(params)) {
+            throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        return wmsRcsService.reportTask(params);
+    }
 
 }
diff --git a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/constant/RcsConstant.java b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/constant/RcsConstant.java
index 5baa51e..62e4139 100644
--- a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/constant/RcsConstant.java
+++ b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/constant/RcsConstant.java
@@ -8,4 +8,6 @@
 
     public static String modifystatus = "/api/open/modify/status";
 
+    public static String cancelTask = "/api/open/task/cancel";
+
 }
diff --git a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/RcsPubTaskParams.java b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/RcsPubTaskParams.java
index 3240a4c..52aa46c 100644
--- a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/RcsPubTaskParams.java
+++ b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/RcsPubTaskParams.java
@@ -14,10 +14,10 @@
 public class RcsPubTaskParams implements Serializable {
 
     @ApiModelProperty("鎵规")
-    private String batch;
+    private String batchNo;
 
     @ApiModelProperty("浠诲姟鏄庣粏")
-    private List<TaskParam> taskList;
+    private List<TaskParam> tasks;
 }
 
 @Data
@@ -25,11 +25,8 @@
 @ApiModel(value = "TaskItem", description = "浠诲姟鍒楄〃")
 class TaskParam {
 
-    @ApiModelProperty("浠诲姟绫诲瀷{LOC_TO_LOC: 绉诲簱, LOC_TO_STA: 鍑哄簱, STA_TO_LOC: 鍏ュ簱, STA_TO_STA: 绔欑偣闂存惉杩恾")
-    private String taskType;
-
     @ApiModelProperty("浠诲姟鍙�")
-    private String seqNum;
+    private String taskNo;
 
     @ApiModelProperty("璧峰搴撲綅")
     private String oriLoc;
diff --git a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/TaskReportParams.java b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/TaskReportParams.java
new file mode 100644
index 0000000..2dcc160
--- /dev/null
+++ b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/TaskReportParams.java
@@ -0,0 +1,29 @@
+package com.vincent.rsf.openApi.entity.params;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * @author Ryan
+ * @date 2026/2/3
+ * @description: RCS鍥炶皟
+ * @version 1.0
+ */
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "TaskReportParams", description = "RCS鍥炶皟")
+public class TaskReportParams implements Serializable {
+
+    @ApiModelProperty(value = "浠诲姟鎵规", required = true)
+    private String batchNo;
+
+    @ApiModelProperty(value = "浠诲姟缂栧彿", required = true)
+    private String taskNo;
+
+    @ApiModelProperty(value = "鏃堕棿鎴�", required = true)
+    private String timestamp;
+}
diff --git a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/WmsRcsService.java b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/WmsRcsService.java
index 134688b..8b8928b 100644
--- a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/WmsRcsService.java
+++ b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/WmsRcsService.java
@@ -10,6 +10,7 @@
 import com.vincent.rsf.openApi.entity.params.LocSiteParams;
 import com.vincent.rsf.openApi.entity.params.RcsPubTaskParams;
 import com.vincent.rsf.openApi.entity.params.SyncRcsLocsParam;
+import com.vincent.rsf.openApi.entity.params.TaskReportParams;
 
 import java.util.List;
 import java.util.Map;
@@ -25,4 +26,6 @@
     List<SyncLocsDto> syncLocs(SyncRcsLocsParam params);
 
     R modifyLocOrSite(LocSiteParams params);
+
+    CommonResponse reportTask(TaskReportParams params);
 }
diff --git a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java
index 35b4602..7429bb9 100644
--- a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java
+++ b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java
@@ -19,6 +19,7 @@
 import com.vincent.rsf.openApi.entity.params.LocSiteParams;
 import com.vincent.rsf.openApi.entity.params.RcsPubTaskParams;
 import com.vincent.rsf.openApi.entity.params.SyncRcsLocsParam;
+import com.vincent.rsf.openApi.entity.params.TaskReportParams;
 import com.vincent.rsf.openApi.mapper.LocMapper;
 import com.vincent.rsf.openApi.service.WmsRcsService;
 import lombok.extern.slf4j.Slf4j;
@@ -60,28 +61,57 @@
     public CommonResponse pubTasks(RcsPubTaskParams params)  {
         /**RCS鍩虹閰嶇疆閾炬帴*/
         String rcsUrl =  rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.pubTask;
-        log.info("浠诲姟涓嬪彂锛岃姹傚湴鍧�锛� {}锛� 璇锋眰鍙傛暟锛� {}", rcsUrl , JSONObject.toJSONString(params));
+        log.info("========== 寮�濮嬩笅鍙戜换鍔″埌RCS ==========");
+        log.info("RCS璇锋眰鍦板潃锛歿}", rcsUrl);
+        if (params != null) {
+            log.info("鎵规缂栧彿锛歿}", params.getBatchNo());
+            if (params.getTasks() != null) {
+                log.info("浠诲姟鏁伴噺锛歿}", params.getTasks().size());
+            }
+        }
+        log.info("璇锋眰鍙傛暟锛歿}", JSONObject.toJSONString(params));
         HttpHeaders headers = new HttpHeaders();
         headers.add("Content-Type", "application/json");
         headers.add("api-version", "v2.0");
         HttpEntity httpEntity = new HttpEntity(params, headers);
+        long startTime = System.currentTimeMillis();
         ResponseEntity<String> exchange = restTemplate.exchange(rcsUrl, HttpMethod.POST, httpEntity, String.class);
-        log.info("浠诲姟涓嬪彂鍚庯紝鍝嶅簲缁撴灉锛� {}", exchange);
+        long endTime = System.currentTimeMillis();
+        log.info("RCS鍝嶅簲鑰楁椂锛歿}ms", (endTime - startTime));
+        log.info("RCS鍝嶅簲鐘舵�佺爜锛歿}", exchange.getStatusCode());
+        log.info("RCS鍝嶅簲澶达細{}", exchange.getHeaders());
+        log.info("RCS鍝嶅簲浣擄細{}", exchange.getBody());
         if (Objects.isNull(exchange.getBody())) {
-            throw new CoolException("浠诲姟涓嬪彂澶辫触锛侊紒");
+            log.error("========== RCS浠诲姟涓嬪彂澶辫触 ==========");
+            log.error("RCS鍝嶅簲浣撲负绌猴紝鏃犳硶瑙f瀽鍝嶅簲缁撴灉");
+            log.error("璇锋眰鍦板潃锛歿}", rcsUrl);
+            log.error("璇锋眰鍙傛暟锛歿}", JSONObject.toJSONString(params));
+            throw new CoolException("浠诲姟涓嬪彂澶辫触锛孯CS鍝嶅簲浣撲负绌猴紒锛�");
         } else {
             ObjectMapper objectMapper = new ObjectMapper();
             objectMapper.coercionConfigDefaults()
                     .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty);
             try {
                 CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class);
+                log.info("RCS鍝嶅簲瑙f瀽缁撴灉 - code锛歿}锛宮sg锛歿}锛宒ata锛歿}", 
+                        result.getCode(), result.getMsg(), result.getData());
                 if (result.getCode() == 200) {
+                    log.info("========== RCS浠诲姟涓嬪彂鎴愬姛 ==========");
                     return result;
                 } else {
+                    log.error("========== RCS浠诲姟涓嬪彂澶辫触 ==========");
+                    log.error("RCS杩斿洖閿欒 - code锛歿}锛宮sg锛歿}锛宒ata锛歿}", 
+                            result.getCode(), result.getMsg(), result.getData());
                     return result;
                 }
             } catch (JsonProcessingException e) {
-                throw new CoolException(e.getMessage());
+                log.error("========== RCS浠诲姟涓嬪彂寮傚父 ==========");
+                log.error("瑙f瀽RCS鍝嶅簲澶辫触锛屽搷搴斾綋锛歿}", exchange.getBody(), e);
+                throw new CoolException("瑙f瀽RCS鍝嶅簲澶辫触锛�" + e.getMessage());
+            } catch (Exception e) {
+                log.error("========== RCS浠诲姟涓嬪彂寮傚父 ==========");
+                log.error("浠诲姟涓嬪彂杩囩▼涓彂鐢熷紓甯�", e);
+                throw e;
             }
         }
     }
@@ -93,8 +123,66 @@
      * @version 1.0
      */
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public CommonResponse cancelTasks(Map<String, Object> params) {
-        return  new CommonResponse();
+        /**RCS鍩虹閰嶇疆閾炬帴*/
+        String rcsUrl = rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.cancelTask;
+        log.info("========== 寮�濮嬪彇娑圧CS浠诲姟锛坥pen-rcs鎺ュ彛锛� ==========");
+        log.info("RCS鍙栨秷浠诲姟璇锋眰鍦板潃锛歿}", rcsUrl);
+        log.info("RCS鍙栨秷浠诲姟璇锋眰鍙傛暟锛歿}", JSONObject.toJSONString(params));
+        
+        // 鎵撳嵃璇︾粏鐨勮姹傚弬鏁颁俊鎭�
+        if (params != null) {
+            Object batchNo = params.get("batchNo");
+            Object tasks = params.get("tasks");
+            if (batchNo != null) {
+                log.info("鎵规缂栧彿锛歿}", batchNo);
+            }
+            if (tasks != null) {
+                if (tasks instanceof List) {
+                    log.info("浠诲姟鏁伴噺锛歿}", ((List<?>) tasks).size());
+                    log.info("浠诲姟缂栧彿鍒楄〃锛歿}", tasks);
+                } else {
+                    log.info("浠诲姟鍙傛暟锛歿}", tasks);
+                }
+            }
+        }
+        
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("Content-Type", "application/json");
+        headers.add("api-version", "v2.0");
+        HttpEntity httpEntity = new HttpEntity(params, headers);
+        
+        long startTime = System.currentTimeMillis();
+        ResponseEntity<String> exchange = restTemplate.exchange(rcsUrl, HttpMethod.POST, httpEntity, String.class);
+        long endTime = System.currentTimeMillis();
+        
+        log.info("RCS鍙栨秷浠诲姟鍝嶅簲鑰楁椂锛歿}ms", (endTime - startTime));
+        log.info("RCS鍙栨秷浠诲姟鍝嶅簲鐘舵�佺爜锛歿}", exchange.getStatusCode());
+        log.info("RCS鍙栨秷浠诲姟鍝嶅簲澶达細{}", exchange.getHeaders());
+        log.info("RCS鍙栨秷浠诲姟鍝嶅簲浣擄細{}", exchange.getBody());
+        if (Objects.isNull(exchange.getBody())) {
+            throw new CoolException("鍙栨秷浠诲姟澶辫触锛侊紒");
+        } else {
+            ObjectMapper objectMapper = new ObjectMapper();
+            objectMapper.coercionConfigDefaults()
+                    .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty);
+            try {
+                CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class);
+                if (result.getCode() == 200) {
+                    log.info("========== RCS浠诲姟鍙栨秷鎴愬姛锛坥pen-rcs鎺ュ彛锛� ==========");
+                    log.info("鎴愬姛鍙栨秷鐨勪换鍔$紪鍙凤細{}", params.get("tasks"));
+                    return result;
+                } else {
+                    log.error("========== RCS浠诲姟鍙栨秷澶辫触锛坥pen-rcs鎺ュ彛锛� ==========");
+                    log.error("RCS杩斿洖閿欒鐮侊細{}锛岄敊璇俊鎭細{}", result.getCode(), result.getMsg());
+                    throw new CoolException("鍙栨秷浠诲姟澶辫触锛侊紒" + (result.getMsg() != null ? "锛�" + result.getMsg() : ""));
+                }
+            } catch (JsonProcessingException e) {
+                log.error("RCS鍙栨秷浠诲姟鍝嶅簲瑙f瀽澶辫触锛歿}", e.getMessage(), e);
+                throw new CoolException("RCS鍙栨秷浠诲姟鍝嶅簲瑙f瀽澶辫触锛�" + e.getMessage());
+            }
+        }
     }
 
     /**
@@ -105,6 +193,24 @@
      */
     @Override
     public CommonResponse callBackEvent(ExMsgCallbackParams params) {
+        // 鍙傛暟鏍¢獙
+        if (Objects.isNull(params)) {
+            log.error("RCS鍥炶皟浜嬩欢鍙傛暟涓虹┖锛�");
+            throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        
+        // 璇︾粏璁板綍鎺ユ敹鍒扮殑鍙傛暟
+        log.info("RCS鍥炶皟浜嬩欢鎺ユ敹鍙傛暟 - seqNum: {}, eventType: {}, robotCode: {}, zpallet: {}", 
+                params.getSeqNum(), params.getEventType(), params.getRobotCode(), params.getZpallet());
+        
+        // 妫�鏌ュ叧閿瓧娈垫槸鍚︿负绌�
+        if (Objects.isNull(params.getSeqNum()) || params.getSeqNum().isEmpty()) {
+            log.warn("RCS鍥炶皟浜嬩欢鍙傛暟seqNum涓虹┖锛佸畬鏁村弬鏁帮細{}", JSONObject.toJSONString(params));
+        }
+        if (Objects.isNull(params.getEventType()) || params.getEventType().isEmpty()) {
+            log.warn("RCS鍥炶皟浜嬩欢鍙傛暟eventType涓虹┖锛佸畬鏁村弬鏁帮細{}", JSONObject.toJSONString(params));
+        }
+        
         String callUrl =  wmsApi.getHost() + ":" + wmsApi.getPort() + WmsConstant.callBack;
         /**WMS鍩虹閰嶇疆閾炬帴*/
         log.info("浠诲姟鎵ц鐘舵�佷笂鎶ワ紝璇锋眰鍦板潃锛� {}锛� 璇锋眰鍙傛暟锛� {}", callUrl , JSONObject.toJSONString(params));
@@ -192,7 +298,7 @@
     public List<SyncLocsDto> syncRcsLocs(SyncRcsLocsParam  params) {
         /**RCS鍩虹閰嶇疆閾炬帴*/
         String rcsUrl =  rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.syncLocs;
-        log.info("浠诲姟涓嬪彂锛岃姹傚湴鍧�锛� {}锛� 璇锋眰鍙傛暟锛� {}", rcsUrl , JSONObject.toJSONString(params));
+        log.info("浠诲姟涓嬪彂锛岃姹傚湴鍧�2锛� {}锛� 璇锋眰鍙傛暟锛� {}", rcsUrl , JSONObject.toJSONString(params));
         HttpHeaders headers = new HttpHeaders();
         headers.add("Content-Type", "application/json");
         headers.add("api-version", "v2.0");
@@ -220,4 +326,78 @@
             }
         }
     }
+
+    /**
+     * @author Ryan
+     * @date 2026/2/3
+     * @description: 浠诲姟鎵ц閫氱煡涓婃姤锛圧CS鍥炶皟鎺ュ彛锛�
+     * @version 1.0
+     */
+    @Override
+    public CommonResponse reportTask(TaskReportParams params) {
+        log.info("RCS鍥炶皟锛岃姹傚弬鏁帮細 {}", JSONObject.toJSONString(params));
+        
+        // 鍙傛暟鏍¢獙
+        if (Objects.isNull(params)) {
+            throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        if (Objects.isNull(params.getBatchNo()) || params.getBatchNo().isEmpty()) {
+            throw new CoolException("浠诲姟鎵规涓嶈兘涓虹┖锛侊紒");
+        }
+        if (Objects.isNull(params.getTaskNo()) || params.getTaskNo().isEmpty()) {
+            throw new CoolException("浠诲姟缂栧彿涓嶈兘涓虹┖锛侊紒");
+        }
+        if (Objects.isNull(params.getTimestamp()) || params.getTimestamp().isEmpty()) {
+            throw new CoolException("鏃堕棿鎴充笉鑳戒负绌猴紒锛�");
+        }
+        
+        // 灏員askReportParams杞崲涓篍xMsgParams鏍煎紡锛坱askNo -> seqNum锛�
+        // 鏍规嵁RCS鏂版帴鍙h鑼冿紝taskNo瀵瑰簲鏃ф帴鍙g殑seqNum
+        JSONObject exMsgParams = new JSONObject();
+        exMsgParams.put("seqNum", params.getTaskNo()); // taskNo鏄犲皠鍒皊eqNum
+        // eventType璁剧疆涓篍ND锛岃〃绀轰换鍔″畬鎴愶紙鏍规嵁涓氬姟闇�姹傚彲鑳介渶瑕佽皟鏁达級
+        exMsgParams.put("eventType", "END");
+        exMsgParams.put("robotCode", null);
+        exMsgParams.put("zpallet", null);
+        
+        // 灏嗕换鍔′笂鎶ュ洖璋冭浆鍙戝埌WMS绯荤粺
+        String callUrl = wmsApi.getHost() + ":" + wmsApi.getPort() + WmsConstant.callBack;
+        log.info("RCS鍥炶皟锛岃姹傚湴鍧�锛� {}锛� 杞崲鍚庡弬鏁帮細 {}", callUrl, exMsgParams.toJSONString());
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("Content-Type", "application/json");
+        headers.add("api-version", "v2.0");
+        HttpEntity httpEntity = new HttpEntity(exMsgParams, headers);
+        ResponseEntity<String> exchange = restTemplate.exchange(callUrl, HttpMethod.POST, httpEntity, String.class);
+        log.info("RCS鍥炶皟锛屽搷搴旂粨鏋滐細 {}", exchange);
+        
+        if (Objects.isNull(exchange.getBody())) {
+            // 濡傛灉鍥炶皟澶辫触锛岃繑鍥炴垚鍔熷搷搴旓紙閬垮厤RCS閲嶅鍥炶皟锛�
+            CommonResponse response = new CommonResponse();
+            response.setCode(200);
+            response.setMsg("鎺ユ敹鎴愬姛");
+            log.warn("RCS鍥炶皟澶辫触锛屼絾杩斿洖鎴愬姛鍝嶅簲锛屼换鍔$紪鍙凤細{}锛屾壒娆★細{}", params.getTaskNo(), params.getBatchNo());
+            return response;
+        } else {
+            ObjectMapper objectMapper = new ObjectMapper();
+            objectMapper.coercionConfigDefaults()
+                    .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty);
+            try {
+                CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class);
+                if (result.getCode() == 200) {
+                    log.info("RCS鍥炶皟涓婃姤鎴愬姛锛屼换鍔$紪鍙凤細{}锛屾壒娆★細{}", params.getTaskNo(), params.getBatchNo());
+                    return result;
+                } else {
+                    log.warn("RCS鍥炶皟涓婃姤鍥炶皟杩斿洖闈�200鐘舵�侊紝浠诲姟缂栧彿锛歿}锛屾壒娆★細{}锛屽搷搴旓細{}", params.getTaskNo(), params.getBatchNo(), exchange.getBody());
+                    return result;
+                }
+            } catch (JsonProcessingException e) {
+                log.error("RCS鍥炶皟涓婃姤鍥炶皟鍝嶅簲瑙f瀽澶辫触锛屼换鍔$紪鍙凤細{}锛屾壒娆★細{}锛岄敊璇細{}", params.getTaskNo(), params.getBatchNo(), e.getMessage());
+                // 瑙f瀽澶辫触鏃惰繑鍥炴垚鍔熷搷搴旓紝閬垮厤RCS閲嶅鍥炶皟
+                CommonResponse response = new CommonResponse();
+                response.setCode(200);
+                response.setMsg("鎺ユ敹鎴愬姛");
+                return response;
+            }
+        }
+    }
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/constant/RcsConstant.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/constant/RcsConstant.java
index 0d527e0..7eddd2f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/constant/RcsConstant.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/constant/RcsConstant.java
@@ -2,8 +2,8 @@
 
 public class RcsConstant {
 
-    //涓嬪彂浠诲姟鑷砇CS
-    public static String pubTask = "/rsf-open-api/rcs/pub/task";
+    //涓嬪彂浠诲姟鑷砇CS锛堟柊鎺ュ彛璺緞锛�
+    public static String pubTask = "/api/open/bus/submit";
 
     //鍚屾RCS搴撲綅淇℃伅
     public static String syncLocs = "/rsf-open-api/rcs/sync/locs";
@@ -16,4 +16,7 @@
 
     //涓婃姤绔欑偣鐘舵��
     public static String REPORT_SITE_STATUS = "/rsf-open-api/rcs/modify/status";
+    
+    //鍙栨秷RCS浠诲姟
+    public static String cancelTask = "/api/open/task/cancel";
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/params/WcsTaskParams.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/params/WcsTaskParams.java
index e25c034..24fc123 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/params/WcsTaskParams.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/entity/params/WcsTaskParams.java
@@ -14,9 +14,9 @@
 @ApiModel(value = "WcsTaskParams", description = "浠诲姟涓嬪彂鍙傛暟")
 public class WcsTaskParams implements Serializable {
 
-    @ApiModelProperty("鎵规")
-    private String batch;
+    @ApiModelProperty("鎵规缂栧彿")
+    private String batchNo;
 
-    @ApiModelProperty("浠诲姟鏄庣粏")
-    private List<TaskItemParam> taskList;
+    @ApiModelProperty("浠诲姟鏁扮粍")
+    private List<TaskItemParam> tasks;
 }
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java
index d1cfe78..c5c7240 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java
@@ -35,6 +35,8 @@
 import com.vincent.rsf.server.system.service.UserService;
 import com.vincent.rsf.server.system.utils.SerialRuleUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -57,6 +59,8 @@
  */
 @Service
 public class MobileServiceImpl implements MobileService {
+
+    private static final Logger logger = LoggerFactory.getLogger(MobileServiceImpl.class);
 
     @Value("${super.pwd}")
     private String superPwd;
@@ -544,9 +548,9 @@
         String batch = params.get("batch");
 //        String barcode = params.get("barcode");
 
-        if (Objects.isNull(crushNo)) {
-            throw new CoolException("绁ㄥ彿涓嶈兘涓虹┖锛侊紒");
-        }
+//        if (Objects.isNull(crushNo)) {
+//            throw new CoolException("绁ㄥ彿涓嶈兘涓虹┖锛侊紒");
+//        }
 //        if (Objects.isNull(code)) {
 //            throw new CoolException("瀹瑰櫒鍙蜂笉鑳戒负绌猴紒锛�");
 //        }
@@ -561,29 +565,132 @@
 //            }
 //        }
 
-        String fieldIndex = null;
+        String fieldIndexTemp = null;
         if (!Objects.isNull(crushNo)) {
             FieldsItem fieldsItem = fieldsItemService.getOne(new LambdaQueryWrapper<FieldsItem>().eq(FieldsItem::getValue, crushNo).last("Limit 1"));
             if (!Objects.isNull(fieldsItem)) {
-                fieldIndex = fieldsItem.getUuid();
+                fieldIndexTemp = fieldsItem.getUuid();
             }
         }
-        //TODO 鍚庣画闇�鏍规嵁绛栫暐閰嶇疆锛岃幏鍙栫粍鎷栨暟鎹�傚锛氭贩瑁咃紝鎸夋壒娆℃贩瑁呯瓑
-        LambdaQueryWrapper<WarehouseAreasItem> queryWrapper = new LambdaQueryWrapper<WarehouseAreasItem>()
-                .or().eq(!Cools.isEmpty(code), WarehouseAreasItem::getTrackCode, code)
-                .or().eq(!Cools.isEmpty(batch), WarehouseAreasItem::getSplrBatch, batch)
-                .or().eq(WarehouseAreasItem::getFieldsIndex, fieldIndex)
-                .or().eq(!Cools.isEmpty(matnrCode), WarehouseAreasItem::getMatnrCode, matnrCode)
-                .or().eq(!Cools.isEmpty(asnCode), WarehouseAreasItem::getAsnCode, asnCode);
-        List<WarehouseAreasItem> list = warehouseAreasItemService.list(queryWrapper);
-        if (!list.isEmpty()) {
-            list.removeIf(e -> e.getAnfme() <= e.getWorkQty());
+        final String fieldIndex = fieldIndexTemp;
+        
+        // 妫�鏌ユ槸鍚︽湁鑷冲皯涓�涓湁鏁堟煡璇㈡潯浠�
+        boolean hasValidCondition = !Cools.isEmpty(code) || !Cools.isEmpty(batch) 
+                || !Objects.isNull(fieldIndex) || !Cools.isEmpty(matnrCode) || !Cools.isEmpty(asnCode);
+        
+        if (!hasValidCondition) {
+            throw new CoolException("璇疯嚦灏戣緭鍏ヤ竴涓煡璇㈡潯浠讹細鐗╂枡缂栫爜銆丄SN鍗曞彿銆佽窡韪爜銆佹壒娆℃垨绁ㄥ彿");
         }
+        
+        //TODO 鍚庣画闇�鏍规嵁绛栫暐閰嶇疆锛岃幏鍙栫粍鎷栨暟鎹�傚锛氭贩瑁咃紝鎸夋壒娆℃贩瑁呯瓑
+        LambdaQueryWrapper<WarehouseAreasItem> queryWrapper = new LambdaQueryWrapper<>();
+        
+        // 鏋勫缓OR鏌ヨ鏉′欢缁�
+        // 缁熻鏈夋晥鏉′欢鏁伴噺
+        int conditionCount = 0;
+        if (!Cools.isEmpty(code)) conditionCount++;
+        if (!Cools.isEmpty(batch)) conditionCount++;
+        if (!Objects.isNull(fieldIndex)) conditionCount++;
+        if (!Cools.isEmpty(matnrCode)) conditionCount++;
+        if (!Cools.isEmpty(asnCode)) conditionCount++;
+        
+        // 濡傛灉鍙湁涓�涓潯浠讹紝鐩存帴浣跨敤eq锛涘鏋滄湁澶氫釜鏉′欢锛屼娇鐢╝nd鍖呰9or鏉′欢缁�
+        if (conditionCount == 1) {
+            // 鍗曚釜鏉′欢锛岀洿鎺ユ煡璇�
+            if (!Cools.isEmpty(code)) {
+                queryWrapper.eq(WarehouseAreasItem::getTrackCode, code);
+            } else if (!Cools.isEmpty(batch)) {
+                queryWrapper.eq(WarehouseAreasItem::getSplrBatch, batch);
+            } else if (!Objects.isNull(fieldIndex)) {
+                queryWrapper.eq(WarehouseAreasItem::getFieldsIndex, fieldIndex);
+            } else if (!Cools.isEmpty(matnrCode)) {
+                queryWrapper.eq(WarehouseAreasItem::getMatnrCode, matnrCode);
+            } else if (!Cools.isEmpty(asnCode)) {
+                queryWrapper.eq(WarehouseAreasItem::getAsnCode, asnCode);
+            }
+        } else {
+            // 澶氫釜鏉′欢锛屼娇鐢∣R杩炴帴
+            queryWrapper.and(wrapper -> {
+                boolean first = true;
+                if (!Cools.isEmpty(code)) {
+                    wrapper.eq(WarehouseAreasItem::getTrackCode, code);
+                    first = false;
+                }
+                if (!Cools.isEmpty(batch)) {
+                    if (!first) wrapper.or();
+                    wrapper.eq(WarehouseAreasItem::getSplrBatch, batch);
+                    first = false;
+                }
+                if (!Objects.isNull(fieldIndex)) {
+                    if (!first) wrapper.or();
+                    wrapper.eq(WarehouseAreasItem::getFieldsIndex, fieldIndex);
+                    first = false;
+                }
+                if (!Cools.isEmpty(matnrCode)) {
+                    if (!first) wrapper.or();
+                    wrapper.eq(WarehouseAreasItem::getMatnrCode, matnrCode);
+                    first = false;
+                }
+                if (!Cools.isEmpty(asnCode)) {
+                    if (!first) wrapper.or();
+                    wrapper.eq(WarehouseAreasItem::getAsnCode, asnCode);
+                }
+            });
+        }
+        
+        // 鎵撳嵃鏌ヨ鍙傛暟鍒版帶鍒跺彴
+        logger.info("=== 鏌ヨ鍙粍鎵樼墿鏂� ===");
+        logger.info("鏌ヨ鍙傛暟 - code: {}, matnrCode: {}, asnCode: {}, batch: {}, fieldIndex: {}", 
+                code, matnrCode, asnCode, batch, fieldIndex);
+        
+        List<WarehouseAreasItem> list = warehouseAreasItemService.list(queryWrapper);
+        logger.info("鏌ヨ鍒� {} 鏉℃敹璐у尯搴撳瓨鏁版嵁", list.size());
+        
+        // 杩囨护鏉′欢锛氬彧杩斿洖鍙粍鎵樻暟閲� > 0 鐨勬暟鎹�
+        // 鍙粍鎵樻暟閲� = anfme - workQty - qty
+        if (!list.isEmpty()) {
+            int beforeFilterSize = list.size();
+            list.removeIf(e -> {
+                // 濡傛灉anfme涓簄ull锛岀Щ闄よ鏁版嵁
+                Double anfme = e.getAnfme();
+                if (Objects.isNull(anfme) || anfme <= 0) {
+                    logger.debug("杩囨护鏁版嵁 - ID: {}, matnrCode: {}, anfme涓簄ull鎴�<=0: {}", 
+                            e.getId(), e.getMatnrCode(), anfme);
+                    return true; // 绉婚櫎鏁伴噺涓簄ull鎴�<=0鐨勬暟鎹�
+                }
+                
+                Double workQty = Objects.isNull(e.getWorkQty()) ? 0.0 : e.getWorkQty();
+                Double qty = Objects.isNull(e.getQty()) ? 0.0 : e.getQty();
+                
+                // 鍙粍鎵樻暟閲� = 鎬绘暟閲� - 宸叉墽琛屾暟閲� - 宸叉敹璐ф暟閲�
+                Double availableQty = anfme - workQty - qty;
+                if (availableQty <= 0) {
+                    logger.debug("杩囨护鏁版嵁 - ID: {}, matnrCode: {}, anfme: {}, workQty: {}, qty: {}, 鍙粍鎵樻暟閲�: {} <= 0", 
+                            e.getId(), e.getMatnrCode(), anfme, workQty, qty, availableQty);
+                }
+                return availableQty <= 0; // 绉婚櫎鍙粍鎵樻暟閲� <= 0 鐨勬暟鎹�
+            });
+            
+            // 濡傛灉杩囨护鍚庢暟鎹负绌猴紝璇存槑鎵�鏈夋暟鎹兘琚繃婊ゆ帀浜�
+            if (list.isEmpty() && beforeFilterSize > 0) {
+                logger.warn("鏈壘鍒板彲缁勬墭鐨勭墿鏂欙紝璇锋鏌ワ細1.鐗╂枡缂栫爜鏄惁姝g‘ 2.鐗╂枡鏄惁宸叉敹璐ц嚦鏀惰揣鍖� 3.鏄惁杩樻湁鍙粍鎵樻暟閲�");
+                logger.warn("鏌ヨ鏉′欢 - code: {}, matnrCode: {}, asnCode: {}, batch: {}, fieldIndex: {}", 
+                        code, matnrCode, asnCode, batch, fieldIndex);
+                logger.warn("鏌ヨ鍒� {} 鏉℃暟鎹紝浣嗗叏閮ㄨ杩囨护锛堝彲缁勬墭鏁伴噺 <= 0锛�", beforeFilterSize);
+            }
+        } else {
+            logger.warn("鏈壘鍒板彲缁勬墭鐨勭墿鏂欙紝璇锋鏌ワ細1.鐗╂枡缂栫爜鏄惁姝g‘ 2.鐗╂枡鏄惁宸叉敹璐ц嚦鏀惰揣鍖� 3.鏄惁杩樻湁鍙粍鎵樻暟閲�");
+            logger.warn("鏌ヨ鏉′欢 - code: {}, matnrCode: {}, asnCode: {}, batch: {}, fieldIndex: {}", 
+                    code, matnrCode, asnCode, batch, fieldIndex);
+            logger.warn("鏁版嵁搴撴煡璇㈢粨鏋滀负绌猴紝鍙兘鍘熷洜锛�1.鐗╂枡缂栫爜涓嶅尮閰� 2.鐗╂枡鏈敹璐ц嚦鏀惰揣鍖� 3.鏁版嵁宸茶鍒犻櫎");
+        }
+        
         list.forEach(item -> {
             Map<String, String> fields = FieldsUtils.getFields(item.getFieldsIndex());
             item.setExtendFields(fields);
         });
 
+        logger.info("杩斿洖 {} 鏉″彲缁勬墭鐗╂枡鏁版嵁", list.size());
         return R.ok(list);
     }
 
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 87de94a..5a7939a 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
@@ -463,12 +463,18 @@
     @Override
     public R receiveExMsg(ExMsgParams params) {
         if (Objects.isNull(params)) {
+            log.error("RCS鍥炶皟涓虹┖锛�");
             return R.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
         }
+        log.info("========== 鎺ユ敹RCS鍥炶皟 ==========");
+        log.info("浠诲姟缂栧彿锛歿}锛屼簨浠剁被鍨嬶細{}", params.getSeqNum(), params.getEventType());
         Task task = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getTaskCode, params.getSeqNum()));
         if (Objects.isNull(task)) {
-            throw new CoolException("浠诲姟涓嶅瓨鍦ㄥ彲宸茬粨鏉燂紒锛�");
+            log.error("浠诲姟涓嶅瓨鍦ㄦ垨宸茬粨鏉燂紒浠诲姟缂栧彿锛歿}", params.getSeqNum());
+            throw new CoolException("浠诲姟涓嶅瓨鍦ㄦ垨宸茬粨鏉燂紒锛�");
         }
+        log.info("鏌ヨ鍒颁换鍔� - 浠诲姟缂栫爜锛歿}锛屼换鍔$被鍨嬶細{}锛屽綋鍓嶇姸鎬侊細{}", 
+                task.getTaskCode(), task.getTaskType(), task.getTaskStatus());
 
         /**鏂欑鎼繍涓紝 淇敼绔欑偣鐘舵��*/
 //        if (params.getEventType().equals(CallBackEvent.CALL_BACK_EVENT_OBIT.event)) {
@@ -493,21 +499,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)
@@ -519,22 +544,45 @@
                 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());
                 }
             }
+        } else {
+            log.warn("鏈鐞嗙殑浜嬩欢绫诲瀷 - 浜嬩欢绫诲瀷锛歿}锛屼换鍔$紪鐮侊細{}锛屼换鍔$被鍨嬶細{}", 
+                    params.getEventType(), task.getTaskCode(), task.getTaskType());
         }
-        log.info(JSONObject.toJSONString(params));
+        log.info("========== RCS鍥炶皟澶勭悊瀹屾垚 ==========");
+        log.info("澶勭悊缁撴灉锛歿}", JSONObject.toJSONString(params));
         return R.ok(JSONObject.toJSONString(params));
     }
 
@@ -547,7 +595,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");
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
index 09c9ea8..cdabff1 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.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.framework.common.R;
 import com.vincent.rsf.framework.exception.CoolException;
 import com.vincent.rsf.server.api.config.RemotesInfoProperties;
@@ -252,6 +251,7 @@
     @Scheduled(cron = "0/55 * * * * ?  ")
     @Transactional(rollbackFor = Exception.class)
     public void pubTaskToWcs() {
+        log.info("瀹氭椂浠诲姟寮�濮嬫墽琛岋細浠诲姟涓嬪彂鍒癛CS");
         Long loginUserId = SystemAuthUtils.getLoginUserId();
         List<Integer> list = Arrays.asList(TaskType.TASK_TYPE_IN.type, TaskType.TASK_TYPE_OUT.type, TaskType.TASK_TYPE_LOC_MOVE.type, TaskType.TASK_TYPE_EMPITY_IN.type
                 , TaskType.TASK_TYPE_CHECK_IN.type, TaskType.TASK_TYPE_MERGE_IN.type, TaskType.TASK_TYPE_EMPITY_OUT.type, TaskType.TASK_TYPE_PICK_IN.type,
@@ -261,13 +261,16 @@
                 .in(Task::getTaskType, list)
                 .in(Task::getTaskStatus, integers)
                 .orderByDesc(Task::getSort));
+        log.info("鏌ヨ鍒板緟涓嬪彂浠诲姟鏁伴噺锛歿}", tasks.size());
         if (tasks.isEmpty()) {
+            log.debug("娌℃湁寰呬笅鍙戠殑浠诲姟锛屽畾鏃朵换鍔$粨鏉�");
             return;
         }
         Config config = configService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getFlag, GlobalConfigCode.AUTO_RUN_CHECK_ORDERS));
         if (!Objects.isNull(config) && !Objects.isNull(config.getVal())) {
             if (Boolean.parseBoolean(config.getVal())) {
-               return;
+                log.info("閰嶇疆椤笰UTO_RUN_CHECK_ORDERS涓簍rue锛岃烦杩囦换鍔′笅鍙�");
+                return;
             }
         }
 //        for (Task task : tasks) {
@@ -282,7 +285,9 @@
 //            }
 //        }
         /**涓嬪彂鏅�氱珯鐐逛换鍔★紝鎶ラ敊鍥炴粴锛屼笉鍐嶅線涓嬫墽琛�*/
+        log.info("寮�濮嬩笅鍙憑}涓换鍔″埌RCS", tasks.size());
         taskService.pubTaskToWcs(tasks);
+        log.info("瀹氭椂浠诲姟鎵ц瀹屾垚锛氫换鍔′笅鍙戝埌RCS");
     }
 
     /**
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
index f1a7ffb..9da1c20 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -19,6 +19,7 @@
 import com.vincent.rsf.server.manager.utils.OptimalAlgorithmUtil;
 import com.vincent.rsf.server.system.constant.SerialRuleCode;
 import com.vincent.rsf.server.system.utils.SerialRuleUtils;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,6 +41,7 @@
  * @return
  * @time 2025/3/7 08:02
  */
+@Slf4j
 @Service("outStockServiceImpl")
 public class OutStockServiceImpl extends ServiceImpl<AsnOrderMapper, WkOrder> implements OutStockService {
 
@@ -488,21 +490,83 @@
             if (!Objects.isNull(loc)) {
                 List<LocItem> locItems = new ArrayList<>();
                 LocItem locItem = locItemService.getById(param.getId());
+                
+                if (Objects.isNull(locItem)) {
+                    throw new CoolException("搴撲綅鏄庣粏涓嶅瓨鍦紝ID锛�" + param.getId());
+                }
 
                 // 淇锛氭瀯寤烘煡璇㈡潯浠讹紝鍏堟瀯寤哄熀纭�鏉′欢锛屽啀鏍规嵁鍊兼槸鍚︿负绌哄姩鎬佹坊鍔�
+                // 浼樺厛浣跨敤渚涘簲鍟嗘壒娆″尮閰嶏紝濡傛灉娌℃湁鍒欎娇鐢ㄥ簱瀛樻壒娆″尮閰�
                 LambdaQueryWrapper<WkOrderItem> orderItemWrapper = new LambdaQueryWrapper<WkOrderItem>()
                         .eq(WkOrderItem::getOrderId, outId)
                         .eq(WkOrderItem::getMatnrId, locItem.getMatnrId());
-                if (StringUtils.isNotBlank(locItem.getBatch())) {
-                    orderItemWrapper.eq(WkOrderItem::getSplrBatch, locItem.getBatch());
+                
+                // 浼樺厛浣跨敤渚涘簲鍟嗘壒娆″尮閰�
+                if (StringUtils.isNotBlank(locItem.getSplrBatch())) {
+                    orderItemWrapper.eq(WkOrderItem::getSplrBatch, locItem.getSplrBatch());
+                } else if (StringUtils.isNotBlank(locItem.getBatch())) {
+                    // 濡傛灉LocItem鍙湁batch瀛楁锛屽皾璇曞悓鏃跺尮閰峎kOrderItem鐨刡atch鍜宻plrBatch瀛楁
+                    // 鍥犱负鏌愪簺鎯呭喌涓婰ocItem鐨刡atch鍙兘瀵瑰簲WkOrderItem鐨剆plrBatch
+                    orderItemWrapper.and(wrapper -> wrapper
+                            .eq(WkOrderItem::getBatch, locItem.getBatch())
+                            .or()
+                            .eq(WkOrderItem::getSplrBatch, locItem.getBatch())
+                    );
                 }
+                
                 if (StringUtils.isNotBlank(locItem.getFieldsIndex())) {
                     orderItemWrapper.eq(WkOrderItem::getFieldsIndex, locItem.getFieldsIndex());
                 }
                 WkOrderItem orderItem = outStockItemService.getOne(orderItemWrapper);
 
+                // 濡傛灉鎵句笉鍒板崟鎹槑缁嗭紝涓擫ocItem鏉ヨ嚜搴撳瓨璋冩暣锛屽垯鑷姩鍒涘缓WkOrderItem
                 if (Objects.isNull(orderItem)) {
-                    throw new CoolException("鍗曟嵁鏄庣粏涓嶅瓨鍦紒锛�");
+                    // 妫�鏌ユ槸鍚︽槸搴撳瓨璋冩暣浜х敓鐨勫簱瀛�
+                    if (locItem.getWkType() != null && 
+                        locItem.getWkType().equals(Short.parseShort(OrderWorkType.ORDER_WORK_TYPE_STOCK_REVISE.type))) {
+                        // 鑾峰彇鍑哄簱鍗曚俊鎭�
+                        WkOrder outOrder = outStockService.getById(outId);
+                        if (Objects.isNull(outOrder)) {
+                            throw new CoolException("鍑哄簱鍗曟嵁涓嶅瓨鍦紒锛�");
+                        }
+                        
+                        log.info("搴撳瓨璋冩暣浜х敓鐨勫簱瀛橈紝鑷姩鍒涘缓WkOrderItem - 鍑哄簱鍗旾D锛歿}锛岀墿鏂橧D锛歿}锛屾壒娆★細{}", 
+                                outId, locItem.getMatnrId(), locItem.getBatch());
+                        
+                        // 鍒涘缓WkOrderItem
+                        orderItem = new WkOrderItem();
+                        orderItem.setOrderId(outId)
+                                .setOrderCode(outOrder.getCode())
+                                .setMatnrId(locItem.getMatnrId())
+                                .setMatnrCode(locItem.getMatnrCode())
+                                .setMaktx(locItem.getMaktx())
+                                .setBatch(StringUtils.isNotBlank(param.getBatch()) ? param.getBatch() : locItem.getBatch())
+                                .setSplrBatch(StringUtils.isNotBlank(locItem.getSplrBatch()) ? locItem.getSplrBatch() : 
+                                             (StringUtils.isNotBlank(locItem.getBatch()) ? locItem.getBatch() : null))
+                                .setFieldsIndex(locItem.getFieldsIndex())
+                                .setAnfme(param.getOutQty())
+                                .setWorkQty(0.0)
+                                .setStockUnit(locItem.getUnit())
+                                .setPurUnit(locItem.getUnit())
+                                .setSpec(locItem.getSpec())
+                                .setModel(locItem.getModel())
+                                .setCreateBy(loginUserId)
+                                .setUpdateBy(loginUserId)
+                                .setCreateTime(new Date())
+                                .setUpdateTime(new Date());
+                        
+                        if (!outStockItemService.save(orderItem)) {
+                            throw new CoolException("搴撳瓨璋冩暣鍗曟嵁鏄庣粏鍒涘缓澶辫触锛侊紒");
+                        }
+                        
+                        log.info("WkOrderItem鍒涘缓鎴愬姛 - ID锛歿}锛屽嚭搴撳崟ID锛歿}锛岀墿鏂橧D锛歿}", 
+                                orderItem.getId(), outId, locItem.getMatnrId());
+                    } else {
+                        throw new CoolException("鍗曟嵁鏄庣粏涓嶅瓨鍦紒锛佸嚭搴撳崟ID锛�" + outId + "锛岀墿鏂橧D锛�" + locItem.getMatnrId() + 
+                                (StringUtils.isNotBlank(locItem.getSplrBatch()) ? "锛屼緵搴斿晢鎵规锛�" + locItem.getSplrBatch() : 
+                                 StringUtils.isNotBlank(locItem.getBatch()) ? "锛屽簱瀛樻壒娆★細" + locItem.getBatch() : "") +
+                                (StringUtils.isNotBlank(locItem.getFieldsIndex()) ? "锛屽瓧娈电储寮曪細" + locItem.getFieldsIndex() : ""));
+                    }
                 }
 
                 locItem.setOutQty(param.getOutQty())
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 0fc9d28..adcbecd 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
@@ -462,6 +462,9 @@
                 if (task.getTaskType().equals(TaskType.TASK_TYPE_IN.type)) {
                     //1.鍏ュ簱
                     complateInstock(task, loginUserId);
+                } else if (task.getTaskType().equals(TaskType.TASK_TYPE_EMPITY_IN.type)) {
+                    //10.绌烘墭鍏ュ簱
+                    complateEmpityInStock(task, loginUserId);
                 } else if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_IN.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) {
                     //53.鎷f枡鍐嶅叆搴�
                     //57.鐩樼偣鍐嶅叆搴�
@@ -777,16 +780,132 @@
     @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);
+        // 鍏堟煡璇㈡墍鏈変换鍔★紙涓嶉檺鍒剁姸鎬侊級锛岀敤浜庢鏌CS浠诲姟
         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_EMPITY_IN.type, TaskType.TASK_TYPE_LOC_MOVE.type,
                 TaskType.TASK_TYPE_EMPITY_OUT.type, TaskType.TASK_TYPE_MERGE_OUT.type);
+        List<Task> allTasks = this.list(new LambdaQueryWrapper<Task>()
+                .in(Task::getTaskType, list)
+                .in(Task::getId, (Object[]) ids));
+        
+        if (allTasks.isEmpty()) {
+            throw new CoolException("浠诲姟涓嶅瓨鍦紒锛�");
+        }
+        
+        // 鏀堕泦闇�瑕佸彇娑堢殑RCS浠诲姟缂栧彿鍜屾壒娆$紪鍙凤紙涓嶉檺鍒剁姸鎬侊紝鍙宸蹭笅鍙戝埌RCS灏遍渶瑕佸彇娑堬級
+        List<String> rcsTaskCodes = new ArrayList<>();
+        String batchNo = null;
+        for (Task task : allTasks) {
+            // 鍒ゆ柇浠诲姟鏄惁宸蹭笅鍙戝埌RCS
+            // 鍏ュ簱浠诲姟锛氱姸鎬� >= WCS_EXECUTE_IN(2) 琛ㄧず宸蹭笅鍙�
+            // 鍑哄簱浠诲姟锛氱姸鎬� >= WCS_EXECUTE_OUT(102) 琛ㄧず宸蹭笅鍙�
+            boolean isRcsTask = false;
+            if (task.getTaskType() < 100) {
+                // 鍏ュ簱浠诲姟
+                if (task.getTaskStatus() >= TaskStsType.WCS_EXECUTE_IN.id) {
+                    isRcsTask = true;
+                }
+            } else {
+                // 鍑哄簱浠诲姟
+                if (task.getTaskStatus() >= TaskStsType.WCS_EXECUTE_OUT.id) {
+                    isRcsTask = true;
+                }
+            }
+            
+            if (isRcsTask && StringUtils.isNotBlank(task.getTaskCode())) {
+                rcsTaskCodes.add(task.getTaskCode());
+                // 鑾峰彇鎵规缂栧彿锛屼紭鍏堜娇鐢ㄤ换鍔$殑barcode锛屽鏋滄病鏈夊垯浣跨敤浠诲姟缂栧彿
+                if (StringUtils.isBlank(batchNo)) {
+                    if (StringUtils.isNotBlank(task.getBarcode())) {
+                        batchNo = task.getBarcode();
+                    } else if (StringUtils.isNotBlank(task.getTaskCode())) {
+                        // 濡傛灉浠诲姟娌℃湁barcode锛屼娇鐢ㄤ换鍔$紪鍙蜂綔涓烘壒娆$紪鍙�
+                        batchNo = task.getTaskCode();
+                    }
+                }
+                log.info("浠诲姟宸蹭笅鍙戝埌RCS锛岄渶瑕佸彇娑圧CS浠诲姟 - 浠诲姟ID锛歿}锛屼换鍔$紪鍙凤細{}锛屼换鍔$姸鎬侊細{}锛屾墭鐩樼爜锛歿}", 
+                        task.getId(), task.getTaskCode(), task.getTaskStatus(), task.getBarcode());
+            }
+        }
+        
+        // 濡傛灉鏈変换鍔″凡涓嬪彂鍒癛CS锛屽厛璋冪敤RCS鍙栨秷鎺ュ彛
+        boolean rcsCancelSuccess = false;
+        if (!rcsTaskCodes.isEmpty()) {
+            try {
+                log.info("========== 寮�濮嬪彇娑圧CS浠诲姟 ==========");
+                log.info("闇�瑕佸彇娑堢殑RCS浠诲姟缂栧彿锛歿}", rcsTaskCodes);
+                String rcsUrl = rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.cancelTask;
+                log.info("RCS鍙栨秷浠诲姟璇锋眰鍦板潃锛歿}", rcsUrl);
+                
+                // 濡傛灉娌℃湁鎵规缂栧彿锛屼娇鐢ㄧ涓�涓换鍔$紪鍙蜂綔涓烘壒娆$紪鍙�
+                if (StringUtils.isBlank(batchNo) && !rcsTaskCodes.isEmpty()) {
+                    batchNo = rcsTaskCodes.get(0);
+                }
+                
+                Map<String, Object> cancelParams = new HashMap<>();
+                cancelParams.put("tasks", rcsTaskCodes);
+                if (StringUtils.isNotBlank(batchNo)) {
+                    cancelParams.put("batchNo", batchNo);
+                }
+                
+                log.info("RCS鍙栨秷浠诲姟璇锋眰鍙傛暟锛歿}", JSONObject.toJSONString(cancelParams));
+                
+                HttpHeaders headers = new HttpHeaders();
+                headers.add("Content-Type", "application/json");
+                headers.add("api-version", "v2.0");
+                HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(cancelParams, headers);
+                
+                long startTime = System.currentTimeMillis();
+                ResponseEntity<String> exchange = restTemplate.exchange(rcsUrl, HttpMethod.POST, httpEntity, String.class);
+                long endTime = System.currentTimeMillis();
+                
+                log.info("RCS鍙栨秷浠诲姟鍝嶅簲鑰楁椂锛歿}ms", (endTime - startTime));
+                log.info("RCS鍙栨秷浠诲姟鍝嶅簲鐘舵�佺爜锛歿}", exchange.getStatusCode());
+                log.info("RCS鍙栨秷浠诲姟鍝嶅簲浣擄細{}", exchange.getBody());
+                
+                if (Objects.isNull(exchange.getBody())) {
+                    log.error("RCS鍙栨秷浠诲姟澶辫触锛氬搷搴斾綋涓虹┖");
+                    throw new CoolException("RCS鍙栨秷浠诲姟澶辫触锛氬搷搴斾綋涓虹┖");
+                }
+                
+                ObjectMapper objectMapper = new ObjectMapper();
+                objectMapper.coercionConfigDefaults()
+                        .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty);
+                CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class);
+                
+                if (result.getCode() == 200) {
+                    log.info("========== RCS浠诲姟鍙栨秷鎴愬姛 ==========");
+                    log.info("鎴愬姛鍙栨秷鐨凴CS浠诲姟缂栧彿锛歿}", rcsTaskCodes);
+                    rcsCancelSuccess = true;
+                } else {
+                    log.error("RCS鍙栨秷浠诲姟澶辫触锛歿}", result.getMsg());
+                    throw new CoolException("RCS鍙栨秷浠诲姟澶辫触锛�" + result.getMsg());
+                }
+            } catch (JsonProcessingException e) {
+                log.error("RCS鍙栨秷浠诲姟鍝嶅簲瑙f瀽澶辫触锛歿}", e.getMessage(), e);
+                throw new CoolException("RCS鍙栨秷浠诲姟鍝嶅簲瑙f瀽澶辫触锛�" + e.getMessage());
+            } catch (Exception e) {
+                log.error("RCS鍙栨秷浠诲姟寮傚父锛歿}", e.getMessage(), e);
+                throw new CoolException("RCS鍙栨秷浠诲姟寮傚父锛�" + e.getMessage());
+            }
+        }
+        
+        // 鏌ヨ绗﹀悎鍙栨秷鏉′欢鐨勪换鍔★紙鐘舵�佷负1銆�101銆�199锛�
+        List<Integer> allowedStatuses = Arrays.asList(TaskStsType.GENERATE_IN.id, TaskStsType.GENERATE_OUT.id, TaskStsType.WAVE_SEED.id);
         List<Task> tasks = this.list(new LambdaQueryWrapper<Task>()
                 .in(Task::getTaskType, list)
-                .in(Task::getId, ids)
-                .in(Task::getTaskStatus, longs));
-        if (tasks.isEmpty()) {
+                .in(Task::getId, (Object[]) ids)
+                .in(Task::getTaskStatus, allowedStatuses));
+        
+        // 濡傛灉绗﹀悎鍙栨秷鏉′欢鐨勪换鍔′负绌猴紝浣哛CS鍙栨秷鎴愬姛锛屽厑璁哥户缁紙鍙兘鏄换鍔$姸鎬佸凡鍙樻洿锛�
+        if (tasks.isEmpty() && !rcsCancelSuccess) {
             throw new CoolException("浠诲姟宸插鎵ц鐘舵�佷笉鍙彇娑堬紒锛�");
+        }
+        
+        // 濡傛灉绗﹀悎鍙栨秷鏉′欢鐨勪换鍔′负绌猴紝浣哛CS鍙栨秷鎴愬姛锛岃褰曟棩蹇楀苟杩斿洖
+        if (tasks.isEmpty() && rcsCancelSuccess) {
+            log.warn("WMS鍐呴儴浠诲姟鐘舵�佷笉绗﹀悎鍙栨秷鏉′欢锛屼絾RCS浠诲姟宸叉垚鍔熷彇娑� - 浠诲姟ID锛歿}", Arrays.toString(ids));
+            return R.ok("RCS浠诲姟宸插彇娑堬紝WMS鍐呴儴浠诲姟鐘舵�佸凡鍙樻洿");
         }
         for (Task task : tasks) {
             //鍙栨秷绉诲簱浠诲姟
@@ -1402,13 +1521,28 @@
     public void pubTaskToWcs(List<Task> tasks) {
         WcsTaskParams taskParams = new WcsTaskParams();
         List<TaskItemParam> items = new ArrayList<>();
+        
+        // 璁剧疆鎵规缂栧彿锛堜娇鐢ㄧ涓�涓换鍔$殑barcode锛屽鏋滀负null鍒欎娇鐢ㄤ换鍔$紪鐮侊級
+        String batchNo = null;
+        if (!tasks.isEmpty()) {
+            Task firstTask = tasks.get(0);
+            batchNo = StringUtils.isNotBlank(firstTask.getBarcode()) 
+                    ? firstTask.getBarcode() 
+                    : firstTask.getTaskCode();
+        }
+        if (StringUtils.isBlank(batchNo)) {
+            // 濡傛灉鎵规缂栧彿浠嶄负绌猴紝鐢熸垚涓�涓粯璁ゅ��
+            batchNo = "BATCH_" + System.currentTimeMillis();
+        }
+
+        taskParams.setBatchNo(batchNo);
+        log.info("璁剧疆鎵规缂栧彿锛歿}", batchNo);
+        
         tasks.forEach(task -> {
             TaskItemParam itemParam = new TaskItemParam();
-            //浠诲姟绫诲瀷锛屼换鍔$紪鐮�
-            itemParam.setTaskType(RcsTaskType.getTypeDesc(task.getTaskType()))
-                    .setSeqNum(task.getTaskCode());
-            //涓诲弬鏁�
-            taskParams.setBatch(task.getBarcode());
+            //浠诲姟缂栫爜锛堝搴攕eqNum锛�
+            itemParam.setTaskNo(task.getTaskCode());
+            itemParam.setPriority(1);
             BasStation station = null;
             if (!task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type)) {
                 station = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, task.getTargSite()));
@@ -1474,27 +1608,50 @@
             }
             items.add(itemParam);
         });
-        taskParams.setTaskList(items);
+        taskParams.setTasks(items);
         /**浠诲姟涓嬪彂鎺ュ彛*/
         String pubTakUrl = rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.pubTask;
         /**RCS鍩虹閰嶇疆閾炬帴*/
-        log.info("浠诲姟涓嬪彂锛岃姹傚湴鍧�锛� {}锛� 璇锋眰鍙傛暟锛� {}", pubTakUrl, JSONObject.toJSONString(taskParams));
+        log.info("========== 寮�濮嬩笅鍙戜换鍔″埌RCS ==========");
+        log.info("RCS璇锋眰鍦板潃锛歿}", pubTakUrl);
+        log.info("鎵规缂栧彿锛歿}", batchNo);
+        log.info("浠诲姟鏁伴噺锛歿}", tasks.size());
+        log.info("浠诲姟鍒楄〃璇︽儏锛�");
+        tasks.forEach(task -> {
+            log.info("  - 浠诲姟缂栫爜锛歿}锛屼换鍔$被鍨嬶細{}锛屾簮搴撲綅锛歿}锛岀洰鏍囧簱浣嶏細{}锛屾簮绔欑偣锛歿}锛岀洰鏍囩珯鐐癸細{}", 
+                    task.getTaskCode(), task.getTaskType(), task.getOrgLoc(), 
+                    task.getTargLoc(), task.getOrgSite(), task.getTargSite());
+        });
+        log.info("璇锋眰鍙傛暟锛歿}", JSONObject.toJSONString(taskParams));
         HttpHeaders headers = new HttpHeaders();
         headers.add("Content-Type", "application/json");
         headers.add("api-version", "v2.0");
         HttpEntity httpEntity = new HttpEntity(taskParams, headers);
+        long startTime = System.currentTimeMillis();
         ResponseEntity<String> exchange = restTemplate.exchange(pubTakUrl, HttpMethod.POST, httpEntity, String.class);
-        log.info("浠诲姟涓嬪彂鍚庯紝鍝嶅簲缁撴灉锛� {}", exchange);
+        long endTime = System.currentTimeMillis();
+        log.info("RCS鍝嶅簲鑰楁椂锛歿}ms", (endTime - startTime));
+        log.info("RCS鍝嶅簲鐘舵�佺爜锛歿}", exchange.getStatusCode());
+        log.info("RCS鍝嶅簲澶达細{}", exchange.getHeaders());
+        log.info("RCS鍝嶅簲浣擄細{}", exchange.getBody());
         if (Objects.isNull(exchange.getBody())) {
-            throw new CoolException("浠诲姟涓嬪彂澶辫触锛侊紒");
+            log.error("========== RCS浠诲姟涓嬪彂澶辫触 ==========");
+            log.error("RCS鍝嶅簲浣撲负绌猴紝鏃犳硶瑙f瀽鍝嶅簲缁撴灉");
+            log.error("璇锋眰鍦板潃锛歿}", pubTakUrl);
+            log.error("璇锋眰鍙傛暟锛歿}", JSONObject.toJSONString(taskParams));
+            throw new CoolException("浠诲姟涓嬪彂澶辫触锛孯CS鍝嶅簲浣撲负绌猴紒锛�");
         } else {
             try {
                 ObjectMapper objectMapper = new ObjectMapper();
                 objectMapper.coercionConfigDefaults()
                         .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty);
                 CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class);
+                log.info("RCS鍝嶅簲瑙f瀽缁撴灉 - code锛歿}锛宮sg锛歿}锛宒ata锛歿}", 
+                        result.getCode(), result.getMsg(), result.getData());
                 if (result.getCode() == 200) {
+                    log.info("RCS浠诲姟涓嬪彂鎴愬姛锛屽紑濮嬫洿鏂颁换鍔$姸鎬�");
                     tasks.forEach(task -> {
+                        log.info("鏇存柊浠诲姟鐘舵�� - 浠诲姟缂栫爜锛歿}锛屼换鍔$被鍨嬶細{}", task.getTaskCode(), task.getTaskType());
                         if (task.getTaskType().equals(TaskType.TASK_TYPE_IN.type)
                                 || task.getTaskType().equals(TaskType.TASK_TYPE_PICK_IN.type)
                                 || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)
@@ -1507,10 +1664,12 @@
                                 throw new CoolException("绔欑偣涓嶅瓨鍦紒锛�");
                             }
 
+                            log.info("鏇存柊鍏ュ簱浠诲姟鐘舵�� - 浠诲姟缂栫爜锛歿}锛屾柊鐘舵�侊細{}", task.getTaskCode(), TaskStsType.WCS_EXECUTE_IN.id);
                             if (!taskService.update(new LambdaUpdateWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode())
                                     .set(Task::getTaskStatus, TaskStsType.WCS_EXECUTE_IN.id))) {
                                 throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
                             }
+                            log.info("鍏ュ簱浠诲姟鐘舵�佹洿鏂版垚鍔� - 浠诲姟缂栫爜锛歿}", task.getTaskCode());
                             /**鎺掗櫎绉诲簱鍔熻兘*/
                             if (!task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type)) {
                                 /**濡傛灉鏄櫘閫氱珯鐐癸紝淇敼绔欑偣鐘舵�佷负鍑哄簱棰勭害*/
@@ -1531,10 +1690,12 @@
                                 throw new CoolException("绔欑偣涓嶅瓨鍦紒锛�");
                             }
 
+                            log.info("鏇存柊鍑哄簱浠诲姟鐘舵�� - 浠诲姟缂栫爜锛歿}锛屾柊鐘舵�侊細{}", task.getTaskCode(), TaskStsType.WCS_EXECUTE_OUT.id);
                             if (!taskService.update(new LambdaUpdateWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode())
                                     .set(Task::getTaskStatus, TaskStsType.WCS_EXECUTE_OUT.id))) {
                                 throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
                             }
+                            log.info("鍑哄簱浠诲姟鐘舵�佹洿鏂版垚鍔� - 浠诲姟缂栫爜锛歿}", task.getTaskCode());
                             /**濡傛灉鏄櫘閫氱珯鐐癸紝淇敼绔欑偣鐘舵�佷负鍏ュ簱棰勭害*/
                             if (curSta.getType().equals(StationTypeEnum.STATION_TYPE_NORMAL.type)) {
                                 curSta.setUseStatus(LocStsType.LOC_STS_TYPE_S.type);
@@ -1544,15 +1705,27 @@
                             }
                         }
                     });
+                    log.info("========== RCS浠诲姟涓嬪彂瀹屾垚锛屽叡{}涓换鍔$姸鎬佸凡鏇存柊 ==========", tasks.size());
                 } else {
-                    log.error(JSONObject.toJSONString(result));
+                    log.error("========== RCS浠诲姟涓嬪彂澶辫触 ==========");
+                    log.error("RCS杩斿洖閿欒 - code锛歿}锛宮sg锛歿}锛宒ata锛歿}", 
+                            result.getCode(), result.getMsg(), result.getData());
+                    log.error("澶辫触鐨勪换鍔″垪琛細");
+                    tasks.forEach(task -> {
+                        log.error("  - 浠诲姟缂栫爜锛歿}锛屼换鍔$被鍨嬶細{}", task.getTaskCode(), task.getTaskType());
+                    });
 //                    throw new CoolException("浠诲姟涓嬪彂澶辫触锛侊紒");
                 }
             } catch (JsonProcessingException e) {
-                throw new CoolException(e.getMessage());
+                log.error("========== RCS浠诲姟涓嬪彂寮傚父 ==========");
+                log.error("瑙f瀽RCS鍝嶅簲澶辫触锛屽搷搴斾綋锛歿}", exchange.getBody(), e);
+                throw new CoolException("瑙f瀽RCS鍝嶅簲澶辫触锛�" + e.getMessage());
+            } catch (Exception e) {
+                log.error("========== RCS浠诲姟涓嬪彂寮傚父 ==========");
+                log.error("浠诲姟涓嬪彂杩囩▼涓彂鐢熷紓甯�", e);
+                throw e;
             }
         }
-
     }/**
 
 
@@ -1636,6 +1809,80 @@
     }
 
     /**
+     * 绌烘墭鍏ュ簱瀹屾垚
+     *
+     * @param task
+     * @param loginUserId
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public synchronized void complateEmpityInStock(Task task, Long loginUserId) {
+        if (Objects.isNull(task)) {
+            return;
+        }
+
+        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, task.getTargLoc()));
+        if (Objects.isNull(loc)) {
+            throw new CoolException("鐩爣搴撲綅涓嶅瓨鍦紒");
+        }
+
+        if (!loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_S.type)) {
+            throw new CoolException("褰撳墠搴撲綅鐘舵�佷笉澶勪簬S.鍏ュ簱棰勭害锛屼笉鍙墽琛屽叆搴撴搷浣滐紒");
+        }
+
+        List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId()));
+        if (taskItems.isEmpty()) {
+            throw new CoolException("浠诲姟鏄庣粏涓嶅瓨鍦紒锛�");
+        }
+
+        //鏇存柊搴撲綅鏄庣粏
+        saveLocItem(taskItems, task.getId(), loginUserId);
+
+        //绌烘墭鍏ュ簱涓嶆牎楠岀粍鎵樹俊鎭紝鐩存帴澶勭悊浠诲姟鏄庣粏
+        //濡傛灉鏈変换鍔℃槑缁嗗叧鑱斾簡缁勬墭锛屼篃闇�瑕佷繚瀛樺叆鍑哄簱鏄庣粏鍜岀Щ鍑烘敹璐у尯搴撳瓨
+        Map<Long, List<TaskItem>> orderMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getSource));
+        orderMap.keySet().forEach(key -> {
+            // 濡傛灉source涓嶄负绌猴紝璇存槑鏈夊叧鑱旂殑缁勬墭鏄庣粏锛岄渶瑕佸鐞�
+            if (key != null && key > 0) {
+                WaitPakinItem pakinItem = waitPakinItemService.getById(key);
+                if (!Objects.isNull(pakinItem)) {
+                    List<TaskItem> items = orderMap.get(key);
+                    //淇濆瓨鍏ュ嚭搴撴槑缁�
+                    saveStockItems(items, task, pakinItem.getId(), pakinItem.getAsnCode(), pakinItem.getWkType(), pakinItem.getType(), loginUserId);
+                    //绉诲嚭鏀惰揣鍖哄簱瀛橈紝 淇敼缁勬墭鐘舵��
+                    removeReceiptStock(pakinItem, loginUserId);
+                }
+            }
+        });
+
+        // 澶勭悊缁勬墭鐘舵�侊紙濡傛灉鏈夌粍鎵樺叧鑱旓級
+        Set<Long> pkinItemIds = taskItems.stream()
+                .map(TaskItem::getSource)
+                .filter(source -> source != null && source > 0)
+                .collect(Collectors.toSet());
+        
+        if (!pkinItemIds.isEmpty()) {
+            List<WaitPakinItem> pakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().in(WaitPakinItem::getId, pkinItemIds));
+            if (!pakinItems.isEmpty()) {
+                Set<Long> pakinIds = pakinItems.stream().map(WaitPakinItem::getPakinId).collect(Collectors.toSet());
+                if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
+                        .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val)
+                        .set(WaitPakin::getUpdateBy, loginUserId)
+                        .in(WaitPakin::getId, pakinIds))) {
+                    throw new CoolException("缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+                }
+            }
+        }
+
+        /**淇敼搴撲綅鐘舵�佷负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("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+        }
+    }
+
+    /**
      * @param
      * @param loginUserId
      * @return
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaitPakinServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaitPakinServiceImpl.java
index 766ec93..0dc85d7 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaitPakinServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaitPakinServiceImpl.java
@@ -75,8 +75,11 @@
                     if (Objects.isNull(warehouseAreasItems)) {
                         throw new CoolException("鐗╂枡鏈�佽嚦鏀惰揣鍖烘垨宸茬粍鎵樺畬鎴愮Щ鍑烘敹璐у尯锛侊紒");
                     }
-                    if (item.getFieldsIndex().equals(warehouseAreasItems.getFieldsIndex())) {
-                        throw new CoolException("绁ㄥ彿锛�" + item.getExtendFields().get("crushNo") + "宸茬粍鎵橈紝涓嶅彲閲嶅缁勬墭锛侊紒");
+                    // 鍙湪绁ㄥ彿涓嶄负绌烘椂鎵嶈繘琛岄噸澶嶆鏌�
+                    if (!Objects.isNull(item.getFieldsIndex()) && !Objects.isNull(warehouseAreasItems.getFieldsIndex()) 
+                        && item.getFieldsIndex().equals(warehouseAreasItems.getFieldsIndex())) {
+                        String crushNo = item.getExtendFields() != null ? item.getExtendFields().get("crushNo") : "";
+                        throw new CoolException("绁ㄥ彿锛�" + crushNo + "宸茬粍鎵橈紝涓嶅彲閲嶅缁勬墭锛侊紒");
                     }
                 }
             });

--
Gitblit v1.9.1