From 96adc295cb04fd135d63d3a907f2732274f90965 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期二, 21 四月 2026 01:11:21 +0800
Subject: [PATCH] feat: 添加MES异步上传辅助服务并重构相关代码

---
 Code/.omc/state/mission-state.json                                                          |  388 ++++++++++++++
 Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Outbound.cs              |   25 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs |  178 +-----
 Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/MesUploadHelper.cs                          |   93 +++
 Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs                           |   83 ---
 Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs                             |  111 +--
 Code/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMesUploadHelper.cs                        |   28 +
 Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Inbound.cs               |   80 --
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/JobFactory.cs                     |   48 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/CommonConveyorLineJob.cs        |    3 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs       |  116 +---
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/SchedulerCenterServer.cs          |   13 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs   |   24 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Storage.cs                                  |   15 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json                               |    3 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs                         |    2 
 Code/.omc/state/last-tool-error.json                                                        |    8 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs             |    2 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs        |    6 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneCommandBuilder.cs   |   33 
 Code/.omc/state/subagent-tracking.json                                                      |  276 ++++++++++
 21 files changed, 1,032 insertions(+), 503 deletions(-)

diff --git a/Code/.omc/state/last-tool-error.json b/Code/.omc/state/last-tool-error.json
index 6556fa7..778c26d 100644
--- a/Code/.omc/state/last-tool-error.json
+++ b/Code/.omc/state/last-tool-error.json
@@ -1,7 +1,7 @@
 {
-  "tool_name": "Read",
-  "tool_input_preview": "{\"file_path\":\"D:\\\\Git\\\\ShanMeiXinNengYuan\\\\Code\\\\WMS\\\\WIDESEA_WMSClient_Vben_v2\\\\apps\\\\web-ele\\\\src\\\\views\\\\dashboard\\\\index.vue\"}",
-  "error": "File does not exist. Note: your current working directory is D:\\Git\\ShanMeiXinNengYuan\\Code.",
-  "timestamp": "2026-04-20T01:28:36.836Z",
+  "tool_name": "Bash",
+  "tool_input_preview": "{\"command\":\"cd \\\"D:/Git/ShanMeiXinNengYuan/Code\\\" && dotnet build WMS/WIDESEA_WMSServer/WIDESEA_WMSServer.sln 2>&1\",\"timeout\":120000,\"description\":\"Build WMS solution to verify changes\"}",
+  "error": "Exit code 1\n  姝e湪纭畾瑕佽繕鍘熺殑椤圭洰鈥r\n  鎵�鏈夐」鐩潎鏄渶鏂扮殑锛屾棤娉曡繕鍘熴�俓r\nD:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\AOP\\LogAOP.cs(169,123): warning CS8625: 鏃犳硶灏� null 瀛楅潰閲忚浆鎹负闈� null 鐨勫紩鐢ㄧ被鍨嬨�� [D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\WIDESEA_Core.csproj]\r\nD:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\Authorization\\AuthorizationResponse.cs(21,30): warning CS8625: 鏃犳硶灏� null 瀛楅潰閲忚浆鎹负闈� null 鐨勫紩鐢ㄧ被鍨嬨�� [D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\WIDES...",
+  "timestamp": "2026-04-20T16:56:32.862Z",
   "retry_count": 1
 }
\ No newline at end of file
diff --git a/Code/.omc/state/mission-state.json b/Code/.omc/state/mission-state.json
index 749450d..5fe9719 100644
--- a/Code/.omc/state/mission-state.json
+++ b/Code/.omc/state/mission-state.json
@@ -1,5 +1,5 @@
 {
-  "updatedAt": "2026-04-20T02:13:36.765Z",
+  "updatedAt": "2026-04-20T17:02:18.624Z",
   "missions": [
     {
       "id": "session:9007b9ea-1eb6-4d24-8fe7-2c3a949eac88:none",
@@ -1964,6 +1964,392 @@
           "sourceKey": "session-stop:a6eae12446c31bdfe"
         }
       ]
+    },
+    {
+      "id": "session:bce34684-82ff-42dd-b951-6194cfe1e77c:none",
+      "source": "session",
+      "name": "none",
+      "objective": "Session mission",
+      "createdAt": "2026-04-20T15:49:37.351Z",
+      "updatedAt": "2026-04-20T17:02:18.624Z",
+      "status": "done",
+      "workerCount": 30,
+      "taskCounts": {
+        "total": 30,
+        "pending": 0,
+        "blocked": 0,
+        "inProgress": 0,
+        "completed": 30,
+        "failed": 0
+      },
+      "agents": [
+        {
+          "name": "general-purpose:af087f2",
+          "role": "general-purpose",
+          "ownership": "af087f2e64d433e39",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T17:02:18.624Z"
+        },
+        {
+          "name": "general-purpose:a151e5f",
+          "role": "general-purpose",
+          "ownership": "a151e5f87f0cbdac6",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:50:53.499Z"
+        },
+        {
+          "name": "general-purpose:a9435dc",
+          "role": "general-purpose",
+          "ownership": "a9435dc250bc7482e",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:50:38.393Z"
+        },
+        {
+          "name": "general-purpose:a32b075",
+          "role": "general-purpose",
+          "ownership": "a32b0751a039672ef",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:51:30.118Z"
+        },
+        {
+          "name": "general-purpose:aaa2a0f",
+          "role": "general-purpose",
+          "ownership": "aaa2a0f6b2a25bec0",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:51:23.092Z"
+        },
+        {
+          "name": "general-purpose:a86b879",
+          "role": "general-purpose",
+          "ownership": "a86b879fb7a0801be",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:52:07.543Z"
+        },
+        {
+          "name": "general-purpose:a12823e",
+          "role": "general-purpose",
+          "ownership": "a12823e675f358745",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:52:29.208Z"
+        },
+        {
+          "name": "general-purpose:ae97a4d",
+          "role": "general-purpose",
+          "ownership": "ae97a4de553f0b4c3",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:52:16.206Z"
+        },
+        {
+          "name": "general-purpose:a4a2d7d",
+          "role": "general-purpose",
+          "ownership": "a4a2d7dfcc130e3c8",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:53:19.832Z"
+        },
+        {
+          "name": "general-purpose:afef0a2",
+          "role": "general-purpose",
+          "ownership": "afef0a2e4255227bd",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:53:08.591Z"
+        },
+        {
+          "name": "general-purpose:ae1e2c3",
+          "role": "general-purpose",
+          "ownership": "ae1e2c3f798ee872a",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:53:36.457Z"
+        },
+        {
+          "name": "general-purpose:a66e87c",
+          "role": "general-purpose",
+          "ownership": "a66e87c9223005128",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:56:26.414Z"
+        },
+        {
+          "name": "general-purpose:a113f70",
+          "role": "general-purpose",
+          "ownership": "a113f704503b35113",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:54:23.336Z"
+        },
+        {
+          "name": "general-purpose:a7cc134",
+          "role": "general-purpose",
+          "ownership": "a7cc1344397da9324",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:58:27.436Z"
+        },
+        {
+          "name": "general-purpose:aeac471",
+          "role": "general-purpose",
+          "ownership": "aeac471bcaec36af3",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:00:25.655Z"
+        },
+        {
+          "name": "general-purpose:a6c7e45",
+          "role": "general-purpose",
+          "ownership": "a6c7e458af6948696",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T15:57:35.457Z"
+        },
+        {
+          "name": "general-purpose:a5144b6",
+          "role": "general-purpose",
+          "ownership": "a5144b6e94595b89f",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:01:24.405Z"
+        },
+        {
+          "name": "general-purpose:ac4bbba",
+          "role": "general-purpose",
+          "ownership": "ac4bbba9b05c57c6a",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:03:43.062Z"
+        },
+        {
+          "name": "general-purpose:ad3b6fa",
+          "role": "general-purpose",
+          "ownership": "ad3b6fad5f339a4e5",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:02:27.528Z"
+        },
+        {
+          "name": "general-purpose:a72a84d",
+          "role": "general-purpose",
+          "ownership": "a72a84d56ec83e520",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:03:48.315Z"
+        },
+        {
+          "name": "general-purpose:a62f850",
+          "role": "general-purpose",
+          "ownership": "a62f85025e6fd117b",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:04:24.590Z"
+        },
+        {
+          "name": "general-purpose:a3265e6",
+          "role": "general-purpose",
+          "ownership": "a3265e63c320b7fb7",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:04:17.712Z"
+        },
+        {
+          "name": "general-purpose:a75fe8e",
+          "role": "general-purpose",
+          "ownership": "a75fe8e3716ab2841",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:05:07.601Z"
+        },
+        {
+          "name": "general-purpose:ab70218",
+          "role": "general-purpose",
+          "ownership": "ab7021856484bc64e",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:18:18.639Z"
+        },
+        {
+          "name": "general-purpose:a9c7d87",
+          "role": "general-purpose",
+          "ownership": "a9c7d87d13a26caa1",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:18:25.585Z"
+        },
+        {
+          "name": "general-purpose:ac4481c",
+          "role": "general-purpose",
+          "ownership": "ac4481cc8f2fd18cf",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:18:05.225Z"
+        },
+        {
+          "name": "general-purpose:ad8e51b",
+          "role": "general-purpose",
+          "ownership": "ad8e51b3e49b68c5b",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:19:04.231Z"
+        },
+        {
+          "name": "general-purpose:a8d6992",
+          "role": "general-purpose",
+          "ownership": "a8d69927a9c24e9b5",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:36:32.273Z"
+        },
+        {
+          "name": "general-purpose:a9f7c77",
+          "role": "general-purpose",
+          "ownership": "a9f7c771d702937f2",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:35:27.503Z"
+        },
+        {
+          "name": "general-purpose:aaecb7b",
+          "role": "general-purpose",
+          "ownership": "aaecb7b0d7ead5188",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-20T16:32:32.486Z"
+        }
+      ],
+      "timeline": [
+        {
+          "id": "session-start:a8d69927a9c24e9b5:2026-04-20T16:31:25.163Z",
+          "at": "2026-04-20T16:31:25.163Z",
+          "kind": "update",
+          "agent": "general-purpose:a8d6992",
+          "detail": "started general-purpose:a8d6992",
+          "sourceKey": "session-start:a8d69927a9c24e9b5"
+        },
+        {
+          "id": "session-start:a9f7c771d702937f2:2026-04-20T16:31:25.222Z",
+          "at": "2026-04-20T16:31:25.222Z",
+          "kind": "update",
+          "agent": "general-purpose:a9f7c77",
+          "detail": "started general-purpose:a9f7c77",
+          "sourceKey": "session-start:a9f7c771d702937f2"
+        },
+        {
+          "id": "session-start:aaecb7b0d7ead5188:2026-04-20T16:31:25.289Z",
+          "at": "2026-04-20T16:31:25.289Z",
+          "kind": "update",
+          "agent": "general-purpose:aaecb7b",
+          "detail": "started general-purpose:aaecb7b",
+          "sourceKey": "session-start:aaecb7b0d7ead5188"
+        },
+        {
+          "id": "session-stop:aaecb7b0d7ead5188:2026-04-20T16:32:32.486Z",
+          "at": "2026-04-20T16:32:32.486Z",
+          "kind": "completion",
+          "agent": "general-purpose:aaecb7b",
+          "detail": "completed",
+          "sourceKey": "session-stop:aaecb7b0d7ead5188"
+        },
+        {
+          "id": "session-stop:a9f7c771d702937f2:2026-04-20T16:35:27.503Z",
+          "at": "2026-04-20T16:35:27.503Z",
+          "kind": "completion",
+          "agent": "general-purpose:a9f7c77",
+          "detail": "completed",
+          "sourceKey": "session-stop:a9f7c771d702937f2"
+        },
+        {
+          "id": "session-stop:a8d69927a9c24e9b5:2026-04-20T16:36:32.273Z",
+          "at": "2026-04-20T16:36:32.273Z",
+          "kind": "completion",
+          "agent": "general-purpose:a8d6992",
+          "detail": "completed",
+          "sourceKey": "session-stop:a8d69927a9c24e9b5"
+        },
+        {
+          "id": "session-stop:a02e13efa2a4d4a7d:2026-04-20T16:43:22.723Z",
+          "at": "2026-04-20T16:43:22.723Z",
+          "kind": "completion",
+          "agent": "general-purpose:af087f2",
+          "detail": "completed",
+          "sourceKey": "session-stop:a02e13efa2a4d4a7d"
+        },
+        {
+          "id": "session-stop:a82856d42f4ef095b:2026-04-20T17:02:18.624Z",
+          "at": "2026-04-20T17:02:18.624Z",
+          "kind": "completion",
+          "agent": "general-purpose:af087f2",
+          "detail": "completed",
+          "sourceKey": "session-stop:a82856d42f4ef095b"
+        }
+      ]
     }
   ]
 }
