|
@@ -2,25 +2,34 @@
|
|
|
using Hotline.Share.Dtos;
|
|
|
using RestSharp;
|
|
|
using System.Collections;
|
|
|
-using System.Net;
|
|
|
+using System.Net.Http.Headers;
|
|
|
+using System.Net.Http.Json;
|
|
|
using System.Text;
|
|
|
using Hotline.Share.Dtos.Enterprise;
|
|
|
+using Microsoft.Extensions.Logging;
|
|
|
+using Microsoft.Extensions.Options;
|
|
|
using XF.Domain.Cache;
|
|
|
using XF.Domain.Exceptions;
|
|
|
-using Newtonsoft.Json.Linq;
|
|
|
-using Newtonsoft.Json;
|
|
|
+using XF.Domain.Dependency;
|
|
|
|
|
|
namespace Hotline.YbEnterprise.Sdk
|
|
|
{
|
|
|
- public class EnterpriseService : IEnterpriseService
|
|
|
+ public class EnterpriseService : IEnterpriseService, IScopeDependency
|
|
|
{
|
|
|
- private readonly RestClient _client;
|
|
|
- private readonly EnterpriseConfig _config;
|
|
|
-
|
|
|
- public EnterpriseService(EnterpriseConfig config)
|
|
|
+ private readonly IHttpClientFactory _httpClientFactory;
|
|
|
+ private readonly IOptionsSnapshot<EnterpriseConfig> _enterpriseOptions;
|
|
|
+ private readonly ITypedCache<YbEnterpriseToken> _tokenCache;
|
|
|
+ private readonly ILogger<EnterpriseService> _logger;
|
|
|
+ public EnterpriseService(
|
|
|
+ IHttpClientFactory httpClientFactory,
|
|
|
+ IOptionsSnapshot<EnterpriseConfig> enterpriseOptions,
|
|
|
+ ITypedCache<YbEnterpriseToken> tokenCache,
|
|
|
+ ILogger<EnterpriseService> logger)
|
|
|
{
|
|
|
- _client = new RestClient();
|
|
|
- _config = config;
|
|
|
+ _httpClientFactory = httpClientFactory;
|
|
|
+ _enterpriseOptions = enterpriseOptions;
|
|
|
+ _tokenCache = tokenCache;
|
|
|
+ _logger = logger;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -31,288 +40,65 @@ namespace Hotline.YbEnterprise.Sdk
|
|
|
/// <param name="size"></param>
|
|
|
/// <param name="cancellationToken"></param>
|
|
|
/// <returns></returns>
|
|
|
- public async Task<EnterpriseListData> GetEnterpriseList(string name = "", int current = 1, int size = 10, CancellationToken cancellationToken = default, ITypedCache<EnterpriseVo> cacheResponse = default)
|
|
|
+ public async Task<YbEnterprisePaged> QueryYbEnterprisesAsync(
|
|
|
+ string name, int current, int size, CancellationToken cancellationToken)
|
|
|
{
|
|
|
- //var request = new EnterpriseListRequest
|
|
|
- //{
|
|
|
- // EnterpriseName = name,
|
|
|
- // Current = current,
|
|
|
- // Size = size
|
|
|
- //};
|
|
|
- string postJson = "{";
|
|
|
- postJson += "\"enterpriseName\":\"" + name + "\",";
|
|
|
- postJson += "\"current\":\"" + current + "\",";
|
|
|
- postJson += "\"size\":\"" + size + "\"";
|
|
|
- postJson += "}";
|
|
|
- var token = await cacheResponse.GetAsync("EnterpriseResponse", cancellationToken);
|
|
|
- if (token == null || (token != null && token.EndTime > DateTime.Now))
|
|
|
+ var request = new YbEnterprisesRequest()
|
|
|
{
|
|
|
- token = await GetTokenAsync(cancellationToken);
|
|
|
- token.EndTime = DateTime.Now.AddMinutes(45);
|
|
|
- await cacheResponse.SetAsync("EnterpriseResponse", token, cancellationToken: cancellationToken);
|
|
|
- }
|
|
|
- var path = _config.AddressUrl + "platform/12345/selectEnterpriseList";
|
|
|
- //var rest = new RestRequest(path, Method.Post);
|
|
|
- ////rest.AddHeader("content-type", "application/json");
|
|
|
- ////rest.AddHeader("Blade-Auth", token.TokenType + " " + token.AccessToken);
|
|
|
- //rest.AddHeaders(new[] {
|
|
|
- // new KeyValuePair<string, string>("content-type", "application/json"),
|
|
|
- // new KeyValuePair<string, string>("Blade-Auth", token.TokenType + " " + token.AccessToken)
|
|
|
- //});
|
|
|
-
|
|
|
- List<KeyValuePair<string, string>> headers = new List<KeyValuePair<string, string>>();
|
|
|
- headers.Add(new KeyValuePair<string, string>("Blade-Auth", token.TokenType + " " + token.AccessToken));
|
|
|
+ EnterpriseName = name,
|
|
|
+ Current = current,
|
|
|
+ Size = size
|
|
|
+ };
|
|
|
|
|
|
- string strResult = HttpPost(path, postJson, "UTF-8", "application/json", headers);
|
|
|
- //var res = await ExecuteAsync<EnterpriseListRequest, EnterpriseListResponse>(path, Method.Post, request, rest, cancellationToken);
|
|
|
- var res = new EnterpriseListResponse();
|
|
|
- if (false == string.IsNullOrEmpty(strResult))
|
|
|
- {
|
|
|
- res = (EnterpriseListResponse)JsonConvert.DeserializeObject(strResult)!;
|
|
|
- }
|
|
|
- return res.data;
|
|
|
+ var token = await GetTokenAsync(YbEnterpriseDefaults.KeyOfToken, cancellationToken);
|
|
|
+ var result = await ExecuteAsync<YbEnterprisesRequest, YbEnterpriseResponse<YbEnterprisePaged>>(
|
|
|
+ YbEnterpriseDefaults.PathEnterprises,
|
|
|
+ request,
|
|
|
+ d => d.DefaultRequestHeaders.Add("Blade-Auth", $"{token.TokenType} {token.AccessToken}"),
|
|
|
+ cancellationToken);
|
|
|
+ if (result is null || !result.Success)
|
|
|
+ throw new UserFriendlyException("未获取到企业专班数据");
|
|
|
+ return result.Data;
|
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 获取TOKEN
|
|
|
- /// </summary>
|
|
|
- /// <param name="cancellationToken"></param>
|
|
|
- /// <returns></returns>
|
|
|
- /// <exception cref="UserFriendlyException"></exception>
|
|
|
- public async Task<EnterpriseVo> GetTokenAsync(CancellationToken cancellationToken)
|
|
|
- {
|
|
|
-
|
|
|
- string authorization = _config.ClientId + ":" + _config.ClientSecret;
|
|
|
- authorization = Encoder.Base64Code(authorization);
|
|
|
- authorization = authorization.Replace("@", "=");
|
|
|
-
|
|
|
- var path = _config.AddressUrl + "blade-auth/oauth/getAccessToken";
|
|
|
- //var rest = new RestRequest(path, Method.Post);
|
|
|
- //rest.AddHeader("content-type", "application/json");
|
|
|
- //rest.AddHeader("Authorization", "Basic " + authorization);
|
|
|
- //rest.AddHeader("Tenant-Id", _config.TenantId);
|
|
|
- //rest.AddHeaders(new[] {
|
|
|
- // new KeyValuePair<string, string>("content-type", "application/json"),
|
|
|
- // new KeyValuePair<string, string>("Authorization", "Basic " + authorization),
|
|
|
- // new KeyValuePair<string, string>("Tenant-Id", _config.TenantId)});
|
|
|
- string json = "{\"a\":\"1\"}";
|
|
|
- //var res = await ExecuteAsync<string, EnterpriseServiceResponse>(path, Method.Post, "", rest, cancellationToken);
|
|
|
- List<KeyValuePair<string, string>> headers = new List<KeyValuePair<string, string>>();
|
|
|
- headers.Add(new KeyValuePair<string, string>("Authorization", "Basic " + authorization));
|
|
|
- headers.Add(new KeyValuePair<string, string>("Tenant-Id", _config.TenantId));
|
|
|
- string strResult = HttpPost(path, json, "UTF-8", "application/json", headers);
|
|
|
- EnterpriseServiceResponse? res = new EnterpriseServiceResponse();
|
|
|
- if (false == string.IsNullOrEmpty(strResult))
|
|
|
- {
|
|
|
- res = (EnterpriseServiceResponse)JsonConvert.DeserializeObject(strResult)!;
|
|
|
- }
|
|
|
- if (res is null)
|
|
|
- throw new UserFriendlyException("获取token请求失败 authorization:" + authorization + " ,path:" + path + " , res:" + strResult);
|
|
|
- if (!res.success)
|
|
|
- throw new UserFriendlyException("获取token请求失败 authorization2:" + authorization + " ,path:" + path + " , res:" + System.Text.Json.JsonSerializer.Serialize(res));
|
|
|
- return res.data;
|
|
|
- }
|
|
|
- public async Task<TResponse> ExecuteAsync<TRequest, TResponse>(string path, Method httpMethod, TRequest request, RestRequest restRequest = null,
|
|
|
- CancellationToken cancellationToken = default)
|
|
|
- where TRequest : class
|
|
|
+ private async Task<YbEnterpriseToken> GetTokenAsync(string key, CancellationToken cancellationToken)
|
|
|
{
|
|
|
- var req = new RestRequest(path, httpMethod);
|
|
|
- if (httpMethod is Method.Get)
|
|
|
- {
|
|
|
- req.AddObject(request);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- req.AddJsonBody(request);
|
|
|
- }
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
- var response = await _client.ExecuteAsync<TResponse>(req, cancellationToken);
|
|
|
- return response.Data;
|
|
|
- }
|
|
|
- catch (Exception e)
|
|
|
- {
|
|
|
- throw new HttpRequestException($"企业服务数据错误,Error: {e.Message}");
|
|
|
- }
|
|
|
+ var token = await _tokenCache.GetAsync(key, cancellationToken);
|
|
|
+ if (token is not null) return token;
|
|
|
+ token = await GetTokenAsync(cancellationToken);
|
|
|
+ await _tokenCache.SetAsync(key, token, TimeSpan.FromSeconds(token.ExpiresIn - 5), cancellationToken);
|
|
|
+ return token;
|
|
|
}
|
|
|
|
|
|
- public static string HttpPost(string strUrl, string strPar = "", string strEncoding = "UTF-8", string strContentType = "application/x-www-form-urlencoded", List<KeyValuePair<string, string>> headers = null)
|
|
|
+ private async Task<YbEnterpriseToken> GetTokenAsync(CancellationToken cancellationToken)
|
|
|
{
|
|
|
- // 返回数据
|
|
|
- string strResult = "";
|
|
|
- // 网页客户端,用于打开链接,获取返回参数
|
|
|
- WebClient wc = new WebClient();
|
|
|
- try
|
|
|
- {
|
|
|
- byte[] responseData = null;
|
|
|
- wc.Headers.Add("Content-Type", strContentType);
|
|
|
- if (null != headers && headers.Count > 0)
|
|
|
- {
|
|
|
- headers.ForEach(p =>
|
|
|
- {
|
|
|
- wc.Headers.Add(p.Key, p.Value);
|
|
|
- });
|
|
|
- }
|
|
|
- byte[] postData = Encoding.GetEncoding(strEncoding).GetBytes(strPar);
|
|
|
- responseData = wc.UploadData(strUrl, "POST", postData);
|
|
|
- strResult = Encoding.GetEncoding(strEncoding).GetString(responseData);
|
|
|
- strResult = strResult.Trim();
|
|
|
- }
|
|
|
- catch (Exception)
|
|
|
- {
|
|
|
- strResult = "";
|
|
|
- }
|
|
|
- finally
|
|
|
- {
|
|
|
- wc.Dispose();
|
|
|
- wc = null;
|
|
|
- }
|
|
|
+ var config = _enterpriseOptions.Value;
|
|
|
+ string authorization = config.ClientId + ":" + config.ClientSecret;
|
|
|
+ authorization = Convert.ToBase64String(Encoding.UTF8.GetBytes(authorization));
|
|
|
+ var result = await ExecuteAsync<object, YbEnterpriseResponse<YbEnterpriseToken>>(
|
|
|
+ YbEnterpriseDefaults.PathToken,
|
|
|
+ new(),
|
|
|
+ d =>
|
|
|
+ {
|
|
|
+ d.DefaultRequestHeaders.Authorization = AuthenticationHeaderValue.Parse($"Basic {authorization}");
|
|
|
+ d.DefaultRequestHeaders.Add("Tenant-Id", config.TenantId);
|
|
|
+ }, cancellationToken);
|
|
|
|
|
|
- return strResult;
|
|
|
+ if (result is null || !result.Success)
|
|
|
+ throw new UserFriendlyException("获取enterprise token失败");
|
|
|
+ return result.Data;
|
|
|
}
|
|
|
|
|
|
- public static class Encoder
|
|
|
+ private async Task<TResponse?> ExecuteAsync<TRequest, TResponse>(string path, TRequest request,
|
|
|
+ Action<HttpClient>? clientInitialize = null, CancellationToken cancellationToken = default)
|
|
|
{
|
|
|
- /// <summary>
|
|
|
- /// 对string 进行 Base64 编码
|
|
|
- /// </summary>
|
|
|
- /// <param name="strMessage">string 参数</param>
|
|
|
- /// <returns> Base64 编码</returns>
|
|
|
- public static string Base64Code(string strMessage)
|
|
|
- {
|
|
|
- bool flag = string.IsNullOrEmpty(strMessage);
|
|
|
- string result;
|
|
|
- if (flag)
|
|
|
- {
|
|
|
- result = "";
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- char[] array = new char[]
|
|
|
- {
|
|
|
- 'A',
|
|
|
- 'B',
|
|
|
- 'C',
|
|
|
- 'D',
|
|
|
- 'E',
|
|
|
- 'F',
|
|
|
- 'G',
|
|
|
- 'H',
|
|
|
- 'I',
|
|
|
- 'J',
|
|
|
- 'K',
|
|
|
- 'L',
|
|
|
- 'M',
|
|
|
- 'N',
|
|
|
- 'O',
|
|
|
- 'P',
|
|
|
- 'Q',
|
|
|
- 'R',
|
|
|
- 'S',
|
|
|
- 'T',
|
|
|
- 'U',
|
|
|
- 'V',
|
|
|
- 'W',
|
|
|
- 'X',
|
|
|
- 'Y',
|
|
|
- 'Z',
|
|
|
- 'a',
|
|
|
- 'b',
|
|
|
- 'c',
|
|
|
- 'd',
|
|
|
- 'e',
|
|
|
- 'f',
|
|
|
- 'g',
|
|
|
- 'h',
|
|
|
- 'i',
|
|
|
- 'j',
|
|
|
- 'k',
|
|
|
- 'l',
|
|
|
- 'm',
|
|
|
- 'n',
|
|
|
- 'o',
|
|
|
- 'p',
|
|
|
- 'q',
|
|
|
- 'r',
|
|
|
- 's',
|
|
|
- 't',
|
|
|
- 'u',
|
|
|
- 'v',
|
|
|
- 'w',
|
|
|
- 'x',
|
|
|
- 'y',
|
|
|
- 'z',
|
|
|
- '0',
|
|
|
- '1',
|
|
|
- '2',
|
|
|
- '3',
|
|
|
- '4',
|
|
|
- '5',
|
|
|
- '6',
|
|
|
- '7',
|
|
|
- '8',
|
|
|
- '9',
|
|
|
- '+',
|
|
|
- '/',
|
|
|
- '='
|
|
|
- };
|
|
|
- byte b = 0;
|
|
|
- ArrayList arrayList = new ArrayList(Encoding.Default.GetBytes(strMessage));
|
|
|
- int count = arrayList.Count;
|
|
|
- int num = count / 3;
|
|
|
- int num2 = count % 3;
|
|
|
- bool flag2 = num2 > 0;
|
|
|
- if (flag2)
|
|
|
- {
|
|
|
- for (int i = 0; i < 3 - num2; i++)
|
|
|
- {
|
|
|
- arrayList.Add(b);
|
|
|
- }
|
|
|
- num++;
|
|
|
- }
|
|
|
- StringBuilder stringBuilder = new StringBuilder(num * 4);
|
|
|
- for (int i = 0; i < num; i++)
|
|
|
- {
|
|
|
- byte[] array2 = new byte[]
|
|
|
- {
|
|
|
- (byte)arrayList[i * 3],
|
|
|
- (byte)arrayList[i * 3 + 1],
|
|
|
- (byte)arrayList[i * 3 + 2]
|
|
|
- };
|
|
|
- int[] array3 = new int[4];
|
|
|
- array3[0] = array2[0] >> 2;
|
|
|
- array3[1] = ((int)(array2[0] & 3) << 4 ^ array2[1] >> 4);
|
|
|
- bool flag3 = !array2[1].Equals(b);
|
|
|
- if (flag3)
|
|
|
- {
|
|
|
- array3[2] = ((int)(array2[1] & 15) << 2 ^ array2[2] >> 6);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- array3[2] = 64;
|
|
|
- }
|
|
|
- bool flag4 = !array2[2].Equals(b);
|
|
|
- if (flag4)
|
|
|
- {
|
|
|
- array3[3] = (int)(array2[2] & 63);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- array3[3] = 64;
|
|
|
- }
|
|
|
- stringBuilder.Append(array[array3[0]]);
|
|
|
- stringBuilder.Append(array[array3[1]]);
|
|
|
- stringBuilder.Append(array[array3[2]]);
|
|
|
- stringBuilder.Append(array[array3[3]]);
|
|
|
- }
|
|
|
- string text = stringBuilder.ToString();
|
|
|
- text = text.Replace("=", "@");
|
|
|
- text = text.Replace("+", "%2B");
|
|
|
- result = text;
|
|
|
- }
|
|
|
- return result;
|
|
|
- }
|
|
|
+ var client = _httpClientFactory.CreateClient(YbEnterpriseDefaults.HttpName);
|
|
|
+ clientInitialize?.Invoke(client);
|
|
|
+
|
|
|
+ using var responseMessage = await client.PostAsJsonAsync(path, request, cancellationToken);
|
|
|
+ responseMessage.EnsureSuccessStatusCode();
|
|
|
+ var result = await responseMessage.Content.ReadFromJsonAsync<TResponse>(cancellationToken: cancellationToken);
|
|
|
+ return result;
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+}
|