using AutoMapper; using Kean.Domain.Task.Commands; using Kean.Domain.Task.Enums; using Kean.Domain.Task.Events; using Kean.Domain.Task.Repositories; using Kean.Domain.Task.SharedServices.Proxies; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Linq; using System.Threading; namespace Kean.Domain.Task.CommandHandlers { /// /// 任务完成命令处理程序 /// public sealed class CompleteCommandHandler : CommandHandler { private readonly ICommandBus _commandBus; // 命令总线 private readonly IMapper _mapper; // 模型映射 private readonly ITaskRepository _taskRepository; // 任务仓库 private readonly IWarehouseRepository _warehouseRepository; // 库房仓库 private readonly StockProxy _stockProxy; // 仓储域 private readonly WcsProxy _wcsProxy; private readonly Kean.Infrastructure.Soap.LED.LedService _ledService; private readonly INotification _notifications; // 总线通知 private readonly ILogger _logger; // 日志 /// /// 依赖注入 /// public CompleteCommandHandler( ICommandBus commandBus, IMapper mapper, ITaskRepository taskRepository, IWarehouseRepository warehouseRepository, WcsProxy wcsProxy, Kean.Infrastructure.Soap.LED.LedService ledService, ILogger logger, INotification notifications, StockProxy stockProxy) { _commandBus = commandBus; _mapper = mapper; _taskRepository = taskRepository; _warehouseRepository = warehouseRepository; _wcsProxy = wcsProxy; _stockProxy = stockProxy; _ledService = ledService; _notifications = notifications; _logger = logger; } /// /// 处理程序 /// public override async System.Threading.Tasks.Task Handle(CompleteCommand command, CancellationToken cancellationToken) { if (command.ValidationResult.IsValid) { var task = await _taskRepository.GetTask(command.Id); if (task != null) { if (task.ManageStatus == TaskState.ScanError.ToString() && command.ManualFlg != 1) { } else { if (task.Type != TaskType.ApplyOut && task.Type != TaskType.PalletOut && task.Type != TaskType.Bypass) { int? cellId = await _stockProxy.GetCell(task.Barcode); int originalCellId = cellId.HasValue ? cellId.Value : task.Original; await _warehouseRepository.ReleaseCell(task.TransitPlace == 0 ? originalCellId : task.TransitPlace, task.Destination); } //await _taskRepository.DeleteTask(command.Id); string isAgv = string.Empty; bool bDeleteWcs = (task.Tag != "@Avert"); // 前端人工操作 if (command.ManualFlg == 1) { if (!string.IsNullOrEmpty(task.Tag) && (task.Tag != "@Avert")) { try { JObject jObj = JObject.Parse(task.Tag); JToken manualFlg = jObj.SelectToken("ManualFlg"); if (manualFlg == null) { jObj.Add("ManualFlg", command.ManualFlg); } JToken transaction = jObj.SelectToken("Transaction"); if (transaction == null) { jObj.Add("Transaction", task.Type.ToString()); } JToken @operator = jObj.SelectToken("Operator"); if (@operator == null) { jObj.Add("Operator", command.Operator); } else { jObj["Operator"] = command.Operator; } if (command.IsCancelAgv == "1") { jObj["isAgv"] = "0"; } if (command.IsCancelHiwms == "1") { jObj.Add("IsCancelHiwms", command.IsCancelHiwms); jObj.Remove("orderInfo"); jObj.Remove("backupOrderInfo"); } isAgv = jObj["isAgv"].ToString(); task.Tag = JsonConvert.SerializeObject(jObj); } catch { task.Tag = JsonConvert.SerializeObject(new { ManualFlg = command.ManualFlg, Transaction = task.Type.ToString(), Operator = command.Operator }); } } else { task.Tag = JsonConvert.SerializeObject(new { ManualFlg = command.ManualFlg, Transaction = task.Type.ToString(), Operator = command.Operator }); } if (task.Type != TaskType.ApplyOut && task.Type != TaskType.PalletOut && bDeleteWcs) { await _wcsProxy.DeleteWcs(task.Id, $"人工完成"); } } if (task.Type == TaskType.ApplyOut || task.Type == TaskType.PalletOut || task.Type == TaskType.Bypass) { await _stockProxy.SendOutToHiWMS(task.Type.ToString(), task.Barcode, task.RequestNo, "2"); if (!_notifications.Any()) { if (task.Destination == 29101 || task.Destination == 22017) { await _stockProxy.SendAGV(task.Barcode, task.Tag, task.Destination); } } if (!_notifications.Any()) { // 前端人工操作 if (command.ManualFlg == 1) { await _wcsProxy.DeleteWcs(task.Id, $"人工完成"); } int? cellId = await _stockProxy.GetCell(task.Barcode); int originalCellId = cellId.HasValue ? cellId.Value : task.Original; await _warehouseRepository.ReleaseCell(task.TransitPlace == 0 ? originalCellId : task.TransitPlace, task.Destination); await _warehouseRepository.UpdateCell(task.TransitPlace == 0 ? originalCellId : task.TransitPlace, "Empty"); //await _stockProxy.Relocate( // "Transfer", // task.Barcode, // null, // task.Original, // task.Destination, // task.Operator, // task.Tag, // (task.Timestamp, DateTime.Now)); await _taskRepository.DeleteTask(command.Id); await _stockProxy.AutoOut(task.Type.ToString(), task.Barcode, task.Original, task.Destination, task.Operator, task.Tag, task.Timestamp); } //LED提示 string ledSlTarget = string.Empty; string ledSlSourceL2 = string.Empty; if (!string.IsNullOrEmpty(task.Tag)) { JObject jObj = JObject.Parse(task.Tag); JToken jIsAgv = jObj.SelectToken("isAgv"); JToken jSlTarget = jObj.SelectToken("slTarget"); if (jIsAgv != null && jSlTarget != null) { if (jObj["isAgv"].ToString() == "1" && !string.IsNullOrEmpty(jObj["slTarget"].ToString())) { ledSlTarget = "-" + jObj["slTarget"].ToString(); ledSlSourceL2 = " 目的地:" + jObj["slTarget"].ToString(); } } } string line1 = $"{task.Barcode}出库{ledSlTarget}"; string line2 = $"请搬运"; if (!string.IsNullOrEmpty(task.Tag)) { JObject jObj = JObject.Parse(task.Tag); //JToken isAgvToken = jObj["isAgv"]; JToken jIsAgv = jObj.SelectToken("isAgv"); ////使用AGV //if (jIsAgv != null && jIsAgv.ToString().Equals("1")) //{ // line2 = $"等待AGV搬运{ledSlSourceL2}"; //} } if (_notifications.Any()) { line1 = $"{task.Barcode}出库错误"; line2 = $"{_notifications.FirstOrDefault().ErrorMessage}"; } await _ledService.Invoke(task.Destination.ToString(), line1, line2); } else { //await _taskRepository.DeleteTask(command.Id); var @event = _mapper.Map(task); @event.Id = command.Id; @event.Timestamp = DateTime.Now; @event.Tag = task.RequestNo; await _commandBus.Trigger(@event, cancellationToken); if (!bDeleteWcs) { await _wcsProxy.DeleteWcs(task.Id, $"人工完成"); } try { task = await _taskRepository.GetTask(command.Id); if (task != null && task.ManageStatus != "WaiteWmsResult" && task.ManageStatus != "UploadError" && task.ManageStatus != "WmsResultFail" && task.ManageStatus != "ScanError" && task.ManageStatus != "AgvFail") { await _taskRepository.DeleteTask(command.Id); } } catch { } } } } try { foreach (var item in await _taskRepository.GetRepairFollowed()) { _logger.LogInformation($"找到需要补发后续任务({item.Id})"); await _taskRepository.DeleteTask(item.Id); int? cellId = await _stockProxy.GetCell(item.Barcode); int originalCellId = cellId.HasValue ? cellId.Value : item.Original; await _warehouseRepository.ReleaseCell(item.TransitPlace == 0 ? originalCellId : item.TransitPlace, item.Destination); item.Previous = null; item.Warehouse = (await _warehouseRepository.GetCellById(item.Original)) == null ? 0 : (await _warehouseRepository.GetCellById(item.Original)).Warehouse; item.Tag = item.Tag.Contains("isAgv") ? item.Tag : ""; var newcommand = _mapper.Map(item, typeof(Models.Task), Type.GetType($"Kean.Domain.Task.Commands.{item.Type}Command")) as ICommand; await _commandBus.Execute(newcommand, cancellationToken); if (!_notifications.Any()) { _logger.LogInformation($"需要补发后续任务({item.Id})生成新的后续任务({Convert.ToInt32(newcommand.GetType().GetProperty("Id").GetValue(newcommand))})"); await _taskRepository.UpdatePrevious(item.Id, Convert.ToInt32(newcommand.GetType().GetProperty("Id").GetValue(newcommand))); } } } catch (Exception e) { _logger.LogInformation($"需要补发后续任务处理异常,原因:{e.StackTrace}"); } } else { await _commandBus.Notify(command.ValidationResult, cancellationToken: cancellationToken); } } } }