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.

330 lines
13 KiB

1 year ago
  1. using Microsoft.Data.SqlClient;
  2. using Microsoft.Extensions.Configuration;
  3. using Microsoft.Extensions.Logging;
  4. using Newtonsoft.Json;
  5. using Newtonsoft.Json.Converters;
  6. using Npgsql;
  7. using Oracle.ManagedDataAccess.Client;
  8. using Shentun.Utilities;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Data.Common;
  12. using System.IdentityModel.Tokens.Jwt;
  13. using System.Linq;
  14. using System.Linq.Dynamic.Core.Tokenizer;
  15. using System.Net.Http.Headers;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. namespace Shentun.WebPeis.PlugIns
  19. {
  20. public class PlugInsBase
  21. {
  22. protected IConfiguration? AppConfig;
  23. protected IConfiguration? InterfaceConfig;
  24. protected string? AppConnctionStr;
  25. private string? _appBaseAddress;
  26. private static string? _accesToken;
  27. protected string? AppUser;
  28. protected string? AppPassword;
  29. protected string? InterfaceSql;
  30. protected string? InterfaceSqlKeyColumn;
  31. protected string? InterfaceDbType;
  32. protected string? InterfaceConnctionStr;
  33. protected string? InterfaceWebApiUrl;
  34. protected Guid ItemColumnReferenceId;
  35. protected Guid AsbitemColumnReferenceId;
  36. protected Guid DepartmentColumnReferenceId;
  37. protected Guid UserColumnReferenceId;
  38. protected ILogger<PlugInsBase> Logger;
  39. static PlugInsBase()
  40. {
  41. Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
  42. }
  43. public PlugInsBase()
  44. {
  45. Init();
  46. }
  47. public PlugInsBase(string parmValue)
  48. {
  49. Init();
  50. Init(parmValue);
  51. }
  52. public void Init()
  53. {
  54. AppConfig = new ConfigurationBuilder()
  55. .SetBasePath(DirectoryHelper.GetAppDirectory()) // 设置基础路径为当前目录
  56. .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
  57. .Build();
  58. AppConnctionStr = AppConfig.GetSection("ConnectionStrings")
  59. .GetSection("Default").Value;
  60. _appBaseAddress = AppConfig.GetSection("App")
  61. .GetSection("SelfUrl").Value;
  62. AppUser = AppConfig.GetSection("App")
  63. .GetSection("SelfUser").Value;
  64. AppPassword = AppConfig.GetSection("App")
  65. .GetSection("SelfPassword").Value;
  66. using var loggerFactory = LoggerFactory.Create(builder =>
  67. {
  68. });
  69. Logger = loggerFactory.CreateLogger<PlugInsBase>();
  70. }
  71. public void Init(string parmValue)
  72. {
  73. var configurationBuilder = new ConfigurationBuilder()
  74. .AddJsonStream(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(parmValue)));
  75. InterfaceConfig = configurationBuilder.Build();
  76. //如果接口配置里面配置了用户名密码,则用接口中的覆盖本地配置
  77. var appUser = InterfaceConfig.GetSection("App").GetSection("User").Value;
  78. if(!string.IsNullOrWhiteSpace(appUser))
  79. {
  80. AppUser = appUser;
  81. }
  82. var appPassword = InterfaceConfig.GetSection("App").GetSection("Password").Value;
  83. if (!string.IsNullOrWhiteSpace(appPassword))
  84. {
  85. AppPassword = appPassword;
  86. }
  87. //设置接口有关配置
  88. InterfaceSql = InterfaceConfig.GetSection("Interface").GetSection("Sql").Value;
  89. InterfaceSqlKeyColumn = InterfaceConfig.GetSection("Interface").GetSection("SqlKeyColumn").Value;
  90. InterfaceDbType = InterfaceConfig.GetSection("Interface").GetSection("DbType").Value;
  91. InterfaceWebApiUrl = InterfaceConfig.GetSection("Interface").GetSection("WebApiUrl").Value;
  92. InterfaceConnctionStr = InterfaceConfig.GetSection("Interface").GetSection("ConnectionStrings").Value;
  93. var itemColumnReferenceIdStr = InterfaceConfig.GetSection("Interface")
  94. .GetSection("ItemColumnReferenceId").Value;
  95. if (!string.IsNullOrWhiteSpace(itemColumnReferenceIdStr))
  96. {
  97. ItemColumnReferenceId = new Guid(itemColumnReferenceIdStr);
  98. }
  99. var asbItemColumnReferenceIdStr = InterfaceConfig.GetSection("Interface")
  100. .GetSection("AsbitemColumnReferenceId").Value;
  101. if (!string.IsNullOrWhiteSpace(asbItemColumnReferenceIdStr))
  102. {
  103. AsbitemColumnReferenceId = new Guid(asbItemColumnReferenceIdStr);
  104. }
  105. var departmentColumnReferenceIdStr = InterfaceConfig.GetSection("Interface")
  106. .GetSection("DepartmentColumnReferenceId").Value;
  107. if (!string.IsNullOrWhiteSpace(departmentColumnReferenceIdStr))
  108. {
  109. DepartmentColumnReferenceId = new Guid(departmentColumnReferenceIdStr);
  110. }
  111. var userColumnReferenceIdStr = InterfaceConfig.GetSection("Interface")
  112. .GetSection("UserColumnReferenceId").Value;
  113. if (!string.IsNullOrWhiteSpace(userColumnReferenceIdStr))
  114. {
  115. UserColumnReferenceId = new Guid(userColumnReferenceIdStr);
  116. }
  117. }
  118. protected DbConnection CreateInterfaceDbConnect()
  119. {
  120. DbConnection conn;
  121. if (string.IsNullOrWhiteSpace(InterfaceConnctionStr))
  122. {
  123. throw new ArgumentException("数据连接设置中的DbType不能为空");
  124. }
  125. InterfaceDbType = InterfaceDbType.ToLower();
  126. //Logger.LogInformation("数据库类型:" + InterfaceDbType);
  127. if (InterfaceDbType == "sqlserver")
  128. {
  129. //Logger.LogInformation("调用sqlserver:" + InterfaceDbType);
  130. conn = new SqlConnection(InterfaceConnctionStr);
  131. }
  132. else if (InterfaceDbType == "postgres")
  133. {
  134. //Logger.LogInformation("调用postgres:" + InterfaceDbType);
  135. conn = new NpgsqlConnection(InterfaceConnctionStr);
  136. }
  137. else if (InterfaceDbType == "oracle")
  138. {
  139. //Logger.LogInformation("调用oracle:" + InterfaceDbType);
  140. conn = new OracleConnection(InterfaceConnctionStr);
  141. }
  142. else
  143. {
  144. throw new ArgumentException("数据连接设置中的DbType不支持");
  145. }
  146. return conn;
  147. }
  148. public async Task<TOut> CallAppServiceAsync<TInput, TOut>(string url, TInput data, string method = "post")
  149. {
  150. if(string.IsNullOrWhiteSpace(_appBaseAddress))
  151. {
  152. throw new Exception("_appBaseAddress不能为空");
  153. }
  154. string baseAddress = _appBaseAddress;
  155. await CheckLoginAsync();
  156. using (var httpClientHandler = new HttpClientHandler())
  157. {
  158. using (var httpClient = new HttpClient(httpClientHandler))
  159. {
  160. httpClient.BaseAddress = new Uri(baseAddress);
  161. httpClient.DefaultRequestHeaders.Accept.Add(
  162. new MediaTypeWithQualityHeaderValue("application/json"));//设置accept标头,告诉JSON是可接受的响应类型
  163. httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accesToken);
  164. IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
  165. timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
  166. var sendData = JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.Indented, timeFormat);
  167. using (HttpContent httpContent = new StringContent(sendData))
  168. {
  169. httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  170. HttpResponseMessage response = null;
  171. if (method == "post")
  172. {
  173. response = await httpClient.PostAsync(url, httpContent);
  174. }
  175. else
  176. {
  177. response = await httpClient.GetAsync(url);
  178. }
  179. string result;
  180. if (!response.IsSuccessStatusCode)
  181. {
  182. result = response.Content.ReadAsStringAsync().Result;
  183. throw new Exception("http通信错误:" + response.StatusCode + ",结果:" + result);
  184. }
  185. result = await response.Content.ReadAsStringAsync();
  186. var resultDto = JsonConvert.DeserializeObject< WebApiOutDto<TOut>>(result);
  187. if (resultDto.Code == -1)
  188. {
  189. throw new Exception($"调用WebApi失败,返回-1,消息:" + resultDto.Message);
  190. }
  191. return resultDto.Data;
  192. }
  193. }
  194. }
  195. }
  196. public virtual async Task DoWorkAsync()
  197. {
  198. }
  199. public virtual Task DoWork()
  200. {
  201. return Task.CompletedTask;
  202. }
  203. public async virtual Task<WebApiOutDto<LoginOutDataDto>> LoginAsync()
  204. {
  205. if(string.IsNullOrWhiteSpace(AppUser))
  206. {
  207. throw new Exception("SelfUser不能为空");
  208. }
  209. if (string.IsNullOrWhiteSpace(AppPassword))
  210. {
  211. throw new Exception("SelfPassword不能为空");
  212. }
  213. var relult = await LoginAsync(AppUser, AppPassword);
  214. return relult;
  215. }
  216. public async Task<WebApiOutDto<LoginOutDataDto>> LoginAsync(string userId, string password)
  217. {
  218. if (string.IsNullOrWhiteSpace(userId))
  219. {
  220. throw new Exception("用户ID不能为空");
  221. }
  222. if (string.IsNullOrWhiteSpace(password))
  223. {
  224. throw new Exception("密码不能为空");
  225. }
  226. using (var httpClientHandler = new HttpClientHandler())
  227. {
  228. using (var httpClient = new HttpClient(httpClientHandler))
  229. {
  230. httpClient.BaseAddress = new Uri(_appBaseAddress);
  231. httpClient.DefaultRequestHeaders.Accept.Add(
  232. new MediaTypeWithQualityHeaderValue("application/json"));//设置accept标头,告诉JSON是可接受的响应类型
  233. var url = "api/identity/users/login";
  234. var loginUser = new LoginInputDto()
  235. {
  236. UserName = userId,
  237. Password = password
  238. };
  239. var sendData = JsonConvert.SerializeObject(loginUser);
  240. using (HttpContent httpContent = new StringContent(sendData))
  241. {
  242. httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
  243. HttpResponseMessage response = await httpClient.PostAsync(url, httpContent);
  244. string result;
  245. if (!response.IsSuccessStatusCode)
  246. {
  247. result = response.Content.ReadAsStringAsync().Result;
  248. throw new Exception("http通信错误:" + response.StatusCode + ",结果:" + result);
  249. }
  250. result = await response.Content.ReadAsStringAsync();
  251. var restultDto = JsonConvert.DeserializeObject<WebApiOutDto<LoginOutDataDto>>(result);
  252. if (restultDto == null)
  253. {
  254. throw new Exception("返回结果是空");
  255. }
  256. if (restultDto.Code != 1)
  257. {
  258. throw new Exception($"登录失败{restultDto.Message}");
  259. }
  260. _accesToken = restultDto.Data.access_token;
  261. return restultDto;
  262. }
  263. }
  264. }
  265. }
  266. private async Task CheckLoginAsync()
  267. {
  268. if (string.IsNullOrWhiteSpace(_accesToken))
  269. {
  270. await LoginAsync();
  271. }
  272. else
  273. {
  274. var handler = new JwtSecurityTokenHandler();
  275. var payload = handler.ReadJwtToken(_accesToken).Payload;
  276. var claims = payload.Claims;
  277. var exp = claims.First(claim => claim.Type == "exp").Value;
  278. if (exp == null)
  279. {
  280. await LoginAsync();
  281. }
  282. else
  283. {
  284. if (long.TryParse(exp, out var expires))
  285. {
  286. var expireTime = DateTimeOffset.FromUnixTimeSeconds(expires).LocalDateTime;
  287. if (expireTime <= DateTime.Now)
  288. {
  289. await LoginAsync();
  290. }
  291. }
  292. else
  293. {
  294. await LoginAsync();
  295. }
  296. }
  297. }
  298. }
  299. }
  300. }