From 853f7a71577bd8694c848985e1eb21c74d30eba9 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期二, 21 四月 2026 21:19:23 +0800
Subject: [PATCH] fix(WCS): 修复输送线任务处理逻辑并更新设备映射

---
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs |  134 +++++++++++++++++++++++++++++++++-----------
 1 files changed, 100 insertions(+), 34 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs
index b92261d..96be485 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs
@@ -1,15 +1,15 @@
-using Microsoft.Extensions.Logging;
 using Newtonsoft.Json;
+using Serilog;
 using System.Diagnostics.CodeAnalysis;
 using WIDESEA_Core;
 using WIDESEAWCS_Common.Constants;
 using WIDESEAWCS_Common.HttpEnum;
 using WIDESEAWCS_Common.TaskEnum;
 using WIDESEAWCS_Core;
-using WIDESEAWCS_Core.LogHelper;
 using WIDESEAWCS_ITaskInfoService;
 using WIDESEAWCS_Model.Models;
 using WIDESEAWCS_QuartzJob;
+using WIDESEAWCS_QuartzJob.ConveyorLine.Enum;
 using WIDESEAWCS_QuartzJob.Models;
 using WIDESEAWCS_QuartzJob.Service;
 
@@ -63,7 +63,7 @@
         /// <param name="httpClientHelper">HTTP 瀹㈡埛绔府鍔╃被</param>
         /// <param name="logger">鏃ュ織璁板綍鍣�</param>
         public StackerCraneTaskSelector(ITaskService taskService, IRouterService routerService, HttpClientHelper httpClientHelper, ILogger logger)
-            : this(taskService, routerService, taskNum => QueryTransferTask(httpClientHelper, taskNum), logger)
+            : this(taskService, routerService, taskNum => QueryTransferTask(httpClientHelper, taskNum, logger), logger)
         {
         }
 
@@ -101,16 +101,14 @@
             Dt_Task? candidateTask;
             var deviceCode = commonStackerCrane.DeviceCode;
 