\ No newline at end of file
diff --git a/Code/.omc/state/subagent-tracking.json b/Code/.omc/state/subagent-tracking.json
index 62341aa..ccae26c 100644
--- a/Code/.omc/state/subagent-tracking.json
+++ b/Code/.omc/state/subagent-tracking.json
@@ -1184,10 +1184,280 @@
       "status": "completed",
       "completed_at": "2026-04-20T02:08:23.744Z",
       "duration_ms": 81044
+    },
+    {
+      "agent_id": "af087f2e64d433e39",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:49:37.351Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:50:06.600Z",
+      "duration_ms": 29249
+    },
+    {
+      "agent_id": "a151e5f87f0cbdac6",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:50:24.517Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:50:53.498Z",
+      "duration_ms": 28981
+    },
+    {
+      "agent_id": "a9435dc250bc7482e",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:50:24.578Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:50:38.390Z",
+      "duration_ms": 13812
+    },
+    {
+      "agent_id": "a32b0751a039672ef",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:51:08.683Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:51:30.117Z",
+      "duration_ms": 21434
+    },
+    {
+      "agent_id": "aaa2a0f6b2a25bec0",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:51:08.748Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:51:23.091Z",
+      "duration_ms": 14343
+    },
+    {
+      "agent_id": "a86b879fb7a0801be",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:51:49.188Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:52:07.541Z",
+      "duration_ms": 18353
+    },
+    {
+      "agent_id": "a12823e675f358745",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:51:49.202Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:52:29.206Z",
+      "duration_ms": 40004
+    },
+    {
+      "agent_id": "ae97a4de553f0b4c3",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:51:49.272Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:52:16.205Z",
+      "duration_ms": 26933
+    },
+    {
+      "agent_id": "a4a2d7dfcc130e3c8",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:52:54.548Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:53:19.831Z",
+      "duration_ms": 25283
+    },
+    {
+      "agent_id": "afef0a2e4255227bd",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:52:54.560Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:53:08.589Z",
+      "duration_ms": 14029
+    },
+    {
+      "agent_id": "ae1e2c3f798ee872a",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:52:54.621Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:53:36.456Z",
+      "duration_ms": 41835
+    },
+    {
+      "agent_id": "a66e87c9223005128",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:53:53.740Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:56:26.413Z",
+      "duration_ms": 152673
+    },
+    {
+      "agent_id": "a113f704503b35113",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:53:53.756Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:54:23.335Z",
+      "duration_ms": 29579
+    },
+    {
+      "agent_id": "a7cc1344397da9324",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:56:59.419Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:58:27.434Z",
+      "duration_ms": 88015
+    },
+    {
+      "agent_id": "aeac471bcaec36af3",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:56:59.484Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:00:25.654Z",
+      "duration_ms": 206170
+    },
+    {
+      "agent_id": "a6c7e458af6948696",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T15:56:59.548Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T15:57:35.456Z",
+      "duration_ms": 35908
+    },
+    {
+      "agent_id": "a5144b6e94595b89f",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:00:50.066Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:01:24.403Z",
+      "duration_ms": 34337
+    },
+    {
+      "agent_id": "ad3b6fad5f339a4e5",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:01:46.364Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:02:27.526Z",
+      "duration_ms": 41162
+    },
+    {
+      "agent_id": "ac4bbba9b05c57c6a",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:01:46.304Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:03:43.060Z",
+      "duration_ms": 116756
+    },
+    {
+      "agent_id": "a72a84d56ec83e520",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:01:46.423Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:03:48.313Z",
+      "duration_ms": 121890
+    },
+    {
+      "agent_id": "a62f85025e6fd117b",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:04:06.835Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:04:24.588Z",
+      "duration_ms": 17753
+    },
+    {
+      "agent_id": "a3265e63c320b7fb7",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:04:06.894Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:04:17.711Z",
+      "duration_ms": 10817
+    },
+    {
+      "agent_id": "a75fe8e3716ab2841",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:04:35.938Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:05:07.599Z",
+      "duration_ms": 31661
+    },
+    {
+      "agent_id": "ab7021856484bc64e",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:15:18.619Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:18:18.637Z",
+      "duration_ms": 180018
+    },
+    {
+      "agent_id": "a9c7d87d13a26caa1",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:15:18.684Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:18:25.584Z",
+      "duration_ms": 186900
+    },
+    {
+      "agent_id": "ac4481cc8f2fd18cf",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:15:18.748Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:18:05.224Z",
+      "duration_ms": 166476
+    },
+    {
+      "agent_id": "ad8e51b3e49b68c5b",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:18:33.453Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:19:04.229Z",
+      "duration_ms": 30776
+    },
+    {
+      "agent_id": "a8d69927a9c24e9b5",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:31:25.163Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:36:32.272Z",
+      "duration_ms": 307109
+    },
+    {
+      "agent_id": "a9f7c771d702937f2",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:31:25.222Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:35:27.501Z",
+      "duration_ms": 242279
+    },
+    {
+      "agent_id": "aaecb7b0d7ead5188",
+      "agent_type": "general-purpose",
+      "started_at": "2026-04-20T16:31:25.289Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-20T16:32:32.484Z",
+      "duration_ms": 67195
     }
   ],
-  "total_spawned": 118,
-  "total_completed": 127,
+  "total_spawned": 135,
+  "total_completed": 157,
   "total_failed": 0,
