From 2e7937ca43b0712ddf96b29b04cc7baf34fa1305 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期六, 25 四月 2026 18:40:00 +0800
Subject: [PATCH] feat: 添加托盘库存明细查询功能并优化机械手任务处理

---
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Server.cs         |    3 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs                  |  837 +++++++++++++++++++++++++-----------------------
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/HttpEnum/ConfigKey.cs                         |    7 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockController.cs          |   11 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs |   60 ++
 Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs                            |   20 +
 Code/WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IStockService.cs                          |    7 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs                |   18 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs      |   10 
 9 files changed, 547 insertions(+), 426 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/HttpEnum/ConfigKey.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/HttpEnum/ConfigKey.cs
index f170c0a..53d5a3c 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/HttpEnum/ConfigKey.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/HttpEnum/ConfigKey.cs
@@ -92,7 +92,12 @@
         /// <summary>
         /// 鎵归噺缁勭洏纭
         /// </summary>
-        GroupPalletConfirm
+        GroupPalletConfirm,
+
+        /// <summary>
+        /// 鏍规嵁鎵樼洏鍙锋煡璇㈠簱瀛樻槑缁嗘暟閲�
+        /// </summary>
+        GetStockDetailCount
 
         #endregion WMS鎺ュ彛
     }
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs
index c7d972f..3502c79 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs
@@ -1,76 +1,77 @@
-锘�#region << 鐗� 鏈� 娉� 閲� >>
-
-/*----------------------------------------------------------------
- * 鍛藉悕绌洪棿锛歐IDESEAWCS_TaskInfoService
- * 鍒涘缓鑰咃細鑳$搴�
- * 鍒涘缓鏃堕棿锛�2024/8/2 16:13:36
- * 鐗堟湰锛歏1.0.0
- * 鎻忚堪锛�
- *
- * ----------------------------------------------------------------
- * 淇敼浜猴細
- * 淇敼鏃堕棿锛�
- * 鐗堟湰锛歏1.0.1
- * 淇敼璇存槑锛�
- *
- *----------------------------------------------------------------*/
-
-#endregion << 鐗� 鏈� 娉� 閲� >>
-
-using MapsterMapper;
-using Microsoft.Extensions.Configuration;
-using Newtonsoft.Json;
-using Serilog;
-using SqlSugar;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using WIDESEA_Core;
-using WIDESEAWCS_Common.HttpEnum;
-using WIDESEAWCS_Common.TaskEnum;
-using WIDESEAWCS_Core;
-using WIDESEAWCS_Core.BaseServices;
-using WIDESEAWCS_Core.Enums;
-using WIDESEAWCS_Core.Helper;
-using WIDESEAWCS_Core.Utilities;
-using WIDESEAWCS_DTO.Stock;
-using WIDESEAWCS_DTO.TaskInfo;
-using WIDESEAWCS_ITaskInfoRepository;
-using WIDESEAWCS_ITaskInfoService;
-using WIDESEAWCS_Model.Models;
-using WIDESEAWCS_QuartzJob;
-using WIDESEAWCS_QuartzJob.DTO;
-using WIDESEAWCS_Tasks;
-
-namespace WIDESEAWCS_TaskInfoService
-{
-    public class RobotTaskService : ServiceBase<Dt_RobotTask, IRobotTaskRepository>, IRobotTaskService
-    {
-        private readonly IMapper _mapper;
-        private readonly HttpClientHelper _httpClientHelper;
-        private readonly ITaskExecuteDetailService _taskExecuteDetailService;
-        private readonly ILogger _logger;
-
-        private Dictionary<string, OrderByType> _taskOrderBy = new()
-            {
-                {nameof(Dt_RobotTask.RobotGrade),OrderByType.Desc },
-                {nameof(Dt_RobotTask.CreateDate),OrderByType.Asc},
-            };
-
-        public Dictionary<string, OrderByType> TaskOrderBy
-        { get { return _taskOrderBy; } set { _taskOrderBy = value; } }
-
-        public List<int> TaskInboundTypes => typeof(TaskInboundTypeEnum).GetEnumIndexList();
-
-        public List<int> TaskOutboundTypes => typeof(TaskOutboundTypeEnum).GetEnumIndexList();
-
-        public List<int> TaskRobotTypes => typeof(TaskOtherTypeEnum).GetEnumIndexList();
-
-        public RobotTaskService(IRobotTaskRepository BaseDal, IMapper mapper, HttpClientHelper httpClientHelper, ITaskExecuteDetailService taskExecuteDetailService, ILogger logger) : base(BaseDal)
-        {
-            _mapper = mapper;
-            _httpClientHelper = httpClientHelper;
-            _taskExecuteDetailService = taskExecuteDetailService;
-            _logger = logger;
+锘�#region << 鐗� 鏈� 娉� 閲� >>
+
+/*----------------------------------------------------------------
+ * 鍛藉悕绌洪棿锛歐IDESEAWCS_TaskInfoService
+ * 鍒涘缓鑰咃細鑳$搴�
+ * 鍒涘缓鏃堕棿锛�2024/8/2 16:13:36
+ * 鐗堟湰锛歏1.0.0
+ * 鎻忚堪锛�
+ *
+ * ----------------------------------------------------------------
+ * 淇敼浜猴細
+ * 淇敼鏃堕棿锛�
+ * 鐗堟湰锛歏1.0.1
+ * 淇敼璇存槑锛�
+ *
+ *----------------------------------------------------------------*/
+
+#endregion << 鐗� 鏈� 娉� 閲� >>
+
+using MapsterMapper;
+using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json;
+using Serilog;
+using SqlSugar;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using WIDESEA_Core;
+using WIDESEAWCS_Common;
+using WIDESEAWCS_Common.HttpEnum;
+using WIDESEAWCS_Common.TaskEnum;
+using WIDESEAWCS_Core;
+using WIDESEAWCS_Core.BaseServices;
+using WIDESEAWCS_Core.Enums;
+using WIDESEAWCS_Core.Helper;
+using WIDESEAWCS_Core.Utilities;
+using WIDESEAWCS_DTO.Stock;
+using WIDESEAWCS_DTO.TaskInfo;
+using WIDESEAWCS_ITaskInfoRepository;
+using WIDESEAWCS_ITaskInfoService;
+using WIDESEAWCS_Model.Models;
+using WIDESEAWCS_QuartzJob;
+using WIDESEAWCS_QuartzJob.DTO;
+using WIDESEAWCS_Tasks;
+
+namespace WIDESEAWCS_TaskInfoService
+{
+    public class RobotTaskService : ServiceBase<Dt_RobotTask, IRobotTaskRepository>, IRobotTaskService
+    {
+        private readonly IMapper _mapper;
+        private readonly HttpClientHelper _httpClientHelper;
+        private readonly ITaskExecuteDetailService _taskExecuteDetailService;
+        private readonly ILogger _logger;
+
+        private Dictionary<string, OrderByType> _taskOrderBy = new()
+            {
+                {nameof(Dt_RobotTask.RobotGrade),OrderByType.Desc },
+                {nameof(Dt_RobotTask.CreateDate),OrderByType.Asc},
+            };
+
+        public Dictionary<string, OrderByType> TaskOrderBy
+        { get { return _taskOrderBy; } set { _taskOrderBy = value; } }
+
+        public List<int> TaskInboundTypes => typeof(TaskInboundTypeEnum).GetEnumIndexList();
+
+        public List<int> TaskOutboundTypes => typeof(TaskOutboundTypeEnum).GetEnumIndexList();
+
+        public List<int> TaskRobotTypes => typeof(TaskOtherTypeEnum).GetEnumIndexList();
+
+        public RobotTaskService(IRobotTaskRepository BaseDal, IMapper mapper, HttpClientHelper httpClientHelper, ITaskExecuteDetailService taskExecuteDetailService, ILogger logger) : base(BaseDal)
+        {
+            _mapper = mapper;
+            _httpClientHelper = httpClientHelper;
+            _taskExecuteDetailService = taskExecuteDetailService;
+            _logger = logger;
         }
         public override WebResponseContent DeleteData(object[] keys)
         {
@@ -84,330 +85,368 @@
             return WebResponseContent.Instance.OK($"鎴愬姛鍒犻櫎{tasks.Count}鏉℃暟鎹�");
 
         }
-        public bool DeleteRobotTask(int id)
-        {
-            Dt_RobotTask task = BaseDal.QueryFirst(x => x.RobotTaskId == id);
-            return BaseDal.DeleteAndMoveIntoHty(task, OperateTypeEnum.鑷姩瀹屾垚);
-        }
-
-        public WebResponseContent ReceiveWMSTask([NotNull] WMSTaskDTO taskDTO, StockDTO stockDTO)
-        {
-            WebResponseContent content = new WebResponseContent();
-            try
-            {
-                if (BaseDal.QueryFirst(x => x.RobotTaskNum == taskDTO.TaskNum || x.RobotSourceAddressPalletCode == taskDTO.PalletCode) != null)
-                {
-                    return content.Error("浠诲姟宸插瓨鍦�");
-                }
-
-                Dt_RobotTask task = new Dt_RobotTask
-                {
-                    RobotTaskNum = taskDTO.TaskNum,
-                    RobotSourceAddressLineCode = stockDTO?.SourceLineNo ?? string.Empty,
-                    RobotTargetAddressLineCode = stockDTO?.TargetLineNo ?? string.Empty,
-                    RobotRoadway = stockDTO?.Roadway ?? string.Empty,
-                    RobotSourceAddress = taskDTO.SourceAddress,
-                    RobotTargetAddress = taskDTO.TargetAddress,
-                    RobotSourceAddressPalletCode = stockDTO?.SourcePalletNo ?? string.Empty,
-                    RobotTargetAddressPalletCode = stockDTO?.TargetPalletNo ?? string.Empty,
-                    RobotTaskType = taskDTO.TaskType,
-                    RobotTaskState = taskDTO.TaskStatus,
-                    RobotGrade = taskDTO.Grade,
-                    Creater = "WMS",
-                    RobotTaskTotalNum = taskDTO.TaskQuantity,
-                };
-
-                BaseDal.AddData(task);
-
-                _taskExecuteDetailService.AddTaskExecuteDetail(new List<int> { task.RobotTaskNum }, "鎺ユ敹WMS浠诲姟");
-
-                content = WebResponseContent.Instance.OK("鎴愬姛", task);
-            }
-            catch (Exception ex)
-            {
-                content = WebResponseContent.Instance.Error($"浠诲姟鎺ユ敹閿欒,閿欒淇℃伅:{ex.Message}");
-            }
-            return content;
-        }
-
-        public Dt_RobotTask? QueryRobotCraneTask(string deviceCode)
-        {
-            return BaseDal.QueryFirst(x => x.RobotRoadway == deviceCode && x.RobotTaskState != (int)TaskRobotStatusEnum.RobotExecuting, TaskOrderBy);
-        }
-
-        public Dt_RobotTask? QueryRobotCraneExecutingTask(string deviceCode)
-        {
-            return BaseDal.QueryFirst(x => x.RobotRoadway == deviceCode && x.RobotTaskState == (int)TaskRobotStatusEnum.RobotExecuting, TaskOrderBy);
-        }
-
-        public async Task<bool> UpdateRobotTaskAsync(Dt_RobotTask robotTask)
-        {
-            return await BaseDal.UpdateDataAsync(robotTask);
-        }
-
-        /// <summary>
-        /// 鑾峰彇WMS绯荤粺鏈烘鎵嬩换鍔�
-        /// </summary>
-        /// <param name="task"></param>
-        /// <returns></returns>
-        public WebResponseContent GetWMSRobotTask(Dt_Task task)
-        {
-            string configKey = ResolveRobotTaskConfigKey(task.TargetAddress);
-            StockDTO stock = BuildRobotTaskStock(task, configKey);
-            string requestParam = stock.ToJson();
-            var stopwatch = Stopwatch.StartNew();
-
-            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
-            stopwatch.Stop();
-            if (!result.IsSuccess || !result.Data.Status)
-            {
-                QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskService");
-                return WebResponseContent.Instance.Error($"鑾峰彇WMS绯荤粺鏈烘鎵嬩换鍔″け璐�,浠诲姟鍙�:銆恵task.TaskNum}銆�,鎵樼洏鍙�:銆恵task.PalletCode}銆�,鐩爣鍦板潃:銆恵task.TargetAddress}銆�,鎺ュ彛:銆恵configKey}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�");
-            }
-
-            QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{stopwatch.ElapsedMilliseconds}ms", "RobotTaskService");
-
-            var wMSTask = JsonConvert.DeserializeObject<WMSTaskDTO>(result?.Data?.Data?.ToString() ?? string.Empty);
-            if (wMSTask == null)
-                return WebResponseContent.Instance.Error($"鑾峰彇WMS绯荤粺鏈烘鎵嬩换鍔″け璐�,浠诲姟鍙�:銆恵task.TaskNum}銆�,鎵樼洏鍙�:銆恵task.PalletCode}銆�,閿欒淇℃伅:銆怶MS鏈繑鍥炴湁鏁堜换鍔℃暟鎹��");
-
-            return ReceiveWMSTask(wMSTask, stock);
-        }
-
-        /// <summary>
-        /// 鍦ㄦ湰鍦扮洿鎺ュ垱寤烘満姊版墜浠诲姟锛屼笉璋冪敤WMS鎺ュ彛銆�
-        /// 鏍规嵁鐩爣鍦板潃瑙f瀽浠诲姟绫诲瀷锛屾瀯寤轰换鍔℃暟鎹苟鍐欏叆鏁版嵁搴撱��
-        /// </summary>
-        /// <param name="task">鍑哄簱浠诲姟瀹炰綋</param>
-        /// <returns>鎿嶄綔缁撴灉</returns>
-        public WebResponseContent CreateLocalRobotTask(Dt_Task task)
-        {
-            WebResponseContent content = new();
-            try
-            {
-                // 鏍规嵁鐩爣鍦板潃瑙f瀽浠诲姟绫诲瀷閰嶇疆閿�
-                string configKey = ResolveRobotTaskConfigKey(task.TargetAddress);
-
-                // 鏋勫缓Stock鏁版嵁
-                StockDTO stock = BuildRobotTaskStock(task, configKey);
-
-                // 鑾峰彇鎶撳彇鍜屾斁缃湴鍧�鐨勭嚎浣撻厤缃紙濡傛灉鏈夛級
-                var section = App.Configuration.GetSection("RobotAddressRules").GetSection(stock?.TargetLineNo ?? string.Empty).GetChildren().Select(c => c.Value).ToArray();
-                if (section.Length < 2)
-                    return WebResponseContent.Instance.Error($"鏈壘鍒扮嚎浣揫{stock?.TargetLineNo}]鐨勫湴鍧�閰嶇疆");
-
-                int taskType = MapConfigKeyToRobotTaskType(configKey);
-                // 鍒涘缓鏈湴鏈哄櫒浜轰换鍔�
-                Dt_RobotTask robotTask = new()
-                {
-                    RobotTaskNum = Random.Shared.Next(),
-                    RobotSourceAddress = section[0]!,
-                    RobotTargetAddress = section[1]!,
-                    RobotSourceAddressLineCode = stock?.SourceLineNo ?? string.Empty,
-                    RobotTargetAddressLineCode = stock?.TargetLineNo ?? string.Empty,
-                    RobotRoadway = stock?.TargetLineNo == "11068" ? "娉ㄦ恫缁勭洏鏈烘鎵�" : "鎹㈢洏鏈烘鎵�" ?? string.Empty, // todo
-                    RobotSourceAddressPalletCode = stock?.SourcePalletNo ?? string.Empty,
-                    RobotTargetAddressPalletCode = stock?.TargetPalletNo ?? string.Empty,
-                    RobotTaskType = taskType,
-                    RobotTaskState = (int)TaskRobotStatusEnum.RobotNew,
-                    RobotGrade = task.Grade,
-                    Creater = "WCS_Local",
-                    RobotTaskTotalNum = taskType == (int)RobotTaskTypeEnum.GroupPallet ? 48 : 1,
-                    CreateDate = DateTime.Now
-                };
-
-                BaseDal.AddData(robotTask);
-
-                _taskExecuteDetailService.AddTaskExecuteDetail(new List<int> { robotTask.RobotTaskNum }, "鏈湴鍒涘缓鏈哄櫒浜轰换鍔�");
-
-                QuartzLogHelper.LogInfo(_logger, $"鏈湴鍒涘缓鏈哄櫒浜轰换鍔℃垚鍔�,浠诲姟鍙�:銆恵robotTask.RobotTaskNum}銆�,婧愬湴鍧�:銆恵robotTask.RobotSourceAddress}銆�,鐩爣鍦板潃:銆恵robotTask.RobotTargetAddress}銆�,浠诲姟绫诲瀷:銆恵configKey}銆�", "RobotTaskService");
-
-                content = WebResponseContent.Instance.OK("鏈湴鍒涘缓鏈哄櫒浜轰换鍔℃垚鍔�", robotTask);
-            }
-            catch (Exception ex)
-            {
-                QuartzLogHelper.LogError(_logger, $"鏈湴鍒涘缓鏈哄櫒浜轰换鍔″け璐�,浠诲姟鍙�:銆恵task.TaskNum}銆�,閿欒淇℃伅:{ex.Message}", "RobotTaskService");
-                content = WebResponseContent.Instance.Error($"鏈湴鍒涘缓鏈哄櫒浜轰换鍔″け璐�,閿欒淇℃伅:{ex.Message}");
-            }
-            return content;
-        }
-
-        /// <summary>
-        /// 灏嗛厤缃敭鏄犲皠鍒版満姊版墜浠诲姟绫诲瀷鏋氫妇鍊笺��
-        /// </summary>
-        /// <param name="configKey">閰嶇疆閿悕绉�</param>
-        /// <returns>浠诲姟绫诲瀷鏋氫妇鍊�</returns>
-        public int MapConfigKeyToRobotTaskType(string? configKey)
-        {
-            return configKey switch
-            {
-                nameof(ConfigKey.CreateRobotGroupPalletTask) => (int)RobotTaskTypeEnum.GroupPallet,
-                nameof(ConfigKey.CreateRobotSplitPalletTask) => (int)RobotTaskTypeEnum.SplitPallet,
-                _ => (int)RobotTaskTypeEnum.ChangePallet
-            };
-        }
-
-        /// <summary>
-        /// 鏍规嵁杈撻�佺嚎鐩爣鍦板潃瑙f瀽鏈烘鎵嬩换鍔℃帴鍙c��
-        /// 瑙勫垯锛�
-        /// 1. 浠庨厤缃鍙栫簿纭湴鍧�鏄犲皠锛圓ddressMap锛�
-        /// 2. 鏈懡涓椂榛樿鎹㈢洏
-        /// </summary>
-        public string ResolveRobotTaskConfigKey(string? targetAddress)
-        {
-            string address = (targetAddress ?? string.Empty).Trim();
-            if (string.IsNullOrWhiteSpace(address))
-                return nameof(ConfigKey.CreateRobotChangePalletTask);
-
-            var section = App.Configuration.GetSection("RobotTaskAddressRules");
-            var addressMap = ReadRobotRuleMap(section.GetSection("AddressMap"));
-            if (addressMap.TryGetValue(address, out string? exactTaskType))
-                return MapRobotTaskTypeToConfigKey(exactTaskType);
-
-            return nameof(ConfigKey.CreateRobotChangePalletTask);
-        }
-
-        public int MapWarehouseIdConfigKey(string? targetAddress)
-        {
-            return targetAddress switch
-            {
-                "11068" => 1,
-                "11001" => 3,
-                "11010" => 3,
-                "10010" => 1,
-                "10030" => 1,
-                _ => 1
-            };
-        }
-
-        /// <summary>
-        /// 灏嗛厤缃换鍔$被鍨嬭浆鎹负鎺ュ彛閰嶇疆閿��
-        /// 鏀寔鍊硷細Split/Group/Change锛堝ぇ灏忓啓涓嶆晱鎰燂級
-        /// </summary>
-        public string MapRobotTaskTypeToConfigKey(string? taskType)
-        {
-            string type = (taskType ?? string.Empty).Trim().ToLowerInvariant();
-            return type switch
-            {
-                "split" => nameof(ConfigKey.CreateRobotSplitPalletTask),
-                "group" => nameof(ConfigKey.CreateRobotGroupPalletTask),
-                _ => nameof(ConfigKey.CreateRobotChangePalletTask)
-            };
-        }
-
-        /// <summary>
-        /// 鏍规嵁鎺ュ彛绫诲瀷鏋勫缓鏈烘鎵嬩换鍔″叆鍙傘��
-        /// </summary>
-        public StockDTO BuildRobotTaskStock(Dt_Task task, string configKey)
-        {
-            string targetAddress = task.TargetAddress ?? string.Empty;
-            string roadway = ResolveRobotRuleValue(targetAddress, "AddressRoadwayMap", task.Roadway);
-            string sourceLineNo = ResolveRobotRuleValue(targetAddress, "AddressSourceLineNoMap", task.SourceAddress);
-
-            var stock = new StockDTO
-            {
-                Roadway = roadway,
-                SourceLineNo = sourceLineNo,
-                TargetLineNo = task.TargetAddress,
-                SourcePalletNo = task.PalletCode,
-                TargetPalletNo = task.PalletCode
-            };
-
-            if (configKey == nameof(ConfigKey.CreateRobotSplitPalletTask))
-            {
-                stock.TargetPalletNo = string.Empty;
-            }
-            else if (configKey == nameof(ConfigKey.CreateRobotGroupPalletTask))
-            {
-                stock.SourcePalletNo = string.Empty;
-            }
-            else if (configKey == nameof(ConfigKey.CreateRobotChangePalletTask))
-            {
-                IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceProDTOs.Any(d => d.DeviceChildCode == sourceLineNo));
-                if (device != null)
-                {
-                    CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
-
-                    DeviceProDTO? devicePro = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(ConveyorLineDBNameNew.Barcode) && x.DeviceChildCode == sourceLineNo);
-                    //ConveyorLineTaskCommandNew command = conveyorLine.ReadCustomer<ConveyorLineTaskCommandNew>(sourceLineNo);  // 娴嬭瘯鐢�
-                    var barcode = conveyorLine.GetValue<ConveyorLineDBNameNew, string>(ConveyorLineDBNameNew.Barcode, sourceLineNo);
-                    stock.SourcePalletNo = string.IsNullOrEmpty(barcode) ? string.Empty : barcode;
-                }
-            }
-
-            return stock;
-        }
-
-        public override WebResponseContent AddData(SaveModel saveModel)
-        {
-            try
-            {
-                if (saveModel == null || saveModel.MainData == null || saveModel.MainData.Count == 0)
-                {
-                    return WebResponseContent.Instance.Error("浼犲弬閿欒,鍙傛暟涓嶈兘涓虹┖");
-                }
-
-                string validResult = typeof(Dt_RobotTask).ValidateDicInEntity(saveModel.MainData, true, TProperties);
-                if (!string.IsNullOrEmpty(validResult))
-                {
-                    return WebResponseContent.Instance.Error(validResult);
-                }
-
-                object? taskNumObj = saveModel.MainData[nameof(Dt_RobotTask.RobotTaskNum)];
-                if (taskNumObj != null)
-                {
-                    int taskNum = Convert.ToInt32(taskNumObj);
-                    if (BaseDal.QueryFirst(x => x.RobotTaskNum == taskNum) != null)
-                    {
-                        return WebResponseContent.Instance.Error($"浠诲姟缂栧彿 {taskNum} 宸插瓨鍦�");
-                    }
-                }
-
-                Dt_RobotTask entity = saveModel.MainData.DicToModel<Dt_RobotTask>();
-                entity.Creater = "鎵嬪姩鍒涘缓";
-                entity.CreateDate = DateTime.Now;
-
-                if (saveModel.DetailData == null || saveModel.DetailData.Count == 0)
-                {
-                    BaseDal.AddData(entity);
-                    return WebResponseContent.Instance.OK("鏂板鎴愬姛", entity);
-                }
-
-                return base.AddData(saveModel);
-            }
-            catch (Exception ex)
-            {
-                return WebResponseContent.Instance.Error($"鏂板澶辫触,閿欒淇℃伅:{ex.Message}");
-            }
-        }
-
-        /// <summary>
-        /// 鏍规嵁鐩爣鍦板潃鎸夈�岀簿纭� > 鍥為��鍊笺�嶈В鏋愯鍒欏�笺��
-        /// </summary>
-        public string ResolveRobotRuleValue(string? targetAddress, string addressSectionName, string? fallback)
-        {
-            string address = (targetAddress ?? string.Empty).Trim();
-            string defaultValue = fallback ?? string.Empty;
-            if (string.IsNullOrWhiteSpace(address))
-                return defaultValue;
-
-            var section = App.Configuration.GetSection("RobotTaskAddressRules");
-            var addressMap = ReadRobotRuleMap(section.GetSection(addressSectionName));
-            if (addressMap.TryGetValue(address, out string? value))
-                return value;
-
-            return defaultValue;
-        }
-
-        /// <summary>
-        /// 璇诲彇瑙勫垯鏄犲皠娈点��
-        /// </summary>
-        private Dictionary<string, string> ReadRobotRuleMap(IConfigurationSection section)
-        {
-            return section
-                .GetChildren()
-                .Where(x => !string.IsNullOrWhiteSpace(x.Key) && !string.IsNullOrWhiteSpace(x.Value))
-                .ToDictionary(x => x.Key.Trim(), x => x.Value!.Trim());
-        }
-    }
+        public bool DeleteRobotTask(int id)
+        {
+            Dt_RobotTask task = BaseDal.QueryFirst(x => x.RobotTaskId == id);
+            return BaseDal.DeleteAndMoveIntoHty(task, OperateTypeEnum.鑷姩瀹屾垚);
+        }
+
+        public WebResponseContent ReceiveWMSTask([NotNull] WMSTaskDTO taskDTO, StockDTO stockDTO)
+        {
+            WebResponseContent content = new WebResponseContent();
+            try
+            {
+                if (BaseDal.QueryFirst(x => x.RobotTaskNum == taskDTO.TaskNum || x.RobotSourceAddressPalletCode == taskDTO.PalletCode) != null)
+                {
+                    return content.Error("浠诲姟宸插瓨鍦�");
+                }
+
+                Dt_RobotTask task = new Dt_RobotTask
+                {
+                    RobotTaskNum = taskDTO.TaskNum,
+                    RobotSourceAddressLineCode = stockDTO?.SourceLineNo ?? string.Empty,
+                    RobotTargetAddressLineCode = stockDTO?.TargetLineNo ?? string.Empty,
+                    RobotRoadway = stockDTO?.Roadway ?? string.Empty,
+                    RobotSourceAddress = taskDTO.SourceAddress,
+                    RobotTargetAddress = taskDTO.TargetAddress,
+                    RobotSourceAddressPalletCode = stockDTO?.SourcePalletNo ?? string.Empty,
+                    RobotTargetAddressPalletCode = stockDTO?.TargetPalletNo ?? string.Empty,
+                    RobotTaskType = taskDTO.TaskType,
+                    RobotTaskState = taskDTO.TaskStatus,
+                    RobotGrade = taskDTO.Grade,
+                    Creater = "WMS",
+                    RobotTaskTotalNum = taskDTO.TaskQuantity,
+                };
+
+                BaseDal.AddData(task);
+
+                _taskExecuteDetailService.AddTaskExecuteDetail(new List<int> { task.RobotTaskNum }, "鎺ユ敹WMS浠诲姟");
+
+                content = WebResponseContent.Instance.OK("鎴愬姛", task);
+            }
+            catch (Exception ex)
+            {
+                content = WebResponseContent.Instance.Error($"浠诲姟鎺ユ敹閿欒,閿欒淇℃伅:{ex.Message}");
+            }
+            return content;
+        }
+
+        public Dt_RobotTask? QueryRobotCraneTask(string deviceCode)
+        {
+            return BaseDal.QueryFirst(x => x.RobotRoadway == deviceCode && x.RobotTaskState != (int)TaskRobotStatusEnum.RobotExecuting, TaskOrderBy);
+        }
+
+        public Dt_RobotTask? QueryRobotCraneExecutingTask(string deviceCode)
+        {
+            return BaseDal.QueryFirst(x => x.RobotRoadway == deviceCode && x.RobotTaskState == (int)TaskRobotStatusEnum.RobotExecuting, TaskOrderBy);
+        }
+
+        public async Task<bool> UpdateRobotTaskAsync(Dt_RobotTask robotTask)
+        {
+            return await BaseDal.UpdateDataAsync(robotTask);
+        }
+
+        /// <summary>
+        /// 鑾峰彇WMS绯荤粺鏈烘鎵嬩换鍔�
+        /// </summary>
+        /// <param name="task"></param>
+        /// <returns></returns>
+        public WebResponseContent GetWMSRobotTask(Dt_Task task)
+        {
+            string configKey = ResolveRobotTaskConfigKey(task.TargetAddress);
+            StockDTO stock = BuildRobotTaskStock(task, configKey);
+            string requestParam = stock.ToJson();
+            var stopwatch = Stopwatch.StartNew();
+
+            var result = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+            stopwatch.Stop();
+            if (!result.IsSuccess || !result.Data.Status)
+            {
+                QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "RobotTaskService");
+                return WebResponseContent.Instance.Error($"鑾峰彇WMS绯荤粺鏈烘鎵嬩换鍔″け璐�,浠诲姟鍙�:銆恵task.TaskNum}銆�,鎵樼洏鍙�:銆恵task.PalletCode}銆�,鐩爣鍦板潃:銆恵task.TargetAddress}銆�,鎺ュ彛:銆恵configKey}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�");
+            }
+
+            QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{stopwatch.ElapsedMilliseconds}ms", "RobotTaskService");
+
+            var wMSTask = JsonConvert.DeserializeObject<WMSTaskDTO>(result?.Data?.Data?.ToString() ?? string.Empty);
+            if (wMSTask == null)
+                return WebResponseContent.Instance.Error($"鑾峰彇WMS绯荤粺鏈烘鎵嬩换鍔″け璐�,浠诲姟鍙�:銆恵task.TaskNum}銆�,鎵樼洏鍙�:銆恵task.PalletCode}銆�,閿欒淇℃伅:銆怶MS鏈繑鍥炴湁鏁堜换鍔℃暟鎹��");
+
+            return ReceiveWMSTask(wMSTask, stock);
+        }
+
+        /// <summary>
+        /// 鍦ㄦ湰鍦扮洿鎺ュ垱寤烘満姊版墜浠诲姟锛屼笉璋冪敤WMS鎺ュ彛銆�
+        /// 鏍规嵁鐩爣鍦板潃瑙f瀽浠诲姟绫诲瀷锛屾瀯寤轰换鍔℃暟鎹苟鍐欏叆鏁版嵁搴撱��
+        /// </summary>
+        /// <param name="task">鍑哄簱浠诲姟瀹炰綋</param>
+        /// <returns>鎿嶄綔缁撴灉</returns>
+        public WebResponseContent CreateLocalRobotTask(Dt_Task task)
+        {
+            WebResponseContent content = new();
+            try
+            {
+                // 鏍规嵁鐩爣鍦板潃瑙f瀽浠诲姟绫诲瀷閰嶇疆閿�
+                string configKey = ResolveRobotTaskConfigKey(task.TargetAddress);
+
+                // 鏋勫缓Stock鏁版嵁
+                StockDTO stock = BuildRobotTaskStock(task, configKey);
+
+                // 鑾峰彇鎶撳彇鍜屾斁缃湴鍧�鐨勭嚎浣撻厤缃紙濡傛灉鏈夛級
+                var section = App.Configuration.GetSection("RobotAddressRules").GetSection(stock?.TargetLineNo ?? string.Empty).GetChildren().Select(c => c.Value).ToArray();
+                if (section.Length < 2)
+                    return WebResponseContent.Instance.Error($"鏈壘鍒扮嚎浣揫{stock?.TargetLineNo}]鐨勫湴鍧�閰嶇疆");
+
+                int taskType = MapConfigKeyToRobotTaskType(configKey);
+                // 鍒涘缓鏈湴鏈哄櫒浜轰换鍔�
+                Dt_RobotTask robotTask = new()
+                {
+                    RobotTaskNum = Random.Shared.Next(),
+                    RobotSourceAddress = section[0]!,
+                    RobotTargetAddress = section[1]!,
+                    RobotSourceAddressLineCode = stock?.SourceLineNo ?? string.Empty,
+                    RobotTargetAddressLineCode = stock?.TargetLineNo ?? string.Empty,
+                    RobotRoadway = stock?.TargetLineNo switch
+                    {
+                        "11068" => "娉ㄦ恫缁勭洏鏈烘鎵�",
+                        "1000" => "鎷嗙洏鏈烘鎵�",
+                        "2000" => "鎴愬搧缁勭洏鏈烘鎵�",
+                        _ => "鎹㈢洏鏈烘鎵�"
+                    },
+                    RobotSourceAddressPalletCode = stock?.SourcePalletNo ?? string.Empty,
+                    RobotTargetAddressPalletCode = stock?.TargetPalletNo ?? string.Empty,
+                    RobotTaskType = taskType,
+                    RobotTaskState = (int)TaskRobotStatusEnum.RobotNew,
+                    RobotGrade = task.Grade,
+                    Creater = "WCS_Local",
+                    RobotTaskTotalNum = GetRobotTaskTotalNum(taskType, stock.SourcePalletNo),
+                    CreateDate = DateTime.Now
+                };
+
+                BaseDal.AddData(robotTask);
+
+                _taskExecuteDetailService.AddTaskExecuteDetail(new List<int> { robotTask.RobotTaskNum }, "鏈湴鍒涘缓鏈哄櫒浜轰换鍔�");
+
+                QuartzLogHelper.LogInfo(_logger, $"鏈湴鍒涘缓鏈哄櫒浜轰换鍔℃垚鍔�,浠诲姟鍙�:銆恵robotTask.RobotTaskNum}銆�,婧愬湴鍧�:銆恵robotTask.RobotSourceAddress}銆�,鐩爣鍦板潃:銆恵robotTask.RobotTargetAddress}銆�,浠诲姟绫诲瀷:銆恵configKey}銆�", "RobotTaskService");
+
+                content = WebResponseContent.Instance.OK("鏈湴鍒涘缓鏈哄櫒浜轰换鍔℃垚鍔�", robotTask);
+            }
+            catch (Exception ex)
+            {
+                QuartzLogHelper.LogError(_logger, $"鏈湴鍒涘缓鏈哄櫒浜轰换鍔″け璐�,浠诲姟鍙�:銆恵task.TaskNum}銆�,閿欒淇℃伅:{ex.Message}", "RobotTaskService");
+                content = WebResponseContent.Instance.Error($"鏈湴鍒涘缓鏈哄櫒浜轰换鍔″け璐�,閿欒淇℃伅:{ex.Message}");
+            }
+            return content;
+        }
+
+        /// <summary>
+        /// 鑾峰彇鏈烘鎵嬩换鍔℃�绘暟閲忋��
+        /// 缁勭洏浠诲姟鍥哄畾48锛屾崲鐩樺拰鎷嗙洏浠诲姟閫氳繃鎵樼洏鍙锋煡璇MS搴撳瓨鏄庣粏鏁伴噺銆�
+        /// </summary>
+        private int GetRobotTaskTotalNum(int taskType, string? palletCode)
+        {
+            if (taskType == (int)RobotTaskTypeEnum.GroupPallet)
+                return 48;
+
+            if (string.IsNullOrWhiteSpace(palletCode))
+                return 1;
+
+            try
+            {
+                string url = $"{BaseAPI.WMSBaseUrl}Stock/GetStockDetailCount?palletCode={Uri.EscapeDataString(palletCode)}";
+                var result = _httpClientHelper.Get(url);
+                if (!result.IsSuccess || string.IsNullOrEmpty(result.Content))
+                    return 1;
+
+                var response = JsonConvert.DeserializeObject<WebResponseContent>(result.Content);
+                if (response == null || !response.Status)
+                    return 1;
+
+                var detailCount = response.Data?.GetType().GetProperty("DetailCount")?.GetValue(response.Data);
+                return detailCount is int count and > 0 ? count : 1;
+            }
+            catch
+            {
+                return 1;
+            }
+        }
+
+        /// <summary>
+        /// 灏嗛厤缃敭鏄犲皠鍒版満姊版墜浠诲姟绫诲瀷鏋氫妇鍊笺��
+        /// </summary>
+        /// <param name="configKey">閰嶇疆閿悕绉�</param>
+        /// <returns>浠诲姟绫诲瀷鏋氫妇鍊�</returns>
+        public int MapConfigKeyToRobotTaskType(string? configKey)
+        {
+            return configKey switch
+            {
+                nameof(ConfigKey.CreateRobotGroupPalletTask) => (int)RobotTaskTypeEnum.GroupPallet,
+                nameof(ConfigKey.CreateRobotSplitPalletTask) => (int)RobotTaskTypeEnum.SplitPallet,
+                _ => (int)RobotTaskTypeEnum.ChangePallet
+            };
+        }
+
+        /// <summary>
+        /// 鏍规嵁杈撻�佺嚎鐩爣鍦板潃瑙f瀽鏈烘鎵嬩换鍔℃帴鍙c��
+        /// 瑙勫垯锛�
+        /// 1. 浠庨厤缃鍙栫簿纭湴鍧�鏄犲皠锛圓ddressMap锛�
+        /// 2. 鏈懡涓椂榛樿鎹㈢洏
+        /// </summary>
+        public string ResolveRobotTaskConfigKey(string? targetAddress)
+        {
+            string address = (targetAddress ?? string.Empty).Trim();
+            if (string.IsNullOrWhiteSpace(address))
+                return nameof(ConfigKey.CreateRobotChangePalletTask);
+
+            var section = App.Configuration.GetSection("RobotTaskAddressRules");
+            var addressMap = ReadRobotRuleMap(section.GetSection("AddressMap"));
+            if (addressMap.TryGetValue(address, out string? exactTaskType))
+                return MapRobotTaskTypeToConfigKey(exactTaskType);
+
+            return nameof(ConfigKey.CreateRobotChangePalletTask);
+        }
+
+        public int MapWarehouseIdConfigKey(string? targetAddress)
+        {
+            return targetAddress switch
+            {
+                "11068" => 1,
+                "11001" => 3,
+                "11010" => 3,
+                "10010" => 1,
+                "10030" => 1,
+                _ => 1
+            };
+        }
+
+        /// <summary>
+        /// 灏嗛厤缃换鍔$被鍨嬭浆鎹负鎺ュ彛閰嶇疆閿��
+        /// 鏀寔鍊硷細Split/Group/Change锛堝ぇ灏忓啓涓嶆晱鎰燂級
+        /// </summary>
+        public string MapRobotTaskTypeToConfigKey(string? taskType)
+        {
+            string type = (taskType ?? string.Empty).Trim().ToLowerInvariant();
+            return type switch
+            {
+                "split" => nameof(ConfigKey.CreateRobotSplitPalletTask),
+                "group" => nameof(ConfigKey.CreateRobotGroupPalletTask),
+                _ => nameof(ConfigKey.CreateRobotChangePalletTask)
+            };
+        }
+
+        /// <summary>
+        /// 鏍规嵁鎺ュ彛绫诲瀷鏋勫缓鏈烘鎵嬩换鍔″叆鍙傘��
+        /// </summary>
+        public StockDTO BuildRobotTaskStock(Dt_Task task, string configKey)
+        {
+            string targetAddress = task.TargetAddress ?? string.Empty;
+            string roadway = ResolveRobotRuleValue(targetAddress, "AddressRoadwayMap", task.Roadway);
+            string sourceLineNo = ResolveRobotRuleValue(targetAddress, "AddressSourceLineNoMap", task.SourceAddress);
+
+            var stock = new StockDTO
+            {
+                Roadway = roadway,
+                SourceLineNo = sourceLineNo,
+                TargetLineNo = task.TargetAddress,
+                SourcePalletNo = task.PalletCode,
+                TargetPalletNo = task.PalletCode
+            };
+
+            if (configKey == nameof(ConfigKey.CreateRobotSplitPalletTask))
+            {
+                stock.TargetPalletNo = string.Empty;
+            }
+            else if (configKey == nameof(ConfigKey.CreateRobotGroupPalletTask))
+            {
+                stock.SourcePalletNo = string.Empty;
+            }
+            else if (configKey == nameof(ConfigKey.CreateRobotChangePalletTask))
+            {
+                IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceProDTOs.Any(d => d.DeviceChildCode == sourceLineNo));
+                if (device != null)
+                {
+                    CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
+
+                    DeviceProDTO? devicePro = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(ConveyorLineDBNameNew.Barcode) && x.DeviceChildCode == sourceLineNo);
+                    //ConveyorLineTaskCommandNew command = conveyorLine.ReadCustomer<ConveyorLineTaskCommandNew>(sourceLineNo);  // 娴嬭瘯鐢�
+                    var barcode = conveyorLine.GetValue<ConveyorLineDBNameNew, string>(ConveyorLineDBNameNew.Barcode, sourceLineNo);
+                    stock.SourcePalletNo = string.IsNullOrEmpty(barcode) ? string.Empty : barcode;
+                }
+            }
+
+            return stock;
+        }
+
+        public override WebResponseContent AddData(SaveModel saveModel)
+        {
+            try
+            {
+                if (saveModel == null || saveModel.MainData == null || saveModel.MainData.Count == 0)
+                {
+                    return WebResponseContent.Instance.Error("浼犲弬閿欒,鍙傛暟涓嶈兘涓虹┖");
+                }
+
+                string validResult = typeof(Dt_RobotTask).ValidateDicInEntity(saveModel.MainData, true, TProperties);
+                if (!string.IsNullOrEmpty(validResult))
+                {
+                    return WebResponseContent.Instance.Error(validResult);
+                }
+
+                object? taskNumObj = saveModel.MainData[nameof(Dt_RobotTask.RobotTaskNum)];
+                if (taskNumObj != null)
+                {
+                    int taskNum = Convert.ToInt32(taskNumObj);
+                    if (BaseDal.QueryFirst(x => x.RobotTaskNum == taskNum) != null)
+                    {
+                        return WebResponseContent.Instance.Error($"浠诲姟缂栧彿 {taskNum} 宸插瓨鍦�");
+                    }
+                }
+
+                Dt_RobotTask entity = saveModel.MainData.DicToModel<Dt_RobotTask>();
+                entity.Creater = "鎵嬪姩鍒涘缓";
+                entity.CreateDate = DateTime.Now;
+
+                if (saveModel.DetailData == null || saveModel.DetailData.Count == 0)
+                {
+                    BaseDal.AddData(entity);
+                    return WebResponseContent.Instance.OK("鏂板鎴愬姛", entity);
+                }
+
+                return base.AddData(saveModel);
+            }
+            catch (Exception ex)
+            {
+                return WebResponseContent.Instance.Error($"鏂板澶辫触,閿欒淇℃伅:{ex.Message}");
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁鐩爣鍦板潃鎸夈�岀簿纭� > 鍥為��鍊笺�嶈В鏋愯鍒欏�笺��
+        /// </summary>
+        public string ResolveRobotRuleValue(string? targetAddress, string addressSectionName, string? fallback)
+        {
+            string address = (targetAddress ?? string.Empty).Trim();
+            string defaultValue = fallback ?? string.Empty;
+            if (string.IsNullOrWhiteSpace(address))
+                return defaultValue;
+
+            var section = App.Configuration.GetSection("RobotTaskAddressRules");
+            var addressMap = ReadRobotRuleMap(section.GetSection(addressSectionName));
+            if (addressMap.TryGetValue(address, out string? value))
+                return value;
+
+            return defaultValue;
+        }
+
+        /// <summary>
+        /// 璇诲彇瑙勫垯鏄犲皠娈点��
+        /// </summary>
+        private Dictionary<string, string> ReadRobotRuleMap(IConfigurationSection section)
+        {
+            return section
+                .GetChildren()
+                .Where(x => !string.IsNullOrWhiteSpace(x.Key) && !string.IsNullOrWhiteSpace(x.Value))
+                .ToDictionary(x => x.Key.Trim(), x => x.Value!.Trim());
+        }
+    }
 }
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs
index 7372d1a..fb56484 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs
@@ -6,6 +6,7 @@
 using Serilog;
 using SqlSugar;
 using WIDESEA_Core;
