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);
}
}
}
}