SmsNotifyPusher.cs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using Admin.NET.Core.Service;
  2. namespace Admin.NET.Plugin.ApprovalFlow.Service;
  3. /// <summary>
  4. /// 短信推送(P4-16)
  5. /// 由于 Admin.NET 内置的 SysSmsService.SendSms 依赖运营商预注册模板(阿里云/腾讯云/自定义),
  6. /// 动态内容不可塞入;本渠道作用限于通知触达(类似"您有新审批待办,请登录系统处理"),
  7. /// 依赖 NotifyChannelConfig.SmsTemplateId 对应的模板在运营商侧已发布。
  8. /// 未配置 SmsTemplateId / 用户无手机号时静默跳过。
  9. /// </summary>
  10. public class SmsNotifyPusher : INotifyPusher, ITransient
  11. {
  12. public string Channel => "Sms";
  13. private readonly SysSmsService _smsService;
  14. private readonly SqlSugarRepository<SysUser> _userRep;
  15. public SmsNotifyPusher(SysSmsService smsService, SqlSugarRepository<SysUser> userRep)
  16. {
  17. _smsService = smsService;
  18. _userRep = userRep;
  19. }
  20. public bool IsEnabled(NotifyChannelConfig cfg) => cfg?.Sms == true && !string.IsNullOrWhiteSpace(cfg.SmsTemplateId);
  21. public async Task<FlowNotifyPushResult> PushAsync(List<long> userIds, FlowNotification notification)
  22. {
  23. if (userIds.Count == 0) return FlowNotifyPushResult.Ok(0);
  24. var cfg = App.GetConfig<NotifyChannelConfig>("ApprovalFlow:Notify");
  25. var tplId = cfg?.SmsTemplateId;
  26. if (string.IsNullOrWhiteSpace(tplId)) return FlowNotifyPushResult.Ok(0);
  27. var users = await _userRep.AsQueryable()
  28. .Where(u => userIds.Contains(u.Id) && !string.IsNullOrEmpty(u.Phone))
  29. .Select(u => new { u.Id, u.Phone })
  30. .ToListAsync();
  31. if (users.Count == 0) return FlowNotifyPushResult.Ok(0);
  32. var errors = new List<string>();
  33. var successCount = 0;
  34. foreach (var user in users)
  35. {
  36. try
  37. {
  38. await _smsService.SendSms(user.Phone, tplId);
  39. successCount++;
  40. }
  41. catch (Exception ex)
  42. {
  43. errors.Add($"[{user.Id}]{ex.Message}");
  44. }
  45. }
  46. if (successCount > 0 && errors.Count == 0)
  47. return FlowNotifyPushResult.Ok(successCount);
  48. if (successCount > 0)
  49. return new FlowNotifyPushResult
  50. {
  51. Success = true,
  52. ActualTargetCount = successCount,
  53. ErrorMessage = $"部分失败: {string.Join("; ", errors)}"
  54. };
  55. return FlowNotifyPushResult.Fail(string.Join("; ", errors));
  56. }
  57. }