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