-            //_logger.LogInformation("SelectTask锛氬紑濮嬮�夋嫨浠诲姟锛岃澶�: {DeviceCode}锛屼笂涓�浠诲姟绫诲瀷: {LastTaskType}", deviceCode, commonStackerCrane.LastTaskType);
-            //QuartzLogger.Info($"寮�濮嬮�夋嫨浠诲姟锛岃澶�: {deviceCode}锛屼笂涓�浠诲姟绫诲瀷: {commonStackerCrane.LastTaskType}", deviceCode);
+            QuartzLogHelper.LogDebug(_logger, $"寮�濮嬮�夋嫨浠诲姟锛岃澶�: {deviceCode}锛屼笂涓�浠诲姟绫诲瀷: {commonStackerCrane.LastTaskType}",commonStackerCrane.DeviceName);
 
             // 鏍规嵁涓婁竴浠诲姟绫诲瀷鍐冲畾鏌ヨ绛栫暐
             if (commonStackerCrane.LastTaskType == null || commonStackerCrane.LastTaskType == TaskRelocationTypeEnum.Relocation.GetHashCode())
             {
                 // 娌℃湁涓婁竴浠诲姟绫诲瀷锛屾煡璇㈡櫘閫氫换鍔�
                 candidateTask = _taskService.QueryStackerCraneTask(deviceCode);
-                _logger.LogDebug("SelectTask锛氭煡璇㈡櫘閫氫换鍔★紝璁惧: {DeviceCode}锛岀粨鏋�: {TaskNum}", deviceCode, candidateTask?.TaskNum);
-                QuartzLogger.Debug($"鏌ヨ鏅�氫换鍔★紝璁惧: {deviceCode}锛岀粨鏋�: {candidateTask?.TaskNum}", deviceCode);
+                QuartzLogHelper.LogDebug(_logger, $"鏌ヨ鏅�氫换鍔★紝璁惧: {deviceCode}锛岀粨鏋�: {candidateTask?.TaskNum}", commonStackerCrane.DeviceName);
             }
             else if (commonStackerCrane.LastTaskType.GetValueOrDefault().GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
             {
@@ -118,30 +116,26 @@
                 candidateTask = _taskService.QueryStackerCraneInTask(deviceCode);
                 // 濡傛灉娌℃湁鍏ュ簱浠诲姟锛屽啀鏌ヤ竴涓嬪嚭搴撲换鍔�
                 candidateTask ??= _taskService.QueryStackerCraneOutTask(deviceCode);
-                _logger.LogDebug("SelectTask锛氬嚭搴撳悗浼樺厛鏌ュ叆搴擄紝璁惧: {DeviceCode}锛岀粨鏋�: {TaskNum}", deviceCode, candidateTask?.TaskNum);
-                QuartzLogger.Debug($"鍑哄簱鍚庝紭鍏堟煡鍏ュ簱锛岃澶�: {deviceCode}锛岀粨鏋�: {candidateTask?.TaskNum}", deviceCode);
+                QuartzLogHelper.LogDebug(_logger, $"鍑哄簱鍚庝紭鍏堟煡鍏ュ簱锛岃澶�: {deviceCode}锛岀粨鏋�: {candidateTask?.TaskNum}", commonStackerCrane.DeviceName);
             }
             else
             {
                 // 涓婁竴浠诲姟鏄叆搴擄紙闈炲嚭搴擄級锛屼紭鍏堟煡鍑哄簱浠诲姟
                 candidateTask = _taskService.QueryStackerCraneOutTask(deviceCode);
-                _logger.LogDebug("SelectTask锛氬叆搴撳悗浼樺厛鏌ュ嚭搴擄紝璁惧: {DeviceCode}锛岀粨鏋�: {TaskNum}", deviceCode, candidateTask?.TaskNum);
-                QuartzLogger.Debug($"鍏ュ簱鍚庝紭鍏堟煡鍑哄簱锛岃澶�: {deviceCode}锛岀粨鏋�: {candidateTask?.TaskNum}", deviceCode);
+                QuartzLogHelper.LogDebug(_logger, $"鍏ュ簱鍚庝紭鍏堟煡鍑哄簱锛岃澶�: {deviceCode}锛岀粨鏋�: {candidateTask?.TaskNum}", commonStackerCrane.DeviceName);
             }
 
             // 濡傛灉娌℃湁鍊欓�変换鍔★紝杩斿洖 null
             if (candidateTask == null)
             {
-                _logger.LogDebug("SelectTask锛氭病鏈夊�欓�変换鍔★紝璁惧: {DeviceCode}", deviceCode);
-                QuartzLogger.Debug($"娌℃湁鍊欓�変换鍔★紝璁惧: {deviceCode}", deviceCode);
+                QuartzLogHelper.LogDebug(_logger, $"娌℃湁鍊欓�変换鍔★紝璁惧: {deviceCode}", commonStackerCrane.DeviceName);
                 return null;
             }
 
             // 濡傛灉涓嶆槸鍑哄簱浠诲姟锛岀洿鎺ヨ繑鍥�
             if (candidateTask.TaskType.GetTaskTypeGroup() != TaskTypeGroup.OutbondGroup)
             {
-                _logger.LogInformation("SelectTask锛氶�変腑闈炲嚭搴撲换鍔★紝璁惧: {DeviceCode}锛屼换鍔″彿: {TaskNum}锛屼换鍔$被鍨�: {TaskType}", deviceCode, candidateTask.TaskNum, candidateTask.TaskType);
-                QuartzLogger.Info($"閫変腑闈炲嚭搴撲换鍔★紝浠诲姟鍙�: {candidateTask.TaskNum}锛屼换鍔$被鍨�: {candidateTask.TaskType}", deviceCode);
+                QuartzLogHelper.LogDebug(_logger, $"閫変腑闈炲嚭搴撲换鍔★紝浠诲姟鍙�: {candidateTask.TaskNum}锛屼换鍔$被鍨�: {candidateTask.TaskType}", commonStackerCrane.DeviceName);
                 return candidateTask;
             }
 
@@ -149,11 +143,27 @@
             Dt_Task? selectedTask = TrySelectOutboundTask(candidateTask);
             if (selectedTask != null)
             {
-                _logger.LogInformation("SelectTask锛氶�変腑鍑哄簱浠诲姟锛岃澶�: {DeviceCode}锛屼换鍔″彿: {TaskNum}", deviceCode, selectedTask.TaskNum);
-                QuartzLogger.Info($"閫変腑鍑哄簱浠诲姟锛屼换鍔″彿: {selectedTask.TaskNum}", deviceCode);
+                QuartzLogHelper.LogDebug(_logger, $"閫変腑鍑哄簱浠诲姟锛屼换鍔″彿: {selectedTask.TaskNum}", commonStackerCrane.DeviceName);
                 return selectedTask;
             }
 
+            // ===== TargetAddress 涓嶅彲鐢ㄦ椂锛屽厛灏濊瘯鍚� NextAddress 鐨勫叾浠栦换鍔� =====
+            var sameStationTasks = _taskService
+                .QueryStackerCraneOutTasks(deviceCode, new List<string> { candidateTask.NextAddress })
+                .Where(x => x.TaskId != candidateTask.TaskId)
+                .ToList();
+
+            foreach (var sameStationTask in sameStationTasks)
+            {
+                selectedTask = TrySelectOutboundTask(sameStationTask);
+                if (selectedTask != null)
+                {
+                    QuartzLogHelper.LogDebug(_logger, $"閫変腑鍚岀珯鍙板閫夊嚭搴撲换鍔★紝浠诲姟鍙�: {selectedTask.TaskNum}", commonStackerCrane.DeviceName);
+                    return selectedTask;
+                }
+            }
+
+            // ===== 鍚� NextAddress 鏃犲彲鐢ㄤ换鍔★紝灏濊瘯涓嶅悓 NextAddress 鐨勪换鍔� =====
             // 鏌ユ壘鍏朵粬鍙敤鐨勫嚭搴撶珯鍙�
             var otherOutStationCodes = _routerService
                 .QueryNextRoutes(deviceCode, candidateTask.NextAddress, candidateTask.TaskType)
@@ -167,16 +177,14 @@
                 selectedTask = TrySelectOutboundTask(alternativeTask);
                 if (selectedTask != null)
                 {
-                    _logger.LogInformation("SelectTask锛氶�変腑澶囬�夊嚭搴撲换鍔★紝璁惧: {DeviceCode}锛屼换鍔″彿: {TaskNum}", deviceCode, selectedTask.TaskNum);
-                    QuartzLogger.Info($"閫変腑澶囬�夊嚭搴撲换鍔★紝浠诲姟鍙�: {selectedTask.TaskNum}", deviceCode);
+                    QuartzLogHelper.LogDebug(_logger, $"閫変腑澶囬�夊嚭搴撲换鍔★紝浠诲姟鍙�: {selectedTask.TaskNum}", commonStackerCrane.DeviceName);
                     return selectedTask;
                 }
             }
 
             // 娌℃湁鍙敤鍑哄簱浠诲姟锛屽皾璇曡繑鍥炲叆搴撲换鍔�
             var inboundTask = _taskService.QueryStackerCraneInTask(deviceCode);
