From ff006f77f6267fc0d2c4ee810d897a85165f5b8f Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期四, 30 四月 2026 22:08:29 +0800
Subject: [PATCH] Merge branch 'xiaoyang' into dev

---
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs |  196 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 190 insertions(+), 6 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs
index 3502c79..915f224 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs
@@ -17,13 +17,17 @@
 
 #endregion << 鐗� 鏈� 娉� 閲� >>
 
+using Autofac.Core;
 using MapsterMapper;
+using Masuit.Tools;
 using Microsoft.Extensions.Configuration;
 using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
 using Serilog;
 using SqlSugar;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
+using System.Text;
 using WIDESEA_Core;
 using WIDESEAWCS_Common;
 using WIDESEAWCS_Common.HttpEnum;
@@ -73,6 +77,7 @@
             _taskExecuteDetailService = taskExecuteDetailService;
             _logger = logger;
         }
+
         public override WebResponseContent DeleteData(object[] keys)
         {
             List<int> taskKeys = new List<int>();
@@ -83,8 +88,8 @@
             List<Dt_RobotTask> tasks = BaseDal.QueryData(x => taskKeys.Contains(x.RobotTaskId));
             BaseDal.DeleteAndMoveIntoHty(tasks, OperateTypeEnum.浜哄伐鍒犻櫎);
             return WebResponseContent.Instance.OK($"鎴愬姛鍒犻櫎{tasks.Count}鏉℃暟鎹�");
-
         }
+
         public bool DeleteRobotTask(int id)
         {
             Dt_RobotTask task = BaseDal.QueryFirst(x => x.RobotTaskId == id);
@@ -133,7 +138,7 @@
 
         public Dt_RobotTask? QueryRobotCraneTask(string deviceCode)
         {
-            return BaseDal.QueryFirst(x => x.RobotRoadway == deviceCode && x.RobotTaskState != (int)TaskRobotStatusEnum.RobotExecuting, TaskOrderBy);
+            return BaseDal.QueryFirst(x => x.RobotRoadway == deviceCode, TaskOrderBy);
         }
 
         public Dt_RobotTask? QueryRobotCraneExecutingTask(string deviceCode)
@@ -240,10 +245,108 @@
         }
 
         /// <summary>