+using WIDESEAWCS_Common.HttpEnum;
 using WIDESEAWCS_Common.TaskEnum;
 using WIDESEAWCS_Core;
 using WIDESEAWCS_Core.Helper;
@@ -148,15 +149,6 @@
                         return Task.CompletedTask;
                     }
 
-                    // 鍒涘缓骞惰閫夐」锛岄檺鍒舵渶澶у苟鍙戞暟
-                    //var parallelOptions = new ParallelOptions
-                    //{
-                    //    // 闄愬埗骞跺彂鏁帮細瀛愯澶囨暟閲忓拰 CPU 鏍稿績鏁�*2 鐨勮緝灏忓��
-                    //    MaxDegreeOfParallelism = Math.Min(childDeviceCodes.Count, Environment.ProcessorCount * 2),
-                    //};
-
-                    // 骞惰澶勭悊姣忎釜瀛愯澶�
-                    //Parallel.For(0, childDeviceCodes.Count, parallelOptions, i =>
                     foreach (var childDeviceCode in childDeviceCodes)
                     {
                         //string childDeviceCode = childDeviceCodes[i];
@@ -274,15 +266,15 @@
                                     QuartzLogHelper.LogInfo(_logger, $"澶勭悊浠诲姟 {task.TaskNum}锛岀姸鎬�: {task.TaskStatus}", conveyorLine.DeviceCode);
                                     // 澶勭悊浠诲姟鐘舵�侊紙鏍规嵁鐘舵�佸垎鍙戝埌涓嶅悓鏂规硶锛�
                                     ProcessTaskState(conveyorLine, command, task, childDeviceCode);
-                                    return Task.CompletedTask;
+                                    continue;
                                 }
                                 else if (!command.Barcode.IsNullOrEmpty() && childDeviceCode == "11068")
                                 {
-                                    var isWcsTask = _taskService.Db.Queryable<Dt_Task>().Any(x => x.PalletCode == command.Barcode && x.TaskStatus == (int)TaskOutStatusEnum.OutNew);
-                                    var isRobotTask = _robotTaskService.Db.Queryable<Dt_RobotTask>().Any(x => x.RobotTargetAddressPalletCode == command.Barcode);
+                                    var isWcsTask = _taskService.Db.Queryable<Dt_Task>().Any(x => x.PalletCode == command.Barcode && (x.TaskStatus == (int)TaskOutStatusEnum.OutNew || x.TaskStatus == (int)TaskInStatusEnum.InNew));
+                                    var isRobotTask = _robotTaskService.Db.Queryable<Dt_RobotTask>().Any(x => x.RobotTargetAddressPalletCode == command.Barcode || x.RobotRoadway == "娉ㄦ恫缁勭洏鏈烘鎵�");
                                     if (isWcsTask || isRobotTask)
                                     {
-                                        return Task.CompletedTask;
+                                        continue;
                                     }
 
                                     // 鐩存帴娣诲姞鏈烘鎵嬬粍鐩樹换鍔�
@@ -306,6 +298,48 @@
                                         conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode);
                                     }
                                 }
