PushDomainService.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. using DotNetCore.CAP;
  2. using Hotline.Orders;
  3. using Hotline.Share.Dtos.FlowEngine;
  4. using Hotline.Share.Dtos.Push;
  5. using Hotline.Share.Dtos.Push.FWMessage;
  6. using Hotline.Share.Enums.Push;
  7. using MapsterMapper;
  8. using MediatR;
  9. using Microsoft.Extensions.Configuration;
  10. using System.Text.RegularExpressions;
  11. using XF.Domain.Dependency;
  12. using XF.Domain.Exceptions;
  13. using XF.Domain.Repository;
  14. namespace Hotline.Push.FWMessage;
  15. /// <summary>
  16. ///
  17. /// </summary>
  18. public class PushDomainService : IPushDomainService, IScopeDependency
  19. {
  20. #region 注入
  21. private readonly IRepository<Message> _messageRepository;
  22. private readonly IMapper _mapper;
  23. private readonly IHttpClientFactory _httpClientFactory;
  24. private readonly IConfiguration _config;
  25. private readonly SmsAccountInfo? accountInfo = null;
  26. private readonly IMediator _mediator;
  27. private readonly IRepository<MessageTemplate> _messageTemplateRepository;
  28. private readonly ICapPublisher _capPublisher;
  29. /// <summary>
  30. ///
  31. /// </summary>
  32. /// <param name="messageRepository"></param>
  33. /// <param name="httpClientFactory"></param>
  34. /// <param name="mapper"></param>
  35. /// <param name="config"></param>
  36. /// <param name="mediator"></param>
  37. /// <param name="cacheWaitSendId"></param>
  38. /// <param name="messageTemplateRepository"></param>
  39. /// <param name="capPublisher"></param>
  40. public PushDomainService(IRepository<Message> messageRepository, IHttpClientFactory httpClientFactory
  41. , IMapper mapper, IConfiguration config, IMediator mediator,
  42. IRepository<MessageTemplate> messageTemplateRepository, ICapPublisher capPublisher)
  43. {
  44. _messageRepository = messageRepository;
  45. _httpClientFactory = httpClientFactory;
  46. _mapper = mapper;
  47. _config = config;
  48. accountInfo = _config.GetSection("SmsAccountInfo").Get<SmsAccountInfo>();
  49. _mediator = mediator;
  50. _messageTemplateRepository = messageTemplateRepository;
  51. _capPublisher = capPublisher;
  52. }
  53. #endregion
  54. /// <summary>
  55. /// 短信发送
  56. /// </summary>
  57. /// <param name="messageDto"></param>
  58. /// <param name="cancellation"></param>
  59. /// <returns></returns>
  60. public async Task PushMsgAsync(MessageDto messageDto, CancellationToken cancellation)
  61. {
  62. if (messageDto == null)
  63. throw UserFriendlyException.SameMessage("消息不能为空!");
  64. if (string.IsNullOrEmpty(messageDto.TemplateCode) && string.IsNullOrEmpty(messageDto.Content))
  65. throw UserFriendlyException.SameMessage("模板和内容不能同时为空!");
  66. #region 替换模板内容
  67. //如果模板为空,参数为空则直接用短信内容
  68. if (!string.IsNullOrEmpty(messageDto.TemplateCode))
  69. {
  70. //查询模板信息
  71. var messageTemplate = await _messageTemplateRepository.GetAsync(p => p.Code == messageDto.TemplateCode, cancellation);
  72. if (messageTemplate == null || string.IsNullOrEmpty(messageTemplate.Content))
  73. throw UserFriendlyException.SameMessage("未找到模板短信!");
  74. string Template = messageTemplate.Content;
  75. if (messageDto.Params != null && messageDto.Params.Count > 0)
  76. {
  77. //正则查询模板中需要替换的内容
  78. Regex regex = new(@"\{[a-zA-Z0-9]{1,}\}");
  79. var matches = regex.Matches(Template);
  80. if (matches != null && matches.Count != messageDto.Params.Count)
  81. //参数与需要替换的字符数不匹配
  82. throw UserFriendlyException.SameMessage("模板需要参数与实际传递参数个数不匹配!");
  83. //reason = "模板需要参数与实际传递参数个数不匹配!";
  84. //根据正则查询出来的匹配项替换内容
  85. for (int i = 0; i < matches.Count; i++)
  86. Template = Template.Replace(matches[i].ToString(), messageDto.Params[i]);
  87. }
  88. messageDto.Content = Template;
  89. }
  90. #endregion
  91. var message = _mapper.Map<Message>(messageDto);
  92. var id = await _messageRepository.AddAsync(message);//写入本地数据库
  93. PushMessageDto pushMessage = new()
  94. {
  95. ClientId = "Hotline",
  96. ExternalId = id,
  97. Content = message.Content,
  98. Remark = message.Remark,
  99. Name = message.Name,
  100. TelNumber = message.TelNumber
  101. };
  102. await _capPublisher.PublishAsync(Hotline.Share.Mq.EventNames.SendSms, pushMessage, cancellationToken: cancellation);
  103. }
  104. /// <summary>
  105. /// 修改短信推送状态
  106. /// </summary>
  107. /// <param name="dto"></param>
  108. /// <param name="cancellation"></param>
  109. /// <returns></returns>
  110. public async Task PushMsgUpdateStateAsync(PushReceiveMessageDto dto, CancellationToken cancellation)
  111. {
  112. var data = await _messageRepository.GetAsync(p => p.Id == dto.ExternalId, cancellation);
  113. if (data != null)
  114. {
  115. if (dto.Type == "0")
  116. {
  117. if (dto.SendState == ESendState.Sending)
  118. {
  119. data.SmsWaitSendingId = dto.SmsWaitSendingId;
  120. data.SendState = ESendState.Sending;
  121. data.Status = EPushStatus.Success;
  122. }
  123. else
  124. data.Status = EPushStatus.Failed;
  125. }
  126. else if (dto.Type == "1")
  127. {
  128. data.SendTime = Convert.ToDateTime(dto.SendTime);
  129. data.SendState = dto.SendState;
  130. data.MsgCount = dto.MsgCount;
  131. data.SmsSendingCompletedId = dto.SmsSendingCompletedId;
  132. }
  133. else if (dto.Type == "2")
  134. {
  135. data.IsSmsReply = dto.IsSmsReply;
  136. data.SmsReplyTime = Convert.ToDateTime(dto.SmsReplyTime);
  137. data.SmsReplyContent = dto.SmsReplyContent;
  138. }
  139. await _messageRepository.UpdateAsync(data, cancellation);
  140. }
  141. }
  142. }