-  "last_updated": "2026-04-20T02:13:36.867Z"
+  "last_updated": "2026-04-20T17:02:18.739Z"
 }
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/JobFactory.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/JobFactory.cs
index 224be01..3d6e525 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/JobFactory.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/JobFactory.cs
@@ -19,6 +19,7 @@
 using Quartz.Spi;
 using Quartz;
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -28,7 +29,7 @@
 namespace WIDESEAWCS_QuartzJob
 {
     /// <summary>
-    /// Job娉ㄥ叆
+    /// Job娉ㄥ叆宸ュ巶锛岀鐞� Job 瀹炰緥鐨� DI 浣滅敤鍩熺敓鍛藉懆鏈�
     /// </summary>
     public class JobFactory : IJobFactory
     {
@@ -38,48 +39,71 @@
         private readonly IServiceProvider _serviceProvider;
 
         /// <summary>
+        /// Job 瀹炰緥涓庡搴旂殑 DI 浣滅敤鍩熸槧灏勶紝鐢ㄤ簬鍦� ReturnJob 鏃舵纭噴鏀捐祫婧�
+        /// </summary>
+        private readonly ConcurrentDictionary<IJob, IServiceScope> _scopes = new();
+
+        /// <summary>
         /// Job娉ㄥ叆
         /// </summary>
-        /// <param name="serviceProvider"></param>
+        /// <param name="serviceProvider">鏈嶅姟鎻愪緵鑰�</param>
         public JobFactory(IServiceProvider serviceProvider)
         {
             _serviceProvider = serviceProvider;
         }
 
         /// <summary>
-        /// 瀹炵幇鎺ュ彛Job
+        /// 鍒涘缓 Job 瀹炰緥锛屽苟涓烘瘡涓� Job 鍒涘缓鐙珛鐨� DI 浣滅敤鍩�
         /// </summary>
-        /// <param name="bundle"></param>
-        /// <param name="scheduler"></param>
-        /// <returns></returns>
+        /// <param name="bundle">瑙﹀彂鍣ㄨЕ鍙戜笂涓嬫枃</param>
+        /// <param name="scheduler">璋冨害鍣ㄥ疄渚�</param>
+        /// <returns>Job 瀹炰緥</returns>
         public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
         {
             try
             {
-                if (App.ExpDateTime != null && (DateTime.Now - App.ExpDateTime.GetValueOrDefault()).Seconds > 0)
+                // 楠岃瘉鏈夋晥鏈燂紝浣跨敤 TotalSeconds 閬垮厤 .Seconds 鍙栨ā瀵艰嚧闂存瓏鎬у垽鏂敊璇�
+                if (App.ExpDateTime != null && (DateTime.Now - App.ExpDateTime.GetValueOrDefault()).TotalSeconds > 0)
                 {
                     throw new InvalidOperationException($"楠岃瘉閿欒");
                 }
 
+                // 涓烘瘡涓� Job 鍒涘缓鐙珛鐨� DI 浣滅敤鍩燂紝纭繚 Scoped 鏈嶅姟姝g‘閲婃斁
                 IServiceScope serviceScope = _serviceProvider.CreateScope();
                 IJob? job = serviceScope.ServiceProvider.GetService(bundle.JobDetail.JobType) as IJob;
+
+                if (job == null)
+                {
+                    // Job 瑙f瀽澶辫触鏃剁珛鍗抽噴鏀句綔鐢ㄥ煙锛岄伩鍏嶆硠婕�
+                    serviceScope.Dispose();
+                    throw new InvalidOperationException($"鏃犳硶瑙f瀽 Job 绫诲瀷: {bundle.JobDetail.JobType.Name}");
+                }
+
+                // 淇濆瓨 scope 寮曠敤锛屼互渚� ReturnJob 鏃堕噴鏀�
+                _scopes[job] = serviceScope;
                 return job;
             }
             catch (Exception ex)
             {
                 Console.Out.WriteLine(ex.ToString());
-                throw new Exception(ex.Message);
+                throw;
             }
         }
 
         /// <summary>
-        /// Job娉ㄥ叆
+        /// 閲婃斁 Job 瀹炰緥鍙婂叾鍏宠仈鐨� DI 浣滅敤鍩�
         /// </summary>
-        /// <param name="job"></param>
+        /// <param name="job">寰呴噴鏀剧殑 Job 瀹炰緥</param>
         public void ReturnJob(IJob job)
         {
-            IDisposable? disposable = job as IDisposable;
-            disposable?.Dispose();
+            // 鍏堥噴鏀惧叧鑱旂殑 DI 浣滅敤鍩燂紙鍖呮嫭鍏朵腑鎵�鏈� Scoped 鏈嶅姟锛�
+            if (_scopes.TryRemove(job, out IServiceScope? scope))
+            {
+                scope.Dispose();
+            }
+
+            // 鍐嶉噴鏀� Job 鏈韩
+            (job as IDisposable)?.Dispose();
         }
     }
 }
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs
index 41e3e7e..9caa056 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs
@@ -50,7 +50,7 @@
 
                 deviceInfos.ForEach(x =>
                 {
-                    if (!Storage.Devices.Exists(d => d.DeviceCode == x.DeviceCode))
+                    if (!Storage.Devices.Any(d => d.DeviceCode == x.DeviceCode))
                     {
                         try
                         {
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/SchedulerCenterServer.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/SchedulerCenterServer.cs
index 919b7e9..6be42fe 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/SchedulerCenterServer.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/SchedulerCenterServer.cs
@@ -86,7 +86,7 @@
             WebResponseContent result = new WebResponseContent();
             try
             {
-                if (_scheduler.IsShutdown && _scheduler.IsStarted)
+                if (_scheduler.IsShutdown || !_scheduler.IsStarted)
                 {
                     // 浠嶧actory涓幏鍙朣cheduler瀹炰緥
                     NameValueCollection collection = new NameValueCollection
@@ -110,7 +110,7 @@
                 }
                 else
                 {
-                    await _scheduler.Shutdown();
+                    // 璋冨害鍣ㄥ凡鍦ㄨ繍琛岋紝鐩存帴杩斿洖鎻愮ず
                     result = WebResponseContent.Instance.Error(QuartzJobInfoMessage.JobHasStart);
                     return result;
                 }
@@ -135,16 +135,13 @@
                     //绛夊緟浠诲姟杩愯瀹屾垚
                     await _scheduler.Shutdown(false);
 
-                    await Console.Out.WriteLineAsync(QuartzJobInfoMessage.StopJobSuccess);
+                    QuartzLogger.Info(QuartzJobInfoMessage.StopJobSuccess);
                     result = WebResponseContent.Instance.OK(QuartzJobInfoMessage.StopJobSuccess);
                     return result;
                 }
                 else
                 {
-                    IReadOnlyCollection<string> jobGroupNames = await _scheduler.GetJobGroupNames();
-
-                    await _scheduler.PauseAll();
-
+                    // 璋冨害鍣ㄥ凡鍋滄锛岀洿鎺ヨ繑鍥炴彁绀猴紙涓嶅啀瀵瑰凡 shutdown 鐨� scheduler 璋冪敤 PauseAll锛�
                     result = WebResponseContent.Instance.Error(QuartzJobInfoMessage.JobHasStop);
                     return result;
                 }
@@ -169,7 +166,7 @@
             {
                 try
                 {
-                    if (_scheduler.IsShutdown && _scheduler.IsStarted)
+                    if (_scheduler.IsShutdown || !_scheduler.IsStarted)
                     {
                         // 浠嶧actory涓幏鍙朣cheduler瀹炰緥
                         NameValueCollection collection = new NameValueCollection
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs
index 4e70c2f..06829af 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/StackerCrane/Common/CommonStackerCrane.cs
@@ -20,12 +20,14 @@
 using HslCommunication;
 using System.ComponentModel;
 using System.Reflection;
+using System.Threading;
 using WIDESEAWCS_Communicator;
 using WIDESEAWCS_QuartzJob.DeviceBase;
 using WIDESEAWCS_QuartzJob.DTO;
 using WIDESEAWCS_QuartzJob.StackerCrane;
 using WIDESEAWCS_QuartzJob.StackerCrane.Common;
 using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
+using WIDESEAWCS_Core.LogHelper;
 
 namespace WIDESEAWCS_QuartzJob
 {
@@ -67,7 +69,10 @@
         /// </summary>
         private int _lastTaskNum;
 
-        private bool _isChecked = false;
+        /// <summary>
+        /// 鏍囪鏄惁姝e湪妫�鏌ヤ换鍔″畬鎴愮姸鎬侊紙volatile 淇濊瘉澶氱嚎绋嬪彲瑙佹�э級
+        /// </summary>
+        private volatile bool _isChecked = false;
 
         private bool _heartStatr = true;
 
@@ -399,30 +404,33 @@
                         {
                             OperateResult<TimeSpan> operateResult = new OperateResult<TimeSpan>();
                             TypeCode typeCode = SiemensDBDataType.GetTypeCode(devicePro.DeviceDataType);
+
+                            // 瓒呮椂浠� 10*6000ms (60s) 闄嶄綆鍒� 10*1000ms (10s)锛岄槻姝㈡柇杩炴椂闀挎椂闂撮樆濉�
+                            int timeout = 10 * 1000;
                             switch (typeCode)
                             {
                                 case TypeCode.Boolean:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToBoolean(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToBoolean(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
 
                                 case TypeCode.Byte:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToByte(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToByte(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
 
                                 case TypeCode.Int16:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToInt16(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToInt16(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
 
                                 case TypeCode.Int32:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToInt32(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToInt32(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
 
                                 case TypeCode.UInt16:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToUInt16(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToUInt16(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
 
                                 case TypeCode.UInt32:
-                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToUInt32(deviceProtocolDetail.ProtocalDetailValue));
+                                    operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToUInt32(deviceProtocolDetail.ProtocalDetailValue));
                                     break;
 
                                 default:
@@ -440,6 +448,8 @@
                 }
                 catch (Exception ex)
                 {
+                    // 璁板綍寮傚父锛岄伩鍏嶉敊璇闈欓粯鍚炴帀
+                    QuartzLogger.Error($"CheckStackerCraneTaskCompleted: 璁惧 {_deviceCode} 妫�鏌ュ紓甯�", "CommonStackerCrane", ex);
                 }
                 finally
                 {
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Storage.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Storage.cs
index e8a07d7..15c9114 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Storage.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Storage.cs
@@ -3,6 +3,7 @@
 using Quartz;
 using SqlSugar;
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Drawing;
@@ -19,14 +20,14 @@
 namespace WIDESEAWCS_QuartzJob
 {
     /// <summary>
-    /// 闈欐�佸彉鑴稿瓨鍌ㄥ尯锛屽彲浣跨敤闈欐�佸彉閲忥紝涔熷彲娉ㄥ叆浣跨敤
+    /// 闈欐�佸彉閲忓瓨鍌ㄥ尯锛屽彲浣跨敤闈欐�佸彉閲忥紝涔熷彲娉ㄥ叆浣跨敤
     /// </summary>
     public class Storage
     {
         /// <summary>
-        /// 宸茶繛鎺ヨ澶囧璞¢泦鍚�
+        /// 宸茶繛鎺ヨ澶囧璞¢泦鍚堬紙绾跨▼瀹夊叏锛�
         /// </summary>
-        public static List<IDevice> Devices = new List<IDevice>();
+        public static ConcurrentBag<IDevice> Devices = new ConcurrentBag<IDevice>();
 
         /// <summary>
         /// 璁惧瀵硅薄
@@ -44,8 +45,8 @@
         /// <summary>
         /// 鑾峰彇璁惧
         /// </summary>
-        /// <param name="deviceCode"></param>
-        /// <returns></returns>
+        /// <param name="deviceCode">璁惧缂栫爜</param>
+        /// <returns>璁惧瀹炰緥锛屾湭鎵惧埌杩斿洖 null</returns>
         public IDevice? GetDevice(string deviceCode)
         {
             return Pro_Devices.FirstOrDefault(x => x.DeviceCode == deviceCode);
@@ -54,8 +55,8 @@
         /// <summary>
         /// 鑾峰彇璁惧
         /// </summary>
-        /// <param name="deviceCodes"></param>
-        /// <returns></returns>
+        /// <param name="deviceCodes">璁惧缂栫爜鍒楄〃</param>
+        /// <returns>鍖归厤鐨勮澶囧垪琛�</returns>
         public List<IDevice> GetDevices(List<string> deviceCodes)
         {
             return Pro_Devices.Where(x => deviceCodes.Contains(x.DeviceCode)).ToList();
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
index 9e558aa..caf766d 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
@@ -18,7 +18,8 @@
   "Logging": {
     "LogLevel": {
       "Default": "Information",
-      "Microsoft.AspNetCore": "Warning"
+      "Microsoft.AspNetCore": "Warning",
+      "Quartz": "Debug"
     }
   },
   "dics": "deviceType,devicePlcType,jobAssembly,jobClassName,deviceStatus,taskType,taskState,inOutType,dispatchId",
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/CommonConveyorLineJob.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/CommonConveyorLineJob.cs
index 34470e0..c4d84ef 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/CommonConveyorLineJob.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/CommonConveyorLineJob.cs
@@ -28,6 +28,7 @@
 using WIDESEAWCS_Communicator;
 using WIDESEAWCS_Core;
 using WIDESEAWCS_Core.Helper;
+using WIDESEAWCS_Core.LogHelper;
 using WIDESEAWCS_ITaskInfoService;
 using WIDESEAWCS_Model.Models;
 using WIDESEAWCS_QuartzJob;
@@ -87,6 +88,8 @@
             }
             catch (Exception ex)
             {
+                // 璁板綍寮傚父锛岄伩鍏嶉敊璇闈欓粯鍚炴帀
+                QuartzLogger.Error("CommonConveyorLineJob Execute 寮傚父", "CommonConveyorLineJob", ex);
             }
             return Task.CompletedTask;
         }
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
index 984336f..385b838 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/CommonStackerCraneJob.cs
@@ -111,13 +111,13 @@
             _logger = logger;
 
             // 鍔犺浇閰嶇疆鏂囦欢
-            _config = LoadConfig();
+            //_config = LoadConfig();
 
             // 鍒濆鍖栦换鍔¢�夋嫨鍣�
             _taskSelector = new StackerCraneTaskSelector(taskService, routerService, httpClientHelper, _logger);
 
             // 鍒濆鍖栧懡浠ゆ瀯寤哄櫒
-            _commandBuilder = new StackerCraneCommandBuilder(taskService, routerService, _config, _logger);
+            _commandBuilder = new StackerCraneCommandBuilder(taskService, routerService, _logger);
         }
 
         /// <summary>
@@ -222,7 +222,7 @@
                 bool sendFlag = SendStackerCraneCommand(commonStackerCrane, stackerCraneTaskCommand);
                 if (sendFlag)
                 {
-                    Task.Delay(1000).Wait();
+                    Thread.Sleep(1000);
                     commonStackerCrane.SetValue(StackerCraneDBName.WorkAction, (short)StackerCraneWorkActionEnum.StartTask);
                     // 鍙戦�佹垚鍔燂紝鏇存柊鐘舵��
                     commonStackerCrane.LastTaskType = task.TaskType;
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneCommandBuilder.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneCommandBuilder.cs
index 3fdd873..ae7cb04 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneCommandBuilder.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneCommandBuilder.cs
@@ -37,11 +37,6 @@
         private readonly IRouterService _routerService;
 
         /// <summary>
-        /// 鍫嗗灈鏈哄懡浠ら厤缃�
-        /// </summary>
-        private readonly StackerCraneCommandConfig _config;
-
-        /// <summary>
         /// 鏃ュ織璁板綍鍣�
         /// </summary>
         private readonly ILogger _logger;
@@ -56,12 +51,10 @@
         public StackerCraneCommandBuilder(
             ITaskService taskService,
             IRouterService routerService,
-            StackerCraneCommandConfig config,
             ILogger logger)
         {
             _taskService = taskService;
             _routerService = routerService;
-            _config = config;
             _logger = logger;
         }
 
@@ -99,20 +92,20 @@
         /// </remarks>
         /// <param name="roadway">宸烽亾缂栫爜</param>
         /// <returns>鍛戒护绫诲瀷锛圫tandard 鎴� Formation锛�</returns>
-        private string GetCommandType(string roadway)
-        {
-            foreach (var mapping in _config.RoadwayCommandMapping)
-            {
-                if (roadway.Contains(mapping.Key))
-                {
-                    QuartzLogHelper.LogDebug(_logger, "GetCommandType锛氬尮閰嶅贩閬� {Roadway}锛屽懡浠ょ被鍨�: {CommandType}", $"GetCommandType锛氬尮閰嶅贩閬� {roadway}锛屽懡浠ょ被鍨�: {mapping.Value}", roadway, roadway, mapping.Value);
-                    return mapping.Value;
-                }
-            }
+        //private string GetCommandType(string roadway)
+        //{
+        //    foreach (var mapping in _config.RoadwayCommandMapping)
+        //    {
+        //        if (roadway.Contains(mapping.Key))
+        //        {
+        //            QuartzLogHelper.LogDebug(_logger, "GetCommandType锛氬尮閰嶅贩閬� {Roadway}锛屽懡浠ょ被鍨�: {CommandType}", $"GetCommandType锛氬尮閰嶅贩閬� {roadway}锛屽懡浠ょ被鍨�: {mapping.Value}", roadway, roadway, mapping.Value);
+        //            return mapping.Value;
+        //        }
+        //    }
 
-            QuartzLogHelper.LogDebug(_logger, "GetCommandType锛氬贩閬� {Roadway} 鏈尮閰嶏紝浣跨敤榛樿鍛戒护绫诲瀷: {DefaultType}", $"GetCommandType锛氬贩閬� {roadway} 鏈尮閰嶏紝浣跨敤榛樿鍛戒护绫诲瀷: {_config.DefaultCommandType}", roadway, roadway, _config.DefaultCommandType);
-            return _config.DefaultCommandType;
-        }
+        //    QuartzLogHelper.LogDebug(_logger, "GetCommandType锛氬贩閬� {Roadway} 鏈尮閰嶏紝浣跨敤榛樿鍛戒护绫诲瀷: {DefaultType}", $"GetCommandType锛氬贩閬� {roadway} 鏈尮閰嶏紝浣跨敤榛樿鍛戒护绫诲瀷: {_config.DefaultCommandType}", roadway, roadway, _config.DefaultCommandType);
+        //    return _config.DefaultCommandType;
+        //}
 
         /// <summary>
         /// 鍒涘缓鏍囧噯鍛戒护
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMesUploadHelper.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMesUploadHelper.cs
new file mode 100644
index 0000000..705c340
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMesUploadHelper.cs
@@ -0,0 +1,28 @@
+using WIDESEA_Common.StockEnum;
+using WIDESEA_Core;
+
+namespace WIDESEA_IBasicService
+{
+    /// <summary>
+    /// MES寮傛涓婁紶杈呭姪鏈嶅姟 - 灏佽Task.Run + 鐘舵�佹洿鏂� + 鏃ュ織璁板綍鐨勭粺涓�妯″紡
+    /// </summary>
+    public interface IMesUploadHelper : IDependency
+    {
+        /// <summary>
+        /// 浠ire-and-forget鏂瑰紡寮傛鎵цMES璋冪敤锛岃嚜鍔ㄦ洿鏂颁笂浼犵姸鎬佸苟璁板綍鏃ュ織
+        /// </summary>
+        /// <param name="palletCode">鎵樼洏鍙�</param>
+        /// <param name="successStatus">鎴愬姛鏃剁殑鐘舵�佹灇涓惧�硷紙濂囨暟=鎴愬姛锛屽伓鏁�=澶辫触锛�</param>
+        /// <param name="apiType">MES鎺ュ彛绫诲瀷鍚嶇О</param>
+        /// <param name="requestJson">璇锋眰JSON锛堢敤浜庢棩蹇楄褰曪級</param>
+        /// <param name="mesCall">MES璋冪敤濮旀墭锛岃繑鍥�(鏄惁鎴愬姛, 鍝嶅簲JSON, 閿欒娑堟伅)</param>
+        /// <param name="creator">鎿嶄綔浜�</param>
+        void FireAndForget(
+            string palletCode,
+            MesUploadStatusEnum successStatus,
+            string apiType,
+            string requestJson,
+            Func<(bool isSuccess, string responseJson, string errorMessage)> mesCall,
+            string creator = "System");
+    }
+}
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/MesUploadHelper.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/MesUploadHelper.cs
new file mode 100644
index 0000000..52672b6
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/MesUploadHelper.cs
@@ -0,0 +1,93 @@
+using System.Diagnostics;
+using WIDESEA_Common.StockEnum;
+using WIDESEA_Core;
+using WIDESEA_DTO.MES;
+using WIDESEA_IStockService;
+using WIDESEA_IBasicService;
+
+namespace WIDESEA_StockService
+{
+    /// <summary>
+    /// MES寮傛涓婁紶杈呭姪鏈嶅姟瀹炵幇
+    /// </summary>
+    public class MesUploadHelper : IMesUploadHelper
+    {
+        private readonly IStockInfoService _stockInfoService;
+        private readonly IMesLogService _mesLogService;
+
+        /// <summary>
+        /// 鏋勯�犲嚱鏁�
+        /// </summary>
+        /// <param name="stockInfoService">搴撳瓨淇℃伅鏈嶅姟</param>
+        /// <param name="mesLogService">MES鏃ュ織鏈嶅姟</param>
+        public MesUploadHelper(IStockInfoService stockInfoService, IMesLogService mesLogService)
+        {
+            _stockInfoService = stockInfoService;
+            _mesLogService = mesLogService;
+        }
+
+        /// <summary>
+        /// 浠ire-and-forget鏂瑰紡寮傛鎵цMES璋冪敤锛岃嚜鍔ㄦ洿鏂颁笂浼犵姸鎬佸苟璁板綍鏃ュ織
+        /// </summary>
+        public void FireAndForget(
+            string palletCode,
+            MesUploadStatusEnum successStatus,
+            string apiType,
+            string requestJson,
+            Func<(bool isSuccess, string responseJson, string errorMessage)> mesCall,
+            string creator = "System")
+        {
+            _ = Task.Run(async () =>
+            {
+                var stopwatch = Stopwatch.StartNew();
+                try
+                {
+                    var (isSuccess, responseJson, errorMessage) = mesCall();
+                    stopwatch.Stop();
+
+                    // 濂囨暟=鎴愬姛锛屽伓鏁�=澶辫触
+                    int status = isSuccess ? (int)successStatus : (int)successStatus + 1;
+                    await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, status);
+
+                    await LogAsync(palletCode, apiType, requestJson, responseJson,
+                        stopwatch.ElapsedMilliseconds, isSuccess, errorMessage, creator);
+                }
+                catch (Exception ex)
+                {
+                    stopwatch.Stop();
+                    int status = (int)successStatus + 1;
+                    await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, status);
+
+                    await LogAsync(palletCode, apiType, requestJson, "",
+                        stopwatch.ElapsedMilliseconds, false, ex.Message, creator);
+                }
+            });
+        }
+
+        /// <summary>
+        /// 璁板綍MES鎺ュ彛璋冪敤鏃ュ織
+        /// </summary>
+        private async Task LogAsync(string palletCode, string apiType, string requestJson,
+            string responseJson, long elapsedMs, bool isSuccess, string errorMessage, string creator)
+        {
+            try
+            {
+                await _mesLogService.LogAsync(new MesApiLogDto
+                {
+                    PalletCode = palletCode,
+                    ApiType = apiType,
+                    RequestJson = requestJson,
+                    ResponseJson = responseJson,
+                    IsSuccess = isSuccess,
+                    ErrorMessage = errorMessage,
+                    ElapsedMs = (int)elapsedMs,
+                    Creator = creator
+                });
+            }
+            catch
+            {
+                // 鏃ュ織璁板綍澶辫触涓嶅奖鍝嶄富娴佺▼
+            }
+        }
+    }
+}
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs
index 8a808ae..59e0f51 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs
@@ -391,7 +391,7 @@
         {
             try
             {
-                var stockInfo = await BaseDal.QueryDataFirstAsync(x => x.PalletCode == palletCode);
+                var stockInfo = await BaseDal.QueryFirstAsync(x => x.PalletCode == palletCode);
                 if (stockInfo == null)
                     return false;
 
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
index 81914e7..1e37368 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
@@ -1,6 +1,5 @@
 锘縰sing Newtonsoft.Json;
 using SqlSugar;
-using System.Diagnostics;
 using WIDESEA_Common.Constants;
 using WIDESEA_Common.StockEnum;
 using WIDESEA_Core;
@@ -54,6 +53,7 @@
         public IMesService _mesService { get; }
 
         private readonly IMesLogService _mesLogService;
+        private readonly IMesUploadHelper _mesUploadHelper;
 
         /// <summary>
         /// 鏋勯�犲嚱鏁�
@@ -62,6 +62,7 @@
         /// <param name="stockInfoService">搴撳瓨淇℃伅鏈嶅姟</param>
         /// <param name="stockInfoDetail_HtyService">搴撳瓨鏄庣粏鍘嗗彶鏈嶅姟</param>
         /// <param name="stockInfo_HtyService">搴撳瓨鍘嗗彶鏈嶅姟</param>
+        /// <param name="mesUploadHelper">MES寮傛涓婁紶杈呭姪鏈嶅姟</param>
         public StockService(
             IStockInfoDetailService stockInfoDetailService,
             IStockInfoService stockInfoService,
@@ -70,7 +71,8 @@
             IMesService mesService,
             IWarehouseService warehouseService,
             ISqlSugarClient sqlSugarClient,
-            IMesLogService mesLogService)
+            IMesLogService mesLogService,
+            IMesUploadHelper mesUploadHelper)
         {
             StockInfoDetailService = stockInfoDetailService;
             StockInfoService = stockInfoService;
@@ -80,6 +82,7 @@
             _warehouseService = warehouseService;
             SqlSugarClient = sqlSugarClient;
             _mesLogService = mesLogService;
+            _mesUploadHelper = mesUploadHelper;
         }
 
         /// <summary>
@@ -444,43 +447,25 @@
                     ContainCode = palletCode,
                     SfcList = sfcList
                 };
-                _ = Task.Run(() =>
-                {
-                    var stopwatch = Stopwatch.StartNew();
-                    try
+                string requestJson = unbindRequest.ToJson();
+                var localToken = token;
+
+                _mesUploadHelper.FireAndForget(
+                    palletCode,
+                    MesUploadStatusEnum.鎷嗙洏涓婁紶鎴愬姛,
+                    "UnBindContainer",
+                    requestJson,
+                    () =>
                     {
-                        var unbindResult = string.IsNullOrWhiteSpace(token)
+                        var result = string.IsNullOrWhiteSpace(localToken)
                             ? _mesService.UnBindContainer(unbindRequest)
-                            : _mesService.UnBindContainer(unbindRequest, token);
-                        stopwatch.Stop();
-
-                        bool isSuccess = unbindResult?.Data?.IsSuccess ?? false;
-                        int status = isSuccess
-                            ? (int)MesUploadStatusEnum.鎷嗙洏涓婁紶鎴愬姛
-                            : (int)MesUploadStatusEnum.鎷嗙洏涓婁紶澶辫触;
-
-                        // 鏇存柊MES涓婁紶鐘舵��
-                        StockInfoService.UpdateMesUploadStatusAsync(palletCode, status).ConfigureAwait(false);
-
-                        // 璁板綍MES鏃ュ織
-                        _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = palletCode,
-                            ApiType = "UnBindContainer",
-                            RequestJson = unbindRequest.ToJson(),
-                            ResponseJson = System.Text.Json.JsonSerializer.Serialize(unbindResult),
-                            IsSuccess = isSuccess,
-                            ErrorMessage = unbindResult?.Data?.Msg ?? unbindResult?.ErrorMessage ?? "鏈煡閿欒",
-                            ElapsedMs = (int)stopwatch.ElapsedMilliseconds,
-                            Creator = "System"
-                        }).ConfigureAwait(false);
-                    }
-                    catch (Exception ex)
-                    {
-                        // 璋冪敤澶辫触
-                        StockInfoService.UpdateMesUploadStatusAsync(palletCode, (int)MesUploadStatusEnum.鎷嗙洏涓婁紶澶辫触).ConfigureAwait(false);
-                    }
-                });
+                            : _mesService.UnBindContainer(unbindRequest, localToken);
+                        return (
+                            result?.Data?.IsSuccess ?? false,
+                            System.Text.Json.JsonSerializer.Serialize(result),
+                            result?.Data?.Msg ?? result?.ErrorMessage ?? "鏈煡閿欒"
+                        );
+                    });
 
                 // 4. 鍒犻櫎涓存椂琛ㄨ褰�
                 await SqlSugarClient.Deleteable<Dt_SplitTemp>().Where(t => t.PalletCode == palletCode).ExecuteCommandAsync();
@@ -502,7 +487,6 @@
         public async Task<WebResponseContent> GroupPalletConfirmAsync(string palletCode, string deviceName)
         {
             WebResponseContent content = new WebResponseContent();
-            var stopwatch = Stopwatch.StartNew();
             try
             {
                 if (string.IsNullOrWhiteSpace(palletCode))
@@ -548,44 +532,25 @@
                     }).ToList()
                 };
                 string requestJson = bindRequest.ToJson();
+                var localToken = token;
+
                 // 3. Fire-and-forget寮傛璋冪敤MES缁戝畾
-                _ = Task.Run(() =>
-                {
-                    var stopwatch = Stopwatch.StartNew();
-                    try
+                _mesUploadHelper.FireAndForget(
+                    palletCode,
+                    MesUploadStatusEnum.缁勭洏涓婁紶鎴愬姛,
+                    "BindContainer",
+                    requestJson,
+                    () =>
                     {
-                        var bindResult = string.IsNullOrWhiteSpace(token)
+                        var result = string.IsNullOrWhiteSpace(localToken)
                             ? _mesService.BindContainer(bindRequest)
-                            : _mesService.BindContainer(bindRequest, token);
-                        stopwatch.Stop();
-
-                        bool isSuccess = bindResult?.Data?.IsSuccess ?? false;
-                        int status = isSuccess
-                            ? (int)MesUploadStatusEnum.缁勭洏涓婁紶鎴愬姛
-                            : (int)MesUploadStatusEnum.缁勭洏涓婁紶澶辫触;
-
-                        // 鏇存柊MES涓婁紶鐘舵��
-                        StockInfoService.UpdateMesUploadStatusAsync(palletCode, status).ConfigureAwait(false);
-
-                        // 璁板綍MES鏃ュ織
-                        _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = palletCode,
-                            ApiType = "BindContainer",
-                            RequestJson = requestJson,
-                            ResponseJson = System.Text.Json.JsonSerializer.Serialize(bindResult),
-                            IsSuccess = isSuccess,
-                            ErrorMessage = bindResult?.ErrorMessage ?? "鏈煡閿欒",
-                            ElapsedMs = (int)stopwatch.ElapsedMilliseconds,
-                            Creator = "System"
-                        }).ConfigureAwait(false);
-                    }
-                    catch (Exception ex)
-                    {
-                        // 璋冪敤澶辫触
-                        StockInfoService.UpdateMesUploadStatusAsync(palletCode, (int)MesUploadStatusEnum.缁勭洏涓婁紶澶辫触).ConfigureAwait(false);
-                    }
-                });
+                            : _mesService.BindContainer(bindRequest, localToken);
+                        return (
+                            result?.Data?.IsSuccess ?? false,
+                            System.Text.Json.JsonSerializer.Serialize(result),
+                            result?.Data?.Msg ?? result?.ErrorMessage ?? "鏈煡閿欒"
+                        );
+                    });
 
                 return content.OK("鎵归噺缁勭洏纭鎴愬姛");
             }
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
index d232686..241396b 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -17,10 +17,7 @@
 using WIDESEA_Core.Helper;
 using WIDESEA_DTO.GradingMachine;
 using WIDESEA_DTO.MES;
-using WIDESEA_DTO.Stock;
 using WIDESEA_DTO.Task;
-using Newtonsoft.Json;
-using System.Diagnostics;
 using WIDESEA_IBasicService;
 using WIDESEA_IRecordService;
 using WIDESEA_IStockService;
@@ -44,6 +41,7 @@
         private readonly IRecordService _recordService;
         private readonly IMESDeviceConfigService _mesDeviceConfigService;
         private readonly IMesLogService _mesLogService;
+        private readonly IMesUploadHelper _mesUploadHelper;
 
         public IRepository<Dt_Task> Repository => BaseDal;
 
@@ -70,7 +68,8 @@
             IUnitOfWorkManage unitOfWorkManage,
             IRecordService recordService,
             IMESDeviceConfigService mesDeviceConfigService,
-            IMesLogService mesLogService) : base(BaseDal)
+            IMesLogService mesLogService,
+            IMesUploadHelper mesUploadHelper) : base(BaseDal)
         {
             _mapper = mapper;
             _stockInfoService = stockInfoService;
@@ -85,6 +84,7 @@
             _recordService = recordService;
             _mesDeviceConfigService = mesDeviceConfigService;
             _mesLogService = mesLogService;
+            _mesUploadHelper = mesUploadHelper;
         }
 
         /// <summary>
@@ -200,80 +200,5 @@
             return DetermineTargetAddress(roadway, addressMap);
         }
 
-        /// <summary>
-        /// 寮傛鎵цMES涓婁紶 - 涓嶉樆濉炰富涓氬姟閫昏緫
-        /// </summary>
-        /// <param name="palletCode">鎵樼洏鍙�</param>
-        /// <param name="successStatus">鎴愬姛鏃剁殑鐘舵�佹灇涓惧�硷紙濂囨暟锛�</param>
-        /// <param name="uploadFunc">鍏蜂綋鐨凪ES璋冪敤鍑芥暟</param>
-        private async Task MesUploadAsync(string palletCode, MesUploadStatusEnum successStatus, Func<Task<HttpResponseResult<MesResponse>>> uploadFunc)
-        {
-            var stopwatch = Stopwatch.StartNew();
-            string requestJson = "";
-            string responseJson = "";
-            bool isSuccess = false;
-            string errorMessage = "";
-
-            try
-            {
-                // 璋冪敤MES
-                var result = await uploadFunc();
-
-                stopwatch.Stop();
-                isSuccess = result?.Data?.IsSuccess ?? false;
-                errorMessage = result?.Data?.Msg ?? result?.ErrorMessage ?? "鏈煡閿欒";
-                responseJson = JsonConvert.SerializeObject(result);
-
-                // 鏍规嵁鎴愬姛/澶辫触鍐冲畾鐘舵�佸�硷細濂囨暟=鎴愬姛锛屽伓鏁�=澶辫触
-                var uploadStatus = isSuccess ? (int)successStatus : (int)successStatus + 1;
-
-                // 鏇存柊搴撳瓨琛ㄧ姸鎬侊紙涓嶇瓑寰咃級
-                _ = _stockInfoService.UpdateMesUploadStatusAsync(palletCode, uploadStatus);
-
-                // 璁板綍MES鏃ュ織
-                await LogMesCallAsync(palletCode, successStatus.ToString(), requestJson, responseJson,
-                    stopwatch.ElapsedMilliseconds, isSuccess ? "鎴愬姛" : "澶辫触", errorMessage);
-            }
-            catch (Exception ex)
-            {
-                stopwatch.Stop();
-                errorMessage = ex.Message;
-
-                // 鏇存柊鐘舵�佷负澶辫触锛坰uccessStatus+1 鍗充负澶辫触鐘舵�侊級
-                var uploadStatus = (int)successStatus + 1;
-                _ = _stockInfoService.UpdateMesUploadStatusAsync(palletCode, uploadStatus);
-
-                // 璁板綍寮傚父鏃ュ織
-                await LogMesCallAsync(palletCode, successStatus.ToString(), requestJson, responseJson,
-                    stopwatch.ElapsedMilliseconds, "澶辫触", errorMessage);
-            }
-        }
-
-        /// <summary>
-        /// 璁板綍MES鎺ュ彛璋冪敤鏃ュ織
-        /// </summary>
-        private async Task LogMesCallAsync(string palletCode, string apiType, string requestJson,
-            string responseJson, long durationMs, string status, string errorMessage)
-        {
-            try
-            {
-                var mesLog = new MesApiLogDto
-                {
-                    PalletCode = palletCode,
-                    ApiType = apiType,
-                    RequestJson = requestJson,
-                    ResponseJson = responseJson,
-                    IsSuccess = status == "鎴愬姛",
-                    ErrorMessage = errorMessage,
-                    ElapsedMs = (int)durationMs,
-                    Creator = "System"
-                };
-                await _mesLogService.LogAsync(mesLog);
-            }
-            catch
-            {
-                // 鏃ュ織璁板綍澶辫触涓嶅奖鍝嶄富娴佺▼
-            }
-        }
     }
 }
\ No newline at end of file
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Inbound.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Inbound.cs
index c8a798c..1a731c9 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Inbound.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Inbound.cs
@@ -1,6 +1,4 @@
-using Microsoft.AspNetCore.Http.HttpResults;
 using Newtonsoft.Json;
-using System.Diagnostics;
 using WIDESEA_Common.Constants;
 using WIDESEA_Common.LocationEnum;
 using WIDESEA_Common.StockEnum;
@@ -122,7 +120,6 @@
         /// </summary>
         public async Task<WebResponseContent> InboundFinishTaskAsync(CreateTaskDto taskDto)
         {
-            var stopwatch = Stopwatch.StartNew();
             try
             {
                 var task = await BaseDal.QueryFirstAsync(s => s.PalletCode == taskDto.PalletCode);
@@ -153,8 +150,6 @@
                 }
                 else
                 {
-
-
                     // 鍒ゆ柇鏄笉鏄瀬鍗峰簱浠诲姟
                     if (taskDto.WarehouseId == (int)WarehouseEnum.FJ1 || taskDto.WarehouseId == (int)WarehouseEnum.ZJ1)
                     {
@@ -188,62 +183,33 @@
                         string token = mesConfig?.Token;
 
                         // 寮傛璋冪敤MES鎵樼洏杩涚珯锛屼笉闃诲涓婚�昏緫
-                        var palletCode = taskDto.PalletCode;
-                        var localEquipmentCode = equipmentCode;
-                        var localResourceCode = resourceCode;
-                        var localToken = token;
-                        _ = Task.Run(async () =>
+                        var inboundRequest = new InboundInContainerRequest
                         {
-                            var localStopwatch = Stopwatch.StartNew();
-                            try
+                            EquipmentCode = equipmentCode,
+                            ResourceCode = resourceCode,
+                            LocalTime = DateTime.Now,
+                            ContainerCode = taskDto.PalletCode
+                        };
+                        string requestJson = inboundRequest.ToJson();
+                        var palletCode = taskDto.PalletCode;
+
+                        _mesUploadHelper.FireAndForget(
+                            palletCode,
+                            MesUploadStatusEnum.杩涚珯涓婁紶鎴愬姛,
+                            "InboundInContainer",
+                            requestJson,
+                            () =>
                             {
-                                var inboundRequest = new InboundInContainerRequest
-                                {
-                                    EquipmentCode = localEquipmentCode,
-                                    ResourceCode = localResourceCode,
-                                    LocalTime = DateTime.Now,
-                                    ContainerCode = palletCode
-                                };
-                                string localRequestJson = inboundRequest.ToJson();
-                                var inboundResult = string.IsNullOrWhiteSpace(localToken)
+                                var result = string.IsNullOrWhiteSpace(token)
                                     ? _mesService.InboundInContainer(inboundRequest)
-                                    : _mesService.InboundInContainer(inboundRequest, localToken);
-                                localStopwatch.Stop();
+                                    : _mesService.InboundInContainer(inboundRequest, token);
+                                return (
+                                    result?.Data?.IsSuccess ?? false,
+                                    JsonConvert.SerializeObject(result),
+                                    result?.Data?.Msg ?? result?.ErrorMessage ?? "鏈煡閿欒"
+                                );
+                            });
 
-                                bool isSuccess = inboundResult?.Data?.IsSuccess ?? false;
-                                int status = isSuccess
-                                    ? (int)MesUploadStatusEnum.杩涚珯涓婁紶鎴愬姛
-                                    : (int)MesUploadStatusEnum.杩涚珯涓婁紶澶辫触;
-
-                                await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, status);
-
-                                await _mesLogService.LogAsync(new MesApiLogDto
-                                {
-                                    PalletCode = palletCode,
-                                    ApiType = "InboundInContainer",
-                                    RequestJson = localRequestJson,
-                                    ResponseJson = JsonConvert.SerializeObject(inboundResult),
-                                    IsSuccess = isSuccess,
-                                    ErrorMessage = inboundResult?.Data?.Msg ?? inboundResult?.ErrorMessage ?? "鏈煡閿欒",
-                                    ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                                    Creator = "systeam"
-                                });
-                            }
-                            catch (Exception ex)
-                            {
-                                localStopwatch.Stop();
-                                await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, (int)MesUploadStatusEnum.杩涚珯涓婁紶澶辫触);
-                                await _mesLogService.LogAsync(new MesApiLogDto
-                                {
-                                    PalletCode = palletCode,
-                                    ApiType = "InboundInContainer",
-                                    IsSuccess = false,
-                                    ErrorMessage = ex.Message,
-                                    ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                                    Creator = "systeam"
-                                });
-                            }
-                        });
                         return await CompleteTaskAsync(task, "鍏ュ簱瀹屾垚");
                     });
                 }
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Outbound.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Outbound.cs
index cac934b..3f0f31d 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Outbound.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Outbound.cs
@@ -1,4 +1,3 @@
-using System.Diagnostics;
 using WIDESEA_Common.Constants;
 using WIDESEA_Common.LocationEnum;
 using WIDESEA_Common.StockEnum;
@@ -60,7 +59,6 @@
         /// </summary>
         public async Task<WebResponseContent> OutboundFinishTaskAsync(CreateTaskDto taskDto)
         {
-            var stopwatch = Stopwatch.StartNew();
             try
             {
                 var task = await BaseDal.QueryFirstAsync(s => s.PalletCode == taskDto.PalletCode);
@@ -139,14 +137,25 @@
                         ContainerCode = taskDto.PalletCode
                     };
                     string palletCode = taskDto.PalletCode;
+                    string requestJson = outboundRequest.ToJson();
 
                     // Fire-and-forget: 寮傛鎵цMES鍑虹珯锛屼笉闃诲涓讳笟鍔¢�昏緫
-                    _ = Task.Run(() => MesUploadAsync(palletCode, MesUploadStatusEnum.鍑虹珯涓婁紶鎴愬姛, async () =>
-                    {
-                        return await Task.FromResult(string.IsNullOrWhiteSpace(token)
-                            ? _mesService.OutboundInContainer(outboundRequest)
-                            : _mesService.OutboundInContainer(outboundRequest, token));
-                    }));
+                    _mesUploadHelper.FireAndForget(
+                        palletCode,
+                        MesUploadStatusEnum.鍑虹珯涓婁紶鎴愬姛,
+                        "OutboundInContainer",
+                        requestJson,
+                        () =>
+                        {
+                            var result = string.IsNullOrWhiteSpace(token)
+                                ? _mesService.OutboundInContainer(outboundRequest)
+                                : _mesService.OutboundInContainer(outboundRequest, token);
+                            return (
+                                result?.Data?.IsSuccess ?? false,
+                                Newtonsoft.Json.JsonConvert.SerializeObject(result),
+                                result?.Data?.Msg ?? result?.ErrorMessage ?? "鏈煡閿欒"
+                            );
+                        });
 
                     var completeResult = await CompleteTaskAsync(task, "鍑哄簱瀹屾垚");
                     if (!completeResult.Status)
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs
index 02447f2..c04b982 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs
@@ -11,7 +11,6 @@
 using WIDESEA_Model.Models;
 using WIDESEA_Common.Constants;
 using WIDESEA_Common.StockEnum;
-using System.Diagnostics;
 
 namespace WIDESEA_WMSServer.Controllers.Stock
 {
@@ -22,25 +21,22 @@
     [ApiController]
     public class StockInfoController : ApiBaseController<IStockInfoService, Dt_StockInfo>
     {
-        private readonly IMesLogService _mesLogService;
         private readonly IMesService _mesService;
         private readonly IMESDeviceConfigService _mesDeviceConfigService;
         private readonly ISys_DictionaryService _sysDictionaryService;
-        private readonly IStockInfoService _stockInfoService;
+        private readonly IMesUploadHelper _mesUploadHelper;
 
         public StockInfoController(
             IStockInfoService service,
-            IMesLogService mesLogService,
             IMesService mesService,
             IMESDeviceConfigService mesDeviceConfigService,
             ISys_DictionaryService sysDictionaryService,
-            IStockInfoService stockInfoService) : base(service)
+            IMesUploadHelper mesUploadHelper) : base(service)
         {
-            _mesLogService = mesLogService;
             _mesService = mesService;
             _mesDeviceConfigService = mesDeviceConfigService;
             _sysDictionaryService = sysDictionaryService;
-            _stockInfoService = stockInfoService;
+            _mesUploadHelper = mesUploadHelper;
         }
 
         /// <summary>
@@ -106,50 +102,23 @@
                 string palletCode = stockInfo.PalletCode;
 
                 // 5. 寮傛鎵цMES璋冪敤锛坒ire-and-forget锛�
-                _ = Task.Run(async () =>
-                {
-                    var localStopwatch = Stopwatch.StartNew();
-                    try
+                _mesUploadHelper.FireAndForget(
+                    palletCode,
+                    MesUploadStatusEnum.杩涚珯涓婁紶鎴愬姛,
+                    "InboundInContainer",
+                    requestJson,
+                    () =>
                     {
                         var result = string.IsNullOrWhiteSpace(token)
                             ? _mesService.InboundInContainer(mesRequest)
                             : _mesService.InboundInContainer(mesRequest, token);
-                        localStopwatch.Stop();
-
-                        bool isSuccess = result?.IsSuccess ?? false;
-                        int status = isSuccess
-                            ? (int)MesUploadStatusEnum.杩涚珯涓婁紶鎴愬姛
-                            : (int)MesUploadStatusEnum.杩涚珯涓婁紶澶辫触;
-
-                        await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, status);
-
-                        await _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = palletCode,
-                            ApiType = "InboundInContainer",
-                            RequestJson = requestJson,
-                            ResponseJson = System.Text.Json.JsonSerializer.Serialize(result),
-                            IsSuccess = isSuccess,
-                            ErrorMessage = result?.ErrorMessage ?? "鏈煡閿欒",
-                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                            Creator = App.User.UserName
-                        });
-                    }
-                    catch (Exception ex)
-                    {
-                        localStopwatch.Stop();
-                        await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, (int)MesUploadStatusEnum.杩涚珯涓婁紶澶辫触);
-                        await _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = palletCode,
-                            ApiType = "InboundInContainer",
-                            IsSuccess = false,
-                            ErrorMessage = ex.Message,
-                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                            Creator = App.User.UserName
-                        });
-                    }
-                });
+                        return (
+                            result?.IsSuccess ?? false,
+                            System.Text.Json.JsonSerializer.Serialize(result),
+                            result?.ErrorMessage ?? "鏈煡閿欒"
+                        );
+                    },
+                    App.User.UserName);
 
                 // 6. 绔嬪嵆杩斿洖鎴愬姛
                 return response.OK("鎵樼洏杩涚珯鎴愬姛");