+                                else if (!command.Barcode.IsNullOrEmpty() && (childDeviceCode == "11001" || childDeviceCode == "11010"))
+                                {
+                                    var isWcsTask = _taskService.Db.Queryable<Dt_Task>().Any(x => x.PalletCode == command.Barcode && (x.TaskStatus == (int)TaskOutStatusEnum.OutNew || x.TaskStatus == (int)TaskInStatusEnum.InNew));
+                                    var isRobotTask = _robotTaskService.Db.Queryable<Dt_RobotTask>().Any(x => x.RobotTargetAddressPalletCode == command.Barcode);
+                                    if (isWcsTask || isRobotTask)
+                                    {
+                                        continue;
+                                    }
+
+                                    // 璋冪敤 WMS 鍒涘缓绌烘墭鐩樺叆搴撲换鍔�
+                                    string configKey = nameof(ConfigKey.CreateTaskInboundAsync);
+                                    string requestParam = new CreateTaskDto()
+                                    {
+                                        PalletCode = command.Barcode,
+                                        SourceAddress = childDeviceCode,
+                                        TargetAddress = "GWSC1",  // 鐩爣鍦板潃
+                                        Roadway = "GWSC1",             // 宸烽亾
+                                        WarehouseId = 1,                   // 浠撳簱 ID
+                                        PalletType = 1,                             // 鎵樼洏绫诲瀷锛堥粯璁や负1锛�
+                                        TaskType = TaskTypeEnum.InEmpty.GetHashCode()                         // 浠诲姟绫诲瀷锛堝叆搴�/绌烘墭鐩樺叆搴擄級
+                                    }.Serialize();
+                                    DateTime startTime = DateTime.Now;
+
+                                    var responseResult = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam);
+
+                                    if (responseResult.IsSuccess && responseResult.Data.Status)
+                                    {
+                                        QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,鍝嶅簲鏁版嵁:銆恵responseResult.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", conveyorLine.DeviceCode);
+                                        var wmsTask = JsonConvert.DeserializeObject<WMSTaskDTO>(responseResult?.Data?.Data?.ToString());
+                                        List<WMSTaskDTO> taskDTOs = new List<WMSTaskDTO> { wmsTask };
+                                        if (wmsTask == null) continue;
+
+                                        if (_taskService.ReceiveWMSTask(taskDTOs).Status)
+                                        {
+                                            conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode);
+                                        }
+                                    }
+                                    else
+                                    {
+                                        QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵responseResult.Data?.Message}銆�", conveyorLine.DeviceCode);
+                                    }
+                                }
                             }
                         }
                         catch (Exception innerEx)
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
index 62c05dd..f49e018 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
@@ -60,10 +60,14 @@
                             break;
                         }
 