-            _logger.LogInformation("SelectTask锛氳繑鍥炲叆搴撲换鍔★紝璁惧: {DeviceCode}锛屼换鍔″彿: {TaskNum}", deviceCode, inboundTask?.TaskNum);
-            QuartzLogger.Info($"杩斿洖鍏ュ簱浠诲姟锛屼换鍔″彿: {inboundTask?.TaskNum}", deviceCode);
+            QuartzLogHelper.LogDebug(_logger, $"杩斿洖鍏ュ簱浠诲姟锛屼换鍔″彿: {inboundTask?.TaskNum}", commonStackerCrane.DeviceName);
             return inboundTask;
         }
 
@@ -194,7 +202,21 @@
         /// <returns>鍙�変腑鐨勪换鍔★紝鎴� null锛堢珯鍙颁笉鍙敤锛�</returns>
         private Dt_Task? TrySelectOutboundTask(Dt_Task outboundTask)
         {
-            // 瀵逛簬鎵�鏈夊嚭搴撲换鍔★紝蹇呴』鍏堣皟鐢� WMS 鍒ゆ柇鏄惁闇�瑕佺Щ搴�
+            // 鍏堣繘琛屾湰鍦扮珯鍙版鏌ワ紙PLC 璇诲彇锛屽揩閫燂級锛岄伩鍏嶄笉蹇呰鐨� WMS HTTP 璋冪敤
+
+            // 鍒ゆ柇 TargetAddress 杈撻�佺嚎绔欏彴鏄惁绌洪棽
+            if (!IsTargetAddressConveyorStationAvailable(outboundTask))
+            {
+                return null;
+            }
+
+            // 鍒ゆ柇 NextAddress 鍑哄簱绔欏彴鏄惁鍙敤
+            if (!IsOutTaskStationAvailable(outboundTask))
+            {
+                return null;
+            }
+
+            // 绔欏彴妫�鏌ラ�氳繃鍚庯紝璋冪敤 WMS 鍒ゆ柇鏄惁闇�瑕佺Щ搴�
             var taskAfterTransferCheck = _transferCheck(outboundTask.TaskNum) ?? outboundTask;
             var taskGroup = taskAfterTransferCheck.TaskType.GetTaskTypeGroup();
 
@@ -216,8 +238,7 @@
                 return taskAfterTransferCheck;
             }
 
