From c1aabd3aaa92b072591fc368d81ab2cc37a0aa14 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期五, 27 三月 2026 17:33:25 +0800
Subject: [PATCH] 路由变更

---
 Code/WCS/docs(superpowers)/specs/2026-03-27-task-logging-design.md                   |  167 +++++++
 Code/WCS/WIDESEAWCS_Server/docs/superpowers/plans/2026-03-27-router-cache.md         |  239 ++++++++++
 Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs                      |  223 +++++----
 Code/WCS/WIDESEAWCS_Server/docs/superpowers/plans/2026-03-27-router-service-audit.md |  324 ++++++++++++++
 项目资料/设备协议/上位系统对接/陕西顷刻能源科技MES系统对接接口.md                                                |  329 ++++++++++++++
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs             |   11 
 6 files changed, 1,184 insertions(+), 109 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
index 1a04379..b060189 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Service/RouterService.cs
@@ -1,11 +1,5 @@
 锘縰sing SqlSugar;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 using WIDESEAWCS_Common;
-using WIDESEAWCS_Common.TaskEnum;
 using WIDESEAWCS_Core;
 using WIDESEAWCS_Core.BaseServices;
 using WIDESEAWCS_Core.Enums;
@@ -533,11 +527,12 @@
                     _cacheService.TryAdd($"{RedisPrefix.System}:{RedisName.DevicePositions}:{deviceCode}", positions);
                 }
             }
-            else 
+            else
                 positions = device;
             // 杩斿洖浣嶇疆鍒楄〃
             return positions;
         }
+
         /// <summary>
         /// 鑾峰彇璺敱琛ㄤ腑鎵�鏈夊畬鏁寸殑璺敱淇℃伅(鍓嶇璋冪敤灞曠ず鏁版嵁)銆�
         /// </summary>
@@ -742,4 +737,4 @@
             return content;
         }
     }
