InternalCapSubscriber.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. using DotNetCore.CAP;
  2. using Hotline.Application.Orders;
  3. using Hotline.Caching.Interfaces;
  4. using Hotline.Configurations;
  5. using Hotline.FlowEngine.Workflows;
  6. using Hotline.Orders;
  7. using Hotline.Push;
  8. using Hotline.Push.Notifies;
  9. using Hotline.SeedData;
  10. using Hotline.Settings;
  11. using Hotline.Settings.TimeLimitDomain;
  12. using Hotline.Share.Dtos.Order;
  13. using Hotline.Share.Dtos.Push;
  14. using Hotline.Share.Enums.FlowEngine;
  15. using Hotline.Share.Enums.Order;
  16. using Hotline.Share.Enums.Push;
  17. using Hotline.Share.Mq;
  18. using Hotline.Users;
  19. using MapsterMapper;
  20. using MediatR;
  21. using Microsoft.AspNetCore.Http;
  22. using Microsoft.Extensions.Options;
  23. using NPOI.SS.Formula.Functions;
  24. using StackExchange.Redis;
  25. using XF.Domain.Authentications;
  26. using XF.Domain.Dependency;
  27. using XF.Domain.Repository;
  28. namespace Hotline.Application.Subscribers
  29. {
  30. public class InternalCapSubscriber : ICapSubscribe, ITransientDependency
  31. {
  32. private readonly IOrderRepository _orderRepository;
  33. private readonly IMediator _mediator;
  34. private readonly IRepository<User> _userRepository;
  35. private readonly ICapPublisher _capPublisher;
  36. private readonly IRepository<BatchSmsTask> _batchSmsTaskRepository;
  37. private readonly ISystemSettingCacheManager _systemSettingCacheManager;
  38. private readonly IOrderApplication _orderApplication;
  39. private readonly IRepository<OrderDelay> _orderDelayRepository;
  40. private readonly IWorkflowDomainService _workflowDomainService;
  41. private readonly ICalcExpireTime _expireTime;
  42. private readonly IMapper _mapper;
  43. private readonly IOptionsSnapshot<AppConfiguration> _appOptions;
  44. public InternalCapSubscriber(
  45. IOrderRepository orderRepository,
  46. IMediator mediator,
  47. IRepository<User> userRepository,
  48. ICapPublisher capPublisher,
  49. IRepository<BatchSmsTask> batchSmsTaskRepository,
  50. ISystemSettingCacheManager systemSettingCacheManager,
  51. IOrderApplication orderApplication,
  52. IRepository<OrderDelay> orderDelayRepository,
  53. IWorkflowDomainService workflowDomainService,
  54. ICalcExpireTime expireTime,
  55. IMapper mapper
  56. ,
  57. IOptionsSnapshot<AppConfiguration> appOptions)
  58. {
  59. _orderRepository = orderRepository;
  60. _mediator = mediator;
  61. _userRepository = userRepository;
  62. _capPublisher = capPublisher;
  63. _batchSmsTaskRepository = batchSmsTaskRepository;
  64. _systemSettingCacheManager = systemSettingCacheManager;
  65. _orderApplication = orderApplication;
  66. _orderDelayRepository = orderDelayRepository;
  67. _workflowDomainService = workflowDomainService;
  68. _expireTime = expireTime;
  69. _mapper = mapper;
  70. _appOptions = appOptions;
  71. }
  72. /// <summary>
  73. /// 工单即将超期短信发送(延迟消息)
  74. /// </summary>
  75. /// <param name="dto"></param>
  76. /// <param name="cancellationToken"></param>
  77. /// <returns></returns>
  78. [CapSubscribe(EventNames.HotlineOrderNearlyExpiredTimeSms)]
  79. public async Task SendOrderNearlyExpiredTimeSms(PublishNearlyExpiredTimeSmsDto dto, CancellationToken cancellationToken)
  80. {
  81. var order = await _orderRepository.GetAsync(dto.OrderId, cancellationToken);
  82. if (order != null && order.Status < Share.Enums.Order.EOrderStatus.Filed && order.NearlyExpiredTime?.ToString("yyyy-MM-dd hh:mm") == DateTime.Now.ToString("yyyy-MM-dd hh:mm"))
  83. {
  84. //当前办理人不为空发短信给个人
  85. if (!string.IsNullOrEmpty(order.CurrentHandlerId))
  86. {
  87. //查询人员
  88. var user = await _userRepository.GetAsync(order.CurrentHandlerId, cancellationToken);
  89. if (user != null && !string.IsNullOrEmpty(user.PhoneNo))
  90. {
  91. //发送短信
  92. var messageDto = new Share.Dtos.Push.MessageDto
  93. {
  94. PushBusiness = EPushBusiness.OrderUrge,
  95. ExternalId = order.Id,
  96. OrderId = order.Id,
  97. PushPlatform = EPushPlatform.Sms,
  98. Remark = order.Title,
  99. Name = user.Name,
  100. TemplateCode = "1001",
  101. Params = new List<string>() { order.No },
  102. TelNumber = user.PhoneNo,
  103. };
  104. await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
  105. }
  106. }
  107. //当前办理部门不为空,发短信给部门经办人
  108. else if (!string.IsNullOrEmpty(order.CurrentHandleOrgId))
  109. {
  110. var acceptSmsRoleIds = _systemSettingCacheManager.GetSetting(SettingConstants.AcceptSmsRoleIds)?.SettingValue;
  111. //查询部门经办人
  112. var userlist = await _userRepository.Queryable().Where(x =>
  113. x.OrgId == order.CurrentHandleOrgId && !string.IsNullOrEmpty(x.PhoneNo) &&
  114. x.Roles.Any(d => acceptSmsRoleIds.Contains(d.Id))).ToListAsync();
  115. foreach (var user in userlist)
  116. {
  117. if (!string.IsNullOrEmpty(user.PhoneNo))
  118. {
  119. //发送短信
  120. var messageDto = new Share.Dtos.Push.MessageDto
  121. {
  122. PushBusiness = EPushBusiness.OrderUrge,
  123. ExternalId = order.Id,
  124. OrderId = order.Id,
  125. PushPlatform = EPushPlatform.Sms,
  126. Remark = order.Title,
  127. Name = user.Name,
  128. TemplateCode = "1001",
  129. Params = new List<string>() { order.No },
  130. TelNumber = user.PhoneNo,
  131. };
  132. await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
  133. }
  134. }
  135. }
  136. //TODO发送短信超期
  137. //_capPublisher.PublishDelay(order.ExpiredTime.Value- DateTime.Now, EventNames.HotlineOrderExpiredTimeSms, new PublishNearlyExpiredTimeSmsDto() { OrderId = order.Id });
  138. }
  139. }
  140. /// <summary>
  141. /// 工单超期短信发送(延迟消息)
  142. /// </summary>
  143. /// <param name="dto"></param>
  144. /// <param name="cancellationToken"></param>
  145. /// <returns></returns>
  146. [CapSubscribe(EventNames.HotlineOrderExpiredTimeSms)]
  147. public async Task SendOrderExpiredTimeSms(PublishNearlyExpiredTimeSmsDto dto, CancellationToken cancellationToken)
  148. {
  149. var order = await _orderRepository.GetAsync(dto.OrderId, cancellationToken);
  150. if (order != null && order.Status < Share.Enums.Order.EOrderStatus.Filed && order.NearlyExpiredTime?.ToString("yyyy-MM-dd hh:mm") == DateTime.Now.ToString("yyyy-MM-dd hh:mm"))
  151. {
  152. //当前办理人不为空发短信给个人
  153. if (!string.IsNullOrEmpty(order.CurrentHandlerId))
  154. {
  155. //查询人员
  156. var user = await _userRepository.GetAsync(order.CurrentHandlerId, cancellationToken);
  157. if (user != null && !string.IsNullOrEmpty(user.PhoneNo))
  158. {
  159. //发送短信
  160. var messageDto = new Share.Dtos.Push.MessageDto
  161. {
  162. PushBusiness = EPushBusiness.OrderUrge,
  163. ExternalId = order.Id,
  164. OrderId = order.Id,
  165. PushPlatform = EPushPlatform.Sms,
  166. Remark = order.Title,
  167. Name = user.Name,
  168. TemplateCode = "1009",
  169. Params = new List<string>() { order.No },
  170. TelNumber = user.PhoneNo,
  171. };
  172. await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
  173. }
  174. }
  175. //当前办理部门不为空,发短信给部门经办人
  176. else if (!string.IsNullOrEmpty(order.CurrentHandleOrgId))
  177. {
  178. var acceptSmsRoleIds = _systemSettingCacheManager.GetSetting(SettingConstants.AcceptSmsRoleIds)?.SettingValue;
  179. //查询部门经办人
  180. var userlist = await _userRepository.Queryable().Where(x =>
  181. x.OrgId == order.CurrentHandleOrgId && !string.IsNullOrEmpty(x.PhoneNo) &&
  182. x.Roles.Any(d => acceptSmsRoleIds.Contains(d.Id))).ToListAsync();
  183. foreach (var user in userlist)
  184. {
  185. if (!string.IsNullOrEmpty(user.PhoneNo))
  186. {
  187. //发送短信
  188. var messageDto = new Share.Dtos.Push.MessageDto
  189. {
  190. PushBusiness = EPushBusiness.OrderUrge,
  191. ExternalId = order.Id,
  192. OrderId = order.Id,
  193. PushPlatform = EPushPlatform.Sms,
  194. Remark = order.Title,
  195. Name = user.Name,
  196. TemplateCode = "1009",
  197. Params = new List<string>() { order.No },
  198. TelNumber = user.PhoneNo,
  199. };
  200. await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
  201. }
  202. }
  203. }
  204. }
  205. }
  206. /// <summary>
  207. /// 批量发送短信(延迟消息)
  208. /// </summary>
  209. /// <param name="dto"></param>
  210. /// <param name="cancellationToken"></param>
  211. /// <returns></returns>
  212. [CapSubscribe(EventNames.HotlineBatchSmsTask)]
  213. public async Task SendBatchSmsTask(PublishBatchSmsTaskDto dto, CancellationToken cancellationToken)
  214. {
  215. var task = await _batchSmsTaskRepository.Queryable()
  216. .Includes(x => x.BatchSmsTaskDetails)
  217. .Where(x => x.Id == dto.TaskId).FirstAsync();
  218. if (task != null && task.SmsTaskState == ESmsTaskState.WaitDo && task.PlanSendTime.ToString("yyyy-MM-dd hh:mm") == DateTime.Now.ToString("yyyy-MM-dd hh:mm"))
  219. {
  220. foreach (var item in task.BatchSmsTaskDetails)
  221. {
  222. //发送短信
  223. var messageDto = new Share.Dtos.Push.MessageDto
  224. {
  225. PushBusiness = EPushBusiness.BatchSms,
  226. PushPlatform = EPushPlatform.Sms,
  227. Name = item.Name,
  228. TelNumber = item.PhoneNum,
  229. Content = task.Content
  230. };
  231. await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
  232. }
  233. }
  234. }
  235. /// <summary>
  236. /// 自动延期
  237. /// </summary>
  238. /// <param name="dto"></param>
  239. /// <param name="cancellationToken"></param>
  240. /// <returns></returns>
  241. [CapSubscribe(EventNames.HotlineOrderAutomaticDelay)]
  242. public async Task AutomaticDelay(PublishAutomaticDelayDto dto, CancellationToken cancellationToken)
  243. {
  244. var enabled = _systemSettingCacheManager.GetSetting(SettingConstants.EnabledAutomaticDelay)?.SettingValue[0];
  245. if (bool.Parse(enabled))
  246. {
  247. var order = await _orderRepository.GetAsync(dto.OrderId, cancellationToken);
  248. var expiredTime = DateTime.Now.AddHours(2);
  249. if (order != null && order.Status < EOrderStatus.Filed && order.ExpiredTime >= DateTime.Now)
  250. {
  251. if (order.ExpiredTime <= expiredTime)
  252. {
  253. var delayAny = await _orderDelayRepository.Queryable().Where(x => x.OrderId == order.Id && x.DelayState == EDelayState.Examining).AnyAsync();
  254. if (!delayAny)
  255. {
  256. var delays = await _orderDelayRepository.Queryable().Where(x => x.OrderId == order.Id && x.AutomaticDelayNum > 0).ToListAsync(cancellationToken);
  257. var delay = new OrderDelay();
  258. if (delays.Any())
  259. {
  260. delay = delays.First();
  261. var startTime = DateTime.Now;
  262. if (order.CenterToOrgTime.HasValue)
  263. {
  264. startTime = order.CenterToOrgTime.Value;
  265. }
  266. var beforeDelay = DateTime.Now;
  267. if (!_appOptions.Value.IsYiBin)
  268. {
  269. beforeDelay = order.ExpiredTime.Value;
  270. }
  271. delay.AfterDelay = (await _expireTime
  272. .CalcEndTime(beforeDelay, startTime, delay.DelayUnit, delay.DelayNum, order.AcceptTypeCode))?.EndTime; //todo
  273. await _orderDelayRepository.Updateable().SetColumns(x => new OrderDelay() { AutomaticDelayNum = x.AutomaticDelayNum + 1, ApplyDelayTime = DateTime.Now, AfterDelay = delay.AfterDelay })
  274. .Where(x => x.Id == delay.Id).ExecuteCommandAsync(cancellationToken);
  275. }
  276. else
  277. {
  278. delay.OrderId = order.Id;
  279. delay.EmployeeId = "";
  280. delay.EmployeeName = "系统自动延期";
  281. delay.ApplyOrgName = OrgSeedData.CenterName;
  282. delay.ApplyOrgCode = OrgSeedData.CenterId;
  283. delay.DelayApplyType = EDelayApplyType.LocalApply;
  284. delay.BeforeDelay = order.ExpiredTime;
  285. delay.DelayState = EDelayState.Pass;
  286. delay.DelayReason = "系统自动延期";
  287. delay.ApplyDelayTime = DateTime.Now;
  288. delay.No = order.No;
  289. delay.AutomaticDelayNum = 1;
  290. delay.DelayNum = 1;
  291. delay.DelayUnit = Share.Enums.Settings.ETimeType.WorkDay;
  292. delay.IsProDelay = false;
  293. delay.CreatorOrgId = OrgSeedData.CenterId;
  294. delay.CreatorOrgName = OrgSeedData.CenterName;
  295. delay.CreatorName = "系统自动延期";
  296. var startTime = DateTime.Now;
  297. if (order.CenterToOrgTime.HasValue)
  298. {
  299. startTime = order.CenterToOrgTime.Value;
  300. }
  301. if (delay.BeforeDelay != null)
  302. {
  303. delay.AfterDelay = (await _expireTime
  304. .CalcEndTime(delay.BeforeDelay.Value, startTime, delay.DelayUnit, delay.DelayNum, order.AcceptTypeCode))?.EndTime; //todo
  305. }
  306. await _orderDelayRepository.AddAsync(delay, false, cancellationToken);
  307. }
  308. //处理工单延期
  309. await _orderApplication.DelayOrderExpiredTimeAsync(order.Id, delay.DelayNum, delay.DelayUnit, delay.IsProDelay, cancellationToken);
  310. // 自贡任务 320调整“延期催办短信”发送的时间,将短信发送时间提前2个小时,所以拆分出去
  311. ////发送短信
  312. //var workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withSteps: true, cancellationToken: cancellationToken);
  313. //var steps = workflow.Steps.Where(x => x.Status == EWorkflowStepStatus.WaitForAccept || x.Status == EWorkflowStepStatus.WaitForHandle).ToList();
  314. //if (steps.Any())
  315. //{
  316. // foreach (var step in steps)
  317. // {
  318. // var setting = step.HandlerOrgId == OrgSeedData.CenterId ? SettingConstants.AutomaticDelayCenterRoles : SettingConstants.AutomaticDelayDepartmentRoles;
  319. // var roleIds = _systemSettingCacheManager.GetSetting(setting)?.SettingValue;
  320. // if (step.HandlerOrgId == OrgSeedData.CenterId && string.IsNullOrEmpty(step.RoleId))
  321. // {
  322. // roleIds.Add(step.RoleId);
  323. // }
  324. // var userList = await _userRepository.Queryable().Where(x => x.OrgId == step.HandlerOrgId && x.Roles.Any(r => roleIds.Contains(r.Name))).ToListAsync(cancellationToken);
  325. // foreach (var user in userList)
  326. // {
  327. // if (!string.IsNullOrEmpty(user.PhoneNo))
  328. // {
  329. // //发送短信
  330. // var messageDto = new Share.Dtos.Push.MessageDto
  331. // {
  332. // PushBusiness = EPushBusiness.AutomaticDelay,
  333. // ExternalId = order.Id,
  334. // OrderId = order.Id,
  335. // PushPlatform = EPushPlatform.Sms,
  336. // Remark = order.Title,
  337. // Name = user.Name,
  338. // TemplateCode = "1015",
  339. // Params = new List<string>() { order.No },
  340. // TelNumber = user.PhoneNo,
  341. // };
  342. // await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
  343. // }
  344. // }
  345. // }
  346. //}
  347. }
  348. }
  349. order = await _orderRepository.GetAsync(dto.OrderId, cancellationToken);
  350. _capPublisher.PublishDelay(order.ExpiredTime.Value - DateTime.Now.AddHours(1), EventNames.HotlineOrderAutomaticDelay, new PublishAutomaticDelayDto() { OrderId = order.Id });
  351. var orderDto = _mapper.Map<OrderDto>(order);
  352. await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.HotlineOrderExpiredTimeUpdate, orderDto,
  353. cancellationToken: cancellationToken);
  354. }
  355. }
  356. }
  357. /// <summary>
  358. /// 延期催办短信(延迟消息,自动延期前2小时发送)
  359. /// </summary>
  360. /// <param name="dto"></param>
  361. /// <param name="cancellationToken"></param>
  362. /// <returns></returns>
  363. [CapSubscribe(EventNames.HotlineOrderAutomaticSendSmsDelay)]
  364. public async Task AutomaticDelaySendSms(PublishAutomaticDelayDto dto, CancellationToken cancellationToken)
  365. {
  366. var enabled = _systemSettingCacheManager.GetSetting(SettingConstants.EnabledAutomaticDelay)?.SettingValue[0];
  367. if (bool.Parse(enabled))
  368. {
  369. var order = await _orderRepository.GetAsync(dto.OrderId, cancellationToken);
  370. var expiredTime = DateTime.Now.AddHours(2);
  371. if (order != null && order.Status < EOrderStatus.Filed && order.ExpiredTime >= DateTime.Now)
  372. {
  373. if (order.ExpiredTime <= expiredTime)
  374. {
  375. var delayAny = await _orderDelayRepository.Queryable().Where(x => x.OrderId == order.Id && x.DelayState == EDelayState.Examining).AnyAsync();
  376. if (!delayAny)
  377. {
  378. //发送短信
  379. var workflow = await _workflowDomainService.GetWorkflowAsync(order.WorkflowId, withSteps: true, cancellationToken: cancellationToken);
  380. var steps = workflow.Steps.Where(x => x.Status == EWorkflowStepStatus.WaitForAccept || x.Status == EWorkflowStepStatus.WaitForHandle).ToList();
  381. if (steps.Any())
  382. {
  383. foreach (var step in steps)
  384. {
  385. var setting = step.HandlerOrgId == OrgSeedData.CenterId ? SettingConstants.AutomaticDelayCenterRoles : SettingConstants.AutomaticDelayDepartmentRoles;
  386. var roleIds = _systemSettingCacheManager.GetSetting(setting)?.SettingValue;
  387. if (step.HandlerOrgId == OrgSeedData.CenterId && string.IsNullOrEmpty(step.RoleId))
  388. {
  389. roleIds.Add(step.RoleId);
  390. }
  391. var userList = await _userRepository.Queryable().Where(x => x.OrgId == step.HandlerOrgId && x.Roles.Any(r => roleIds.Contains(r.Name))).ToListAsync(cancellationToken);
  392. foreach (var user in userList)
  393. {
  394. if (!string.IsNullOrEmpty(user.PhoneNo))
  395. {
  396. //发送短信
  397. var messageDto = new Share.Dtos.Push.MessageDto
  398. {
  399. PushBusiness = EPushBusiness.AutomaticDelay,
  400. ExternalId = order.Id,
  401. OrderId = order.Id,
  402. PushPlatform = EPushPlatform.Sms,
  403. Remark = order.Title,
  404. Name = user.Name,
  405. TemplateCode = "1015",
  406. Params = new List<string>() { order.No },
  407. TelNumber = user.PhoneNo,
  408. };
  409. await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
  410. }
  411. }
  412. }
  413. }
  414. }
  415. }
  416. }
  417. }
  418. }
  419. /// <summary>
  420. /// 批量发送短信
  421. /// </summary>
  422. /// <param name="dto"></param>
  423. /// <param name="cancellationToken"></param>
  424. /// <returns></returns>
  425. [CapSubscribe(EventNames.HotlineLeaderSMS)]
  426. public async Task SendLeaderSMS(PublishLeaderSMSDto dto, CancellationToken cancellationToken)
  427. {
  428. //发送短信
  429. var messageDto = new Share.Dtos.Push.MessageDto
  430. {
  431. PushBusiness = EPushBusiness.OrderSend,
  432. ExternalId = dto.OrderId,
  433. OrderId = dto.OrderId,
  434. PushPlatform = EPushPlatform.Sms,
  435. Remark = string.Empty,
  436. Name = dto.Name,
  437. TemplateCode = "1014",
  438. Params = new(),
  439. TelNumber = dto.TelNumber,
  440. };
  441. await _mediator.Publish(new PushMessageNotify(messageDto), cancellationToken);
  442. }
  443. }
  444. }