-            // 鍒ゆ柇鍑哄簱绔欏彴鏄惁鍙敤
-            return IsOutTaskStationAvailable(taskAfterTransferCheck) ? taskAfterTransferCheck : null;
+            return taskAfterTransferCheck;
         }
 
         /// <summary>
@@ -229,18 +250,24 @@
         /// <param name="httpClientHelper">HTTP 瀹㈡埛绔府鍔╃被</param>
         /// <param name="taskNum">浠诲姟鍙�</param>
         /// <returns>濡傛灉闇�瑕佺Щ搴撹繑鍥炵Щ搴撲换鍔★紝鍚﹀垯杩斿洖 null</returns>
-        private static Dt_Task? QueryTransferTask(HttpClientHelper httpClientHelper, int taskNum)
+        private static Dt_Task? QueryTransferTask(HttpClientHelper httpClientHelper, int taskNum, ILogger logger)
         {
             // 璋冪敤 WMS 鐨勭Щ搴撴鏌ユ帴鍙�
+            string configKey = nameof(ConfigKey.TransferCheck);
+            string requestParam = taskNum.ToString();
+
             var response = httpClientHelper.Post<WebResponseContent>(
-                nameof(ConfigKey.TransferCheck),
-                taskNum.ToString());
+                configKey,
+                requestParam);
 
             // 妫�鏌ュ搷搴旀槸鍚︽垚鍔�
             if (response == null || !response.IsSuccess || response.Data == null || !response.Data.Status || response.Data.Data == null)
             {
+                QuartzLogHelper.LogError(logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵(response?.Data?.Message ?? "鏃犲搷搴�")}銆�", "StackerCraneTaskSelector");
                 return null;
             }
+
+            QuartzLogHelper.LogInfo(logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵response.Data.Data}銆�", "StackerCraneTaskSelector");
 
             // 瑙f瀽杩斿洖鐨勪换鍔℃暟鎹�
             var taskJson = response.Data.Data.ToString();
