using Autofac;
|
using Newtonsoft.Json;
|
using System.Diagnostics.CodeAnalysis;
|
using WIDESEAWCS_Common.HttpEnum;
|
using WIDESEAWCS_Common.TaskEnum;
|
using WIDESEA_Core;
|
using WIDESEAWCS_Core;
|
using WIDESEAWCS_Core.Helper;
|
using WIDESEAWCS_Core.Enums;
|
using WIDESEAWCS_DTO;
|
using WIDESEAWCS_DTO.Stock;
|
using WIDESEAWCS_DTO.TaskInfo;
|
using WIDESEAWCS_ITaskInfoRepository;
|
using WIDESEAWCS_ITaskInfoService;
|
using WIDESEAWCS_Model.Models;
|
using WIDESEAWCS_QuartzJob.DTO;
|
using WIDESEAWCS_QuartzJob.Models;
|
using WIDESEAWCS_QuartzJob.Service;
|
|
namespace WIDESEAWCS_TaskInfoService.Flows
|
{
|
/// <summary>
|
/// 出库任务流程服务。
|
/// 负责出库任务接收初始化、状态推进及堆垛机完成处理。
|
/// </summary>
|
public class OutboundTaskFlowService : IOutboundTaskFlowService
|
{
|
private readonly IRouterService _routerService;
|
private readonly HttpClientHelper _httpClientHelper;
|
private readonly IRobotTaskService _robotTaskService;
|
private readonly ITaskRepository _taskRepository;
|
private readonly IComponentContext _componentContext;
|
|
/// <summary>
|
/// 初始化出库任务流程服务。
|
/// </summary>
|
/// <param name="routerService">路由服务。</param>
|
/// <param name="httpClientHelper">WMS接口调用帮助类。</param>
|
/// <param name="robotTaskService">机械手任务服务。</param>
|
/// <param name="taskRepository">任务仓储(用于删除出库任务)。</param>
|
/// <param name="componentContext">Autofac组件上下文(用于延迟解析ITaskService以避免循环依赖)。</param>
|
public OutboundTaskFlowService(IRouterService routerService, HttpClientHelper httpClientHelper, IRobotTaskService robotTaskService, ITaskRepository taskRepository, IComponentContext componentContext)
|
{
|
_routerService = routerService;
|
_httpClientHelper = httpClientHelper;
|
_robotTaskService = robotTaskService;
|
_taskRepository = taskRepository;
|
_componentContext = componentContext;
|
}
|
|
/// <summary>
|
/// 延迟解析ITaskService以避免循环依赖
|
/// </summary>
|
private ITaskService TaskService => _componentContext.Resolve<ITaskService>();
|
|
/// <summary>
|
/// 接收WMS任务时初始化出库任务。
|
/// </summary>
|
/// <param name="task">任务实体。</param>
|
/// <param name="source">WMS任务原始数据。</param>
|
public void InitializeOnReceive([NotNull] Dt_Task task, [NotNull] WMSTaskDTO source)
|
{
|
int taskType = task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty ? 100 : task.TaskType;
|
Dt_Router router = _routerService.QueryNextRoute(source.Roadway, source.TargetAddress, taskType);
|
if (router == null)
|
{
|
return;
|
}
|
|
task.TaskStatus = (int)TaskOutStatusEnum.OutNew;
|
task.CurrentAddress = source.SourceAddress;
|
task.NextAddress = router.ChildPosi;
|
}
|
|
/// <summary>
|
/// 推进出库任务状态,并在关键状态调用WMS接口。
|
/// </summary>
|
/// <param name="task">任务实体。</param>
|
/// <returns>推进结果。</returns>
|
public WebResponseContent MoveToNextStatus([NotNull] Dt_Task task)
|
{
|
if (task.TaskStatus >= (int)TaskOutStatusEnum.OutFinish)
|
return WebResponseContent.Instance.Error($"该任务状态不可跳转到下一步,任务号:【{task.TaskNum}】,任务状态:【{task.TaskStatus}】");
|
|
task.TaskStatus = task.TaskStatus.GetNextNotCompletedStatus<TaskOutStatusEnum>();
|
if (task.TaskStatus <= 0)
|
return WebResponseContent.Instance.Error($"该任务状态不可跳转到下一步,任务号:【{task.TaskNum}】,任务状态:【{task.TaskStatus}】");
|
|
if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutFinish && task.TaskType == (int)TaskOutboundTypeEnum.Outbound)
|
{
|
return GetWMSOutboundTrayTask(task);
|
}
|
|
if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutFinish && task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty)
|
{
|
WebResponseContent content = _robotTaskService.GetWMSRobotTask(task);
|
if (!content.Status)
|
{
|
return content;
|
}
|
return OutboundFinishTaskTray(task);
|
}
|
|
if (task.TaskStatus == (int)TaskOutStatusEnum.Line_OutExecuting)
|
{
|
return WebResponseContent.Instance.OK();
|
}
|
|
return UpdateWMSTaskStatus(task);
|
}
|
|
/// <summary>
|
/// 处理堆垛机出库完成动作。
|
/// </summary>
|
/// <param name="task">任务实体。</param>
|
/// <returns>处理结果。</returns>
|
public WebResponseContent CompleteStackerTask([NotNull] Dt_Task task)
|
{
|
WebResponseContent content = new WebResponseContent();
|
if (task.TaskStatus != (int)TaskOutStatusEnum.SC_OutExecuting)
|
{
|
return WebResponseContent.Instance.OK();
|
}
|
|
int taskType = task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty ? 100 : task.TaskType;
|
Dt_Router router = _routerService.QueryNextRoute(task.NextAddress, task.TargetAddress, taskType);
|
if (router == null)
|
{
|
return WebResponseContent.Instance.Error("未找到设备路由信息");
|
}
|
|
int nextStatus = task.TaskStatus.GetNextNotCompletedStatus<TaskOutStatusEnum>();
|
task.TaskStatus = nextStatus;
|
task.CurrentAddress = task.NextAddress;
|
task.NextAddress = router.ChildPosi;
|
task.ModifyDate = DateTime.Now;
|
task.Modifier = "System";
|
|
// 通知WMS出库完成并获取返回结果
|
var result = _httpClientHelper.Post<WebResponseContent>(
|
nameof(ConfigKey.OutboundFinishTaskAsync),
|
new StockInfoDTO { PalletCode = task.PalletCode, TaskNum = task.TaskNum }.ToJson());
|
|
if (!result.IsSuccess || !result.Data.Status)
|
{
|
return content.Error($"通知WMS系统堆垛机出库完成失败,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】,错误信息:【{result.Data?.Message}】");
|
}
|
|
// 处理WMS返回的入库任务(如果有)
|
if (result.Data?.Data != null)
|
{
|
var inboundTaskJson = result.Data.Data.ToString();
|
var inboundTaskDto = JsonConvert.DeserializeObject<WMSTaskDTO>(inboundTaskJson);
|
|
if (inboundTaskDto != null)
|
{
|
// 先删除本地出库任务,避免托盘号唯一键冲突
|
_taskRepository.DeleteAndMoveIntoHty(task, OperateTypeEnum.自动完成);
|
|
// 调用ReceiveWMSTask创建本地入库任务
|
var receiveResult = TaskService.ReceiveWMSTask(new List<WMSTaskDTO> { inboundTaskDto });
|
if (!receiveResult.Status)
|
{
|
return content.Error($"创建本地入库任务失败: {receiveResult.Message}");
|
}
|
}
|
}
|
|
return content.OK($"通知WMS系统堆垛机出库完成成功,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】");
|
}
|
|
/// <summary>
|
/// 通知WMS出库完成。
|
/// </summary>
|
/// <param name="task">任务实体。</param>
|
/// <returns>通知结果。</returns>
|
private WebResponseContent NotifyWMSOutboundFinish(Dt_Task task)
|
{
|
var result = _httpClientHelper.Post<WebResponseContent>(
|
nameof(ConfigKey.OutboundFinishTaskAsync),
|
new StockInfoDTO { PalletCode = task.PalletCode, TaskNum = task.TaskNum }.ToJson());
|
|
if (!result.IsSuccess || !result.Data.Status)
|
return WebResponseContent.Instance.Error($"通知WMS系统堆垛机出库完成失败,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】,错误信息:【{result.Data?.Message}】");
|
|
return WebResponseContent.Instance.OK();
|
}
|
|
/// <summary>
|
/// 从WMS获取空托盘出库任务。
|
/// </summary>
|
/// <param name="task">任务实体。</param>
|
/// <returns>调用结果,成功时Data中包含一个WMSTaskDTO集合。</returns>
|
private WebResponseContent GetWMSOutboundTrayTask(Dt_Task task)
|
{
|
int warehouseId = _robotTaskService.MapWarehouseIdConfigKey(task.TargetAddress);
|
string sourceLineNo = _robotTaskService.ResolveRobotRuleValue(task.TargetAddress, "AddressSourceLineNoMap", task.TargetAddress);
|
|
var result = _httpClientHelper.Post<WebResponseContent>(
|
nameof(ConfigKey.GetOutBoundTrayTaskAsync),
|
new CreateTaskDto { WarehouseId = warehouseId, TargetAddress = sourceLineNo }.ToJson());
|
|
if (!result.IsSuccess || !result.Data.Status)
|
return WebResponseContent.Instance.Error($"获取WMS系统空托盘出库任务失败,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】,错误信息:【{result.Data?.Message}】");
|
|
WMSTaskDTO? wMSTask = JsonConvert.DeserializeObject<WMSTaskDTO>(result.Data.Data?.ToString() ?? string.Empty);
|
if (wMSTask == null)
|
return WebResponseContent.Instance.Error($"获取WMS系统空托盘出库任务失败,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】,错误信息:【WMS未返回有效任务数据】");
|
|
return WebResponseContent.Instance.OK("成功", new List<WMSTaskDTO> { wMSTask });
|
}
|
|
/// <summary>
|
/// 将任务状态同步到WMS。
|
/// </summary>
|
/// <param name="task">任务实体。</param>
|
/// <returns>同步结果。</returns>
|
private WebResponseContent UpdateWMSTaskStatus(Dt_Task task)
|
{
|
var result = _httpClientHelper.Post<WebResponseContent>(
|
nameof(ConfigKey.UpdateTaskByStatus),
|
new UpdateTaskDto { Id = task.TaskNum, NewStatus = task.TaskStatus }.ToJson());
|
|
if (!result.IsSuccess || !result.Data.Status)
|
return WebResponseContent.Instance.Error($"调用WMS接口更新任务状态失败,任务号:【{task.TaskNum}】,错误信息:【{result.Data?.Message}】");
|
|
return WebResponseContent.Instance.OK();
|
}
|
|
/// <summary>
|
/// 空托盘出库完成同步到WMS。
|
/// </summary>
|
/// <param name="task">任务实体。</param>
|
/// <returns>同步结果。</returns>
|
private WebResponseContent OutboundFinishTaskTray(Dt_Task task)
|
{
|
var result = _httpClientHelper.Post<WebResponseContent>(
|
nameof(ConfigKey.OutboundFinishTaskTray),
|
new CreateTaskDto { PalletCode = task.PalletCode, SourceAddress = task.SourceAddress }.ToJson());
|
|
if (!result.IsSuccess || !result.Data.Status)
|
return WebResponseContent.Instance.Error($"调用WMS接口更新任务状态失败,任务号:【{task.TaskNum}】,错误信息:【{result.Data?.Message}】");
|
|
return WebResponseContent.Instance.OK();
|
}
|
}
|
}
|