wanshenmean
5 小时以前 e4921e003cc293fea714bdaf74dc6a6b6b750295
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs
@@ -1,6 +1,7 @@
using Newtonsoft.Json;
using Serilog;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using WIDESEA_Core;
using WIDESEAWCS_Common.Constants;
using WIDESEAWCS_Common.HttpEnum;
@@ -101,14 +102,14 @@
            Dt_Task? candidateTask;
            var deviceCode = commonStackerCrane.DeviceCode;
            QuartzLogHelper.LogDebug(_logger, $"开始选择任务,设备: {deviceCode},上一任务类型: {commonStackerCrane.LastTaskType}",commonStackerCrane.DeviceName);
            QuartzLogHelper.LogInfo(_logger, $"开始选择任务,设备: {deviceCode},上一任务类型: {commonStackerCrane.LastTaskType}", commonStackerCrane.DeviceName);
            // 根据上一任务类型决定查询策略
            if (commonStackerCrane.LastTaskType == null || commonStackerCrane.LastTaskType == TaskRelocationTypeEnum.Relocation.GetHashCode())
            {
                // 没有上一任务类型,查询普通任务
                candidateTask = _taskService.QueryStackerCraneTask(deviceCode);
                QuartzLogHelper.LogDebug(_logger, $"查询普通任务,设备: {deviceCode},结果: {candidateTask?.TaskNum}", commonStackerCrane.DeviceName);
                QuartzLogHelper.LogInfo(_logger, $"查询普通任务,设备: {deviceCode},结果: {candidateTask?.TaskNum}", commonStackerCrane.DeviceName);
            }
            else if (commonStackerCrane.LastTaskType.GetValueOrDefault().GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
            {
@@ -116,26 +117,29 @@
                candidateTask = _taskService.QueryStackerCraneInTask(deviceCode);
                // 如果没有入库任务,再查一下出库任务
                candidateTask ??= _taskService.QueryStackerCraneOutTask(deviceCode);
                QuartzLogHelper.LogDebug(_logger, $"出库后优先查入库,设备: {deviceCode},结果: {candidateTask?.TaskNum}", commonStackerCrane.DeviceName);
                QuartzLogHelper.LogInfo(_logger, $"出库后优先查入库,设备: {deviceCode},结果: {candidateTask?.TaskNum}", commonStackerCrane.DeviceName);
            }
            else
            {
                // 上一任务是入库(非出库),优先查出库任务
                candidateTask = _taskService.QueryStackerCraneOutTask(deviceCode);
                QuartzLogHelper.LogDebug(_logger, $"入库后优先查出库,设备: {deviceCode},结果: {candidateTask?.TaskNum}", commonStackerCrane.DeviceName);
                // 如果没有出库任务,再查一下入库任务
                candidateTask ??= _taskService.QueryStackerCraneInTask(deviceCode);
                QuartzLogHelper.LogInfo(_logger, $"入库后优先查出库,设备: {deviceCode},结果: {candidateTask?.TaskNum}", commonStackerCrane.DeviceName);
            }
            // 如果没有候选任务,返回 null
            if (candidateTask == null)
            {
                QuartzLogHelper.LogDebug(_logger, $"没有候选任务,设备: {deviceCode}", commonStackerCrane.DeviceName);
                QuartzLogHelper.LogInfo(_logger, $"没有候选任务,设备: {deviceCode}", commonStackerCrane.DeviceName);
                return null;
            }
            // 如果不是出库任务,直接返回
            if (candidateTask.TaskType.GetTaskTypeGroup() != TaskTypeGroup.OutbondGroup)
            {
                QuartzLogHelper.LogDebug(_logger, $"选中非出库任务,任务号: {candidateTask.TaskNum},任务类型: {candidateTask.TaskType}", commonStackerCrane.DeviceName);
                QuartzLogHelper.LogInfo(_logger, $"选中非出库任务,任务号: {candidateTask.TaskNum},任务类型: {candidateTask.TaskType}", commonStackerCrane.DeviceName);
                return candidateTask;
            }
@@ -143,14 +147,14 @@
            Dt_Task? selectedTask = TrySelectOutboundTask(candidateTask);
            if (selectedTask != null)
            {
                QuartzLogHelper.LogDebug(_logger, $"选中出库任务,任务号: {selectedTask.TaskNum}", commonStackerCrane.DeviceName);
                QuartzLogHelper.LogInfo(_logger, $"选中出库任务,任务号: {selectedTask.TaskNum}", commonStackerCrane.DeviceName);
                return selectedTask;
            }
            // ===== TargetAddress 不可用时,先尝试同 NextAddress 的其他任务 =====
            // ===== TargetAddress 不可用时,先尝试同 NextAddress不同TargetAddress 的其他任务 =====
            var sameStationTasks = _taskService
                .QueryStackerCraneOutTasks(deviceCode, new List<string> { candidateTask.NextAddress })
                .Where(x => x.TaskId != candidateTask.TaskId)
                .Where(x => x.TaskId != candidateTask.TaskId && x.TargetAddress != candidateTask.TargetAddress)
                .ToList();
            foreach (var sameStationTask in sameStationTasks)
@@ -158,33 +162,28 @@
                selectedTask = TrySelectOutboundTask(sameStationTask);
                if (selectedTask != null)
                {
                    QuartzLogHelper.LogDebug(_logger, $"选中同站台备选出库任务,任务号: {selectedTask.TaskNum}", commonStackerCrane.DeviceName);
                    QuartzLogHelper.LogInfo(_logger, $"选中同站台备选出库任务,任务号: {selectedTask.TaskNum}", commonStackerCrane.DeviceName);
                    return selectedTask;
                }
            }
            // ===== 同 NextAddress 无可用任务,尝试不同 NextAddress 的任务 =====
            // 查找其他可用的出库站台
            var otherOutStationCodes = _routerService
                .QueryNextRoutes(deviceCode, candidateTask.NextAddress, candidateTask.TaskType)
                .Select(x => x.ChildPosi)
                .ToList();
            // 查询其他站台的出库任务
            var tasks = _taskService.QueryStackerCraneOutTasks(deviceCode, otherOutStationCodes);
            var tasks = _taskService.QueryStackerCraneOutTasks(deviceCode, new List<string> { candidateTask.NextAddress }, false);
            foreach (var alternativeTask in tasks)
            {
                selectedTask = TrySelectOutboundTask(alternativeTask);
                if (selectedTask != null)
                {
                    QuartzLogHelper.LogDebug(_logger, $"选中备选出库任务,任务号: {selectedTask.TaskNum}", commonStackerCrane.DeviceName);
                    QuartzLogHelper.LogInfo(_logger, $"选中备选出库任务,任务号: {selectedTask.TaskNum}", commonStackerCrane.DeviceName);
                    return selectedTask;
                }
            }
            // 没有可用出库任务,尝试返回入库任务
            var inboundTask = _taskService.QueryStackerCraneInTask(deviceCode);
            QuartzLogHelper.LogDebug(_logger, $"返回入库任务,任务号: {inboundTask?.TaskNum}", commonStackerCrane.DeviceName);
            QuartzLogHelper.LogInfo(_logger, $"返回入库任务,任务号: {inboundTask?.TaskNum}", commonStackerCrane.DeviceName);
            return inboundTask;
        }