-                        if(message == lastMessage)
+                        // 鎸夊鎴风鍘婚噸锛氭鏌ユ槸鍚︿笌璇ュ鎴风涓婃娑堟伅鐩稿悓
+                        lock (_syncRoot)
                         {
-                            // 閲嶅娑堟伅锛屽拷鐣�
-                            continue;
+                            if (_clientLastMessage.TryGetValue(clientId, out var prev) && message == prev)
+                            {
+                                continue;
+                            }
+                            _clientLastMessage[clientId] = message;
                         }
 
                         // 鏇存柊瀹㈡埛绔姸鎬�
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Server.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Server.cs
index afaa8ec..e72378c 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Server.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Server.cs
@@ -161,6 +161,9 @@
                 // 绉婚櫎娲昏穬鏃堕棿璁板綍
                 _clientLastActive.Remove(clientId);
 
+                // 绉婚櫎涓婃娑堟伅璁板綍
+                _clientLastMessage.Remove(clientId);
+
                 // 绉婚櫎缂栫爜璁板綍
                 _clientEncodings.Remove(clientId);
 
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs
index d23fe10..3523884 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs
@@ -1,13 +1,6 @@
 using Microsoft.Extensions.Options;
-using System;
-using System.Collections.Generic;
-using System.IO;
 using System.Net.Sockets;
 using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using WIDESEAWCS_Model.Models;