@@ -223,50 +192,23 @@
                 string palletCode = stockInfo.PalletCode;
 
                 // 5. 寮傛鎵цMES璋冪敤锛坒ire-and-forget锛�
-                _ = Task.Run(async () =>
-                {
-                    var localStopwatch = Stopwatch.StartNew();
-                    try
+                _mesUploadHelper.FireAndForget(
+                    palletCode,
+                    MesUploadStatusEnum.鍑虹珯涓婁紶鎴愬姛,
+                    "OutboundInContainer",
+                    requestJson,
+                    () =>
                     {
                         var result = string.IsNullOrWhiteSpace(token)
                             ? _mesService.OutboundInContainer(mesRequest)
                             : _mesService.OutboundInContainer(mesRequest, token);
-                        localStopwatch.Stop();
-
-                        bool isSuccess = result?.IsSuccess ?? false;
-                        int status = isSuccess
-                            ? (int)MesUploadStatusEnum.鍑虹珯涓婁紶鎴愬姛
-                            : (int)MesUploadStatusEnum.鍑虹珯涓婁紶澶辫触;
-
-                        await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, status);
-
-                        await _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = palletCode,
-                            ApiType = "OutboundInContainer",
-                            RequestJson = requestJson,
-                            ResponseJson = System.Text.Json.JsonSerializer.Serialize(result),
-                            IsSuccess = isSuccess,
-                            ErrorMessage = result?.ErrorMessage ?? "鏈煡閿欒",
-                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                            Creator = App.User.UserName
-                        });
-                    }
-                    catch (Exception ex)
-                    {
-                        localStopwatch.Stop();
-                        await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, (int)MesUploadStatusEnum.鍑虹珯涓婁紶澶辫触);
-                        await _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = palletCode,
-                            ApiType = "OutboundInContainer",
-                            IsSuccess = false,
-                            ErrorMessage = ex.Message,
-                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                            Creator = App.User.UserName
-                        });
-                    }
-                });
+                        return (
+                            result?.IsSuccess ?? false,
+                            System.Text.Json.JsonSerializer.Serialize(result),
+                            result?.ErrorMessage ?? "鏈煡閿欒"
+                        );
+                    },
+                    App.User.UserName);
 
                 // 6. 绔嬪嵆杩斿洖鎴愬姛
                 return response.OK("鎵樼洏鍑虹珯鎴愬姛");
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs
index 3680ce8..1b3f335 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs
@@ -9,7 +9,6 @@
 using WIDESEA_Model.Models;
 using WIDESEA_Common.Constants;
 using WIDESEA_Common.StockEnum;