@@ -299,8 +326,7 @@
             if (router == null)
             {
                 // 鏈壘鍒扮珯鍙拌矾鐢变俊鎭�
-                _logger.LogWarning("IsOutTaskStationAvailable锛氭湭鎵惧埌绔欏彴璺敱淇℃伅锛岀珯鍙�: {NextAddress}锛屼换鍔″彿: {TaskNum}", task.NextAddress, task.TaskNum);
-                QuartzLogger.Warn($"IsOutTaskStationAvailable锛氭湭鎵惧埌绔欏彴璺敱淇℃伅锛岀珯鍙�: {task.NextAddress}", task.Roadway);
+                QuartzLogHelper.LogWarn(_logger, "IsOutTaskStationAvailable锛氭湭鎵惧埌绔欏彴璺敱淇℃伅锛岀珯鍙�: {NextAddress}锛屼换鍔″彿: {TaskNum}", $"IsOutTaskStationAvailable锛氭湭鎵惧埌绔欏彴璺敱淇℃伅锛岀珯鍙�: {task.NextAddress}", task.Roadway, task.NextAddress, task.TaskNum);
                 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒扮珯鍙般�恵task.NextAddress}銆戜俊鎭紝鏃犳硶鏍¢獙绔欏彴");
                 return false;
             }
@@ -310,8 +336,7 @@
             if (device == null)
             {
                 // 鏈壘鍒拌澶�
-                _logger.LogWarning("IsOutTaskStationAvailable锛氭湭鎵惧埌鍑哄簱绔欏彴瀵瑰簲鐨勯�氳瀵硅薄锛岀珯鍙�: {ChildPosiDeviceCode}锛屼换鍔″彿: {TaskNum}", router.ChildPosiDeviceCode, task.TaskNum);
-                QuartzLogger.Warn($"IsOutTaskStationAvailable锛氭湭鎵惧埌鍑哄簱绔欏彴瀵瑰簲鐨勯�氳瀵硅薄锛岀珯鍙�: {router.ChildPosiDeviceCode}", task.Roadway);
+                QuartzLogHelper.LogWarn(_logger, "IsOutTaskStationAvailable锛氭湭鎵惧埌鍑哄簱绔欏彴瀵瑰簲鐨勯�氳瀵硅薄锛岀珯鍙�: {ChildPosiDeviceCode}锛屼换鍔″彿: {TaskNum}", $"IsOutTaskStationAvailable锛氭湭鎵惧埌鍑哄簱绔欏彴瀵瑰簲鐨勯�氳瀵硅薄锛岀珯鍙�: {router.ChildPosiDeviceCode}", task.Roadway, router.ChildPosiDeviceCode, task.TaskNum);
                 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"鏈壘鍒板嚭搴撶珯鍙般�恵router.ChildPosiDeviceCode}銆戝搴旂殑閫氳瀵硅薄锛屾棤娉曞垽鏂嚭搴撶珯鍙版槸鍚﹁鍗犵敤");
                 return false;
             }
@@ -321,10 +346,51 @@
 
             // 妫�鏌ョ珯鍙版槸鍚﹁鍗犵敤
             bool isOccupied = conveyorLine.IsOccupied(router.ChildPosi);
-            _logger.LogInformation("IsOutTaskStationAvailable锛氱珯鍙� {ChildPosi}锛屾槸鍚﹁鍗犵敤: {IsOccupied}锛屼换鍔″彿: {TaskNum}", router.ChildPosi, !isOccupied, task.TaskNum);
-            QuartzLogger.Info($"IsOutTaskStationAvailable锛氱珯鍙� {router.ChildPosi}锛屾槸鍚﹁鍗犵敤: {!isOccupied}", task.Roadway);
+            QuartzLogHelper.LogInfo(_logger, "IsOutTaskStationAvailable锛氱珯鍙� {ChildPosi}锛屾槸鍚﹁鍗犵敤: {IsOccupied}锛屼换鍔″彿: {TaskNum}", $"IsOutTaskStationAvailable锛氱珯鍙� {router.ChildPosi}锛屾槸鍚﹁鍗犵敤: {!isOccupied}", task.Roadway, router.ChildPosi, !isOccupied, task.TaskNum);
 
             return isOccupied;
         }
