using Newtonsoft.Json;
|
using System.Diagnostics.CodeAnalysis;
|
using WIDESEA_Core;
|
using WIDESEAWCS_Common.HttpEnum;
|
using WIDESEAWCS_Common.TaskEnum;
|
using WIDESEAWCS_Core;
|
using WIDESEAWCS_ITaskInfoService;
|
using WIDESEAWCS_Model.Models;
|
using WIDESEAWCS_QuartzJob;
|
using WIDESEAWCS_QuartzJob.Models;
|
using WIDESEAWCS_QuartzJob.Service;
|
|
namespace WIDESEAWCS_Tasks
|
{
|
/// <summary>
|
/// 堆垛机任务选择器:封装任务挑选与站台可用性判断。
|
/// </summary>
|
public class StackerCraneTaskSelector
|
{
|
private readonly ITaskService _taskService;
|
private readonly IRouterService _routerService;
|
private readonly Func<int, Dt_Task?> _transferCheck;
|
|
public StackerCraneTaskSelector(ITaskService taskService, IRouterService routerService, HttpClientHelper httpClientHelper)
|
: this(taskService, routerService, taskNum => QueryTransferTask(httpClientHelper, taskNum))
|
{
|
}
|
|
public StackerCraneTaskSelector(ITaskService taskService, IRouterService routerService, Func<int, Dt_Task?> transferCheck)
|
{
|
_taskService = taskService;
|
_routerService = routerService;
|
_transferCheck = transferCheck;
|
}
|
|
public Dt_Task? SelectTask(IStackerCrane commonStackerCrane)
|
{
|
Dt_Task? candidateTask;
|
if (commonStackerCrane.LastTaskType == null)
|
{
|
candidateTask = _taskService.QueryStackerCraneTask(commonStackerCrane.DeviceCode);
|
}
|
else if (commonStackerCrane.LastTaskType.GetValueOrDefault().GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
|
{
|
candidateTask = _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode);
|
candidateTask ??= _taskService.QueryStackerCraneOutTask(commonStackerCrane.DeviceCode);
|
}
|
else
|
{
|
candidateTask = _taskService.QueryStackerCraneOutTask(commonStackerCrane.DeviceCode);
|
}
|
|
if (candidateTask == null)
|
{
|
return null;
|
}
|
|
if (candidateTask.TaskType.GetTaskTypeGroup() != TaskTypeGroup.OutbondGroup)
|
{
|
return candidateTask;
|
}
|
|
Dt_Task? selectedTask = TrySelectOutboundTask(candidateTask);
|
if (selectedTask != null)
|
{
|
return selectedTask;
|
}
|
|
var otherOutStationCodes = _routerService
|
.QueryNextRoutes(commonStackerCrane.DeviceCode, candidateTask.NextAddress, candidateTask.TaskType)
|
.Select(x => x.ChildPosi)
|
.ToList();
|
|
var tasks = _taskService.QueryStackerCraneOutTasks(commonStackerCrane.DeviceCode, otherOutStationCodes);
|
foreach (var alternativeTask in tasks)
|
{
|
selectedTask = TrySelectOutboundTask(alternativeTask);
|
if (selectedTask != null)
|
{
|
return selectedTask;
|
}
|
}
|
|
return _taskService.QueryStackerCraneInTask(commonStackerCrane.DeviceCode);
|
}
|
|
private Dt_Task? TrySelectOutboundTask(Dt_Task outboundTask)
|
{
|
// 只要是出库任务,必须先调用WMS判断是否需要移库。
|
var taskAfterTransferCheck = _transferCheck(outboundTask.TaskNum) ?? outboundTask;
|
var taskGroup = taskAfterTransferCheck.TaskType.GetTaskTypeGroup();
|
|
if (taskGroup == TaskTypeGroup.RelocationGroup || taskGroup == TaskTypeGroup.OutbondGroup)
|
{
|
TryAddTaskFromWms(taskAfterTransferCheck);
|
}
|
|
if (taskGroup == TaskTypeGroup.RelocationGroup)
|
{
|
return taskAfterTransferCheck;
|
}
|
|
if (taskGroup != TaskTypeGroup.OutbondGroup)
|
{
|
return taskAfterTransferCheck;
|
}
|
|
return IsOutTaskStationAvailable(taskAfterTransferCheck) ? taskAfterTransferCheck : null;
|
}
|
|
private static Dt_Task? QueryTransferTask(HttpClientHelper httpClientHelper, int taskNum)
|
{
|
var response = httpClientHelper.Post<WebResponseContent>(
|
nameof(ConfigKey.TransferCheck),
|
taskNum.ToString());
|
|
if (response == null || !response.IsSuccess || response.Data == null || !response.Data.Status || response.Data.Data == null)
|
{
|
return null;
|
}
|
|
var taskJson = response.Data.Data.ToString();
|
return string.IsNullOrWhiteSpace(taskJson) ? null : JsonConvert.DeserializeObject<Dt_Task>(taskJson);
|
}
|
|
private void TryAddTaskFromWms(Dt_Task task)
|
{
|
if (task.TaskNum <= 0)
|
{
|
return;
|
}
|
|
var existingTask = _taskService.QueryByTaskNum(task.TaskNum);
|
if (existingTask != null)
|
{
|
return;
|
}
|
|
_taskService.AddData(task);
|
}
|
|
private bool IsOutTaskStationAvailable([NotNull] Dt_Task task)
|
{
|
int taskType = 0;
|
if (task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty)
|
{
|
taskType = 100;
|
}
|
else
|
taskType = task.TaskType;
|
Dt_Router? router = _routerService.QueryNextRoute(task.Roadway, task.NextAddress, taskType);
|
if (router == null)
|
{
|
_taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到站台【{task.NextAddress}】信息,无法校验站台");
|
return false;
|
}
|
|
IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == router.ChildPosiDeviceCode);
|
if (device == null)
|
{
|
_taskService.UpdateTaskExceptionMessage(task.TaskNum, $"未找到出库站台【{router.ChildPosiDeviceCode}】对应的通讯对象,无法判断出库站台是否被占用");
|
return false;
|
}
|
|
CommonConveyorLine conveyorLine = (CommonConveyorLine)device;
|
return conveyorLine.IsOccupied(router.ChildPosi);
|
}
|
}
|
}
|