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.

293 lines
12 KiB

1 year ago
11 months ago
1 year ago
11 months ago
1 year ago
11 months ago
1 year ago
11 months 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 CreateAppointSmsTask(CreateSmsTaskDto smsDto)
  87. {
  88. var appointSmsTypeIdStr = _appConfig.GetSection("Sms")
  89. .GetSection("AppointSmsTypeId").Value;
  90. if (!Guid.TryParse(appointSmsTypeIdStr, out var appointSmsTypeId))
  91. {
  92. throw new Exception("解析预约成功短信类别ID错误");
  93. }
  94. var smsAppIdStr = _appConfig.GetSection("Sms")
  95. .GetSection("SmsAppId").Value;
  96. if (!Guid.TryParse(smsAppIdStr, out var smsAppId))
  97. {
  98. throw new Exception("解析短信应用ID错误");
  99. }
  100. string appointTemplateId = _appConfig.GetSection("Sms")
  101. .GetSection("AppointTemplateId").Value;
  102. smsDto.SmsAppId = smsAppId;
  103. smsDto.SmsTypeId = appointSmsTypeId;
  104. smsDto.TemplateId = appointTemplateId;
  105. var result = await CallAppServiceAsync<CreateSmsTaskDto, object>(_createSmsTaskUrl, smsDto);
  106. }
  107. public async static Task<TOut> CallAppServiceAsync<TInput, TOut>(string url, TInput data, string method = "post")
  108. {
  109. if (string.IsNullOrWhiteSpace(_baseAddress))
  110. {
  111. throw new Exception("_baseAddress不能为空");
  112. }
  113. string baseAddress = _baseAddress;
  114. await CheckLoginAsync();
  115. using (var httpClientHandler = new HttpClientHandler())
  116. {
  117. using (var httpClient = new HttpClient(httpClientHandler))
  118. {
  119. httpClient.BaseAddress = new Uri(baseAddress);
  120. httpClient.DefaultRequestHeaders.Accept.Add(
  121. new MediaTypeWithQualityHeaderValue("application/json"));//设置accept标头,告诉JSON是可接受的响应类型
  122. httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accesToken);
  123. var jsonOptions = new JsonSerializerOptions
  124. {
  125. WriteIndented = true, // 设置为true以便于可读性更好的JSON输出
  126. PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
  127. // 如果你想要对日期进行格式化,可以使用JsonConverter
  128. Converters = { new JsonDateTimeConverter("yyyy-MM-dd HH:mm:ss") }
  129. };
  130. var sendData = System.Text.Json.JsonSerializer.Serialize(data, jsonOptions);
  131. using (HttpContent httpContent = new StringContent(sendData))
  132. {
  133. httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  134. HttpResponseMessage response = null;
  135. if (method == "post")
  136. {
  137. response = await httpClient.PostAsync(url, httpContent);
  138. }
  139. else
  140. {
  141. response = await httpClient.GetAsync(url);
  142. }
  143. string result;
  144. if (!response.IsSuccessStatusCode)
  145. {
  146. result = response.Content.ReadAsStringAsync().Result;
  147. throw new Exception("http通信错误:" + response.StatusCode + ",结果:" + result);
  148. }
  149. result = await response.Content.ReadAsStringAsync();
  150. var resultDto = System.Text.Json.JsonSerializer.Deserialize<SmsWebApiOutDto<TOut>>(result, jsonOptions);
  151. if (resultDto.Code == -1)
  152. {
  153. throw new Exception($"调用WebApi失败,返回-1,消息:" + resultDto.Message);
  154. }
  155. return resultDto.Data;
  156. }
  157. }
  158. }
  159. }
  160. public async static Task<SmsWebApiOutDto<SmsLoginOutDataDto>> LoginAsync()
  161. {
  162. if (string.IsNullOrWhiteSpace(_user))
  163. {
  164. throw new Exception("SelfUser不能为空");
  165. }
  166. if (string.IsNullOrWhiteSpace(_password))
  167. {
  168. throw new Exception("SelfPassword不能为空");
  169. }
  170. var relult = await LoginAsync(_user, _password);
  171. return relult;
  172. }
  173. public async static Task<SmsWebApiOutDto<SmsLoginOutDataDto>> LoginAsync(string userId, string password)
  174. {
  175. if (string.IsNullOrWhiteSpace(userId))
  176. {
  177. throw new Exception("用户ID不能为空");
  178. }
  179. if (string.IsNullOrWhiteSpace(password))
  180. {
  181. throw new Exception("密码不能为空");
  182. }
  183. using (var httpClientHandler = new HttpClientHandler())
  184. {
  185. using (var httpClient = new HttpClient(httpClientHandler))
  186. {
  187. httpClient.BaseAddress = new Uri(_baseAddress);
  188. httpClient.DefaultRequestHeaders.Accept.Add(
  189. new MediaTypeWithQualityHeaderValue("application/json"));//设置accept标头,告诉JSON是可接受的响应类型
  190. var url = "api/app/CustomerUser/UserLogin";
  191. var jsonOptions = new JsonSerializerOptions
  192. {
  193. WriteIndented = true, // 设置为true以便于可读性更好的JSON输出
  194. PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
  195. // 如果你想要对日期进行格式化,可以使用JsonConverter
  196. Converters = { new JsonDateTimeConverter("yyyy-MM-dd HH:mm:ss") }
  197. };
  198. var loginUser = new SmsLoginInputDto()
  199. {
  200. UserName = userId,
  201. Password = password
  202. };
  203. var sendData = System.Text.Json.JsonSerializer.Serialize(loginUser);
  204. using (HttpContent httpContent = new StringContent(sendData))
  205. {
  206. httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  207. HttpResponseMessage response = await httpClient.PostAsync(url, httpContent);
  208. string result;
  209. if (!response.IsSuccessStatusCode)
  210. {
  211. result = response.Content.ReadAsStringAsync().Result;
  212. throw new Exception("登录短信系统时http通信错误:" + response.StatusCode + ",结果:" + result);
  213. }
  214. result = await response.Content.ReadAsStringAsync();
  215. var restultDto = System.Text.Json.JsonSerializer.Deserialize<SmsWebApiOutDto<SmsLoginOutDataDto>>(result, jsonOptions);
  216. if (restultDto == null)
  217. {
  218. throw new Exception("返回结果是空");
  219. }
  220. if (restultDto.Code != 1)
  221. {
  222. throw new Exception($"短信登录失败{restultDto.Message}");
  223. }
  224. _accesToken = restultDto.Data.access_token;
  225. return restultDto;
  226. }
  227. }
  228. }
  229. }
  230. private async static Task CheckLoginAsync()
  231. {
  232. if (string.IsNullOrWhiteSpace(_accesToken))
  233. {
  234. await LoginAsync();
  235. }
  236. else
  237. {
  238. var handler = new JwtSecurityTokenHandler();
  239. var payload = handler.ReadJwtToken(_accesToken).Payload;
  240. var claims = payload.Claims;
  241. var exp = claims.First(claim => claim.Type == "exp").Value;
  242. if (exp == null)
  243. {
  244. await LoginAsync();
  245. }
  246. else
  247. {
  248. if (long.TryParse(exp, out var expires))
  249. {
  250. var expireTime = DateTimeOffset.FromUnixTimeSeconds(expires).LocalDateTime;
  251. if (expireTime <= DateTime.Now)
  252. {
  253. await LoginAsync();
  254. }
  255. }
  256. else
  257. {
  258. await LoginAsync();
  259. }
  260. }
  261. }
  262. }
  263. }
  264. }