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.

451 lines
19 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. using Shentun.WebPeis.Models;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using Volo.Abp.Application.Services;
  8. using Volo.Abp.Domain.Entities;
  9. using Volo.Abp.Domain.Repositories;
  10. using Volo.Abp.Users;
  11. using Shentun.WebPeis.Wechats;
  12. using Microsoft.Extensions.Configuration;
  13. using System.Net.Http;
  14. using System.Net;
  15. using System.Text.Json;
  16. using Volo.Abp.Identity;
  17. using Volo.Abp;
  18. using Shentun.WebPeis.Enums;
  19. using System.Net.Http.Headers;
  20. using Microsoft.AspNetCore.Mvc;
  21. using OpenIddict.Abstractions;
  22. using Microsoft.AspNetCore.Identity;
  23. using Volo.Abp.ObjectMapping;
  24. using Microsoft.AspNetCore.Authorization;
  25. using Volo.Abp.Caching;
  26. using NPOI.SS.Formula.Functions;
  27. using System.Linq.Dynamic.Core.Tokenizer;
  28. using Microsoft.Extensions.Caching.Distributed;
  29. using Volo.Abp.Uow;
  30. using Scriban.Parsing;
  31. using System.IdentityModel.Tokens.Jwt;
  32. using Shentun.WebPeis.PatientRegisters;
  33. using Microsoft.AspNetCore.Http;
  34. using System.IO;
  35. using Shentun.WebPeis.CustomerOrgs;
  36. namespace Shentun.WebPeis.Persons
  37. {
  38. /// <summary>
  39. /// 微信人员
  40. /// </summary>
  41. [ApiExplorerSettings(GroupName = "Work")]
  42. [Authorize]
  43. public class PersonAppService : ApplicationService
  44. {
  45. private readonly IConfiguration _configuration;
  46. private readonly IRepository<IdentityUser, Guid> _identityUserRepository;
  47. private readonly IdentityUserManager _userManager;
  48. private readonly IRepository<Person> _repository;
  49. private readonly PersonManager _personManager;
  50. private readonly IDistributedCache<string, string> _cache;
  51. private readonly IUnitOfWorkManager _unitOfWorkManager;
  52. private readonly IRepository<PersonKinship> _personKinshipRepository;
  53. private readonly IRepository<PatientRegister> _patientRegisterRepository;
  54. private readonly IRepository<Patient> _patientRepository;
  55. private readonly CacheService _cacheService;
  56. private readonly IHttpContextAccessor _httpContextAccessor;
  57. private readonly IRepository<CustomerOrg> _customerOrgRepository;
  58. public PersonAppService(IRepository<Person> repository,
  59. IConfiguration configuration,
  60. IRepository<Volo.Abp.Identity.IdentityUser, Guid> identityUserRepository,
  61. IdentityUserManager userManager,
  62. PersonManager personManager,
  63. IUnitOfWorkManager unitOfWorkManager,
  64. IDistributedCache<string, string> cache,
  65. IRepository<PersonKinship> personKinshipRepository,
  66. IRepository<PatientRegister> patientRegisterRepository,
  67. IRepository<Patient> patientRepository,
  68. CacheService cacheService,
  69. IHttpContextAccessor httpContextAccessor,
  70. IRepository<CustomerOrg> customerOrgRepository)
  71. {
  72. _repository = repository;
  73. _configuration = configuration;
  74. _identityUserRepository = identityUserRepository;
  75. _userManager = userManager;
  76. _personManager = personManager;
  77. _unitOfWorkManager = unitOfWorkManager;
  78. _cache = cache;
  79. _personKinshipRepository = personKinshipRepository;
  80. _patientRegisterRepository = patientRegisterRepository;
  81. _patientRepository = patientRepository;
  82. _cacheService = cacheService;
  83. _httpContextAccessor = httpContextAccessor;
  84. _customerOrgRepository = customerOrgRepository;
  85. }
  86. public async Task<PersonDto> GetByIdAsync(PersonIdInputDto input)
  87. {
  88. var entity = await _repository.GetAsync(o => o.PersonId == input.PersonId);
  89. var entityDto = ObjectMapper.Map<Person, PersonDto>(entity);
  90. return entityDto;
  91. }
  92. /// <summary>
  93. /// 微信用户登录
  94. /// </summary>
  95. /// <param name="input"></param>
  96. /// <returns></returns>
  97. [AllowAnonymous]
  98. [HttpPost("api/app/Person/WeChatUserLogin")]
  99. public async Task<UserTokenDto> WeChatUserLoginAsync(WechatUserJsCodeInputDto input)
  100. {
  101. var weChatClientId = _configuration.GetSection("AuthServer").GetSection("WeChatClientId").Value;
  102. var secret = _configuration.GetSection("AuthServer").GetSection("WeChatClientSecret").Value;
  103. var commonScopes = new List<string> {
  104. OpenIddictConstants.Permissions.Scopes.Address,
  105. OpenIddictConstants.Permissions.Scopes.Email,
  106. OpenIddictConstants.Permissions.Scopes.Phone,
  107. OpenIddictConstants.Permissions.Scopes.Profile,
  108. OpenIddictConstants.Permissions.Scopes.Roles,
  109. "WebPeis"
  110. };
  111. var dic = new Dictionary<string, object>
  112. {
  113. {"jsCode",input.JsCode},
  114. {"client_id",weChatClientId},
  115. {"client_secret",secret},
  116. {"grant_type",WeChatGrant.GrantType},
  117. {"scope","WeChat offline_access"}
  118. };
  119. var dicStr = dic.Select(m => m.Key + "=" + m.Value).DefaultIfEmpty().Aggregate((m, n) => m + "&" + n);
  120. var token = await GetTokenAsync(dicStr);
  121. return token;
  122. }
  123. [AllowAnonymous]
  124. [HttpPost("api/app/Person/Create")]
  125. [UnitOfWork(IsDisabled = false)]
  126. public async Task<UserTokenDto> CreateAsync(CreatePersonDto input)
  127. {
  128. using (var unitOfWork = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true))
  129. {
  130. var entity = ObjectMapper.Map<CreatePersonDto, Person>(input);
  131. if (string.IsNullOrWhiteSpace(input.JsCode))
  132. {
  133. throw new UserFriendlyException("jsCode不能为空");
  134. }
  135. if (string.IsNullOrWhiteSpace(input.WechatOpenId))
  136. {
  137. throw new UserFriendlyException("WechatOpenId不能为空");
  138. }
  139. if (_cache.Get(CacheKeys.OpenIdKey + input.WechatOpenId) != input.WechatOpenId)
  140. {
  141. throw new UserFriendlyException("无效的WechatOpenId");
  142. }
  143. var person = await _repository.FindAsync(o => o.IdNo == input.IdNo);
  144. if (person != null)
  145. {
  146. var user = (await _identityUserRepository.GetQueryableAsync()).Where(o => o.Id == person.PersonId &&
  147. o.PhoneNumber == input.MobileTelephone).FirstOrDefault();
  148. if (user == null)
  149. {
  150. throw new UserFriendlyException("该身份证号已注册,但手机号码不一致");
  151. }
  152. if(!string.IsNullOrWhiteSpace(person.WechatOpenId))
  153. {
  154. throw new UserFriendlyException("该微信号已注册");
  155. }
  156. person.WechatOpenId = input.WechatOpenId;
  157. await _repository.UpdateAsync(person);
  158. await unitOfWork.SaveChangesAsync();
  159. await unitOfWork.CompleteAsync();
  160. }
  161. else
  162. {
  163. entity.WechatOpenId = input.WechatOpenId;
  164. var userWithPerson = await _personManager.CreateAsync(entity, input.PersonName,
  165. input.Email, input.MobileTelephone);
  166. await _identityUserRepository.InsertAsync(userWithPerson.User);
  167. await _repository.InsertAsync(userWithPerson.Person);
  168. //设置密码
  169. (await _userManager.RemovePasswordAsync(userWithPerson.User)).CheckErrors();
  170. (await _userManager.AddPasswordAsync(userWithPerson.User, Shentun.Utilities.
  171. Encrypt.RandomHelper.CreateRandom(Utilities.Enums.RandomType.NumAndChar, 10) + "0Cz*")).CheckErrors();
  172. await unitOfWork.SaveChangesAsync();
  173. await unitOfWork.CompleteAsync();
  174. }
  175. }
  176. using (var unitOfWork = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
  177. {
  178. var weChatClientId = _configuration.GetSection("AuthServer").GetSection("WeChatClientId").Value;
  179. var secret = _configuration.GetSection("AuthServer").GetSection("WeChatClientSecret").Value;
  180. var dic = new Dictionary<string, object>
  181. {
  182. {"jsCode",input.JsCode},
  183. {"client_id",weChatClientId},
  184. {"client_secret",secret},
  185. {"grant_type",WeChatGrant.GrantType},
  186. {"scope","WeChat offline_access"}
  187. };
  188. var dicStr = dic.Select(m => m.Key + "=" + m.Value).DefaultIfEmpty().Aggregate((m, n) => m + "&" + n);
  189. var token = await GetTokenAsync(dicStr);
  190. //var entityDto = ObjectMapper.Map<Person, PersonDto>(userWithPerson.Person);
  191. await unitOfWork.CompleteAsync();
  192. return token;
  193. }
  194. }
  195. /// <summary>
  196. /// 创建亲属
  197. /// </summary>
  198. /// <param name="input"></param>
  199. /// <returns></returns>
  200. /// <exception cref="UserFriendlyException"></exception>
  201. [HttpPost("api/app/Person/CreatePersonKinship")]
  202. public async Task CreatePersonKinshipAsync(CreatePersonKinshipDto input)
  203. {
  204. var entity = ObjectMapper.Map<CreatePersonKinshipDto, Person>(input);
  205. if (string.IsNullOrWhiteSpace(input.KinshipId))
  206. {
  207. throw new UserFriendlyException("亲属关系不能为空");
  208. }
  209. var person = await _repository.FindAsync(o=>o.IdNo == input.IdNo);
  210. if (person != null)
  211. {
  212. var user = (await _identityUserRepository.GetQueryableAsync()).Where(o =>o.Id == person.PersonId &&
  213. o.PhoneNumber == input.MobileTelephone).FirstOrDefault();
  214. if(user == null)
  215. {
  216. throw new UserFriendlyException("该身份证号已注册,但手机号码不一致");
  217. }
  218. var personKinshipExist = new PersonKinship()
  219. {
  220. PersonId = person.PersonId,
  221. ParentPersonId = (Guid)CurrentUser.Id,
  222. KinshipId = input.KinshipId,
  223. };
  224. await _personKinshipRepository.InsertAsync(personKinshipExist);
  225. return;
  226. }
  227. var userWithPerson = await _personManager.CreateAsync(entity, input.PersonName,
  228. input.Email, input.MobileTelephone);
  229. var personKinship = new PersonKinship()
  230. {
  231. PersonId = userWithPerson.Person.PersonId,
  232. ParentPersonId = (Guid)CurrentUser.Id,
  233. KinshipId = input.KinshipId,
  234. };
  235. await _identityUserRepository.InsertAsync(userWithPerson.User);
  236. await _repository.InsertAsync(userWithPerson.Person);
  237. await _personKinshipRepository.InsertAsync(personKinship);
  238. //设置密码
  239. (await _userManager.RemovePasswordAsync(userWithPerson.User)).CheckErrors();
  240. (await _userManager.AddPasswordAsync(userWithPerson.User, Shentun.Utilities.
  241. Encrypt.RandomHelper.CreateRandom(Utilities.Enums.RandomType.NumAndChar, 10) + "0Cz*")).CheckErrors();
  242. }
  243. /// <summary>
  244. /// 获取体检次数列表
  245. /// </summary>
  246. /// <param name="input"></param>
  247. /// <returns></returns>
  248. [HttpPost("api/app/Person/GetMedicalTimesListByPersonId")]
  249. public async Task<List<PersonMedicalTimesDto>> GetMedicalTimesListByPersonIdAsync(PersonIdInputDto input)
  250. {
  251. var entityList = (from user in await _identityUserRepository.GetQueryableAsync()
  252. join person in await _repository.GetQueryableAsync()
  253. on user.Id equals person.PersonId
  254. join patient in await _patientRepository.GetQueryableAsync()
  255. on new { idNo = person.IdNo ,phone = user.PhoneNumber} equals new { idNo = patient.IdNo, phone = patient.MobileTelephone }
  256. join patientRegister in await _patientRegisterRepository.GetQueryableAsync()
  257. on patient.PatientId equals patientRegister.PatientId
  258. where user.Id == input.PersonId &&
  259. ( patientRegister.CompleteFlag == PatientRegisterCompleteFlag.Audit)
  260. orderby patientRegister.MedicalStartDate
  261. select new PersonMedicalTimesDto()
  262. {
  263. PatientRegisterId = patientRegister.PatientRegisterId,
  264. PersonName = patient.PatientName,
  265. MedicalStartDate = patientRegister.MedicalStartDate,
  266. }).ToList();
  267. return entityList;
  268. }
  269. /// <summary>
  270. /// 获取本人和亲属列表
  271. /// </summary>
  272. /// <returns></returns>
  273. [HttpPost("api/app/Person/GetPersonKinshipList")]
  274. public async Task<List<PersonDto>> GetPersonKinshipList()
  275. {
  276. var personKinshipIds = (await _personKinshipRepository.GetQueryableAsync())
  277. .Where(o => o.ParentPersonId == CurrentUser.Id)
  278. .Select(o => o.PersonId).ToList();
  279. personKinshipIds.Add((Guid)CurrentUser.Id);
  280. var personList = (from user in await _identityUserRepository.GetQueryableAsync()
  281. join person in await _repository.GetQueryableAsync()
  282. on user.Id equals person.PersonId
  283. where personKinshipIds.Contains(user.Id)
  284. orderby user.CreationTime
  285. select new PersonDto
  286. {
  287. PersonId = user.Id,
  288. PersonName = user.Name,
  289. SexId = person.SexId,
  290. SexName = _cacheService.GetSexNameAsync(person.SexId).Result,
  291. MaritalStatusId = person.MaritalStatusId,
  292. MaritalStatusName = _cacheService.GetMaritalStatusNameAsync(person.MaritalStatusId).Result,
  293. IdNo = person.IdNo,
  294. MobileTelephone = user.PhoneNumber
  295. }).ToList();
  296. for(var i = 0; i<personList.Count;i++)
  297. {
  298. personList[i].DisplayOrder = i + 1;
  299. if (personList[i].PersonId == CurrentUser.Id)
  300. {
  301. personList[i].DisplayOrder = 0; //本人强行排第一个
  302. }
  303. }
  304. personList = personList.OrderBy(o=>o.DisplayOrder).ToList();
  305. return personList;
  306. }
  307. /// <summary>
  308. /// 获取PDF体检报告
  309. /// </summary>
  310. /// <param name="input"></param>
  311. /// <returns></returns>
  312. /// <exception cref="UserFriendlyException"></exception>
  313. [HttpPost("api/app/Person/GetMedicalReportByPatientRegisterId")]
  314. public async Task<MedicalReportDto> GetMedicalReportByPatientRegisterIdAsync(PatientRegisterIdInputDto input)
  315. {
  316. var entity = await _patientRegisterRepository.GetAsync(o=>o.PatientRegisterId == input.PatientRegisterId);
  317. if(string.IsNullOrWhiteSpace(entity.ReportFile))
  318. {
  319. throw new UserFriendlyException("没有报告单");
  320. }
  321. var Host = $"{_httpContextAccessor.HttpContext.Request.Scheme}://{_httpContextAccessor.HttpContext.Request.Host.Host}:{ _httpContextAccessor.HttpContext.Request.Host.Port}";
  322. var returnValue = new MedicalReportDto()
  323. {
  324. FilePath = entity.ReportFile,
  325. FileBase64 = Shentun.Utilities.FileHelper.ToBase64(Host + entity.ReportFile)
  326. };
  327. return returnValue;
  328. }
  329. private async Task<UserTokenDto> GetTokenAsync(string request)
  330. {
  331. using var client = new HttpClient();
  332. HttpContent httpContent = new StringContent(request);
  333. httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
  334. var url = _configuration.GetSection("AuthServer").
  335. GetSection("Authority").Value + "/connect/token";
  336. var tokenResult = await client.PostAsync(url
  337. , httpContent);
  338. var tokenResultStr = await tokenResult.Content.ReadAsStringAsync();
  339. if (tokenResult.IsSuccessStatusCode)
  340. {
  341. if (!string.IsNullOrEmpty(tokenResultStr))
  342. {
  343. if (tokenResultStr.ToLower().Contains("openid"))
  344. {
  345. var wechatUserDto = JsonSerializer.Deserialize<WechatUserDto>(tokenResultStr,
  346. new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
  347. var userTokenDto = new UserTokenDto
  348. {
  349. IsNewUser = "Y",
  350. OpenId = wechatUserDto.OpenId
  351. };
  352. var options = new DistributedCacheEntryOptions()
  353. .SetAbsoluteExpiration(TimeSpan.FromMinutes(720));
  354. _cache.Set(CacheKeys.OpenIdKey + wechatUserDto.OpenId,
  355. wechatUserDto.OpenId, options);
  356. return userTokenDto;
  357. }
  358. else
  359. {
  360. var signResult = JsonSerializer.Deserialize<SignInResultDto>(tokenResultStr,
  361. new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
  362. var userTokenDto = new UserTokenDto
  363. {
  364. IsNewUser = "N",
  365. AccessToken = signResult.access_token,
  366. RefreshToken = signResult.refresh_token
  367. };
  368. return userTokenDto;
  369. }
  370. }
  371. else
  372. {
  373. throw new UserFriendlyException("token值为空");
  374. }
  375. }
  376. else
  377. {
  378. //tokenResultStr = tokenResultStr.Replace("<", "").Replace(">", "");
  379. //var grantErrorDto = JsonSerializer.Deserialize<GrantErrorDto>(tokenResultStr,
  380. // new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
  381. throw new UserFriendlyException("获取token失败:" + tokenResultStr);
  382. }
  383. }
  384. private async Task SendSms(string phone, string msg)
  385. {
  386. if (phone.Length == 11)
  387. {
  388. phone = "+86" + phone;
  389. }
  390. else
  391. {
  392. throw new Exception("手机号必须是11位长");
  393. }
  394. //发送短信
  395. //存储短信校验码
  396. _cache.Set(phone, msg);
  397. }
  398. }
  399. }