S8RoleResolver.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using Admin.NET.Core.Service;
  2. using Microsoft.Extensions.Logging;
  3. namespace Admin.NET.Plugin.AiDOP.Service.S8;
  4. /// <summary>
  5. /// S8 本地 Role → UserIds 解析器。
  6. /// 不改 Admin.NET.Core;不新增 SysUserRoleService.GetUserIdListByRoleCode。
  7. /// 在 S8 侧自行完成 RoleCode → SysRole.Id → UserIds 的解析。
  8. ///
  9. /// 兼容策略(与 ado_s8_notification_layer.target_role_ids 现状一致:表当前 0 行,
  10. /// SeedData 同时存在 RoleCode 命名(ROLE_ORDER_PLANNER)和 SysRole.Code 实存值(S8_01)):
  11. /// - 纯数字 token → 视为 SysRole.Id
  12. /// - 非数字 token → 视为 SysRole.Code
  13. /// - 找不到的 token:仅 LogWarning,不抛异常。
  14. /// </summary>
  15. public class S8RoleResolver : ITransient
  16. {
  17. private readonly SqlSugarRepository<SysRole> _sysRoleRep;
  18. private readonly SysUserRoleService _sysUserRoleService;
  19. private readonly ILogger<S8RoleResolver> _logger;
  20. public S8RoleResolver(
  21. SqlSugarRepository<SysRole> sysRoleRep,
  22. SysUserRoleService sysUserRoleService,
  23. ILogger<S8RoleResolver> logger)
  24. {
  25. _sysRoleRep = sysRoleRep;
  26. _sysUserRoleService = sysUserRoleService;
  27. _logger = logger;
  28. }
  29. /// <summary>
  30. /// 解析 RoleCode / RoleId 混合 token 列表为去重 UserId 列表。
  31. /// </summary>
  32. public async Task<List<long>> ResolveUserIdsAsync(IEnumerable<string>? roleTokens)
  33. {
  34. var result = new HashSet<long>();
  35. if (roleTokens == null) return result.ToList();
  36. var roleIds = new HashSet<long>();
  37. var codes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
  38. foreach (var raw in roleTokens)
  39. {
  40. if (string.IsNullOrWhiteSpace(raw)) continue;
  41. var t = raw.Trim();
  42. if (long.TryParse(t, out var rid) && rid > 0) roleIds.Add(rid);
  43. else codes.Add(t);
  44. }
  45. if (codes.Count > 0)
  46. {
  47. try
  48. {
  49. var codeList = codes.ToList();
  50. var found = await _sysRoleRep.AsQueryable()
  51. .Where(r => codeList.Contains(r.Code))
  52. .Select(r => new { r.Id, r.Code })
  53. .ToListAsync();
  54. var foundCodes = new HashSet<string>(found.Select(f => f.Code ?? string.Empty), StringComparer.OrdinalIgnoreCase);
  55. foreach (var c in codes)
  56. {
  57. if (!foundCodes.Contains(c))
  58. _logger.LogWarning("S8RoleResolver: RoleCode '{Code}' not found in SysRole", c);
  59. }
  60. foreach (var f in found) roleIds.Add(f.Id);
  61. }
  62. catch (Exception ex)
  63. {
  64. _logger.LogWarning(ex, "S8RoleResolver: resolve RoleCode batch failed");
  65. }
  66. }
  67. foreach (var rid in roleIds)
  68. {
  69. try
  70. {
  71. var ids = await _sysUserRoleService.GetUserIdList(rid);
  72. foreach (var uid in ids)
  73. if (uid > 0) result.Add(uid);
  74. }
  75. catch (Exception ex)
  76. {
  77. _logger.LogWarning(ex, "S8RoleResolver: GetUserIdList(roleId={RoleId}) failed", rid);
  78. }
  79. }
  80. return result.ToList();
  81. }
  82. /// <summary>
  83. /// 将 ado_s8_notification_layer.target_role_ids 这类 CSV 字段拆为 token 列表。
  84. /// 兼容 ',' 和 ';' 分隔,trim + 去空。
  85. /// </summary>
  86. public static List<string> SplitTokens(string? csv)
  87. {
  88. if (string.IsNullOrWhiteSpace(csv)) return new List<string>();
  89. return csv.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList();
  90. }
  91. }