using AutoMapper; using Kean.Domain.Stock.Commands; using Kean.Domain.Stock.Repositories; using System; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace Kean.Domain.Stock.CommandHandlers { /// /// 合并命令处理程序 /// public sealed class CombineCommandHandler : CommandHandler { private readonly ICommandBus _commandBus; // 命令总线 private readonly INotification _notifications; // 总线通知 private readonly IMapper _mapper; // 模型映射 private readonly IStockRepository _stockRepository; // 存储仓库 /// /// 依赖注入 /// public CombineCommandHandler( ICommandBus commandBus, INotification notifications, IMapper mapper, IStockRepository stockRepository) { _commandBus = commandBus; _notifications = notifications; _mapper = mapper; _stockRepository = stockRepository; } /// /// 处理程序 /// public override async Task Handle(CombineCommand command, CancellationToken cancellationToken) { if (command.ValidationResult.IsValid) { // 时间戳 command.Timestamp ??= DateTime.Now; // 标签 var innerTag = string.IsNullOrWhiteSpace(command.Tag) ? CombineCommand.Feature : $"{CombineCommand.Feature},{command.Tag}"; // 分割库存 var stocks = await _stockRepository.SplitStock(command.Lines).ContinueWith(task => { if (task.Exception?.InnerException is RepositoryException ex) { task.Exception.Handle(_ => true); _commandBus.Notify(ex.Member.Key, ex.Message, ex.Member.Value, cancellationToken: cancellationToken).Wait(); return null; } return task.Result; }); if (stocks != null) { foreach (var item in stocks) { // 转出 var outbound = _mapper.Map(item); outbound.Operator = command.Operator; outbound.Tag = innerTag; outbound.Timestamp = command.Timestamp; foreach (var line in outbound.Lines) { line.Quantity = -line.Quantity; } await _commandBus.Execute(outbound, cancellationToken); if (_notifications.Any()) { break; } } if (!_notifications.Any()) { // 转入 var inbound = _mapper.Map(command); inbound.Tag = innerTag; inbound.Timestamp = command.Timestamp; foreach (var line in inbound.Lines) { line.Id = 0; line.Quantity = -line.Quantity; } await _commandBus.Execute(inbound, cancellationToken); } } } else { await _commandBus.Notify(command.ValidationResult, cancellationToken: cancellationToken); } } } }