-using System.Diagnostics;
 
 namespace WIDESEA_WMSServer.Controllers.Stock
 {
@@ -20,25 +19,25 @@
     [ApiController]
     public class StockInfoDetailController : ApiBaseController<IStockInfoDetailService, Dt_StockInfoDetail>
     {
-        private readonly IMesLogService _mesLogService;
         private readonly IMesService _mesService;
         private readonly ISys_DictionaryService _sysDictionaryService;
         private readonly IStockInfoService _stockInfoService;
         private readonly IMESDeviceConfigService _mesDeviceConfigService;
+        private readonly IMesUploadHelper _mesUploadHelper;
 
         public StockInfoDetailController(
             IStockInfoDetailService service,
-            IMesLogService mesLogService,
             IMesService mesService,
             ISys_DictionaryService sysDictionaryService,
             IStockInfoService stockInfoService,
-            IMESDeviceConfigService mesDeviceConfigService) : base(service)
+            IMESDeviceConfigService mesDeviceConfigService,
+            IMesUploadHelper mesUploadHelper) : base(service)
         {
-            _mesLogService = mesLogService;
             _mesService = mesService;
             _sysDictionaryService = sysDictionaryService;
             _stockInfoService = stockInfoService;
             _mesDeviceConfigService = mesDeviceConfigService;
+            _mesUploadHelper = mesUploadHelper;
         }
 
         /// <summary>
@@ -91,51 +90,23 @@
                 string requestJson = System.Text.Json.JsonSerializer.Serialize(mesRequest);
 
                 // 5. 寮傛璋冪敤MES鎺ュ彛锛坒ire-and-forget锛�
-                var localToken = token;
-                _ = Task.Run(async () =>
-                {
-                    var localStopwatch = Stopwatch.StartNew();
-                    try
+                _mesUploadHelper.FireAndForget(
+                    stockInfo.PalletCode,
+                    MesUploadStatusEnum.缁勭洏涓婁紶鎴愬姛,
+                    "BindContainer",
+                    requestJson,
+                    () =>
                     {
-                        var result = string.IsNullOrWhiteSpace(localToken)
+                        var result = string.IsNullOrWhiteSpace(token)
                             ? _mesService.BindContainer(mesRequest)
-                            : _mesService.BindContainer(mesRequest, localToken);
-                        localStopwatch.Stop();
-
-                        bool isSuccess = result?.IsSuccess ?? false;
-                        int status = isSuccess
-                            ? (int)MesUploadStatusEnum.缁勭洏涓婁紶鎴愬姛
-                            : (int)MesUploadStatusEnum.缁勭洏涓婁紶澶辫触;
-
-                        await _stockInfoService.UpdateMesUploadStatusAsync(stockInfo.PalletCode, status);
-
-                        await _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = stockInfo.PalletCode,
-                            ApiType = "BindContainer",
-                            RequestJson = requestJson,
-                            ResponseJson = System.Text.Json.JsonSerializer.Serialize(result),
-                            IsSuccess = isSuccess,
-                            ErrorMessage = result?.ErrorMessage ?? "鏈煡閿欒",
-                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                            Creator = App.User.UserName
-                        });
-                    }
-                    catch (Exception ex)
-                    {
-                        localStopwatch.Stop();
-                        await _stockInfoService.UpdateMesUploadStatusAsync(stockInfo.PalletCode, (int)MesUploadStatusEnum.缁勭洏涓婁紶澶辫触);
-                        await _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = stockInfo.PalletCode,
-                            ApiType = "BindContainer",
-                            IsSuccess = false,
-                            ErrorMessage = ex.Message,
-                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                            Creator = App.User.UserName
-                        });
-                    }
-                });
+                            : _mesService.BindContainer(mesRequest, token);
+                        return (
+                            result?.IsSuccess ?? false,
+                            System.Text.Json.JsonSerializer.Serialize(result),
+                            result?.ErrorMessage ?? "鏈煡閿欒"
+                        );
+                    },
+                    App.User.UserName);
 
                 // 6. 绔嬪嵆杩斿洖鎴愬姛鍝嶅簲
                 return response.OK("鎵樼洏鐢佃姱缁戝畾鎴愬姛");
