You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

264 lines
11 KiB

1 year ago
1 year ago
  1. using Microsoft.Extensions.Configuration;
  2. using Shentun.Utilities;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IdentityModel.Tokens.Jwt;
  6. using System.Linq;
  7. using System.Net.Http.Headers;
  8. using System.Text;
  9. using System.Text.Json;
  10. using System.Threading.Tasks;
  11. namespace Shentun.Sms.Client
  12. {
  13. public class SmsClientHelper
  14. {
  15. protected static IConfiguration? _appConfig;
  16. private static string? _baseAddress;
  17. private static string? _createSmsTaskUrl;
  18. private static string? _accesToken;
  19. private static string? _user;
  20. private static string? _password;
  21. private static string? _email;
  22. static SmsClientHelper()
  23. {
  24. _appConfig = new ConfigurationBuilder()
  25. .SetBasePath(DirectoryHelper.GetAppDirectory()) // 设置基础路径为当前目录
  26. .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
  27. .Build();
  28. _baseAddress = _appConfig.GetSection("Sms")
  29. .GetSection("BaseAddress").Value;
  30. _createSmsTaskUrl = _appConfig.GetSection("Sms")
  31. .GetSection("CreateSmsTaskUrl").Value;
  32. _user = _appConfig.GetSection("Sms")
  33. .GetSection("User").Value;
  34. _password = _appConfig.GetSection("Sms")
  35. .GetSection("Password").Value;
  36. }
  37. public async static Task CreateSmsTask(CreateSmsTaskDto createSmsTaskDto)
  38. {
  39. if (createSmsTaskDto == null)
  40. {
  41. throw new Exception("createSmsTaskDto参数不能为空");
  42. }
  43. if (createSmsTaskDto.MobileTelephone.Length != 11)
  44. {
  45. throw new Exception("手机号长度必须为11位");
  46. }
  47. if(string.IsNullOrWhiteSpace(createSmsTaskDto.PersonId))
  48. {
  49. throw new Exception("人员ID不能为空");
  50. }
  51. if (string.IsNullOrWhiteSpace(createSmsTaskDto.PersonName))
  52. {
  53. throw new Exception("姓名不能为空");
  54. }
  55. if (string.IsNullOrWhiteSpace(createSmsTaskDto.CountryCode))
  56. {
  57. throw new Exception("国家编码不能为空");
  58. }
  59. if (string.IsNullOrWhiteSpace(createSmsTaskDto.Content))
  60. {
  61. throw new Exception("短信内容不能为空");
  62. }
  63. if (createSmsTaskDto.SmsAppId == null || createSmsTaskDto.SmsAppId == Guid.Empty)
  64. {
  65. var smsAppIdStr = _appConfig.GetSection("Sms")
  66. .GetSection("SmsAppId").Value;
  67. if (!Guid.TryParse(smsAppIdStr, out var smsAppId))
  68. {
  69. throw new Exception("解析短信应用ID错误");
  70. }
  71. createSmsTaskDto.SmsAppId = smsAppId;
  72. }
  73. var reslut = await CallAppServiceAsync<CreateSmsTaskDto, object>(_createSmsTaskUrl, createSmsTaskDto);
  74. }
  75. public async static Task CreateVerifySmsTask(CreateSmsTaskDto smsDto)
  76. {
  77. var verifySmsTypeIdStr = _appConfig.GetSection("Sms")
  78. .GetSection("VerifySmsTypeId").Value;
  79. if (!Guid.TryParse(verifySmsTypeIdStr, out var verifySmsTypeId))
  80. {
  81. throw new Exception("解析校验短信类别ID错误");
  82. }
  83. smsDto.SmsTypeId = verifySmsTypeId;
  84. await CreateSmsTask(smsDto);
  85. }
  86. public async static Task<TOut> CallAppServiceAsync<TInput, TOut>(string url, TInput data, string method = "post")
  87. {
  88. if (string.IsNullOrWhiteSpace(_baseAddress))
  89. {
  90. throw new Exception("_baseAddress不能为空");
  91. }
  92. string baseAddress = _baseAddress;
  93. await CheckLoginAsync();
  94. using (var httpClientHandler = new HttpClientHandler())
  95. {
  96. using (var httpClient = new HttpClient(httpClientHandler))
  97. {
  98. httpClient.BaseAddress = new Uri(baseAddress);
  99. httpClient.DefaultRequestHeaders.Accept.Add(
  100. new MediaTypeWithQualityHeaderValue("application/json"));//设置accept标头,告诉JSON是可接受的响应类型
  101. httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accesToken);
  102. var jsonOptions = new JsonSerializerOptions
  103. {
  104. WriteIndented = true, // 设置为true以便于可读性更好的JSON输出
  105. PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
  106. // 如果你想要对日期进行格式化,可以使用JsonConverter
  107. Converters = { new JsonDateTimeConverter("yyyy-MM-dd HH:mm:ss") }
  108. };
  109. var sendData = System.Text.Json.JsonSerializer.Serialize(data, jsonOptions);
  110. using (HttpContent httpContent = new StringContent(sendData))
  111. {
  112. httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  113. HttpResponseMessage response = null;
  114. if (method == "post")
  115. {
  116. response = await httpClient.PostAsync(url, httpContent);
  117. }
  118. else
  119. {
  120. response = await httpClient.GetAsync(url);
  121. }
  122. string result;
  123. if (!response.IsSuccessStatusCode)
  124. {
  125. result = response.Content.ReadAsStringAsync().Result;
  126. throw new Exception("http通信错误:" + response.StatusCode + ",结果:" + result);
  127. }
  128. result = await response.Content.ReadAsStringAsync();
  129. var resultDto = System.Text.Json.JsonSerializer.Deserialize<SmsWebApiOutDto<TOut>>(result,jsonOptions);
  130. if (resultDto.Code == -1)
  131. {
  132. throw new Exception($"调用WebApi失败,返回-1,消息:" + resultDto.Message);
  133. }
  134. return resultDto.Data;
  135. }
  136. }
  137. }
  138. }
  139. public async static Task<SmsWebApiOutDto<SmsLoginOutDataDto>> LoginAsync()
  140. {
  141. if (string.IsNullOrWhiteSpace(_user))
  142. {
  143. throw new Exception("SelfUser不能为空");
  144. }
  145. if (string.IsNullOrWhiteSpace(_password))
  146. {
  147. throw new Exception("SelfPassword不能为空");
  148. }
  149. var relult = await LoginAsync(_user, _password);
  150. return relult;
  151. }
  152. public async static Task<SmsWebApiOutDto<SmsLoginOutDataDto>> LoginAsync(string userId, string password)
  153. {
  154. if (string.IsNullOrWhiteSpace(userId))
  155. {
  156. throw new Exception("用户ID不能为空");
  157. }
  158. if (string.IsNullOrWhiteSpace(password))
  159. {
  160. throw new Exception("密码不能为空");
  161. }
  162. using (var httpClientHandler = new HttpClientHandler())
  163. {
  164. using (var httpClient = new HttpClient(httpClientHandler))
  165. {
  166. httpClient.BaseAddress = new Uri(_baseAddress);
  167. httpClient.DefaultRequestHeaders.Accept.Add(
  168. new MediaTypeWithQualityHeaderValue("application/json"));//设置accept标头,告诉JSON是可接受的响应类型
  169. var url = "api/app/CustomerUser/UserLogin";
  170. var jsonOptions = new JsonSerializerOptions
  171. {
  172. WriteIndented = true, // 设置为true以便于可读性更好的JSON输出
  173. PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
  174. // 如果你想要对日期进行格式化,可以使用JsonConverter
  175. Converters = { new JsonDateTimeConverter("yyyy-MM-dd HH:mm:ss") }
  176. };
  177. var loginUser = new SmsLoginInputDto()
  178. {
  179. UserName = userId,
  180. Password = password
  181. };
  182. var sendData = System.Text.Json.JsonSerializer.Serialize(loginUser);
  183. using (HttpContent httpContent = new StringContent(sendData))
  184. {
  185. httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  186. HttpResponseMessage response = await httpClient.PostAsync(url, httpContent);
  187. string result;
  188. if (!response.IsSuccessStatusCode)
  189. {
  190. result = response.Content.ReadAsStringAsync().Result;
  191. throw new Exception("登录短信系统时http通信错误:" + response.StatusCode + ",结果:" + result);
  192. }
  193. result = await response.Content.ReadAsStringAsync();
  194. var restultDto = System.Text.Json.JsonSerializer.Deserialize<SmsWebApiOutDto<SmsLoginOutDataDto>>(result, jsonOptions);
  195. if (restultDto == null)
  196. {
  197. throw new Exception("返回结果是空");
  198. }
  199. if (restultDto.Code != 1)
  200. {
  201. throw new Exception($"短信登录失败{restultDto.Message}");
  202. }
  203. _accesToken = restultDto.Data.access_token;
  204. return restultDto;
  205. }
  206. }
  207. }
  208. }
  209. private async static Task CheckLoginAsync()
  210. {
  211. if (string.IsNullOrWhiteSpace(_accesToken))
  212. {
  213. await LoginAsync();
  214. }
  215. else
  216. {
  217. var handler = new JwtSecurityTokenHandler();
  218. var payload = handler.ReadJwtToken(_accesToken).Payload;
  219. var claims = payload.Claims;
  220. var exp = claims.First(claim => claim.Type == "exp").Value;
  221. if (exp == null)
  222. {
  223. await LoginAsync();
  224. }
  225. else
  226. {
  227. if (long.TryParse(exp, out var expires))
  228. {
  229. var expireTime = DateTimeOffset.FromUnixTimeSeconds(expires).LocalDateTime;
  230. if (expireTime <= DateTime.Now)
  231. {
  232. await LoginAsync();
  233. }
  234. }
  235. else
  236. {
  237. await LoginAsync();
  238. }
  239. }
  240. }
  241. }
  242. }
  243. }