From da5d4106e294a229e3bf72939c6b7630e6345d76 Mon Sep 17 00:00:00 2001
From: zwl <1051256694@qq.com>
Date: 星期二, 10 三月 2026 10:30:38 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/api/controller/params/PageRequestParams.java             |   16 
 src/main/java/com/zy/api/service/impl/HmesApiServiceImpl.java                 |   68 +
 src/main/java/com/zy/asrs/controller/LocMastController.java                   |    4 
 src/main/java/com/zy/api/entity/CallAgvParams.java                            |   35 
 src/main/java/com/zy/api/enums/MatType.java                                   |   36 
 src/main/java/com/zy/api/entity/StockAdjustParams.java                        |   27 
 src/main/java/com/zy/asrs/controller/BasArmMastSignController.java            |    3 
 src/main/java/com/zy/api/entity/StationProtocol.java                          |   28 
 src/main/java/com/zy/common/model/StartupDto.java                             |    4 
 src/main/java/com/zy/api/enums/MatLocType.java                                |   65 +
 src/main/java/com/zy/asrs/controller/StaDescController.java                   |  107 
 src/main/java/com/zy/asrs/utils/Utils.java                                    |   34 
 src/main/java/com/zy/api/entity/SyncMatParmas.java                            |   45 
 src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java                   |    2 
 src/main/java/com/zy/api/entity/PubOrderParams.java                           |   17 
 src/main/java/com/zy/common/service/CommonService.java                        |  612 +++++++--
 src/main/java/com/zy/api/entity/OrderItemsParam.java                          |   50 
 src/main/java/com/zy/api/controller/params/WorkTaskParams.java                |   49 
 src/main/java/com/zy/api/entity/StockUpOrderParams.java                       |   19 
 src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java                   |  405 ++----
 src/main/java/com/zy/api/controller/params/ReceviceTaskParams.java            |   46 
 src/main/java/com/zy/api/enums/OrderType.java                                 |   57 
 src/main/java/com/zy/asrs/task/WorkMastScheduler.java                         |   27 
 src/main/java/com/zy/asrs/enums/MatTagType.java                               |   20 
 src/main/java/com/zy/api/service/WcsApiService.java                           |   37 
 src/main/java/com/zy/api/entity/MatnrsParams.java                             |   43 
 src/main/java/com/zy/asrs/enums/LocStsType.java                               |   60 
 src/main/java/com/zy/api/entity/OutOrderParams.java                           |   34 
 src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java                   |  140 +
 src/main/java/com/zy/api/entity/DeviceStatusVo.java                           |   32 
 src/main/java/com/zy/asrs/entity/param/MesToCombParam.java                    |    2 
 src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java                  |  239 +++
 src/main/java/com/zy/api/entity/DeviceConfig.java                             |   18 
 src/main/java/com/zy/api/entity/ReportOrderParam.java                         |   18 
 src/main/java/com/zy/asrs/controller/WrkMastLogController.java                |    6 
 src/main/java/com/zy/common/web/WcsController.java                            |   50 
 src/main/java/com/zy/api/enums/LocAreaType.java                               |   24 
 src/main/java/com/zy/asrs/controller/WrkMastController.java                   |    2 
 src/main/java/com/zy/api/entity/OrderParams.java                              |   66 +
 src/main/java/com/zy/asrs/service/OpenService.java                            |    5 
 src/main/java/com/zy/api/controller/HWmsApiController.java                    |  163 ++
 src/main/java/com/zy/api/service/HWmsApiService.java                          |   78 +
 src/main/java/com/zy/asrs/enums/CommonEnum.java                               |   25 
 src/main/java/com/zy/api/controller/HmesApiController.java                    |   15 
 src/main/java/com/zy/api/entity/dto/XSR.java                                  |   77 +
 src/main/java/com/zy/asrs/controller/BasArmMastController.java                |    3 
 src/main/java/com/zy/asrs/task/AutomaticallyIssueWCSTasksScheduler.java       |    1 
 src/main/java/com/zy/api/entity/BaseRequstParam.java                          |   15 
 src/main/java/com/zy/api/enums/OrderWkType.java                               |   45 
 src/main/java/com/zy/asrs/controller/BasArmMastLogController.java             |    3 
 src/main/java/com/zy/asrs/controller/ManLocDetlController.java                |    2 
 src/main/java/com/zy/asrs/controller/LocDetlController.java                   |    2 
 src/main/java/com/zy/asrs/controller/OpenController.java                      |   20 
 src/main/java/com/zy/api/service/impl/HWmsApiServiceImpl.java                 |  539 ++++++++
 src/main/java/com/zy/api/entity/ReportOrderParams.java                        |   55 
 src/main/java/com/zy/api/entity/DualCrnProtocol.java                          |   64 +
 src/main/java/com/zy/api/service/HmesApiService.java                          |   12 
 src/main/java/com/zy/api/controller/WcsApiController.java                     |   67 +
 src/main/java/com/zy/asrs/task/handler/AutomaticallyIssueWCSTasksHandler.java |    3 
 src/main/java/com/zy/common/web/param/SearchLocParam.java                     |    7 
 src/main/java/com/zy/api/entity/CrnProtocol.java                              |   48 
 src/main/java/com/zy/asrs/enums/ContainerType.java                            |   27 
 src/main/resources/application.yml                                            |    2 
 63 files changed, 3,268 insertions(+), 557 deletions(-)