+        /// 妫�鏌ユ簮绾夸綋鏄惁鏈夋墭鐩樺彿锛屽苟鏍规嵁缁撴灉鍒涘缓鏈烘鎵嬩换鍔°��
+        /// </summary>
+        /// <param name="task">鍑哄簱浠诲姟瀹炰綋</param>
+        /// <returns>
+        /// 鏈夋墭鐩樺彿鏃惰繑鍥� CreateLocalRobotTask 缁撴灉锛�
+        /// 鏃犳墭鐩樺彿鏃惰繑鍥� GetWMSOutboundTrayTask 缁撴灉銆�
+        /// </returns>
+        public WebResponseContent CheckSourceLineAndCreateRobotTask(Dt_Task task)
+        {
+            // 1. 鑾峰彇婧愮嚎浣撶紪鍙凤紙澶嶇敤宸叉湁閫昏緫锛�
+            string configKey = ResolveRobotTaskConfigKey(task.TargetAddress);
+            StockDTO stock = BuildRobotTaskStock(task, configKey);
+            string sourceLineNo = stock.SourceLineNo;
+
+            if (string.IsNullOrWhiteSpace(sourceLineNo))
+            {
+                return GetWMSOutboundTrayTaskFromWMS(task);
+            }
+
+            // 2. 閫氳繃璁惧閫氫俊璇诲彇绾夸綋鎵樼洏鍙�
+            string? palletCode = ReadLineBarcode(sourceLineNo);
+
+            if (!string.IsNullOrWhiteSpace(palletCode))
+            {
+                // 鏈夋墭鐩樺彿锛屾湰鍦板垱寤烘満姊版墜浠诲姟
+                return CreateLocalRobotTask(task);
+            }
+
+            // 鏃犳墭鐩樺彿锛屼粠 WMS 鑾峰彇浠诲姟
+            return GetWMSOutboundTrayTaskFromWMS(task);
+        }
+
+        /// <summary>
+        /// 浠嶹MS鑾峰彇绌烘墭鐩樺嚭搴撲换鍔°��
+        /// </summary>
+        /// <param name="task">浠诲姟瀹炰綋銆�</param>
+        /// <returns>璋冪敤缁撴灉銆�</returns>
+        private WebResponseContent GetWMSOutboundTrayTaskFromWMS(Dt_Task task)
+        {
+            int warehouseId = MapWarehouseIdConfigKey(task.TargetAddress);
+            string sourceLineNo = ResolveRobotRuleValue(task.TargetAddress, "AddressSourceLineNoMap", task.TargetAddress);
+            string configKey = nameof(ConfigKey.GetOutBoundTrayTaskAsync);
+            string requestParam = new CreateTaskDto { WarehouseId = warehouseId, TargetAddress = sourceLineNo }.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}銆�", "RobotTaskService");
+                return WebResponseContent.Instance.Error($"鑾峰彇WMS绯荤粺绌烘墭鐩樺嚭搴撲换鍔″け璐�,浠诲姟鍙�:銆恵task.TaskNum}銆�,鎵樼洏鍙�:銆恵task.PalletCode}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�");
+            }
+
+            QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "RobotTaskService");
+
+            WMSTaskDTO? wMSTask = JsonConvert.DeserializeObject<WMSTaskDTO>(result.Data.Data?.ToString() ?? string.Empty);
+            if (wMSTask == null)
+                return WebResponseContent.Instance.Error($"鑾峰彇WMS绯荤粺绌烘墭鐩樺嚭搴撲换鍔″け璐�,浠诲姟鍙�:銆恵task.TaskNum}銆�,鎵樼洏鍙�:銆恵task.PalletCode}銆�,閿欒淇℃伅:銆怶MS鏈繑鍥炴湁鏁堜换鍔℃暟鎹��");
+
+            // 鏋勫缓StockDTO骞惰皟鐢≧eceiveWMSTask鍒涘缓鏈湴鍏ュ簱浠诲姟
+            var stockDto = new StockDTO
+            {
+                Roadway = task.Roadway,
+                SourceLineNo = sourceLineNo,
+                TargetLineNo = task.TargetAddress,
+                SourcePalletNo = string.Empty,
+                TargetPalletNo = string.Empty
+            };
+            return ReceiveWMSTask(wMSTask, stockDto);
+        }
+
+        /// <summary>
+        /// 璇诲彇鎸囧畾绾夸綋鐨勬墭鐩樺彿銆�
+        /// </summary>
+        /// <param name="sourceLineNo">婧愮嚎浣撶紪鍙�</param>
+        /// <returns>鎵樼洏鍙凤紝濡傛湁寮傚父杩斿洖 null</returns>
+        private string? ReadLineBarcode(string sourceLineNo)
+        {
+            try
+            {
+                IDevice? device = Storage.Devices.FirstOrDefault(x =>
+                    x.DeviceProDTOs.Any(d => d.DeviceChildCode == sourceLineNo));
+
+                if (device == null)
+                    return null;
+
+                CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
+                return conveyorLine.GetValue<ConveyorLineDBNameNew, string>(
+                    ConveyorLineDBNameNew.Barcode, sourceLineNo);
+            }
+            catch (Exception ex)
+            {
+                _logger.Error(ex, $"璇诲彇绾夸綋[{sourceLineNo}]鎵樼洏鍙峰紓甯�");
+                return null;
+            }
+        }
+
+        /// <summary>
         /// 鑾峰彇鏈烘鎵嬩换鍔℃�绘暟閲忋��
         /// 缁勭洏浠诲姟鍥哄畾48锛屾崲鐩樺拰鎷嗙洏浠诲姟閫氳繃鎵樼洏鍙锋煡璇MS搴撳瓨鏄庣粏鏁伴噺銆�
         /// </summary>
-        private int GetRobotTaskTotalNum(int taskType, string? palletCode)
+        public int GetRobotTaskTotalNum(int taskType, string? palletCode)
         {
             if (taskType == (int)RobotTaskTypeEnum.GroupPallet)
                 return 48;
@@ -253,8 +356,10 @@
 
             try
             {
+                QuartzLogHelper.LogInfo(_logger, $"寮�濮嬭皟鐢╓MS鎺ュ彛鑾峰彇搴撳瓨鏄庣粏鏁伴噺,鎵樼洏鍙�:銆恵palletCode}銆�", "RobotTaskService");
                 string url = $"{BaseAPI.WMSBaseUrl}Stock/GetStockDetailCount?palletCode={Uri.EscapeDataString(palletCode)}";
                 var result = _httpClientHelper.Get(url);
+                QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鑾峰彇搴撳瓨鏄庣粏鏁伴噺鎺ュ彛,璇锋眰URL:銆恵url}銆�,鍝嶅簲鏁版嵁:銆恵result.Content}銆�,鑰楁椂:{result.Duration}ms", "RobotTaskService");
                 if (!result.IsSuccess || string.IsNullOrEmpty(result.Content))
                     return 1;
 
@@ -262,8 +367,8 @@
                 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;
+                var detailCount = (response.Data as JObject)?["detailCount"]?.Value<int>();
+                return detailCount.HasValue && detailCount.Value > 0 ? detailCount.Value : 1;
             }
             catch
             {
@@ -368,8 +473,10 @@
                     CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
 
                     DeviceProDTO? devicePro = conveyorLine.DeviceProDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(ConveyorLineDBNameNew.Barcode) && x.DeviceChildCode == sourceLineNo);
+                    //conveyorLine.Communicator.Read(devicePro.DeviceProAddress, 20);
                     //ConveyorLineTaskCommandNew command = conveyorLine.ReadCustomer<ConveyorLineTaskCommandNew>(sourceLineNo);  // 娴嬭瘯鐢�
