WorkflowNextHandler.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. using DotNetCore.CAP;
  2. using Hotline.Application.Quality;
  3. using Hotline.FlowEngine.Notifications;
  4. using Hotline.FlowEngine.WorkflowModules;
  5. using Hotline.FlowEngine.Workflows;
  6. using Hotline.KnowledgeBase;
  7. using Hotline.Orders;
  8. using Hotline.Settings;
  9. using Hotline.Settings.TimeLimits;
  10. using Hotline.Share.Dtos.FlowEngine.Workflow;
  11. using Hotline.Share.Dtos.Order;
  12. using Hotline.Share.Dtos.Settings;
  13. using Hotline.Share.Enums.FlowEngine;
  14. using Hotline.Share.Enums.Order;
  15. using Hotline.Share.Enums.Quality;
  16. using Hotline.Share.Mq;
  17. using MapsterMapper;
  18. using MediatR;
  19. using Microsoft.Extensions.Logging;
  20. using Newtonsoft.Json;
  21. using XF.Domain.Repository;
  22. namespace Hotline.Application.Handlers.FlowEngine;
  23. public class WorkflowNextHandler : INotificationHandler<NextStepNotify>
  24. {
  25. private readonly IOrderDomainService _orderDomainService;
  26. private readonly IKnowledgeDomainService _knowledgeDomainService;
  27. private readonly IOrderRepository _orderRepository;
  28. private readonly ITimeLimitDomainService _timeLimitDomainService;
  29. private readonly IWorkflowDomainService _workflowDomainService;
  30. private readonly ICapPublisher _capPublisher;
  31. private readonly IMapper _mapper;
  32. private readonly ILogger<WorkflowNextHandler> _logger;
  33. private readonly IOrderScreenRepository _orderScreenRepository;
  34. private readonly IQualityApplication _qualityApplication;
  35. private readonly IOrderDelayRepository _orderDelayRepository;
  36. private readonly IKnowledgeRepository _knowledgeRepository;
  37. private readonly IKnowledgeWorkFlowRepository _knowledgeWorkFlowRepository;
  38. public WorkflowNextHandler(
  39. IOrderDomainService orderDomainService,
  40. IKnowledgeDomainService knowledgeDomainService,
  41. IOrderRepository orderRepository,
  42. ITimeLimitDomainService timeLimitDomainService,
  43. IWorkflowDomainService workflowDomainService,
  44. ICapPublisher capPublisher,
  45. IMapper mapper,
  46. ILogger<WorkflowNextHandler> logger,
  47. IOrderScreenRepository orderScreenRepository,
  48. IQualityApplication qualityApplication,
  49. IKnowledgeRepository knowledgeRepository,
  50. IKnowledgeWorkFlowRepository knowledgeWorkFlowRepository,
  51. IOrderDelayRepository orderDelayRepository)
  52. {
  53. _orderDomainService = orderDomainService;
  54. _knowledgeDomainService = knowledgeDomainService;
  55. _orderRepository = orderRepository;
  56. _timeLimitDomainService = timeLimitDomainService;
  57. _workflowDomainService = workflowDomainService;
  58. _capPublisher = capPublisher;
  59. _mapper = mapper;
  60. _logger = logger;
  61. _orderScreenRepository = orderScreenRepository;
  62. _qualityApplication = qualityApplication;
  63. _orderDelayRepository = orderDelayRepository;
  64. _knowledgeRepository = knowledgeRepository;
  65. _knowledgeWorkFlowRepository = knowledgeWorkFlowRepository;
  66. }
  67. /// <summary>Handles a notification</summary>
  68. /// <param name="notification">The notification</param>
  69. /// <param name="cancellationToken">Cancellation token</param>
  70. public async Task Handle(NextStepNotify notification, CancellationToken cancellationToken)
  71. {
  72. //_logger.LogInformation(
  73. // $"收到{nameof(NextStepNotify)}, notification: {JsonConvert.SerializeObject(notification)}");
  74. var workflow = notification.Workflow;
  75. var data = notification.Dto;
  76. var assignInfo = notification.FlowAssignInfo;
  77. var currentTag = string.IsNullOrEmpty(notification.Trace.Tag)
  78. ? null
  79. : System.Text.Json.JsonSerializer.Deserialize<DefinitionTag>(notification.Trace.Tag);
  80. var nextTag = string.IsNullOrEmpty(notification.NextStepDefine.Tag)
  81. ? null
  82. : System.Text.Json.JsonSerializer.Deserialize<DefinitionTag>(notification.NextStepDefine.Tag);
  83. switch (workflow.ModuleCode)
  84. {
  85. case WorkflowModuleConsts.OrderHandle:
  86. var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId, withHotspot: true,
  87. withAcceptor: true, withExtension: true, cancellationToken: cancellationToken);
  88. order.CheckIfFiled();
  89. _mapper.Map(workflow, order);
  90. var expiredTimeChanged = false;
  91. if (data.FlowDirection.HasValue
  92. && data.External.TimeLimit.HasValue
  93. && data.External.TimeLimitUnit.HasValue)
  94. {
  95. // 1. calc expiredTime 2. update order.expiredTime 3. update workflow.expiredTime 4. publish province
  96. // var expiredTime = _timeLimitDomainService.CalcEndTime(DateTime.Now,
  97. // data.External.TimeLimitUnit.Value,
  98. // data.External.TimeLimit.Value, data.FlowDirection is EFlowDirection.OrgToCenter);
  99. var expiredTimeConfig = _timeLimitDomainService.CalcEndTime(DateTime.Now,
  100. new TimeConfig(data.External.TimeLimit.Value, data.External.TimeLimitUnit.Value), order.AcceptTypeCode);
  101. if (data.FlowDirection is EFlowDirection.OrgToCenter)
  102. {
  103. order.OrgToCenter(expiredTimeConfig.TimeText, expiredTimeConfig.Count,
  104. expiredTimeConfig.TimeType, expiredTimeConfig.ExpiredTime, expiredTimeConfig.NearlyExpiredTime);
  105. }
  106. else if (data.FlowDirection is EFlowDirection.CenterToOrg)
  107. {
  108. order.CenterToOrg(expiredTimeConfig.TimeText, expiredTimeConfig.Count,
  109. expiredTimeConfig.TimeType, expiredTimeConfig.ExpiredTime, expiredTimeConfig.NearlyExpiredTime);
  110. //写入质检
  111. await _qualityApplication.AddQualityAsync(EQualitySource.Send, order.Id, cancellationToken);
  112. }
  113. await _workflowDomainService.UpdateExpiredTimeAsync(workflow,
  114. expiredTimeConfig.ExpiredTime, expiredTimeConfig.TimeText,
  115. expiredTimeConfig.Count, expiredTimeConfig.TimeType, expiredTimeConfig.NearlyExpiredTime, cancellationToken);
  116. expiredTimeChanged = true;
  117. }
  118. await _orderRepository.UpdateAsync(order, cancellationToken);
  119. var orderDto = _mapper.Map<OrderDto>(order);
  120. await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderFlowHandled, new OrderFlowDto
  121. {
  122. Order = orderDto,
  123. WorkflowTrace = _mapper.Map<WorkflowTraceDto>(notification.Trace),
  124. ExpiredTimeChanged = expiredTimeChanged,
  125. HandlerOrgLevel = notification.HandlerOrgCode.CalcOrgLevel()
  126. }, cancellationToken: cancellationToken);
  127. break;
  128. case WorkflowModuleConsts.KnowledgeAdd:
  129. case WorkflowModuleConsts.KnowledgeUpdate:
  130. case WorkflowModuleConsts.KnowledgeDelete:
  131. var knowledgeWork = await _knowledgeWorkFlowRepository.Queryable().Where(x=>x.Id==workflow.ExternalId).FirstAsync(cancellationToken);
  132. var knowledge = await _knowledgeRepository.Queryable().Where(x => x.Id == knowledgeWork.KnowledgeId).FirstAsync(cancellationToken);
  133. knowledge.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
  134. await _knowledgeRepository.UpdateAsync(knowledge, cancellationToken);
  135. break;
  136. case WorkflowModuleConsts.OrderScreen:
  137. var screen = await _orderScreenRepository.Queryable().Includes(x => x.Order)
  138. .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
  139. if (screen != null)
  140. {
  141. screen.Status = EScreenStatus.Approval;
  142. screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
  143. await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
  144. }
  145. if (nextTag is not null && nextTag.Type == TagDefaults.TagType.Org)
  146. {
  147. switch (nextTag.Value)
  148. {
  149. case TagDefaults.TagValue.Province:
  150. if (screen != null)
  151. {
  152. var screenDto = _mapper.Map<OrderScreenListDto>(screen);
  153. if (screen.Order != null && screen.Order.Source == ESource.ProvinceStraight)
  154. {
  155. var screenOrderDto = _mapper.Map<OrderDto>(screen.Order);
  156. //推省上
  157. _capPublisher.Publish(EventNames.HotlineOrderScreenApply, new PublishScreenDto()
  158. {
  159. Order = screenOrderDto,
  160. Screen = screenDto,
  161. ClientGuid = ""
  162. });
  163. //try
  164. //{
  165. // await _provinceService.ScreenCaseInfoSend(new PublishScreenDto()
  166. // {
  167. // Order = screenOrderDto,
  168. // Screen = screenDto,
  169. // ClientGuid = ""
  170. // }, cancellationToken);
  171. //}
  172. //catch (Exception e)
  173. //{
  174. // _logger.LogError(
  175. // "_provinceService.ScreenCaseInfoSend throw exception: {ex}", e.Message);
  176. //}
  177. }
  178. }
  179. break;
  180. }
  181. }
  182. break;
  183. case WorkflowModuleConsts.OrderDelay:
  184. var orderDelay = await _orderDelayRepository.Queryable().Includes(x => x.Order)
  185. .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
  186. if (orderDelay != null)
  187. {
  188. orderDelay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
  189. await _orderDelayRepository.UpdateAsync(orderDelay, cancellationToken);
  190. }
  191. if (nextTag is not null && nextTag.Type == TagDefaults.TagType.Org)
  192. {
  193. switch (nextTag.Value)
  194. {
  195. case TagDefaults.TagValue.Province:
  196. //TODO 发起省延期审批
  197. //var orderDelay = await _orderDelayRepository.Queryable().Includes(x => x.Order)
  198. // .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
  199. try
  200. {
  201. if (orderDelay != null)
  202. {
  203. //推送
  204. var publishOrderDelay = _mapper.Map<PublishOrderDelayDto>(orderDelay);
  205. await _capPublisher.PublishAsync(EventNames.HotlineOrderApplyDelay, publishOrderDelay, cancellationToken: cancellationToken);
  206. //await _provinceService.DelayCaseInfoSend(publishOrderDelay, cancellationToken);
  207. }
  208. }
  209. catch (Exception e)
  210. {
  211. _logger.LogError("_provinceService.DelayCaseInfoSend throw exception: {ex}",
  212. e.Message);
  213. }
  214. break;
  215. }
  216. }
  217. break;
  218. }
  219. }
  220. }