在 StackerCraneTaskSelector.SelectTask 方法中,当 TrySelectOutboundTask 因 TargetAddress 输送线站台不空闲(CV_State != 2)而返回 null 时,需要继续搜索其他可选的出库任务,而不是直接返回 null 或仅尝试不同 NextAddress 的任务。
当 TargetAddress 不可用时,按以下顺序搜索备选任务:
在 SelectTask 方法中,TrySelectOutboundTask(candidateTask) 返回 null 之后、现有备选任务循环之前,插入同 NextAddress 任务搜索逻辑:
// 尝试选择出库任务
Dt_Task? selectedTask = TrySelectOutboundTask(candidateTask);
if (selectedTask != null)
{
return selectedTask;
}
// ===== TargetAddress 不可用时,先尝试同 NextAddress 的其他任务 =====
// 查询与当前任务 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)
.Select(x => x.ChildPosi)
.ToList();
var tasks = _taskService.QueryStackerCraneOutTasks(deviceCode, otherOutStationCodes);
foreach (var alternativeTask in tasks)
{
selectedTask = TrySelectOutboundTask(alternativeTask);
if (selectedTask != null)
{
QuartzLogHelper.LogDebug(_logger, $"选中备选出库任务,任务号: {selectedTask.TaskNum}", commonStackerCrane.DeviceName);
return selectedTask;
}
}
利用现有的 QueryStackerCraneOutTasks(deviceCode, stationCodes) 方法,传入单站台列表即可查询同 NextAddress 的任务。过滤掉当前任务(TaskId 不同)避免重复尝试。
SelectTask
↓
TrySelectOutboundTask(candidateTask)
↓
TargetAddress 可用?否 → 返回 null
↓
查询同 NextAddress 的其他出库任务
↓
遍历同站台任务
→ TrySelectOutboundTask(task) → 可用 → 返回任务
→ 不可用 → 继续下一个
↓
同 NextAddress 无可用任务
↓
查询不同 NextAddress 的出库任务(现有逻辑)
↓
遍历 → 返回可用任务 / 无可用 → 返回 null
无需新增 using,现有方法签名已满足。
TaskId 作为唯一标识用于过滤已尝试任务,假设任务表中无重复 TaskIdQueryStackerCraneOutTasks 返回的任务列表需要考虑排序(如果有业务规则决定优先级)