-}
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/docs/superpowers/plans/2026-03-27-router-cache.md b/Code/WCS/WIDESEAWCS_Server/docs/superpowers/plans/2026-03-27-router-cache.md
new file mode 100644
index 0000000..8c65dee
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/docs/superpowers/plans/2026-03-27-router-cache.md
@@ -0,0 +1,239 @@
+# 璺敱缂撳瓨瀹炵幇璁″垝
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** 鍦� RouterService 涓紩鍏� HybridCacheService 娣峰悎缂撳瓨锛岀涓�娆℃煡璇㈠姞杞藉叏閲忚矾鐢卞埌缂撳瓨锛屽悗缁煡璇㈢洿鎺ヤ粠缂撳瓨璇诲彇锛孉ddRouters 鍐欏叆鍚庡悓姝ユ洿鏂扮紦瀛樸��
+
+**Architecture:** 鎸� InOutType 鍒嗗紑缂撳瓨涓や唤锛堝叆鍙�/鍑哄彛锛夛紝GetOrAdd 鎳掑姞杞斤紝鍐欑┛鏇存柊缂撳瓨锛屽崟瀹炰緥閮ㄧ讲鏃犲箍鎾渶姹傘��
+
+**Tech Stack:** ASP.NET Core 6.0, HybridCacheService, SqlSugar ORM
+
+---
+
+## 鏂囦欢鍙樻洿姒傝
+
+**淇敼鏂囦欢锛�**
+- `WIDESEAWCS_QuartzJob/Service/RouterService.cs` 鈥� 鍏ㄩ儴缂撳瓨閫昏緫鏀瑰姩
+
+**涓嶅彉锛�**
+- `FindRoutesInMemory` 鈥� 鍙敼璋冪敤鏂癸紝绠楁硶閫昏緫涓嶅彉
+- `QueryAllPositions` 鈥� 宸叉湁鐙珛缂撳瓨锛屼笉渚濊禆鏈柟妗�
+
+---
+
+## Task 1: 鏂板 GetAllRoutersFromCache 绉佹湁鏂规硶
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs`
+
+鍦ㄧ被鎴愬憳鍙橀噺澹版槑鍖轰箣鍚庛�佺幇鏈夋柟娉曚箣鍓嶏紝鏂板浠ヤ笅绉佹湁鏂规硶锛�
+
+```csharp
+/// <summary>
+/// 浠庣紦瀛樿幏鍙栨寚瀹氱被鍨嬬殑鍏ㄩ噺璺敱鏁版嵁锛岀紦瀛樹笉瀛樺湪鏃惰嚜鍔ㄤ粠鏁版嵁搴撳姞杞藉苟鍐欏叆缂撳瓨
+/// </summary>
+/// <param name="routeType">璺敱绫诲瀷锛堝叆鍙�/鍑哄彛锛�</param>
+/// <returns>璇ョ被鍨嬬殑鍏ㄩ儴璺敱鍒楄〃</returns>
+private List<Dt_Router> GetAllRoutersFromCache(int routeType)
+{
+    string cacheKey = $"Router:AllRouters:{(routeType == RouterInOutType.In.ObjToInt() ? "In" : "Out")}";
+    return _cacheService.GetOrAdd(
+        cacheKey,
+        () => BaseDal.QueryData(x => x.InOutType == routeType)
+    );
+}
+
+---
+
+## Task 2: 鏀归�� QueryNextRoutes 閲嶈浇锛�2涓柟娉曪級
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs:48-98`
+
+### QueryNextRoutes(string, string) 鈥� 绗�48-69琛�
+
+鍘熶唬鐮侊細
+```csharp
+List<Dt_Router> allRouters = BaseDal.QueryData(x => true);
+routers = FindRoutesInMemory(startPosi, endPosi, allRouters, null);
+```
+
+鏀逛负锛�
+```csharp
+List<Dt_Router> allRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt());
+// 鍏ュ彛+鍑哄彛閮藉姞杞斤紝FindRoutesInMemory 鍐呴儴鎸� routeType==null 涓嶅仛杩囨护
+List<Dt_Router> outRouters = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt());
+allRouters.AddRange(outRouters);
+routers = FindRoutesInMemory(startPosi, endPosi, allRouters, null);
+```
+
+### QueryNextRoutes(string, string, int) 鈥� 绗�78-99琛�
+
+鍘熶唬鐮侊細
+```csharp
+List<Dt_Router> allRouters = BaseDal.QueryData(x => x.InOutType == routeType);
+routers = FindRoutesInMemory(startPosi, endPosi, allRouters, routeType);
+```
+
+鏀逛负锛�
+```csharp
+List<Dt_Router> allRouters = GetAllRoutersFromCache(routeType);
+routers = FindRoutesInMemory(startPosi, endPosi, allRouters, routeType);
+```
+
+---
+
+## Task 3: 鏀归�� QueryNextRoute 閲嶈浇锛�4涓柟娉曪級
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs:189-314`
+
+### QueryNextRoute(string) 鈥� 绗�189-205琛�
+
+鍘熶唬鐮侊細
+```csharp
+List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi, ...);
+return routes.FirstOrDefault();
+```
+
+鏀逛负锛�
+```csharp
+List<Dt_Router> routes = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt())
+    .Where(x => x.StartPosi == startPosi)
+    .ToList();
+routes = routes.OrderByDescending(x => x.IsEnd).ToList();
+return routes.FirstOrDefault();
+```
+
+### QueryNextRoute(string, int) 鈥� 绗�213-229琛�
+
+鍘熶唬鐮侊細
+```csharp
+List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi && x.InOutType == routeType, ...);
+return routes.FirstOrDefault();
+```
+
+鏀逛负锛�
+```csharp
+List<Dt_Router> routes = GetAllRoutersFromCache(routeType)
+    .Where(x => x.StartPosi == startPosi)
+    .ToList();
+routes = routes.OrderByDescending(x => x.IsEnd).ToList();
+return routes.FirstOrDefault();
+```
+
+### QueryNextRoute(string, string, int) 鈥� 绗�238-272琛�
+
+鍘熶唬鐮侊紙绗�255琛岋級锛�
+```csharp
+List<Dt_Router> allRouters = BaseDal.QueryData(x => x.InOutType == routeType);
+```
+
+鏀逛负锛�
+```csharp
+List<Dt_Router> allRouters = GetAllRoutersFromCache(routeType);
+```
+
+鍏朵綑鐩存帴璺敱鍒ゆ柇鍜� `FindRoutesInMemory` 璋冪敤閫昏緫涓嶅彉銆�
+
+### QueryNextRoute(string, string) 鈥� 绗�280-314琛�
+
+鍘熶唬鐮侊紙绗�285琛岋級锛�
+```csharp
+List<Dt_Router> routes = BaseDal.QueryData(x => x.StartPosi == startPosi, ...);
+```
+
+鏀逛负锛堝悎骞跺叆鍙�+鍑哄彛涓や唤缂撳瓨锛屼笌鍘熸柟娉曞叏閲忔煡璇㈣涔変竴鑷达級锛�
+```csharp
+List<Dt_Router> inRoutes = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt());
+List<Dt_Router> outRoutes = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt());
+List<Dt_Router> routes = inRoutes.Concat(outRoutes)
+    .Where(x => x.StartPosi == startPosi)
+    .ToList();
+routes = routes.OrderByDescending(x => x.IsEnd).ToList();
+```
+
+鐒跺悗澶嶇敤宸叉湁鐨勭洿鎺ヨ矾鐢卞垽鏂�昏緫銆�
+
+---
+
+## Task 4: 鏀归�� QueryRoutePath
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs:323-366`
+
+绗�355琛岄檮杩戯紝鍘熶唬鐮佷腑 `while` 寰幆閲屾瘡娆¤皟鐢� `QueryNextRoute` 鐨勯�昏緫**涓嶉渶瑕佹敼鍔�**锛堝洜涓� `QueryNextRoute` 宸茬粡鍦� Task3 涓敼閫犱簡锛夈�傛湰浠诲姟鐨勬敼鍔ㄤ粎纭 `QueryRoutePath` 鏂规硶鏈韩涓嶅啀鐩存帴璋冪敤 `BaseDal.QueryData`锛屽嵆涓嶉渶瑕佷换浣曟敼鍔� 鈥斺�� 瀹冭皟鐢ㄧ殑鏄� `QueryNextRoute`锛岃�屽悗鑰呭凡琚敼閫犮��
+
+**楠岃瘉锛�** 纭 `QueryRoutePath` 鏂规硶浣撳唴娌℃湁鐩存帴璋冪敤 `BaseDal.QueryData`锛屽彧鏈夊 `QueryNextRoute` 鐨勮皟鐢ㄣ��
+
+---
+
+## Task 5: 鏀归�� GetAllWholeRouters
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs:412-446`
+
+鍘熶唬鐮侊細
+```csharp
+List<Dt_Router> allRouters = BaseDal.QueryData(x => true);
+```
+
+鏀逛负锛�
+```csharp
+List<Dt_Router> inRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt());
+List<Dt_Router> outRouters = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt());
+List<Dt_Router> allRouters = inRouters.Concat(outRouters).ToList();
+```
+
+鍚庣画閬嶅巻 `dt_Routers`锛堝彇 `IsEnd == true` 鐨勮矾鐢憋級鐨勯�昏緫涓嶅彉銆�
+
+---
+
+## Task 6: 鏀归�� AddRouters锛屽啓鍏� DB 鍚庢洿鏂扮紦瀛�
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs:511-594`
+
+鍦ㄧ568琛岄檮杩戯紝鎵惧埌锛�
+```csharp
+// 鏌ヨ鏁版嵁搴撲腑宸叉湁鐨勮矾鐢变俊鎭�
+List<Dt_Router> dt_Routers = BaseDal.QueryData(x => x.InOutType == routerType);
+```
+
+杩欎釜 `dt_Routers` 鏄�**娣诲姞涔嬪墠**鐨勫凡鏈夋暟鎹紝涓嶅寘鍚湰娆℃柊澧炵殑璺敱銆傚湪绗�586琛� `BaseDal.AddData(routers)` **涔嬪悗**銆乣content = WebResponseContent.Instance.OK()` **涔嬪墠**锛屽繀椤婚噸鏂版煡璇竴娆″叏閲忔暟鎹啀鍐欏叆缂撳瓨锛�
+
+```csharp
+// 娣诲姞鏂扮殑璺敱淇℃伅
+BaseDal.AddData(routers);
+
+// 閲嶆柊鏌ヨ鍏ㄩ噺璺敱锛堟鏃舵墠鍖呭惈鏂板鐨勮矾鐢憋級锛屽啀鍐欏叆缂撳瓨
+List<Dt_Router> updatedRouters = BaseDal.QueryData(x => x.InOutType == routerType);
+string cacheKey = $"Router:AllRouters:{(routerType == RouterInOutType.In.ObjToInt() ? "In" : "Out")}";
+_cacheService.Set(cacheKey, updatedRouters);
+
+content = WebResponseContent.Instance.OK();
+```
+
+---
+
+## Task 7: 缂栬瘧楠岃瘉
+
+**楠岃瘉鍛戒护锛�**
+```bash
+dotnet build WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/WIDESEAWCS_QuartzJob.csproj
+```
+
+棰勬湡锛氭棤缂栬瘧閿欒锛圕S0103/CS0019 绛夌被鍨�/璇硶閿欒鍏ㄩ儴淇鍚庯級
+
+---
+
+## 瀹炴柦椤哄簭
+
+1. Task 1 鈥� 鏂板 `GetAllRoutersFromCache` 绉佹湁鏂规硶
+2. Task 2 鈥� 鏀归�� `QueryNextRoutes` 涓や釜閲嶈浇
+3. Task 3 鈥� 鏀归�� `QueryNextRoute` 鍥涗釜閲嶈浇
+4. Task 4 鈥� 纭 `QueryRoutePath` 鏃犻渶鏀瑰姩锛堝畠渚濊禆宸叉敼閫犵殑 `QueryNextRoute`锛�
+5. Task 5 鈥� 鏀归�� `GetAllWholeRouters`
+6. Task 6 鈥� 鏀归�� `AddRouters` 鏇存柊缂撳瓨
+7. Task 7 鈥� 缂栬瘧楠岃瘉
+
diff --git a/Code/WCS/WIDESEAWCS_Server/docs/superpowers/plans/2026-03-27-router-service-audit.md b/Code/WCS/WIDESEAWCS_Server/docs/superpowers/plans/2026-03-27-router-service-audit.md
new file mode 100644
index 0000000..bf28dd8
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/docs/superpowers/plans/2026-03-27-router-service-audit.md
@@ -0,0 +1,324 @@
+# RouterService 閫昏緫淇涓庢柊鏂规硶瀹炵幇璁″垝
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** 淇 RouterService 涓殑 3 涓�昏緫闂锛屾柊澧� 7 涓矾鐢辨煡璇�/绠$悊鏂规硶锛屽苟鏇存柊鎺ュ彛灞傘��
+
+**Architecture:** 鍦ㄧ幇鏈� RouterService 鍩虹涓婃柊澧炵紦瀛樼鐞嗘柟娉曞拰璺敱鏌ヨ澧炲己鏂规硶锛屼繚鎸佺幇鏈� HybridCacheService 缂撳瓨鏋舵瀯涓嶅彉銆�
+
+**Tech Stack:** ASP.NET Core 6.0, HybridCacheService, SqlSugar ORM
+
+---
+
+## 鏂囦欢鍙樻洿姒傝
+
+**淇敼鏂囦欢锛�**
+- `WIDESEAWCS_QuartzJob/Service/RouterService.cs` 鈥� 閫昏緫淇 + 鏂板鏂规硶瀹炵幇
+- `WIDESEAWCS_QuartzJob/Service/IRouterService.cs` 鈥� 鎺ュ彛鏂板鏂规硶绛惧悕 + 鍘绘帀澶氫綑 `public` 淇グ绗�
+
+---
+
+## Task 1: 淇 AddRouters 缂撳瓨涓�鑷存�ч棶棰�
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs:605-613`
+
+**鍘熶唬鐮侊細**
+```csharp
+BaseDal.AddData(routers);
+
+List<Dt_Router> updatedRouters = BaseDal.QueryData(x => x.InOutType == routerType);
+string cacheKey = $"Router:AllRouters:{(routerType == RouterInOutType.In.ObjToInt() ? "In" : "Out")}";
+_cacheService.AddOrUpdate(cacheKey, updatedRouters);
+
+content = WebResponseContent.Instance.OK();
+```
+
+**鏀逛负锛�**
+```csharp
+// 娣诲姞鏂扮殑璺敱淇℃伅
+BaseDal.AddData(routers);
+
+// 閲嶆柊鏌ヨ鍏ㄩ噺璺敱锛堟鏃舵墠鍖呭惈鏂板鐨勮矾鐢憋級锛屽啀鍐欏叆缂撳瓨
+List<Dt_Router> updatedRouters = BaseDal.QueryData(x => x.InOutType == routerType);
+string cacheKey = $"Router:AllRouters:{(routerType == RouterInOutType.In.ObjToInt() ? "In" : "Out")}";
+
+try
+{
+    _cacheService.AddOrUpdate(cacheKey, updatedRouters);
+}
+catch
+{
+    // 缂撳瓨鏇存柊澶辫触鏃堕潤榛樺拷鐣ワ紝涓嬫鏌ヨ浼氫粠DB鑷姩閲嶅缓缂撳瓨
+}
+
+content = WebResponseContent.Instance.OK();
+```
+
+**璇存槑**锛氱敤 try-catch 鍖呰9缂撳瓨鏇存柊鎿嶄綔锛岄槻姝㈢紦瀛樺啓鍏ュけ璐ユ椂寮傚父閫冮�稿埌澶栧眰琚綋浣滈敊璇繑鍥炪�侱B 宸插啓鍏ユ垚鍔燂紝缂撳瓨澶辫触涓嶅奖鍝嶄笟鍔℃纭�с��
+
+---
+
+## Task 2: 淇 QueryAllPositions 绌� catch 鍧�
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs:412-415`
+
+**鍘熶唬鐮侊細**
+```csharp
+catch
+{
+
+}
+```
+
+**鏀逛负锛�**
+```csharp
+catch (Exception ex)
+{
+    ConsoleHelper.WriteErrorLine($"RouterService.QueryAllPositions 鏌ヨ澶辫触: {ex.Message}");
+}
+```
+
+**璇存槑**锛氬鍔犻敊璇棩蹇楄褰曪紝渚夸簬鎺掓煡闂銆傝繑鍥炲�间粛涓虹┖鍒楄〃锛岃皟鐢ㄦ柟琛屼负涓嶅彉銆�
+
+---
+
+## Task 3: 淇 IRouterService 鎺ュ彛 public 淇グ绗� + 鏂板鏂规硶绛惧悕
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/IRouterService.cs`
+
+鍘绘帀浠ヤ笅琛岀殑 `public` 淇グ绗︼細
+- 绗�40琛岋細`public Dt_Router QueryNextRoute(string startPosi);` 鈫� `Dt_Router QueryNextRoute(string startPosi);`
+- 绗�48琛�
+- 绗�57琛�
+- 绗�65琛�
+- 绗�74琛�
+
+鍚屾椂鍦ㄦ帴鍙f湯灏炬柊澧炰互涓嬫柟娉曠鍚嶏細
+
+```csharp
+/// <summary>
+/// 娓呴櫎璺敱缂撳瓨
+/// </summary>
+void ClearRouterCache();
+
+/// <summary>
+/// 鏍规嵁璁惧缂栧彿鏌ヨ缁忚繃璇ヨ澶囩殑鎵�鏈夎矾鐢�
+/// </summary>
+List<Dt_Router> QueryRoutersByDeviceCode(string deviceCode);
+
+/// <summary>
+/// 鍒ゆ柇涓ょ偣涔嬮棿鏄惁瀛樺湪璺敱锛堝叏绫诲瀷锛�
+/// </summary>
+bool ExistsRouter(string startPosi, string endPosi);
+
+/// <summary>
+/// 鍒ゆ柇涓ょ偣涔嬮棿鏄惁瀛樺湪鎸囧畾绫诲瀷鐨勮矾鐢�
+/// </summary>
+bool ExistsRouter(string startPosi, string endPosi, int routeType);
+
+/// <summary>
+/// 鑾峰彇鍏ㄩ噺璺敱鏁伴噺锛堝悎骞跺叆鍙�+鍑哄彛锛�
+/// </summary>
+int GetRouterCount();
+
+/// <summary>
+/// 鑾峰彇鎸囧畾绫诲瀷璺敱鏁伴噺
+/// </summary>
+int GetRouterCount(int routeType);
+
+/// <summary>
+/// 鎵归噺鍒犻櫎璺敱
+/// </summary>
+WebResponseContent DeleteRouters(List<long> routerIds);
+```
+
+---
+
+## Task 4: 瀹炵幇 ClearRouterCache()
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs`
+
+鍦� `GetAllRoutersFromCache` 鏂规硶涔嬪悗鏂板锛�
+
+```csharp
+/// <summary>
+/// 娓呴櫎鎵�鏈夎矾鐢辩紦瀛橈紙鍏ュ彛鍜屽嚭鍙g被鍨嬶級
+/// </summary>
+public void ClearRouterCache()
+{
+    _cacheService.Remove("Router:AllRouters:In");
+    _cacheService.Remove("Router:AllRouters:Out");
+}
+```
+
+---
+
+## Task 5: 瀹炵幇 QueryRoutersByDeviceCode
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs`
+
+鍦� `ClearRouterCache` 涔嬪悗鏂板锛�
+
+```csharp
+/// <summary>
+/// 鏍规嵁璁惧缂栧彿鏌ヨ缁忚繃璇ヨ澶囩殑鎵�鏈夎矾鐢憋紙鍚堝苟鍏ュ彛+鍑哄彛绫诲瀷锛�
+/// </summary>
+/// <param name="deviceCode">璁惧缂栧彿</param>
+/// <returns>缁忚繃璇ヨ澶囩殑璺敱鍒楄〃</returns>
+public List<Dt_Router> QueryRoutersByDeviceCode(string deviceCode)
+{
+    List<Dt_Router> inRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt());
+    List<Dt_Router> outRouters = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt());
+    return inRouters.Concat(outRouters)
+        .Where(x => x.ChildPosiDeviceCode == deviceCode)
+        .ToList();
+}
+```
+
+---
+
+## Task 6: 瀹炵幇 ExistsRouter锛堜袱涓噸杞斤級
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs`
+
+鍦� `QueryRoutersByDeviceCode` 涔嬪悗鏂板锛�
+
+```csharp
+/// <summary>
+/// 鍒ゆ柇涓ょ偣涔嬮棿鏄惁瀛樺湪璺敱锛堝叏绫诲瀷锛�
+/// </summary>
+public bool ExistsRouter(string startPosi, string endPosi)
+{
+    List<Dt_Router> inRouters = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt());
+    List<Dt_Router> outRouters = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt());
+    var allRouters = inRouters.Concat(outRouters).ToList();
+    var routes = FindRoutesInMemory(startPosi, endPosi, allRouters, null);
+    return routes.Count > 0;
+}
+
+/// <summary>
+/// 鍒ゆ柇涓ょ偣涔嬮棿鏄惁瀛樺湪鎸囧畾绫诲瀷鐨勮矾鐢�
+/// </summary>
+public bool ExistsRouter(string startPosi, string endPosi, int routeType)
+{
+    List<Dt_Router> allRouters = GetAllRoutersFromCache(routeType);
+    var routes = FindRoutesInMemory(startPosi, endPosi, allRouters, routeType);
+    return routes.Count > 0;
+}
+```
+
+---
+
+## Task 7: 瀹炵幇 GetRouterCount锛堜袱涓噸杞斤級
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs`
+
+鍦� `ExistsRouter` 涔嬪悗鏂板锛�
+
+```csharp
+/// <summary>
+/// 鑾峰彇鍏ㄩ噺璺敱鏁伴噺锛堝叆鍙�+鍑哄彛鍚堣锛�
+/// </summary>
+public int GetRouterCount()
+{
+    int inCount = GetAllRoutersFromCache(RouterInOutType.In.ObjToInt()).Count;
+    int outCount = GetAllRoutersFromCache(RouterInOutType.Out.ObjToInt()).Count;
+    return inCount + outCount;
+}
+
+/// <summary>
+/// 鑾峰彇鎸囧畾绫诲瀷璺敱鏁伴噺
+/// </summary>
+public int GetRouterCount(int routeType)
+{
+    return GetAllRoutersFromCache(routeType).Count;
+}
+```
+
+---
+
+## Task 8: 瀹炵幇 DeleteRouters
+
+**鏂囦欢:**
+- Modify: `WIDESEAWCS_QuartzJob/Service/RouterService.cs`
+
+鍦� `AddRouters` 鏂规硶涔嬪悗鏂板锛�
+
+```csharp
+/// <summary>
+/// 鎵归噺鍒犻櫎鎸囧畾ID鐨勮矾鐢憋紝鍒犻櫎鍚庡悓姝ユ竻闄ゅ搴旂被鍨嬬殑缂撳瓨
+/// </summary>
+/// <param name="routerIds">寰呭垹闄ょ殑璺敱ID鍒楄〃</param>
+/// <returns>杩斿洖澶勭悊缁撴灉</returns>
+public WebResponseContent DeleteRouters(List<long> routerIds)
+{
+    WebResponseContent content = new WebResponseContent();
+    try
+    {
+        if (routerIds == null || routerIds.Count == 0)
+        {
+            return content = WebResponseContent.Instance.Error("寰呭垹闄ょ殑璺敱ID鍒楄〃涓嶈兘涓虹┖");
+        }
+
+        // 鏌ヨ寰呭垹闄よ矾鐢辩殑绫诲瀷锛堢敤浜庡悗缁竻闄ょ紦瀛橈級
+        var routersToDelete = BaseDal.QueryData(x => routerIds.Contains(x.Id));
+        if (routersToDelete.Count == 0)
+        {
+            return content = WebResponseContent.Instance.Error("鏈壘鍒板緟鍒犻櫎鐨勮矾鐢�");
+        }
+
+        // 璁板綍娑夊強鐨勭被鍨嬶紙鍘婚噸锛�
+        var affectedTypes = routersToDelete.Select(x => x.InOutType).Distinct().ToList();
+
+        // 鎵ц鎵归噺鍒犻櫎
+        BaseDal.DeleteData(routersToDelete);
+
+        // 娓呴櫎鍙楀奖鍝嶇被鍨嬬殑缂撳瓨
+        foreach (var routeType in affectedTypes)
+        {
+            string cacheKey = $"Router:AllRouters:{(routeType == RouterInOutType.In.ObjToInt() ? "In" : "Out")}";
+            _cacheService.Remove(cacheKey);
+        }
+
+        content = WebResponseContent.Instance.OK();
+    }
+    catch (Exception ex)
+    {
+        content = WebResponseContent.Instance.Error(ex.Message);
+    }
+    return content;
+}
+```
+
+---
+
+## Task 9: 缂栬瘧楠岃瘉
+
+**楠岃瘉鍛戒护锛�**
+```bash
+dotnet build WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/WIDESEAWCS_QuartzJob.csproj
+```
+
+棰勬湡锛�0 errors
+
+---
+
+## 瀹炴柦椤哄簭
+
+1. Task 1 鈥� 淇 AddRouters 缂撳瓨涓�鑷存��
+2. Task 2 鈥� 淇 QueryAllPositions 绌� catch 鍧�
+3. Task 3 鈥� 淇 IRouterService 鎺ュ彛锛堝幓鎺� public + 鏂板绛惧悕锛�
+4. Task 4 鈥� 瀹炵幇 ClearRouterCache
+5. Task 5 鈥� 瀹炵幇 QueryRoutersByDeviceCode
+6. Task 6 鈥� 瀹炵幇 ExistsRouter 涓や釜閲嶈浇
+7. Task 7 鈥� 瀹炵幇 GetRouterCount 涓や釜閲嶈浇
+8. Task 8 鈥� 瀹炵幇 DeleteRouters
+9. Task 9 鈥� 缂栬瘧楠岃瘉
+
diff --git "a/Code/WCS/docs\050superpowers\051/specs/2026-03-27-task-logging-design.md" "b/Code/WCS/docs\050superpowers\051/specs/2026-03-27-task-logging-design.md"
new file mode 100644
index 0000000..06d9025
--- /dev/null
+++ "b/Code/WCS/docs\050superpowers\051/specs/2026-03-27-task-logging-design.md"
@@ -0,0 +1,167 @@
+# 浠诲姟鏃ュ織澧炲己璁捐鏂囨。
+
+## 姒傝堪
+
+涓� `RobotJob`銆乣ConveyorLineNewJob`銆乣StackerCraneJob` 涓変釜妯″潡娣诲姞瀹屽杽鐨勬棩蹇楄褰曞姛鑳姐��
+
+## 鏃ュ織瑙勮寖
+
+### 鏃ュ織绾у埆瀹氫箟锛堜弗鏍兼寜璇箟锛�
+
+| 绾у埆 | 鐢ㄩ�� | 绀轰緥鍦烘櫙 |
+|------|------|----------|
+| `Info` | 姝e父娴佺▼鑺傜偣 | 浠诲姟寮�濮嬪鐞嗐�佸懡浠や笅鍙戞垚鍔熴�佺姸鎬佽浆鎹㈠畬鎴� |
+| `Warn` | 闇�瑕佸叧娉ㄤ絾闈為敊璇� | 瀹㈡埛绔柇杩為噸璇曘�佺珯鍙颁笉鍙敤銆佺増鏈啿绐� |
+| `Error` | 寮傚父/澶辫触 | WMS 璋冪敤澶辫触銆佸懡浠ゅ彂閫佸け璐ャ�佷换鍔℃煡璇㈠け璐� |
+| `Debug` | 璇︾粏淇℃伅 | 杞鎿嶄綔銆佺紦瀛樿鍙栵紙鍙�夛級 |
+
+### 鏃ュ織杈撳嚭鏂瑰紡
+
+1. **ILogger<T>** - 閫氳繃渚濊禆娉ㄥ叆鎴栫埗绫讳紶閫�
+2. **QuartzLogger** - 寮傛鏂囦欢鏃ュ織锛屽悓鏃惰褰�
+
+```csharp
+// 鏍囧噯鏃ュ織鍐欐硶
+_logger.LogInformation("娑堟伅鍐呭");
+QuartzLogger.Info("娑堟伅鍐呭", source);
+```
+
+## 淇敼娓呭崟
+
+### RobotJob 妯″潡
+
+#### RobotJob.cs
+- 鐘舵�侊細宸叉湁 ILogger锛屾棤闇�淇敼
+
+#### RobotClientManager.cs
+- 娣诲姞 `ILogger<RobotClientManager>`
+- 淇鏂繛鏃ュ織锛歐arn 鈫� Info锛堝鎴风鏂紑鏄甯告祦绋嬶級
+- 娣诲姞 EnsureClientSubscribed 涓殑閲嶈瘯/涓嶅彲鐢ㄦ棩蹇�
+
+#### RobotTaskProcessor.cs
+- 娣诲姞 `ILogger<RobotTaskProcessor>`
+- 淇 SendSocketRobotPickAsync锛欵rror 鈫� Info锛堟垚鍔熶笅鍙戝簲璁板綍 Info锛�
+- 娣诲姞 HandleInboundTaskAsync 鐨� WMS 璋冪敤缁撴灉鏃ュ織
+
+#### RobotStateManager.cs
+- 娣诲姞 `ILogger<RobotStateManager>`
+- 鏋勯�犲嚱鏁扮殑 GetOrCreateState 娣诲姞 Info 鏃ュ織
+- TryUpdateStateSafely 娣诲姞鐗堟湰鍐茬獊 Warn 鏃ュ織
+
+#### RobotMessageHandler.cs
+- 宸叉湁 ILogger锛屽凡鏈夎壇濂芥棩蹇楋紝淇濇寔涓嶅彉
+
+#### RobotWorkflowOrchestrator.cs
+- 娣诲姞 `ILogger<RobotWorkflowOrchestrator>`
+- ExecuteAsync 娣诲姞鐘舵�佹満鍐崇瓥鏃ュ織锛堟弧瓒虫潯浠舵椂璁板綍 Info锛�
+- HandlePickFinishedStateAsync 娣诲姞鏀捐揣鎸囦护涓嬪彂鏃ュ織
+- HandlePutFinishedStateAsync 娣诲姞鍙栬揣鎸囦护涓嬪彂鏃ュ織
+
+### ConveyorLineNewJob 妯″潡
+
+#### CommonConveyorLineNewJob.cs
+- 娣诲姞 `ILogger<CommonConveyorLineNewJob>`
+- Execute 鏂规硶锛�
+  - 瀛愯澶囨暟閲忎负 0锛欼nfo
+  - Parallel.For 寮�濮嬶細Debug
+  - 鍛戒护涓虹┖璺宠繃锛欴ebug
+  - WCS_ACK 澶勭悊锛欴ebug
+  - 妫�鏌ユ墭鐩樹綅缃細Info
+  - PLC_STB 妫�鏌ワ細Debug
+  - 鏃犳潯鐮佽姹傚嚭搴擄細Info
+  - 鏈変换鍔″彿澶勭悊浠诲姟锛欼nfo
+  - 寮傚父鎹曡幏锛欵rror
+- ProcessTaskState 鏂规硶锛氭坊鍔犲悇鐘舵�佸垎鏀殑鍏ュ彛鏃ュ織
+
+#### ConveyorLineDispatchHandler.cs
+- 娣诲姞 `ILogger<ConveyorLineDispatchHandler>`
+- HeartBeat锛欴ebug
+- RequestInbound锛欼nfo锛堝叆搴撹姹傚紑濮嬶級
+- RequestInNextAddress锛欼nfo锛堝叆搴撲笅涓�鍦板潃锛�
+- ConveyorLineInFinish锛欼nfo锛堝叆搴撳畬鎴愶級
+- RequestOutbound锛欼nfo锛堝嚭搴撹姹傦級
+- RequestOutNextAddress锛欼nfo锛堝嚭搴撲笅涓�鍦板潃锛�
+- ConveyorLineOutFinish锛欼nfo锛堝嚭搴撳畬鎴愶級
+
+#### ConveyorLineTaskFilter.cs
+- 娣诲姞 `ILogger<ConveyorLineTaskFilter>`
+- QueryPendingTask锛欴ebug
+- QueryExecutingTask锛欴ebug
+- RequestWmsTask锛欼nfo锛圵MS 璇锋眰锛�
+
+#### ConveyorLineTargetAddressSelector.cs
+- 娣诲姞 `ILogger<ConveyorLineTargetAddressSelector>`
+- HandleInboundNextAddress锛欴ebug
+- HandleOutboundNextAddress锛欴ebug
+- HandleDeviceRequest锛欴ebug
+- ProcessDeviceRequest锛欴ebug
+
+### StackerCraneJob 妯″潡
+
+#### CommonStackerCraneJob.cs
+- 娣诲姞 `ILogger<CommonStackerCraneJob>`
+- Execute 鏂规硶锛�
+  - 鍙傛暟鏃犳晥锛歐arn
+  - 浜嬩欢璁㈤槄锛欼nfo
+  - 浠诲姟瀹屾垚妫�鏌ワ細Debug
+  - 涓嶅彲鍙戦�佷换鍔★細Debug
+  - 浠诲姟閫夋嫨缁撴灉锛欼nfo锛堥�変腑浠诲姟鍙锋垨鏃犱换鍔★級
+  - 鍛戒护鏋勫缓缁撴灉锛欼nfo
+  - 鍛戒护鍙戦�佺粨鏋滐細Info
+  - 寮傚父鎹曡幏锛欵rror
+- CommonStackerCrane_StackerCraneTaskCompletedEventHandler锛欼nfo
+- LoadConfig 澶辫触锛歐arn
+
+#### StackerCraneTaskSelector.cs
+- 娣诲姞 `ILogger<StackerCraneTaskSelector>`
+- SelectTask锛欼nfo锛堜换鍔¢�夋嫨寮�濮嬨�侀�夋嫨缁撴灉锛�
+- TrySelectOutboundTask锛欴ebug
+- IsOutTaskStationAvailable锛欼nfo锛堢珯鍙板彲鐢�/涓嶅彲鐢級
+- TryAddTaskFromWms锛欼nfo
+
+#### StackerCraneCommandBuilder.cs
+- 娣诲姞 `ILogger<StackerCraneCommandBuilder>`
+- ConvertToStackerCraneTaskCommand锛欼nfo锛堝懡浠ょ被鍨嬨�佷换鍔″彿锛�
+- GetCommandType锛欴ebug
+- BuildInboundCommand锛欼nfo锛堝叆搴撳懡浠ゆ瀯寤猴級
+- BuildOutboundCommand锛欼nfo锛堝嚭搴撳懡浠ゆ瀯寤猴級
+- BuildRelocationCommand锛欼nfo锛堢Щ搴撳懡浠ゆ瀯寤猴級
+- 鍦板潃瑙f瀽澶辫触锛欵rror
+
+## ILogger 渚濊禆浼犻�掓柟妗�
+
+瀵逛簬閫氳繃 `new` 鐩存帴瀹炰緥鍖栫殑杈呭姪绫伙紝閫氳繃鐖剁被鏋勯�犲嚱鏁颁紶鍏� ILogger锛�
+
+```csharp
+// 杈呭姪绫绘帴鏀� ILogger
+public class RobotStateManager
+{
+    private readonly ILogger _logger;
+    public RobotStateManager(ICacheService cache, ILogger<RobotStateManager> logger)
+    {
+        _logger = logger;
+    }
+}
+
+// Job 鍦ㄥ垱寤鸿緟鍔╃被鏃朵紶鍏ヨ嚜宸辩殑 logger
+public RobotJob(..., ILogger<RobotJob> logger)
+{
+    _stateManager = new RobotStateManager(cache, logger);
+}
+```
+
+## 闇�淇鐨勬棩蹇楄涔夐棶棰�
+
+| 浣嶇疆 | 鍘熷啓娉� | 淇鍚� |
+|------|--------|--------|
+| RobotTaskProcessor.SendSocketRobotPickAsync | QuartzLogger.Error (鎴愬姛鏃�) | QuartzLogger.Info |
+| RobotClientManager.EnsureClientSubscribed | QuartzLogger.Info (寮傚父鏃�) | QuartzLogger.Error |
+| RobotClientManager.OnRobotReceived | QuartzLogger.Warn (鏂繛) | QuartzLogger.Info |
+
+## 楠屾敹鏍囧噯
+
+1. 鎵�鏈夊叧閿笟鍔¤妭鐐规湁 Info 鏃ュ織
+2. 寮傚父鎯呭喌鏈� Error 鏃ュ織骞跺寘鍚紓甯镐俊鎭�
+3. 闇�瑕佸叧娉ㄧ殑鎯呭喌鏈� Warn 鏃ュ織
+4. 鏃ュ織鍚屾椂杈撳嚭鍒� ILogger 鍜� QuartzLogger
+5. 鏃ュ織娑堟伅娓呮櫚锛屽寘鍚叧閿笂涓嬫枃锛堝浠诲姟鍙枫�佽澶囩紪鐮侊級
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
index 1bf9205..8e3c669 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
@@ -102,46 +102,53 @@
         public async Task<WebResponseContent> GroupPalletAsync(StockDTO stock)
         {
             WebResponseContent content = new WebResponseContent();
-            var now = DateTime.Now;
-            var details = stock.Details.Select(item => new Dt_StockInfoDetail
+            try
             {
-                MaterielCode = "鐢佃姱",
-                MaterielName = "鐢佃姱",
-                StockQuantity = item.Quantity,
-                Unit = "PCS",
-                Creater = "system",
-                OrderNo = "111",
-                ProductionDate = now.ToString(),
-                EffectiveDate = now.AddYears(1).ToString(),
-                SerialNumber = item.CellBarcode,
-                InboundOrderRowNo = item.Channel,
-                Status = StockStatusEmun.缁勭洏鏆傚瓨.GetHashCode(),
-            }).ToList();
-
-            return await ExecuteWithinTransactionAsync(async () =>
-            {
-                var existingStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.TargetPalletNo);
-                var result = false;
-                if (existingStock != null)
+                var now = DateTime.Now;
+                var details = stock.Details.Select(item => new Dt_StockInfoDetail
                 {
-                    details.ForEach(d => d.StockId = existingStock.Id);
-                    result = await StockInfoDetailService.Repository.AddDataAsync(details) > 0;
-                    return result ? content.OK("缁勭洏鎴愬姛") : content.Error("缁勭洏澶辫触");
-                }
-
-                var entity = new Dt_StockInfo
-                {
-                    PalletCode = stock.TargetPalletNo,
-                    //WarehouseId = stock.WarehouseId > 0 ? stock.WarehouseId : 1,
-                    WarehouseId = 1,
-                    StockStatus = StockStatusEmun.缁勭洏鏆傚瓨.GetHashCode(),
+                    MaterielCode = "鐢佃姱",
+                    MaterielName = "鐢佃姱",
+                    StockQuantity = item.Quantity,
+                    Unit = "PCS",
                     Creater = "system",
-                    Details = details
-                };
+                    OrderNo = "111",
+                    ProductionDate = now.ToString(),
+                    EffectiveDate = now.AddYears(1).ToString(),
+                    SerialNumber = item.CellBarcode,
+                    InboundOrderRowNo = item.Channel,
+                    Status = StockStatusEmun.缁勭洏鏆傚瓨.GetHashCode(),
+                }).ToList();
 
-                result = StockInfoService.Repository.AddData(entity, x => x.Details);
-                return result ? content.OK("缁勭洏鎴愬姛") : content.Error("缁勭洏澶辫触");
-            });
+                return await ExecuteWithinTransactionAsync(async () =>
+                {
+                    var existingStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.TargetPalletNo);
+                    var result = false;
+                    if (existingStock != null)
+                    {
+                        details.ForEach(d => d.StockId = existingStock.Id);
+                        result = await StockInfoDetailService.Repository.AddDataAsync(details) > 0;
+                        return result ? content.OK("缁勭洏鎴愬姛") : content.Error("缁勭洏澶辫触");
+                    }
+
+                    var entity = new Dt_StockInfo
+                    {
+                        PalletCode = stock.TargetPalletNo,
+                        //WarehouseId = stock.WarehouseId > 0 ? stock.WarehouseId : 1,
+                        WarehouseId = 1,
+                        StockStatus = StockStatusEmun.缁勭洏鏆傚瓨.GetHashCode(),
+                        Creater = "system",
+                        Details = details
+                    };
+
+                    result = StockInfoService.Repository.AddData(entity, x => x.Details);
+                    return result ? content.OK("缁勭洏鎴愬姛") : content.Error("缁勭洏澶辫触");
+                });
+            }
+            catch (Exception ex)
+            {
+                return content.Error($"缁勭洏澶辫触: {ex.Message}");
+            }
         }
 
         /// <summary>
@@ -150,55 +157,62 @@
         public async Task<WebResponseContent> ChangePalletAsync(StockDTO stock)
         {
             WebResponseContent content = new WebResponseContent();
-            if (stock == null ||
-                string.IsNullOrWhiteSpace(stock.TargetPalletNo) ||
-                string.IsNullOrWhiteSpace(stock.SourcePalletNo) ||
-                string.Equals(stock.SourcePalletNo, stock.TargetPalletNo, StringComparison.OrdinalIgnoreCase))
+            try
             {
-                return content.Error("婧愭墭鐩樺彿涓庣洰鏍囨墭鐩樺彿鐩稿悓");
-            }
-
-            return await ExecuteWithinTransactionAsync(async () =>
-            {
-                var sourceStock = await StockInfoService.Repository.QueryDataNavFirstAsync(s => s.PalletCode == stock.SourcePalletNo);
-                if (sourceStock == null) return content.Error("婧愭墭鐩樹笉瀛樺湪");
-
-                var targetStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.TargetPalletNo);
-                if (targetStock == null)
+                if (stock == null ||
+                    string.IsNullOrWhiteSpace(stock.TargetPalletNo) ||
+                    string.IsNullOrWhiteSpace(stock.SourcePalletNo) ||
+                    string.Equals(stock.SourcePalletNo, stock.TargetPalletNo, StringComparison.OrdinalIgnoreCase))
                 {
-                    var newStock = new Dt_StockInfo
-                    {
-                        PalletCode = stock.TargetPalletNo,
-                        WarehouseId = sourceStock.WarehouseId,
-                        StockStatus = StockStatusEmun.缁勭洏鏆傚瓨.GetHashCode(),
-                        Creater = "system",
-                    };
-
-                    var newId = StockInfoService.Repository.AddData(newStock);
-                    if (newId <= 0) return content.Error("鎹㈢洏澶辫触");
-
-                    targetStock = newStock;
-                    targetStock.Id = newId;
+                    return content.Error("婧愭墭鐩樺彿涓庣洰鏍囨墭鐩樺彿鐩稿悓");
                 }
 
-                var serialNumbers = stock.Details.Select(d => d.Channel).Distinct().ToList();
-                if (!serialNumbers.Any()) return content.Error("鏈壘鍒版湁鏁堢殑搴忓垪鍙�");
+                return await ExecuteWithinTransactionAsync(async () =>
+                {
+                    var sourceStock = await StockInfoService.Repository.QueryDataNavFirstAsync(s => s.PalletCode == stock.SourcePalletNo);
+                    if (sourceStock == null) return content.Error("婧愭墭鐩樹笉瀛樺湪");
 
-                var detailEntities = StockInfoDetailService.Repository.QueryData(
-                    d => d.StockId == sourceStock.Id && serialNumbers.Contains(d.InboundOrderRowNo));
-                if (!detailEntities.Any()) return content.Error("鏈壘鍒版湁鏁堢殑搴撳瓨鏄庣粏");
+                    var targetStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.TargetPalletNo);
+                    if (targetStock == null)
+                    {
+                        var newStock = new Dt_StockInfo
+                        {
+                            PalletCode = stock.TargetPalletNo,
+                            WarehouseId = sourceStock.WarehouseId,
+                            StockStatus = StockStatusEmun.缁勭洏鏆傚瓨.GetHashCode(),
+                            Creater = "system",
+                        };
 
-                if (await StockInfoDetail_HtyService.Repository.AddDataAsync(CreateDetailHistory(detailEntities, "鎹㈢洏")) <= 0)
-                    return content.Error("鎹㈢洏鍘嗗彶璁板綍淇濆瓨澶辫触");
+                        var newId = StockInfoService.Repository.AddData(newStock);
+                        if (newId <= 0) return content.Error("鎹㈢洏澶辫触");
 
-                if (await StockInfo_HtyService.Repository.AddDataAsync(CreateStockHistory(new[] { sourceStock, targetStock }, "鎹㈢洏")) <= 0)
-                    return content.Error("鎹㈢洏鍘嗗彶璁板綍淇濆瓨澶辫触");
+                        targetStock = newStock;
+                        targetStock.Id = newId;
+                    }
 
-                detailEntities.ForEach(d => d.StockId = targetStock.Id);
-                var result = await StockInfoDetailService.Repository.UpdateDataAsync(detailEntities);
-                if (!result) return content.Error("鎹㈢洏澶辫触");
-                return content.OK("鎹㈢洏鎴愬姛");
-            });
+                    var serialNumbers = stock.Details.Select(d => d.Channel).Distinct().ToList();
+                    if (!serialNumbers.Any()) return content.Error("鏈壘鍒版湁鏁堢殑搴忓垪鍙�");
+
+                    var detailEntities = StockInfoDetailService.Repository.QueryData(
+                        d => d.StockId == sourceStock.Id && serialNumbers.Contains(d.InboundOrderRowNo));
+                    if (!detailEntities.Any()) return content.Error("鏈壘鍒版湁鏁堢殑搴撳瓨鏄庣粏");
+
+                    if (await StockInfoDetail_HtyService.Repository.AddDataAsync(CreateDetailHistory(detailEntities, "鎹㈢洏")) <= 0)
+                        return content.Error("鎹㈢洏鍘嗗彶璁板綍淇濆瓨澶辫触");
+
+                    if (await StockInfo_HtyService.Repository.AddDataAsync(CreateStockHistory(new[] { sourceStock, targetStock }, "鎹㈢洏")) <= 0)
+                        return content.Error("鎹㈢洏鍘嗗彶璁板綍淇濆瓨澶辫触");
+
+                    detailEntities.ForEach(d => d.StockId = targetStock.Id);
+                    var result = await StockInfoDetailService.Repository.UpdateDataAsync(detailEntities);
+                    if (!result) return content.Error("鎹㈢洏澶辫触");
+                    return content.OK("鎹㈢洏鎴愬姛");
+                });
+            }
+            catch (Exception ex)
+            {
+                return content.Error($"鎹㈢洏澶辫触: {ex.Message}");
+            }
         }
 
         /// <summary>
@@ -207,37 +221,44 @@
         public async Task<WebResponseContent> SplitPalletAsync(StockDTO stock)
         {
             WebResponseContent content = new WebResponseContent();
-            if (stock == null || string.IsNullOrWhiteSpace(stock.SourcePalletNo))
-                return content.Error("婧愭墭鐩樺彿涓嶈兘涓虹┖");
-
-            return await ExecuteWithinTransactionAsync(async () =>
+            try
             {
-                var sourceStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.SourcePalletNo);
-                if (sourceStock == null) return content.Error("婧愭墭鐩樹笉瀛樺湪");
+                if (stock == null || string.IsNullOrWhiteSpace(stock.SourcePalletNo))
+                    return content.Error("婧愭墭鐩樺彿涓嶈兘涓虹┖");
 
-                var serialNumbers = stock.Details.Select(d => d.CellBarcode).Distinct().ToList();
-                if (!serialNumbers.Any())
+                return await ExecuteWithinTransactionAsync(async () =>
                 {
-                    serialNumbers = sourceStock.Details
-                                                .Where(x => stock.Details.Any(d => d.Channel == x.InboundOrderRowNo))
-                                                .Select(x => x.SerialNumber)
-                                                .ToList();
-                }
+                    var sourceStock = StockInfoService.Repository.QueryFirst(s => s.PalletCode == stock.SourcePalletNo);
+                    if (sourceStock == null) return content.Error("婧愭墭鐩樹笉瀛樺湪");
 
-                var detailEntities = StockInfoDetailService.Repository.QueryData(
-                    d => d.StockId == sourceStock.Id && serialNumbers.Contains(d.SerialNumber));
-                if (!detailEntities.Any()) return content.Error("鏈壘鍒版湁鏁堢殑搴撳瓨鏄庣粏");
+                    var serialNumbers = stock.Details.Select(d => d.CellBarcode).Distinct().ToList();
+                    if (!serialNumbers.Any())
+                    {
+                        serialNumbers = sourceStock.Details
+                                                    .Where(x => stock.Details.Any(d => d.Channel == x.InboundOrderRowNo))
+                                                    .Select(x => x.SerialNumber)
+                                                    .ToList();
+                    }
 
-                if (await StockInfoDetail_HtyService.Repository.AddDataAsync(CreateDetailHistory(detailEntities, "鎷嗙洏")) <= 0)
-                    return content.Error("鎷嗙洏鍘嗗彶璁板綍淇濆瓨澶辫触");
+                    var detailEntities = StockInfoDetailService.Repository.QueryData(
+                        d => d.StockId == sourceStock.Id && serialNumbers.Contains(d.SerialNumber));
+                    if (!detailEntities.Any()) return content.Error("鏈壘鍒版湁鏁堢殑搴撳瓨鏄庣粏");
 
-                if (await StockInfo_HtyService.Repository.AddDataAsync(CreateStockHistory(new[] { sourceStock }, "鎷嗙洏")) <= 0)
-                    return content.Error("鎷嗙洏鍘嗗彶璁板綍淇濆瓨澶辫触");
+                    if (await StockInfoDetail_HtyService.Repository.AddDataAsync(CreateDetailHistory(detailEntities, "鎷嗙洏")) <= 0)
+                        return content.Error("鎷嗙洏鍘嗗彶璁板綍淇濆瓨澶辫触");
 
-                var result = await StockInfoDetailService.Repository.DeleteDataAsync(detailEntities);
-                if (!result) return content.Error("鎷嗙洏澶辫触");
-                return content.OK("鎷嗙洏鎴愬姛");
-            });
+                    if (await StockInfo_HtyService.Repository.AddDataAsync(CreateStockHistory(new[] { sourceStock }, "鎷嗙洏")) <= 0)
+                        return content.Error("鎷嗙洏鍘嗗彶璁板綍淇濆瓨澶辫触");
+
+                    var result = await StockInfoDetailService.Repository.DeleteDataAsync(detailEntities);
+                    if (!result) return content.Error("鎷嗙洏澶辫触");
+                    return content.OK("鎷嗙洏鎴愬姛");
+                });
+            }
+            catch (Exception ex)
+            {
+                return content.Error($"鎷嗙洏澶辫触: {ex.Message}");
+            }
         }
 
         /// <summary>
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\344\270\212\344\275\215\347\263\273\347\273\237\345\257\271\346\216\245/\351\231\225\350\245\277\351\241\267\345\210\273\350\203\275\346\272\220\347\247\221\346\212\200MES\347\263\273\347\273\237\345\257\271\346\216\245\346\216\245\345\217\243.md" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\344\270\212\344\275\215\347\263\273\347\273\237\345\257\271\346\216\245/\351\231\225\350\245\277\351\241\267\345\210\273\350\203\275\346\272\220\347\247\221\346\212\200MES\347\263\273\347\273\237\345\257\271\346\216\245\346\216\245\345\217\243.md"
new file mode 100644
index 0000000..714f06f
--- /dev/null
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\344\270\212\344\275\215\347\263\273\347\273\237\345\257\271\346\216\245/\351\231\225\350\245\277\351\241\267\345\210\273\350\203\275\346\272\220\347\247\221\346\212\200MES\347\263\273\347\273\237\345\257\271\346\216\245\346\216\245\345\217\243.md"
@@ -0,0 +1,329 @@
+濂界殑锛屾垜宸茬粡灏嗘偍鎻愪緵鐨勪簲涓帴鍙f枃妗d紭鍖栦负鏇存竻鏅般�佺粨鏋勬洿缁熶竴鐨凪arkdown鏍煎紡銆備富瑕佷紭鍖栫偣鍖呮嫭锛�
+
+1.  **缁熶竴鏍煎紡**锛氬皢鎵�鏈夋帴鍙g殑璇存槑銆佽姹傚瓧娈点�佸搷搴斿瓧娈电瓑閲囩敤涓�鑷寸殑鏍囬灞傜骇鍜岃〃鏍肩粨鏋勩��
+2.  **淇閿欒**锛氫慨姝d簡鈥滄墭鐩樺嚭绔欌�濇帴鍙e悕绉板拰鈥滈�傜敤宸ュ簭鈥濅腑鐨勬槑鏄剧瑪璇��
+3.  **澧炲己鍙鎬�**锛氫娇鐢ㄥ姞绮椼�佷唬鐮佸潡绛塎arkdown鍏冪礌锛屼娇鍏抽敭淇℃伅鍜屾姤鏂囩ず渚嬫洿绐佸嚭銆�
+4.  **琛ュ厖璇存槑**锛氬湪鎶ユ枃绀轰緥涓紝灏哷body`閮ㄥ垎鐢↗SON浠g爜鍧楅珮浜樉绀猴紝渚夸簬闃呰銆�
+
+---
+
+### **1.1. 鎵樼洏鐢佃姱缁戝畾**
+
+#### **1.1.1. 瑙﹀彂鏉′欢**
+
+1.  鐢ㄤ簬鐢佃姱鐮佺粦瀹氭墭鐩樼爜銆�
+
+#### **1.1.2. 鎺ュ彛璇存槑**
+
+| 椤圭洰         | 鍐呭                                     |
+| :----------- | :--------------------------------------- |
+| **鎺ュ彛鍚嶇О** | 鎵樼洏鐢佃姱缁戝畾锛堝湪鍒跺搧&瀹瑰櫒锛�              |
+| **鎺ュ彛鏂瑰紡** | WebApi                                   |
+| **璇锋眰鏂瑰紡** | POST                                     |
+| **鍙戦�佹柟**   | EQP                                      |
+| **鎺ユ敹鏂�**   | MES                                      |
+| **鎺ュ彛鍦板潃** | `/EquipmentService/api/v1/BindContainer` |
+| **閫傜敤宸ュ簭** | 鐢佃姱鐮佺粦瀹氭墭鐩樼爜                         |
+
+#### **1.1.3. 璇锋眰鎶ユ枃**
+
+**Header 瀛楁**
+
+| 搴忓彿 | 瀛楁            | 鍐呭        | 鏁版嵁绫诲瀷 | 澶囨敞        |
+| :--- | :-------------- | :---------- | :------- | :---------- |
+| 1    | `Authorization` | MES璁よ瘉淇℃伅 | STRING   | 鍊肩敱MES鎻愪緵 |
+
+**Body 瀛楁**
+
+| 搴忓彿 | 瀛楁               | 鍐呭               | 鏁版嵁绫诲瀷                               | 澶囨敞                   |
+| :--- | :----------------- | :----------------- | :------------------------------------- | :--------------------- |
+| 1    | `EquipmentCode`    | 璁惧缂栫爜           | STRING                                 |                        |
+| 2    | `ResourceCode`     | 璧勬簮缂栫爜           | STRING                                 |                        |
+| 3    | `LocalTime`        | 璋冪敤鏈湴鏃堕棿       | DATETIME                               |                        |
+| 4    | `ContainerCode`    | 鎵樼洏鐮�             | STRING                                 |                        |
+| 5    | `ContainerSfcList` | 缁戝畾鐨勭數鑺潯鐮佸垪琛� | ARRAY OBJECT                           |                        |
+| 6    | `OperationType`    | 鎿嶄綔绫诲瀷           | 0-榛樿<br>1-杩涚珯<br>2-鍑虹珯<br>3-杩涘嚭绔� | 鎹㈡嫎鏉熸墭鐩樹笂浼�3锛屽叾浣�0 |
+
+**`ContainerSfcList` 鏁版嵁闆嗗瓧娈�**
+
+| 搴忓彿 | 瀛楁       | 鍐呭     | 鏁版嵁绫诲瀷 | 澶囨敞 |
+| :--- | :--------- | :------- | :------- | :--- |
+| 1    | `Sfc`      | 鐢佃姱鐮�   | STRING   |      |
+| 2    | `Location` | 浣嶇疆淇℃伅 | STRING   |      |
+
+**鎶ユ枃绀轰緥**
+
+```json
+{
+  "equipmentCode": "string",
+  "resourceCode": "string",
+  "localTime": "2024-03-01T03:12:29.265Z",
+  "containerCode": "string",
+  "containerSfcList": [
+    {
+      "sfc": "string",
+      "location": "string"
+    }
+  ]
+}
+```
+
+#### **1.1.4. 鍝嶅簲瀛楁**
+
+| 瀛楁   | 鍐呭     | 鏁版嵁绫诲瀷 | 澶囨敞                  |
+| :----- | :------- | :------- | :-------------------- |
+| `code` | 鎵ц浠g爜 | INT      | 0: 鎴愬姛<br>鍏朵粬: 澶辫触 |
+| `msg`  | 杩斿洖淇℃伅 | STRING   | 鍖呭惈鍏蜂綋鐨勯敊璇俊鎭�    |
+
+---
+
+### **1.2. 鎵樼洏鐢佃姱瑙g粦**
+
+#### **1.2.1. 瑙﹀彂鏉′欢**
+
+1.  鐢ㄤ簬鎵樼洏鐮佽В缁戠數鑺粍銆�
+
+#### **1.2.2. 鎺ュ彛璇存槑**
+
+| 椤圭洰         | 鍐呭                                       |
+| :----------- | :----------------------------------------- |
+| **鎺ュ彛鍚嶇О** | 鎵樼洏鐢佃姱瑙g粦锛堝湪鍒跺搧&瀹瑰櫒锛�                |
+| **鎺ュ彛鏂瑰紡** | WebApi                                     |
+| **璇锋眰鏂瑰紡** | POST                                       |
+| **鍙戦�佹柟**   | EQP                                        |
+| **鎺ユ敹鏂�**   | MES                                        |
+| **鎺ュ彛鍦板潃** | `/EquipmentService/api/v1/UnBindContainer` |
+| **閫傜敤宸ュ簭** | 鎵樼洏鐮佽В缁戠數鑺粍                           |
+
+#### **1.2.3. 璇锋眰鎶ユ枃**
+
+**Header 瀛楁**
+
+| 搴忓彿 | 瀛楁            | 鍐呭        | 鏁版嵁绫诲瀷 | 澶囨敞        |
+| :--- | :-------------- | :---------- | :------- | :---------- |
+| 1    | `Authorization` | MES璁よ瘉淇℃伅 | STRING   | 鍊肩敱MES鎻愪緵 |
+
+**Body 瀛楁**
+
+| 搴忓彿 | 瀛楁            | 鍐呭         | 鏁版嵁绫诲瀷     | 澶囨敞 |
+| :--- | :-------------- | :----------- | :----------- | :--- |
+| 1    | `EquipmentCode` | 璁惧缂栫爜     | STRING       |      |
+| 2    | `ResourceCode`  | 璧勬簮缂栫爜     | STRING       |      |
+| 3    | `LocalTime`     | 璋冪敤鏈湴鏃堕棿 | DATETIME     |      |
+| 4    | `ContainCode`   | 鎵樼洏鐮�       | STRING       |      |
+| 5    | `SfcList`       | 鐢佃姱鏉$爜缁�   | ARRAY STRING |      |
+
+**鎶ユ枃绀轰緥**
+
+```json
+{
+  "equipmentCode": "string",
+  "resourceCode": "string",
+  "localTime": "2024-03-01T03:13:12.482Z",
+  "containCode": "string",
+  "sfcList": [
+    "string"
+  ]
+}
+```
+
+#### **1.2.4. 鍝嶅簲瀛楁**
+
+| 瀛楁   | 鍐呭     | 鏁版嵁绫诲瀷 | 澶囨敞                  |
+| :----- | :------- | :------- | :-------------------- |
+| `code` | 鎵ц浠g爜 | INT      | 0: 鎴愬姛<br>鍏朵粬: 澶辫触 |
+| `msg`  | 杩斿洖淇℃伅 | STRING   | 鍖呭惈鍏蜂綋鐨勯敊璇俊鎭�    |
+
+---
+
+### **1.3. 鎵樼洏NG鐢佃姱涓婃姤**
+
+#### **1.3.1. 瑙﹀彂鏉′欢**
+
+1.  鎵樼洏瀛樺湪NG鏉$爜锛屽湪鎷嗙洏鎴栬�匫CV2, OCV3鏃讹紝闇�瑕佷笂鎶G鐢佃姱銆�
+
+#### **1.3.2. 鎺ュ彛璇存槑**
+
+| 椤圭洰         | 鍐呭                                         |
+| :----------- | :------------------------------------------- |
+| **鎺ュ彛鍚嶇О** | 鏉$爜缁戝畾锛堝湪鍒跺搧&瀹瑰櫒锛�                      |
+| **鎺ュ彛鏂瑰紡** | WebApi                                       |
+| **璇锋眰鏂瑰紡** | POST                                         |
+| **鍙戦�佹柟**   | EQP                                          |
+| **鎺ユ敹鏂�**   | MES                                          |
+| **鎺ュ彛鍦板潃** | `/EquipmentService/api/v1/ContainerNgReport` |
+| **閫傜敤宸ュ簭** | 鎵樼洏NG鐢佃姱涓婃姤                               |
+
+#### **1.3.3. 璇锋眰鎶ユ枃**
+
+**Header 瀛楁**
+
+| 搴忓彿 | 瀛楁            | 鍐呭        | 鏁版嵁绫诲瀷 | 澶囨敞        |
+| :--- | :-------------- | :---------- | :------- | :---------- |
+| 1    | `Authorization` | MES璁よ瘉淇℃伅 | STRING   | 鍊肩敱MES鎻愪緵 |
+
+**Body 瀛楁**
+
+| 搴忓彿 | 瀛楁            | 鍐呭                 | 鏁版嵁绫诲瀷     | 澶囨敞 |
+| :--- | :-------------- | :------------------- | :----------- | :--- |
+| 1    | `EquipmentCode` | 璁惧缂栫爜             | STRING       |      |
+| 2    | `ResourceCode`  | 璧勬簮缂栫爜             | STRING       |      |
+| 3    | `LocalTime`     | 璋冪敤鏈湴鏃堕棿         | DATETIME     |      |
+| 4    | `ContainerCode` | 鎵樼洏鐮�               | STRING       |      |
+| 5    | `NgSfcList`     | 缁戝畾NG鐨勭數鑺潯鐮佸垪琛� | ARRAY OBJECT |      |
+
+**`NgSfcList` 鏁版嵁闆嗗瓧娈�**
+
+| 搴忓彿 | 瀛楁              | 鍐呭     | 鏁版嵁绫诲瀷 | 澶囨敞 |
+| :--- | :---------------- | :------- | :------- | :--- |
+| 1    | `sfc`             | 浜у搧鏉$爜 | STRING   |      |
+| 2    | `ngCode`          | NG浠g爜   | STRING   |      |
+| 3    | `ngEquipmentCode` | NG璁惧   | STRING   |      |
+| 4    | `ngResourceCode`  | NG璧勬簮   | STRING   |      |
+
+**鎶ユ枃绀轰緥**
+
+```json
+{
+  "equipmentCode": "string",
+  "resourceCode": "string",
+  "localTime": "2024-03-01T03:42:55.528Z",
+  "containerCode": "string",
+  "ngSfcList": [
+    "string"
+  ]
+}
+```
+
+#### **1.3.4. 鍝嶅簲瀛楁**
+
+| 瀛楁   | 鍐呭     | 鏁版嵁绫诲瀷 | 澶囨敞                  |
+| :----- | :------- | :------- | :-------------------- |
+| `code` | 鎵ц浠g爜 | INT      | 0: 鎴愬姛<br>鍏朵粬: 澶辫触 |
+| `msg`  | 杩斿洖淇℃伅 | STRING   | 鍖呭惈鍏蜂綋鐨勯敊璇俊鎭�    |
+
+---
+
+### **1.4. 鎵樼洏杩涚珯锛堝鍣ㄨ繘绔欙級**
+
+#### **1.4.1. 瑙﹀彂鏉′欢**
+
+1.  鎵樼洏杩涚珯銆�
+
+#### **1.4.2. 鎺ュ彛璇存槑**
+
+| 椤圭洰         | 鍐呭                                          |
+| :----------- | :-------------------------------------------- |
+| **鎺ュ彛鍚嶇О** | 鎵樼洏杩涚珯锛堝鍣ㄨ繘绔欙級                          |
+| **鎺ュ彛鏂瑰紡** | WebApi                                        |
+| **璇锋眰鏂瑰紡** | POST                                          |
+| **鍙戦�佹柟**   | EQP                                           |
+| **鎺ユ敹鏂�**   | MES                                           |
+| **鎺ュ彛鍦板潃** | `/EquipmentService/api/v1/InboundInContainer` |
+| **閫傜敤宸ュ簭** | 鎵樼洏杩涚珯                                      |
+
+#### **1.4.3. 璇锋眰鎶ユ枃**
+
+**Header 瀛楁**
+
+| 搴忓彿 | 瀛楁            | 鍐呭        | 鏁版嵁绫诲瀷 | 澶囨敞        |
+| :--- | :-------------- | :---------- | :------- | :---------- |
+| 1    | `Authorization` | MES璁よ瘉淇℃伅 | STRING   | 鍊肩敱MES鎻愪緵 |
+
+**Body 瀛楁**
+
+| 搴忓彿 | 瀛楁            | 鍐呭         | 鏁版嵁绫诲瀷 | 澶囨敞 |
+| :--- | :-------------- | :----------- | :------- | :--- |
+| 1    | `EquipmentCode` | 璁惧缂栫爜     | STRING   |      |
+| 2    | `ResourceCode`  | 璧勬簮缂栫爜     | STRING   |      |
+| 3    | `LocalTime`     | 璋冪敤鏈湴鏃堕棿 | DATETIME |      |
+| 4    | `ContainerCode` | 鎵樼洏鐮�       | STRING   |      |
+
+**鎶ユ枃绀轰緥**
+
+```json
+{
+  "equipmentCode": "string",
+  "resourceCode": "string",
+  "localTime": "2024-03-01T03:43:42.144Z",
+  "containerCode": "string"
+}
+```
+
+#### **1.4.4. 鍝嶅簲瀛楁**
+
+| 瀛楁   | 鍐呭     | 鏁版嵁绫诲瀷 | 澶囨敞                  |
+| :----- | :------- | :------- | :-------------------- |
+| `code` | 鎵ц浠g爜 | INT      | 0: 鎴愬姛<br>鍏朵粬: 澶辫触 |
+| `msg`  | 杩斿洖淇℃伅 | STRING   | 鍖呭惈鍏蜂綋鐨勯敊璇俊鎭�    |
+
+---
+
+### **1.5. 鎵樼洏鍑虹珯锛堝鍣ㄥ嚭绔欙級**
+
+#### **1.5.1. 瑙﹀彂鏉′欢**
+
+1.  鎵樼洏鍑虹珯銆�
+
+#### **1.5.2. 鎺ュ彛璇存槑**
+
+| 椤圭洰         | 鍐呭                                           |
+| :----------- | :--------------------------------------------- |
+| **鎺ュ彛鍚嶇О** | 鎵樼洏鍑虹珯锛堝鍣ㄥ嚭绔欙級                           |
+| **鎺ュ彛鏂瑰紡** | WebApi                                         |
+| **璇锋眰鏂瑰紡** | POST                                           |
+| **鍙戦�佹柟**   | EQP                                            |
+| **鎺ユ敹鏂�**   | MES                                            |
+| **鎺ュ彛鍦板潃** | `/EquipmentService/api/v1/OutboundInContainer` |
+| **閫傜敤宸ュ簭** | 鎵樼洏鍑虹珯                                       |
+
+#### **1.5.3. 璇锋眰鎶ユ枃**
+
+**Header 瀛楁**
+
+| 搴忓彿 | 瀛楁            | 鍐呭        | 鏁版嵁绫诲瀷 | 澶囨敞        |
+| :--- | :-------------- | :---------- | :------- | :---------- |
+| 1    | `Authorization` | MES璁よ瘉淇℃伅 | STRING   | 鍊肩敱MES鎻愪緵 |
+
+**Body 瀛楁**
+
+| 搴忓彿 | 瀛楁            | 鍐呭         | 鏁版嵁绫诲瀷     | 澶囨敞 |
+| :--- | :-------------- | :----------- | :----------- | :--- |
+| 1    | `EquipmentCode` | 璁惧缂栫爜     | STRING       |      |
+| 2    | `ResourceCode`  | 璧勬簮缂栫爜     | STRING       |      |
+| 3    | `LocalTime`     | 璋冪敤鏈湴鏃堕棿 | DATETIME     |      |
+| 4    | `ContainerCode` | 鎵樼洏鐮�       | STRING       |      |
+| 5    | `ParamList`     | 浜у搧鍙傛暟鍒楄〃 | ARRAY OBJECT |      |
+
+**`ParamList` 鏁版嵁闆嗗瓧娈�**
+
+| 搴忓彿 | 瀛楁             | 鍐呭     | 鏁版嵁绫诲瀷 | 澶囨敞           |
+| :--- | :--------------- | :------- | :------- | :------------- |
+| 1    | `ParamCode`      | 鍙傛暟缂栫爜 | STRING   | 宸ヨ壓鎻愪緵       |
+| 2    | `ParamValue`     | 鍙傛暟鍊�   | STRING   |                |
+| 3    | `CollectionTime` | 鏃堕棿鎴�   | DATETIME | 閲囬泦鍙傛暟鐨勬椂闂� |
+
+**鎶ユ枃绀轰緥**
+
+```json
+{
+  "equipmentCode": "string",
+  "resourceCode": "string",
+  "localTime": "2024-03-01T03:43:42.144Z",
+  "containerCode": "string",
+  "paramList": [
+    {
+      "paramCode": "string",
+      "paramValue": "string",
+      "collectionTime": "2024-03-01T03:43:42.144Z"
+    }
+  ]
+}
+```
+
+#### **1.5.4. 鍝嶅簲瀛楁**
+
+| 瀛楁   | 鍐呭     | 鏁版嵁绫诲瀷 | 澶囨敞                  |
+| :----- | :------- | :------- | :-------------------- |
+| `code` | 鎵ц浠g爜 | INT      | 0: 鎴愬姛<br>鍏朵粬: 澶辫触 |
+| `msg`  | 杩斿洖淇℃伅 | STRING   | 鍖呭惈鍏蜂綋鐨勯敊璇俊鎭�    |

--
Gitblit v1.9.3