@@ -191,51 +162,23 @@
                 string requestJson = System.Text.Json.JsonSerializer.Serialize(mesRequest);
 
                 // 5. 寮傛璋冪敤MES鎺ュ彛锛坒ire-and-forget锛�
-                var localToken = token;
-                _ = Task.Run(async () =>
-                {
-                    var localStopwatch = Stopwatch.StartNew();
-                    try
+                _mesUploadHelper.FireAndForget(
+                    stockInfo.PalletCode,
+                    MesUploadStatusEnum.鎷嗙洏涓婁紶鎴愬姛,
+                    "UnbindContainer",
+                    requestJson,
+                    () =>
                     {
-                        var result = string.IsNullOrWhiteSpace(localToken)
+                        var result = string.IsNullOrWhiteSpace(token)
                             ? _mesService.UnBindContainer(mesRequest)
-                            : _mesService.UnBindContainer(mesRequest, localToken);
-                        localStopwatch.Stop();
-
-                        bool isSuccess = result?.IsSuccess ?? false;
-                        int status = isSuccess
-                            ? (int)MesUploadStatusEnum.鎷嗙洏涓婁紶鎴愬姛
-                            : (int)MesUploadStatusEnum.鎷嗙洏涓婁紶澶辫触;
-
-                        await _stockInfoService.UpdateMesUploadStatusAsync(stockInfo.PalletCode, status);
-
-                        await _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = stockInfo.PalletCode,
-                            ApiType = "UnbindContainer",
-                            RequestJson = requestJson,
-                            ResponseJson = System.Text.Json.JsonSerializer.Serialize(result),
-                            IsSuccess = isSuccess,
-                            ErrorMessage = result?.ErrorMessage ?? "鏈煡閿欒",
-                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                            Creator = App.User.UserName
-                        });
-                    }
-                    catch (Exception ex)
-                    {
-                        localStopwatch.Stop();
-                        await _stockInfoService.UpdateMesUploadStatusAsync(stockInfo.PalletCode, (int)MesUploadStatusEnum.鎷嗙洏涓婁紶澶辫触);
-                        await _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = stockInfo.PalletCode,
-                            ApiType = "UnbindContainer",
-                            IsSuccess = false,
-                            ErrorMessage = ex.Message,
-                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                            Creator = App.User.UserName
-                        });
-                    }
-                });
+                            : _mesService.UnBindContainer(mesRequest, token);
+                        return (
+                            result?.IsSuccess ?? false,
+                            System.Text.Json.JsonSerializer.Serialize(result),
+                            result?.ErrorMessage ?? "鏈煡閿欒"
+                        );
+                    },
+                    App.User.UserName);
 
                 // 6. 绔嬪嵆杩斿洖鎴愬姛鍝嶅簲
                 return response.OK("鎵樼洏鐢佃姱瑙g粦鎴愬姛");