-                    var barcode = conveyorLine.GetValue<ConveyorLineDBNameNew, string>(ConveyorLineDBNameNew.Barcode, sourceLineNo);
+                    var bytes = conveyorLine.Communicator.Read(devicePro.DeviceProAddress, 20);
+                    var barcode = Encoding.Default.GetString(bytes).Trim();
                     stock.SourcePalletNo = string.IsNullOrEmpty(barcode) ? string.Empty : barcode;
                 }
             }
@@ -448,5 +555,82 @@
                 .Where(x => !string.IsNullOrWhiteSpace(x.Key) && !string.IsNullOrWhiteSpace(x.Value))
                 .ToDictionary(x => x.Key.Trim(), x => x.Value!.Trim());
         }
+
+        public WebResponseContent CreateRobotTaskManually(ManualRobotTaskDto request)
+        {
+            try
+            {
+                Dt_RobotTask robotTask = new Dt_RobotTask();
+                robotTask.RobotTaskNum = Random.Shared.StrictNext();
+                robotTask.RobotRoadway = request.RobotRoadway;
+                if (request.RobotRoadway == RobotTaskTypeEnum.GroupPallet.ToString())
+                {
+                    robotTask.RobotTaskType = (int)RobotTaskTypeEnum.GroupPallet;
+                    robotTask.RobotTaskState = (int)TaskRobotStatusEnum.RobotNew;
+                    robotTask.RobotTaskTotalNum = request.RobotTaskTotalNum;
+                    robotTask.RobotDispatchertime = DateTime.Now;
+                    robotTask.RobotRemark = "浜哄伐鎵嬪姩鍒涘缓";
+                    robotTask.RobotTargetAddressPalletCode = request.RobotTargetAddressPalletCode;
+                    robotTask.RobotTargetAddressLineCode = "11068";
+                }
+                else if (request.RobotRoadway == RobotTaskTypeEnum.ChangePallet.ToString())
+                {
+                    switch (request.Forward)
+                    {
+                        case 1:
+                            robotTask.RobotSourceAddress = "1";
+                            robotTask.RobotSourceAddressLineCode = "11010";
+                            robotTask.RobotTargetAddress = "3";
+                            robotTask.RobotTargetAddressLineCode = "2103";
+                            break;
+                        case 2:
+                            robotTask.RobotSourceAddress = "2";
+                            robotTask.RobotSourceAddressLineCode = "11001";
+                            robotTask.RobotTargetAddress = "4";
+                            robotTask.RobotTargetAddressLineCode = "2101";
+                            break;
+                        case 3:
+                            robotTask.RobotSourceAddress = "3";
+                            robotTask.RobotSourceAddressLineCode = "2103";
+                            robotTask.RobotTargetAddress = "1";
+                            robotTask.RobotTargetAddressLineCode = "11010";
+                            break;
+                        case 4:
+                            robotTask.RobotSourceAddress = "4";
+                            robotTask.RobotSourceAddressLineCode = "2101";
+                            robotTask.RobotTargetAddress = "2";
+                            robotTask.RobotTargetAddressLineCode = "11001";
+                            break;
+                        default:
+                            return WebResponseContent.Instance.Error($"娣诲姞鏈哄櫒浜轰换鍔″け璐�,鏂瑰悜涓嶅");
+                    }
+                    robotTask.RobotTaskType = (int)RobotTaskTypeEnum.ChangePallet;
+                    robotTask.RobotTaskState = (int)TaskRobotStatusEnum.RobotNew;
+                    robotTask.RobotTaskTotalNum = request.RobotTaskTotalNum;
+                    robotTask.RobotDispatchertime = DateTime.Now;
+                    robotTask.RobotRemark = "浜哄伐鎵嬪姩鍒涘缓";
+                    robotTask.RobotSourceAddressPalletCode = request.RobotSourceAddressPalletCode;
+                    robotTask.RobotTargetAddressPalletCode = request.RobotTargetAddressPalletCode;
+                }
+                else if (request.RobotRoadway == RobotTaskTypeEnum.SplitPallet.ToString())
+                {
+                    robotTask.RobotTaskType = (int)RobotTaskTypeEnum.SplitPallet;
+                    robotTask.RobotTaskState = (int)TaskRobotStatusEnum.RobotNew;
+                    robotTask.RobotTaskTotalNum = request.RobotTaskTotalNum;
+                    robotTask.RobotDispatchertime = DateTime.Now;
+                    robotTask.RobotRemark = "浜哄伐鎵嬪姩鍒涘缓";
+                    robotTask.RobotSourceAddressPalletCode = request.RobotSourceAddressPalletCode;
+                }
+                else
+                {
+                    return WebResponseContent.Instance.Error($"娣诲姞鏈哄櫒浜轰换鍔″け璐ワ紝鏈哄櫒浜哄悕绉伴敊璇瘂request.RobotRoadway}");
+                }
+                return base.AddData(robotTask);
+            }
+            catch (Exception ex)
+            {
+                return WebResponseContent.Instance.Error($"娣诲姞鏈哄櫒浜轰换鍔″け璐�: {ex.Message}");
+            }
+        }
     }
 }
\ No newline at end of file

--
Gitblit v1.9.3