From 05999b9c77f009ac9a7e98366bc3d23fbb8e83e7 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期日, 26 四月 2026 17:46:10 +0800
Subject: [PATCH] feat: 更新数据库连接配置和机器人任务处理逻辑

---
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs | 1475 ++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 805 insertions(+), 670 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
index c50f942..97fa4ac 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
@@ -1,670 +1,805 @@
-using Microsoft.Extensions.Logging;
-using Newtonsoft.Json;
-using WIDESEA_Core;
-using WIDESEAWCS_Common;
-using WIDESEAWCS_Common.HttpEnum;
-using WIDESEAWCS_Common.TaskEnum;
-using WIDESEAWCS_Core;
-using WIDESEAWCS_Core.Helper;
-using WIDESEAWCS_Core.LogHelper;
-using WIDESEAWCS_DTO.Stock;
-using WIDESEAWCS_DTO.TaskInfo;
-using WIDESEAWCS_ITaskInfoService;
-using WIDESEAWCS_Model.Models;
-using WIDESEAWCS_QuartzJob;
-using WIDESEAWCS_Tasks.Workflow.Abstractions;
-
-namespace WIDESEAWCS_Tasks
-{
-    /// <summary>
-    /// 鏈哄櫒浜轰换鍔″鐞嗗櫒 - 璐熻矗浠诲姟鑾峰彇銆佷笅鍙戙�佸叆搴撲换鍔″洖浼犲強搴撳瓨 DTO 鏋勫缓
-    /// </summary>
-    /// <remarks>
-    /// 鏍稿績鑱岃矗锛�
-    /// 1. 浠庢暟鎹簱杞寰呭鐞嗙殑鏈哄櫒浜轰换鍔�
-    /// 2. 鍚戞満鍣ㄤ汉瀹㈡埛绔笅鍙戝彇璐ф寚浠わ紙Pickbattery锛�
-    /// 3. 澶勭悊鍏ュ簱浠诲姟鐨勫洖浼狅紙鎷嗙洏/缁勭洏/鎹㈢洏鍦烘櫙锛�
-    /// 4. 鏋勫缓搴撳瓨鍥炰紶 DTO 骞惰皟鐢� WMS 鎺ュ彛
-    ///
-    /// 閫氳繃缃戝叧璁块棶 Socket锛岄伩鍏嶄笟鍔″眰鐩存帴渚濊禆 TcpSocketServer銆�
-    /// </remarks>
-    public class RobotTaskProcessor
-    {
-        /// <summary>
-        /// Socket 瀹㈡埛绔綉鍏虫帴鍙�
-        /// </summary>
-        /// <remarks>
-        /// 閫氳繃缃戝叧璁块棶 Socket锛岄伩鍏嶄笟鍔″眰鐩存帴渚濊禆 TcpSocketServer銆�
-        /// 鎻愪緵缁熶竴鐨勫鎴风閫氫俊鎺ュ彛銆�
-        /// </remarks>
-        private readonly ISocketClientGateway _socketClientGateway;
-
-        /// <summary>
-        /// 鏈烘鎵嬬姸鎬佺鐞嗗櫒
-        /// </summary>
-        private readonly RobotStateManager _stateManager;
-
-        /// <summary>
-        /// 鏈哄櫒浜轰换鍔℃湇鍔�
-        /// </summary>
-        /// <remarks>
-        /// 鐢ㄤ簬鏌ヨ銆佹洿鏂般�佸垹闄ゆ満鍣ㄤ汉浠诲姟璁板綍銆�
-        /// </remarks>
-        private readonly IRobotTaskService _robotTaskService;
-
-        /// <summary>
-        /// 閫氱敤浠诲姟鏈嶅姟
-        /// </summary>
-        /// <remarks>
-        /// 鐢ㄤ簬涓� WMS 绯荤粺浜や簰锛屾帴鏀朵换鍔°�佸鐞嗕换鍔$姸鎬佺瓑銆�
-        /// </remarks>
-        private readonly ITaskService _taskService;
-
-        /// <summary>
-        /// HTTP 瀹㈡埛绔府鍔╃被
-        /// </summary>
-        /// <remarks>
-        /// 鐢ㄤ簬璋冪敤 WMS 绯荤粺鐨� HTTP 鎺ュ彛銆�
-        /// </remarks>
-        private readonly HttpClientHelper _httpClientHelper;
-
-        /// <summary>
-        /// 鍋囩數鑺钩闈㈢偣浣嶆湇鍔�
-        /// </summary>
-        /// <remarks>
-        /// 鐢ㄤ簬绠$悊鍋囩數鑺钩闈㈢偣浣嶇殑鍒嗛厤鍜岀姸鎬併��
-        /// </remarks>
-        private readonly IFakeBatteryPositionService _fakeBatteryPositionService;
-
-        /// <summary>
-        /// 鏃ュ織璁板綍鍣�
-        /// </summary>
-        private readonly ILogger _logger;
-
-        /// <summary>
-        /// 鏋勯�犲嚱鏁�
-        /// </summary>
-        /// <param name="socketClientGateway">Socket 缃戝叧</param>
-        /// <param name="stateManager">鐘舵�佺鐞嗗櫒</param>
-        /// <param name="robotTaskService">鏈哄櫒浜轰换鍔℃湇鍔�</param>
-        /// <param name="taskService">閫氱敤浠诲姟鏈嶅姟</param>
-        /// <param name="httpClientHelper">HTTP 瀹㈡埛绔府鍔╃被</param>
-        /// <param name="logger">鏃ュ織璁板綍鍣�</param>
-        public RobotTaskProcessor(
-            ISocketClientGateway socketClientGateway,
-            RobotStateManager stateManager,
-            IRobotTaskService robotTaskService,
-            ITaskService taskService,
-            HttpClientHelper httpClientHelper,
-            ILogger logger,
-            IFakeBatteryPositionService fakeBatteryPositionService)
-        {
-            _socketClientGateway = socketClientGateway;
-            _stateManager = stateManager;
-            _robotTaskService = robotTaskService;
-            _taskService = taskService;
-            _httpClientHelper = httpClientHelper;
-            _logger = logger;
-            _fakeBatteryPositionService = fakeBatteryPositionService;
-        }
-
-        /// <summary>
-        /// 鎸夎澶囩紪鐮佽幏鍙栧綋鍓嶆満鍣ㄤ汉鐨勫緟澶勭悊浠诲姟
-        /// </summary>
-        /// <remarks>
-        /// 浠庢暟鎹簱涓煡璇㈡寚瀹氳澶囩紪鐮佺殑寰呭鐞嗘満鍣ㄤ汉浠诲姟銆�
-        /// 鍙繑鍥炵姸鎬佷负"寰呭鐞�"鐨勪换鍔°��
-        /// </remarks>
-        /// <param name="robotCrane">鏈哄櫒浜鸿澶囦俊鎭紝鍖呭惈璁惧缂栫爜</param>
-        /// <returns>寰呭鐞嗙殑浠诲姟瀵硅薄锛屽鏋滄病鏈夊垯杩斿洖 null</returns>
-        public Dt_RobotTask? GetTask(RobotCraneDevice robotCrane)
-        {
-            return _robotTaskService.QueryRobotCraneTask(robotCrane.DeviceCode);
-        }
-
-        /// <summary>
-        /// 鎸夎澶囩紪鐮佽幏鍙栧綋鍓嶆満鍣ㄤ汉鐨勬墽琛屼腑浠诲姟
-        /// </summary>
-        /// <remarks>
-        /// 浠庢暟鎹簱涓煡璇㈡寚瀹氳澶囩紪鐮佺殑鎵ц涓満鍣ㄤ汉浠诲姟銆�
-        /// 褰揜obotArmObject涓�1锛堟湁鐗╂枡锛変笖娌℃湁寰呭鐞嗕换鍔℃椂璋冪敤銆�
-        /// </remarks>
-        /// <param name="robotCrane">鏈哄櫒浜鸿澶囦俊鎭紝鍖呭惈璁惧缂栫爜</param>
-        /// <returns>鎵ц涓殑浠诲姟瀵硅薄锛屽鏋滄病鏈夊垯杩斿洖 null</returns>
-        public Dt_RobotTask? GetExecutingTask(RobotCraneDevice robotCrane)
-        {
-            return _robotTaskService.QueryRobotCraneExecutingTask(robotCrane.DeviceCode);
-        }
-
-        /// <summary>
-        /// 鍒犻櫎鏈哄櫒浜轰换鍔�
-        /// </summary>
-        /// <remarks>
-        /// 褰撲换鍔″畬鎴愶紙鏃犺鏄垚鍔熻繕鏄け璐ワ級鏃惰皟鐢紝鍒犻櫎鏁版嵁搴撲腑鐨勪换鍔¤褰曘��
-        /// </remarks>
-        /// <param name="ID">瑕佸垹闄ょ殑浠诲姟 ID</param>
-        /// <returns>鍒犻櫎鏄惁鎴愬姛</returns>
-        public bool? DeleteTask(int ID)
-        {
-            return _robotTaskService.Repository.DeleteDataById(ID);
-        }
-
-        /// <summary>
-        /// 涓嬪彂鍙栬揣鎸囦护锛圥ickbattery锛夊埌鏈哄櫒浜哄鎴风
-        /// </summary>
-        /// <remarks>
-        /// 鍙戦�佹牸寮忥細Pickbattery,{婧愬湴鍧�}
-        /// 渚嬪锛歅ickbattery,A01 琛ㄧず浠� A01 浣嶇疆鍙栬揣
-        ///
-        /// 涓嬪彂鎴愬姛鍚庯細
-        /// 1. 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
-        /// 2. 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
-        /// 3. 瀹夊叏鏇存柊鐘舵�佸埌 Redis
-        /// 4. 鏇存柊浠诲姟璁板綍鍒版暟鎹簱
-        /// </remarks>
-        /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
-        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
-        /// <param name="isScanNG">鏄惁鎵爜NG</param>
-        public async Task SendSocketRobotPickAsync(Dt_RobotTask task, RobotSocketState state, bool isScanNG)
-        {
-            // 鏋勫缓鍙栬揣鎸囦护锛屾牸寮忥細Pickbattery,{婧愬湴鍧�}
-            string taskString = $"Pickbattery,{task.RobotSourceAddress}";
-
-            // 閫氳繃 Socket 缃戝叧鍙戦�佹寚浠ゅ埌鏈哄櫒浜哄鎴风
-            bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
-
-            if (result)
-            {
-                // 鍙戦�佹垚鍔燂紝璁板綍 Info 鏃ュ織
-                _logger.LogInformation("涓嬪彂鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {TaskString}锛岃澶�: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
-                QuartzLogger.Info($"涓嬪彂鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}", state.RobotCrane?.DeviceName);
-
-                // 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
-                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
-
-                // 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
-                state.CurrentTask = task;
-
-                if(isScanNG)
-                {
-                    state.IsScanNG = true;
-                }
-
-                // 淇濇寔鍘熻涔夛細浠呭湪鐘舵�佸畨鍏ㄥ啓鍏ユ垚鍔熷悗鍐嶆洿鏂颁换鍔$姸鎬�
-                // 杩欐牱鍙互纭繚鐘舵�佸拰浠诲姟璁板綍鐨勪竴鑷存��
-                if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
-                {
-                    await _robotTaskService.UpdateRobotTaskAsync(task);
-                }
-            }
-            else
-            {
-                // 鍙戦�佸け璐ワ紝璁板綍 Error 鏃ュ織
-                _logger.LogError("涓嬪彂鍙栬揣鎸囦护澶辫触锛屾寚浠�: {TaskString}锛岃澶�: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
-                QuartzLogger.Error($"涓嬪彂鍙栬揣鎸囦护澶辫触锛屾寚浠�: {taskString}", state.RobotCrane?.DeviceName);
-            }
-        }
-
-        /// <summary>
-        /// 涓嬪彂鍋囩數鑺彇璐ф寚浠ゅ埌鏈哄櫒浜哄鎴风
-        /// </summary>
-        /// <remarks>
-        /// 鍙戦�佹牸寮忥細Pickbattery,5,{startPosition}-{endPosition}
-        /// 渚嬪锛歅ickbattery,5,1-3 琛ㄧず浠庡亣鐢佃姱浣嶇疆5鎶撳彇锛屽钩闈㈢偣浣�1鍒�3
-        ///
-        /// 涓嬪彂鎴愬姛鍚庯細
-        /// 1. 鏍囪鐐逛綅涓哄凡浣跨敤
-        /// 2. 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
-        /// 3. 瀹夊叏鏇存柊鐘舵�佸埌 Redis
-        /// </remarks>
-        /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
-        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
-        /// <param name="positions">瑕佹姄鍙栫殑骞抽潰鐐逛綅鍒楄〃</param>
-        public async Task SendSocketRobotFakeBatteryPickAsync(Dt_RobotTask task, RobotSocketState state, List<int> positions)
-        {
-            if (positions == null || positions.Count == 0)
-            {
-                _logger.LogWarning("SendSocketRobotFakeBatteryPickAsync锛氬钩闈㈢偣浣嶅垪琛ㄤ负绌猴紝浠诲姟鍙�: {TaskNum}", task.RobotTaskNum);
-                return;
-            }
-
-            // 璁$畻鐐逛綅鑼冨洿锛屾牸寮忥細1-3
-            int startPos = positions.Min();
-            int endPos = positions.Max();
-            string taskString = $"Pickbattery,5,{startPos}-{endPos}";
-
-            // 鏍囪鐐逛綅涓哄凡浣跨敤
-            _fakeBatteryPositionService.MarkAsUsed(positions);
-
-            // 閫氳繃 Socket 缃戝叧鍙戦�佹寚浠ゅ埌鏈哄櫒浜哄鎴风
-            bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
-
-            if (result)
-            {
-                _logger.LogInformation("涓嬪彂鍋囩數鑺彇璐ф寚浠ゆ垚鍔燂紝鎸囦护: {TaskString}锛岀偣浣�: {Positions}锛岃澶�: {DeviceName}",
-                    taskString, string.Join(",", positions), state.RobotCrane?.DeviceName);
-                QuartzLogger.Info($"涓嬪彂鍋囩數鑺彇璐ф寚浠ゆ垚鍔燂紝鎸囦护: {taskString}", state.RobotCrane?.DeviceName);
-
-                // 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
-                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
-
-                // 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
-                state.CurrentTask = task;
-
-                if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
-                {
-                    await _robotTaskService.UpdateRobotTaskAsync(task);
-                }
-            }
-            else
-            {
-                _logger.LogError("涓嬪彂鍋囩數鑺彇璐ф寚浠ゅけ璐ワ紝鎸囦护: {TaskString}锛岃澶�: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
-                QuartzLogger.Error($"涓嬪彂鍋囩數鑺彇璐ф寚浠ゅけ璐ワ紝鎸囦护: {taskString}", state.RobotCrane?.DeviceName);
-            }
-        }
-
-        /// <summary>
-        /// 鑾峰彇涓婲涓彲鐢ㄧ殑鍋囩數鑺钩闈㈢偣浣�
-        /// </summary>
-        /// <param name="count">闇�瑕佽幏鍙栫殑鐐逛綅鏁伴噺</param>
-        /// <returns>鍙敤鐐逛綅鍒楄〃</returns>
-        public List<int> GetNextAvailableFakeBatteryPositions(int count)
-        {
-            return _fakeBatteryPositionService.GetNextAvailable(count);
-        }
-
-        /// <summary>
-        /// 璁$畻鎵规缂栧彿鑼冨洿
-        /// </summary>
-        /// <remarks>
-        /// 杩斿洖鏍煎紡锛�(start, end)
-        /// - remaining >= 4: (currentIndex, currentIndex + 3)
-        /// - remaining > 1: (currentIndex, currentIndex + remaining - 1)
-        /// - remaining == 1: (currentIndex, 0)  -- 鍗曚釜鐗╁搧鐢� 0 琛ㄧず end
-        /// </remarks>
-        /// <param name="currentIndex">褰撳墠鎵规璧峰缂栧彿</param>
-        /// <param name="remaining">鍓╀綑鏁伴噺</param>
-        /// <returns>(start, end) 鍏冪粍</returns>
-        public (int Start, int End) BuildBatchRange(int currentIndex, int remaining)
-        {
-            if (remaining >= 4)
-                return (currentIndex, currentIndex + 3);
-            else if (remaining > 1)
-                return (currentIndex, currentIndex + remaining - 1);
-            else  // remaining == 1
-                return (currentIndex, 0);
-        }
-
-        /// <summary>
-        /// 涓嬪彂鍙栬揣鎸囦护锛堝甫鎵规鏍煎紡鍜屾�绘暟锛�
-        /// </summary>
-        /// <remarks>
-        /// 鍙戦�侀『搴忥細
-        /// 1. PickTotalNum,{N} -- 鐪熷疄鐢佃姱鎬绘暟
-        /// 2. Pickbattery,{浣嶇疆},{start}-{end} -- 鎵规鍙栬揣鎸囦护
-        ///
-        /// 涓嬪彂鎴愬姛鍚庢洿鏂颁换鍔$姸鎬佷负"鏈哄櫒浜烘墽琛屼腑"銆�
-        /// </remarks>
-        /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
-        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
-        /// <param name="position">鍙栬揣浣嶇疆</param>
-        /// <param name="batchStart">鎵规璧峰缂栧彿</param>
-        /// <param name="batchEnd">鎵规缁撴潫缂栧彿</param>
-        public async Task SendPickWithBatchAsync(Dt_RobotTask task, RobotSocketState state, string position, int batchStart, int batchEnd)
-        {
-            // 鍏堝彂閫佹�绘暟鎸囦护
-            string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}";
-            await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
-
-            // 鍐嶅彂閫佹壒娆″彇璐ф寚浠�
-            string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
-            string taskString = $"Pickbattery,{position},{range}";
-
-            bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
-
-            if (result)
-            {
-                _logger.LogInformation("涓嬪彂鎵规鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {TaskString}锛屾壒娆�: {Range}锛岃澶�: {DeviceName}",
-                    taskString, range, state.RobotCrane?.DeviceName);
-                QuartzLogger.Info($"涓嬪彂鎵规鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛屾壒娆�: {range}", state.RobotCrane?.DeviceName);
-
-                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
-                state.CurrentTask = task;
-
-                if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
-                {
-                    await _robotTaskService.UpdateRobotTaskAsync(task);
-                }
-            }
-            else
-            {
-                _logger.LogError("涓嬪彂鎵规鍙栬揣鎸囦护澶辫触锛屾寚浠�: {TaskString}锛岃澶�: {DeviceName}", taskString, state.RobotCrane?.DeviceName);
-                QuartzLogger.Error($"涓嬪彂鎵规鍙栬揣鎸囦护澶辫触锛屾寚浠�: {taskString}", state.RobotCrane?.DeviceName);
-            }
-        }
-
-        /// <summary>
-        /// 涓嬪彂鏀捐揣鎸囦护锛堝甫鎵规鏍煎紡鍜屾�绘暟锛�
-        /// </summary>
-        /// <remarks>
-        /// 鍙戦�侀『搴忥細
-        /// 1. PutTotalNum,{N} -- 鐪熷疄鐢佃姱鎬绘暟
-        /// 2. Putbattery,{浣嶇疆},{start}-{end} -- 鎵规鏀捐揣鎸囦护
-        ///
-        /// 涓嬪彂鎴愬姛鍚庢洿鏂颁换鍔$姸鎬佷负"鏈哄櫒浜烘墽琛屼腑"銆�
-        /// </remarks>
-        /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
-        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
-        /// <param name="position">鏀捐揣浣嶇疆</param>
-        /// <param name="batchStart">鎵规璧峰缂栧彿</param>
-        /// <param name="batchEnd">鎵规缁撴潫缂栧彿</param>
-        public async Task SendPutWithBatchAsync(Dt_RobotTask task, RobotSocketState state, string position, int batchStart, int batchEnd)
-        {
-            // 鍏堝彂閫佹�绘暟鎸囦护
-            string totalNumCmd = $"PutTotalNum,{task.RobotTaskTotalNum}";
-            await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
-
-            // 鍐嶅彂閫佹壒娆℃斁璐ф寚浠�
-            string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
-            string taskString = $"Putbattery,{position},{range}";
-
-            bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
-
-            if (result)
-            {
-                _logger.LogInformation("涓嬪彂鏀捐揣鎸囦护鎴愬姛锛屾寚浠�: {TaskString}锛屾壒娆�: {Range}锛岃澶�: {DeviceName}",
-                    taskString, range, state.RobotCrane?.DeviceName);
-                QuartzLogger.Info($"涓嬪彂鏀捐揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛屾壒娆�: {range}", state.RobotCrane?.DeviceName);
-
-                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
-                state.CurrentTask = task;
-
-                if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
-                {
-                    await _robotTaskService.UpdateRobotTaskAsync(task);
-                }
-            }
-            else
-            {
-                _logger.LogError("涓嬪彂鏀捐揣鎸囦护澶辫触锛屾寚浠�: {TaskString}锛岃澶�: {DeviceName}",
-                    taskString, state.RobotCrane?.DeviceName);
-                QuartzLogger.Error($"涓嬪彂鏀捐揣鎸囦护澶辫触锛屾寚浠�: {taskString}", state.RobotCrane?.DeviceName);
-            }
-        }
-
-        /// <summary>
-        /// 澶勭悊鍏ュ簱浠诲姟鍥炰紶锛堟媶鐩�/缁勭洏/鎹㈢洏鍦烘櫙锛�
-        /// </summary>
-        /// <remarks>
-        /// 褰撳彇璐у畬鎴愶紙AllPickFinished锛夋垨鏀捐揣瀹屾垚锛圓llPutFinished锛夋椂璋冪敤姝ゆ柟娉曘��
-        /// 鏍规嵁浠诲姟绫诲瀷鍜屽湴鍧�鏉ユ簮鍐冲畾濡備綍鍥炰紶缁� WMS銆�
-        ///
-        /// 澶勭悊閫昏緫锛�
-        /// 1. 鏍规嵁 useSourceAddress 鍐冲畾浣跨敤婧愬湴鍧�杩樻槸鐩爣鍦板潃
-        /// 2. 鏍规嵁浠诲姟绫诲瀷锛堢粍鐩�/鎹㈢洏/鎷嗙洏锛夊喅瀹氫换鍔$被鍨嬶紙鍏ュ簱/绌烘墭鐩樺叆搴擄級
-        /// 3. 鏋勫缓 CreateTaskDto 骞惰皟鐢� WMS 鎺ュ彛鍒涘缓浠诲姟
-        /// 4. 鎺ユ敹 WMS 杩斿洖鐨勪换鍔′俊鎭�
-        /// 5. 鏇存柊杈撻�佺嚎鐨勭洰鏍囧湴鍧�銆佷换鍔″彿绛�
-        /// </remarks>
-        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
-        /// <param name="useSourceAddress">鏄惁浣跨敤婧愬湴鍧�锛坱rue 琛ㄧず鎷嗙洏/鎹㈢洏鍦烘櫙锛宖alse 琛ㄧず缁勭洏/鎹㈢洏鍦烘櫙锛�</param>
-        /// <returns>澶勭悊鏄惁鎴愬姛</returns>
-        public async Task<bool> HandleInboundTaskAsync(RobotSocketState state, bool useSourceAddress)
-        {
-            // 鑾峰彇褰撳墠鍏宠仈鐨勪换鍔�
-            var currentTask = state.CurrentTask;
-            if (currentTask == null)
-            {
-                _logger.LogDebug("HandleInboundTaskAsync锛氬綋鍓嶄换鍔′负绌�");
-                QuartzLogger.Debug($"HandleInboundTaskAsync锛氬綋鍓嶄换鍔′负绌�", state.RobotCrane?.DeviceName ?? "Unknown");
-                return false;
-            }
-
-            // 鑾峰彇宸烽亾浠g爜
-            string roadway = currentTask.RobotSourceAddressLineCode;
-
-            // 鏍规嵁宸烽亾鍚嶇О鍒ゆ柇浠撳簱 ID
-            // ZYRB1 -> 1, HPRB001 -> 2, 鍏朵粬 -> 3
-            int warehouseId = currentTask.RobotRoadway == "娉ㄦ恫缁勭洏鏈烘鎵�" ? 1 : currentTask.RobotRoadway == "HPRB001" ? 2 : 3;
-
-            // 浠诲姟绫诲瀷锛�0 琛ㄧず鏈畾涔夛紝绋嶅悗鏍规嵁浠诲姟绫诲瀷璁剧疆锛�
-            int taskType = 0;
-
-            // 婧愬湴鍧�鍜岀洰鏍囧湴鍧�锛堝垵濮嬪寲锛�
-            string SourceAddress = currentTask.RobotTargetAddressLineCode;
-            string TargetAddress = currentTask.RobotSourceAddressLineCode;
-
-            // 鎵樼洏浠g爜锛堝垵濮嬪寲涓虹┖锛�
-            string PalletCode = string.Empty;
-
-            // 鑾峰彇浠诲姟绫诲瀷鐨勬灇涓惧��
-            var robotTaskType = (RobotTaskTypeEnum)currentTask.RobotTaskType;
-
-            // 鏍规嵁 useSourceAddress 鍐冲畾澶勭悊閫昏緫
-            if (useSourceAddress)
-            {
-                // 浣跨敤婧愬湴鍧�鐨勫満鏅細鎷嗙洏銆佹崲鐩橈紙鏀剧┖鎵樼洏锛�
-                switch (robotTaskType)
-                {
-                    case RobotTaskTypeEnum.GroupPallet:
-                        // 缁勭洏浠诲姟涓嶄娇鐢ㄦ簮鍦板潃锛岀洿鎺ヨ繑鍥� false
-                        _logger.LogDebug("HandleInboundTaskAsync锛氱粍鐩樹换鍔′笉浣跨敤婧愬湴鍧�");
-                        QuartzLogger.Debug($"HandleInboundTaskAsync锛氱粍鐩樹换鍔′笉浣跨敤婧愬湴鍧�", state.RobotCrane?.DeviceName ?? "Unknown");
-                        return false;
-
-                    case RobotTaskTypeEnum.ChangePallet:
-                    case RobotTaskTypeEnum.SplitPallet:
-                        // 鎹㈢洏/鎷嗙洏鍦烘櫙锛氭墭鐩橀渶瑕佸叆搴�
-                        taskType = TaskTypeEnum.InEmpty.GetHashCode();  // 绌烘墭鐩樺叆搴�
-                        PalletCode = currentTask.RobotSourceAddressPalletCode;  // 浣跨敤婧愬湴鍧�鐨勬墭鐩樼爜
-                        break;
-                }
-            }
-            else
-            {
-                // 浣跨敤鐩爣鍦板潃鐨勫満鏅細缁勭洏銆佹崲鐩橈紙鎴愬搧鍏ュ簱锛�
-                switch (robotTaskType)
-                {
-                    case RobotTaskTypeEnum.ChangePallet:
-                    case RobotTaskTypeEnum.GroupPallet:
-                        // 鎹㈢洏/缁勭洏鍦烘櫙锛氳揣鐗╅渶瑕佸叆搴�
-                        taskType = TaskTypeEnum.Inbound.GetHashCode();  // 鎴愬搧鍏ュ簱
-                        PalletCode = currentTask.RobotTargetAddressPalletCode;  // 浣跨敤鐩爣鍦板潃鐨勬墭鐩樼爜
-                        break;
-
-                    case RobotTaskTypeEnum.SplitPallet:
-                        // 鎷嗙洏浠诲姟涓嶄娇鐢ㄧ洰鏍囧湴鍧�
-                        _logger.LogDebug("HandleInboundTaskAsync锛氭媶鐩樹换鍔′笉浣跨敤鐩爣鍦板潃");
-                        QuartzLogger.Debug($"HandleInboundTaskAsync锛氭媶鐩樹换鍔′笉浣跨敤鐩爣鍦板潃", state.RobotCrane?.DeviceName ?? "Unknown");
-                        return true;
-                }
-            }
-
-            // 鏋勫缓鍒涘缓浠诲姟鐨� DTO
-            CreateTaskDto taskDto = new CreateTaskDto
-            {
-                PalletCode = PalletCode,                    // 鎵樼洏鏉$爜
-                SourceAddress = SourceAddress ?? string.Empty,  // 婧愬湴鍧�
-                TargetAddress = TargetAddress ?? string.Empty,  // 鐩爣鍦板潃
-                Roadway = roadway,                          // 宸烽亾
-                WarehouseId = warehouseId,                   // 浠撳簱 ID
-                PalletType = 1,                             // 鎵樼洏绫诲瀷锛堥粯璁や负1锛�
-                TaskType = taskType                         // 浠诲姟绫诲瀷锛堝叆搴�/绌烘墭鐩樺叆搴擄級
-            };
-
-            // 璁板綍鏃ュ織锛氬紑濮嬭皟鐢� WMS 鍒涘缓鍏ュ簱浠诲姟
-            _logger.LogInformation("HandleInboundTaskAsync锛氳皟鐢╓MS鍒涘缓鍏ュ簱浠诲姟锛屾墭鐩樼爜: {PalletCode}锛屼换鍔$被鍨�: {TaskType}", PalletCode, taskType);
-            QuartzLogger.Info($"璋冪敤WMS鍒涘缓鍏ュ簱浠诲姟锛屾墭鐩樼爜: {PalletCode}锛屼换鍔$被鍨�: {taskType}", state.RobotCrane?.DeviceName ?? "Unknown");
-
-            // 璋冪敤 WMS 鎺ュ彛鍒涘缓鍏ュ簱浠诲姟
-            var result = _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.CreateTaskInboundAsync), taskDto.ToJson());
-
-            // 濡傛灉璋冪敤澶辫触鎴栬繑鍥為敊璇姸鎬�
-            if (!result.Data.Status && result.IsSuccess)
-            {
-                _logger.LogError("HandleInboundTaskAsync锛歐MS杩斿洖閿欒鐘舵�侊紝Status: {Status}", result.Data.Status);
-                QuartzLogger.Error($"HandleInboundTaskAsync锛歐MS杩斿洖閿欒鐘舵��", state.RobotCrane?.DeviceName ?? "Unknown");
-                return false;
-            }
-
-            // 瑙f瀽 WMS 杩斿洖鐨勪换鍔′俊鎭�
-            WMSTaskDTO taskDTO = JsonConvert.DeserializeObject<WMSTaskDTO>(result.Data.Data.ToJson() ?? string.Empty) ?? new WMSTaskDTO();
-
-            // 璋冪敤浠诲姟鏈嶅姟鎺ユ敹 WMS 浠诲姟
-            var content = _taskService.ReceiveWMSTask(new List<WMSTaskDTO> { taskDTO });
-            if (!content.Status)
-            {
-                _logger.LogError("HandleInboundTaskAsync锛氭帴鏀禬MS浠诲姟澶辫触");
-                QuartzLogger.Error($"HandleInboundTaskAsync锛氭帴鏀禬MS浠诲姟澶辫触", state.RobotCrane?.DeviceName ?? "Unknown");
-                return false;
-            }
-
-            // 瑙f瀽杩斿洖鐨勪换鍔′俊鎭�
-            //var taskInfos = JsonConvert.DeserializeObject<List<Dt_Task>>(content.Data.ToJson() ?? string.Empty) ?? new List<Dt_Task>();
-            //var taskInfo = taskInfos.FirstOrDefault();
-
-            //// 鑾峰彇婧愬湴鍧�
-            //string sourceAddress = taskDTO.SourceAddress;
-
-            //// 鏌ユ壘婧愬湴鍧�瀵瑰簲鐨勮緭閫佺嚎璁惧
-            //IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceProDTOs.Any(d => d.DeviceChildCode == sourceAddress));
-
-            //if (device != null)
-            //{
-            //    // 灏嗚澶囪浆鎹负杈撻�佺嚎绫诲瀷
-            //    CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
-
-            //    // 璁剧疆杈撻�佺嚎鐨勭洰鏍囧湴鍧�
-            //    conveyorLine.SetValue(ConveyorLineDBNameNew.Target, taskInfo.NextAddress, sourceAddress);
-
-            //    // 璁剧疆杈撻�佺嚎鐨勪换鍔″彿
-            //    conveyorLine.SetValue(ConveyorLineDBNameNew.TaskNo, taskInfo.TaskNum, sourceAddress);
-
-            //    // 瑙﹀彂杈撻�佺嚎寮�濮嬫墽琛岋紙鍐欏叆 WCS_ACK = 1锛�
-            //    conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, sourceAddress);
-
-            //    // 鏇存柊浠诲姟鐘舵�佸埌涓嬩竴闃舵
-            //    if (_taskService.UpdateTaskStatusToNext(taskInfo).Status)
-            //    {
-            //        _logger.LogInformation("HandleInboundTaskAsync锛氬叆搴撲换鍔″鐞嗘垚鍔燂紝浠诲姟鍙�: {TaskNum}", taskInfo.TaskNum);
-            //        QuartzLogger.Info($"HandleInboundTaskAsync锛氬叆搴撲换鍔″鐞嗘垚鍔燂紝浠诲姟鍙�: {taskInfo.TaskNum}", state.RobotCrane?.DeviceName ?? "Unknown");
-            //        return true;
-            //    }
-            //}
-
-            return false;
-        }
-
-        /// <summary>
-        /// 鏋勫缓搴撳瓨鍥炰紶 DTO
-        /// </summary>
-        /// <remarks>
-        /// 鐢ㄤ簬鎷嗙洏鍜岀粍鐩樻搷浣滄椂锛屽悜 WMS 鍥炰紶搴撳瓨淇℃伅銆�
-        /// DTO 鍖呭惈婧愯揣浣嶃�佺洰鏍囪揣浣嶃�佹墭鐩樼爜浠ュ強姣忎釜浣嶇疆鐨勭數姹犳潯鐮併��
-        /// </remarks>
-        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
-        /// <param name="positions">鐢垫睜浣嶇疆鏁扮粍</param>
-        /// <returns>鏋勫缓濂界殑搴撳瓨 DTO</returns>
-        public static StockDTO BuildStockDTO(RobotSocketState state, int[] positions)
-        {
-            return new StockDTO
-            {
-                // 婧愯緭閫佺嚎缂栧彿
-                SourceLineNo = state.CurrentTask.RobotSourceAddressLineCode,
-
-                // 婧愭墭鐩樺彿
-                SourcePalletNo = state.CurrentTask.RobotSourceAddressPalletCode,
-
-                // 鐩爣鎵樼洏鍙�
-                TargetPalletNo = state.CurrentTask.RobotTargetAddressPalletCode,
-
-                // 鐩爣杈撻�佺嚎缂栧彿
-                TargetLineNo = state.CurrentTask.RobotTargetAddressLineCode,
-
-                // 宸烽亾缂栧彿(鏈哄櫒浜哄悕绉�)
-                Roadway = state.CurrentTask.RobotRoadway,
-
-                // 鐢垫睜浣嶇疆璇︽儏鍒楄〃
-                // 杩囨护鎺変綅缃负 0 鎴栬礋鏁扮殑鏃犳晥鏁版嵁
-                // 鎸変綅缃紪鍙锋帓搴�
-                // 涓烘瘡涓綅缃敓鎴愬搴旂殑搴撳瓨璇︽儏
-                Details = positions
-                    .Where(x => x > 0)  // 杩囨护鏃犳晥浣嶇疆
-                    .OrderBy(x => x)   // 鎸変綅缃帓搴�
-                    .Select((x, idx) => new StockDetailDTO
-                    {
-                        // 鏁伴噺锛氬鏋滃凡鏈変换鍔℃�绘暟锛屼娇鐢ㄤ换鍔℃�绘暟+褰撳墠浣嶇疆鏁帮紱鍚﹀垯鍙娇鐢ㄥ綋鍓嶄綅缃暟
-                        Quantity = 1,
-
-                        // 閫氶亾/浣嶇疆缂栧彿
-                        Channel = x,
-
-                        // 鐢垫睜鏉$爜锛氬鏋滅姸鎬佷腑鏈夋潯鐮佸垪琛紝鍙栧搴斾綅缃殑鏉$爜锛涘惁鍒欎负绌�
-                        CellBarcode = state.CellBarcode?.Count > 0 ? state.CellBarcode[x - 1] : ""
-                    })
-                    .ToList()
-            };
-        }
-
-        /// <summary>
-        /// 璋冪敤鎷嗙洏 API
-        /// </summary>
-        /// <remarks>
-        /// 褰撳彇璐у畬鎴愪笖闇�瑕佹媶鐩樻椂璋冪敤銆�
-        /// 灏嗙數姹犱粠鎵樼洏涓婂彇涓嬶紝閫愪釜鏀剧疆鍒扮洰鏍囦綅缃��
-        /// </remarks>
-        /// <param name="stockDTO">搴撳瓨 DTO锛屽寘鍚鎷嗙洏鐨勭數鑺俊鎭�</param>
-        /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
-        public HttpResponseResult<WebResponseContent> PostSplitPalletAsync(StockDTO stockDTO)
-        {
-            return _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.SplitPalletAsync), stockDTO.ToJson());
-        }
-
-        /// <summary>
-        /// 璋冪敤缁勭洏/鎹㈢洏 API
-        /// </summary>
-        /// <remarks>
-        /// 褰撴斁璐у畬鎴愪笖闇�瑕佺粍鐩樻垨鎹㈢洏鏃惰皟鐢ㄣ��
-        /// 灏嗗涓數姹犵粍鍚堝埌鍚屼竴涓墭鐩樹笂銆�
-        ///
-        /// configKey 鍙傛暟鍐冲畾璋冪敤鍝釜 API锛�
-        /// - GroupPalletAsync: 缁勭洏鎺ュ彛
-        /// - ChangePalletAsync: 鎹㈢洏鎺ュ彛
-        /// </remarks>
-        /// <param name="configKey">閰嶇疆閿悕锛屽喅瀹氳皟鐢ㄥ摢涓� API</param>
-        /// <param name="stockDTO">搴撳瓨 DTO锛屽寘鍚缁勭洏鐨勭數鑺俊鎭�</param>
-        /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
-        public HttpResponseResult<WebResponseContent> PostGroupPalletAsync(string configKey, StockDTO stockDTO)
-        {
-            return _httpClientHelper.Post<WebResponseContent>(configKey, stockDTO.ToJson());
-        }
-
-        /// <summary>
-        /// 璋冪敤鎵归噺鎷嗙洏纭 API
-        /// </summary>
-        /// <remarks>
-        /// 褰撴媶鐩樹换鍔″叏閮ㄥ彇瀹屾椂璋冪敤锛屼竴娆℃�т笂浼犳暣涓墭鐩樼殑瑙g粦鏁版嵁鍒� MES銆�
-        /// </remarks>
-        /// <param name="palletCode">婧愭墭鐩樺彿</param>
-        /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
-        public HttpResponseResult<WebResponseContent> PostSplitPalletConfirmAsync(string palletCode)
-        {
-            var request = new { PalletCode = palletCode };
-            return _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.SplitPalletConfirm), request.ToJson());
-        }
-
-        /// <summary>
-        /// 璋冪敤鎵归噺缁勭洏纭 API
-        /// </summary>
-        /// <remarks>
-        /// 褰撶粍鐩樹换鍔″叏閮ㄦ斁瀹屾椂璋冪敤锛屼竴娆℃�т笂浼犳暣涓墭鐩樼殑缁戝畾鏁版嵁鍒� MES銆�
-        /// </remarks>
-        /// <param name="palletCode">鐩爣鎵樼洏鍙�</param>
-        /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
-        public HttpResponseResult<WebResponseContent> PostGroupPalletConfirmAsync(string palletCode)
-        {
-            var request = new { PalletCode = palletCode };
-            return _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.GroupPalletConfirm), request.ToJson());
-        }
-    }
-}
+using Masuit.Tools;
+using Newtonsoft.Json;
+using Serilog;
+using WIDESEA_Core;
+using WIDESEAWCS_Common;
+using WIDESEAWCS_Common.HttpEnum;
+using WIDESEAWCS_Common.TaskEnum;
+using WIDESEAWCS_Core;
+using WIDESEAWCS_Core.Helper;
+using WIDESEAWCS_Core.LogHelper;
+using WIDESEAWCS_DTO.Stock;
+using WIDESEAWCS_DTO.TaskInfo;
+using WIDESEAWCS_ITaskInfoService;
+using WIDESEAWCS_Model.Models;
+using WIDESEAWCS_QuartzJob;
+using WIDESEAWCS_Tasks.Workflow.Abstractions;
+
+namespace WIDESEAWCS_Tasks
+{
+    /// <summary>
+    /// 鏈哄櫒浜轰换鍔″鐞嗗櫒 - 璐熻矗浠诲姟鑾峰彇銆佷笅鍙戙�佸叆搴撲换鍔″洖浼犲強搴撳瓨 DTO 鏋勫缓
+    /// </summary>
+    /// <remarks>
+    /// 鏍稿績鑱岃矗锛�
+    /// 1. 浠庢暟鎹簱杞寰呭鐞嗙殑鏈哄櫒浜轰换鍔�
+    /// 2. 鍚戞満鍣ㄤ汉瀹㈡埛绔笅鍙戝彇璐ф寚浠わ紙Pickbattery锛�
+    /// 3. 澶勭悊鍏ュ簱浠诲姟鐨勫洖浼狅紙鎷嗙洏/缁勭洏/鎹㈢洏鍦烘櫙锛�
+    /// 4. 鏋勫缓搴撳瓨鍥炰紶 DTO 骞惰皟鐢� WMS 鎺ュ彛
+    ///
+    /// 閫氳繃缃戝叧璁块棶 Socket锛岄伩鍏嶄笟鍔″眰鐩存帴渚濊禆 TcpSocketServer銆�
+    /// </remarks>
+    public class RobotTaskProcessor
+    {
+        /// <summary>
+        /// Socket 瀹㈡埛绔綉鍏虫帴鍙�
+        /// </summary>
+        /// <remarks>
+        /// 閫氳繃缃戝叧璁块棶 Socket锛岄伩鍏嶄笟鍔″眰鐩存帴渚濊禆 TcpSocketServer銆�
+        /// 鎻愪緵缁熶竴鐨勫鎴风閫氫俊鎺ュ彛銆�
+        /// </remarks>
+        private readonly ISocketClientGateway _socketClientGateway;
+
+        /// <summary>
+        /// 鏈烘鎵嬬姸鎬佺鐞嗗櫒
+        /// </summary>
+        private readonly RobotStateManager _stateManager;
+
+        /// <summary>
+        /// 鏈哄櫒浜轰换鍔℃湇鍔�
+        /// </summary>
+        /// <remarks>
+        /// 鐢ㄤ簬鏌ヨ銆佹洿鏂般�佸垹闄ゆ満鍣ㄤ汉浠诲姟璁板綍銆�
+        /// </remarks>
+        private readonly IRobotTaskService _robotTaskService;
+
+        /// <summary>
+        /// 閫氱敤浠诲姟鏈嶅姟
+        /// </summary>
+        /// <remarks>
+        /// 鐢ㄤ簬涓� WMS 绯荤粺浜や簰锛屾帴鏀朵换鍔°�佸鐞嗕换鍔$姸鎬佺瓑銆�
+        /// </remarks>
+        private readonly ITaskService _taskService;
+
+        /// <summary>
+        /// HTTP 瀹㈡埛绔府鍔╃被
+        /// </summary>
+        /// <remarks>
+        /// 鐢ㄤ簬璋冪敤 WMS 绯荤粺鐨� HTTP 鎺ュ彛銆�
+        /// </remarks>
+        private readonly HttpClientHelper _httpClientHelper;
+
+        /// <summary>
+        /// 鍋囩數鑺钩闈㈢偣浣嶆湇鍔�
+        /// </summary>
+        /// <remarks>
+        /// 鐢ㄤ簬绠$悊鍋囩數鑺钩闈㈢偣浣嶇殑鍒嗛厤鍜岀姸鎬併��
+        /// </remarks>
+        private readonly IFakeBatteryPositionService _fakeBatteryPositionService;
+
+        /// <summary>
+        /// 鏃ュ織璁板綍鍣�
+        /// </summary>
+        private readonly ILogger _logger;
+
+        /// <summary>
+        /// 鏋勯�犲嚱鏁�
+        /// </summary>
+        /// <param name="socketClientGateway">Socket 缃戝叧</param>
+        /// <param name="stateManager">鐘舵�佺鐞嗗櫒</param>
+        /// <param name="robotTaskService">鏈哄櫒浜轰换鍔℃湇鍔�</param>
+        /// <param name="taskService">閫氱敤浠诲姟鏈嶅姟</param>
+        /// <param name="httpClientHelper">HTTP 瀹㈡埛绔府鍔╃被</param>
+        /// <param name="logger">鏃ュ織璁板綍鍣�</param>
+        public RobotTaskProcessor(
+            ISocketClientGateway socketClientGateway,
+            RobotStateManager stateManager,
+            IRobotTaskService robotTaskService,
+            ITaskService taskService,
+            HttpClientHelper httpClientHelper,
+            ILogger logger,
+            IFakeBatteryPositionService fakeBatteryPositionService)
+        {
+            _socketClientGateway = socketClientGateway;
+            _stateManager = stateManager;
+            _robotTaskService = robotTaskService;
+            _taskService = taskService;
+            _httpClientHelper = httpClientHelper;
+            _logger = logger;
+            _fakeBatteryPositionService = fakeBatteryPositionService;
+        }
+
+        /// <summary>
+        /// 鎸夎澶囩紪鐮佽幏鍙栧綋鍓嶆満鍣ㄤ汉鐨勫緟澶勭悊浠诲姟
+        /// </summary>
+        /// <remarks>
+        /// 浠庢暟鎹簱涓煡璇㈡寚瀹氳澶囩紪鐮佺殑寰呭鐞嗘満鍣ㄤ汉浠诲姟銆�
+        /// 鍙繑鍥炵姸鎬佷负"寰呭鐞�"鐨勪换鍔°��
+        /// </remarks>
+        /// <param name="robotCrane">鏈哄櫒浜鸿澶囦俊鎭紝鍖呭惈璁惧缂栫爜</param>
+        /// <returns>寰呭鐞嗙殑浠诲姟瀵硅薄锛屽鏋滄病鏈夊垯杩斿洖 null</returns>
+        public Dt_RobotTask? GetTask(RobotCraneDevice robotCrane)
+        {
+            return _robotTaskService.QueryRobotCraneTask(robotCrane.DeviceCode);
+        }
+
+        /// <summary>
+        /// 鎸夎澶囩紪鐮佽幏鍙栧綋鍓嶆満鍣ㄤ汉鐨勬墽琛屼腑浠诲姟
+        /// </summary>
+        /// <remarks>
+        /// 浠庢暟鎹簱涓煡璇㈡寚瀹氳澶囩紪鐮佺殑鎵ц涓満鍣ㄤ汉浠诲姟銆�
+        /// 褰揜obotArmObject涓�1锛堟湁鐗╂枡锛変笖娌℃湁寰呭鐞嗕换鍔℃椂璋冪敤銆�
+        /// </remarks>
+        /// <param name="robotCrane">鏈哄櫒浜鸿澶囦俊鎭紝鍖呭惈璁惧缂栫爜</param>
+        /// <returns>鎵ц涓殑浠诲姟瀵硅薄锛屽鏋滄病鏈夊垯杩斿洖 null</returns>
+        public Dt_RobotTask? GetExecutingTask(RobotCraneDevice robotCrane)
+        {
+            return _robotTaskService.QueryRobotCraneExecutingTask(robotCrane.DeviceCode);
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="robotCrane"></param>
+        /// <returns></returns>
+        public Dt_RobotTask? GetRobotTask(RobotCraneDevice robotCrane)
+        {
+            return _robotTaskService.Repository.QueryFirst(x => x.RobotRoadway == robotCrane.DeviceCode);
+        }
+
+        /// <summary>
+        /// 鍒犻櫎鏈哄櫒浜轰换鍔�
+        /// </summary>
+        /// <remarks>
+        /// 褰撲换鍔″畬鎴愶紙鏃犺鏄垚鍔熻繕鏄け璐ワ級鏃惰皟鐢紝鍒犻櫎鏁版嵁搴撲腑鐨勪换鍔¤褰曘��
+        /// </remarks>
+        /// <param name="ID">瑕佸垹闄ょ殑浠诲姟 ID</param>
+        /// <returns>鍒犻櫎鏄惁鎴愬姛</returns>
+        public bool? DeleteTask(int ID)
+        {
+            return _robotTaskService.DeleteRobotTask(ID);
+        }
+
+        /// <summary>
+        /// 涓嬪彂鍙栬揣鎸囦护锛圥ickbattery锛夊埌鏈哄櫒浜哄鎴风
+        /// </summary>
+        /// <remarks>
+        /// 鍙戦�佹牸寮忥細Pickbattery,{婧愬湴鍧�}
+        /// 渚嬪锛歅ickbattery,A01 琛ㄧず浠� A01 浣嶇疆鍙栬揣
+        ///
+        /// 涓嬪彂鎴愬姛鍚庯細
+        /// 1. 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
+        /// 2. 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
+        /// 3. 瀹夊叏鏇存柊鐘舵�佸埌 Redis
+        /// 4. 鏇存柊浠诲姟璁板綍鍒版暟鎹簱
+        /// </remarks>
+        /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
+        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+        /// <param name="isScanNG">鏄惁鎵爜NG</param>
+        public async Task SendSocketRobotPickAsync(Dt_RobotTask task, RobotSocketState state, bool isScanNG = false)
+        {
+            // 鏋勫缓鍙栬揣鎸囦护锛屾牸寮忥細Pickbattery,{婧愬湴鍧�}
+            string taskString = $"Pickbattery,{task.RobotSourceAddress}";
+
+            // 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
+            task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+
+            // 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
+            state.CurrentTask = task;
+
+            if (isScanNG)
+            {
+                state.IsScanNG = true;
+            }
+
+            // 淇濇寔鍘熻涔夛細浠呭湪鐘舵�佸畨鍏ㄥ啓鍏ユ垚鍔熷悗鍐嶆洿鏂颁换鍔$姸鎬�
+            // 杩欐牱鍙互纭繚鐘舵�佸拰浠诲姟璁板綍鐨勪竴鑷存��
+            if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
+            {
+                QuartzLogHelper.LogInfo(_logger, $"鐘舵�佹洿鏂版垚鍔燂紝璁惧: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+                // 閫氳繃 Socket 缃戝叧鍙戦�佹寚浠ゅ埌鏈哄櫒浜哄鎴风
+                bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+                if (result)
+                {
+                    // 鍙戦�佹垚鍔燂紝璁板綍 Info 鏃ュ織
+                    QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+                    //await _robotTaskService.UpdateRobotTaskAsync(task);
+                }
+                else
+                {
+                    // 鍙戦�佸け璐ワ紝璁板綍 Error 鏃ュ織
+                    QuartzLogHelper.LogError(_logger, $"涓嬪彂鍙栬揣鎸囦护澶辫触锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+                }
+            }
+        }
+
+
+        public async Task SendSocketRobotNumAsync(Dt_RobotTask task, RobotSocketState state, bool isPick = true)
+        {
+            string taskString = string.Empty;
+
+            if (isPick)
+                // 鏋勫缓鎸囦护锛屾牸寮忥細PickTotalNum,{鏁伴噺}||PutTotalNum,{鏁伴噺}
+                taskString = $"PickTotalNum,{task.RobotTaskTotalNum + state.RobotTaskTotalNum}";
+            else
+                // 鏋勫缓鎸囦护锛屾牸寮忥細PutTotalNum,{鏁伴噺}||PutTotalNum,{鏁伴噺}
+                taskString = $"PutTotalNum,{task.RobotTaskTotalNum + state.RobotTaskTotalNum}";
+
+            // 閫氳繃 Socket 缃戝叧鍙戦�佹寚浠ゅ埌鏈哄櫒浜哄鎴风
+            bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+            if (result)
+            {
+                // 鍙戦�佹垚鍔燂紝璁板綍 Info 鏃ュ織
+                QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鎬绘暟鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+                //await _robotTaskService.UpdateRobotTaskAsync(task);
+            }
+            else
+            {
+                // 鍙戦�佸け璐ワ紝璁板綍 Error 鏃ュ織
+                QuartzLogHelper.LogError(_logger, $"涓嬪彂鎬绘暟鎸囦护澶辫触锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+            }
+        }
+
+        /// <summary>
+        /// 涓嬪彂鍋囩數鑺彇璐ф寚浠ゅ埌鏈哄櫒浜哄鎴风
+        /// </summary>
+        /// <remarks>
+        /// 鍙戦�佹牸寮忥細Pickbattery,5,{startPosition}-{endPosition}
+        /// 渚嬪锛歅ickbattery,5,1-3 琛ㄧず浠庡亣鐢佃姱浣嶇疆5鎶撳彇锛屽钩闈㈢偣浣�1鍒�3
+        ///
+        /// 涓嬪彂鎴愬姛鍚庯細
+        /// 1. 鏍囪鐐逛綅涓哄凡浣跨敤
+        /// 2. 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
+        /// 3. 瀹夊叏鏇存柊鐘舵�佸埌 Redis
+        /// </remarks>
+        /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
+        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+        /// <param name="positions">瑕佹姄鍙栫殑骞抽潰鐐逛綅鍒楄〃</param>
+        public async Task SendSocketRobotFakeBatteryPickAsync(Dt_RobotTask task, RobotSocketState state, List<int> positions)
+        {
+            if (positions == null || positions.Count == 0)
+            {
+                QuartzLogHelper.LogWarn(_logger, $"SendSocketRobotFakeBatteryPickAsync锛氬钩闈㈢偣浣嶅垪琛ㄤ负绌猴紝浠诲姟鍙�: {task.RobotTaskNum}", state.RobotCrane?.DeviceName ?? "Unknown");
+                return;
+            }
+
+            // 璁$畻鐐逛綅鑼冨洿锛屾牸寮忥細1-3
+            int startPos = positions.Min();
+            int endPos = positions.Max();
+            string taskString = $"Pickbattery,5,{startPos}-{endPos}";
+
+            // 鏍囪鐐逛綅涓哄凡浣跨敤
+            _fakeBatteryPositionService.MarkAsUsed(positions);
+
+            // 鏇存柊浠诲姟鐘舵�佷负"鏈哄櫒浜烘墽琛屼腑"
+            task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+
+            // 灏嗕换鍔″叧鑱斿埌鐘舵�佸璞�
+            state.CurrentTask = task;
+
+            if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
+            {
+                // 閫氳繃 Socket 缃戝叧鍙戦�佹寚浠ゅ埌鏈哄櫒浜哄鎴风
+                bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+
+                if (result)
+                {
+                    QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鍋囩數鑺彇璐ф寚浠ゆ垚鍔燂紝鎸囦护: {taskString}锛岀偣浣�: {string.Join(",", positions)}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+                    //await _robotTaskService.UpdateRobotTaskAsync(task);
+                }
+                else
+                {
+                    QuartzLogHelper.LogError(_logger, $"涓嬪彂鍋囩數鑺彇璐ф寚浠ゅけ璐ワ紝鎸囦护: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇涓婲涓彲鐢ㄧ殑鍋囩數鑺钩闈㈢偣浣�
+        /// </summary>
+        /// <param name="count">闇�瑕佽幏鍙栫殑鐐逛綅鏁伴噺</param>
+        /// <returns>鍙敤鐐逛綅鍒楄〃</returns>
+        public List<int> GetNextAvailableFakeBatteryPositions(int count)
+        {
+            return _fakeBatteryPositionService.GetNextAvailable(count);
+        }
+
+        /// <summary>
+        /// 璁$畻鎵规缂栧彿鑼冨洿
+        /// </summary>
+        /// <remarks>
+        /// 杩斿洖鏍煎紡锛�(start, end)
+        /// - remaining >= 4: (currentIndex, currentIndex + 3)
+        /// - remaining > 1: (currentIndex, currentIndex + remaining - 1)
+        /// - remaining == 1: (currentIndex, 0)  -- 鍗曚釜鐗╁搧鐢� 0 琛ㄧず end
+        /// </remarks>
+        /// <param name="currentIndex">褰撳墠鎵规璧峰缂栧彿</param>
+        /// <param name="remaining">鍓╀綑鏁伴噺</param>
+        /// <returns>(start, end) 鍏冪粍</returns>
+        public (int Start, int End) BuildBatchRange(int currentIndex, int remaining)
+        {
+            if (remaining >= 4)
+                return (currentIndex, currentIndex + 3);
+            else if (remaining > 1)
+                return (currentIndex, currentIndex + remaining - 1);
+            else  // remaining == 1
+                return (currentIndex, 0);
+        }
+
+        /// <summary>
+        /// 涓嬪彂鍙栬揣鎸囦护锛堝甫鎵规鏍煎紡鍜屾�绘暟锛�
+        /// </summary>
+        /// <remarks>
+        /// 鍙戦�侀『搴忥細
+        /// 1. PickTotalNum,{N} -- 鐪熷疄鐢佃姱鎬绘暟
+        /// 2. Pickbattery,{浣嶇疆},{start}-{end} -- 鎵规鍙栬揣鎸囦护
+        ///
+        /// 涓嬪彂鎴愬姛鍚庢洿鏂颁换鍔$姸鎬佷负"鏈哄櫒浜烘墽琛屼腑"銆�
+        /// </remarks>
+        /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
+        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+        /// <param name="position">鍙栬揣浣嶇疆</param>
+        /// <param name="batchStart">鎵规璧峰缂栧彿</param>
+        /// <param name="batchEnd">鎵规缁撴潫缂栧彿</param>
+        public async Task SendPickWithBatchAsync(Dt_RobotTask task, RobotSocketState state, string position, int batchStart, int batchEnd)
+        {
+
+            task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+            state.CurrentTask = task;
+
+            if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
+            {
+                // 鍏堝彂閫佹�绘暟鎸囦护
+                string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}";
+                await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
+
+                // 鍐嶅彂閫佹壒娆″彇璐ф寚浠�
+                string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
+                string taskString = $"Pickbattery,{position},{range}";
+
+                bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+
+                if (result)
+                {
+                    QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鎵规鍙栬揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛屾壒娆�: {range}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+                    //await _robotTaskService.UpdateRobotTaskAsync(task);
+                }
+                else
+                {
+                    QuartzLogHelper.LogError(_logger, $"涓嬪彂鎵规鍙栬揣鎸囦护澶辫触锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 涓嬪彂鍋囩數鑺彇璐ф寚浠わ紙甯︽壒娆℃牸寮忓拰鎬绘暟锛�
+        /// </summary>
+        /// <remarks>
+        /// 鍙戦�侀『搴忥細
+        /// 1. PickTotalNum,{N} -- 鐪熷疄鐢佃姱鎬绘暟
+        /// 2. Pickbattery,5,{start}-{end} -- 鎵规鍙栬揣鎸囦护锛堝浐瀹氫粠5鍙蜂綅鍙栵級
+        ///
+        /// 涓嬪彂鎴愬姛鍚庢洿鏂颁换鍔$姸鎬佷负"鏈哄櫒浜烘墽琛屼腑"銆�
+        /// </remarks>
+        /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
+        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+        /// <param name="batchStart">鎵规璧峰缂栧彿</param>
+        /// <param name="batchEnd">鎵规缁撴潫缂栧彿</param>
+        public async Task SendFakeBatteryPickWithBatchAsync(Dt_RobotTask task, RobotSocketState state, int batchStart, int batchEnd)
+        {
+            task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+            state.CurrentTask = task;
+
+            if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
+            {
+                // 鍏堝彂閫佹�绘暟鎸囦护
+                string totalNumCmd = $"PickTotalNum,{task.RobotTaskTotalNum}";
+                await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
+
+                // 鍐嶅彂閫佹壒娆″彇璐ф寚浠わ紙鍋囩數鑺浐瀹氫粠5鍙蜂綅鍙栵級
+                string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
+                string taskString = $"Pickbattery,5,{range}";
+
+                bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+
+                if (result)
+                {
+                    QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鍋囩數鑺壒娆″彇璐ф寚浠ゆ垚鍔燂紝鎸囦护: {taskString}锛屾壒娆�: {range}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+
+                    //await _robotTaskService.UpdateRobotTaskAsync(task);
+                }
+                else
+                {
+                    QuartzLogHelper.LogError(_logger, $"涓嬪彂鍋囩數鑺壒娆″彇璐ф寚浠ゅけ璐ワ紝鎸囦护: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 涓嬪彂鏀捐揣鎸囦护锛堝甫鎵规鏍煎紡鍜屾�绘暟锛�
+        /// </summary>
+        /// <remarks>
+        /// 鍙戦�侀『搴忥細
+        /// 1. PutTotalNum,{N} -- 鐪熷疄鐢佃姱鎬绘暟
+        /// 2. Putbattery,{浣嶇疆},{start}-{end} -- 鎵规鏀捐揣鎸囦护
+        ///
+        /// 涓嬪彂鎴愬姛鍚庢洿鏂颁换鍔$姸鎬佷负"鏈哄櫒浜烘墽琛屼腑"銆�
+        /// </remarks>
+        /// <param name="task">瑕佷笅鍙戠殑浠诲姟瀵硅薄</param>
+        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+        /// <param name="position">鏀捐揣浣嶇疆</param>
+        /// <param name="batchStart">鎵规璧峰缂栧彿</param>
+        /// <param name="batchEnd">鎵规缁撴潫缂栧彿</param>
+        public async Task SendPutWithBatchAsync(Dt_RobotTask task, RobotSocketState state, string position, int batchStart, int batchEnd)
+        {
+            task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
+            state.CurrentTask = task;
+
+            if (_stateManager.TryUpdateStateSafely(state.IPAddress, state))
+            {
+                // 鍏堝彂閫佹�绘暟鎸囦护
+                string totalNumCmd = $"PutTotalNum,{task.RobotTaskTotalNum}";
+                await _socketClientGateway.SendToClientAsync(state.IPAddress, totalNumCmd);
+
+                // 鍐嶅彂閫佹壒娆℃斁璐ф寚浠�
+                string range = batchEnd == 0 ? $"{batchStart}-0" : $"{batchStart}-{batchEnd}";
+                string taskString = $"Putbattery,{position},{range}";
+
+                bool result = await _socketClientGateway.SendToClientAsync(state.IPAddress, taskString);
+
+                if (result)
+                {
+                    QuartzLogHelper.LogInfo(_logger, $"涓嬪彂鏀捐揣鎸囦护鎴愬姛锛屾寚浠�: {taskString}锛屾壒娆�: {range}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+
+                    //await _robotTaskService.UpdateRobotTaskAsync(task);
+                }
+                else
+                {
+                    QuartzLogHelper.LogError(_logger, $"涓嬪彂鏀捐揣鎸囦护澶辫触锛屾寚浠�: {taskString}锛岃澶�: {state.RobotCrane?.DeviceName}", state.RobotCrane?.DeviceName);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 澶勭悊鍏ュ簱浠诲姟鍥炰紶锛堟媶鐩�/缁勭洏/鎹㈢洏鍦烘櫙锛�
+        /// </summary>
+        /// <remarks>
+        /// 褰撳彇璐у畬鎴愶紙AllPickFinished锛夋垨鏀捐揣瀹屾垚锛圓llPutFinished锛夋椂璋冪敤姝ゆ柟娉曘��
+        /// 鏍规嵁浠诲姟绫诲瀷鍜屽湴鍧�鏉ユ簮鍐冲畾濡備綍鍥炰紶缁� WMS銆�
+        ///
+        /// 澶勭悊閫昏緫锛�
+        /// 1. 鏍规嵁 useSourceAddress 鍐冲畾浣跨敤婧愬湴鍧�杩樻槸鐩爣鍦板潃
+        /// 2. 鏍规嵁浠诲姟绫诲瀷锛堢粍鐩�/鎹㈢洏/鎷嗙洏锛夊喅瀹氫换鍔$被鍨嬶紙鍏ュ簱/绌烘墭鐩樺叆搴擄級
+        /// 3. 鏋勫缓 CreateTaskDto 骞惰皟鐢� WMS 鎺ュ彛鍒涘缓浠诲姟
+        /// 4. 鎺ユ敹 WMS 杩斿洖鐨勪换鍔′俊鎭�
+        /// 5. 鏇存柊杈撻�佺嚎鐨勭洰鏍囧湴鍧�銆佷换鍔″彿绛�
+        /// </remarks>
+        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+        /// <param name="useSourceAddress">鏄惁浣跨敤婧愬湴鍧�锛坱rue 琛ㄧず鎷嗙洏/鎹㈢洏鍦烘櫙锛宖alse 琛ㄧず缁勭洏/鎹㈢洏鍦烘櫙锛�</param>
+        /// <returns>澶勭悊鏄惁鎴愬姛</returns>
+        public async Task<bool> HandleInboundTaskAsync(RobotSocketState state, bool useSourceAddress, string isRoadway = null)
+        {
+            // 鑾峰彇褰撳墠鍏宠仈鐨勪换鍔�
+            var currentTask = state.CurrentTask;
+            if (currentTask == null)
+            {
+                QuartzLogHelper.LogDebug(_logger, $"HandleInboundTaskAsync锛氬綋鍓嶄换鍔′负绌�", state.RobotCrane?.DeviceName ?? "Unknown");
+                return false;
+            }
+
+            // 鑾峰彇宸烽亾浠g爜
+            string roadway = string.Empty;
+
+            // 鏍规嵁宸烽亾鍚嶇О鍒ゆ柇浠撳簱 ID
+            int warehouseId = 0;
+
+            // 婧愬湴鍧�鍜岀洰鏍囧湴鍧�锛堝垵濮嬪寲锛�
+            string SourceAddress = currentTask.RobotTargetAddressLineCode;
+            string TargetAddress = currentTask.RobotSourceAddressLineCode;
+
+            // 浠诲姟绫诲瀷锛�0 琛ㄧず鏈畾涔夛紝绋嶅悗鏍规嵁浠诲姟绫诲瀷璁剧疆锛�
+            int taskType = 0;
+
+            // 鎵樼洏浠g爜锛堝垵濮嬪寲涓虹┖锛�
+            string PalletCode = string.Empty;
+
+            // 鑾峰彇浠诲姟绫诲瀷鐨勬灇涓惧��
+            var robotTaskType = (RobotTaskTypeEnum)currentTask.RobotTaskType;
+
+            // 鏍规嵁 useSourceAddress 鍐冲畾澶勭悊閫昏緫
+            if (useSourceAddress)
+            {
+                // 浣跨敤婧愬湴鍧�鐨勫満鏅細鎷嗙洏銆佹崲鐩橈紙鏀剧┖鎵樼洏锛�
+                switch (robotTaskType)
+                {
+                    case RobotTaskTypeEnum.GroupPallet:
+                        warehouseId = 1;
+                        roadway = "GWSC1";
+                        SourceAddress = currentTask.RobotSourceAddressLineCode;
+                        TargetAddress = currentTask.RobotTargetAddressLineCode;
+                        break;
+
+                    case RobotTaskTypeEnum.ChangePallet:
+                        // 鎹㈢洏/鎷嗙洏鍦烘櫙锛氭墭鐩橀渶瑕佸叆搴�
+                        taskType = TaskTypeEnum.InEmpty.GetHashCode();  // 绌烘墭鐩樺叆搴�
+                        PalletCode = currentTask.RobotSourceAddressPalletCode;  // 浣跨敤婧愬湴鍧�鐨勬墭鐩樼爜
+                        if (isRoadway == "HCSC1")
+                        {
+                            warehouseId = 2;
+                            roadway = "HCSC1";
+                        }
+                        else if (isRoadway == "GWSC1")
+                        {
+                            warehouseId = 1;
+                            roadway = "GWSC1";
+                        }
+
+                        SourceAddress = currentTask.RobotSourceAddressLineCode;
+                        TargetAddress = currentTask.RobotTargetAddressLineCode;
+                        break;
+                    case RobotTaskTypeEnum.SplitPallet:
+                        // 鎹㈢洏/鎷嗙洏鍦烘櫙锛氭墭鐩橀渶瑕佸叆搴�
+                        taskType = TaskTypeEnum.InEmpty.GetHashCode();  // 绌烘墭鐩樺叆搴�
+                        PalletCode = currentTask.RobotSourceAddressPalletCode;  // 浣跨敤婧愬湴鍧�鐨勬墭鐩樼爜
+
+                        warehouseId = 3;
+                        roadway = "CWSC1";
+
+                        SourceAddress = currentTask.RobotSourceAddressLineCode;
+                        TargetAddress = currentTask.RobotTargetAddressLineCode;
+                        break;
+                }
+            }
+            else
+            {
+                // 浣跨敤鐩爣鍦板潃鐨勫満鏅細缁勭洏銆佹崲鐩橈紙鎴愬搧鍏ュ簱锛�
+                switch (robotTaskType)
+                {
+                    case RobotTaskTypeEnum.ChangePallet:
+                        // 鎹㈢洏/缁勭洏鍦烘櫙锛氳揣鐗╅渶瑕佸叆搴�
+                        taskType = TaskTypeEnum.Inbound.GetHashCode();  // 鎴愬搧鍏ュ簱
+                        PalletCode = currentTask.RobotTargetAddressPalletCode;  // 浣跨敤鐩爣鍦板潃鐨勬墭鐩樼爜
+
+                        if (isRoadway == "HCSC1")
+                        {
+                            warehouseId = 2;
+                            roadway = "HCSC1";
+                        }
+                        else if (isRoadway == "GWSC1")
+                        {
+                            warehouseId = 1;
+                            roadway = "GWSC1";
+                        }
+
+                        break;
+                    case RobotTaskTypeEnum.GroupPallet:
+                        // 鎹㈢洏/缁勭洏鍦烘櫙锛氳揣鐗╅渶瑕佸叆搴�
+                        taskType = TaskTypeEnum.Inbound.GetHashCode();  // 鎴愬搧鍏ュ簱
+                        PalletCode = currentTask.RobotTargetAddressPalletCode;  // 浣跨敤鐩爣鍦板潃鐨勬墭鐩樼爜
+
+                        warehouseId = 1;
+                        roadway = "GWSC1";
+                        break;
+
+                    case RobotTaskTypeEnum.SplitPallet:
+
+                        break;
+                }
+            }
+
+            // 鏋勫缓鍒涘缓浠诲姟鐨� DTO
+            CreateTaskDto taskDto = new CreateTaskDto
+            {
+                PalletCode = PalletCode,                    // 鎵樼洏鏉$爜
+                SourceAddress = SourceAddress ?? string.Empty,  // 婧愬湴鍧�
+                TargetAddress = roadway ?? string.Empty,  // 鐩爣鍦板潃
+                Roadway = roadway ?? string.Empty,             // 宸烽亾
+                WarehouseId = warehouseId,                   // 浠撳簱 ID
+                PalletType = 1,                             // 鎵樼洏绫诲瀷锛堥粯璁や负1锛�
+                TaskType = taskType                         // 浠诲姟绫诲瀷锛堝叆搴�/绌烘墭鐩樺叆搴擄級
+            };
+
+            // 璁板綍鏃ュ織锛氬紑濮嬭皟鐢� WMS 鍒涘缓鍏ュ簱浠诲姟
+            QuartzLogHelper.LogInfo(_logger, $"HandleInboundTaskAsync锛氳皟鐢╓MS鍒涘缓鍏ュ簱浠诲姟锛屾墭鐩樼爜: {PalletCode}锛屼换鍔$被鍨�: {taskType}", state.RobotCrane?.DeviceName ?? "Unknown");
+
+            // 璋冪敤 WMS 鎺ュ彛鍒涘缓鍏ュ簱浠诲姟
+            string configKey = nameof(ConfigKey.CreateTaskInboundAsync);
+            string requestParam = taskDto.ToJson();
+            DateTime startTime = DateTime.Now;
+
+            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+
+            if (!result.IsSuccess || !result.Data.Status)
+            {
+                QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", state.RobotCrane?.DeviceName ?? "Unknown");
+                return false;
+            }
+
+            QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", state.RobotCrane?.DeviceName ?? "Unknown");
+
+            // 濡傛灉璋冪敤澶辫触鎴栬繑鍥為敊璇姸鎬�
+            if (!result.Data.Status && result.IsSuccess)
+            {
+                QuartzLogHelper.LogError(_logger, $"HandleInboundTaskAsync锛歐MS杩斿洖閿欒鐘舵�侊紝Status: {result.Data.Status}", state.RobotCrane?.DeviceName ?? "Unknown");
+                return false;
+            }
+
+            // 瑙f瀽 WMS 杩斿洖鐨勪换鍔′俊鎭�
+            WMSTaskDTO taskDTO = JsonConvert.DeserializeObject<WMSTaskDTO>(result.Data.Data.ToJson() ?? string.Empty) ?? new WMSTaskDTO();
+
+            // 璋冪敤浠诲姟鏈嶅姟鎺ユ敹 WMS 浠诲姟
+            var content = _taskService.ReceiveWMSTask(new List<WMSTaskDTO> { taskDTO });
+            if (!content.Status)
+            {
+                QuartzLogHelper.LogError(_logger, $"HandleInboundTaskAsync锛氭帴鏀禬MS浠诲姟澶辫触", state.RobotCrane?.DeviceName ?? "Unknown");
+                return false;
+            }
+
+            return true;
+        }
+
+        /// <summary>
+        /// 鏋勫缓搴撳瓨鍥炰紶 DTO
+        /// </summary>
+        /// <remarks>
+        /// 鐢ㄤ簬鎷嗙洏鍜岀粍鐩樻搷浣滄椂锛屽悜 WMS 鍥炰紶搴撳瓨淇℃伅銆�
+        /// DTO 鍖呭惈婧愯揣浣嶃�佺洰鏍囪揣浣嶃�佹墭鐩樼爜浠ュ強姣忎釜浣嶇疆鐨勭數姹犳潯鐮併��
+        /// </remarks>
+        /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
+        /// <param name="positions">鐢垫睜浣嶇疆鏁扮粍</param>
+        /// <returns>鏋勫缓濂界殑搴撳瓨 DTO</returns>
+        public static StockDTO BuildStockDTO(RobotSocketState state, int[] positions)
+        {
+            return new StockDTO
+            {
+                // 婧愯緭閫佺嚎缂栧彿
+                SourceLineNo = state.CurrentTask.RobotSourceAddressLineCode,
+
+                // 婧愭墭鐩樺彿
+                SourcePalletNo = state.CurrentTask.RobotSourceAddressPalletCode,
+
+                // 鐩爣鎵樼洏鍙�
+                TargetPalletNo = state.CurrentTask.RobotTargetAddressPalletCode,
+
+                // 鐩爣杈撻�佺嚎缂栧彿
+                TargetLineNo = state.CurrentTask.RobotTargetAddressLineCode,
+
+                // 宸烽亾缂栧彿(鏈哄櫒浜哄悕绉�)
+                Roadway = state.CurrentTask.RobotRoadway,
+
+                // 鐢垫睜浣嶇疆璇︽儏鍒楄〃
+                // 杩囨护鎺変綅缃负 0 鎴栬礋鏁扮殑鏃犳晥鏁版嵁
+                // 鎸変綅缃紪鍙锋帓搴�
+                // 涓烘瘡涓綅缃敓鎴愬搴旂殑搴撳瓨璇︽儏
+                Details = positions
+                    .Where(x => x > 0)  // 杩囨护鏃犳晥浣嶇疆
+                    .OrderBy(x => x)   // 鎸変綅缃帓搴�
+                    .Select((x, idx) => new StockDetailDTO
+                    {
+                        // 鏁伴噺锛氬鏋滃凡鏈変换鍔℃�绘暟锛屼娇鐢ㄤ换鍔℃�绘暟+褰撳墠浣嶇疆鏁帮紱鍚﹀垯鍙娇鐢ㄥ綋鍓嶄綅缃暟
+                        Quantity = 1,
+
+                        // 閫氶亾/浣嶇疆缂栧彿
+                        Channel = x,
+
+                        // 鐢垫睜鏉$爜锛氬鏋滅姸鎬佷腑鏈夋潯鐮佸垪琛紝鍙栧搴斾綅缃殑鏉$爜锛涘惁鍒欎负绌�
+                        //CellBarcode = state.CellBarcode?.Count > 0 ? state.CellBarcode[x - 1] : ""
+                        CellBarcode = !state.CellBarcode.IsNullOrEmpty() ? state.CellBarcode[idx].ToString() ?? string.Empty : string.Empty
+                    })
+                    .ToList()
+            };
+        }
+
+        /// <summary>
+        /// 璋冪敤鎷嗙洏 API
+        /// </summary>
+        /// <remarks>
+        /// 褰撳彇璐у畬鎴愪笖闇�瑕佹媶鐩樻椂璋冪敤銆�
+        /// 灏嗙數姹犱粠鎵樼洏涓婂彇涓嬶紝閫愪釜鏀剧疆鍒扮洰鏍囦綅缃��
+        /// </remarks>
+        /// <param name="stockDTO">搴撳瓨 DTO锛屽寘鍚鎷嗙洏鐨勭數鑺俊鎭�</param>
+        /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
+        public HttpResponseResult<WebResponseContent> PostSplitPalletAsync(StockDTO stockDTO)
+        {
+            string configKey = nameof(ConfigKey.SplitPalletAsync);
+            string requestParam = stockDTO.ToJson();
+            DateTime startTime = DateTime.Now;
+
+            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+
+            if (!result.IsSuccess || !result.Data.Status)
+                QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
+            else
+                QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
+
+            return result;
+        }
+
+        /// <summary>
+        /// 璋冪敤缁勭洏/鎹㈢洏 API
+        /// </summary>
+        /// <remarks>
+        /// 褰撴斁璐у畬鎴愪笖闇�瑕佺粍鐩樻垨鎹㈢洏鏃惰皟鐢ㄣ��
+        /// 灏嗗涓數姹犵粍鍚堝埌鍚屼竴涓墭鐩樹笂銆�
+        ///
+        /// configKey 鍙傛暟鍐冲畾璋冪敤鍝釜 API锛�
+        /// - GroupPalletAsync: 缁勭洏鎺ュ彛
+        /// - ChangePalletAsync: 鎹㈢洏鎺ュ彛
+        /// </remarks>
+        /// <param name="configKey">閰嶇疆閿悕锛屽喅瀹氳皟鐢ㄥ摢涓� API</param>
+        /// <param name="stockDTO">搴撳瓨 DTO锛屽寘鍚缁勭洏鐨勭數鑺俊鎭�</param>
+        /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
+        public HttpResponseResult<WebResponseContent> PostGroupPalletAsync(string configKey, StockDTO stockDTO)
+        {
+            string requestParam = stockDTO.ToJson();
+            DateTime startTime = DateTime.Now;
+
+            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+
+            if (!result.IsSuccess || !result.Data.Status)
+                QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
+            else
+                QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
+
+            return result;
+        }
+
+        /// <summary>
+        /// 璋冪敤鎵归噺鎷嗙洏纭 API
+        /// </summary>
+        /// <remarks>
+        /// 褰撴媶鐩樹换鍔″叏閮ㄥ彇瀹屾椂璋冪敤锛屼竴娆℃�т笂浼犳暣涓墭鐩樼殑瑙g粦鏁版嵁鍒� MES銆�
+        /// </remarks>
+        /// <param name="palletCode">婧愭墭鐩樺彿</param>
+        /// <param name="deviceName">璁惧鍚嶇О锛岀敤浜庝紶閫掑埌 WMS</param>
+        /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
+        public HttpResponseResult<WebResponseContent> PostSplitPalletConfirmAsync(string palletCode, string deviceName)
+        {
+            string configKey = nameof(ConfigKey.SplitPalletConfirm);
+            var request = new { PalletCode = palletCode, DeviceName = deviceName };
+            string requestParam = request.ToJson();
+            DateTime startTime = DateTime.Now;
+
+            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+
+            if (!result.IsSuccess || !result.Data.Status)
+                QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
+            else
+                QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
+
+            return result;
+        }
+
+        /// <summary>
+        /// 璋冪敤鎵归噺缁勭洏纭 API
+        /// </summary>
+        /// <remarks>
+        /// 褰撶粍鐩樹换鍔″叏閮ㄦ斁瀹屾椂璋冪敤锛屼竴娆℃�т笂浼犳暣涓墭鐩樼殑缁戝畾鏁版嵁鍒� MES銆�
+        /// </remarks>
+        /// <param name="palletCode">鐩爣鎵樼洏鍙�</param>
+        /// <param name="deviceName">璁惧鍚嶇О锛岀敤浜庝紶閫掑埌 WMS</param>
+        /// <returns>HTTP 鍝嶅簲缁撴灉</returns>
+        public HttpResponseResult<WebResponseContent> PostGroupPalletConfirmAsync(string palletCode, string deviceName)
+        {
+            string configKey = nameof(ConfigKey.GroupPalletConfirm);
+            var request = new { PalletCode = palletCode, DeviceName = deviceName };
+            string requestParam = request.ToJson();
+            DateTime startTime = DateTime.Now;
+
+            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+
+            if (!result.IsSuccess || !result.Data.Status)
+                QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskProcessor");
+            else
+                QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskProcessor");
+
+            return result;
+        }
+
+        public bool UpdateRobotTask(Dt_RobotTask task)
+        {
+            WebResponseContent content = _robotTaskService.UpdateData(task);
+            return content.Status;
+        }
+    }
+}

--
Gitblit v1.9.3