using AutoMapper; using Kean.Domain.Order.Commands; using Kean.Domain.Order.Events; using Kean.Domain.Order.Models; using Kean.Domain.Order.Repositories; using System; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace Kean.Domain.Order.CommandHandlers { /// /// 创建订单命令处理程序 /// public sealed class CreateOrderCommandHandler : CommandHandler { private readonly ICommandBus _commandBus; // 命令总线 private readonly IMapper _mapper; // 模型映射 private readonly IOrderRepository _orderRepository; // 订单仓库 /// /// 依赖注入 /// public CreateOrderCommandHandler( ICommandBus commandBus, IMapper mapper, IOrderRepository orderRepository) { _commandBus = commandBus; _mapper = mapper; _orderRepository = orderRepository; } /// /// 处理程序 /// public override async Task Handle(CreateOrderCommand command, CancellationToken cancellationToken) { if (command.ValidationResult.IsValid) { var type = await _orderRepository.GetType(command.Type); if (type == null) { await _commandBus.Notify(nameof(command.Type), "订单类型不存在", command.Type, cancellationToken: cancellationToken); return; } //// 根据工作流设置入口节点 //var node = await _orderRepository.GetNode(command.Flow, "start"); //if (node == null || !node.Detail.ContainsKey(type.Id)) //{ // await _commandBus.Notify(nameof(command.Flow), "工作流不正确", command.Flow, // cancellationToken: cancellationToken); // return; //} // 单号处理 if (type.No == string.Empty) { if (string.IsNullOrWhiteSpace(command.No)) { await _commandBus.Notify(nameof(command.No), "单号不允许为空", command.No, cancellationToken: cancellationToken); return; } if (await _orderRepository.IsOrderExist(command.No)) { await _commandBus.Notify(nameof(command.No), "单号已存在", command.No, cancellationToken: cancellationToken); return; } } else { // 生成单号 command.No = string.Empty; var format = Format.Interpret(type.No); if (format.Any(s => s.Type == "serial")) { int? serial = null; foreach (var item in format) { switch (item.Type) { case "serial": if (!serial.HasValue) { if (await _orderRepository.IsSerialExist(type.Id)) { serial = await _orderRepository.GetSerialValue(type.Id, DateTime.Now, 2000); } else { var date = format.Where(s => s.Type == "date").ToArray(); // 单号中含有单个时间片段,以此为流水周期 if (date.Length == 1) { await _orderRepository.CreateSerial(type.Id, DateTime.Now.ToString(date[0].Value)); } // 单号中没有时间片段,无限流水 else if (date.Length == 0) { await _orderRepository.CreateSerial(type.Id, string.Empty); } // 单号中含有多个时间片段,取高精度片段为流水周期 else { char? cycle = null; foreach (var unit in "smHdMy") { foreach (var span in date) { if (span.Value.IndexOf(unit) >= 0) { cycle = unit; break; } } if (cycle != null) { break; } } if (!cycle.HasValue) { await _commandBus.Notify(nameof(command.No), "单号生成失败", command.No, cancellationToken: cancellationToken); return; } await _orderRepository.CreateSerial(type.Id, DateTime.Now.ToString("yyyyMMddHHmmss"[..(1 + "yyyyMMddHHmmss".LastIndexOf(cycle.Value))])); } serial = 1; } if (!serial.HasValue) { await _commandBus.Notify(nameof(command.No), "单号生成失败", command.No, cancellationToken: cancellationToken); return; } } command.No += serial.Value.ToString(item.Value); break; case "date": command.No += DateTime.Now.ToString(item.Value); break; default: command.No += item.Value; break; } } } else { foreach (var item in format) { command.No += item.Type == "date" ? DateTime.Now.ToString(item.Value) : item.Value; } } } // 创建订单 var order = _mapper.Map(command); //order.Node = node.Id; Output(nameof(command.Id), order.Id = await _orderRepository.CreateOrder(order)); var @event = _mapper.Map(command); //@event.Node = node.Id; await _commandBus.Trigger(@event, cancellationToken); } else { await _commandBus.Notify(command.ValidationResult, cancellationToken: cancellationToken); } } } }