OrderDomainService.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using DotNetCore.CAP;
  2. using Hotline.FlowEngine;
  3. using Hotline.FlowEngine.Workflows;
  4. using Hotline.Share.Dtos.Order;
  5. using Hotline.Share.Enums.Order;
  6. using Hotline.Share.Mq;
  7. using MapsterMapper;
  8. using Microsoft.Extensions.Logging;
  9. using System.Threading;
  10. using XF.Domain.Authentications;
  11. using XF.Domain.Cache;
  12. using XF.Domain.Dependency;
  13. using XF.Domain.Entities;
  14. using XF.Domain.Exceptions;
  15. using XF.Domain.Extensions;
  16. namespace Hotline.Orders;
  17. public class OrderDomainService : IOrderDomainService, IScopeDependency
  18. {
  19. private const string OrderNoPrefix = "OrderNo:";
  20. private readonly IOrderRepository _orderRepository;
  21. private readonly IOrderRedoRepository _orderRedoRepository;
  22. private readonly ITypedCache<CacheOrderNO> _cacheOrderNo;
  23. private readonly ISessionContext _sessionContext;
  24. private readonly ICapPublisher _capPublisher;
  25. private readonly IMapper _mapper;
  26. private readonly ILogger<OrderDomainService> _logger;
  27. public OrderDomainService(
  28. IOrderRepository orderRepository,
  29. IOrderRedoRepository orderRedoRepository,
  30. ITypedCache<CacheOrderNO> cacheOrderNo,
  31. ISessionContext sessionContext,
  32. ICapPublisher capPublisher,
  33. IMapper mapper,
  34. ILogger<OrderDomainService> logger)
  35. {
  36. _orderRepository = orderRepository;
  37. _orderRedoRepository = orderRedoRepository;
  38. _cacheOrderNo = cacheOrderNo;
  39. _sessionContext = sessionContext;
  40. _capPublisher = capPublisher;
  41. _mapper = mapper;
  42. _logger = logger;
  43. }
  44. public async Task<Order> GetOrderAsync(string? orderId, CancellationToken cancellationToken)
  45. {
  46. if (string.IsNullOrEmpty(orderId))
  47. throw UserFriendlyException.SameMessage("无效工单编号");
  48. var order = await _orderRepository.Queryable()
  49. .Includes(d => d.Hotspot)
  50. .Includes(d => d.Acceptor)
  51. .FirstAsync(d => d.Id == orderId, cancellationToken);
  52. if (order == null)
  53. throw new UserFriendlyException($"无效工单编号, orderId: {orderId}", "无效工单编号");
  54. return order;
  55. }
  56. public async Task<string> AddAsync(Order order, CancellationToken cancellationToken)
  57. {
  58. if (order.OrderType == EOrderType.MarketSupervisionBy12315 && order.AcceptType == EAcceptType.Complain && order.OrderComplain == null)
  59. throw UserFriendlyException.SameMessage("非法投诉参数");
  60. if (order.OrderType == EOrderType.MarketSupervisionBy12315 && order.AcceptType == EAcceptType.Report && order.OrderReport == null)
  61. throw UserFriendlyException.SameMessage("非法举报参数");
  62. order.Init(_sessionContext.RequiredUserId, _sessionContext.UserName, _sessionContext.StaffNo);
  63. order.No = GenerateNewOrderNo();
  64. if (order.SourceChannelCode == OrderDefaults.SourceChannel.DianHua && !string.IsNullOrEmpty(order.CallId))
  65. await _capPublisher.PublishAsync(EventNames.HotlineCallConnectWithOrder, new CallConnectOrderDto
  66. {
  67. Order = _mapper.Map<OrderDto>(order),
  68. //todo calldto
  69. }, cancellationToken: cancellationToken);
  70. return await _orderRepository.AddOrderNavAsync(order, cancellationToken);
  71. }
  72. /// <summary>
  73. /// 归档
  74. /// </summary>
  75. public async Task FileAsync(string? orderId, CancellationToken cancellationToken)
  76. {
  77. var order = await GetOrderAsync(orderId, cancellationToken);
  78. order.Filed();
  79. await _orderRepository.UpdateAsync(order, cancellationToken);
  80. }
  81. public Task<string> AddOrderRedoAsync(OrderRedo orderRedo, CancellationToken cancellationToken) =>
  82. _orderRedoRepository.AddAsync(orderRedo, cancellationToken);
  83. public Task RemoveOrderRedoAsync(string id, CancellationToken cancellationToken) =>
  84. _orderRedoRepository.RemoveAsync(id, cancellationToken: cancellationToken);
  85. public Task UpdateOrderRedoAsync(OrderRedo orderRedo, CancellationToken cancellationToken) =>
  86. _orderRedoRepository.UpdateAsync(orderRedo, cancellationToken);
  87. #region private
  88. private async Task<Order> GetOrderByFlowIdAsync(string workflowId, CancellationToken cancellationToken)
  89. {
  90. if (string.IsNullOrEmpty(workflowId))
  91. throw UserFriendlyException.SameMessage("无效流程编号");
  92. var order = await _orderRepository.Queryable()
  93. .Includes(d => d.Hotspot)
  94. .Includes(d => d.Acceptor)
  95. .FirstAsync(d => d.WorkflowId == workflowId);
  96. if (order == null)
  97. throw new UserFriendlyException($"无效流程编号, workflowId: {workflowId}", "无效流程编号");
  98. return order;
  99. }
  100. //private void CheckOrderIfFiled(Order order)
  101. //{
  102. // if (order.Status is EOrderStatus.Filed)
  103. // throw UserFriendlyException.SameMessage("工单已归档");
  104. //}
  105. private string GenerateNewOrderNo()
  106. {
  107. var today = DateTime.Today;
  108. var cacheKey = $"{OrderNoPrefix}{today:yyyyMMdd}";
  109. var cacheOrderNo = _cacheOrderNo.GetOrSet(cacheKey, f =>
  110. {
  111. var todayOrderCount = _orderRepository.Queryable(true)
  112. .CountAsync(d => d.CreationTime.Date == today.Date)
  113. .GetAwaiter()
  114. .GetResult();
  115. return new CacheOrderNO { TotalCount = todayOrderCount };
  116. }, TimeSpan.FromDays(1));
  117. cacheOrderNo!.TotalCount += 1;
  118. var no = GenerateOrderNo(today, cacheOrderNo.TotalCount);
  119. _cacheOrderNo.Set(cacheKey, cacheOrderNo);
  120. return no;
  121. }
  122. private string GenerateOrderNo(DateTime today, int count)
  123. {
  124. return $"{today:yyyyMMdd}{count.ToString("000000")}";
  125. }
  126. #endregion
  127. }
  128. public class CacheOrderNO
  129. {
  130. public int TotalCount { get; set; }
  131. }