WorkflowStartHandler.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. using DotNetCore.CAP;
  2. using Hotline.Application.CallCenter;
  3. using Hotline.Application.Quality;
  4. using Hotline.CallCenter.Calls;
  5. using Hotline.CallCenter.Configs;
  6. using Hotline.CallCenter.Tels;
  7. using Hotline.FlowEngine.Notifications;
  8. using Hotline.FlowEngine.WorkflowModules;
  9. using Hotline.FlowEngine.Workflows;
  10. using Hotline.KnowledgeBase;
  11. using Hotline.Orders;
  12. using Hotline.Push.Notifies;
  13. using Hotline.Share.Dtos.FlowEngine.Workflow;
  14. using Hotline.Share.Dtos.Order;
  15. using Hotline.Share.Dtos.TrCallCenter;
  16. using Hotline.Share.Enums.KnowledgeBase;
  17. using Hotline.Share.Enums.Push;
  18. using Hotline.Share.Enums.Quality;
  19. using Hotline.Share.Mq;
  20. using Hotline.Users;
  21. using MapsterMapper;
  22. using MediatR;
  23. using Microsoft.AspNetCore.Http;
  24. using Microsoft.Extensions.Logging;
  25. using Microsoft.Extensions.Options;
  26. using XF.Domain.Entities;
  27. using XF.Domain.Repository;
  28. namespace Hotline.Application.Handlers.FlowEngine
  29. {
  30. public class WorkflowStartHandler : INotificationHandler<StartWorkflowNotify>
  31. {
  32. private readonly IOrderDomainService _orderDomainService;
  33. private readonly IKnowledgeDomainService _knowledgeDomainService;
  34. private readonly ITelDomainService _telDomainService;
  35. private readonly IOrderRepository _orderRepository;
  36. private readonly ICapPublisher _capPublisher;
  37. private readonly IMapper _mapper;
  38. private readonly ILogger<WorkflowStartHandler> _logger;
  39. private readonly IQualityApplication _qualityApplication;
  40. // private readonly IRepository<TrCallRecord> _trCallRecordRepository;
  41. private readonly IOrderScreenRepository _orderScreenRepository;
  42. private readonly IOrderDelayRepository _orderDelayRepository;
  43. private readonly IRepository<User> _userRepository;
  44. private readonly ICallApplication _callApplication;
  45. private readonly IOptionsSnapshot<CallCenterConfiguration> _callcenterOptions;
  46. private readonly IMediator _mediator;
  47. private readonly IKnowledgeRepository _knowledgeRepository;
  48. public WorkflowStartHandler(
  49. IOrderDomainService orderDomainService,
  50. IKnowledgeDomainService knowledgeDomainService,
  51. ITelDomainService telDomainService,
  52. IOrderRepository orderRepository,
  53. ICapPublisher capPublisher,
  54. IQualityApplication qualityApplication,
  55. IMapper mapper,
  56. ILogger<WorkflowStartHandler> logger,
  57. // IRepository<TrCallRecord> trCallRecordRepository,
  58. IOrderScreenRepository orderScreenRepository,
  59. IOrderDelayRepository orderDelayRepository,
  60. IRepository<User> userRepository,
  61. ICallApplication callApplication,
  62. IOptionsSnapshot<CallCenterConfiguration> callcenterOptions,
  63. IMediator mediator,
  64. IKnowledgeRepository knowledgeRepository
  65. )
  66. {
  67. _orderDomainService = orderDomainService;
  68. _knowledgeDomainService = knowledgeDomainService;
  69. _telDomainService = telDomainService;
  70. _orderRepository = orderRepository;
  71. _capPublisher = capPublisher;
  72. _qualityApplication = qualityApplication;
  73. _mapper = mapper;
  74. _logger = logger;
  75. // _trCallRecordRepository = trCallRecordRepository;
  76. _orderScreenRepository = orderScreenRepository;
  77. _orderDelayRepository = orderDelayRepository;
  78. _userRepository = userRepository;
  79. _callApplication = callApplication;
  80. _callcenterOptions = callcenterOptions;
  81. _mediator = mediator;
  82. _knowledgeRepository = knowledgeRepository;
  83. }
  84. /// <summary>Handles a notification</summary>
  85. /// <param name="notification">The notification</param>
  86. /// <param name="cancellationToken">Cancellation token</param>
  87. public async Task Handle(StartWorkflowNotify notification, CancellationToken cancellationToken)
  88. {
  89. try
  90. {
  91. //基础拉丁字母和中日韩统一表意文字的基础Unicode 块(U+4E00-U+9FCC)。 基本涵盖了除使用西里尔字母以外所有西方国家的文字和亚洲中日韩越的文字
  92. _logger.LogInformation(
  93. //$"收到{nameof(StartWorkflowNotify)}, notification: {JsonSerializer.Serialize(notification, new JsonSerializerOptions { Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.CjkUnifiedIdeographs) })}");
  94. $"收到{nameof(StartWorkflowNotify)}, workflowId: {notification.Workflow.Id}");
  95. var workflow = notification.Workflow;
  96. var data = notification.Dto;
  97. switch (workflow.ModuleCode)
  98. {
  99. case WorkflowModuleConsts.OrderHandle:
  100. var order = await _orderDomainService.GetOrderAsync(workflow.ExternalId, withHotspot: true, withAcceptor: true,
  101. withExtension: true, cancellationToken);
  102. order.CheckIfFiled();
  103. //order.StartManageFlow();
  104. order.UpdateHandlingStatus(workflow.IsInCountersign);
  105. _mapper.Map(workflow, order);
  106. await _orderRepository.UpdateAsync(order, cancellationToken);
  107. var publishCallRecordDto = new PublishCallRecrodDto() { };
  108. //查询通话记录
  109. //var callRecord = await _trCallRecordRepository.GetAsync(p => p.CallAccept == order.CallId, cancellationToken); //由CallAccept改为OtherAccept
  110. // var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
  111. // if (callRecord != null)
  112. // {
  113. // publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
  114. // }
  115. if (order.SourceChannelCode == AppDefaults.SourceChannel.DianHua &&
  116. !string.IsNullOrEmpty(order.CallId))
  117. {
  118. if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.TianRun)
  119. {
  120. // var callRecord = await _trCallRecordRepository.GetAsync(p => p.OtherAccept == order.CallId, cancellationToken);
  121. var callRecord = await _callApplication.GetTianrunCallAsync(order?.CallId, cancellationToken);
  122. if (callRecord != null)
  123. {
  124. publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(callRecord);
  125. }
  126. }
  127. else if (_callcenterOptions.Value.CallCenterType == AppDefaults.CallCenterType.XingTang)
  128. {
  129. var call = await _callApplication.GetCallAsync(order?.CallId, cancellationToken);
  130. if (call is not null)
  131. publishCallRecordDto.TrCallRecordDto = _mapper.Map<TrCallDto>(call);
  132. }
  133. }
  134. publishCallRecordDto.Order = _mapper.Map<OrderDto>(order);
  135. publishCallRecordDto.WorkflowTrace = _mapper.Map<WorkflowTraceDto>(notification.Trace);
  136. await _capPublisher.PublishAsync(EventNames.HotlineOrderFlowStarted, publishCallRecordDto,
  137. cancellationToken: cancellationToken);
  138. try
  139. {
  140. if (notification.Dto.IsSms)
  141. {
  142. switch (notification.FlowAssignInfo.FlowAssignType)
  143. {
  144. case EFlowAssignType.Org:
  145. var orgCodes = notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
  146. var orgList = await _userRepository.Queryable().Where(x =>
  147. orgCodes.Contains(x.OrgId) && x.Roles.Any(d => d.Id == "08dae71e-0eca-4bc4-89fe-7eaefae8a98e")).ToListAsync();
  148. foreach (var item in orgList)
  149. {
  150. if (!string.IsNullOrEmpty(item.PhoneNo))
  151. {
  152. var messageDto = new Share.Dtos.Push.MessageDto
  153. {
  154. PushBusiness = EPushBusiness.OrderSupervise,
  155. ExternalId = order.Id,
  156. OrderId = order.Id,
  157. PushPlatform = EPushPlatform.Sms,
  158. Remark = order.Title,
  159. Name = item.Name,
  160. TemplateCode = "1007",
  161. Params = new List<string>() { order.No },
  162. TelNumber = item.PhoneNo,
  163. };
  164. await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
  165. }
  166. }
  167. break;
  168. case EFlowAssignType.User:
  169. var userCodes = notification.FlowAssignInfo.HandlerObjects.Select(x => x.Key);
  170. var userList = await _userRepository.Queryable().Where(x =>
  171. userCodes.Contains(x.Id) && x.Roles.Any(d => d.Id == "08dae71e-0eca-4bc4-89fe-7eaefae8a98e")).ToListAsync();
  172. foreach (var item in userList)
  173. {
  174. var messageDto = new Share.Dtos.Push.MessageDto
  175. {
  176. PushBusiness = EPushBusiness.OrderSupervise,
  177. ExternalId = order.Id,
  178. OrderId = order.Id,
  179. PushPlatform = EPushPlatform.Sms,
  180. Remark = order.Title,
  181. Name = item.Name,
  182. TemplateCode = "1007",
  183. Params = new List<string>() { order.No },
  184. TelNumber = item.PhoneNo,
  185. };
  186. await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
  187. }
  188. break;
  189. default:
  190. break;
  191. }
  192. }
  193. }
  194. catch (Exception e)
  195. {
  196. _logger.LogError($"发送短信失败! orderId: {order.Id},\r\n{e.Message}");
  197. }
  198. try
  199. {
  200. //写入质检
  201. await _qualityApplication.AddQualityAsync(EQualitySource.Accepted, order.Id, cancellationToken);
  202. }
  203. catch (Exception e)
  204. {
  205. _logger.LogError($"写入质检异常!orderId: {order.Id}, \r\n{e.Message}");
  206. }
  207. break;
  208. case WorkflowModuleConsts.KnowledgeAdd:
  209. case WorkflowModuleConsts.KnowledgeUpdate:
  210. case WorkflowModuleConsts.KnowledgeDelete:
  211. await _knowledgeDomainService.UpdateWorkFlowId(workflow.ExternalId, workflow.Id,
  212. workflow.HandlerUsers, workflow.HandlerOrgs, workflow.FlowedUserIds, workflow.FlowedOrgIds,
  213. cancellationToken);
  214. break;
  215. //case WorkflowModuleConsts.OrderScreen:
  216. // var screen = await _orderScreenRepository.Queryable().Includes(x => x.Order)
  217. // .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
  218. // if (screen != null)
  219. // {
  220. // screen.WorkflowId = workflow.Id;
  221. // screen.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
  222. // await _orderScreenRepository.UpdateAsync(screen, cancellationToken);
  223. // }
  224. // break;
  225. case WorkflowModuleConsts.OrderDelay:
  226. var orderDelay = await _orderDelayRepository.Queryable()
  227. .Where(x => x.Id == workflow.ExternalId).FirstAsync(cancellationToken);
  228. if (orderDelay != null)
  229. {
  230. orderDelay.WorkflowId = workflow.Id;
  231. orderDelay.Flowed(workflow.FlowedUserIds, workflow.FlowedOrgIds, workflow.HandlerUsers, workflow.HandlerOrgs);
  232. await _orderDelayRepository.UpdateAsync(orderDelay, cancellationToken);
  233. }
  234. break;
  235. }
  236. }
  237. catch (Exception e)
  238. {
  239. _logger.LogError($"{nameof(WorkflowStartHandler)}异常,{e}");
  240. throw;
  241. }
  242. }
  243. }
  244. }