diff --git a/src/main/java/com/zy/api/controller/HWmsApiController.java b/src/main/java/com/zy/api/controller/HWmsApiController.java
new file mode 100644
index 0000000..a154d8d
--- /dev/null
+++ b/src/main/java/com/zy/api/controller/HWmsApiController.java
@@ -0,0 +1,163 @@
+package com.zy.api.controller;
+
+
+import com.zy.api.controller.params.PageRequestParams;
+import com.zy.api.entity.PubOrderParams;
+import com.zy.api.entity.ReportOrderParam;
+import com.zy.api.entity.StockAdjustParams;
+import com.zy.api.entity.StockUpOrderParams;
+import com.zy.api.entity.SyncMatParmas;
+import com.zy.api.entity.dto.XSR;
+import com.zy.api.service.HWmsApiService;
+import com.zy.common.web.BaseController;
+
+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;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Objects;
+
+
+
+@Slf4j
+@RestController
+@RequestMapping("/kopen")
+public class HWmsApiController extends BaseController{
+
+    @Autowired
+    private HWmsApiService kopenApiService;
+
+    /**
+     * 涓婃父涓嬪彂娲惧伐鍗�
+     * 
+     * @author Ryan
+     * @date 2025/11/24 15:18
+     * @param params
+     * @return com.core.common.R
+     */
+    @ApiOperation("鍏ュ簱鍗曚笅鍙�")
+    @PostMapping("/sendInDispatch")
+    public XSR receiveOrders(@RequestBody List<PubOrderParams> params) {
+        if (Objects.isNull(params)) {
+            return XSR.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+//        if (Objects.isNull(params.getType())) {
+//            return XSR.error("鍗曟嵁绫诲瀷涓嶈兘涓虹┖锛�");
+//        }
+          
+        return kopenApiService.receiveOrders(params);
+    }
+
+    /**
+     * 涓婃父涓嬪彂闆朵欢鏁版嵁鍙樻洿
+     * 
+     * @author Ryan
+     * @date 2025/11/24 15:19
+     * @param params
+     * @return com.core.common.R
+     */
+    @ApiOperation("闆朵欢淇℃伅鏁版嵁鏇存柊")
+    @PostMapping("/sendPartsMaster")
+    public XSR basMatUpdate(@RequestBody List<SyncMatParmas> params) {
+        if (Objects.isNull(params) || params.isEmpty()) {
+            return XSR.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        return kopenApiService.basMatupdate(params);
+    }
+
+    /**
+     * 涓婃灦娲惧伐鍗曞弽棣�
+     * @author Ryan
+     * @date 2025/11/24 15:20
+     * @param params
+     * @return com.core.common.R
+     */
+    @ApiOperation("涓婃灦娲惧伐鍗曞弽棣�")
+    @PostMapping("/getInDispatchResult")
+    public XSR getInDispatchResult(@RequestBody List<ReportOrderParam> params) {
+        if (Objects.isNull(params)) {
+            return XSR.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+//        if (Objects.isNull(params.getKopen_id()) && Objects.isNull(params.getInv_no()) && Objects.isNull(params.getDispatch_no())) {
+//            return XSR.error("鍙栨秷鏉′欢涓嶈兘涓虹┖锛侊紒");
+//        }
+        return kopenApiService.getInDispatchResult(params, null);
+    }
+
+    /**
+     * 澶囪揣鎸囩ず娲惧伐鍗曚笅鍙�
+     * @author Ryan
+     * @date 2025/11/24 15:21
+     * @param params
+     * @return com.core.common.R
+     */
+    @ApiOperation("澶囪揣鎸囩ず娲惧伐鍗曚笅鍙�")
+    @PostMapping("/sendOutDispatch")
+    public XSR sendStockPrepareDispatch(@RequestBody List<PubOrderParams> params) {
+        if (Objects.isNull(params)) {
+            return XSR.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+//        if (Objects.isNull(params.getDetails()) || params.getDetails().isEmpty()) {
+//            return XSR.error("涓婃姤璁㈠崟鍒楄〃涓嶈兘涓虹┖锛侊紒");
+//        }
+        return kopenApiService.sendOutDispatch(params);
+    }
+
+
+    //  /**
+    //  * 澶囪揣鎸囩ず娲惧伐鍗曞弽棣�
+    //  * @author Ryan
+    //  * @date 2025/11/24 15:22
+    //  * @param params
+    //  * @return com.core.common.R
+    //  */
+    // @ApiOperation("澶囪揣鎸囩ず娲惧伐鍗曞弽棣�")
+    // @PostMapping("/getOutDispatchResult")
+    // public R getOutDispatchResult(@RequestBody ReportOrderParam params) {
+    //     if (Objects.isNull(params)) {
+    //         return R.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+    //     }
+    //     if (Objects.isNull(params.getKopen_id()) && Objects.isNull(params.getInv_no()) && Objects.isNull(params.getDispatch_no())) {
+    //         return R.error("鍙栨秷鏉′欢涓嶈兘涓虹┖锛侊紒");
+    //     }
+    //     return kopenApiService.getOutDispatchResult(params);
+    // }
+
+
+    /**
+     * 澶囪揣鍗曚笅鍙�
+     * @author Ryan
+     * @date 2025/11/24 15:21
+     * @param params
+     * @return com.core.common.R
+     */
+    @ApiOperation("澶囪揣鍗曚笅鍙�")
+    @PostMapping("/getOutDetails")
+    public XSR getOutDetails(@RequestBody List<StockUpOrderParams> params) {
+        if (Objects.isNull(params)) {
+            return XSR.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        return kopenApiService.getOutDetails(params);
+    }
+
+
+    /**
+     * 鏌ヨWMS搴撳瓨淇℃伅
+     * @author Ryan
+     * @date 2025/11/24 15:22
+     * @param params
+     * @return com.core.common.R
+     */
+    @ApiOperation("鏌ヨWMS搴撳瓨淇℃伅")
+    @PostMapping("/getStockInfo")
+    public XSR getStockInfo(@RequestBody PageRequestParams params) {
+        return kopenApiService.getStockInfo(params);
+    }
+
+}
diff --git a/src/main/java/com/zy/api/controller/HmesApiController.java b/src/main/java/com/zy/api/controller/HmesApiController.java
new file mode 100644
index 0000000..fcd078a
--- /dev/null
+++ b/src/main/java/com/zy/api/controller/HmesApiController.java
@@ -0,0 +1,15 @@
+package com.zy.api.controller;
+
+import io.swagger.annotations.Api;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@Api(value = "HMES瀵规帴")
+@RestController
+@RequestMapping("/api")
+public class HmesApiController {
+
+
+
+}
diff --git a/src/main/java/com/zy/api/controller/WcsApiController.java b/src/main/java/com/zy/api/controller/WcsApiController.java
new file mode 100644
index 0000000..c639fae
--- /dev/null
+++ b/src/main/java/com/zy/api/controller/WcsApiController.java
@@ -0,0 +1,67 @@
+package com.zy.api.controller;
+
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.core.annotations.ManagerAuth;
+import com.core.common.R;
+import com.zy.api.controller.params.ReceviceTaskParams;
+import com.zy.api.controller.params.WorkTaskParams;
+import com.zy.api.service.WcsApiService;
+import com.zy.asrs.entity.WaitPakin;
+import com.zy.asrs.service.WaitPakinService;
+import com.zy.asrs.utils.Utils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Objects;
+
+@Api("WCS浜や簰鎺ュ彛")
+@RequestMapping("/wcs")
+@RestController
+public class WcsApiController {
+
+    @Autowired
+    private WcsApiService wcsApiService;
+    @Autowired
+    private WaitPakinService waitPakinService;
+
+    /**
+     * 涓嬪彂浠诲姟鑷砏CS
+     * @author Ryan
+     * @date 2026/1/10 13:57
+     * @param params
+     * @return com.core.common.R
+     */
+    @ManagerAuth
+    @ApiOperation("涓嬪彂浠诲姟鑷砏CS")
+    @PostMapping("/pub/wrks")
+    public R pubWrkToWcs(@RequestBody WorkTaskParams params) {
+        if (Objects.isNull(params)) {
+            return R.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        return wcsApiService.pubWrkToWcs(params);
+    }
+
+//    @ManagerAuth
+    @ApiOperation("璁惧鎵ц鐘舵�佸洖鍐�-wcs浠诲姟瀹屾垚鍥炲啓")
+    @PostMapping("/openapi/report")
+    public R receviceTaskFromWcs(@RequestBody ReceviceTaskParams params) {
+        if (Objects.isNull(params)) {
+            return R.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        return wcsApiService.receviceTaskFromWcs(params);
+
+    }
+
+    @ManagerAuth
+    @ApiOperation("鑾峰彇缁勬墭鍏ュ簱鎵樼洏淇℃伅")
+    @PostMapping("/openapi/waitPakins")
+    public R waitPakins() {
+        List<WaitPakin> waitPakins = waitPakinService.selectList(new EntityWrapper<WaitPakin>().eq("io_status", "N"));
+        return R.ok().add(waitPakins);
+
+    }
+}
diff --git a/src/main/java/com/zy/api/controller/params/PageRequestParams.java b/src/main/java/com/zy/api/controller/params/PageRequestParams.java
new file mode 100644
index 0000000..07ca0b3
--- /dev/null
+++ b/src/main/java/com/zy/api/controller/params/PageRequestParams.java
@@ -0,0 +1,16 @@
+package com.zy.api.controller.params;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+@ApiModel("鍒嗛〉璇锋眰鍙傛暟")
+public class PageRequestParams {
+
+    private Integer curr = 1;
+
+    private Integer limit = 50;
+
+}
diff --git a/src/main/java/com/zy/api/controller/params/ReceviceTaskParams.java b/src/main/java/com/zy/api/controller/params/ReceviceTaskParams.java
new file mode 100644
index 0000000..9e7dc98
--- /dev/null
+++ b/src/main/java/com/zy/api/controller/params/ReceviceTaskParams.java
@@ -0,0 +1,46 @@
+package com.zy.api.controller.params;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "ReceviceTaskParams", description = "绌跨嚎澧欏弬鏁�")
+public class ReceviceTaskParams implements Serializable {
+
+    @ApiModelProperty("鏈哄彴鍙�")
+    private String devNo;
+
+    @ApiModelProperty("娴佹按鍙�")
+    private Long id;
+
+    @ApiModelProperty("閫氱煡绫诲瀷锛歵ask")
+    private String notifyType;
+
+    @ApiModelProperty("鍫嗗灈鏈哄彿")
+    private Integer device;
+
+    @ApiModelProperty("WMS浠诲姟鍙�")
+    private String superTaskNo;
+
+    @ApiModelProperty("娑堟伅绫诲瀷锛歵ask_complete銆乼ask_cancel")
+    private String msgType;
+
+    @ApiModelProperty("娑堟伅鎻忚堪")
+    private String msgDesc;
+
+    @ApiModelProperty("娑堟伅鏁版嵁")
+    private String data;
+
+    @ApiModelProperty("閲嶉噺")
+    private Double weight;
+
+    @ApiModelProperty("Y锛氬喕缁�  N:瑙e喕")
+    private String freeze;
+
+}
diff --git a/src/main/java/com/zy/api/controller/params/WorkTaskParams.java b/src/main/java/com/zy/api/controller/params/WorkTaskParams.java
new file mode 100644
index 0000000..8c462b9
--- /dev/null
+++ b/src/main/java/com/zy/api/controller/params/WorkTaskParams.java
@@ -0,0 +1,49 @@
+package com.zy.api.controller.params;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "WorkTaskParams", description = "鎵ц浠诲姟鍙傛暟")
+public class WorkTaskParams implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("鍗忚浠诲姟缂栧彿(瀵瑰簲鍑哄簱浠诲姟鍙�)")
+    private String taskNo;
+
+    @ApiModelProperty("宸ヤ綔妗d换鍔″彿")
+    private String wrkNo;
+
+    @ApiModelProperty("搴撲綅缂栫爜")
+    private String locNo;
+
+    //婧愬簱浣�
+    private String sourceLocNo;
+
+    //婧愮珯鐐�
+    private String sourceStaNo;
+
+    @ApiModelProperty("鏉$爜")
+    private String barcode;
+
+    @ApiModelProperty("浼樺厛绾�")
+    private Integer taskPri;
+
+    @ApiModelProperty("鍑哄簱绔欑偣")
+    private String staNo;
+
+    @ApiModelProperty("浣滀笟绫诲瀷锛宨n: 鍏ュ簱锛� out:鍑哄簱")
+    private String type;
+
+    @ApiModelProperty("鏄惁浣欐枡")
+    private Integer isSuplus;
+
+
+}
diff --git a/src/main/java/com/zy/api/entity/BaseRequstParam.java b/src/main/java/com/zy/api/entity/BaseRequstParam.java
new file mode 100644
index 0000000..acd8d03
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/BaseRequstParam.java
@@ -0,0 +1,15 @@
+package com.zy.api.entity;
+
+import java.util.Map;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@ApiModel("鍩虹璇锋眰鍙傛暟")
+@Accessors(chain = true)
+public class BaseRequstParam {
+
+    private Map<String, Object> root;
+}
diff --git a/src/main/java/com/zy/api/entity/CallAgvParams.java b/src/main/java/com/zy/api/entity/CallAgvParams.java
new file mode 100644
index 0000000..59b5fd1
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/CallAgvParams.java
@@ -0,0 +1,35 @@
+package com.zy.api.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "CallAgvParams", description = "AGV鎼繍鍙傛暟")
+public class CallAgvParams implements Serializable {
+
+    @ApiModelProperty("鍛煎彨绫诲瀷锛氬嚭搴擄細out, 鍏ュ簱锛歩n")
+    private String type;
+
+    @ApiModelProperty("鍘熷簱浣�")
+    private String orgLoc;
+
+    @ApiModelProperty("鐩爣绔欑偣")
+    private String tarSite;
+
+    @ApiModelProperty("鍘熺珯鐐�")
+    private String orgSite;
+
+    @ApiModelProperty("鐩爣搴撲綅")
+    private String tarLoc;
+
+    @ApiModelProperty("鎼繍鐘舵��")
+    private String status;
+
+    @ApiModelProperty("浠诲姟鍙�")
+    private String wrkNo;
+}
diff --git a/src/main/java/com/zy/api/entity/CrnProtocol.java b/src/main/java/com/zy/api/entity/CrnProtocol.java
new file mode 100644
index 0000000..6480801
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/CrnProtocol.java
@@ -0,0 +1,48 @@
+package com.zy.api.entity;
+
+import lombok.Data;
+import java.util.Map;
+
+@Data
+public class CrnProtocol {
+    private Integer crnNo;
+    private Integer mode;           // 1=Manual, 2=Auto, 3=Computer
+    private Object modeType;        // Enum: CrnModeType
+    private Integer alarm;          // Error code
+    private Integer taskNo;         // Task number
+    private Integer status;         // Current status code
+    private Object statusType;      // Enum: CrnStatusType
+    private Integer bay;            // Current bay
+    private Integer level;          // Current level
+    private Integer forkPos;        // Fork position code
+    private Object forkPosType;     // Enum: CrnForkPosType
+    private Integer liftPos;        // Lift position code
+    private Object liftPosType;     // Enum: CrnLiftPosType
+    private Integer walkPos;        // 0=In Position, 1=Not in Position
+    private Integer loaded;         // 1=Loaded, 0=Empty
+
+    // Speed and Distance
+    private Double xSpeed;
+    private Double ySpeed;
+    private Double zSpeed;
+    private Double xDistance;
+    private Double yDistance;
+    private Double xDuration;
+    private Double yDuration;
+
+    // Other Info
+    private String lastIo;          // "I"=Inbound, "O"=Outbound
+    private Integer crnLane;        // Lane number
+    private float weight;
+    private String barcode;
+    private Long deviceDataLog;
+    private Long lastCommandTime;
+
+    // Reserved/Temp
+    private Integer temp1;
+    private Integer temp2;
+    private Integer temp3;
+    private Integer temp4;
+
+    private Map<String, Object> extend;
+}
\ No newline at end of file
diff --git a/src/main/java/com/zy/api/entity/DeviceConfig.java b/src/main/java/com/zy/api/entity/DeviceConfig.java
new file mode 100644
index 0000000..6487cb4
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/DeviceConfig.java
@@ -0,0 +1,18 @@
+package com.zy.api.entity;
+
+import lombok.Data;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class DeviceConfig implements Serializable {
+    private Integer id;
+    private String ip;
+    private Integer port;
+    private String threadImpl;
+    private Date createTime;
+    private String deviceType;
+    private Integer deviceNo;
+    private Integer fake;
+    private String fakeInitStatus;
+}
diff --git a/src/main/java/com/zy/api/entity/DeviceStatusVo.java b/src/main/java/com/zy/api/entity/DeviceStatusVo.java
new file mode 100644
index 0000000..20cd184
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/DeviceStatusVo.java
@@ -0,0 +1,32 @@
+package com.zy.api.entity;
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * Device Status Response Object
+ * Corresponds to the map returned by OpenController.getDeviceStatus
+ */
+@Data
+public class DeviceStatusVo {
+    /**
+     * Stacker Crane (CRN) Data List
+     */
+    private List<CrnProtocol> crnList;
+
+    /**
+     * RGV Device Config List
+     * Note: The controller returns the DeviceConfig list for RGV, not the protocol status list.
+     */
+    private List<DeviceConfig> rgvList;
+
+    /**
+     * Dual-Station Stacker Crane Data List
+     */
+    private List<DualCrnProtocol> dualCrnList;
+
+    /**
+     * Conveyor Station Data List
+     */
+    private List<StationProtocol> stationList;
+}
diff --git a/src/main/java/com/zy/api/entity/DualCrnProtocol.java b/src/main/java/com/zy/api/entity/DualCrnProtocol.java
new file mode 100644
index 0000000..1199f70
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/DualCrnProtocol.java
@@ -0,0 +1,64 @@
+package com.zy.api.entity;
+import lombok.Data;
+import java.util.Map;
+
+@Data
+public class DualCrnProtocol {
+    private Integer crnNo;
+    private Integer mode;
+    private Object modeType;        // Enum: DualCrnModeType
+    private Integer alarm;
+
+    // Station 1 Data
+    private Integer taskNo;
+    private Integer status;
+    private Object statusType;      // Enum: DualCrnStatusType
+    private Integer bay;
+    private Integer level;
+    private Integer forkPos;
+    private Object forkPosType;     // Enum: DualCrnForkPosType
+    private Integer liftPos;
+    private Object liftPosType;     // Enum: DualCrnLiftPosType
+    private Integer walkPos;
+    private Integer loaded;
+    private Integer taskReceive;
+
+    // Station 2 Data
+    private Integer taskNoTwo;
+    private Integer statusTwo;
+    private Object statusTypeTwo;
+    private Integer bayTwo;
+    private Integer levelTwo;
+    private Integer forkPosTwo;
+    private Object forkPosTypeTwo;
+    private Integer liftPosTwo;
+    private Object liftPosTypeTwo;
+    private Integer walkPosTwo;
+    private Integer loadedTwo;
+    private Integer taskReceiveTwo;
+
+    // Movement Data (Integer type in DualCrnProtocol)
+    private Integer xSpeed;
+    private Integer ySpeed;
+    private Integer zSpeed;
+    private Integer xDistance;
+    private Integer yDistance;
+    private Integer xDuration;
+    private Integer yDuration;
+
+    // Other Info
+    private Integer goodsType;
+    private String barcode;
+    private String lastIo;
+    private Integer crnLane;
+    private Long deviceDataLog;
+    private Long lastCommandTime;
+
+    // Reserved/Temp
+    private Integer temp1;
+    private Integer temp2;
+    private Integer temp3;
+    private Integer temp4;
+
+    private Map<String, Object> extend;
+}
diff --git a/src/main/java/com/zy/api/entity/MatnrsParams.java b/src/main/java/com/zy/api/entity/MatnrsParams.java
new file mode 100644
index 0000000..c1e72ec
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/MatnrsParams.java
@@ -0,0 +1,43 @@
+package com.zy.api.entity;
+
+import org.springframework.format.annotation.DateTimeFormat;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "MatnrsParams", description = "鐗╂枡淇℃伅")
+public class MatnrsParams {
+
+    @ApiModelProperty("鍗曟嵁绫诲瀷")
+    private String pro_komcode;
+
+    @ApiModelProperty("宸ュ崟绫诲瀷")
+    private String pro_id;
+
+    @ApiModelProperty("璁㈠崟鍙�")
+    private String company_id;
+
+    @ApiModelProperty("璁㈠崟鏁伴噺")
+    private Double pro_name;
+
+    @ApiModelProperty("鎿嶄綔浜�")
+    private String pro_size;
+
+    @ApiModelProperty("閲嶉噺")
+    private String pro_wet;
+
+    @ApiModelProperty("闆朵欢绫诲瀷")
+    private String pro_type;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private String update_time;
+}
diff --git a/src/main/java/com/zy/api/entity/OrderItemsParam.java b/src/main/java/com/zy/api/entity/OrderItemsParam.java
new file mode 100644
index 0000000..30f3613
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/OrderItemsParam.java
@@ -0,0 +1,50 @@
+package com.zy.api.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "OrderItemsParam", description = "璁㈠崟鏄庣粏鍙傛暟")
+public class OrderItemsParam implements Serializable {
+
+    @ApiModelProperty("BS Code")
+    private String total_serial;
+
+    @ApiModelProperty("鐩爣搴撳尯")
+    private String target_location;
+
+    @ApiModelProperty("闆朵欢绫诲瀷")
+    private String pro_type;
+
+    @ApiModelProperty("闆朵欢浠g爜")
+    private String pro_komcode;
+
+    @ApiModelProperty("渚涘簲鍟嗙紪鐮�")
+    private String pro_id;
+
+    @ApiModelProperty("鍏ュ簱閫氱煡鏁伴噺")
+    private Double inv_qty;
+
+    @ApiModelProperty("鎸囩ず鎷h揣璁㈠崟鏁伴噺")
+    private Integer order_qty;
+
+    @ApiModelProperty("鍘熶笂鏋舵淳宸ユ暟閲�")
+    private Integer old_qty;
+
+    @ApiModelProperty("鍙樻洿鏁伴噺")
+    private Integer new_qty;
+
+    @ApiModelProperty("鎹嗙粦/鍙枡/鏁伴噺鏁伴噺")
+    private Integer pick_qty;
+
+    @ApiModelProperty("鎹熸孩鏁伴噺")
+    private Integer bsby_qty;
+
+    @ApiModelProperty("鎵樼洏缂栧彿")
+    private String location_no;
+
+}
diff --git a/src/main/java/com/zy/api/entity/OrderParams.java b/src/main/java/com/zy/api/entity/OrderParams.java
new file mode 100644
index 0000000..e09e9a9
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/OrderParams.java
@@ -0,0 +1,66 @@
+package com.zy.api.entity;
+
+import java.io.Serializable;
+
+import org.springframework.format.annotation.DateTimeFormat;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "OrderParams", description = "鍗曟嵁淇℃伅")
+public class OrderParams implements Serializable {
+
+    @ApiModelProperty("娴佹按鍙凤紙鍞竴锛�")
+    private String kopen_id;
+
+    @ApiModelProperty("娲惧伐鍗曞彿")
+    private String dispatch_no;
+
+    @ApiModelProperty("鍏徃ID")
+    private String company_id;
+
+    @ApiModelProperty("鍏ュ簱绫诲瀷 1: 閲囪喘鍏ュ簱锛�2: 璋冩嫧鍏ュ簱锛�3: 閿�鍞��璐у叆搴擄紝4: 濂楀寘鍏ュ簱, 5:SO, 6:EO, 7:鍑哄簱")
+    private String type;
+
+    @ApiModelProperty("绠卞彿")
+    private String pm_tktid;
+
+    @ApiModelProperty("鍏ュ簱閫氱煡鍗曞彿")
+    private String inv_no;
+
+    @ApiModelProperty("鐩爣搴撳尯")
+    private String target_location;
+
+    @ApiModelProperty("婧愬簱鍖�")
+    private String source_location;
+
+
+    @ApiModelProperty("鎷h揣鍗曞彿")
+    private String pick_no;
+
+    @ApiModelProperty("璁㈠崟鍙�")
+    private String order_no;
+
+
+    @ApiModelProperty("瀹㈡埛ID")
+    private String cus_id;
+
+
+    @ApiModelProperty("瀹㈡埛鍦板潃")
+    private String cus_address;
+
+
+    @ApiModelProperty("WMS ID")
+    private String wms_id;
+
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private String update_time;
+}
diff --git a/src/main/java/com/zy/api/entity/OutOrderParams.java b/src/main/java/com/zy/api/entity/OutOrderParams.java
new file mode 100644
index 0000000..32aed18
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/OutOrderParams.java
@@ -0,0 +1,34 @@
+package com.zy.api.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "OutOrderParams", description = "澶囪揣璁㈠崟鍙傛暟")
+public class OutOrderParams implements Serializable {
+
+    @ApiModelProperty("鏄庣粏澶囪揣鍗曞彿")
+    private String pick_no;
+
+    @ApiModelProperty("璁㈠崟鍙�")
+    private String order_no;
+
+    @ApiModelProperty("瀹㈡埛")
+    private String cus_id;
+
+    @ApiModelProperty("瀹㈡埛鍦板潃")
+    private String cus_address;
+
+    @ApiModelProperty("涓氬姟绫诲瀷")
+    private String type;
+
+    @ApiModelProperty("璁㈠崟鏄庣粏")
+    private List<OrderItemsParam> partList;
+
+
+}
diff --git a/src/main/java/com/zy/api/entity/PubOrderParams.java b/src/main/java/com/zy/api/entity/PubOrderParams.java
new file mode 100644
index 0000000..2f90cdb
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/PubOrderParams.java
@@ -0,0 +1,17 @@
+package com.zy.api.entity;
+
+import java.util.List;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "PubOrderParams", description = "鍙戝竷璁㈠崟淇℃伅")
+public class PubOrderParams extends OrderParams {
+
+    @ApiModelProperty("鍏ュ簱鐗╂枡鍒楄〃")
+    List<OrderItemsParam> details;
+}
diff --git a/src/main/java/com/zy/api/entity/ReportOrderParam.java b/src/main/java/com/zy/api/entity/ReportOrderParam.java
new file mode 100644
index 0000000..139cdce
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/ReportOrderParam.java
@@ -0,0 +1,18 @@
+package com.zy.api.entity;
+
+import java.util.List;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "ReportOrderParam", description = "涓婃姤璁㈠崟淇℃伅")
+public class ReportOrderParam extends OrderParams{
+
+    @ApiModelProperty("涓婃姤璁㈠崟鍒楄〃")
+    List<ReportOrderParams> details;
+
+}
diff --git a/src/main/java/com/zy/api/entity/ReportOrderParams.java b/src/main/java/com/zy/api/entity/ReportOrderParams.java
new file mode 100644
index 0000000..99585b2
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/ReportOrderParams.java
@@ -0,0 +1,55 @@
+package com.zy.api.entity;
+
+import java.io.Serializable;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+@ApiModel("涓婃姤璁㈠崟鍙傛暟")
+public class ReportOrderParams implements Serializable {
+
+        @ApiModelProperty("BS Code")
+        private String total_serial;
+
+        @ApiModelProperty("浜у搧绫诲瀷")
+        private String pro_type;
+
+        @ApiModelProperty("闆朵欢浠g爜")
+        private String pro_komcode;
+
+        @ApiModelProperty("渚涘簲鍟咺D")
+        private String pro_id;
+
+        @ApiModelProperty("瀹瑰櫒缂栫爜")
+        private String location_no;
+
+        @ApiModelProperty("璐т綅绫诲瀷")
+        private String location_type;
+
+        @ApiModelProperty("涓婃灦鏃ユ湡")
+        private String sj_date;
+
+        @ApiModelProperty("涓婃灦浜�")
+        private String sj_emp;
+
+        @ApiModelProperty("涓婃灦鏁伴噺")
+        private Integer pick_qty;
+
+        @ApiModelProperty("鐮存崯鏁伴噺")
+        private Integer damage_qty;
+        
+        @ApiModelProperty("宸紓鏁伴噺")
+        private Integer diff_qty;
+
+        @ApiModelProperty("鍘熶笂鏋舵淳宸ユ暟閲�")
+        private Integer old_qty;
+
+        @ApiModelProperty("鍙樻洿鏁伴噺")
+        private Integer new_qty;
+
+
+}
diff --git a/src/main/java/com/zy/api/entity/StationProtocol.java b/src/main/java/com/zy/api/entity/StationProtocol.java
new file mode 100644
index 0000000..1c7e121
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/StationProtocol.java
@@ -0,0 +1,28 @@
+package com.zy.api.entity;
+import lombok.Data;
+import java.util.Map;
+
+@Data
+public class StationProtocol {
+    private Integer stationId;      // Station ID
+    private Integer taskNo;         // Task number
+    private Integer targetStaNo;    // Target Station ID
+
+    // Status Flags
+    private boolean autoing;        // Auto mode
+    private boolean loading;        // Has goods
+    private boolean inEnable;       // Inbound enabled
+    private boolean outEnable;      // Outbound enabled
+    private boolean emptyMk;        // Empty pallet mark
+    private boolean fullPlt;        // Full pallet
+    private boolean runBlock;       // Running blocked
+    private boolean enableIn;       // Start inbound
+
+    private Integer palletHeight;
+    private Integer error;          // Error code
+    private String errorMsg;        // Error message
+    private String barcode;
+    private Double weight;
+
+    private Map<String, Object> extend;
+}
\ No newline at end of file
diff --git a/src/main/java/com/zy/api/entity/StockAdjustParams.java b/src/main/java/com/zy/api/entity/StockAdjustParams.java
new file mode 100644
index 0000000..5b3ae43
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/StockAdjustParams.java
@@ -0,0 +1,27 @@
+package com.zy.api.entity;
+
+import java.util.List;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "StockAdjustParams", description = "闆朵欢鎹熸孩鍗曞弬鏁�")
+public class StockAdjustParams extends OrderParams {
+
+    @ApiModelProperty("璋冩暣鍘熷洜")
+    private String reason;
+
+    @ApiModelProperty("璋冩暣鍘熷洜鍚嶇О")
+    private String reason_name;
+
+    @ApiModelProperty("璋冩暣鍗曠紪鍙�")
+    private String bsby_no;
+
+    @ApiModelProperty("璋冩暣鍗曟槑缁嗗垪琛�")
+    List<OrderItemsParam> details;
+
+}
diff --git a/src/main/java/com/zy/api/entity/StockUpOrderParams.java b/src/main/java/com/zy/api/entity/StockUpOrderParams.java
new file mode 100644
index 0000000..6243370
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/StockUpOrderParams.java
@@ -0,0 +1,19 @@
+package com.zy.api.entity;
+
+import java.util.List;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "StockUpOrderParams", description = "澶囪揣璁㈠崟鍙傛暟")
+public class StockUpOrderParams extends OrderParams{
+
+
+    @ApiModelProperty("璁㈠崟鏄庣粏")
+    private List<OutOrderParams> details;
+
+}
diff --git a/src/main/java/com/zy/api/entity/SyncMatParmas.java b/src/main/java/com/zy/api/entity/SyncMatParmas.java
new file mode 100644
index 0000000..7de24a6
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/SyncMatParmas.java
@@ -0,0 +1,45 @@
+package com.zy.api.entity;
+
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "SyncMatParmas", description = "鐗╂枡鍚屾鍙傛暟")
+public class SyncMatParmas implements Serializable {
+
+
+    @ApiModelProperty("闆朵欢绫诲瀷")
+    private String pro_type;
+
+    @ApiModelProperty("闆朵欢浠g爜")
+    private String pro_komcode;
+
+    @ApiModelProperty("渚涘簲鍟嗙紪鐮�")
+    private String pro_id;
+
+    @ApiModelProperty("鍏ュ簱閫氱煡鏁伴噺")
+    private Double inv_qty;
+
+    @ApiModelProperty("鍏徃ID")
+    private String company_id;
+
+    @ApiModelProperty("闆朵欢鍚嶇О")
+    private String pro_name;
+
+    @ApiModelProperty("灏哄")
+    private String pro_size;
+
+    @ApiModelProperty("閲嶉噺")
+    private String pro_wet;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    private String update_time;
+
+}
diff --git a/src/main/java/com/zy/api/entity/dto/XSR.java b/src/main/java/com/zy/api/entity/dto/XSR.java
new file mode 100644
index 0000000..842a586
--- /dev/null
+++ b/src/main/java/com/zy/api/entity/dto/XSR.java
@@ -0,0 +1,77 @@
+package com.zy.api.entity.dto;
+
+import java.sql.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+@ApiModel(value = "XSR", description = "鍩虹鍝嶅簲")
+public class XSR<T> {
+    private static final String SUCCESS_CODE = "200";
+    private static final String FAIL_CODE = "500";
+
+    private String code;
+
+    private String message;
+
+    private Boolean success;
+
+    private String returnMessage;
+
+    private T result;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date timestamp;
+
+    public XSR() {
+        this.timestamp = new Date(System.currentTimeMillis());
+    }
+
+    public static <T> XSR<T> ok() {
+        return new XSR<T>()
+                .setCode(SUCCESS_CODE)
+                .setSuccess(true)
+                .setMessage("鎿嶄綔鎴愬姛")
+                .setReturnMessage("鎿嶄綔鎴愬姛");
+    }
+
+    public static <T> XSR<T> ok(T data) {
+        return new XSR<T>()
+                .setCode(SUCCESS_CODE)
+                .setSuccess(true)
+                .setMessage("鎿嶄綔鎴愬姛")
+                .setReturnMessage("鎿嶄綔鎴愬姛")
+                .setResult(data);
+    }
+
+    public static <T> XSR<T> ok(T data, String message) {
+        return new XSR<T>()
+                .setCode(SUCCESS_CODE)
+                .setSuccess(true)
+                .setMessage(message)
+                .setReturnMessage(message)
+                .setResult(data);
+    }
+
+    public static <T> XSR<T> error(String message) {
+        return new XSR<T>()
+                .setCode(FAIL_CODE)
+                .setSuccess(false)
+                .setMessage(message)
+                .setReturnMessage(message);
+    }
+
+    public static <T> XSR<T> error(String code, String message) {
+        return new XSR<T>()
+                .setCode(code)
+                .setSuccess(false)
+                .setMessage(message)
+                .setReturnMessage(message);
+    }
+}
diff --git a/src/main/java/com/zy/api/enums/LocAreaType.java b/src/main/java/com/zy/api/enums/LocAreaType.java
new file mode 100644
index 0000000..3ac462b
--- /dev/null
+++ b/src/main/java/com/zy/api/enums/LocAreaType.java
@@ -0,0 +1,24 @@
+package com.zy.api.enums;
+/**
+ * 搴撳尯绫诲瀷
+ */
+public enum LocAreaType {
+
+
+    /** 澶у簱鍖� */
+     AUTOMATED("1", "绔嬪簱"),
+    /** 涓簱鍖� */
+    SO_HOLDING("2", "SO绛夊緟鍖�"),
+    /** 灏忎欢搴撳尯 */
+    EO_HOLDING("3", "EO绛夊緟鍖�");
+
+    public String type;
+
+    public String desc;
+
+    LocAreaType(String type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+}
diff --git a/src/main/java/com/zy/api/enums/MatLocType.java b/src/main/java/com/zy/api/enums/MatLocType.java
new file mode 100644
index 0000000..714ac23
--- /dev/null
+++ b/src/main/java/com/zy/api/enums/MatLocType.java
@@ -0,0 +1,65 @@
+package com.zy.api.enums;
+
+/**
+ * 鐗╂枡鎵�灞炲簱浣嶇被鍨�
+ * @author Ryan
+ * @date 2025/12/6 10:41
+ * @return null
+ */
+public enum MatLocType {
+
+    /** 灏忎欢 */
+    AUTOMATED("12", "灏忎欢"),
+    /** 涓欢 */
+    SO_HOLDING("13", "涓欢"),
+    /** 澶т欢 */
+    EO_HOLDING("14", "婊よ姱");
+
+    public String type;
+
+    public String desc;
+
+    MatLocType(String type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+    public static String getTagName(String type) {
+        if (type.equals(MatLocType.AUTOMATED.type)) {
+            return MatLocType.AUTOMATED.desc;
+        } else if (type.equals(MatLocType.SO_HOLDING.type)) {
+            return MatLocType.SO_HOLDING.desc;
+        } else if (type.equals(MatLocType.EO_HOLDING.type)) {
+            return MatLocType.EO_HOLDING.desc;
+        } else {
+            return null;
+        }
+    }
+
+
+    public static Long getTag(String type) {
+        if (type.equals(MatType.LARGE.type)) {
+            return Long.parseLong(MatLocType.AUTOMATED.type);
+        } else if (type.equals(MatType.MIDDEL.type)) {
+            return Long.parseLong(MatLocType.SO_HOLDING.type);
+        } else if (type.equals(MatType.SMALL.type)) {
+            return Long.parseLong(MatLocType.EO_HOLDING.type);
+        } else {
+            return null;
+        }
+    }
+
+
+    
+    public static String getMatTag(String type) {
+        if (type.equals(MatLocType.AUTOMATED.type)) {
+            return MatType.LARGE.type;
+        } else if (type.equals(MatLocType.SO_HOLDING.type)) {
+            return MatType.MIDDEL.type;
+        } else if (type.equals(MatLocType.EO_HOLDING.type)) {
+            return MatType.SMALL.type;
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/src/main/java/com/zy/api/enums/MatType.java b/src/main/java/com/zy/api/enums/MatType.java
new file mode 100644
index 0000000..0b4cfac
--- /dev/null
+++ b/src/main/java/com/zy/api/enums/MatType.java
@@ -0,0 +1,36 @@
+package com.zy.api.enums;
+
+/**
+ * 鐗╂枡绫诲瀷
+ */
+public enum MatType {
+
+    /** 婊よ姱 */
+    LARGE("1", "婊よ姱"),
+    /** 涓欢 */
+    MIDDEL("2", "涓欢"),
+    /** 灏忎欢 */
+    SMALL("3", "灏忎欢");
+
+    public String type;
+
+    public String desc;
+
+    MatType(String type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+    public static Long getTag(String type) {
+        if (type.equals(MatType.LARGE.type)) {
+            return Long.parseLong(MatLocType.AUTOMATED.type);
+        } else if (type.equals(MatType.MIDDEL.type)) {
+            return Long.parseLong(MatLocType.SO_HOLDING.type);
+        } else if (type.equals(MatType.SMALL.type)) {
+            return Long.parseLong(MatLocType.EO_HOLDING.type);
+        } else {
+            return null;
+        }
+    }
+
+}
diff --git a/src/main/java/com/zy/api/enums/OrderType.java b/src/main/java/com/zy/api/enums/OrderType.java
new file mode 100644
index 0000000..0216467
--- /dev/null
+++ b/src/main/java/com/zy/api/enums/OrderType.java
@@ -0,0 +1,57 @@
+package com.zy.api.enums;
+
+/**
+ * @author Ryan
+ * @version 1.0
+ * @title PurchaseType
+ * @description
+ * @create 2025/3/5 15:54
+ */
+public enum OrderType {
+    //璁㈠崟绫诲瀷
+    ORDER_OUT("out", "鍑哄簱鍗�"),
+    ORDER_IN("in", "鍏ュ簱鍗�"),
+    ORDER_TRANSFER("transfer", "璋冩嫈鍗�"),
+    ORDER_REVISE("revise", "搴撳瓨璋冩暣"),
+    ORDER_CHECK("check", "鐩樼偣鍗�");
+
+
+    OrderType(String type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+    public String type;
+    public String desc;
+
+    public static String getTypeVal(String desc) {
+        if (desc.equals(OrderType.ORDER_IN.desc)) {
+            return OrderType.ORDER_IN.type;
+        } else if (desc.equals(OrderType.ORDER_OUT.desc)) {
+            return OrderType.ORDER_OUT.type;
+        } else if (desc.equals(OrderType.ORDER_CHECK.desc)) {
+            return OrderType.ORDER_CHECK.type;
+        } else if (desc.equals(OrderType.ORDER_TRANSFER.desc)) {
+            return OrderType.ORDER_TRANSFER.type;
+        } else if (desc.equals(OrderType.ORDER_REVISE.desc)) {
+            return OrderType.ORDER_REVISE.type;
+        }
+        return null;
+    }
+
+    public static String getValType(String type) {
+        if (type.equals(OrderType.ORDER_IN.type)) {
+            return OrderType.ORDER_IN.desc;
+        } else if (type.equals(OrderType.ORDER_OUT.type)) {
+            return OrderType.ORDER_OUT.desc;
+        } else if (type.equals(OrderType.ORDER_CHECK.type)) {
+            return OrderType.ORDER_CHECK.desc;
+        } else if (type.equals(OrderType.ORDER_TRANSFER.type)) {
+            return OrderType.ORDER_TRANSFER.desc;
+        } else if (type.equals(OrderType.ORDER_REVISE.type)) {
+            return OrderType.ORDER_REVISE.desc;
+        }
+        return null;
+    }
+
+}
diff --git a/src/main/java/com/zy/api/enums/OrderWkType.java b/src/main/java/com/zy/api/enums/OrderWkType.java
new file mode 100644
index 0000000..a656e3d
--- /dev/null
+++ b/src/main/java/com/zy/api/enums/OrderWkType.java
@@ -0,0 +1,45 @@
+package com.zy.api.enums;
+
+
+public enum OrderWkType {
+
+    // 璁㈠崟绫诲瀷
+    ORDER_WK_PUR_IN("0", "閲囪喘鍏ュ簱"),
+    ORDER_WK_TRANSFER_IN("1", "璋冩嫈鍏ュ簱"),
+    ORDER_WK_SALE_IN("2", "瀹㈡埛閫�璐�"),
+    ORDER_WK_BAG_IN("5", "绱㈣禂鍏ュ簱"),
+    ORDER_WK_SUPLUS_IN("7", "鎶ユ孩鍏ュ簱"),
+    ORDER_WK_PRO_UPDATE_IN("8", "浠跺彿鍙樻洿鍏ュ簱"),
+    ORDER_WK_MEGER_IN("K", "缁勫悎鎷嗛浂鍏ュ簱"),
+    ORDER_WK_ORDER_OUT_EO("11", "澶囪揣鎸囩ず娲惧伐鍗曪紙EO锛�"),
+    ORDER_WK_ORDER_OUT_SO("12", "澶囪揣鎸囩ず娲惧伐鍗曪紙SO锛�"),
+    ORDER_WK_ORDER_OUT("13", "澶囪揣鍗�");
+
+    OrderWkType(String val, String desc) {
+        this.val = val;
+        this.desc = desc;
+    }
+
+    public String val;
+    public String desc;
+
+    public static String getTypeVal(String val) {
+        if (val.equals(OrderWkType.ORDER_WK_PUR_IN.val)
+                || val.equals(OrderWkType.ORDER_WK_SUPLUS_IN.val)
+                || val.equals(OrderWkType.ORDER_WK_MEGER_IN.val)
+                || val.equals(OrderWkType.ORDER_WK_PRO_UPDATE_IN.val)) {
+            return OrderType.ORDER_IN.type;
+        } else if (val.equals(OrderWkType.ORDER_WK_TRANSFER_IN.val)) {
+            return OrderType.ORDER_IN.type;
+        } else if (val.equals(OrderWkType.ORDER_WK_SALE_IN.val)) {
+            return OrderType.ORDER_IN.type;
+        } else if (val.equals(OrderWkType.ORDER_WK_BAG_IN.val)) {
+            return OrderType.ORDER_IN.type;
+        } else if (val.equals(OrderWkType.ORDER_WK_ORDER_OUT_EO.val)  || val.equals(OrderWkType.ORDER_WK_ORDER_OUT_SO.val)  || val.equals(OrderWkType.ORDER_WK_ORDER_OUT.val)) {
+            return OrderType.ORDER_OUT.type;
+        } else {
+            return null;
+        }
+    }
+
+}
diff --git a/src/main/java/com/zy/api/service/HWmsApiService.java b/src/main/java/com/zy/api/service/HWmsApiService.java
new file mode 100644
index 0000000..5733310
--- /dev/null
+++ b/src/main/java/com/zy/api/service/HWmsApiService.java
@@ -0,0 +1,78 @@
+package com.zy.api.service;
+
+import java.util.List;
+
+import com.zy.api.controller.params.PageRequestParams;
+import com.zy.api.entity.PubOrderParams;
+import com.zy.api.entity.ReportOrderParam;
+import com.zy.api.entity.StockAdjustParams;
+import com.zy.api.entity.StockUpOrderParams;
+import com.zy.api.entity.SyncMatParmas;
+import com.zy.api.entity.dto.XSR;
+import com.zy.asrs.entity.Order;
+
+public interface HWmsApiService {
+
+
+    /**
+     * 涓婃灦娲惧伐鍗曚笅鍙�
+     * @author Ryan
+     * @date 2025/11/24 14:42
+     * @param params
+     * @return com.core.common.R
+     */
+    XSR receiveOrders(List<PubOrderParams> params);
+
+    /**
+     * 鍩虹闆朵欢鍙樻洿
+     * @author Ryan
+     * @date 2025/11/24 15:04
+     * @param matnrs
+     * @return com.core.common.R
+     */
+    XSR basMatupdate(List<SyncMatParmas> matnrs);
+
+
+    /**
+     * 鏂板鎴栦慨鏀瑰崟鎹俊鎭�
+     * @author Ryan
+     * @date 2025/11/24 15:33
+     */
+    void addOrUpdateOrders(PubOrderParams params, String type) ;
+
+    /**
+     * 涓婃灦娲惧伐鍗曞弽棣�
+     *
+     * @param params
+     * @param order
+     * @return
+     */
+    XSR getInDispatchResult(List<ReportOrderParam> params, Order order);
+
+    /**
+     * 澶囪揣鎸囩ず娲惧伐鍗曚笅鍙�
+     * @param params
+     * @return
+     */
+    XSR sendOutDispatch(List<PubOrderParams> params);
+
+    /**
+     * 澶囪揣鍗曚笅鍙�
+     * @author Ryan
+     * @date 2025/11/24 15:40
+     * @param params
+     * @return com.core.common.R
+     */
+    XSR getOutDetails(List<StockUpOrderParams> params);
+
+    /**
+     * 鏌ヨWMS搴撳瓨淇℃伅
+     * @author Ryan
+     * @date 2025/11/24 15:22
+     * @param params
+     * @return com.core.common.R
+     */
+    XSR getStockInfo(PageRequestParams params);
+
+
+}
diff --git a/src/main/java/com/zy/api/service/HmesApiService.java b/src/main/java/com/zy/api/service/HmesApiService.java
new file mode 100644
index 0000000..8930fae
--- /dev/null
+++ b/src/main/java/com/zy/api/service/HmesApiService.java
@@ -0,0 +1,12 @@
+package com.zy.api.service;
+
+import com.core.common.R;
+import com.zy.api.controller.params.ReceviceTaskParams;
+import com.zy.asrs.entity.param.OpenOrderPakoutParam;
+
+public interface HmesApiService {
+
+    R pubWorkTask(OpenOrderPakoutParam params);
+
+    R releaseLock(ReceviceTaskParams params);
+}
diff --git a/src/main/java/com/zy/api/service/WcsApiService.java b/src/main/java/com/zy/api/service/WcsApiService.java
new file mode 100644
index 0000000..c908ec5
--- /dev/null
+++ b/src/main/java/com/zy/api/service/WcsApiService.java
@@ -0,0 +1,37 @@
+package com.zy.api.service;
+
+import com.core.common.R;
+import com.zy.api.controller.params.ReceviceTaskParams;
+import com.zy.api.controller.params.StopOutTaskParams;
+import com.zy.api.controller.params.WorkTaskParams;
+
+import java.util.Set;
+
+public interface WcsApiService {
+
+    /**
+     * 涓嬪彂浠诲姟鑷砏CS
+     * @author Ryan
+     * @date 2026/1/10 13:57
+     * @param params
+     * @return com.core.common.R
+     */
+    R pubWrkToWcs(WorkTaskParams params);
+
+    /**
+     * 鍫嗗灈鏈轰换鍔″畬鎴愮姸鎬佷笂鎶�
+     * @author Ryan
+     * @date 2026/1/10 16:29
+     * @param params
+     * @return com.core.common.R
+     */
+    R receviceTaskFromWcs(ReceviceTaskParams params);
+
+    /**
+     * batch pause out tasks
+     * @param params
+     * @return
+     */
+    R pauseOutTasks(StopOutTaskParams params);
+
+}
diff --git a/src/main/java/com/zy/api/service/impl/HWmsApiServiceImpl.java b/src/main/java/com/zy/api/service/impl/HWmsApiServiceImpl.java
new file mode 100644
index 0000000..3f89a3d
--- /dev/null
+++ b/src/main/java/com/zy/api/service/impl/HWmsApiServiceImpl.java
@@ -0,0 +1,539 @@
+package com.zy.api.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.plugins.Page;
+import com.core.common.SnowflakeIdWorker;
+import com.core.exception.CoolException;
+import com.zy.api.controller.params.PageRequestParams;
+import com.zy.api.entity.OrderItemsParam;
+import com.zy.api.entity.OrderParams;
+import com.zy.api.entity.OutOrderParams;
+import com.zy.api.entity.PubOrderParams;
+import com.zy.api.entity.ReportOrderParam;
+import com.zy.api.entity.StockUpOrderParams;
+import com.zy.api.entity.SyncMatParmas;
+import com.zy.api.entity.dto.XSR;
+import com.zy.api.enums.MatLocType;
+import com.zy.api.enums.OrderType;
+import com.zy.api.enums.OrderWkType;
+import com.zy.api.service.HWmsApiService;
+import com.zy.asrs.entity.LocDetl;
+import com.zy.asrs.entity.Mat;
+import com.zy.asrs.entity.Order;
+import com.zy.asrs.entity.OrderDetl;
+import com.zy.asrs.enums.CommonEnum;
+import com.zy.asrs.service.LocDetlService;
+import com.zy.asrs.service.MatService;
+import com.zy.asrs.service.OrderDetlService;
+import com.zy.asrs.service.OrderService;
+
+import com.zy.asrs.utils.Utils;
+import com.zy.common.utils.HttpHandler;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+
+@Slf4j
+@Service("kopenApiServiceImpl")
+public class HWmsApiServiceImpl implements HWmsApiService {
+
+    @Autowired
+    private OrderService orderService;
+    @Autowired
+    private OrderDetlService orderDetlService;
+    @Autowired
+    private MatService matService;
+    @Autowired
+    private LocDetlService locDetlService;
+    @Autowired
+    private SnowflakeIdWorker snowflakeIdWorker;
+//    @Value("${kopen.url}")
+    private String url;
+//    @Value("${kopen.port}")
+    private String port;
+//    @Value("${kopen.prefix}")
+    private String prefix;
+
+
+    /**
+     * 鎺ユ敹涓嬪彂璁㈠崟淇℃伅
+     *
+     * @param orderParams
+     * @return com.core.common.R
+     * @author Ryan
+     * @date 2025/11/24 14:49
+     */
+    @Override
+    public XSR receiveOrders(List<PubOrderParams> orderParams) {
+        orderParams.forEach(params -> {
+            if (params.getType().equals(OrderWkType.getTypeVal(params.getType()))) {
+                throw new CoolException("褰撳墠绫诲瀷涓嶆槸涓婃灦娲惧伐鍗曪紒锛�");
+            }
+            addOrUpdateOrders(params, "add");
+        });
+
+        return XSR.ok("鍗曟嵁涓嬪彂鎴愬姛锛侊紒");
+    }
+
+    /**
+     * 涓婃灦娲惧伐鍗曞弽棣�
+     *
+     * @author Ryan
+     * @date 2025/11/24 15:33
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public XSR getInDispatchResult(List<ReportOrderParam> params, Order order) {
+        if (Objects.isNull(params)) {
+            return XSR.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        String response = null;
+
+        try {
+            response = new HttpHandler.Builder()
+                    .setUri(url + ":" + port)
+                    .setPath(prefix + "/getInDispatchResult")
+                    .setJson(JSONObject.toJSONString(params))
+                    .build()
+                    .doPost();
+            if (Objects.isNull(response) || response.trim().isEmpty()) {
+                return XSR.error("澶栫綉鎺ュ彛鏃犲搷搴旓紒锛�");
+            }
+            JSONObject jsonObject = JSONObject.parseObject(response);
+            Integer code = jsonObject.getInteger("code");
+            if (!Objects.isNull(code) && code.equals(200)) {
+                if (!Objects.isNull(order)) {
+//                    order.setReportOnce(5);
+                    orderService.updateById(order);
+                }
+                return XSR.ok("鍏ュ簱鍗曚笂鎶ュ畬鎴愶紒锛�");
+            } else {
+                if (!Objects.isNull(order)) {
+//                    int reportOnce = order.getReportOnce();
+//                    reportOnce ++;
+//                    order.setReportOnce(reportOnce);
+                    orderService.updateById(order);
+                }
+                String msg = jsonObject.getString("message");
+                return XSR.error(Objects.isNull(msg) ? "涓婃姤澶辫触锛侊紒" : msg);
+            }
+        } catch (Exception e) {
+            if (!Objects.isNull(order)) {
+//                int reportOnce = order.getReportOnce();
+//                reportOnce ++;
+//                order.setReportOnce(reportOnce);
+                orderService.updateById(order);
+            }
+            log.error(e.getMessage(), e);
+            return XSR.error(e.getMessage());
+        }
+    }
+
+    /**
+     * 鑾峰彇鑷畾涔夎姹傚ご
+     * @author Ryan
+     * @date 2025/12/29 9:11
+     * @return java.util.Map<java.lang.String,java.lang.Object>
+     */
+    private Map<String, Object> getHeaderParam() {
+        Map<String, Object> headerParam = new HashMap<>();
+//        headerParam.put("accept", "*/*");
+//        headerParam.put("connection", "Keep-Alive");
+        //璁剧疆璇锋眰杩炴帴鐨凾oken
+        headerParam.put("api_key", "WMS");
+        headerParam.put("charset", "UTF-8");
+        headerParam.put("timestamp", new Date());
+        headerParam.put("format", "xml");
+        headerParam.put("signature", "c56ced444ed772098ffeb59537bbfa59");
+
+        return headerParam;
+    }
+
+    /* */
+
+    /**
+     * 澶囪揣鎸囩ず娲惧伐鍗曚笅鍙�
+     *
+     * @param pubOrderParams
+     * @return com.core.common.R
+     * @author Ryan
+     * @date 2025/11/24 15:21
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public XSR sendOutDispatch(List<PubOrderParams> pubOrderParams) {
+        if (Objects.isNull(pubOrderParams) || pubOrderParams.isEmpty()) {
+            return XSR.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        pubOrderParams.forEach(params -> {
+            // 鏍¢獙鍙傛暟
+            if (Objects.isNull(params.getDispatch_no())) {
+                throw new CoolException("娲惧伐鍗曠紪鍙蜂笉鑳戒负绌猴紒锛�");
+            }
+            if (Objects.isNull(params.getKopen_id())) {
+                throw new CoolException("娴佹按鍙蜂笉鑳戒负绌猴紒锛�");
+            }
+            if (Objects.isNull(params.getCompany_id())) {
+                throw new CoolException("鍏徃ID涓嶈兘涓虹┖锛侊紒");
+            }
+
+            addOrUpdateOrders(params, "add");
+        });
+
+        return XSR.ok("澶囪揣鎸囩ず娲惧伐鍗曚笅鍙戞垚鍔燂紒锛�");
+    }
+
+    // /**
+    // * 澶囪揣鎸囩ず娲惧伐鍗�
+    // *
+    // * @author Ryan
+    // * @date 2025/12/16 9:15
+    // * @param params
+    // */
+    // private void outOrderAddAndUpdate(PubOrderParams params, String type) {
+    // if (Objects.isNull(params)) {
+    // throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+    // }
+    // if (Objects.isNull(params.getType())) {
+    // throw new CoolException("璁㈠崟绫诲瀷涓嶈兘涓虹┖锛侊紒");
+    // }
+
+    // OrderParams orderParams =
+    // JSONObject.parseObject(JSONObject.toJSONString(params), OrderParams.class);
+    // Order order = orderService.selectOne(new
+    // EntityWrapper<Order>().eq("order_no", orderParams.getInv_no()));
+    // if (type.equals("add") && !Objects.isNull(order)) {
+    // throw new CoolException("鍗曟嵁宸插瓨鍦�, 涓嶅彲閲嶅娣诲姞锛侊紒");
+    // }
+    // // 鍒ゆ柇璁㈠崟鏄惁瀛樺湪
+    // if (Objects.isNull(order)) {
+    // /** 涓嶅瓨鍦紝鏂板璁㈠崟 */
+    // generateOrders(params);
+    // } else {
+    // /** 瀛樺湪锛屽垹闄よ�佽鍗曪紝鏇存柊鎻掑叆鏂拌鍗� */
+    // // 鍒犻櫎鏃ц鍗曟槑缁�
+    // if (!orderDetlService.delete(new EntityWrapper<OrderDetl>().eq("order_id",
+    // order.getId()))) {
+    // throw new CoolException("璁㈠崟鏄庣粏鍒犻櫎澶辫触锛侊紒");
+    // }
+    // ;
+    // if (!orderService.deleteById(order.getId())) {
+    // throw new CoolException("鍘熷崟鎹垹闄ゅけ璐ワ紒锛�");
+    // }
+    // generateOrders(params);
+    // }
+
+    // }
+
+    /**
+     * 鍩虹闆朵欢鍙樻洿
+     *
+     * @param params
+     * @return com.core.common.R
+     * @author Ryan
+     * @date 2025/11/24 15:05
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public synchronized XSR basMatupdate(List<SyncMatParmas> params) {
+        if (Objects.isNull(params) || params.isEmpty()) {
+            return XSR.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        params.forEach(mats -> {
+            if (Objects.isNull(mats)) {
+                throw new CoolException("鐗╂枡缂栫爜涓嶈兘涓虹┖锛侊紒");
+            }
+            if (Objects.isNull(mats.getPro_type())) {
+                throw new CoolException("闆朵欢绫诲瀷涓嶈兘涓虹┖锛侊紒");
+            }
+            Mat matnr = matService.selectOne(new EntityWrapper<Mat>().eq("matnr", mats.getPro_komcode()));
+            if (!Objects.isNull(matnr)) {
+//                // 璁㈠崟鏃堕棿
+//                if (Utils.isValidFormat(mats.getUpdate_time(), "yyyy-MM-dd HH:mm:ss")) {
+//                    Date date1 = Utils.getFormateDate(mats.getUpdate_time());
+//                    matnr.setUpdateTime(date1);
+//                }
+//                matnr.setMaktx(mats.getPro_name());
+//                matnr.setSpecs(mats.getPro_size());
+//                matnr.setWeight(Objects.isNull(mats.getPro_wet()) ? 0.0 : Double.parseDouble(mats.getPro_wet()));
+//                matnr.setSuppCode(mats.getPro_id());
+//                matnr.setTagId(MatLocType.getTag(mats.getPro_type()));
+//                matnr.setLocType(MatLocType.getTag(mats.getPro_type()));
+//                matnr.setManu(mats.getCompany_id());
+//                if (!matService.updateById(matnr)) {
+//                    throw new CoolException("鐗╂枡鏇存柊澶辫触鎴栨棤闇�鏇存柊锛侊紒");
+//                }
+            } else {
+                if (Objects.isNull(matnr)) {
+                    matnr = new Mat();
+                }
+//                // 璁㈠崟鏃堕棿
+//                if (Utils.isValidFormat(mats.getUpdate_time(), "yyyy-MM-dd HH:mm:ss")) {
+//                    Date date1 = Utils.getFormateDate(mats.getUpdate_time());
+//                    matnr.setUpdateTime(date1);
+//                }
+//                matnr.setMaktx(mats.getPro_name());
+//                matnr.setMatnr(mats.getPro_komcode());
+//                matnr.setSpecs(mats.getPro_size());
+//                matnr.setWeight(Double.parseDouble(mats.getPro_wet()));
+//                matnr.setSuppCode(mats.getPro_id());
+//                matnr.setTagId(MatLocType.getTag(mats.getPro_type()));
+//                matnr.setLocType(MatLocType.getTag(mats.getPro_type()));
+//                matnr.setManu(mats.getCompany_id());
+//                if (!matService.insert(matnr)) {
+//                    throw new CoolException("鐗╂枡鏇存柊澶辫触锛侊紒");
+//                }
+            }
+        });
+
+        return XSR.ok("淇濆瓨鎴愬姛锛侊紒");
+    }
+
+    /**
+     * 鏂板鎴栦慨鏀硅鍗曚俊鎭�
+     *
+     * @author Ryan
+     * @date 2025/11/24 15:32
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void addOrUpdateOrders(PubOrderParams params, String type) {
+        if (Objects.isNull(params)) {
+            throw new CoolException("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        if (Objects.isNull(params.getType())) {
+            throw new CoolException("璁㈠崟绫诲瀷涓嶈兘涓虹┖锛侊紒");
+        }
+        OrderParams orderParams = JSONObject.parseObject(JSONObject.toJSONString(params), OrderParams.class);
+        // Order order = orderService.selectOne(new
+        // EntityWrapper<Order>().eq("order_no", orderParams.getDispatch_no()));
+        Order order = null;
+        if (OrderType.ORDER_IN.type.equals(OrderWkType.getTypeVal(params.getType()))) {
+            // 鍏ュ簱
+            order = orderService.selectOne(new EntityWrapper<Order>().eq("order_no",
+                    orderParams.getDispatch_no()));
+        } else if (OrderType.ORDER_OUT.type.equals(OrderWkType.getTypeVal(params.getType()))) {
+            // 鍑哄簱
+            if (OrderWkType.ORDER_WK_ORDER_OUT.val.equals(params.getType())) {
+                // 澶囪揣鍗曞嚭搴�
+                order = orderService.selectOne(new EntityWrapper<Order>().eq("order_no",
+                        orderParams.getPick_no()));
+            } else if (OrderWkType.ORDER_WK_ORDER_OUT_EO.val.equals(params.getType())
+                    || OrderWkType.ORDER_WK_ORDER_OUT_SO.val.equals(params.getType())) {
+                // 澶囪揣鎸囩ず娲惧伐鍗曪紙EO/SO锛夊嚭搴�
+                order = orderService.selectOne(new EntityWrapper<Order>().eq("order_no",
+                        orderParams.getDispatch_no()));
+            } else {
+                throw new CoolException("鍗曟嵁绫诲瀷涓嶅瓨鍦紝涓嶆敮鎸佹坊鍔狅紒锛�");
+            }
+        } else {
+            throw new CoolException("鍗曟嵁绫诲瀷涓嶅瓨鍦紝涓嶆敮鎸佹坊鍔狅紒锛�");
+        }
+        // 鍑哄簱
+        if (type.equals("add") && !Objects.isNull(order)) {
+            throw new CoolException("鍗曟嵁宸插瓨鍦�, 涓嶅彲閲嶅娣诲姞锛侊紒");
+        }
+        // 鍒ゆ柇璁㈠崟鏄惁瀛樺湪
+        if (Objects.isNull(order)) {
+            /** 涓嶅瓨鍦紝鏂板璁㈠崟 */
+            generateOrders(params);
+        } else {
+            /** 瀛樺湪锛屽垹闄よ�佽鍗曪紝鏇存柊鎻掑叆鏂拌鍗� */
+            // 鍒犻櫎鏃ц鍗曟槑缁�
+            if (!orderDetlService.delete(new EntityWrapper<OrderDetl>().eq("order_id", order.getId()))) {
+                throw new CoolException("璁㈠崟鏄庣粏鍒犻櫎澶辫触锛侊紒");
+            }
+
+            if (!orderService.deleteById(order.getId())) {
+                throw new CoolException("鍘熷崟鎹垹闄ゅけ璐ワ紒锛�");
+            }
+            generateOrders(params);
+        }
+    }
+
+    public static String generateUUID(OrderParams params) {
+        return UUID.randomUUID().toString();
+    }
+
+    /**
+     * 鐢熸垚璁㈠崟淇℃伅
+     *
+     * @param params
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void generateOrders(PubOrderParams params) {
+        // 灏嗘暟鎹綋鏂拌鍗曟彃鍏�
+        Order newOrder = new Order();
+        // 娲惧伐鍗曞彿
+        newOrder.setOrderNo(params.getDispatch_no());
+        if (OrderType.ORDER_IN.type.equals(OrderWkType.getTypeVal(params.getType()))) {
+            // 鍏ュ簱
+            newOrder.setPakinPakoutStatus(1);
+//            Integer docType = OrderWkType.getDocType(params.getType());
+//            newOrder.setDocType(Long.parseLong(docType + ""));
+            newOrder.setNumber(params.getInv_no());
+        } else if (OrderType.ORDER_OUT.type.equals(OrderWkType.getTypeVal(params.getType()))) {
+            // 鍑哄簱
+            if (OrderWkType.ORDER_WK_ORDER_OUT.val.equals(params.getType())) {
+                // 澶囪揣鍗曞嚭搴�
+                newOrder.setOrderNo(params.getPick_no());
+                newOrder.setNumber(params.getDispatch_no());
+                newOrder.setShipCode(params.getOrder_no());
+                newOrder.setCstmrName(params.getCus_id());
+                newOrder.setTel(params.getCus_address());
+//                newOrder.setDocType(Long.parseLong(OrderTypeEnum.STOCK.type + ""));
+            } else if (OrderWkType.ORDER_WK_ORDER_OUT_EO.val.equals(params.getType())
+                    || OrderWkType.ORDER_WK_ORDER_OUT_SO.val.equals(params.getType())) {
+                // 澶囪揣鎸囩ず娲惧伐鍗曪紙EO/SO锛夊嚭搴�
+//                newOrder.setDocType(Long.parseLong(OrderTypeEnum.TRANSFER.type + ""));
+            }
+            newOrder.setPakinPakoutStatus(2);
+        }
+
+        newOrder.setUuid(generateUUID(params));
+        // 娴佹按鍙凤紙鍞竴锛�
+        newOrder.setDefNumber(params.getKopen_id());
+//        newOrder.setTargetLocation(params.getTarget_location());
+        // 绠卞彿
+        newOrder.setItemName(params.getPm_tktid());
+//        newOrder.setSettle(OrderSettle.ORDER_SETTLE_HOLDING.type);
+        newOrder.setStatus(CommonEnum.COMMON_ENUM_Y.type);
+        // 璁㈠崟鏃堕棿
+//        if (Utils.isValidFormat(params.getUpdate_time(), "yyyy-MM-dd HH:mm:ss")) {
+//            newOrder.setOrderTime(params.getUpdate_time());
+//        }
+        // 鍏徃ID
+        newOrder.setCstmrName(params.getCompany_id());
+        newOrder.setCreateTime(new Date());
+        newOrder.setUpdateTime(new Date());
+        if (!orderService.insert(newOrder)) {
+            throw new RuntimeException("鏂板璁㈠崟澶辫触锛侊紒");
+        }
+        if (!Objects.isNull(params.getDetails()) && !params.getDetails().isEmpty()) {
+            params.getDetails().forEach(item -> {
+                Mat matnr = matService.selectOne(new EntityWrapper<Mat>().eq("matnr", item.getPro_komcode()));
+                if (Objects.isNull(matnr)) {
+                    throw new CoolException("鐗╂枡缂栫爜涓嶅瓨鍦紒锛�");
+                }
+                OrderDetl orderItem = new OrderDetl();
+                BeanUtils.copyProperties(matnr, orderItem);
+                orderItem.setOrderId(newOrder.getId());
+                orderItem.setOrderNo(newOrder.getOrderNo());
+
+                if (OrderType.ORDER_IN.type.equals(OrderWkType.getTypeVal(params.getType()))) {
+                    // 鍏ュ簱
+                    orderItem.setAnfme(Math.round(item.getInv_qty() * 10000) / 10000.0);
+                } else if (OrderType.ORDER_OUT.type.equals(OrderWkType.getTypeVal(params.getType()))) {
+                    // 鍑哄簱
+                    if (OrderWkType.ORDER_WK_ORDER_OUT.val.equals(params.getType())) {
+                        // 澶囪揣鍗曞嚭搴�
+                        orderItem.setAnfme(Math.round(item.getPick_qty() * 10000) / 10000.0);
+                    } else if (OrderWkType.ORDER_WK_ORDER_OUT_EO.val.equals(params.getType())
+                            || OrderWkType.ORDER_WK_ORDER_OUT_SO.val.equals(params.getType())) {
+                        // 澶囪揣鎸囩ず娲惧伐鍗曪紙EO/SO锛夊嚭搴�
+                        orderItem.setAnfme(Math.round(item.getOrder_qty() * 10000) / 10000.0);
+                    }
+                }
+                orderItem.setMatnr(matnr.getMatnr());
+                orderItem.setMaktx(matnr.getMaktx());
+                orderItem.setBrand(matnr.getBrand());
+                orderItem.setBatch("");
+                orderItem.setStandby1(item.getPro_id());
+                // 鍏宠仈涓婂姞娲惧伐鍗曞彿+闆朵欢浠g爜+渚涘簲鍟嗕唬鐮�
+                orderItem.setThreeCode(item.getTotal_serial());
+                // 渚涘簲鍟嗕唬鐮�
+                orderItem.setSuppCode(item.getPro_id());
+                orderItem.setCreateTime(new Date());
+                orderItem.setUpdateTime(new Date());
+                if (!orderDetlService.insert(orderItem)) {
+                    throw new CoolException("璁㈠崟鏄庣粏鏂板澶辫触锛侊紒");
+                }
+            });
+        }
+    }
+
+    /**
+     * 澶囪揣鍗曚笅鍙�
+     *
+     * @param stockUpParams
+     * @return com.core.common.R
+     * @author Ryan
+     * @date 2025/11/24 15:40
+     */
+    @Override
+    public XSR getOutDetails(List<StockUpOrderParams> stockUpParams) {
+        if (Objects.isNull(stockUpParams)) {
+            return XSR.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
+        }
+        stockUpParams.forEach(params -> {
+            if (Objects.isNull(params.getDispatch_no())) {
+                throw new CoolException("娲惧伐鍗曠紪鍙蜂笉鑳戒负绌猴紒锛�");
+            }
+            if (Objects.isNull(params.getKopen_id())) {
+                throw new CoolException("娴佹按鍙蜂笉鑳戒负绌猴紒锛�");
+            }
+            if (Objects.isNull(params.getCompany_id())) {
+                throw new CoolException("鍏徃ID涓嶈兘涓虹┖锛侊紒");
+            }
+            if (Objects.isNull(params.getDetails()) || params.getDetails().isEmpty()) {
+                throw new CoolException("璁㈠崟鏄庣粏涓嶈兘涓虹┖锛侊紒");
+            }
+            List<OrderItemsParam> items = new ArrayList<>();
+            if (params.getDetails() != null) {
+                for (OutOrderParams detail : params.getDetails()) {
+                    if (detail.getPartList() != null) {
+                        items.addAll(detail.getPartList());
+                    }
+                }
+            }
+
+            params.getDetails().forEach(item -> {
+                PubOrderParams pubOrderParams = new PubOrderParams();
+                BeanUtils.copyProperties(params, pubOrderParams);
+                pubOrderParams.setType(item.getType())
+                        .setPick_no(item.getPick_no())
+                        .setCus_address(item.getCus_address())
+                        .setOrder_no(item.getOrder_no())
+                        .setUpdate_time(params.getUpdate_time())
+                        .setCus_id(item.getCus_id());
+                pubOrderParams.setDetails(item.getPartList());
+                addOrUpdateOrders(pubOrderParams, "add");
+            });
+        });
+
+        return XSR.ok("澶囪揣鍗曚笅鍙戞垚鍔燂紒锛�");
+    }
+
+    /**
+     * 鏌ヨWMS搴撳瓨淇℃伅
+     *
+     * @param params
+     * @return com.core.common.R
+     */
+    @Override
+    public XSR getStockInfo(PageRequestParams params) {
+        EntityWrapper<LocDetl> wrapper = new EntityWrapper<>();
+//        if (!Objects.isNull(params.getPro_id())) {
+//            wrapper.eq("supp_code", params.getPro_id());
+//        }
+//        if (!Objects.isNull(params.getPro_komcode())) {
+//            wrapper.eq("matnr", params.getPro_komcode());
+//        }
+
+        Page<LocDetl> locDetls = locDetlService.selectPage(new Page<>(params.getCurr(), params.getLimit()),  wrapper);
+
+        return XSR.ok(locDetls.getRecords());
+    }
+
+
+    private String kopen() {
+        return url + ":" + port + prefix;
+    }
+
+}
diff --git a/src/main/java/com/zy/api/service/impl/HmesApiServiceImpl.java b/src/main/java/com/zy/api/service/impl/HmesApiServiceImpl.java
new file mode 100644
index 0000000..8c7c221
--- /dev/null
+++ b/src/main/java/com/zy/api/service/impl/HmesApiServiceImpl.java
@@ -0,0 +1,68 @@
+package com.zy.api.service.impl;
+
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.core.common.Cools;
+import com.core.common.DateUtils;
+import com.core.common.R;
+import com.core.common.SnowflakeIdWorker;
+import com.core.exception.CoolException;
+import com.zy.api.controller.params.ReceviceTaskParams;
+import com.zy.api.service.HmesApiService;
+import com.zy.api.service.WcsApiService;
+import com.zy.asrs.entity.*;
+import com.zy.asrs.entity.param.OpenOrderPakoutParam;
+import com.zy.asrs.enums.LocStsType;
+import com.zy.asrs.service.*;
+import com.zy.asrs.service.impl.LocDetlServiceImpl;
+import com.zy.asrs.service.impl.OrderDetlPakoutServiceImpl;
+import com.zy.asrs.service.impl.OrderPakoutServiceImpl;
+import com.zy.common.model.DetlDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+public class HmesApiServiceImpl implements HmesApiService {
+
+
+    @Autowired
+    private LocMastService locMastService;
+
+    @Autowired
+    private WcsApiService wcsApiService;
+
+    @Autowired
+    private OrderService orderService;
+
+    @Autowired
+    private DocTypeService docTypeService;
+
+    @Autowired
+    private SnowflakeIdWorker snowflakeIdWorker;
+
+    @Autowired
+    private MatService matService;
+
+    @Autowired
+    private OrderDetlService orderDetlService;
+    @Autowired
+    private OrderPakoutServiceImpl orderPakoutService;
+    @Autowired
+    private OrderDetlPakoutServiceImpl orderDetlPakoutService;
+    @Autowired
+    private LocDetlServiceImpl locDetlService;
+
+
+    @Override
+    public R pubWorkTask(OpenOrderPakoutParam params) {
+        return null;
+    }
+
+    @Override
+    public R releaseLock(ReceviceTaskParams params) {
+        return null;
+    }
+}
diff --git a/src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java b/src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java
new file mode 100644
index 0000000..6ec1185
--- /dev/null
+++ b/src/main/java/com/zy/api/service/impl/WcsApiServiceImpl.java
@@ -0,0 +1,239 @@
+package com.zy.api.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.core.common.Cools;
+import com.core.common.R;
+import com.core.exception.CoolException;
+import com.zy.api.controller.params.ReceviceTaskParams;
+import com.zy.api.controller.params.StopOutTaskParams;
+import com.zy.api.controller.params.WorkTaskParams;
+import com.zy.api.service.WcsApiService;
+import com.zy.asrs.entity.*;
+import com.zy.asrs.service.*;
+import com.zy.asrs.utils.Utils;
+import com.zy.common.constant.MesConstant;
+import com.zy.common.service.CommonService;
+import com.zy.common.utils.HttpHandler;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class WcsApiServiceImpl implements WcsApiService {
+
+    @Autowired
+    private LocMastService locMastService;
+    @Autowired
+    private WrkMastService wrkMastService;
+    @Autowired
+    private WorkService workService;
+    @Autowired
+    private WrkDetlService wrkDetlService;
+    @Autowired
+    private MatService matService;
+    @Autowired
+    private LocDetlService locDetlService;
+    @Value("${wcs.switch}")
+    private String switchValue;
+
+    @Value("${wcs.address.URL}")
+    private String wcs_address;
+
+    @Value("${wcs.address.createOutTask}")
+    private String getWcs_address;
+
+    @Value("${wcs.address.createInTask}")
+    private String createInTask;
+
+    @Value("${wcs.address.createLocMoveTask}")
+    private String createLocMoveTask;
+
+    @Value("${wcs.address.stopOutTask}")
+    private String stopOutTask;
+    @Autowired
+    private CommonService commonService;
+
+
+    /**
+     * 涓嬪彂浠诲姟鑷砏CS
+     *
+     * @param params
+     * @return com.core.common.R
+     * @author Ryan
+     * @date 2026/1/10 13:58
+     */
+    @Override
+    public R pubWrkToWcs(WorkTaskParams params) {
+        if (Objects.isNull(params.getTaskNo())) {
+            return R.error("浠诲姟鍙蜂笉鑳戒负绌猴紒锛�");
+        }
+        if (Objects.isNull(params.getBarcode())) {
+            return R.error("鎵樼洏鐮佷笉鑳戒负绌猴紒锛�");
+        }
+        if (Objects.isNull(params.getLocNo())) {
+            return R.error("鐩爣搴撲綅涓嶈兘涓虹┖锛侊紒");
+        }
+        String url = createInTask;
+        if (!Objects.isNull(params.getType()) && params.getType().equals("out")) {
+            url = getWcs_address;
+        }else if (!Objects.isNull(params.getType()) && params.getType().equals("move")) {
+            url = createLocMoveTask;
+        }
+        String response;
+        R r = R.ok();
+        WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", params.getTaskNo()));
+        if (!Objects.isNull(wrkMast) && "out".equalsIgnoreCase(params.getType()) && "Y".equalsIgnoreCase(wrkMast.getPauseMk())) {
+            return R.error("task paused");
+        }
+        try {
+            log.info("涓嬪彂鎼繍浠诲姟缁檞cs="+JSON.toJSONString(params));
+            response = new HttpHandler.Builder()
+                    .setUri(wcs_address)
+                    .setPath(url)
+                    .setJson(JSON.toJSONString(params))
+                    .build()
+                    .doPost();
+            JSONObject jsonObject = JSON.parseObject(response);
+            log.info("涓嬪彂浠诲姟缁檞cs鐨勮繑鍥炲��="+response);
+            Integer code = jsonObject.getInteger("code");
+
+            if (code==200) {
+                if (!Objects.isNull(wrkMast)) {
+                    if (wrkMast.getIoType()==1 || wrkMast.getIoType()==10) {
+                        wrkMast.setWrkSts(2L);
+                        wrkMast.setModiTime(new Date());
+                        wrkMastService.updateById(wrkMast);
+                    }else if(wrkMast.getIoType()==2){
+                        wrkMast.setWrkSts(2L);
+                        wrkMast.setModiTime(new Date());
+                        wrkMastService.updateById(wrkMast);
+                    }else if (wrkMast.getIoType()==101 || wrkMast.getIoType()==110) {
+                        wrkMast.setWrkSts(12L);
+                        wrkMast.setModiTime(new Date());
+                        wrkMastService.updateById(wrkMast);
+                    }
+                }
+                //TODO 涓婃姤鏄惁鎴愬姛
+            }else {
+                r =R.error();
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return r;
+    }
+
+    /**
+     * 鍫嗗灈鏈烘墽琛岀姸鎬佷笂鎶�
+     *
+     * @param params
+     * @return com.core.common.R
+     * @author Ryan
+     * @date 2026/1/10 16:30
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R receviceTaskFromWcs(ReceviceTaskParams params) {
+        log.info("wcs浠诲姟鍙嶉="+JSON.toJSONString(params));
+        if (Objects.isNull(params.getSuperTaskNo())) {
+            throw new CoolException("WMS浠诲姟鍙蜂笉鑳戒负绌猴紒锛�");
+        }
+        if (Objects.isNull(params.getNotifyType())) {
+            throw new CoolException("鍔ㄤ綔绫诲瀷涓嶈兘涓虹┖锛侊紒");
+        }
+        WrkMast mast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", params.getSuperTaskNo()));
+        if (Objects.isNull(mast)) {
+            throw new CoolException("浠诲姟妗d笉瀛樺湪锛侊紒");
+        }
+
+
+        if (params.getNotifyType().equals("task")) {
+            //浠诲姟
+            if (params.getMsgType().equals("task_complete")) {
+
+                if (mast.getIoType() == 1 || mast.getIoType() == 2 ||mast.getIoType() == 10) {
+                    mast.setWrkSts(4L);
+                } else if ((mast.getIoType() == 101||mast.getIoType()==110) && mast.getWrkSts()<14) {
+                    mast.setWrkSts(14L);
+                    if(Cools.isEmpty(mast.getStaNo())){
+                        mast.setOveMk("Y");
+                    }
+                }
+                if (!wrkMastService.updateById(mast)) {
+                    throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+                }
+            } else if (params.getMsgType().equals("task_cancel")) {
+                if (mast.getIoType() != null && mast.getIoType() > 100 && mast.getWrkSts() < 14) {
+                    mast.setPauseMk("Y");
+                    mast.setUpdMk("WCS_CANCELLED");
+                    mast.setManuType("WCS_CANCELLED");
+                    mast.setModiTime(new Date());
+                    if (!wrkMastService.updateById(mast)) {
+                        throw new CoolException("task cancel update fail");
+                    }
+                }
+            }else if (params.getMsgType().equals("task_arrive")) {
+                //鍒拌揪鐩殑鍦�
+                //濡傛灉鍑哄簱浠诲姟鏄法鍖哄垯闇�瑕佺敓鎴愭柊鐨勫叆搴撲换鍔″叆搴�
+                if(!Cools.isEmpty(mast.getLocNo())){
+                    mast.setOnlineYn("N");//绛夊緟鐢熸垚璺ㄥ尯鍏ュ簱浠诲姟
+                }
+                mast.setWrkSts(14L);
+                if(Cools.isEmpty(mast.getStaNo())){
+                    mast.setOveMk("Y");
+                }
+                mast.setModiTime(new Date());
+                if (!wrkMastService.updateById(mast)) {
+                    throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+                }
+            }
+        } else if (params.getNotifyType().equals("weight")) {
+
+        }
+        return R.ok();
+    }
+    @Override
+    public R pauseOutTasks(StopOutTaskParams params) {
+        if (params == null || params.getTasks() == null || params.getTasks().isEmpty()) {
+            return R.ok("no tasks to stop");
+        }
+        if (!Boolean.parseBoolean(String.valueOf(switchValue))) {
+            return R.ok("wcs switch off");
+        }
+        String response;
+        try {
+            response = new HttpHandler.Builder()
+                    .setUri(wcs_address)
+                    .setPath(stopOutTask)
+                    .setHttps(wcs_address != null && wcs_address.startsWith("https://"))
+                    .setTimeout(10, TimeUnit.SECONDS)
+                    .setJson(JSON.toJSONString(params))
+                    .build()
+                    .doPost();
+            JSONObject jsonObject = JSON.parseObject(response == null ? "{}" : response);
+            Integer code = jsonObject.getInteger("code");
+            if (code == null || !Objects.equals(code, 200)) {
+                String msg = jsonObject.getString("msg");
+                throw new CoolException(Cools.isEmpty(msg) ? "WCS stop out task failed" : msg);
+            }
+        } catch (IOException e) {
+            throw new CoolException("call WCS stop out task fail: " + e.getMessage());
+        }
+        return R.ok();
+    }
+
+}
diff --git a/src/main/java/com/zy/asrs/controller/BasArmMastController.java b/src/main/java/com/zy/asrs/controller/BasArmMastController.java
index ac73fc1..ad24102 100644
--- a/src/main/java/com/zy/asrs/controller/BasArmMastController.java
+++ b/src/main/java/com/zy/asrs/controller/BasArmMastController.java
@@ -78,9 +78,6 @@
                 String[] dates = val.split(RANGE_TIME_LINK);
                 wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
                 wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
-            } else if (entry.getKey().equals("binding_tags")){
-                long aLong = Long.parseLong(val);
-                wrapper.ge(entry.getKey(), aLong);
             } else {
                 wrapper.like(entry.getKey(), val);
             }
diff --git a/src/main/java/com/zy/asrs/controller/BasArmMastLogController.java b/src/main/java/com/zy/asrs/controller/BasArmMastLogController.java
index 127f80c..70b977e 100644
--- a/src/main/java/com/zy/asrs/controller/BasArmMastLogController.java
+++ b/src/main/java/com/zy/asrs/controller/BasArmMastLogController.java
@@ -54,9 +54,6 @@
                 String[] dates = val.split(RANGE_TIME_LINK);
                 wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
                 wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
-            } else if (entry.getKey().equals("binding_tags")){
-                long aLong = Long.parseLong(val);
-                wrapper.ge(entry.getKey(), aLong);
             } else {
                 wrapper.like(entry.getKey(), val);
             }
diff --git a/src/main/java/com/zy/asrs/controller/BasArmMastSignController.java b/src/main/java/com/zy/asrs/controller/BasArmMastSignController.java
index 7ea6ad3..e455599 100644
--- a/src/main/java/com/zy/asrs/controller/BasArmMastSignController.java
+++ b/src/main/java/com/zy/asrs/controller/BasArmMastSignController.java
@@ -54,9 +54,6 @@
                 String[] dates = val.split(RANGE_TIME_LINK);
                 wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
                 wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
-            } else if (entry.getKey().equals("create_time")){
-                long aLong = Long.parseLong(val);
-                wrapper.ge(entry.getKey(), aLong);
             } else {
                 wrapper.like(entry.getKey(), val);
             }
diff --git a/src/main/java/com/zy/asrs/controller/LocDetlController.java b/src/main/java/com/zy/asrs/controller/LocDetlController.java
index ad44284..026a1c2 100644
--- a/src/main/java/com/zy/asrs/controller/LocDetlController.java
+++ b/src/main/java/com/zy/asrs/controller/LocDetlController.java
@@ -210,7 +210,7 @@
                 wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
             } else {
                 if (entry.getKey().equals("locNo")) {
-                    wrapper.eq("loc_no", String.valueOf(entry.getValue()));
+                    wrapper.like("loc_no", String.valueOf(entry.getValue()));
                 } else {
                     wrapper.like(entry.getKey(), String.valueOf(entry.getValue()));
                 }
diff --git a/src/main/java/com/zy/asrs/controller/LocMastController.java b/src/main/java/com/zy/asrs/controller/LocMastController.java
index c914c92..0533bc1 100644
--- a/src/main/java/com/zy/asrs/controller/LocMastController.java
+++ b/src/main/java/com/zy/asrs/controller/LocMastController.java
@@ -95,13 +95,11 @@
                 String[] dates = val.split(RANGE_TIME_LINK);
                 wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
                 wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
-            } else if (entry.getKey().equals("loc_no")){
-                wrapper.like(entry.getKey(), val);
             } else {
                 if (entry.getKey().equals("loc_type1")){
                     sign=true;
                 }
-                wrapper.eq(entry.getKey(), val);
+                wrapper.like(entry.getKey(), val);
             }
         }
         if (sign){
diff --git a/src/main/java/com/zy/asrs/controller/ManLocDetlController.java b/src/main/java/com/zy/asrs/controller/ManLocDetlController.java
index 61e94e1..345fffd 100644
--- a/src/main/java/com/zy/asrs/controller/ManLocDetlController.java
+++ b/src/main/java/com/zy/asrs/controller/ManLocDetlController.java
@@ -101,7 +101,7 @@
                 wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
             } else {
                 if (entry.getKey().equals("locNo")) {
-                    wrapper.eq("loc_no", String.valueOf(entry.getValue()));
+                    wrapper.like("loc_no", String.valueOf(entry.getValue()));
                 } else {
                     wrapper.like(entry.getKey(), String.valueOf(entry.getValue()));
                 }
diff --git a/src/main/java/com/zy/asrs/controller/OpenController.java b/src/main/java/com/zy/asrs/controller/OpenController.java
index 42ea5ea..6e9425d 100644
--- a/src/main/java/com/zy/asrs/controller/OpenController.java
+++ b/src/main/java/com/zy/asrs/controller/OpenController.java
@@ -140,6 +140,21 @@
     }
 
     /**
+     * pause out order
+     */
+    @PostMapping("/order/pakout/pause/default/v1")
+    @AppAuth(memo = "pause out order")
+    public synchronized R pakoutOrderPause(@RequestHeader(required = false) String appkey,
+                                           @RequestBody OpenOrderPakoutPauseParam param,
+                                           HttpServletRequest request) {
+        auth(appkey, param, request);
+        if (Cools.isEmpty(param) || Cools.isEmpty(param.getOrderNo())) {
+            return R.error("orderNo is empty");
+        }
+        return openService.pakoutOrderPause(param);
+    }
+
+    /**
      * 鍑哄簱鍗曞洖鍐�
      */
 //    @PostMapping("/order/pakout/complete/default/v1")
@@ -448,7 +463,7 @@
             // 鍒ゆ柇鏄惁鏈夌浉鍚屾潯鐮佺殑鏁版嵁
             if (waitPakinService.selectCount(new EntityWrapper<WaitPakin>().
                     eq("zpallet", mesToCombParam.getPalletId()).eq("io_status", "N")) > 0) {
-                return R.error(mesToCombParam.getPalletId()+"-璇ユ墭鐩樼爜宸茬粡瀛樺湪缁勬墭妗d腑");
+                waitPakinService.delete(new EntityWrapper<WaitPakin>().eq("zpallet", mesToCombParam.getPalletId()));
             }
 
             if (mesToCombParam.getPalletId().length() != 8) {
@@ -483,7 +498,4 @@
         }
         return R.ok();
     }
-
-
-
 }
diff --git a/src/main/java/com/zy/asrs/controller/StaDescController.java b/src/main/java/com/zy/asrs/controller/StaDescController.java
index 3a6ac32..ac39f58 100644
--- a/src/main/java/com/zy/asrs/controller/StaDescController.java
+++ b/src/main/java/com/zy/asrs/controller/StaDescController.java
@@ -5,50 +5,59 @@
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.baomidou.mybatisplus.mapper.Wrapper;
 import com.baomidou.mybatisplus.plugins.Page;
-import com.zy.asrs.entity.StaDesc;
-import com.zy.asrs.entity.param.StaDescInitParam;
-import com.zy.asrs.mapper.StaDescMapper;
-import com.zy.asrs.service.StaDescService;
-import com.zy.common.web.BaseController;
 import com.core.annotations.ManagerAuth;
 import com.core.common.BaseRes;
 import com.core.common.Cools;
 import com.core.common.DateUtils;
 import com.core.common.R;
-import org.apache.ibatis.session.ExecutorType;
-import org.apache.ibatis.session.SqlSession;
-import org.apache.ibatis.session.SqlSessionFactory;
+import com.zy.asrs.entity.StaDesc;
+import com.zy.asrs.entity.param.StaDescInitParam;
+import com.zy.asrs.service.StaDescService;
+import com.zy.common.web.BaseController;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 @RestController
 public class StaDescController extends BaseController {
 
     private static final Logger log = LoggerFactory.getLogger(StaDescController.class);
+
     @Autowired
     private StaDescService staDescService;
-    @Autowired
-    private SqlSessionFactory sqlSessionFactory;
 
     @RequestMapping(value = "/staDesc/init/auth")
     @ManagerAuth(memo = "鍒濆鍖栫珯鐐硅矾寰�")
+    @Transactional(rollbackFor = Exception.class)
     public R init(StaDescInitParam param) {
-        try{
-            if (param.getTypeDesc()==1){
+        try {
+            if (param.getTypeDesc() == 1) {
                 staDescService.delete(new EntityWrapper<>());
             }
             String[] startStaList = param.getStartStaList().split(";");
             String[] endStaList = param.getEndStaList().split(";");
-            List<StaDesc> staDescList = new ArrayList<>();
-            SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH,false);
-            StaDescMapper sqlSessionMapper = sqlSession.getMapper(StaDescMapper.class);
-            for (String startSta : startStaList){
-                for (String endSta : endStaList){
-                    for (Integer type:param.getType()){
+            Set<String> requestKeys = new HashSet<>();
+            for (String startSta : startStaList) {
+                for (String endSta : endStaList) {
+                    for (Integer type : param.getType()) {
+                        String uniqueKey = type + "_" + startSta + "_" + param.getCrnNo() + "_" + endSta;
+                        if (!requestKeys.add(uniqueKey)) {
+                            continue;
+                        }
                         int sameRes = staDescService.selectCount(new EntityWrapper<StaDesc>()
                                 .eq("type_no", type)
                                 .eq("stn_no", Integer.parseInt(startSta))
@@ -66,22 +75,13 @@
                         staDesc.setModiTime(new Date());
                         staDesc.setAppeUser(getUserId());
                         staDesc.setAppeTime(new Date());
-//                        staDescList.add(staDesc);
-                        sqlSessionMapper.insert(staDesc);
-
+                        staDescService.insert(staDesc);
                     }
                 }
             }
-            try{
-                sqlSession.commit();
-                sqlSession.close();
-            }catch (Exception e){
-                log.error("鍒濆鍖栫珯鐐硅矾寰勫紓甯�===>sql寮傚父锛歿}",e.getMessage());
-            }
-//            staDescService.insertBatch(staDescList);
-        }catch (Exception e){
-            log.error("鍒濆鍖栫珯鐐硅矾寰勫紓甯革細{}",e.getMessage());
-            return R.error("鍒濆鍖栫珯鐐硅矾寰勫紓甯革細"+e.getMessage());
+        } catch (Exception e) {
+            log.error("鍒濆鍖栫珯鐐硅矾寰勫紓甯革細{}", e.getMessage(), e);
+            return R.error("鍒濆鍖栫珯鐐硅矾寰勫紓甯革細" + e.getMessage());
         }
 
         return R.ok("ok1").add("ok2");
@@ -95,22 +95,24 @@
 
     @RequestMapping(value = "/staDesc/list/auth")
     @ManagerAuth
-    public R list(@RequestParam(defaultValue = "1")Integer curr,
-                  @RequestParam(defaultValue = "10")Integer limit,
-                  @RequestParam(required = false)String orderByField,
-                  @RequestParam(required = false)String orderByType,
-                  @RequestParam Map<String, Object> param){
+    public R list(@RequestParam(defaultValue = "1") Integer curr,
+                  @RequestParam(defaultValue = "10") Integer limit,
+                  @RequestParam(required = false) String orderByField,
+                  @RequestParam(required = false) String orderByType,
+                  @RequestParam Map<String, Object> param) {
         excludeTrash(param);
         EntityWrapper<StaDesc> wrapper = new EntityWrapper<>();
         convert(param, wrapper);
-        if (!Cools.isEmpty(orderByField)){wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));}
+        if (!Cools.isEmpty(orderByField)) {
+            wrapper.orderBy(humpToLine(orderByField), "asc".equals(orderByType));
+        }
         return R.ok(staDescService.selectPage(new Page<>(curr, limit), wrapper));
     }
 
-    private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper){
-        for (Map.Entry<String, Object> entry : map.entrySet()){
+    private <T> void convert(Map<String, Object> map, EntityWrapper<T> wrapper) {
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
             String val = String.valueOf(entry.getValue());
-            if (val.contains(RANGE_TIME_LINK)){
+            if (val.contains(RANGE_TIME_LINK)) {
                 String[] dates = val.split(RANGE_TIME_LINK);
                 wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
                 wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
@@ -139,10 +141,10 @@
         return R.ok();
     }
 
-	@RequestMapping(value = "/staDesc/update/auth")
-	@ManagerAuth(memo = "绔欑偣璺緞淇敼")
-    public R update(StaDesc staDesc){
-        if (Cools.isEmpty(staDesc) || null==staDesc.getTypeId()){
+    @RequestMapping(value = "/staDesc/update/auth")
+    @ManagerAuth(memo = "绔欑偣璺緞淇敼")
+    public R update(StaDesc staDesc) {
+        if (Cools.isEmpty(staDesc) || null == staDesc.getTypeId()) {
             return R.error();
         }
         staDesc.setModiUser(getUserId());
@@ -153,12 +155,12 @@
 
     @RequestMapping(value = "/staDesc/delete/auth")
     @ManagerAuth(memo = "绔欑偣璺緞鍒犻櫎")
-    public R delete(@RequestParam String param){
+    public R delete(@RequestParam String param) {
         List<StaDesc> list = JSONArray.parseArray(param, StaDesc.class);
-        if (Cools.isEmpty(list)){
+        if (Cools.isEmpty(list)) {
             return R.error();
         }
-        for (StaDesc entity : list){
+        for (StaDesc entity : list) {
             staDescService.delete(new EntityWrapper<>(entity));
         }
         return R.ok();
@@ -166,7 +168,7 @@
 
     @RequestMapping(value = "/staDesc/export/auth")
     @ManagerAuth(memo = "绔欑偣璺緞瀵煎嚭")
-    public R export(@RequestBody JSONObject param){
+    public R export(@RequestBody JSONObject param) {
         List<String> fields = JSONObject.parseArray(param.getJSONArray("fields").toJSONString(), String.class);
         EntityWrapper<StaDesc> wrapper = new EntityWrapper<>();
         Map<String, Object> map = excludeTrash(param.getJSONObject("staDesc"));
@@ -182,7 +184,7 @@
         wrapper.like("crn_no", condition);
         Page<StaDesc> page = staDescService.selectPage(new Page<>(0, 10), wrapper);
         List<Map<String, Object>> result = new ArrayList<>();
-        for (StaDesc staDesc : page.getRecords()){
+        for (StaDesc staDesc : page.getRecords()) {
             Map<String, Object> map = new HashMap<>();
             map.put("id", staDesc.getCrnNo());
             map.put("value", staDesc.getCrnNo());
@@ -195,10 +197,9 @@
     @ManagerAuth
     public R query(@RequestBody JSONObject param) {
         Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>().eq(humpToLine(String.valueOf(param.get("key"))), param.get("val"));
-        if (null != staDescService.selectOne(wrapper)){
+        if (null != staDescService.selectOne(wrapper)) {
             return R.parse(BaseRes.REPEAT).add(getComment(StaDesc.class, String.valueOf(param.get("key"))));
         }
         return R.ok();
     }
-
 }
diff --git a/src/main/java/com/zy/asrs/controller/WrkMastController.java b/src/main/java/com/zy/asrs/controller/WrkMastController.java
index 3a6a9c5..7fa4e46 100644
--- a/src/main/java/com/zy/asrs/controller/WrkMastController.java
+++ b/src/main/java/com/zy/asrs/controller/WrkMastController.java
@@ -61,7 +61,7 @@
                 wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
                 wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
             } else {
-                wrapper.eq(entry.getKey(), val);
+                wrapper.like(entry.getKey(), val);
             }
         }
     }
diff --git a/src/main/java/com/zy/asrs/controller/WrkMastLogController.java b/src/main/java/com/zy/asrs/controller/WrkMastLogController.java
index a6fae62..2e9a168 100644
--- a/src/main/java/com/zy/asrs/controller/WrkMastLogController.java
+++ b/src/main/java/com/zy/asrs/controller/WrkMastLogController.java
@@ -87,11 +87,7 @@
                 wrapper.ge(entry.getKey(), DateUtils.convert(dates[0]));
                 wrapper.le(entry.getKey(), DateUtils.convert(dates[1]));
             } else {
-                if (entry.getKey().equals("manu_type")) {
-                    wrapper.like(entry.getKey(), val);
-                } else {
-                    wrapper.eq(entry.getKey(), val);
-                }
+                wrapper.like(entry.getKey(), val);
             }
         }
     }
diff --git a/src/main/java/com/zy/asrs/entity/param/MesToCombParam.java b/src/main/java/com/zy/asrs/entity/param/MesToCombParam.java
index e6a2346..1576293 100644
--- a/src/main/java/com/zy/asrs/entity/param/MesToCombParam.java
+++ b/src/main/java/com/zy/asrs/entity/param/MesToCombParam.java
@@ -29,4 +29,6 @@
     private Integer operateType;
     //鍞竴鐮�
     private String BizNo;
+    //鏄惁鏁h揣锛�0 闈炴暎璐э紱1 鏁h揣锛涗负浜嗙鎺у嚭璐ч�熺巼锛屾暎璐у彲浠ュ嚭鎱㈢偣銆�
+    private Integer package1;
 }
diff --git a/src/main/java/com/zy/asrs/enums/CommonEnum.java b/src/main/java/com/zy/asrs/enums/CommonEnum.java
new file mode 100644
index 0000000..e2fcbf9
--- /dev/null
+++ b/src/main/java/com/zy/asrs/enums/CommonEnum.java
@@ -0,0 +1,25 @@
+package com.zy.asrs.enums;
+
+/**
+ * @author Ryan
+ * @date 2025/9/25
+ * @description: 閫氱敤绫诲瀷鏋氫妇
+ * @version 1.0
+ */
+public enum CommonEnum {
+
+    //閫氱敤绫诲瀷
+    COMMON_ENUM_Y(1, "鏄�"),
+    //閫氱敤
+    COMMON_ENUM_N(0, "鍚�");
+
+    public Integer type;
+
+    public String desc;
+
+    CommonEnum(Integer type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+}
diff --git a/src/main/java/com/zy/asrs/enums/ContainerType.java b/src/main/java/com/zy/asrs/enums/ContainerType.java
new file mode 100644
index 0000000..379d1aa
--- /dev/null
+++ b/src/main/java/com/zy/asrs/enums/ContainerType.java
@@ -0,0 +1,27 @@
+package com.zy.asrs.enums;
+
+public enum ContainerType {
+
+    //鏂欑
+    CONTAINER_TYPE_BOX("12", "鏂欑"),
+    //鎵樼洏
+    CONTAINER_TYPE_SALVER("14", "鎵樼洏"),
+
+    CONTAINER_TYPE_CAGE("13", "绗兼"),
+
+    CONTAINER_TYPE_CAR("3", "鍙拌溅"),
+    ;
+
+    public Long type;
+
+    public String desc;
+
+    ContainerType(String type, String desc) {
+        this.type = Long.valueOf(type);
+        this.desc = desc;
+    }
+
+
+
+
+}
diff --git a/src/main/java/com/zy/asrs/enums/LocStsType.java b/src/main/java/com/zy/asrs/enums/LocStsType.java
new file mode 100644
index 0000000..fe48c4d
--- /dev/null
+++ b/src/main/java/com/zy/asrs/enums/LocStsType.java
@@ -0,0 +1,60 @@
+package com.zy.asrs.enums;
+
+public enum LocStsType {
+
+    //绌烘澘
+    LOC_STS_TYPE_D("D", "绌烘澘"),
+    //鍦ㄥ簱
+    LOC_STS_TYPE_F("F", "鍦ㄥ簱"),
+    //绌哄簱
+    LOC_STS_TYPE_O("O", "绌哄簱"),
+    //绂佺敤
+    LOC_STS_TYPE_X("X", "绂佺敤"),
+    //鍏ュ簱棰勭害
+    LOC_STS_TYPE_S("S", "鍏ュ簱棰勭害"),
+    //鍑哄簱棰勭害
+    LOC_STS_TYPE_R("R", "鍑哄簱棰勭害"),
+    ;
+
+    public String type;
+
+    public String desc;
+
+    LocStsType(String type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+
+    public static LocStsType get(String el) {
+        for (LocStsType value : LocStsType.values()) {
+            if (el.equals(value.toString())) {
+                return value;
+            }
+        }
+        return null;
+    }
+
+//    /**
+//     * @author Ryan
+//     * @date 2025/8/28
+//     * @description: RCS搴撲綅鐘舵�佽浆鎹�
+//     * @version 1.0
+//     */
+//    public static String getLocSts(String val) {
+//        if (val.equals(RcsLocStsType.LOC_STS_TYPE_D.type)) {
+//            return LocStsType.LOC_STS_TYPE_O.type;
+//        } else if (val.equals(RcsLocStsType.LOC_STS_TYPE_F.type)) {
+//            return LocStsType.LOC_STS_TYPE_F.type;
+//        } else if (val.equals(RcsLocStsType.LOC_STS_TYPE_S.type)) {
+//            return LocStsType.LOC_STS_TYPE_S.type;
+//        } else if (val.equals(RcsLocStsType.LOC_STS_TYPE_R.type)) {
+//            return LocStsType.LOC_STS_TYPE_R.type;
+//        } else if (val.equals(RcsLocStsType.LOC_STS_TYPE_X.type)) {
+//            return LocStsType.LOC_STS_TYPE_X.type;
+//        }
+//        return null;
+//    }
+
+
+}
diff --git a/src/main/java/com/zy/asrs/enums/MatTagType.java b/src/main/java/com/zy/asrs/enums/MatTagType.java
new file mode 100644
index 0000000..dbf9a6d
--- /dev/null
+++ b/src/main/java/com/zy/asrs/enums/MatTagType.java
@@ -0,0 +1,20 @@
+package com.zy.asrs.enums;
+
+public enum MatTagType {
+    //涓欢
+    MAT_TAGT_YPE_MIDDLE("13", "涓欢"),
+    //灏忎欢
+    MAT_TAGT_YPE_SMALL("12", "灏忎欢"),
+    //婊よ姱
+    MAT_TAGT_YPE_XIN("14", "婊よ姱")
+    ;
+
+    public String id;
+
+    public String type;
+
+    MatTagType(String id, String type) {
+        this.type = type;
+        this.id = id;
+    }
+}
diff --git a/src/main/java/com/zy/asrs/service/OpenService.java b/src/main/java/com/zy/asrs/service/OpenService.java
index e8cfe03..8e16e40 100644
--- a/src/main/java/com/zy/asrs/service/OpenService.java
+++ b/src/main/java/com/zy/asrs/service/OpenService.java
@@ -26,6 +26,11 @@
     void pakoutOrderCreate(OpenOrderPakoutParam param);
 
     /**
+     * pause out order
+     */
+    R pakoutOrderPause(OpenOrderPakoutPauseParam param);
+
+    /**
      * 鍏ュ簱鍗曞洖鍐�
      */
     List<OpenOrderCompeteResult> pakoutOrderComplete(OpenOrderCompleteParam param);
diff --git a/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
index 77aec40..15d88ba 100644
--- a/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
@@ -2,6 +2,8 @@
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.zy.api.controller.params.StopOutTaskParams;
+import com.zy.api.service.WcsApiService;
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.core.common.*;
 import com.core.exception.CoolException;
@@ -31,6 +33,7 @@
 
 import javax.rmi.CORBA.Util;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * Created by vincent on 2022/4/9
@@ -87,6 +90,8 @@
     private WaitPakinService waitPakinService;
     @Autowired
     private WrkMastService wrkMastService;
+    @Autowired
+    private WcsApiService wcsApiService;
 
     @Override
     @Transactional
@@ -358,6 +363,107 @@
                 throw new CoolException("鐢熸垚鍗曟嵁鏄庣粏澶辫触锛岃鑱旂郴绠$悊鍛�");
             }
         }
+    }
+
+    @Override
+    @Transactional
+    public R pakoutOrderPause(OpenOrderPakoutPauseParam param) {
+        if (param == null || Cools.isEmpty(param.getOrderNo())) {
+            throw new CoolException("orderNo is empty");
+        }
+        Order order = orderService.selectByNo(param.getOrderNo());
+        if (order == null) {
+            order = OrderInAndOutUtil.selectByNo(Boolean.FALSE, param.getOrderNo());
+        }
+        if (order == null) {
+            throw new CoolException("order not found: " + param.getOrderNo());
+        }
+
+        List<WrkMast> activeTasks = findActiveOutboundTasks(param.getOrderNo());
+        if (activeTasks.isEmpty()) {
+            return R.ok("no active out tasks");
+        }
+
+        Date now = new Date();
+        int pausedCount = 0;
+        List<WrkMast> issuedTasks = new ArrayList<>();
+        for (WrkMast wrkMast : activeTasks) {
+            if (wrkMast == null || "Y".equalsIgnoreCase(wrkMast.getPauseMk())) {
+                continue;
+            }
+            wrkMast.setPauseMk("Y");
+            wrkMast.setUpdMk(needNotifyWcsStop(wrkMast) ? "WCS_STOP_REQUESTED" : "WMS_PAUSED");
+            wrkMast.setManuType("ERP_PAUSE");
+            wrkMast.setModiTime(now);
+            wrkMast.setModiUser(9527L);
+            if (!wrkMastService.updateById(wrkMast)) {
+                throw new CoolException("pause out task failed: " + wrkMast.getWrkNo());
+            }
+            pausedCount++;
+            if (needNotifyWcsStop(wrkMast)) {
+                issuedTasks.add(wrkMast);
+            }
+        }
+
+        if (pausedCount == 0) {
+            return R.ok("tasks already paused");
+        }
+
+        if (!issuedTasks.isEmpty()) {
+            wcsApiService.pauseOutTasks(buildStopOutTaskParams(param, issuedTasks));
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("orderNo", param.getOrderNo());
+        result.put("pausedCount", pausedCount);
+        result.put("wcsStopCount", issuedTasks.size());
+        return R.ok("pause out success").add(result);
+    }
+
+    private List<WrkMast> findActiveOutboundTasks(String orderNo) {
+        List<WrkDetl> wrkDetls = wrkDetlService.selectList(new EntityWrapper<WrkDetl>().eq("order_no", orderNo));
+        if (wrkDetls == null || wrkDetls.isEmpty()) {
+            return Collections.emptyList();
+        }
+        Set<Integer> wrkNos = wrkDetls.stream()
+                .map(WrkDetl::getWrkNo)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (wrkNos.isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+                .in("wrk_no", wrkNos)
+                .in("io_type", Arrays.asList(101, 108, 110))
+                .lt("wrk_sts", 14L));
+        if (wrkMasts == null || wrkMasts.isEmpty()) {
+            return Collections.emptyList();
+        }
+        wrkMasts.sort(Comparator.comparing(WrkMast::getWrkNo));
+        return wrkMasts;
+    }
+
+    private boolean needNotifyWcsStop(WrkMast wrkMast) {
+        return wrkMast != null
+                && wrkMast.getWrkSts() != null
+                && wrkMast.getWrkSts() >= 12L
+                && wrkMast.getWrkSts() < 14L;
+    }
+
+    private StopOutTaskParams buildStopOutTaskParams(OpenOrderPakoutPauseParam param, List<WrkMast> wrkMasts) {
+        StopOutTaskParams stopParams = new StopOutTaskParams();
+        stopParams.setOrderNo(param.getOrderNo());
+        stopParams.setReason(param.getReason());
+        for (WrkMast wrkMast : wrkMasts) {
+            StopOutTaskParams.TaskItem item = new StopOutTaskParams.TaskItem();
+            item.setTaskNo(String.valueOf(wrkMast.getWrkNo()));
+            if (wrkMast.getStaNo() != null) {
+                item.setStaNo(String.valueOf(wrkMast.getStaNo()));
+            }
+            item.setLocNo(wrkMast.getSourceLocNo());
+            stopParams.getTasks().add(item);
+        }
+        return stopParams;
     }
 
     @Override
@@ -1037,28 +1143,21 @@
 
         Mat mat = matService.selectByMatnr(param.getMatnr());
         if (Cools.isEmpty(mat)) {
-            if (Cools.isEmpty(param.getFull())) {
-                if (param.getAnfme() == 0) {
-                    //绌烘墭鐩�
-                    mat = matService.selectByMatnr("0");
-                } else {
-                    //婊℃墭鐩�
-                    mat = matService.selectByMatnr("1");
-                }
-            } else {
-                if (param.getFull()==1){
-                    //婊℃墭鐩�
-                    mat = matService.selectByMatnr("1");
-                }else if (param.getFull()==0){
-                    //绌烘墭鐩�
-                    mat = matService.selectByMatnr("0");
-                }
+
+            if (param.getFull() == 1) {
+                //婊℃墭鐩�
+                mat = matService.selectByMatnr(param.getMatnr());
+            } else if (param.getFull() == 0) {
+                //绌烘墭鐩�
+                mat = matService.selectByMatnr("emptyPallet");
             }
         }
+
         WaitPakin waitPakin = new WaitPakin();
         waitPakin.sync(mat);
         waitPakin.setBatch(String.valueOf(param.getBatchId()));
         waitPakin.setZpallet(param.getPalletId());   // 鎵樼洏鐮�
+
         waitPakin.setIoStatus("N");     // 鍏ュ嚭鐘舵��
         waitPakin.setAnfme(param.getAnfme());  // 鏁伴噺
         waitPakin.setStatus("Y");    // 鐘舵��
@@ -1070,6 +1169,7 @@
         waitPakin.setOrigin(String.valueOf(param.getStorageArea()));//寤鸿鍏ュ簱鍖哄煙
         waitPakin.setManu(String.valueOf(param.getLocId()));//mes鍏蜂綋搴撲綅缂栧彿
         waitPakin.setThreeCode(param.getBizNo());
+        waitPakin.setBeBatch(param.getPackage1());//鏄惁鏁h揣锛�0 闈炴暎璐э紱1 鏁h揣锛涗负浜嗙鎺у嚭璐ч�熺巼锛屾暎璐у彲浠ュ嚭鎱㈢偣銆�
         if (!waitPakinService.insert(waitPakin)) {
             throw new CoolException("淇濆瓨鍏ュ簱閫氱煡妗eけ璐�");
         }
@@ -1080,7 +1180,7 @@
     public R outOrder(OutTaskParam param) {
         LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", "F").eq("barcode", param.getPalletId()));
         if (locMast == null) {
-            return R.error("娌℃湁鎵惧埌鎵樼洏鐮�="+param.getPalletId()+"瀵瑰簲鐨勫簱浣�");
+            return R.error("娌℃湁鎵惧埌鎵樼洏鐮�=" + param.getPalletId() + "瀵瑰簲鐨勫簱浣�");
         }
         Integer ioType = 101;
         // 鑾峰彇璺緞
@@ -1113,11 +1213,11 @@
         wrkMast.setModiUser(9995L);
         wrkMast.setModiTime(now);
         if (!wrkMastService.insert(wrkMast)) {
-            throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐ワ紝鍑哄簱搴撲綅鍙凤細"+locMast.getLocNo());
+            throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐ワ紝鍑哄簱搴撲綅鍙凤細" + locMast.getLocNo());
         }
         List<LocDetl> locNo = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no", locMast.getLocNo()));
         if (locNo == null || locNo.size() == 0) {
-            throw new CoolException("鏌ヨ搴撳瓨鏄庣粏澶辫触锛屽嚭搴撳簱浣嶅彿锛�"+locMast.getLocNo());
+            throw new CoolException("鏌ヨ搴撳瓨鏄庣粏澶辫触锛屽嚭搴撳簱浣嶅彿锛�" + locMast.getLocNo());
         }
         // 鐢熸垚宸ヤ綔妗f槑缁�
         for (LocDetl locDetl : locNo) {
@@ -1144,7 +1244,7 @@
             locMast.setModiUser(9995L);
             locMast.setModiTime(now);
             if (!locMastService.updateById(locMast)) {
-                throw new CoolException("棰勭害搴撲綅鐘舵�佸け璐ワ紝搴撲綅鍙凤細"+locMast.getLocNo());
+                throw new CoolException("棰勭害搴撲綅鐘舵�佸け璐ワ紝搴撲綅鍙凤細" + locMast.getLocNo());
             }
         } else {
             log.error(locMast.getLocNo() + "搴撲綅涓嶆槸鍦ㄥ簱鐘舵��");
diff --git a/src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
index 7ae931d..e7e15e9 100644
--- a/src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/WorkServiceImpl.java
@@ -1660,7 +1660,7 @@
         }
         LocTypeDto locTypeDto = new LocTypeDto();
         locTypeDto.setLocType1((short) 1);
-        return wcsController.startupFullPutStore(301, list.get(0).getZpallet(), locTypeDto, list);
+        return wcsController.startupFullPutStore(301, list.get(0).getZpallet(), locTypeDto, list, null);
     }
 
     @Override
diff --git a/src/main/java/com/zy/asrs/task/AutomaticallyIssueWCSTasksScheduler.java b/src/main/java/com/zy/asrs/task/AutomaticallyIssueWCSTasksScheduler.java
index f177901..9002363 100644
--- a/src/main/java/com/zy/asrs/task/AutomaticallyIssueWCSTasksScheduler.java
+++ b/src/main/java/com/zy/asrs/task/AutomaticallyIssueWCSTasksScheduler.java
@@ -27,6 +27,7 @@
         List<WrkMast> wrkMasts = wrkMastService.selectList(
                 new com.baomidou.mybatisplus.mapper.EntityWrapper<WrkMast>()
                         .eq("wrk_sts", 11)
+                        .last(" and (pause_mk is null or pause_mk <> 'Y')")
         );
         if (wrkMasts.isEmpty()) {
             return;
diff --git a/src/main/java/com/zy/asrs/task/WorkMastScheduler.java b/src/main/java/com/zy/asrs/task/WorkMastScheduler.java
index 9a9065f..10bffd4 100644
--- a/src/main/java/com/zy/asrs/task/WorkMastScheduler.java
+++ b/src/main/java/com/zy/asrs/task/WorkMastScheduler.java
@@ -26,33 +26,6 @@
     @Autowired
     private WorkMastHandler workMastHandler;
 
-    /**
-     * wcs涓婃姤浠诲姟瀹屾垚鍚庯紝灏嗕换鍔′笂鎶ョ粰erp
-     * 2.鍏ュ簱涓婃姤
-     * 13.鍑哄簱涓婃姤
-     */
-    @Scheduled(cron = "0/3 * * * * ? ")
-    private void execute1(){
-        List<WrkMast> wrkMasts = wrkMastService.selectList(
-                new com.baomidou.mybatisplus.mapper.EntityWrapper<WrkMast>()
-                        .in("wrk_sts", 2, 13)
-        );
-        if (wrkMasts.isEmpty()) {
-            return;
-        }
-        for (WrkMast wrkMast : wrkMasts) {
-            ReturnT<String> returnT = workMastHandler.start1(wrkMast);
-            if (!returnT.isSuccess()) {
-                wrkMast.setUpdMk("X");
-                wrkMast.setErrorMemo(returnT.getMsg());
-                wrkMast.setErrorTime(new Date());
-                if (!wrkMastService.updateById(wrkMast)) {
-                    log.error("宸ヤ綔妗workNo={}]鏍囪寰呭鐞嗗け璐�", wrkMast.getWrkNo());
-                }
-            }
-        }
-    }
-
     @Scheduled(cron = "0/3 * * * * ? ")
     private void execute(){
         List<WrkMast> wrkMasts = wrkMastService.selectToBeCompleteData();
diff --git a/src/main/java/com/zy/asrs/task/handler/AutomaticallyIssueWCSTasksHandler.java b/src/main/java/com/zy/asrs/task/handler/AutomaticallyIssueWCSTasksHandler.java
index b47a30e..c642e7f 100644
--- a/src/main/java/com/zy/asrs/task/handler/AutomaticallyIssueWCSTasksHandler.java
+++ b/src/main/java/com/zy/asrs/task/handler/AutomaticallyIssueWCSTasksHandler.java
@@ -48,6 +48,9 @@
             for (WrkMast m : wrkMast) {
                 if (m == null) { continue; }
                 if (Objects.equals(m.getWrkSts(), 11L)) {
+                    if ("Y".equalsIgnoreCase(m.getPauseMk())) {
+                        continue;
+                    }
                     if (m.getUpdMk() != null && "WCS_SENT".equalsIgnoreCase(m.getUpdMk())) {
                         continue;
                     }
diff --git a/src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java b/src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java
index 7e2a3df..aa515c1 100644
--- a/src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java
+++ b/src/main/java/com/zy/asrs/task/handler/WorkMastHandler.java
@@ -1,22 +1,25 @@
 package com.zy.asrs.task.handler;
 
-import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.core.common.Cools;
+import com.core.exception.CoolException;
 import com.zy.asrs.entity.*;
+import com.zy.asrs.enums.LocStsType;
 import com.zy.asrs.service.*;
+import com.zy.asrs.service.impl.*;
 import com.zy.asrs.task.AbstractHandler;
 import com.zy.asrs.task.core.ReturnT;
+import com.zy.common.entity.Parameter;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
-import springfox.documentation.spring.web.json.Json;
 
-import java.util.Date;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * Created by vincent on 2020/7/4
@@ -25,15 +28,6 @@
 @Service
 @Transactional
 public class WorkMastHandler extends AbstractHandler<String> {
-
-    @Value("${erp.address.URL}")
-    private String erpBaseUrl;
-
-    @Value("${erp.address.Inaddress}")
-    private String erpInAddress;
-
-    @Value("${erp.address.Outaddress}")
-    private String erpOutAddress;
 
     @Autowired
     private WrkMastService wrkMastService;
@@ -51,19 +45,57 @@
     private OrderDetlPakinService orderDetlPakinService;
     @Autowired
     private OrderDetlPakoutService orderDetlPakoutService;
+    @Autowired
+    private OrderPakinService orderPakinService;
+    @Autowired
+    private WorkService workService;
+
+    @Value("${erp.switch.ErpReportOld}")
+    private boolean erpReportOld;
 
     public ReturnT<String> start(WrkMast wrkMast) {
         // 4.鍏ュ簱瀹屾垚
         if (wrkMast.getWrkSts() == 4) {
             return doIn(wrkMast);
-        // 14.鍑哄簱瀹屾垚
-        } else  if (wrkMast.getWrkSts() == 14) {
+            // 14.鍑哄簱瀹屾垚
+        } else if (wrkMast.getWrkSts() == 14) {
             return doOut(wrkMast);
         }
         return SUCCESS;
     }
 
-    private ReturnT<String> doIn(WrkMast wrkMast){
+
+    private boolean needInboundErpReport(WrkMast wrkMast) {
+        if (!erpReportOld) {
+            return false;
+        }
+        String erpReport = Parameter.get().getErpReport();
+        if (!Cools.isEmpty(erpReport) && !"true".equalsIgnoreCase(erpReport)) {
+            return false;
+        }
+        if (wrkMast == null || Cools.isEmpty(wrkMast.getBarcode())) {
+            return false;
+        }
+        Integer ioType = wrkMast.getIoType();
+        return ioType != null && (ioType == 1 || ioType == 8 || ioType == 53 || ioType == 54 || ioType == 57);
+    }
+
+    private boolean needOutboundErpReport(WrkMast wrkMast) {
+        if (!erpReportOld) {
+            return false;
+        }
+        String erpReport = Parameter.get().getErpReport();
+        if (!Cools.isEmpty(erpReport) && !"true".equalsIgnoreCase(erpReport)) {
+            return false;
+        }
+        if (wrkMast == null || Cools.isEmpty(wrkMast.getBarcode())) {
+            return false;
+        }
+        Integer ioType = wrkMast.getIoType();
+        return ioType != null && (ioType == 101 || ioType == 108 || ioType == 110);
+    }
+
+    public ReturnT<String> doIn(WrkMast wrkMast) {
         Date now = new Date();
         LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
         try {
@@ -107,12 +139,11 @@
                     }
                     // 閬嶅巻宸ヤ綔鏄庣粏锛屾洿鏂板簱瀛樻槑缁嗗拰鍏ュ簱閫氱煡妗�
                     for (WrkDetl wrkDetl : wrkDetls) {
-
-                        LocDetl locDetl = locDetlService.selectItem(locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand()
-                        ,wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3());
+                        LocDetl locDetl = locDetlService.selectItem(locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand()
+                                , wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(), wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
                         if (null != locDetl) {
-                            if (!locDetlService.updateAnfme(wrkDetl.getAnfme(), wrkMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3()
-                            ,wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3())) {
+                            if (!locDetlService.updateAnfme(wrkDetl.getAnfme(), wrkMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3()
+                                    , wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3())) {
 //                                exceptionHandle("鍏ㄦ澘鍏ュ簱 ===>> 鏇存柊搴撳瓨鏄庣粏澶辫触锛沎workNo={0}],[locNo={1}]", wrkMast.getWrkNo(), wrkMast.getLocNo());
                                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                                 return FAIL.setMsg("鍏ㄦ澘鍏ュ簱 ===>> 鏇存柊搴撳瓨鏄庣粏澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]");
@@ -125,45 +156,12 @@
                             locDetl.setZpallet(wrkDetl.getZpallet()); // 鎵樼洏鏉$爜
                             locDetl.setModiTime(now);
                             locDetl.setAppeTime(now);
-                            locDetl.setOrigin("鍦ㄥ簱");
                             if (!locDetlService.insert(locDetl)) {
 //                                exceptionHandle("鍏ㄦ澘鍏ュ簱 ===>> 娣诲姞搴撳瓨鏄庣粏澶辫触锛沎workNo={0}],[locNo={1}]", wrkMast.getWrkNo(), wrkMast.getLocNo());
                                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                                 return FAIL.setMsg("鍏ㄦ澘鍏ュ簱 ===>> 娣诲姞搴撳瓨鏄庣粏澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]");
                             }
                         }
-
-                        if (!Cools.isEmpty(wrkDetl.getOrderNo())){
-                            log.info("杩涘叆鍏ュ簱浠诲姟瀹屾垚锛屽甫璁㈠崟:"+ JSON.toJSONString(wrkDetl));
-                            // 鏇存柊璁㈠崟瀹屾垚鏁伴噺
-                            OrderDetlPakin orderDetlPakin = orderDetlPakinService.selectItem
-                                    (wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
-                                            wrkDetl.getBatch(), wrkDetl.getBrand(),
-                                            wrkDetl.getStandby1(), wrkDetl.getStandby2(),wrkDetl.getStandby3(),
-                                            wrkDetl.getBoxType1(),wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
-                            if (orderDetlPakin==null){
-                                log.info("杩涘叆鍏ュ簱浠诲姟瀹屾垚锛屾煡璇㈣鍗曞け璐�:"+ JSON.toJSONString(wrkDetl));
-
-                                orderDetlPakin = orderDetlPakinService.selectItem
-                                        (wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
-                                                wrkDetl.getBatch(), wrkDetl.getBrand(),
-                                                wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),
-                                                wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3());
-                            }
-                            try {
-                                if(!Cools.isEmpty(orderDetlPakin)){
-                                    if(!orderDetlPakinService.increaseQtyByOrderNo(wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
-                                            orderDetlPakin.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),
-                                            wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3(),wrkDetl.getAnfme())){
-//                                    exceptionHandle("鍏ㄦ澘鍏ュ簱 ===>> 鏇存柊璁㈠崟瀹屾垚鏁伴噺澶辫触锛沎workNo={0}],[locNo={1}]",
-//                                            wrkMast.getWrkNo(), wrkMast.getLocNo());
-                                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-                                        return FAIL.setMsg("鍏ㄦ澘鍏ュ簱 ===>> 鏇存柊璁㈠崟瀹屾垚鏁伴噺澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]");
-                                    }
-                                }
-                            } catch (Exception ignore){}
-                        }
-
                     }
                     // 淇敼搴撲綅鐘舵�� S ====>> F
                     if (locMast.getLocSts().equals("S")) {
@@ -188,7 +186,6 @@
                     }
                     // 閬嶅巻宸ヤ綔鏄庣粏锛屾洿鏂板簱瀛樻槑缁嗗拰鍏ュ簱閫氱煡妗�
                     for (WrkDetl wrkDetl : wrkDetls8) {
-
                         LocDetl locDetl = locDetlService.selectItem(locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand()
                                 , wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(), wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
                         if (null != locDetl) {
@@ -233,40 +230,39 @@
                     }
                     for (WrkDetl wrkDetl : wrkDetls53) {
 
-                        LocDetl locDetl = locDetlService.selectItem(locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand()
-                                ,wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3());
+                        LocDetl locDetl = locDetlService.selectItem(locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand()
+                                , wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(), wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
                         if (null != locDetl) {
-                            if (!locDetlService.updateAnfme(locDetl.getAnfme() - wrkDetl.getAnfme(), locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3()
-                                    ,wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3())) {
+                            if (!locDetlService.updateAnfme(locDetl.getAnfme() - wrkDetl.getAnfme(), locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3()
+                                    , wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3())) {
 //                                exceptionHandle("鎷f枡鍏ュ簱 ===>> 淇敼搴撳瓨鏄庣粏鏁伴噺澶辫触锛沎workNo={0}],[locNo={1}]", wrkMast.getWrkNo(), wrkMast.getLocNo());
                                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                                 return FAIL.setMsg("鎷f枡鍏ュ簱 ===>> 淇敼搴撳瓨鏄庣粏鏁伴噺澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]");
                             }
                         }
 
-                        if (!Cools.isEmpty(wrkDetl.getOrderNo())){
-                            // 鏇存柊璁㈠崟瀹屾垚鏁伴噺
-                            OrderDetlPakout orderDetlPakout = orderDetlPakoutService.selectItem
-                                    (wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(),
-                                            wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
+                        // 鏇存柊璁㈠崟瀹屾垚鏁伴噺
+                        OrderDetlPakin orderDetlPakin = orderDetlPakinService.selectItem
+                                (wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(),
+                                        wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
+                                        wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
+                        if (orderDetlPakin == null) {
+                            orderDetlPakin = orderDetlPakinService.selectItem
+                                    (wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
                                             wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
-                            if (orderDetlPakout==null){
-                                orderDetlPakout = orderDetlPakoutService.selectItem
-                                        (wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),
-                                                wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3());
-                            }
-                            try {
-                                if(!Cools.isEmpty(orderDetlPakout)){
-                                    if(!orderDetlPakoutService.increaseQtyByOrderNo(wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
-                                            orderDetlPakout.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),
-                                            wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3(),wrkDetl.getAnfme())){
+                        }
+                        try {
+                            if (!Cools.isEmpty(orderDetlPakin)) {
+                                if (!orderDetlPakinService.increaseQtyByOrderNo(wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
+                                        orderDetlPakin.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
+                                        wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3(), wrkDetl.getAnfme())) {
 //                                    exceptionHandle("鎷f枡鍏ュ簱 ===>> 鏇存柊璁㈠崟瀹屾垚鏁伴噺澶辫触锛沎workNo={0}],[locNo={1}]",
 //                                            wrkMast.getWrkNo(), wrkMast.getLocNo());
-                                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-                                        return FAIL.setMsg("鎷f枡鍏ュ簱 ===>> 鏇存柊璁㈠崟瀹屾垚鏁伴噺澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]");
-                                    }
+                                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                                    return FAIL.setMsg("鎷f枡鍏ュ簱 ===>> 鏇存柊璁㈠崟瀹屾垚鏁伴噺澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]");
                                 }
-                            } catch (Exception ignore){}
+                            }
+                        } catch (Exception ignore) {
                         }
 
                     }
@@ -293,13 +289,13 @@
                         return FAIL.setMsg("骞舵澘鍏ュ簱 ===>> 宸ヤ綔鏄庣粏妗d负绌�; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]");
                     }
                     // 淇敼搴撳瓨鏄庣粏鏁伴噺锛屽鏃犲簱瀛橈紝鏇炬柊澧�
-                    for (WrkDetl wrkDetl:wrkDetls54) {
+                    for (WrkDetl wrkDetl : wrkDetls54) {
 
-                        LocDetl locDetl = locDetlService.selectItem(locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand()
-                                ,wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3());
+                        LocDetl locDetl = locDetlService.selectItem(locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand()
+                                , wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(), wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
                         if (null != locDetl) {
-                            if (!locDetlService.updateAnfme(wrkDetl.getAnfme(), locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3()
-                                    ,wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3())) {
+                            if (!locDetlService.updateAnfme(wrkDetl.getAnfme(), locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3()
+                                    , wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3())) {
 //                                exceptionHandle("骞舵澘鍏ュ簱 ===>> 淇敼搴撳瓨鏄庣粏鏁伴噺澶辫触锛沎workNo={0}],[matnr={1}]", wrkMast.getWrkNo(), wrkDetl.getMatnr());
                                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                                 return FAIL.setMsg("骞舵澘鍏ュ簱 ===>> 淇敼搴撳瓨鏄庣粏鏁伴噺澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]");
@@ -319,17 +315,17 @@
                         }
 
                         // 鏇存柊璁㈠崟瀹屾垚鏁伴噺
-                        OrderDetlPakin orderDetlPakin = orderDetlPakinService.selectItem(wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand(), wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(), wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3());
+                        OrderDetlPakin orderDetlPakin = orderDetlPakinService.selectItem(wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(), wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
                         try {
-                            if(!Cools.isEmpty(orderDetlPakin)){
-                                if(!orderDetlPakinService.increaseQtyByOrderNo(wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
-                                        orderDetlPakin.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),
-                                        wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3(),wrkDetl.getAnfme())){
+                            if (!Cools.isEmpty(orderDetlPakin)) {
+                                if (!orderDetlPakinService.increaseQtyByOrderNo(wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
+                                        orderDetlPakin.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
+                                        wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3(), wrkDetl.getAnfme())) {
                                     TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                                     return FAIL.setMsg("骞舵澘鍏ュ簱 ===>> 鏇存柊璁㈠崟瀹屾垚鏁伴噺澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]");
                                 }
                             }
-                        } catch (Exception ignore){
+                        } catch (Exception ignore) {
 
                         }
 
@@ -373,7 +369,7 @@
                     }
                     // 淇敼搴撲綅鐘舵�� Q ====>> F
                     if (locMast.getLocSts().equals("Q")) {
-                        locMast.setLocSts(wrkMast.getFullPlt().equals("Y")?"F":"D");
+                        locMast.setLocSts(wrkMast.getFullPlt().equals("Y") ? "F" : "D");
                         locMast.setBarcode(wrkMast.getBarcode());
                         locMast.setIoTime(now);
                         locMast.setModiTime(now);
@@ -426,7 +422,15 @@
                     break;
             }
             // 淇敼宸ヤ綔涓绘。鐘舵��
-            wrkMast.setWrkSts(5L);
+            if (needInboundErpReport(wrkMast)) {
+                wrkMast.setWrkSts(WorkErpReportHandler.ERP_REPORT_PENDING_WRK_STS);
+                wrkMast.setLogMk(WorkErpReportHandler.ERP_REPORT_PENDING_FLAG);
+                wrkMast.setExpTime(0D);
+                wrkMast.setLogErrMemo(null);
+                wrkMast.setLogErrTime(null);
+            } else {
+                wrkMast.setWrkSts(5L);
+            }
             wrkMast.setModiTime(now);
             if (!wrkMastService.updateById(wrkMast)) {
 //                exceptionHandle("鏇存柊鍏ュ簱瀹屾垚鐘舵�佸け璐�;[workNo={0}]", wrkMast.getWrkNo());
@@ -442,11 +446,13 @@
         return SUCCESS;
     }
 
-    private ReturnT<String> doOut(WrkMast wrkMast){
+
+    @Transactional(rollbackFor = Exception.class)
+    public ReturnT<String> doOut(WrkMast wrkMast) {
         Date now = new Date();
         LocMast locMast = locMastService.selectById(wrkMast.getSourceLocNo());
         try {
-            if (null == locMast && wrkMast.getIoType() !=12) {
+            if (null == locMast) {
 //                exceptionHandle("宸ヤ綔妗workNo={0}]搴撲綅鍙烽敊璇痆locNo={1}]", wrkMast.getWrkNo(), wrkMast.getLocNo());
                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                 return FAIL.setMsg("宸ヤ綔妗e簱浣嶅彿閿欒; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]");
@@ -455,6 +461,9 @@
             switch (wrkMast.getIoType()) {
                 // 鍏ㄦ澘鍑哄簱
                 case 101:
+                    //濡傛灉wrkCode涓嶄负绌猴紝琛ㄧず鏄伐浣滃彴鍙揣,濡傛灉涓嶄负绌鸿蛋绉诲簱閫昏緫
+                    //todo 鍒ゆ柇濡傛灉搴撲綅鎵�灞炰笉鏄悓涓�涓爢鍨涙満鍙凤紝闇�鍐嶇敓鎴愪竴涓柊鐨勫叆搴撲换鍔�
+
 //                    // 鍑哄簱纭淇″彿浣�
 //                    if (Cools.isEmpty(wrkMast.getInvWh()) || wrkMast.getInvWh().equals("N")) {
 //                        return SUCCESS;
@@ -466,33 +475,29 @@
                         TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                         return FAIL.setMsg("鍏ㄦ澘鍑哄簱 ===>> 宸ヤ綔鏄庣粏妗d负绌�; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getSourceLocNo() + "]");
                     }
-
                     for (WrkDetl wrkDetl : wrkDetls101) {
-                        if (!Cools.isEmpty(wrkDetl.getOrderNo())){
-                            // 鏇存柊璁㈠崟瀹屾垚鏁伴噺
-                            OrderDetlPakout orderDetlPakout = orderDetlPakoutService.selectItem(wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),
-                                    wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3());
-                            if (orderDetlPakout==null){
-                                orderDetlPakout = orderDetlPakoutService.selectItem(wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),
-                                        wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3());
-                            }
-                            try {
-                                if(!Cools.isEmpty(orderDetlPakout)){
-                                    if(!orderDetlPakoutService.increaseQtyByOrderNo(wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
-                                            orderDetlPakout.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),
-                                            wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3(),wrkDetl.getAnfme())){
-//                                    exceptionHandle("鍏ㄦ澘鍑哄簱 ===>> 鏇存柊璁㈠崟瀹屾垚鏁伴噺澶辫触锛沎workNo={0}],[locNo={1}]",
-//                                            wrkMast.getWrkNo(), wrkMast.getLocNo());
-                                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-                                        return FAIL.setMsg("鍏ㄦ澘鍑哄簱 ===>> 鏇存柊璁㈠崟瀹屾垚鏁伴噺澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getSourceLocNo() + "]");
-                                    }
+                        // 鏇存柊璁㈠崟瀹屾垚鏁伴噺
+                        OrderDetlPakout orderDetlPakout = orderDetlPakoutService.selectItem(wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
+                                wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
+                        if (orderDetlPakout == null) {
+                            orderDetlPakout = orderDetlPakoutService.selectItem(wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
+                                    wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
+                        }
+                        try {
+                            if (!Cools.isEmpty(orderDetlPakout)) {
+                                if (!orderDetlPakoutService.increaseQtyByOrderNo(wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
+                                        orderDetlPakout.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
+                                        wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3(), wrkDetl.getAnfme())) {
+                                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                                    return FAIL.setMsg("鍏ㄦ澘鍑哄簱 ===>> 鏇存柊璁㈠崟瀹屾垚鏁伴噺澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getSourceLocNo() + "]");
                                 }
-                            } catch (Exception ignore){}
+                            }
+                        } catch (Exception ignore) {
+
                         }
                     }
                     // 鍒犻櫎宸ヤ綔妗f簮搴撲綅鐨勫簱瀛樻槑缁�
                     if (!locDetlService.delete(new EntityWrapper<LocDetl>().eq("loc_no", wrkMast.getSourceLocNo()))) {
-//                        exceptionHandle("鍏ㄦ澘鍑哄簱 ===>> 鍒犻櫎搴撳瓨鏄庣粏澶辫触锛沎workNo={0}],[sourceLocNo={1}]", wrkMast.getWrkNo(), wrkMast.getSourceLocNo());
                         TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                         return FAIL.setMsg("鍏ㄦ澘鍑哄簱 ===>> 鍒犻櫎搴撳瓨鏄庣粏澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getSourceLocNo() + "]");
                     }
@@ -503,11 +508,11 @@
                         locMast.setModiTime(now);
                         locMast.setIoTime(now);
                         if (!locMastService.updateById(locMast)) {
-//                            exceptionHandle("鍏ㄦ澘鍑哄簱 ===>> 淇敼婧愬簱浣嶇姸鎬佸け璐ワ紱[workNo={0}],[sourceLocNo={1}]", wrkMast.getWrkNo(), wrkMast.getSourceLocNo());
                             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                             return FAIL.setMsg("鍏ㄦ澘鍑哄簱 ===>> 淇敼婧愬簱浣嶇姸鎬佸け璐�; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getSourceLocNo() + "]");
                         }
                     }
+
                     break;
                 // 骞舵澘閫斾腑鎹℃枡
                 case 108:
@@ -518,28 +523,29 @@
                         return FAIL.setMsg("骞舵澘閫斾腑鎹℃枡 ===>> 宸ヤ綔鏄庣粏妗d负绌�; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getSourceLocNo() + "]");
                     }
                     for (WrkDetl wrkDetl : wrkDetls108) {
-                        LocDetl locDetl = locDetlService.selectItem(locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand()
-                                ,wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3());
+                        LocDetl locDetl = locDetlService.selectItem(locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand()
+                                , wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(), wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
                         if (null != locDetl) {
-                            if (!locDetlService.updateAnfme(locDetl.getAnfme() - wrkDetl.getAnfme(), locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3()
-                                    ,wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3())) {
+                            if (!locDetlService.updateAnfme(locDetl.getAnfme() - wrkDetl.getAnfme(), locMast.getLocNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3()
+                                    , wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3())) {
                                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                                 return FAIL.setMsg("骞舵澘閫斾腑鎹℃枡 ===>> 淇敼搴撳瓨鏄庣粏鏁伴噺澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getLocNo() + "]");
                             }
                         }
                         // 鏇存柊璁㈠崟瀹屾垚鏁伴噺
-                        OrderDetlPakout orderDetlPakout = orderDetlPakoutService.selectItem(wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),
-                                wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3());
+                        OrderDetlPakout orderDetlPakout = orderDetlPakoutService.selectItem(wrkDetl.getOrderNo(), wrkDetl.getMatnr(), wrkDetl.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
+                                wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3());
                         try {
-                            if(!Cools.isEmpty(orderDetlPakout)){
-                                if(!orderDetlPakoutService.increaseQtyByOrderNo(wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
-                                        orderDetlPakout.getBatch(),wrkDetl.getBrand(),wrkDetl.getStandby1(),wrkDetl.getStandby2(),wrkDetl.getStandby3(),
-                                        wrkDetl.getBoxType1(),wrkDetl.getBoxType2(),wrkDetl.getBoxType3(),wrkDetl.getAnfme())){
+                            if (!Cools.isEmpty(orderDetlPakout)) {
+                                if (!orderDetlPakoutService.increaseQtyByOrderNo(wrkDetl.getOrderNo(), wrkDetl.getMatnr(),
+                                        orderDetlPakout.getBatch(), wrkDetl.getBrand(), wrkDetl.getStandby1(), wrkDetl.getStandby2(), wrkDetl.getStandby3(),
+                                        wrkDetl.getBoxType1(), wrkDetl.getBoxType2(), wrkDetl.getBoxType3(), wrkDetl.getAnfme())) {
                                     TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                                     return FAIL.setMsg("骞舵澘閫斾腑鎹℃枡 ===>> 鏇存柊璁㈠崟瀹屾垚鏁伴噺澶辫触; [workNo=" + wrkMast.getWrkNo() + "],[locNo=" + wrkMast.getSourceLocNo() + "]");
                                 }
                             }
-                        } catch (Exception ignore){}
+                        } catch (Exception ignore) {
+                        }
                     }
                     break;
                 // 绌烘澘鍑哄簱
@@ -557,14 +563,23 @@
                         }
                     }
                     break;
-                //3鍙峰爢鍨涙満琛旀帴
-                case 12:
-                    break;
                 default:
                     break;
             }
             // 淇敼宸ヤ綔涓绘。鐘舵��
-            wrkMast.setWrkSts(15L);
+            if (needOutboundErpReport(wrkMast)) {
+                wrkMast.setWrkSts(WorkOutErpReportHandler.ERP_REPORT_PENDING_WRK_STS);
+                wrkMast.setLogMk(WorkOutErpReportHandler.ERP_REPORT_PENDING_FLAG);
+                wrkMast.setExpTime(0D);
+                wrkMast.setLogErrMemo(null);
+                wrkMast.setLogErrTime(null);
+            } else {
+                wrkMast.setWrkSts(15L);
+            }
+//            if (!Objects.isNull(wrkMast.getWrkCode())) {
+//                //棰嗘枡鍑哄簱浠诲姟锛屼笉淇敼
+//            } else {
+//            }
             wrkMast.setModiTime(now);
             if (!wrkMastService.updateById(wrkMast)) {
 //                exceptionHandle("鏇存柊鍑哄簱瀹屾垚鐘舵�佸け璐�;[workNo={0}]", wrkMast.getWrkNo());
@@ -579,134 +594,4 @@
         }
         return SUCCESS;
     }
-
-    /**
-     * wcs涓婃姤浠诲姟瀹屾垚鍚庯紝灏嗕换鍔′笂鎶ョ粰erp
-     * 2.鍏ュ簱涓婃姤
-     * 13.鍑哄簱涓婃姤
-     */
-    public ReturnT<String> start1(WrkMast wrkMast) {
-        // 2.鍏ュ簱涓婃姤
-        if (wrkMast.getWrkSts() == 2) {
-            return ErpdoIn(wrkMast);
-            // 13.鍑哄簱涓婃姤
-        } else  if (wrkMast.getWrkSts() == 13) {
-            return ErpdoOut(wrkMast);
-        }
-        return SUCCESS;
-    }
-
-    private ReturnT<String> ErpdoOut(WrkMast wrkMast){
-        try {
-            com.zy.common.utils.HttpHandler.Builder builder = new com.zy.common.utils.HttpHandler.Builder();
-            if (Cools.isEmpty(erpBaseUrl) || Cools.isEmpty(erpOutAddress)) {
-                return FAIL.setMsg("ERP鍑哄簱涓婃姤鍦板潃鏈厤缃甗erp.address.URL / erp.address.Outaddress]");
-            }
-            java.util.List<WrkDetl> wrkDetls = wrkDetlService.selectList(
-                    new com.baomidou.mybatisplus.mapper.EntityWrapper<WrkDetl>().eq("wrk_no", wrkMast.getWrkNo())
-            );
-            if (wrkDetls == null || wrkDetls.isEmpty()) {
-                return FAIL.setMsg("ERP鍑哄簱涓婃姤澶辫触, 鏈壘鍒板伐浣滄槑缁哰workNo=" + wrkMast.getWrkNo() + "]");
-            }
-
-            java.util.Map<String, Object> payload = new java.util.HashMap<>();
-            payload.put("palletId", wrkMast.getBarcode());
-            payload.put("anfme", wrkDetls.get(0).getAnfme());
-            payload.put("locId", wrkMast.getSourceLocNo());
-            payload.put("weight", wrkMast.getScWeight());
-            payload.put("photos", new java.util.ArrayList<String>());
-            if (wrkMast.getModiTime() != null) {
-                payload.put("createTime", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(wrkMast.getModiTime()));
-            } else {
-                payload.put("createTime", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()));
-            }
-            payload.put("BizNo", String.valueOf(wrkDetls.get(0).getThreeCode()));
-
-            String uri = erpBaseUrl;
-            String response = builder
-                    .setUri(uri)
-                    .setPath(erpOutAddress)
-                    .setHttps(uri != null && uri.startsWith("https://"))
-                    .setTimeout(10, java.util.concurrent.TimeUnit.SECONDS)
-                    .setJson(com.alibaba.fastjson.JSON.toJSONString(payload))
-                    .build()
-                    .doPost();
-
-            com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSON.parseObject(response == null ? "{}" : response);
-            Integer code = jsonObject.getInteger("code");
-            if (code == null || code != 0) {
-                String msg = jsonObject.getString("msg");
-                return FAIL.setMsg(Cools.isEmpty(msg) ? "ERP鍑哄簱涓婃姤澶辫触" : msg);
-            }
-            wrkMast.setWrkSts(wrkMast.getWrkSts() + 1);
-            wrkMast.setModiTime(new java.util.Date());
-            if (!wrkMastService.updateById(wrkMast)) {
-                return FAIL.setMsg("ERP鍑哄簱涓婃姤鎴愬姛浣嗘洿鏂板伐浣滅姸鎬佸け璐�; [workNo=" + wrkMast.getWrkNo() + "]");
-            }
-        } catch (Exception e) {
-            return FAIL.setMsg(e.getMessage());
-        }
-        return SUCCESS;
-    }
-
-    private ReturnT<String> ErpdoIn(WrkMast wrkMast){
-        try {
-            com.zy.common.utils.HttpHandler.Builder builder = new com.zy.common.utils.HttpHandler.Builder();
-            if (Cools.isEmpty(erpBaseUrl) || Cools.isEmpty(erpInAddress)) {
-                return FAIL.setMsg("ERP鍏ュ簱涓婃姤鍦板潃鏈厤缃甗erp.address.URL / erp.address.Inaddress]");
-            }
-
-            java.util.Map<String, Object> payload = new java.util.HashMap<>();
-            payload.put("palletId", wrkMast.getBarcode());
-            java.util.List<WrkDetl> wrkDetls = wrkDetlService.selectList(
-                    new com.baomidou.mybatisplus.mapper.EntityWrapper<WrkDetl>().eq("wrk_no", wrkMast.getWrkNo())
-            );
-            if (wrkDetls == null || wrkDetls.isEmpty()) {
-                return FAIL.setMsg("ERP鍏ュ簱涓婃姤澶辫触, 鏈壘鍒板伐浣滄槑缁哰workNo=" + wrkMast.getWrkNo() + "]");
-            }
-            double anfme = 0D;
-            for (WrkDetl d : wrkDetls) {
-                if (d != null && d.getAnfme() != null) {
-                    anfme += d.getAnfme();
-                }
-            }
-            payload.put("anfme", anfme);
-            payload.put("locId", wrkMast.getLocNo());
-            payload.put("weight", wrkMast.getScWeight());
-            payload.put("photos", new java.util.ArrayList<String>());
-            if (wrkMast.getModiTime() != null) {
-                payload.put("createTime", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(wrkMast.getModiTime()));
-            } else {
-                payload.put("createTime", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()));
-            }
-            payload.put("BizNo", String.valueOf(wrkDetls.get(0).getThreeCode()));
-
-            String uri = erpBaseUrl;
-
-            String response = builder
-                    .setUri(uri)
-                    .setPath(erpInAddress)
-                    .setHttps(uri != null && uri.startsWith("https://"))
-                    .setTimeout(10, java.util.concurrent.TimeUnit.SECONDS)
-                    .setJson(com.alibaba.fastjson.JSON.toJSONString(payload))
-                    .build()
-                    .doPost();
-
-            com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSON.parseObject(response == null ? "{}" : response);
-            Integer code = jsonObject.getInteger("code");
-            if (code == null || code != 0) {
-                String msg = jsonObject.getString("msg");
-                return FAIL.setMsg(Cools.isEmpty(msg) ? "ERP鍏ュ簱涓婃姤澶辫触" : msg);
-            }
-            wrkMast.setWrkSts(wrkMast.getWrkSts() + 1);
-            wrkMast.setModiTime(new java.util.Date());
-            if (!wrkMastService.updateById(wrkMast)) {
-                return FAIL.setMsg("ERP鍏ュ簱涓婃姤鎴愬姛浣嗘洿鏂板伐浣滅姸鎬佸け璐�; [workNo=" + wrkMast.getWrkNo() + "]");
-            }
-        } catch (Exception e) {
-            return FAIL.setMsg(e.getMessage());
-        }
-        return SUCCESS;
-    }
-
 }
diff --git a/src/main/java/com/zy/asrs/utils/Utils.java b/src/main/java/com/zy/asrs/utils/Utils.java
index 6039033..e0eb6dc 100644
--- a/src/main/java/com/zy/asrs/utils/Utils.java
+++ b/src/main/java/com/zy/asrs/utils/Utils.java
@@ -739,4 +739,38 @@
         return result;
     }
 
+    //灏唚ms搴撲綅鍙疯浆鎹㈡垚wcs搴撲綅鍙�
+    public static String WMSLocToWCSLoc(String locNo) {
+        String row = locNo.substring(0, 2);
+        int i = 0;
+        for (char c : row.toCharArray()) {
+            if (c == '0') {
+                i++;
+            }else {
+                break;
+            }
+        }
+        row = row.substring(i);
+        int j = 0;
+        String boy = locNo.substring(2, 5);
+        for (char c : boy.toCharArray()) {
+            if (c == '0') {
+                j++;
+            }else {
+                break;
+            }
+        }
+        boy = boy.substring(j);
+        int k = 0;
+        String lev = locNo.substring(5);
+        for (char c : lev.toCharArray()) {
+            if (c == '0') {
+                k++;
+            }else {
+                break;
+            }
+        }
+        lev = lev.substring(k);
+        return row + "-" + boy + "-" + lev;
+    }
 }
diff --git a/src/main/java/com/zy/common/model/StartupDto.java b/src/main/java/com/zy/common/model/StartupDto.java
index b0ecc3e..1530829 100644
--- a/src/main/java/com/zy/common/model/StartupDto.java
+++ b/src/main/java/com/zy/common/model/StartupDto.java
@@ -18,4 +18,8 @@
 
     private Integer workNo;
 
+    private String barcode;
+
+    private String taskNo;
+
 }
diff --git a/src/main/java/com/zy/common/service/CommonService.java b/src/main/java/com/zy/common/service/CommonService.java
index cf5f7e8..e4f7cd1 100644
--- a/src/main/java/com/zy/common/service/CommonService.java
+++ b/src/main/java/com/zy/common/service/CommonService.java
@@ -25,7 +25,9 @@
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -35,6 +37,7 @@
 @Slf4j
 @Service
 public class CommonService {
+    private static final int MIN_SPARE_LOC_COUNT = 2;
 
     @Autowired
     private WrkMastService wrkMastService;
@@ -126,10 +129,18 @@
      */
     @Transactional
     public StartupDto getLocNo(Integer staDescId, Integer sourceStaNo, FindLocNoAttributeVo findLocNoAttributeVo, LocTypeDto locTypeDto) {
+        return getLocNo(staDescId, sourceStaNo, findLocNoAttributeVo, locTypeDto, null);
+    }
+
+    @Transactional
+    public StartupDto getLocNo(Integer staDescId, Integer sourceStaNo, FindLocNoAttributeVo findLocNoAttributeVo, LocTypeDto locTypeDto, List<Integer> recommendRows) {
         try {
             Integer whsType = Utils.GetWhsType(sourceStaNo);
             RowLastno rowLastno = rowLastnoService.selectById(whsType);
             RowLastnoType rowLastnoType = rowLastnoTypeService.selectById(rowLastno.getTypeId());
+            if (rowLastnoType.getType() == 2) {
+                return getLocNoRun2(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, 0, locTypeDto, 0);
+            }
             /**
              * 搴撳瀷 1: 鏍囧噯鍫嗗灈鏈哄簱  2: 骞冲簱  3: 绌挎鏉�  4: 鍥涘悜杞�  5: AGV  0: 鏈煡
              */
@@ -145,7 +156,7 @@
                 case 4:
                     return getLocNoRun4(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, 4, locTypeDto, 0);
                 case 5:
-                    return getLocNoRun5(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, 0, locTypeDto, 0);
+                    return getLocNoRun5(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, 0, locTypeDto, recommendRows, 0);
                 default:
                     log.error("绔欑偣={} 鏈煡璇㈠埌瀵瑰簲鐨勮鍒�", sourceStaNo);
                     break;
@@ -177,7 +188,7 @@
             int availableLocCount = locMastService.selectCount(new EntityWrapper<LocMast>()
                     .eq("row1", nearRow)
                     .eq("loc_sts", "O")
-                    .eq("whs_type", rowLastnoType.getType().longValue()));
+                    .eq("whs_type", 1));
             int crnCountO = wrkMastService.selectCount(new EntityWrapper<WrkMast>()
                     .eq("crn_no", crnNo).le("io_type", 100));
             if (availableLocCount - crnCountO <= 2) { // 鍙互鎻愭垚甯搁噺锛屾瘮濡� MIN_SPARE_SLOTS = 2
@@ -188,6 +199,298 @@
             return Optional.of(new CrnRowInfo(crnNo, nearRow, curRow, rowCount, attempt));
         }
         return Optional.empty();
+    }
+
+    private Optional<CrnRowInfo> findBalancedCrnAndNearRow(RowLastno rowLastno, int curRow, int crnNumber, int times,
+                                                           FindLocNoAttributeVo findLocNoAttributeVo, LocTypeDto locTypeDto,
+                                                           RowLastnoType rowLastnoType) {
+        int maxScanTimes = Math.max(crnNumber * 2, 1);
+        int scanCurRow = curRow;
+        Map<Integer, Integer> availableLocCountCache = new HashMap<>();
+        Map<Integer, Integer> crnTaskCountCache = new HashMap<>();
+
+        CrnRowInfo bestInfo = null;
+        int bestTaskCount = Integer.MAX_VALUE;
+        int bestSpareLocCount = Integer.MIN_VALUE;
+        int bestOffset = Integer.MAX_VALUE;
+        CrnRowInfo fallbackInfo = null;
+        int fallbackTaskCount = Integer.MAX_VALUE;
+        int fallbackAvailableLocCount = Integer.MIN_VALUE;
+        int fallbackOffset = Integer.MAX_VALUE;
+
+        for (int attempt = 0; attempt < maxScanTimes; attempt++) {
+            int[] params = Utils.LocNecessaryParameters(rowLastno, scanCurRow, crnNumber);
+            scanCurRow = params[1];
+            int rowCount = params[0];
+            int crnNo = params[2];
+            int nearRow = params[3];
+
+            if (attempt < times) {
+                continue;
+            }
+
+            int availableLocCount = availableLocCountCache.computeIfAbsent(crnNo, key ->
+                    countAvailableLocForCrn(rowLastno, rowLastnoType, key, nearRow));
+            int crnTaskCount = crnTaskCountCache.computeIfAbsent(crnNo, key ->
+                    wrkMastService.selectCount(new EntityWrapper<WrkMast>()
+                            .eq("crn_no", key)
+                            .le("io_type", 100)));
+            int spareLocCount = availableLocCount - crnTaskCount;
+            int offset = attempt - times;
+
+            if (availableLocCount > 0 && isBetterCrnCandidate(crnTaskCount, availableLocCount, offset,
+                    fallbackTaskCount, fallbackAvailableLocCount, fallbackOffset)) {
+                fallbackInfo = new CrnRowInfo(crnNo, nearRow, scanCurRow, rowCount, attempt);
+                fallbackTaskCount = crnTaskCount;
+                fallbackAvailableLocCount = availableLocCount;
+                fallbackOffset = offset;
+            }
+
+            if (spareLocCount <= MIN_SPARE_LOC_COUNT) {
+                log.warn("{}鍙峰爢鍨涙満鍙敤绌哄簱浣嶄綑閲忎笉瓒筹紝闄嶇骇鍊欓�夌户缁繚鐣欍�傚昂瀵歌鏍硷細{}锛岃疆璇㈡鏁帮細{}", crnNo, JSON.toJSONString(locTypeDto), attempt);
+                continue;
+            }
+
+            if (isBetterCrnCandidate(crnTaskCount, spareLocCount, offset, bestTaskCount, bestSpareLocCount, bestOffset)) {
+                bestInfo = new CrnRowInfo(crnNo, nearRow, scanCurRow, rowCount, attempt);
+                bestTaskCount = crnTaskCount;
+                bestSpareLocCount = spareLocCount;
+                bestOffset = offset;
+            }
+        }
+        if (bestInfo != null) {
+            return Optional.of(bestInfo);
+        }
+        if (fallbackInfo != null) {
+            log.warn("鍫嗗灈鏈哄潎琛″垎閰嶆湭鎵惧埌婊¤冻浣欓噺闃堝�肩殑鍊欓�夛紝闄嶇骇浣跨敤浠嶆湁绌轰綅鐨勫爢鍨涙満: crnNo={}", fallbackInfo.getCrnNo());
+        }
+        return Optional.ofNullable(fallbackInfo);
+    }
+
+    private boolean isBetterCrnCandidate(int taskCount, int spareLocCount, int offset,
+                                         int bestTaskCount, int bestSpareLocCount, int bestOffset) {
+        if (taskCount != bestTaskCount) {
+            return taskCount < bestTaskCount;
+        }
+        if (spareLocCount != bestSpareLocCount) {
+            return spareLocCount > bestSpareLocCount;
+        }
+        return offset < bestOffset;
+    }
+
+    private int countAvailableLocForCrn(RowLastno rowLastno, RowLastnoType rowLastnoType, int crnNo, int preferredNearRow) {
+        List<Integer> searchRows = getCrnSearchRows(rowLastno, crnNo, preferredNearRow);
+        if (searchRows.isEmpty()) {
+            return 0;
+        }
+        return locMastService.selectCount(new EntityWrapper<LocMast>()
+                .in("row1", searchRows)
+                .eq("loc_sts", "O")
+                .eq("whs_type", rowLastnoType.getType().longValue()));
+    }
+
+    private int countAvailableSingleExtensionLocForCrn(RowLastno rowLastno, RowLastnoType rowLastnoType, int crnNo, int preferredNearRow, LocTypeDto locTypeDto) {
+        List<Integer> searchRows = getCrnSearchRows(rowLastno, crnNo, preferredNearRow);
+        if (searchRows.isEmpty()) {
+            return 0;
+        }
+        Wrapper<LocMast> wrapper = new EntityWrapper<LocMast>()
+                .in("row1", searchRows)
+                .eq("loc_sts", "O")
+                .eq("whs_type", rowLastnoType.getType().longValue());
+        if (locTypeDto != null && locTypeDto.getLocType1() != null) {
+            wrapper.eq("loc_type1", locTypeDto.getLocType1());
+        }
+        return locMastService.selectCount(wrapper);
+    }
+
+    private Optional<CrnRowInfo> findBalancedSingleExtensionCrnAndNearRow(RowLastno rowLastno, int curRow, int crnNumber, int times,
+                                                                           LocTypeDto locTypeDto, RowLastnoType rowLastnoType) {
+        int maxScanTimes = Math.max(crnNumber * 2, 1);
+        int scanCurRow = curRow;
+        Map<Integer, Integer> availableLocCountCache = new HashMap<>();
+        Map<Integer, Integer> crnTaskCountCache = new HashMap<>();
+
+        CrnRowInfo bestInfo = null;
+        int bestTaskCount = Integer.MAX_VALUE;
+        int bestSpareLocCount = Integer.MIN_VALUE;
+        int bestOffset = Integer.MAX_VALUE;
+        CrnRowInfo fallbackInfo = null;
+        int fallbackTaskCount = Integer.MAX_VALUE;
+        int fallbackAvailableLocCount = Integer.MIN_VALUE;
+        int fallbackOffset = Integer.MAX_VALUE;
+
+        for (int attempt = 0; attempt < maxScanTimes; attempt++) {
+            int[] params = Utils.LocNecessaryParameters(rowLastno, scanCurRow, crnNumber);
+            scanCurRow = params[1];
+            int rowCount = params[0];
+            int crnNo = params[2];
+            int nearRow = params[3];
+
+            if (attempt < times) {
+                continue;
+            }
+
+            int availableLocCount = availableLocCountCache.computeIfAbsent(crnNo, key ->
+                    countAvailableSingleExtensionLocForCrn(rowLastno, rowLastnoType, key, nearRow, locTypeDto));
+            int crnTaskCount = crnTaskCountCache.computeIfAbsent(crnNo, key ->
+                    wrkMastService.selectCount(new EntityWrapper<WrkMast>()
+                            .eq("crn_no", key)
+                            .le("io_type", 100)));
+            int spareLocCount = availableLocCount - crnTaskCount;
+            int offset = attempt - times;
+
+            if (availableLocCount > 0 && isBetterCrnCandidate(crnTaskCount, availableLocCount, offset,
+                    fallbackTaskCount, fallbackAvailableLocCount, fallbackOffset)) {
+                fallbackInfo = new CrnRowInfo(crnNo, nearRow, scanCurRow, rowCount, attempt);
+                fallbackTaskCount = crnTaskCount;
+                fallbackAvailableLocCount = availableLocCount;
+                fallbackOffset = offset;
+            }
+
+            if (spareLocCount <= MIN_SPARE_LOC_COUNT) {
+                continue;
+            }
+
+            if (isBetterCrnCandidate(crnTaskCount, spareLocCount, offset, bestTaskCount, bestSpareLocCount, bestOffset)) {
+                bestInfo = new CrnRowInfo(crnNo, nearRow, scanCurRow, rowCount, attempt);
+                bestTaskCount = crnTaskCount;
+                bestSpareLocCount = spareLocCount;
+                bestOffset = offset;
+            }
+        }
+        if (bestInfo != null) {
+            return Optional.of(bestInfo);
+        }
+        return Optional.ofNullable(fallbackInfo);
+    }
+
+    private List<Integer> getCrnSearchRows(RowLastno rowLastno, int crnNo, int preferredNearRow) {
+        List<Integer> searchRows = new ArrayList<>();
+        addSearchRow(searchRows, preferredNearRow, rowLastno);
+
+        Integer rowSpan = getCrnRowSpan(rowLastno.getTypeId());
+        if (rowSpan == null) {
+            return searchRows;
+        }
+
+        int crnOffset = crnNo - rowLastno.getsCrnNo();
+        if (crnOffset < 0) {
+            return searchRows;
+        }
+        int startRow = rowLastno.getsRow() + crnOffset * rowSpan;
+        switch (rowLastno.getTypeId()) {
+            case 1:
+                addSearchRow(searchRows, startRow + 1, rowLastno);
+                addSearchRow(searchRows, startRow + 2, rowLastno);
+                break;
+            case 2:
+                addSearchRow(searchRows, startRow, rowLastno);
+                addSearchRow(searchRows, startRow + 1, rowLastno);
+                break;
+            default:
+                break;
+        }
+        return searchRows;
+    }
+
+    private Integer getCrnRowSpan(Integer typeId) {
+        if (typeId == null) {
+            return null;
+        }
+        switch (typeId) {
+            case 1:
+                return 4;
+            case 2:
+                return 2;
+            default:
+                return null;
+        }
+    }
+
+    private void addSearchRow(List<Integer> searchRows, Integer row, RowLastno rowLastno) {
+        if (row == null) {
+            return;
+        }
+        if (row < rowLastno.getsRow() || row > rowLastno.geteRow()) {
+            return;
+        }
+        if (!searchRows.contains(row)) {
+            searchRows.add(row);
+        }
+    }
+
+    private LocMast findStandardEmptyLoc(RowLastno rowLastno, RowLastnoType rowLastnoType, int crnNo, int nearRow, LocTypeDto locTypeDto) {
+        for (Integer searchRow : getCrnSearchRows(rowLastno, crnNo, nearRow)) {
+            List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>()
+                    .eq("row1", searchRow)
+                    .eq("loc_sts", "O")
+                    .eq("whs_type", rowLastnoType.getType().longValue())
+                    .orderBy("lev1", true)
+                    .orderBy("bay1", true));
+            for (LocMast locMast1 : locMasts) {
+                if (!VersionUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) {
+                    continue;
+                }
+                if (Utils.BooleanWhsTypeStaIoType(rowLastno)) {
+                    String shallowLoc = Utils.getDeepLoc(slaveProperties, locMast1.getLocNo());
+                    LocMast locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
+                            .eq("loc_no", shallowLoc)
+                            .eq("loc_sts", "O")
+                            .eq("whs_type", rowLastnoType.getType().longValue()));
+                    if (!Cools.isEmpty(locMast2)) {
+                        return locMast2;
+                    }
+                } else if (!Cools.isEmpty(locMast1)) {
+                    return locMast1;
+                }
+            }
+
+            if (!Utils.BooleanWhsTypeStaIoType(rowLastno)) {
+                continue;
+            }
+
+            for (LocMast locMast1 : locMasts) {
+                if (!VersionUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) {
+                    continue;
+                }
+                String shallowLoc = Utils.getDeepLoc(slaveProperties, locMast1.getLocNo());
+                LocMast locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
+                        .eq("loc_no", shallowLoc)
+                        .eq("loc_sts", "O")
+                        .eq("whs_type", rowLastnoType.getType().longValue()));
+                if (!Cools.isEmpty(locMast2)) {
+                    return locMast2;
+                }
+                locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
+                        .eq("loc_no", shallowLoc)
+                        .eq("loc_sts", "F")
+                        .eq("whs_type", rowLastnoType.getType().longValue()));
+                if (!Cools.isEmpty(locMast2)) {
+                    return locMast1;
+                }
+                locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
+                        .eq("loc_no", shallowLoc)
+                        .eq("loc_sts", "D")
+                        .eq("whs_type", rowLastnoType.getType().longValue()));
+                if (!Cools.isEmpty(locMast2)) {
+                    return locMast1;
+                }
+            }
+        }
+        return null;
+    }
+
+    private LocTypeDto buildUpwardCompatibleLocTypeDto(LocTypeDto locTypeDto) {
+        if (locTypeDto == null || locTypeDto.getLocType1() == null || locTypeDto.getLocType1() >= 2) {
+            return null;
+        }
+        LocTypeDto compatibleLocTypeDto = new LocTypeDto();
+        compatibleLocTypeDto.setLocType1((short) (locTypeDto.getLocType1() + 1));
+        compatibleLocTypeDto.setLocType2(locTypeDto.getLocType2());
+        compatibleLocTypeDto.setLocType3(locTypeDto.getLocType3());
+        compatibleLocTypeDto.setSiteId(locTypeDto.getSiteId());
+        return compatibleLocTypeDto;
     }
 
 
@@ -241,7 +544,10 @@
         }
 
         //姝ょ▼搴忕敤浜庝紭鍖栧爢鍨涙満寮傚父鏃剁殑杩愯鏃堕棿
-        Optional<CrnRowInfo> infoOpt = findAvailableCrnAndNearRow(rowLastno, curRow, crnNumber, times, findLocNoAttributeVo, locTypeDto, rowLastnoType);
+        Optional<CrnRowInfo> infoOpt = findBalancedCrnAndNearRow(rowLastno, curRow, crnNumber, times, findLocNoAttributeVo, locTypeDto, rowLastnoType);
+        if (!infoOpt.isPresent()) {
+            infoOpt = findAvailableCrnAndNearRow(rowLastno, curRow, crnNumber, times, findLocNoAttributeVo, locTypeDto, rowLastnoType);
+        }
         if (!infoOpt.isPresent()) {
             throw new CoolException("鏃犲彲鐢ㄥ爢鍨涙満");
         }
@@ -370,153 +676,35 @@
             }
         }
 
-        // 寮�濮嬫煡鎵惧簱浣� ==============================>>
+        // Search empty location ==============================>>
         if (staDescId == 10 && Cools.isEmpty(locMast) && crnNo != 0) {
-            List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>()
-                    .eq("row1", nearRow)
-                    .eq("loc_sts", "O").eq("whs_type", rowLastnoType.getType().longValue())
-                    .orderBy("lev1", true).orderBy("bay1", false));
-            for (LocMast locMast1 : locMasts) {
-                if (!VersionUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) {
-                    continue;
-                }
-                if (Utils.BooleanWhsTypeStaIoType(rowLastno)) {
-                    String shallowLoc = Utils.getDeepLoc(slaveProperties, locMast1.getLocNo());
-                    LocMast locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
-                            .eq("loc_no", shallowLoc).eq("loc_sts", "O").eq("whs_type", rowLastnoType.getType().longValue()));
-                    if (!Cools.isEmpty(locMast2)) {
-                        locMast = locMast2;
-                        break;
-                    }
-                } else {
-                    if (!Cools.isEmpty(locMast1)) {
-                        locMast = locMast1;
-                        break;
-                    }
-                }
-            }
-
-            if (Cools.isEmpty(locMast) && Utils.BooleanWhsTypeStaIoType(rowLastno)) {
-                for (LocMast locMast1 : locMasts) {
-                    if (!VersionUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) {
-                        continue;
-                    }
-                    if (Utils.BooleanWhsTypeStaIoType(rowLastno)) {
-                        String shallowLoc = Utils.getDeepLoc(slaveProperties, locMast1.getLocNo());
-                        LocMast locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
-                                .eq("loc_no", shallowLoc).eq("loc_sts", "O").eq("whs_type", rowLastnoType.getType().longValue()));
-                        if (!Cools.isEmpty(locMast2)) {
-                            locMast = locMast2;
-                            break;
-                        } else {
-                            locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
-                                    .eq("loc_no", shallowLoc).eq("loc_sts", "F").eq("whs_type", rowLastnoType.getType().longValue()));
-                            if (!Cools.isEmpty(locMast2)) {
-                                locMast = locMast1;
-                                break;
-                            } else {
-                                locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
-                                        .eq("loc_no", shallowLoc).eq("loc_sts", "D").eq("whs_type", rowLastnoType.getType().longValue()));
-                                if (!Cools.isEmpty(locMast2)) {
-                                    locMast = locMast1;
-                                    break;
-                                }
-                            }
-                        }
-                    } else {
-                        if (!Cools.isEmpty(locMast1)) {
-                            locMast = locMast1;
-                            break;
-                        }
-                    }
-                }
-            }
+            locMast = findStandardEmptyLoc(rowLastno, rowLastnoType, crnNo, nearRow, locTypeDto);
         }
 
 
 
-        // 1.鎸夎鍒欐煡鎵惧簱浣�
         if (Cools.isEmpty(locMast) && crnNo != 0) {
-            List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>()
-                    .eq("row1", nearRow)
-                    .eq("loc_sts", "O").eq("whs_type", rowLastnoType.getType().longValue())
-                    .orderBy("lev1", true).orderBy("bay1", false));
-            for (LocMast locMast1 : locMasts) {
-                if (!VersionUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) {
-                    continue;
-                }
-                if (Utils.BooleanWhsTypeStaIoType(rowLastno)) {
-                    String shallowLoc = Utils.getDeepLoc(slaveProperties, locMast1.getLocNo());
-                    LocMast locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
-                            .eq("loc_no", shallowLoc).eq("loc_sts", "O").eq("whs_type", rowLastnoType.getType().longValue()));
-                    if (!Cools.isEmpty(locMast2)) {
-                        locMast = locMast2;
-                        break;
-                    }
-                } else {
-                    if (!Cools.isEmpty(locMast1)) {
-                        locMast = locMast1;
-                        break;
-                    }
-                }
-            }
-
-            if (Cools.isEmpty(locMast) && Utils.BooleanWhsTypeStaIoType(rowLastno)) {
-                for (LocMast locMast1 : locMasts) {
-                    if (!VersionUtils.locMoveCheckLocTypeComplete(locMast1, locTypeDto)) {
-                        continue;
-                    }
-                    if (Utils.BooleanWhsTypeStaIoType(rowLastno)) {
-                        String shallowLoc = Utils.getDeepLoc(slaveProperties, locMast1.getLocNo());
-                        LocMast locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
-                                .eq("loc_no", shallowLoc).eq("loc_sts", "O").eq("whs_type", rowLastnoType.getType().longValue()));
-                        if (!Cools.isEmpty(locMast2)) {
-                            locMast = locMast2;
-                            break;
-                        } else {
-                            locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
-                                    .eq("loc_no", shallowLoc).eq("loc_sts", "F").eq("whs_type", rowLastnoType.getType().longValue()));
-                            if (!Cools.isEmpty(locMast2)) {
-                                locMast = locMast1;
-                                break;
-                            } else {
-                                locMast2 = locMastService.selectOne(new EntityWrapper<LocMast>()
-                                        .eq("loc_no", shallowLoc).eq("loc_sts", "D").eq("whs_type", rowLastnoType.getType().longValue()));
-                                if (!Cools.isEmpty(locMast2)) {
-                                    locMast = locMast1;
-                                    break;
-                                }
-                            }
-                        }
-                    } else {
-                        if (!Cools.isEmpty(locMast1)) {
-                            locMast = locMast1;
-                            break;
-                        }
-                    }
-                }
-            }
+            locMast = findStandardEmptyLoc(rowLastno, rowLastnoType, crnNo, nearRow, locTypeDto);
         }
 
         if (!Cools.isEmpty(locMast) && !basCrnpService.checkSiteError(crnNo, true)) {
             locMast = null;
         }
 
-        // 閫掑綊鏌ヨ
+        // Retry search
         if (Cools.isEmpty(locMast) || !locMast.getLocSts().equals("O")) {
-            // 褰撳墠宸烽亾鏃犵┖搴撲綅鏃讹紝閫掑綊璋冩暣鑷充笅涓�宸烽亾锛屾绱㈠叏閮ㄥ贩閬撴棤鏋滃悗锛岃烦鍑洪�掑綊
+            // Scan next aisle first, then retry with upward-compatible locType1.
             if (times < rowCount * 2) {
                 times = times + 1;
                 return getLocNoRun(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, moveCrnNo, locTypeDto, times);
             }
-//            // 2.搴撲綅褰撳墠鎵�灞炲昂瀵告棤绌哄簱浣嶆椂锛岃皟鏁村昂瀵稿弬鏁帮紝鍚戜笂鍏煎妫�绱㈠簱浣�
-//            if (locTypeDto.getLocType1() < 2) {
-//                int i = locTypeDto.getLocType1() + 1;
-//                locTypeDto.setLocType1((short)i);
-//                return getLocNo(1, staDescId, sourceStaNo, matnr,batch,grade, locTypeDto, 0);
-//            }
-            log.error("绯荤粺娌℃湁绌哄簱浣嶏紒锛侊紒 灏哄瑙勬牸锛� {}锛� 杞娆℃暟锛歿}", JSON.toJSONString(locTypeDto), times);
-            throw new CoolException("娌℃湁绌哄簱浣�");
+            LocTypeDto compatibleLocTypeDto = buildUpwardCompatibleLocTypeDto(locTypeDto);
+            if (compatibleLocTypeDto != null) {
+                log.warn("locType1 upward compatibility retry. source={}, target={}", JSON.toJSONString(locTypeDto), JSON.toJSONString(compatibleLocTypeDto));
+                return getLocNoRun(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, moveCrnNo, compatibleLocTypeDto, 0);
+            }
+            log.error("No empty location found. spec={}, times={}", JSON.toJSONString(locTypeDto), times);
+            throw new CoolException("\u6ca1\u6709\u7a7a\u5e93\u4f4d");
         }
         String locNo = locMast.getLocNo();
 
@@ -528,6 +716,112 @@
         startupDto.setSourceStaNo(sourceStaNo);
         startupDto.setLocNo(locNo);
         return startupDto;
+    }
+
+    public StartupDto getLocNoRun2(Integer whsType, Integer staDescId, Integer sourceStaNo, FindLocNoAttributeVo findLocNoAttributeVo, Integer moveCrnNo, LocTypeDto locTypeDto, int times) {
+
+        int crnNo = 0;
+        int nearRow = 0;
+        int curRow = 0;
+        int rowCount = 0;
+        LocMast locMast = null;
+
+        StartupDto startupDto = new StartupDto();
+        RowLastno rowLastno = rowLastnoService.selectById(whsType);
+
+        if (Cools.isEmpty(rowLastno)) {
+            throw new CoolException("鏁版嵁寮傚父锛岃鑱旂郴绠$悊鍛�===>搴撲綅瑙勫垯鏈煡");
+        }
+        crnNo = rowLastno.getCurrentRow()/2+1;
+        RowLastnoType rowLastnoType = rowLastnoTypeService.selectById(rowLastno.getTypeId());
+        if (Cools.isEmpty(rowLastnoType)) {
+            throw new CoolException("鏁版嵁寮傚父锛岃鑱旂郴绠$悊鍛�===銆嬪簱浣嶈鍒欑被鍨嬫湭鐭�");
+        }
+        int crnNumber = rowLastno.getCrnQty();
+
+        curRow = rowLastno.getCurrentRow();
+
+        Wrapper<StaDesc> wrapper = null;
+        StaDesc staDesc = null;
+        BasDevp staNo = null;
+
+        if (Utils.BooleanWhsTypeSta(rowLastno, staDescId)) {
+            wrapper = new EntityWrapper<StaDesc>()
+                    .eq("type_no", staDescId)
+                    .eq("stn_no", sourceStaNo)
+                    .eq("crn_no", crnNo);
+            staDesc = staDescService.selectOne(wrapper);
+            if (Cools.isEmpty(staDesc)) {
+                log.error("type_no={},stn_no={},crn_no={}", staDescId, sourceStaNo, crnNo);
+                crnNo = 0;
+            } else {
+                staNo = basDevpService.selectById(staDesc.getCrnStn());
+                if (!staNo.getAutoing().equals("Y")) {
+                    log.error("鐩爣绔檣}涓嶅彲鐢�", staDesc.getCrnStn());
+                    crnNo = 0;
+                }
+                startupDto.setStaNo(staNo.getDevNo());
+            }
+        }
+
+        LocMast locMast1 = locMastService.selectOne(new EntityWrapper<LocMast>()
+                .eq("crn_no", crnNo)
+                .eq("loc_sts", "O")
+                .orderBy("lev1")
+                .orderBy("bay1")
+                .eq("loc_type1",locTypeDto.getLocType1()));
+        if (!Cools.isEmpty(locMast1)) {
+            locMast=locMast1;
+        }
+        if (curRow==rowLastno.geteRow()-1) {
+            curRow = 1;
+        }else{
+            curRow = curRow + 2;
+        }
+        rowLastno.setCurrentRow(curRow);
+        rowLastnoService.updateById(rowLastno);
+
+        if (!Cools.isEmpty(locMast) && !basCrnpService.checkSiteError(crnNo, true)) {
+            locMast = null;
+        }
+
+        if (Cools.isEmpty(locMast) || !locMast.getLocSts().equals("O")) {
+            if (times < rowCount * 2) {
+                times = times + 1;
+                return getLocNoRun2(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, moveCrnNo, locTypeDto, times);
+            }
+            LocTypeDto compatibleLocTypeDto = buildUpwardCompatibleLocTypeDto(locTypeDto);
+            if (compatibleLocTypeDto != null) {
+                log.warn("locType1 upward compatibility retry. source={}, target={}", JSON.toJSONString(locTypeDto), JSON.toJSONString(compatibleLocTypeDto));
+                return getLocNoRun2(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, moveCrnNo, compatibleLocTypeDto, 0);
+            }
+            log.error("No empty location found. spec={}, times={}", JSON.toJSONString(locTypeDto), times);
+            throw new CoolException("\u6ca1\u6709\u7a7a\u5e93\u4f4d");
+        }
+
+        int workNo = getWorkNo(0);
+        startupDto.setWorkNo(workNo);
+        startupDto.setCrnNo(crnNo);
+        startupDto.setSourceStaNo(sourceStaNo);
+        startupDto.setLocNo(locMast.getLocNo());
+        return startupDto;
+    }
+
+    private LocMast findSingleExtensionEmptyLoc(RowLastno rowLastno, int crnNo, int nearRow, RowLastnoType rowLastnoType, LocTypeDto locTypeDto) {
+        for (Integer searchRow : getCrnSearchRows(rowLastno, crnNo, nearRow)) {
+            List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>()
+                    .eq("row1", searchRow)
+                    .eq("loc_sts", "O")
+                    .eq("whs_type", rowLastnoType.getType().longValue())
+                    .orderBy("bay1", true)
+                    .orderBy("lev1", true));
+            for (LocMast locMast : locMasts) {
+                if (VersionUtils.locMoveCheckLocTypeComplete(locMast, locTypeDto)) {
+                    return locMast;
+                }
+            }
+        }
+        return null;
     }
 
     public StartupDto getLocNoRun4(Integer whsType, Integer staDescId, Integer sourceStaNo, FindLocNoAttributeVo findLocNoAttributeVo, Integer moveCrnNo, LocTypeDto locTypeDto, int times) {
@@ -928,10 +1222,10 @@
                         continue;
                     }
                     if (Utils.BooleanWhsTypeStaIoType(rowLastno)) {
-                        //鑾峰彇鐩爣搴撲綅鎵�鍦ㄥ贩閬撳苟鎺掑簭
+                        // ?????????????
 //                        List<String> groupOutsideLocCrn = Utils.getGroupOutLocCrn(curRow,nearRow,locMast1.getLocNo(), curRow>nearRow);
 
-                        //鑾峰彇鐩爣搴撲綅鎵�鍦ㄥ贩閬撴渶娴呴潪绌哄簱浣�
+                        // ????????????????
                         LocMast locMast2 = locMastService.selectLocByLocStsPakInF(curRow, nearRow, locMast1, rowLastnoType.getType().longValue());
                         if (Cools.isEmpty(locMast2)) {
                             LocMast locMast3 = locMastService.selectLocByLocStsPakInO(curRow, nearRow, locMast1, rowLastnoType.getType().longValue());
@@ -953,15 +1247,20 @@
             }
         }
 
-        // 閫掑綊鏌ヨ
+        // Retry search
         if (Cools.isEmpty(locMast) || !locMast.getLocSts().equals("O")) {
-            // 褰撳墠宸烽亾鏃犵┖搴撲綅鏃讹紝閫掑綊璋冩暣鑷充笅涓�宸烽亾锛屾绱㈠叏閮ㄥ贩閬撴棤鏋滃悗锛岃烦鍑洪�掑綊
+            // Scan next aisle first, then retry with upward-compatible locType1.
             if (times < rowCount * 2) {
                 times = times + 1;
                 return getLocNoRun4(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, moveCrnNo, locTypeDto, times);
             }
-            log.error("绯荤粺娌℃湁绌哄簱浣嶏紒锛侊紒 灏哄瑙勬牸锛� {}锛� 杞娆℃暟锛歿}", JSON.toJSONString(locTypeDto), times);
-            throw new CoolException("娌℃湁绌哄簱浣�");
+            LocTypeDto compatibleLocTypeDto = buildUpwardCompatibleLocTypeDto(locTypeDto);
+            if (compatibleLocTypeDto != null) {
+                log.warn("locType1 upward compatibility retry. source={}, target={}", JSON.toJSONString(locTypeDto), JSON.toJSONString(compatibleLocTypeDto));
+                return getLocNoRun4(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, moveCrnNo, compatibleLocTypeDto, 0);
+            }
+            log.error("No empty location found. spec={}, times={}", JSON.toJSONString(locTypeDto), times);
+            throw new CoolException("\u6ca1\u6709\u7a7a\u5e93\u4f4d");
         }
         String locNo = locMast.getLocNo();
 
@@ -975,7 +1274,7 @@
         return startupDto;
     }
 
-    public StartupDto getLocNoRun5(Integer whsType, Integer staDescId, Integer sourceStaNo, FindLocNoAttributeVo findLocNoAttributeVo, Integer moveCrnNo, LocTypeDto locTypeDto, int times) {
+    public StartupDto getLocNoRun5(Integer whsType, Integer staDescId, Integer sourceStaNo, FindLocNoAttributeVo findLocNoAttributeVo, Integer moveCrnNo, LocTypeDto locTypeDto, List<Integer> recommendRows, int times) {
 
         // 鍒濆鍖栧弬鏁�
         int crnNo = 0;      //鍫嗗灈鏈哄彿
@@ -1045,6 +1344,20 @@
         }
 
         // 寮�濮嬫煡鎵惧簱浣� ==============================>>
+
+        if (Cools.isEmpty(locMast) && !Cools.isEmpty(recommendRows)) {
+            for (Integer recommendRow : recommendRows) {
+                if (Cools.isEmpty(recommendRow)) {
+                    continue;
+                }
+                LocMast recommendLoc = locMastService.queryFreeLocMast(recommendRow, locTypeDto.getLocType1(), rowLastnoType.getType().longValue());
+                if (!Cools.isEmpty(recommendLoc) && VersionUtils.locMoveCheckLocTypeComplete(recommendLoc, locTypeDto)) {
+                    locMast = recommendLoc;
+                    crnNo = recommendLoc.getCrnNo();
+                    break;
+                }
+            }
+        }
 
         if (Cools.isEmpty(locMast) && sourceStaNo != 4006) {//si'lou'p鍥涙ゼ鐩樼偣閫夋嫨鍖哄煙
                  List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>()
@@ -1143,7 +1456,7 @@
                             continue;
                         }
                         if (Utils.BooleanWhsTypeStaIoType(rowLastno)) {
-                            // 鑾峰彇鐩爣搴撲綅鎵�鍦ㄥ贩閬撴渶娣辩┖搴撲綅
+                            // ???????????????
                             LocMast locMast2 = locMastService.selectLocByLocStsPakInO(curRow, nearRow, locMast1, rowLastnoType.getType().longValue());
                             if (!Cools.isEmpty(locMast2) && locMast2.getRow1() == curRow) {
                                 locMast = locMast2;
@@ -1154,7 +1467,7 @@
                     }
 
                     if (found) {
-                        break; // 鎵惧埌鐩爣搴撲綅鍚庤烦鍑哄惊鐜�
+                        break; // ???????????
                     }
                 }
             }
@@ -1162,15 +1475,20 @@
 
 
 
-        // 閫掑綊鏌ヨ
+        // Retry search
         if (Cools.isEmpty(locMast) || !locMast.getLocSts().equals("O")) {
-            // 褰撳墠宸烽亾鏃犵┖搴撲綅鏃讹紝閫掑綊璋冩暣鑷充笅涓�宸烽亾锛屾绱㈠叏閮ㄥ贩閬撴棤鏋滃悗锛岃烦鍑洪�掑綊
+            // Scan next aisle first, then retry with upward-compatible locType1.
             if (times < rowCount * 2) {
                 times = times + 1;
-                return getLocNoRun5(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, moveCrnNo, locTypeDto, times);
+                return getLocNoRun5(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, moveCrnNo, locTypeDto, recommendRows, times);
             }
-            log.error("绯荤粺娌℃湁绌哄簱浣嶏紒锛侊紒 灏哄瑙勬牸锛� {}锛� 杞娆℃暟锛歿}", JSON.toJSONString(locTypeDto), times);
-            throw new CoolException("娌℃湁绌哄簱浣�");
+            LocTypeDto compatibleLocTypeDto = buildUpwardCompatibleLocTypeDto(locTypeDto);
+            if (compatibleLocTypeDto != null) {
+                log.warn("locType1 upward compatibility retry. source={}, target={}", JSON.toJSONString(locTypeDto), JSON.toJSONString(compatibleLocTypeDto));
+                return getLocNoRun5(whsType, staDescId, sourceStaNo, findLocNoAttributeVo, moveCrnNo, compatibleLocTypeDto, recommendRows, 0);
+            }
+            log.error("No empty location found. spec={}, times={}", JSON.toJSONString(locTypeDto), times);
+            throw new CoolException("\u6ca1\u6709\u7a7a\u5e93\u4f4d");
         }
         String locNo = locMast.getLocNo();
 
diff --git a/src/main/java/com/zy/common/web/WcsController.java b/src/main/java/com/zy/common/web/WcsController.java
index a4d3b9e..4afa422 100644
--- a/src/main/java/com/zy/common/web/WcsController.java
+++ b/src/main/java/com/zy/common/web/WcsController.java
@@ -9,6 +9,7 @@
 import com.zy.asrs.entity.param.EmptyPlateOutParam;
 import com.zy.asrs.entity.result.FindLocNoAttributeVo;
 import com.zy.asrs.service.*;
+import com.zy.asrs.utils.Utils;
 import com.zy.common.CodeRes;
 import com.zy.common.model.LocTypeDto;
 import com.zy.common.model.StartupDto;
@@ -64,6 +65,23 @@
             if (Cools.isEmpty(param.getBarcode())) {
                 return R.error("鏉$爜涓嶈兘涓虹┖");
             }
+        WrkMast wrkMast1 = wrkMastService.selectByBarcode(param.getBarcode());
+        if (!Cools.isEmpty(wrkMast1)&&wrkMast1.getWrkSts()==2) {
+            StartupDto dto1 =new StartupDto();
+            dto1.setBarcode(param.getBarcode());
+            dto1.setStaNo(Integer.valueOf(wrkMast1.getStaNo()));
+            String wcsLoc = Utils.WMSLocToWCSLoc(wrkMast1.getLocNo());
+            dto1.setLocNo(wcsLoc);
+            dto1.setCrnNo(wrkMast1.getCrnNo());
+            dto1.setWorkNo(wrkMast1.getWrkNo());
+            dto1.setTaskNo(wrkMast1.getWrkNo()+"");
+//            dto1.setTaskPri((int) Math.round(wrkMast1.getIoPri()));
+            return R.ok(dto1);
+        }
+        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("io_type", 1));
+        if (!Cools.isEmpty(wrkMasts)&&wrkMasts.size()>30) {
+            return R.error("闄愯");
+        }
             waitPakins = waitPakinService.selectList(new EntityWrapper<WaitPakin>().eq("zpallet", param.getBarcode()));
             if (Cools.isEmpty(waitPakins)) {
                 WrkMast wrkMast = wrkMastService.selectByBarcode(param.getBarcode());
@@ -105,18 +123,7 @@
         sourceStaNo.setLocType1(param.getLocType1());
         LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo);
 
-        StartupDto dto = null;
-        switch (param.getIoType()) {
-            case 1://婊℃墭鐩樺叆搴�
-                assert waitPakins != null;
-                dto = startupFullPutStore(param.getSourceStaNo(), param.getBarcode(), locTypeDto, waitPakins);
-                break;
-            case 10://绌烘墭鐩樺叆搴�
-                dto = emptyPlateIn(param.getSourceStaNo(), locTypeDto, param.getBarcode());
-                break;
-            default:
-                break;
-        }
+        StartupDto dto = startupFullPutStore(param.getSourceStaNo(), param.getBarcode(), locTypeDto, waitPakins, param.getRow());
         log.info("WCS鍏ュ簱鎺ュ彛杩斿弬:{},鎵樼洏鐮�:{}", dto, param.getBarcode());
         return R.ok().add(dto);
     }
@@ -417,7 +424,7 @@
      * 鍏ㄦ澘鍏ュ簱
      */
     @Transactional
-    public StartupDto startupFullPutStore(Integer devpNo, String barcode, LocTypeDto locTypeDto, List<WaitPakin> waitPakins) {
+    public StartupDto startupFullPutStore(Integer devpNo, String barcode, LocTypeDto locTypeDto, List<WaitPakin> waitPakins, List<Integer> recommendRows) {
         // 婧愮珯鐐圭姸鎬佹娴�
         BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true);
         // 妫�绱㈠簱浣�
@@ -425,7 +432,7 @@
         List<String> batchs = waitPakins.stream().map(WaitPakin::getBatch).distinct().collect(Collectors.toList());
         FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(matnrs.get(0), batchs.get(0));
 //        FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(waitPakins.get(0));
-        StartupDto dto = commonService.getLocNo( 1, devpNo,findLocNoAttributeVo, locTypeDto);
+        StartupDto dto = commonService.getLocNo(1, devpNo, findLocNoAttributeVo, locTypeDto, recommendRows);
         int workNo = dto.getWorkNo();
         Date now = new Date();
         // 鐢熸垚宸ヤ綔妗�
@@ -475,12 +482,12 @@
         if (!waitPakinService.update(setParam, wrapper)) {
             throw new CoolException("鏇存柊閫氱煡妗eけ璐�");
         }
-        // 鏇存柊婧愮珯鐐逛俊鎭�
-        sourceStaNo.setWrkNo(workNo);
-        sourceStaNo.setModiTime(now);
-        if (!basDevpService.updateById(sourceStaNo)){
-            throw new CoolException("鏇存柊婧愮珯澶辫触");
-        }
+//        // 鏇存柊婧愮珯鐐逛俊鎭�
+//        sourceStaNo.setWrkNo(workNo);
+//        sourceStaNo.setModiTime(now);
+//        if (!basDevpService.updateById(sourceStaNo)){
+//            throw new CoolException("鏇存柊婧愮珯澶辫触");
+//        }
         // 鏇存柊鐩爣搴撲綅鐘舵��
         LocMast locMast = locMastService.selectById(dto.getLocNo());
         if (locMast.getLocSts().equals("O")){
@@ -492,6 +499,9 @@
         } else {
             throw new CoolException(dto.getLocNo()+"鐩爣搴撲綅宸茶鍗犵敤");
         }
+        String wcsLoc = Utils.WMSLocToWCSLoc(dto.getLocNo());
+        dto.setLocNo(wcsLoc);
+        dto.setTaskNo(workNo+"");
         return dto;
     }
 
diff --git a/src/main/java/com/zy/common/web/param/SearchLocParam.java b/src/main/java/com/zy/common/web/param/SearchLocParam.java
index ccdd3c4..009d3ce 100644
--- a/src/main/java/com/zy/common/web/param/SearchLocParam.java
+++ b/src/main/java/com/zy/common/web/param/SearchLocParam.java
@@ -11,14 +11,11 @@
 public class SearchLocParam {
     private String barcode;
     private Integer sourceStaNo;
-    private List<Integer> rowList;
+    private List<Integer> row;
 
-    // 搴撲綅瑙勬牸锛� 0:鏈煡, 1:浣庡簱浣�, 2:楂樺簱浣嶏級
+    // 搴撲綅瑙勬牸锛�0:鏈煡, 1:浣庡簱浣�, 2:楂樺簱浣嶏級
     private Short locType1;
 
     private Integer ioType;
     private Integer outArea;
-
-
-
 }
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 5d4c25a..5eafde0 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -112,3 +112,5 @@
     createOutTask: /openapi/createOutTask
     #绉诲簱浠诲姟涓嬪彂鍦板潃
     createLocMoveTask: /openapi/createLocMoveTask
+    #pause out task
+    stopOutTask: /openapi/stopOutTask

--
Gitblit v1.9.1