EnterpriseService.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. using Hotline.Enterprise;
  2. using Hotline.Share.Dtos;
  3. using RestSharp;
  4. using System.Collections;
  5. using System.Net.Http.Headers;
  6. using System.Net.Http.Json;
  7. using System.Text;
  8. using Hotline.Share.Dtos.Enterprise;
  9. using Microsoft.Extensions.Logging;
  10. using Microsoft.Extensions.Options;
  11. using XF.Domain.Cache;
  12. using XF.Domain.Exceptions;
  13. using XF.Domain.Dependency;
  14. namespace Hotline.YbEnterprise.Sdk
  15. {
  16. public class EnterpriseService : IEnterpriseService, IScopeDependency
  17. {
  18. private readonly IHttpClientFactory _httpClientFactory;
  19. private readonly IOptionsSnapshot<EnterpriseConfig> _enterpriseOptions;
  20. private readonly ITypedCache<YbEnterpriseToken> _tokenCache;
  21. private readonly ILogger<EnterpriseService> _logger;
  22. public EnterpriseService(
  23. IHttpClientFactory httpClientFactory,
  24. IOptionsSnapshot<EnterpriseConfig> enterpriseOptions,
  25. ITypedCache<YbEnterpriseToken> tokenCache,
  26. ILogger<EnterpriseService> logger)
  27. {
  28. _httpClientFactory = httpClientFactory;
  29. _enterpriseOptions = enterpriseOptions;
  30. _tokenCache = tokenCache;
  31. _logger = logger;
  32. }
  33. /// <summary>
  34. /// 获取企业列表
  35. /// </summary>
  36. /// <param name="name"></param>
  37. /// <param name="current"></param>
  38. /// <param name="size"></param>
  39. /// <param name="cancellationToken"></param>
  40. /// <returns></returns>
  41. public async Task<YbEnterprisePaged> QueryYbEnterprisesAsync(
  42. string name, int current, int size, CancellationToken cancellationToken)
  43. {
  44. var request = new YbEnterprisesRequest()
  45. {
  46. EnterpriseName = name,
  47. Current = current,
  48. Size = size
  49. };
  50. var token = await GetTokenAsync(YbEnterpriseDefaults.KeyOfToken, cancellationToken);
  51. var result = await ExecuteAsync<YbEnterprisesRequest, YbEnterpriseResponse<YbEnterprisePaged>>(
  52. YbEnterpriseDefaults.PathEnterprises,
  53. request,
  54. d => d.DefaultRequestHeaders.Add("Blade-Auth", $"{token.TokenType} {token.AccessToken}"),
  55. cancellationToken);
  56. if (result is null || !result.Success)
  57. throw new UserFriendlyException("未获取到企业专班数据");
  58. return result.Data;
  59. }
  60. private async Task<YbEnterpriseToken> GetTokenAsync(string key, CancellationToken cancellationToken)
  61. {
  62. var token = await _tokenCache.GetAsync(key, cancellationToken);
  63. if (token is not null) return token;
  64. token = await GetTokenAsync(cancellationToken);
  65. await _tokenCache.SetAsync(key, token, TimeSpan.FromSeconds(token.ExpiresIn - 5), cancellationToken);
  66. return token;
  67. }
  68. private async Task<YbEnterpriseToken> GetTokenAsync(CancellationToken cancellationToken)
  69. {
  70. var config = _enterpriseOptions.Value;
  71. string authorization = config.ClientId + ":" + config.ClientSecret;
  72. authorization = Convert.ToBase64String(Encoding.UTF8.GetBytes(authorization));
  73. var result = await ExecuteAsync<object, YbEnterpriseResponse<YbEnterpriseToken>>(
  74. YbEnterpriseDefaults.PathToken,
  75. new(),
  76. d =>
  77. {
  78. d.DefaultRequestHeaders.Authorization = AuthenticationHeaderValue.Parse($"Basic {authorization}");
  79. d.DefaultRequestHeaders.Add("Tenant-Id", config.TenantId);
  80. }, cancellationToken);
  81. if (result is null || !result.Success)
  82. throw new UserFriendlyException("获取enterprise token失败");
  83. return result.Data;
  84. }
  85. private async Task<TResponse?> ExecuteAsync<TRequest, TResponse>(string path, TRequest request,
  86. Action<HttpClient>? clientInitialize = null, CancellationToken cancellationToken = default)
  87. {
  88. var client = _httpClientFactory.CreateClient(YbEnterpriseDefaults.HttpName);
  89. clientInitialize?.Invoke(client);
  90. using var responseMessage = await client.PostAsJsonAsync(path, request, cancellationToken);
  91. responseMessage.EnsureSuccessStatusCode();
  92. var result = await responseMessage.Content.ReadFromJsonAsync<TResponse>(cancellationToken: cancellationToken);
  93. return result;
  94. }
  95. }
  96. }