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.

332 lines
13 KiB

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