山东雷驰
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
6.7 KiB

3 months ago
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
{
/// <summary>
/// 创建避让命令处理程序
/// </summary>
public sealed class AvertCommandHandler : CommandHandler<AvertCommand>
{
private readonly ICommandBus _commandBus; // 命令总线
private readonly INotification _notifications; // 总线通知
private readonly ITaskRepository _taskRepository; // 任务仓库
private readonly IWarehouseRepository _warehouseRepository; // 库房仓库
private readonly AvertContext<AvertStrategy_Simple> _avertContext; // 避让策略
/// <summary>
/// 依赖注入
/// </summary>
public AvertCommandHandler(
IServiceProvider serviceProvider,
ICommandBus commandBus,
INotification notifications,
ITaskRepository taskRepository,
IWarehouseRepository warehouseRepository)
{
_commandBus = commandBus;
_notifications = notifications;
_taskRepository = taskRepository;
_warehouseRepository = warehouseRepository;
_avertContext = new(serviceProvider);
}
/// <summary>
/// 处理程序
/// </summary>
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);
}
}
}
}