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_DTO; using WIDESEAWCS_DTO.Stock; using WIDESEAWCS_DTO.TaskInfo; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob.DTO; 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; /// /// 初始化出库任务流程服务。 /// /// 路由服务。 /// WMS接口调用帮助类。 /// 机械手任务服务。 public OutboundTaskFlowService(IRouterService routerService, HttpClientHelper httpClientHelper, IRobotTaskService robotTaskService) { _routerService = routerService; _httpClientHelper = httpClientHelper; _robotTaskService = robotTaskService; } /// /// 接收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"; content = NotifyWMSOutboundFinish(task); if (!content.Status) { return content; } return content.Error($"通知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 }.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(); } } }