@@ -213,6 +212,14 @@
            // 判断 NextAddress 出库站台是否可用
            if (!IsOutTaskStationAvailable(outboundTask))
            {
                return null;
            }
            // 检查是否有正在执行的输送线任务去往同一 TargetAddress
            if (_taskService.HasExecutingTaskToTarget(outboundTask.Roadway, outboundTask.TargetAddress))
            {
                QuartzLogHelper.LogInfo(_logger, "TrySelectOutboundTask:TargetAddress: {TargetAddress} 已有正在执行的输送线任务,任务号: {TaskNum}",
                    $"TrySelectOutboundTask:TargetAddress: {outboundTask.TargetAddress} 已有正在执行的输送线任务", outboundTask.Roadway, outboundTask.TargetAddress, outboundTask.TaskNum);
                return null;
            }
@@ -385,7 +392,7 @@
            CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
            // 读取 CV_State,CV_State == 2 表示空闲
            byte cvState = conveyorLine.GetValue<ConveyorLineStatus, byte>(ConveyorLineStatus.CV_State, task.TargetAddress);
            byte cvState = conveyorLine.GetValue<ConveyorLineDBNameNew, byte>(ConveyorLineDBNameNew.CV_State, task.TargetAddress);
            bool isAvailable = cvState == 2;
            QuartzLogHelper.LogInfo(_logger, "IsTargetAddressConveyorStationAvailable:TargetAddress: {TargetAddress},CV_State: {CV_State},是否空闲: {IsAvailable},任务号: {TaskNum}",
                $"IsTargetAddressConveyorStationAvailable:TargetAddress: {task.TargetAddress},CV_State: {cvState},是否空闲: {isAvailable}", task.Roadway, task.TargetAddress, cvState, isAvailable, task.TaskNum);