WorkflowNextHandler.cs 12 KB

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