-using WIDESEAWCS_QuartzJob;
 
 namespace WIDESEAWCS_Tasks.SocketServer
 {
@@ -137,9 +130,13 @@
         public bool IsRunning { get; private set; }
 
         /// <summary>
-        /// 涓婃鎺ユ敹娑堟伅婧�
+        /// 姣忎釜瀹㈡埛绔笂娆℃帴鏀剁殑娑堟伅锛岀敤浜庡幓閲�
         /// </summary>
-        public string lastMessage;
+        /// <remarks>
+        /// Key: 瀹㈡埛绔� ID
+        /// Value: 涓婃鎺ユ敹鐨勬秷鎭唴瀹�
+        /// </remarks>
+        public readonly Dictionary<string, string> _clientLastMessage = new();
 
         /// <summary>
         /// 娑堟伅鎺ユ敹浜嬩欢
@@ -200,8 +197,9 @@
         /// <param name="message">鏃ュ織娑堟伅</param>
         private void Log(string message)
         {
+            //Logger.None.Information(message);
             Console.WriteLine(message);
             try { File.AppendAllText(_logFile, message + Environment.NewLine); } catch { }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IStockService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IStockService.cs
index 6dc1603..27fc74f 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IStockService.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IStockService.cs
@@ -71,5 +71,12 @@
         /// <param name="deviceName">璁惧鍚嶇О锛堢敤浜庡姩鎬丮ES鍑瘉鏌ヨ锛�</param>
         /// <returns>鎿嶄綔缁撴灉</returns>
         Task<WebResponseContent> GroupPalletConfirmAsync(string palletCode, string deviceName);
+
+        /// <summary>
+        /// 鏍规嵁鎵樼洏鍙锋煡璇㈠簱瀛樻槑缁嗘暟閲�
+        /// </summary>
+        /// <param name="palletCode">鎵樼洏鍙�</param>
+        /// <returns>搴撳瓨鏄庣粏鏁伴噺</returns>
+        Task<WebResponseContent> GetStockDetailCountByPalletCodeAsync(string palletCode);
     }
 }
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
index 03fa684..2a154b9 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
@@ -584,6 +584,26 @@
         }
 
         /// <summary>
