LiveConsultationService.Emergency.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. using WingInterfaceLibrary.Enum;
  2. using WingInterfaceLibrary.LiveConsultation;
  3. using WingServerCommon.Service;
  4. using WingInterfaceLibrary.LiveConsultation.Consultation;
  5. using WingInterfaceLibrary.DB.Request;
  6. using WingInterfaceLibrary.DTO.Consultation;
  7. using WingInterfaceLibrary.DTO.Schedule;
  8. using WingInterfaceLibrary.DTO.Device;
  9. using WingServerCommon.Interfaces.Cache;
  10. using WingInterfaceLibrary.Request;
  11. using WingInterfaceLibrary.DTO.User;
  12. using WingInterfaceLibrary.Request.DBRequest;
  13. using WingInterfaceLibrary.Request.Authentication;
  14. using WingServerCommon.Mapper;
  15. using WingInterfaceLibrary.Internal.Request;
  16. using Newtonsoft.Json.Linq;
  17. using WingInterfaceLibrary.Request.Patient;
  18. namespace WingLiveConsultationService
  19. {
  20. partial class LiveConsultationService : JsonRpcService, ILiveConsultationService
  21. {
  22. /// <summary>
  23. /// 获取即时会诊配置
  24. /// </summary>
  25. /// <param name="request"></param>
  26. /// <returns></returns>
  27. public async Task<GetEmergencySettingResult> GetEmergencySettingAsync(GetEmergencySettingRequest request)
  28. {
  29. var userCode = await GetClientIdByTokenAsync(request.Token);
  30. var userDTO = await _userDBService.FindUserByCodeAsync(userCode);
  31. var result = new GetEmergencySettingResult { EmergencyNeedFill = false };
  32. if (string.IsNullOrWhiteSpace(userDTO.RootOrganizationCode))
  33. {
  34. return result;
  35. }
  36. var organizationCache = CacheMaintenance.Instance.Get<IOrganizationsManager>().Get(userDTO.RootOrganizationCode);
  37. if (organizationCache == null || string.IsNullOrWhiteSpace(organizationCache.Code) || !organizationCache.EmergencyNeedFill)
  38. {
  39. return result;
  40. }
  41. result.OrganizationCode = organizationCache.Code;
  42. result.EmergencyNeedFill = organizationCache.EmergencyNeedFill;
  43. result.EmergencySettingVersion = organizationCache.ExamSettingVersion;
  44. result.EmergencySettingJson = organizationCache.EmergencySettingJson;
  45. if (string.IsNullOrWhiteSpace(result.EmergencySettingJson))
  46. {
  47. var json = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resource", "Consultation", "EmergencyInfo.json"));
  48. JObject o = JObject.Parse(json);
  49. result.EmergencySettingVersion = o["General"]["Version"].ToString();
  50. o.Remove("General");
  51. result.EmergencySettingJson = o.ToString();
  52. }
  53. return result;
  54. }
  55. /// <summary>
  56. /// 获取急诊订单号
  57. /// </summary>
  58. /// <param name="request"></param>
  59. /// <returns></returns>
  60. public async Task<string> GetEmergencyOrderAsync(GetEmergencyOrderRequest request)
  61. {
  62. var deviceInfo = await _deviceDBService.FindDeviceInfoBySerialNumberAsync(request.EmergencySerialNumber);
  63. if (deviceInfo != null)
  64. {
  65. return await _consultationRecordDBService.GetEmergencyOrderAsync(new GetEmergencyOrderDBRequest
  66. {
  67. EmergencyDeviceCode = deviceInfo.DeviceCode
  68. });
  69. }
  70. ThrowRpcException(CustomerRpcCode.DeviceNotExist, "DeviceNotExist");
  71. return string.Empty;
  72. }
  73. /// <summary>
  74. /// 急诊申请
  75. /// </summary>
  76. public async Task<string> ApplyEmergencyTreatment(ApplyEmergencyTreatmentRequest request)
  77. {
  78. var userCode = await GetClientIdByTokenAsync(request.Token);
  79. var userDTO = await _userDBService.FindUserByCodeAsync(userCode);
  80. var organizationRequest = new GetOrganizationDBRequest { OrganizationCode = userDTO.RootOrganizationCode };
  81. var organization = await _organizationDBService.GetOrganizationDetailAsync(organizationRequest);
  82. DeviceInfoDTO device = null;
  83. UserDTO expertDTO = null;
  84. if (!string.IsNullOrWhiteSpace(request.DeviceUniqueCode))
  85. {
  86. device = await _deviceDBService.FindDeviceInfoBySerialNumberAsync(request.DeviceUniqueCode);
  87. var emergencyDoctors = await GetEmergencyDoctorsAsync(userDTO.RootOrganizationCode);
  88. if (!emergencyDoctors.Any())
  89. {
  90. ThrowRpcException(CustomerRpcCode.EmergencyDoctorsIsEmpty, "Emergency Doctors Is Empty");
  91. }
  92. }
  93. else
  94. {
  95. if (string.IsNullOrWhiteSpace(request.DeviceCode))
  96. {
  97. ThrowRpcException(CustomerRpcCode.DeviceCodeIsEmpty, "DeviceCodeIsEmpty");
  98. }
  99. device = await _deviceDBService.FindDeviceInfoByCodeAsync(request.DeviceCode);
  100. if (string.IsNullOrWhiteSpace(request.ExpertCode))
  101. {
  102. ThrowRpcException(CustomerRpcCode.ExpertCodeIsEmpty, "ExportCodeIsEmpty");
  103. }
  104. expertDTO = await _userDBService.FindUserByCodeAsync(request.ExpertCode);
  105. if (expertDTO == null || string.IsNullOrWhiteSpace(expertDTO.UserCode))
  106. {
  107. ThrowRpcException(CustomerRpcCode.ExpertNotExisted, "ExpertNotExisted");
  108. }
  109. var expertTokens = CacheMaintenance.Instance.Get<ITokensManager>().Where(x => x.ClientId == expertDTO.UserCode);
  110. if (expertTokens == null || !expertTokens.Any(x => x.IsOnline))
  111. {
  112. ThrowRpcException(CustomerRpcCode.ExpertNotOnline, "ExpertNotOnline");
  113. }
  114. }
  115. if (device == null || string.IsNullOrWhiteSpace(device.DeviceCode))
  116. {
  117. ThrowRpcException(CustomerRpcCode.EmergencyDeviceNotExisted, "EmergencyDeviceNotExisted");
  118. }
  119. var deviceTokens = CacheMaintenance.Instance.Get<ITokensManager>().Where(x => x.ClientId == device.DeviceCode);
  120. if (deviceTokens == null || !deviceTokens.Any(x => x.IsOnline))
  121. {
  122. ThrowRpcException(CustomerRpcCode.DeviceNotOnline, "DeviceNotOnline");
  123. }
  124. var emergencyCode = await _consultationRecordDBService.GetEmergencyOrderAsync(new GetEmergencyOrderDBRequest
  125. {
  126. EmergencyDeviceCode = device.DeviceCode
  127. });
  128. if (string.IsNullOrWhiteSpace(emergencyCode))
  129. {
  130. ThrowRpcException(CustomerRpcCode.EmergencyCodeError, "EmergencyCodeError");
  131. }
  132. var dbRequest = new CreateConsultationRecordDBRequest();
  133. dbRequest.Data = new ConsultationDetailDTO();
  134. var applyUserCode = userDTO.UserCode;
  135. var applyUserInfoDTO = await _userDBService.FindUserByCodeAsync(applyUserCode);
  136. dbRequest.Data.ApplyUserCode = applyUserCode;
  137. if (applyUserInfoDTO.OrganizationCode != applyUserInfoDTO.RootOrganizationCode)
  138. {
  139. dbRequest.Data.ApplyDepartmentCode = applyUserInfoDTO.OrganizationCode;
  140. }
  141. else
  142. {
  143. dbRequest.Data.ApplyDepartmentCode = "";
  144. }
  145. var startTime = DateTime.UtcNow;
  146. var endTime = startTime.AddHours(2);
  147. dbRequest.Data.ApplyOrganizationCode = applyUserInfoDTO.RootOrganizationCode;
  148. dbRequest.Data.ConsultationTime = startTime;
  149. dbRequest.Data.ConsultationTimeEnd = endTime;
  150. dbRequest.Data.OperateUserCode = userDTO.UserCode;
  151. dbRequest.Data.DeviceCode = device.DeviceCode;
  152. dbRequest.Data.CreateTime = DateTime.UtcNow;
  153. dbRequest.Data.ConsultationStatus = TransactionStatusEnum.ToStart;
  154. dbRequest.Data.IsEmergency = true; //是否急诊标识
  155. dbRequest.Data.EmergencyCode = emergencyCode;//急诊code
  156. dbRequest.Data.ScanUserCode = applyUserCode;
  157. dbRequest.Data.ScanUserName = applyUserInfoDTO.DisplayName;
  158. if (expertDTO != null)
  159. {
  160. dbRequest.Data.ExpertUserCode = expertDTO.UserCode;
  161. dbRequest.Data.ExpertOrganizationCode = expertDTO.RootOrganizationCode;
  162. dbRequest.Data.ExpertDepartmentCode = string.Empty;
  163. if (expertDTO.OrganizationCode != expertDTO.RootOrganizationCode)
  164. {
  165. dbRequest.Data.ExpertDepartmentCode = expertDTO.OrganizationCode;
  166. }
  167. await _userDBService.UpdateEmergencyInfoDBAsync(new UpdateEmergencyInfoDBRequest { UserCode = userCode, EmergencyDeviceCode = device.DeviceCode, EmergencyExpertCode = expertDTO.UserCode });
  168. }
  169. if (!string.IsNullOrWhiteSpace(request.PatientCode))
  170. {
  171. dbRequest.Data.PatientCode = request.PatientCode;
  172. dbRequest.Data.PatientType = organization.PatientType;
  173. if (request.PatientDatas != null && request.PatientDatas.Any())
  174. {
  175. await _patientService.UpdatePatientAsync(new UpdatePatientRequest
  176. {
  177. Token = request.Token,
  178. Code = request.PatientCode,
  179. PatientData = request.PatientDatas,
  180. });
  181. var patientInfo = await _patientInfoDBService.FindPatientByCodeAsync(request.PatientCode);
  182. dbRequest.Data.PatientDatas = patientInfo?.PatientData;
  183. }
  184. }
  185. var result = await _consultationRecordDBService.InsertConsultationRecordAsync(dbRequest);
  186. //创建日程
  187. var addScheduleDBRequest = new AddScheduleDBRequest();
  188. addScheduleDBRequest.Data = new ScheduleDTO()
  189. {
  190. Title = emergencyCode,
  191. StartTime = startTime,
  192. EndTime = endTime,
  193. Status = TransactionStatusEnum.ToStart,
  194. ScheduleType = ScheduleTypeEnum.Consultation,
  195. RelevanceCode = result,
  196. UserCodes = new List<string> { userCode }
  197. };
  198. await _userDBService.AddScheduleDBAsync(addScheduleDBRequest);
  199. return result;
  200. }
  201. public async Task<QueryEmergencyDataResult> QueryEmergencyDataAsync(TokenRequest request)
  202. {
  203. var result = new QueryEmergencyDataResult();
  204. var userCode = await GetClientIdByTokenAsync(request.Token);
  205. //查询用户是否存在
  206. var userInfo = await _userDBService.FindUserByCodeAsync(userCode);
  207. if (userInfo == null)
  208. {
  209. ThrowRpcException(CustomerRpcCode.UserNotExistError, "User does not exist");
  210. }
  211. //查询用户的医院是否存在
  212. if (string.IsNullOrEmpty(userInfo.OrganizationCode))
  213. {
  214. ThrowRpcException(CustomerRpcCode.OrganizationNotExist, "Org does not exist");
  215. }
  216. //急诊设备列表:只查询在线的,上次选择的在第一个
  217. var deviceInfoList = new List<EmergencyDeviceInfoDTO>();
  218. //急诊专家列表:只查询在线的,上次选择的在第一个
  219. var expertList = new List<UserDTO>();
  220. var deviceInfoDOList = new List<DeviceInfoDTO>();
  221. //普通用户,查询用户绑定的设备
  222. if (userInfo.BindDevices != null && userInfo.BindDevices.Any())
  223. {
  224. deviceInfoDOList = await _deviceDBService.FindDeviceInfoListByCodeListAsync(userInfo.BindDevices);
  225. }
  226. if (userInfo.IsDirector)
  227. {
  228. //机构负责人
  229. var orgRootCodes = new List<string> { userInfo.RootOrganizationCode };
  230. var allChildOrganizations = await _organizationDBService.GetAllChildOrganizations(userInfo.RootOrganizationCode);
  231. if (allChildOrganizations != null && allChildOrganizations.Count() > 0)
  232. {
  233. orgRootCodes.AddRange(allChildOrganizations.Select(x => x.OrganizationCode));
  234. }
  235. var orgDeviceInfoDTOList = await _deviceDBService.FindDeviceInfoListByOrganizationCodesAsync(orgRootCodes);
  236. if (orgDeviceInfoDTOList != null && orgDeviceInfoDTOList.Count > 0)
  237. {
  238. var devinceInfoCodes = deviceInfoDOList.Select(x => x.DeviceCode);
  239. foreach (var item in orgDeviceInfoDTOList)
  240. {
  241. if (!devinceInfoCodes.Contains(item.DeviceCode))
  242. {
  243. deviceInfoDOList.Add(item);
  244. }
  245. }
  246. }
  247. }
  248. if (deviceInfoDOList.Any())
  249. {
  250. var deviceCodes = deviceInfoDOList.Select(x => x.DeviceCode).ToList();
  251. var deviceTokens = await _authenticationService.GetTokenWithClientIdsAsync(new GetTokenWithClientIdsRequest { ClientIds = deviceCodes });
  252. var onLineDeviceCodes = deviceTokens.Where(x => x.IsOnline == true).Select(x => x.ClientId);
  253. var onlineDeviceInfoDOList = deviceInfoDOList.Where(x => onLineDeviceCodes.Contains(x.DeviceCode)).ToList();
  254. if (onlineDeviceInfoDOList != null && onlineDeviceInfoDOList.Count > 0)
  255. {
  256. var bindEmergencyDeviceCode = userInfo.BindEmergencyDeviceCode;
  257. if (!string.IsNullOrWhiteSpace(bindEmergencyDeviceCode))
  258. {
  259. //排序
  260. if (onLineDeviceCodes.Contains(bindEmergencyDeviceCode))
  261. {
  262. var bindEmergencyDevice = onlineDeviceInfoDOList.FirstOrDefault(x => x.DeviceCode == bindEmergencyDeviceCode);
  263. if (bindEmergencyDevice != null && !string.IsNullOrWhiteSpace(bindEmergencyDevice.DeviceCode))
  264. {
  265. deviceInfoList.Add(await GetEmergencyDeviceInfoDTO(bindEmergencyDevice));
  266. }
  267. }
  268. }
  269. onlineDeviceInfoDOList = onlineDeviceInfoDOList.Where(x => x.DeviceCode != bindEmergencyDeviceCode).ToList();
  270. //超声机设备是否被占用
  271. foreach (var item in onlineDeviceInfoDOList)
  272. {
  273. deviceInfoList.Add(await GetEmergencyDeviceInfoDTO(item));
  274. }
  275. }
  276. else
  277. {
  278. ThrowRpcException(CustomerRpcCode.DeviceNotOnline, "DeviceNotOnline");
  279. }
  280. }
  281. if (deviceInfoList.Count == 0)
  282. {
  283. ThrowRpcException(CustomerRpcCode.EmergencyDeviceNotFound, "EmergencyDeviceNotFound");
  284. }
  285. var orgRequest = new GetOrganizationDBRequest { OrganizationCode = userInfo.RootOrganizationCode };
  286. var rootOrg = await _organizationDBService.GetOrganizationDetailAsync(orgRequest);
  287. var orgCodes = new List<string> { rootOrg.RootCode, rootOrg.ParentCode };
  288. orgCodes.AddRange(rootOrg.ReferralOrganizationCodes);
  289. orgCodes = orgCodes.Distinct().ToList();
  290. var orgs = await _organizationDBService.FindOrganizationListByCodesAsync(orgCodes);
  291. var userList = new List<UserDTO>();
  292. foreach (var orgCode in orgCodes)
  293. {
  294. var roles = new List<string>() { "Role_CertifiedExpert", "Role_CertifiedPhysician" };
  295. var tempUserList = await FindOrganizationAssistantsAsync(orgCode, roles);
  296. foreach (var item in tempUserList)
  297. {
  298. item.RootOrganizationName = orgs.FirstOrDefault(x => x.RootCode == orgCode)?.OrganizationName;
  299. }
  300. userList.AddRange(tempUserList);
  301. }
  302. var userExts = userList.MappingTo<List<UserExtendDTO>>();
  303. if (userExts == null || userExts.Count == 0)
  304. {
  305. ThrowRpcException(CustomerRpcCode.EmergencyExpertNotFound, "EmergencyExpertNotFound");
  306. }
  307. foreach (var item in userExts)
  308. {
  309. item.UserStatus = GetUserStatus(item.UserCode);
  310. }
  311. userExts = userExts.Where(x => x.UserCode != userCode).ToList();
  312. if (userExts.Count <= 0)//专家未找到
  313. {
  314. ThrowRpcException(CustomerRpcCode.EmergencyExpertNotFound, "EmergencyExpertNotFound");
  315. }
  316. var idleUsers = userExts.Where(x => x.UserStatus == UserStatusEnum.Idle).ToList();//在线
  317. if (idleUsers != null && idleUsers.Count > 0)
  318. {
  319. var idleUserCodes = idleUsers.Select(x => x.UserCode);
  320. string bindEmergencyExpertCode = userInfo.BindEmergencyExpertCode;
  321. if (!string.IsNullOrWhiteSpace(bindEmergencyExpertCode) && bindEmergencyExpertCode != userCode)
  322. {
  323. //排序
  324. if (idleUserCodes.Contains(bindEmergencyExpertCode))
  325. {
  326. var bindEmergencyExpert = idleUsers.FirstOrDefault(x => x.UserCode == bindEmergencyExpertCode);
  327. if (bindEmergencyExpert != null && !string.IsNullOrWhiteSpace(bindEmergencyExpert.UserCode))
  328. {
  329. expertList.Add(bindEmergencyExpert);
  330. }
  331. }
  332. }
  333. idleUsers = idleUsers.Where(x => x.UserCode != bindEmergencyExpertCode).ToList();
  334. if (idleUsers != null && idleUsers.Count > 0)
  335. {
  336. expertList.AddRange(idleUsers);
  337. }
  338. }
  339. else
  340. {
  341. ThrowRpcException(CustomerRpcCode.ExpertNotOnline, "ExpertNotOnline");
  342. }
  343. result.ExpertList = expertList;
  344. result.DeviceInfoList = deviceInfoList;
  345. return result;
  346. }
  347. private async Task<EmergencyDeviceInfoDTO> GetEmergencyDeviceInfoDTO(DeviceInfoDTO deviceInfoDTO)
  348. {
  349. var emergencyDeviceInfoDTO = deviceInfoDTO.MappingTo<EmergencyDeviceInfoDTO>();
  350. var liveRoomDTO = await _rtcService.GetInitiatingRoomByDeviceCodeAsync(new GetInitiatingRoomByDeviceCodeRequest()
  351. {
  352. DeviceCode = deviceInfoDTO.DeviceCode,
  353. });
  354. if (liveRoomDTO != null)
  355. {
  356. emergencyDeviceInfoDTO.IsOccupied = true;
  357. emergencyDeviceInfoDTO.OccupiedModuleEnum = liveRoomDTO.BusinessModule;
  358. }
  359. return emergencyDeviceInfoDTO;
  360. }
  361. }
  362. }