using Autofac;
using Newtonsoft.Json;
using System.Diagnostics.CodeAnalysis;
using WIDESEA_Core;
using WIDESEAWCS_Common.HttpEnum;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.BaseRepository;
using WIDESEAWCS_Core.Enums;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_DTO;
using WIDESEAWCS_DTO.Stock;
using WIDESEAWCS_DTO.TaskInfo;
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob.Models;
using WIDESEAWCS_QuartzJob.Service;
namespace WIDESEAWCS_TaskInfoService.Flows
{
///
/// 出库任务流程服务。
/// 负责出库任务接收初始化、状态推进及堆垛机完成处理。
///
public class OutboundTaskFlowService : IOutboundTaskFlowService
{
private readonly IRouterService _routerService;
private readonly HttpClientHelper _httpClientHelper;
private readonly IRobotTaskService _robotTaskService;
private readonly IComponentContext _componentContext;
private readonly IUnitOfWorkManage _unitOfWorkManage;
///
/// 初始化出库任务流程服务。
///
/// 路由服务。
/// WMS接口调用帮助类。
/// 机械手任务服务。
/// Autofac组件上下文(用于延迟解析ITaskService以避免循环依赖)。
public OutboundTaskFlowService(IRouterService routerService, HttpClientHelper httpClientHelper, IRobotTaskService robotTaskService, IComponentContext componentContext, IUnitOfWorkManage unitOfWorkManage)
{
_routerService = routerService;
_httpClientHelper = httpClientHelper;
_robotTaskService = robotTaskService;
_componentContext = componentContext;
_unitOfWorkManage = unitOfWorkManage;
}
///
/// 延迟解析ITaskService以避免循环依赖
///
private ITaskService TaskService => _componentContext.Resolve();
///
/// 接收WMS任务时初始化出库任务。
///
/// 任务实体。
/// WMS任务原始数据。
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;
}
///
/// 推进出库任务状态,并在关键状态调用WMS接口。
///
/// 任务实体。
/// 推进结果。
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();
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);
}
///
/// 处理堆垛机出库完成动作。
///
/// 任务实体。
/// 处理结果。
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();
task.TaskStatus = nextStatus;
task.CurrentAddress = task.NextAddress;
task.NextAddress = router.ChildPosi;
task.ModifyDate = DateTime.Now;
task.Modifier = "System";
// 通知WMS出库完成并获取返回结果
var result = _httpClientHelper.Post(
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(inboundTaskJson);
if (inboundTaskDto != null)
{
_unitOfWorkManage.BeginTran(() =>
{
// 先删除本地出库任务,避免托盘号唯一键冲突
bool isDeleted = TaskService.Repository.DeleteAndMoveIntoHty(task, OperateTypeEnum.自动完成);
if (!isDeleted)
{
return content.Error($"删除本地出库任务失败,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】");
}
// 调用ReceiveWMSTask创建本地入库任务
var receiveResult = TaskService.ReceiveWMSTask(new List { inboundTaskDto });
if (!receiveResult.Status)
{
return content.Error($"创建本地入库任务失败: {receiveResult.Message}");
}
return content.OK("创建本地入库任务成功");
});
}
}
return content.OK($"通知WMS系统堆垛机出库完成成功,任务号:【{task.TaskNum}】,托盘号:【{task.PalletCode}】");
}
///
/// 通知WMS出库完成。
///
/// 任务实体。
/// 通知结果。
private WebResponseContent NotifyWMSOutboundFinish(Dt_Task task)
{
var result = _httpClientHelper.Post(
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();
}
///
/// 从WMS获取空托盘出库任务。
///
/// 任务实体。
/// 调用结果,成功时Data中包含一个WMSTaskDTO集合。
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(
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(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 { wMSTask });
}
///
/// 将任务状态同步到WMS。
///
/// 任务实体。
/// 同步结果。
private WebResponseContent UpdateWMSTaskStatus(Dt_Task task)
{
var result = _httpClientHelper.Post(
nameof(ConfigKey.UpdateTaskByStatus),
new UpdateTaskDto { Id = task.TaskNum, NewStatus = task.TaskStatus, NextAddress = task.NextAddress, CurrentAddress = task.CurrentAddress }.ToJson());
if (!result.IsSuccess || !result.Data.Status)
return WebResponseContent.Instance.Error($"调用WMS接口更新任务状态失败,任务号:【{task.TaskNum}】,错误信息:【{result.Data?.Message}】");
return WebResponseContent.Instance.OK();
}
///
/// 空托盘出库完成同步到WMS。
///
/// 任务实体。
/// 同步结果。
private WebResponseContent OutboundFinishTaskTray(Dt_Task task)
{
var result = _httpClientHelper.Post(
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();
}
}
}