using Kean.Domain.Task.Commands; using Kean.Domain.Task.Enums; using Kean.Domain.Task.Repositories; using Kean.Domain.Task.Strategies; using System; using System.Linq; using System.Threading; namespace Kean.Domain.Task.CommandHandlers { /// /// 创建避让命令处理程序 /// public sealed class AvertCommandHandler : CommandHandler { private readonly ICommandBus _commandBus; // 命令总线 private readonly INotification _notifications; // 总线通知 private readonly ITaskRepository _taskRepository; // 任务仓库 private readonly IWarehouseRepository _warehouseRepository; // 库房仓库 private readonly AvertContext _avertContext; // 避让策略 /// /// 依赖注入 /// public AvertCommandHandler( IServiceProvider serviceProvider, ICommandBus commandBus, INotification notifications, ITaskRepository taskRepository, IWarehouseRepository warehouseRepository) { _commandBus = commandBus; _notifications = notifications; _taskRepository = taskRepository; _warehouseRepository = warehouseRepository; _avertContext = new(serviceProvider); } /// /// 处理程序 /// public override async System.Threading.Tasks.Task Handle(AvertCommand command, CancellationToken cancellationToken) { if (command.ValidationResult.IsValid) { switch (command.Behavior) { // 送入行为 case AvertCommand.Entering: { // 内侧状态 var inner = await _warehouseRepository.GetInnerCell(command.Cell.Id); if (inner != null) { if (inner.State == CellState.Selected) { Output(nameof(command.Id), (await _taskRepository.GetTask(inner))?.Id); } } else { // 外侧状态 var outer = await _warehouseRepository.GetOuterCell(command.Cell.Id); if (outer != null) { if (outer.State == CellState.Selected) { Output(nameof(command.Id), (await _taskRepository.GetTask(outer))?.Id); } else if (!outer.IsEmpty) { var transfer = await _avertContext.AutoCommand(outer); if (transfer.Destination == null) { await _commandBus.Notify(nameof(transfer.Destination), "避让任务未找到转移货位", outer.Id, cancellationToken: cancellationToken); return; } transfer.Priority = command.Priority; transfer.Operator = -1; transfer.Tag = AvertCommand.Feature; transfer.Previous = command.Previous; transfer.Timestamp = command.Timestamp; await _commandBus.Execute(transfer, cancellationToken); if (!_notifications.Any()) { Output(nameof(command.Id), transfer.Id); } } } } } break; // 取出行为 case AvertCommand.Leaving: { // 外侧状态 var outer = await _warehouseRepository.GetOuterCell(command.Cell.Id); if (outer != null) { if (outer.State == CellState.Selected) { Output(nameof(command.Id), (await _taskRepository.GetTask(outer))?.Id); } else if (!outer.IsEmpty) { var transfer = await _avertContext.AutoCommand(outer); if (transfer.Destination == null) { await _commandBus.Notify(nameof(transfer.Destination), "避让任务未找到转移货位", outer.Id, cancellationToken: cancellationToken); return; } transfer.Priority = command.Priority; transfer.Operator = -1; transfer.Tag = AvertCommand.Feature; transfer.Previous = command.Previous; transfer.Timestamp = command.Timestamp; transfer.Warehouse = outer.Warehouse; await _commandBus.Execute(transfer, cancellationToken); if (!_notifications.Any()) { Output(nameof(command.Id), transfer.Id); } } } } break; // 未知行为 default: await _commandBus.Notify(nameof(command.Behavior), "未知的避让行为", command.Behavior, cancellationToken: cancellationToken); break; } } else { await _commandBus.Notify(command.ValidationResult, cancellationToken: cancellationToken); } } } }