+        /// 鏍规嵁鎵樼洏鍙锋煡璇㈠簱瀛樻槑缁嗘暟閲�
+        /// </summary>
+        /// <param name="palletCode">鎵樼洏鍙�</param>
+        /// <returns>搴撳瓨鏄庣粏鏁伴噺</returns>
+        public async Task<WebResponseContent> GetStockDetailCountByPalletCodeAsync(string palletCode)
+        {
+            WebResponseContent content = new WebResponseContent();
+            if (string.IsNullOrWhiteSpace(palletCode))
+                return content.Error("鎵樼洏鍙蜂笉鑳戒负绌�");
+
+            var stockInfo = StockInfoService.Repository.QueryFirst(s => s.PalletCode == palletCode);
+            if (stockInfo == null)
+                return content.Error("鎵樼洏涓嶅瓨鍦�");
+
+            var count = await StockInfoDetailService.Repository.Db.Queryable<Dt_StockInfoDetail>()
+                .CountAsync(d => d.StockId == stockInfo.Id);
+            return content.OK("鏌ヨ鎴愬姛", new { PalletCode = palletCode, DetailCount = count });
+        }
+
+        /// <summary>
         /// 鏍规嵁璁惧鍚嶇О鍜屾墭鐩樺彿瑙f瀽MES璁惧閰嶇疆
         /// </summary>
         /// <param name="deviceName">璁惧鍚嶇О</param>
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockController.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockController.cs
index 6fecdfb..d6d062c 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockController.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockController.cs
@@ -85,5 +85,16 @@
         {
             return await Service.GroupPalletConfirmAsync(dto.PalletCode, dto.DeviceName);
         }
+
+        /// <summary>
+        /// 鏍规嵁鎵樼洏鍙锋煡璇㈠簱瀛樻槑缁嗘暟閲�
+        /// </summary>
+        /// <param name="palletCode">鎵樼洏鍙�</param>
+        /// <returns>搴撳瓨鏄庣粏鏁伴噺</returns>
+        [HttpGet("GetStockDetailCount"), AllowAnonymous]
+        public async Task<WebResponseContent> GetStockDetailCount(string palletCode)
+        {
+            return await Service.GetStockDetailCountByPalletCodeAsync(palletCode);
+        }
     }
 }

--
Gitblit v1.9.3