+
+        /// <summary>
+        /// 鍒ゆ柇 TargetAddress 杈撻�佺嚎绔欏彴鏄惁绌洪棽
+        /// </summary>
+        /// <param name="task">鍑哄簱浠诲姟</param>
+        /// <returns>绔欏彴绌洪棽锛圕V_State == 2锛夎繑鍥� true</returns>
+        private bool IsTargetAddressConveyorStationAvailable([NotNull] Dt_Task task)
+        {
+            // 纭畾浠诲姟绫诲瀷
+            int taskType = task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty
+                ? StackerCraneConst.EmptyPalletTaskType
+                : task.TaskType;
+
+            // 閫氳繃璺敱鏌ユ壘 TargetAddress 瀵瑰簲鐨勮澶囦俊鎭�
+            Dt_Router? router = _routerService.QueryNextRoute(task.Roadway, task.TargetAddress, taskType);
+            if (router == null)
+            {
+                QuartzLogHelper.LogWarn(_logger, "IsTargetAddressConveyorStationAvailable锛氭湭鎵惧埌 TargetAddress 璺敱淇℃伅锛孴argetAddress: {TargetAddress}锛屼换鍔″彿: {TaskNum}",
+                    $"IsTargetAddressConveyorStationAvailable锛氭湭鎵惧埌 TargetAddress 璺敱淇℃伅锛孴argetAddress: {task.TargetAddress}", task.Roadway, task.TargetAddress, task.TaskNum);
+                return false;
+            }
+
+            // 鏌ユ壘杈撻�佺嚎璁惧
+            IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == router.ChildPosiDeviceCode);
+            if (device == null)
+            {
+                QuartzLogHelper.LogWarn(_logger, "IsTargetAddressConveyorStationAvailable锛氭湭鎵惧埌杈撻�佺嚎璁惧锛孋hildPosiDeviceCode: {ChildPosiDeviceCode}锛屼换鍔″彿: {TaskNum}",
+                    $"IsTargetAddressConveyorStationAvailable锛氭湭鎵惧埌杈撻�佺嚎璁惧锛孋hildPosiDeviceCode: {router.ChildPosiDeviceCode}", task.Roadway, router.ChildPosiDeviceCode, task.TaskNum);
+                return false;
+            }
+
+            // 杞崲涓鸿緭閫佺嚎璁惧
+            CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
+
+            // 璇诲彇 CV_State锛孋V_State == 2 琛ㄧず绌洪棽
+            byte cvState = conveyorLine.GetValue<ConveyorLineDBNameNew, byte>(ConveyorLineDBNameNew.CV_State, task.TargetAddress);
+            bool isAvailable = cvState == 2;
+            QuartzLogHelper.LogInfo(_logger, "IsTargetAddressConveyorStationAvailable锛歍argetAddress: {TargetAddress}锛孋V_State: {CV_State}锛屾槸鍚︾┖闂�: {IsAvailable}锛屼换鍔″彿: {TaskNum}",
+                $"IsTargetAddressConveyorStationAvailable锛歍argetAddress: {task.TargetAddress}锛孋V_State: {cvState}锛屾槸鍚︾┖闂�: {isAvailable}", task.Roadway, task.TargetAddress, cvState, isAvailable, task.TaskNum);
+
+            return isAvailable;
+        }
     }
-}
+}
\ No newline at end of file

--
Gitblit v1.9.3