@@ -302,48 +245,21 @@
                 string requestJson = System.Text.Json.JsonSerializer.Serialize(mesRequest);
 
                 // 5. 寮傛璋冪敤MES鎺ュ彛锛坒ire-and-forget锛�
-                _ = Task.Run(async () =>
-                {
-                    var localStopwatch = Stopwatch.StartNew();
-                    try
+                _mesUploadHelper.FireAndForget(
+                    stockInfo.PalletCode,
+                    MesUploadStatusEnum.NG涓婃姤鎴愬姛,
+                    "ContainerNgReport",
+                    requestJson,
+                    () =>
                     {
                         var result = _mesService.ContainerNgReport(mesRequest);
-                        localStopwatch.Stop();
-
-                        bool isSuccess = result?.IsSuccess ?? false;
-                        int status = isSuccess
-                            ? (int)MesUploadStatusEnum.NG涓婃姤鎴愬姛
-                            : (int)MesUploadStatusEnum.NG涓婃姤澶辫触;
-
-                        await _stockInfoService.UpdateMesUploadStatusAsync(stockInfo.PalletCode, status);
-
-                        await _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = stockInfo.PalletCode,
-                            ApiType = "ContainerNgReport",
-                            RequestJson = requestJson,
-                            ResponseJson = System.Text.Json.JsonSerializer.Serialize(result),
-                            IsSuccess = isSuccess,
-                            ErrorMessage = result?.ErrorMessage ?? "鏈煡閿欒",
-                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                            Creator = App.User.UserName
-                        });
-                    }
-                    catch (Exception ex)
-                    {
-                        localStopwatch.Stop();
-                        await _stockInfoService.UpdateMesUploadStatusAsync(stockInfo.PalletCode, (int)MesUploadStatusEnum.NG涓婃姤澶辫触);
-                        await _mesLogService.LogAsync(new MesApiLogDto
-                        {
-                            PalletCode = stockInfo.PalletCode,
-                            ApiType = "ContainerNgReport",
-                            IsSuccess = false,
-                            ErrorMessage = ex.Message,
-                            ElapsedMs = (int)localStopwatch.ElapsedMilliseconds,
-                            Creator = App.User.UserName
-                        });
-                    }
-                });
+                        return (
+                            result?.IsSuccess ?? false,
+                            System.Text.Json.JsonSerializer.Serialize(result),
+                            result?.ErrorMessage ?? "鏈煡閿欒"
+                        );
+                    },
+                    App.User.UserName);
 
                 // 6. 绔嬪嵆杩斿洖鎴愬姛鍝嶅簲
                 return response.OK("NG鐢佃姱涓婃姤鎴愬姛");

--
Gitblit v1.9.3