LiveConsultationRoom.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. using WingInterfaceLibrary.LiveConsultation;
  2. using WingInterfaceLibrary.Enum;
  3. using WingInterfaceLibrary.Request.Notification;
  4. using WingServerCommon.Config;
  5. using WingInterfaceLibrary.Notifications;
  6. using WingServerCommon.Interfaces.Cache;
  7. using WingInterfaceLibrary.Rtc;
  8. using WingServerCommon.Log;
  9. using System.Text;
  10. using WingInterfaceLibrary.DTO.User;
  11. using WingInterfaceLibrary.LiveConsultation.Consultation;
  12. namespace WingLiveConsultationService
  13. {
  14. /// <summary>
  15. /// 会诊房间
  16. /// </summary>
  17. public partial class LiveConsultationRoom : LiveConsultationRoomDTO
  18. {
  19. public static Func<int, string, GenerateRoomUrlResult> OnRtcGenerateRoomUrl;
  20. public static Func<string, string> OnGetUserSign;
  21. public LiveConsultationRoom(string roomId, int roomNo, string patientName, DateTime consultationTime, TransactionStatusEnum consultationStatus
  22. , string applyOrganizationCode, string applyUserCode, string expertOrganizationCode, List<LiveConsultationMember> liveMembers, string expertUserCode, bool isEmergency) : base(roomId)
  23. {
  24. RoomId = roomId;
  25. RoomNo = roomNo;
  26. PatientName = patientName ?? string.Empty;
  27. ConsultationTime = consultationTime;
  28. ConsultationStatus = consultationStatus;
  29. ApplyOrganizationCode = applyOrganizationCode;
  30. ApplyUserCode = applyUserCode;
  31. ExpertOrganizationCode = expertOrganizationCode;
  32. Members = liveMembers ?? new List<LiveConsultationMember>();
  33. ExpertUserCode = expertUserCode;
  34. IsEmergency = isEmergency;
  35. InteractiveBoardDatas = new List<InteractiveBoardDataDTO>();
  36. }
  37. /// <summary>
  38. /// 修改预约记录状态
  39. /// </summary>
  40. /// <param name="status"></param>
  41. public void ChangeConsultationStatus(TransactionStatusEnum status)
  42. {
  43. WriteDebugLogs("ChangeConsultationStatus", null, $"{ConsultationStatus.ToString()}>>{status.ToString()}");
  44. ConsultationStatus = status;
  45. }
  46. /// <summary>
  47. /// 参与人员同意参加会诊
  48. /// </summary>
  49. /// <param name="userCode"></param>
  50. public void Agree(string userCode)
  51. {
  52. var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
  53. if (liveMember != null)
  54. {
  55. liveMember.Status = LiveConsultationMemberStatus.Default;
  56. }
  57. else
  58. {
  59. liveMember = InitLiveMemberByCode(userCode);
  60. liveMember.Status = LiveConsultationMemberStatus.Default;
  61. Members.Add(liveMember);
  62. }
  63. WriteDebugLogs("Agree", liveMember);
  64. }
  65. /// <summary>
  66. /// 开始会诊
  67. /// </summary>
  68. /// <param name="initiatorCode"></param>
  69. /// <param name="integerRoomId"></param>
  70. /// <param name="timeout"></param>
  71. /// <param name="sdkAppId"></param>
  72. public void Initiate(string initiatorCode, int integerRoomId, int timeout, int sdkAppId, bool pushMessage = false)
  73. {
  74. var initiator = Members.FirstOrDefault(x => x.Id == initiatorCode);
  75. if (initiator != null)
  76. {
  77. initiator.IsInitiator = true;
  78. initiator.Status = LiveConsultationMemberStatus.Joined;
  79. }
  80. else
  81. {
  82. initiator = InitLiveMemberByCode(initiatorCode);
  83. initiator.IsInitiator = true;
  84. initiator.Status = LiveConsultationMemberStatus.Joined;
  85. Members.Add(initiator);
  86. }
  87. foreach (var liveMember in Members)
  88. {
  89. if (liveMember.Id != initiatorCode)
  90. {
  91. liveMember.IsInitiator = false;
  92. liveMember.Status = LiveConsultationMemberStatus.Default;
  93. }
  94. liveMember.Mute = false;
  95. liveMember.VideoOpend = true;
  96. liveMember.IsControllingParameter = false;
  97. }
  98. RoomNo = integerRoomId;
  99. ConsultationStatus = TransactionStatusEnum.InProgress;
  100. Status = LiveConsultationRoomStatus.Initiating;
  101. InteractiveBoardDatas = new List<InteractiveBoardDataDTO>();
  102. EmergencyAccepted = false;
  103. RefreshMemberInfosByToken();
  104. //StartCheckConnectionTimeout(timeout);
  105. if (pushMessage)
  106. {
  107. PushInitiateMessage(sdkAppId);
  108. }
  109. WriteDebugLogs("Initiate", initiator);
  110. }
  111. /// <summary>
  112. /// 接受会诊邀请-参与人员
  113. /// </summary>
  114. /// <param name="userCode"></param>
  115. public void Accept(string userCode, bool pushMessage = false)
  116. {
  117. var accepter = Members.FirstOrDefault(x => x.Id == userCode);
  118. if (accepter != null)
  119. {
  120. accepter.Status = LiveConsultationMemberStatus.Accepted;
  121. accepter.Mute = false;
  122. accepter.IsControllingParameter = false;
  123. accepter.VideoOpend = true;
  124. RemoveInteractiveBoardDatasByUserCode(userCode);
  125. if (Status == LiveConsultationRoomStatus.Connected)
  126. {
  127. Status = LiveConsultationRoomStatus.Initiating;
  128. }
  129. if (pushMessage)
  130. {
  131. PushCancelInviteInMessage(new List<string> { accepter.Id }, true);//取消其他端的呼叫行为
  132. PushAcceptMessage(accepter);
  133. }
  134. }
  135. WriteDebugLogs("Accept", accepter);
  136. }
  137. /// <summary>
  138. /// 接受会诊邀请-急诊专家
  139. /// </summary>
  140. /// <param name="userCode"></param>
  141. /// <param name="orgCode"></param>
  142. /// <param name="pushMessage"></param>
  143. public void EmergencyAccept(string userCode, string orgCode, bool pushMessage = false)
  144. {
  145. EmergencyAccepted = true;
  146. var accepter = Members.FirstOrDefault(x => x.Id == userCode);
  147. if (accepter == null)
  148. {
  149. accepter = InitLiveMemberByCode(userCode);
  150. accepter.Status = LiveConsultationMemberStatus.Accepted;
  151. Members.Add(accepter);
  152. //急诊专家信息
  153. ExpertUserCode = userCode;
  154. ExpertOrganizationCode = orgCode;
  155. }
  156. accepter.Status = LiveConsultationMemberStatus.Accepted;
  157. accepter.Mute = false;
  158. accepter.VideoOpend = true;
  159. accepter.IsControllingParameter = false;
  160. if (Status == LiveConsultationRoomStatus.Connected)
  161. {
  162. Status = LiveConsultationRoomStatus.Initiating;
  163. }
  164. if (pushMessage)
  165. {
  166. PushAcceptMessage(accepter);
  167. }
  168. WriteDebugLogs("EmergencyAccept", accepter);
  169. }
  170. /// <summary>
  171. /// 拒绝会诊邀请-参与人员
  172. /// </summary>
  173. /// <param name="userCode"></param>
  174. public void Reject(string userCode, bool pushMessage = false)
  175. {
  176. var rejecter = Members.FirstOrDefault(x => x.Id == userCode);
  177. if (rejecter != null)
  178. {
  179. rejecter.Status = LiveConsultationMemberStatus.Rejected;
  180. if (pushMessage)
  181. {
  182. PushCancelInviteInMessage(new List<string> { rejecter.Id }, true);//取消其他端的呼叫行为
  183. PushRejectMessage(rejecter);
  184. }
  185. }
  186. WriteDebugLogs("Reject", rejecter);
  187. }
  188. /// <summary>
  189. /// 取消会诊
  190. /// </summary>
  191. public void CancelInitiate(bool pushMessage = false)
  192. {
  193. Status = LiveConsultationRoomStatus.Cancelled;
  194. ConsultationStatus = TransactionStatusEnum.ToStart;
  195. if (pushMessage)
  196. {
  197. PushCancelMessage();
  198. PushCloseMessage();
  199. }
  200. foreach (var liveMember in Members)
  201. {
  202. if (liveMember.Status == LiveConsultationMemberStatus.Joined)
  203. {
  204. liveMember.Status = LiveConsultationMemberStatus.Left;
  205. }
  206. }
  207. WriteDebugLogs("CancelInitiate", Initiator);
  208. }
  209. /// <summary>
  210. /// 会诊心跳,进入房间
  211. /// </summary>
  212. /// <param name="userCode"></param>
  213. public void HeartRateJoin(string userCode, bool pushMessage = false)
  214. {
  215. var joiner = Members.FirstOrDefault(x => x.Id == userCode);
  216. if (joiner != null && joiner.Status != LiveConsultationMemberStatus.Joined)
  217. {
  218. joiner.Status = LiveConsultationMemberStatus.Joined;
  219. if (pushMessage)
  220. {
  221. PushHeartRateJoinMessage(joiner);
  222. }
  223. }
  224. WriteDebugLogs("HeartRateJoin", joiner);
  225. }
  226. /// <summary>
  227. /// 会诊心跳,网络质量不佳
  228. /// </summary>
  229. /// <param name="userCode"></param>
  230. public void NetworkErr(string userCode, bool pushMessage = false)
  231. {
  232. var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
  233. if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
  234. {
  235. if (pushMessage)
  236. {
  237. PushNetworkErrMessage(liveMember);
  238. }
  239. }
  240. WriteDebugLogs("NetworkErr", liveMember);
  241. }
  242. /// <summary>
  243. /// 会诊心跳,离开房间
  244. /// </summary>
  245. /// <param name="userCode"></param>
  246. public bool HeartRateLeave(string userCode, bool pushMessage = false)
  247. {
  248. var leaver = Members.FirstOrDefault(x => x.Id == userCode);
  249. var needClose = false;
  250. if (leaver != null && leaver.Status == LiveConsultationMemberStatus.Joined)
  251. {
  252. leaver.Status = LiveConsultationMemberStatus.Left;
  253. if (pushMessage)
  254. {
  255. PushHeartRateLeaveMessage(leaver);
  256. }
  257. if (MainUserInfos == null || MainUserInfos.All(x => x.Status != LiveConsultationMemberStatus.Joined))
  258. {
  259. Close(pushMessage);
  260. needClose = true;
  261. }
  262. }
  263. WriteDebugLogs("HeartRateLeave", leaver);
  264. return needClose;
  265. }
  266. /// <summary>
  267. /// 离开房间,含结束会诊
  268. /// </summary>
  269. /// <param name="userCode"></param>
  270. public bool Leave(string userCode, bool pushMessage = false)
  271. {
  272. var leaver = Members.FirstOrDefault(x => x.Id == userCode);
  273. var needClose = false;
  274. if (leaver != null && leaver.Status == LiveConsultationMemberStatus.Joined)
  275. {
  276. leaver.Status = LiveConsultationMemberStatus.Left;
  277. leaver.Mute = false;
  278. leaver.IsControllingParameter = false;
  279. leaver.VideoOpend = true;
  280. RemoveInteractiveBoardDatasByUserCode(userCode);
  281. if (pushMessage)
  282. {
  283. PushLeaveMessage(leaver);
  284. }
  285. if (MainUserInfos == null || MainUserInfos.All(x => x.Status != LiveConsultationMemberStatus.Joined))
  286. {
  287. Close(pushMessage);
  288. needClose = true;
  289. }
  290. }
  291. WriteDebugLogs("Leave", leaver, $"close:{needClose.ToString()}");
  292. return needClose;
  293. }
  294. /// <summary>
  295. /// 结束会诊
  296. /// </summary>
  297. public void Close(bool pushMessage = false)
  298. {
  299. Status = LiveConsultationRoomStatus.Closed;
  300. ConsultationStatus = TransactionStatusEnum.PendingReport;
  301. if (pushMessage)
  302. {
  303. PushCancelMessage();
  304. PushCloseMessage();
  305. }
  306. foreach (var liveMember in Members)
  307. {
  308. if (liveMember.Status == LiveConsultationMemberStatus.Joined)
  309. {
  310. liveMember.Status = LiveConsultationMemberStatus.Left;
  311. }
  312. }
  313. InteractiveBoardDatas = new List<InteractiveBoardDataDTO>();
  314. WriteDebugLogs("Close");
  315. }
  316. /// <summary>
  317. /// 开启关闭静音
  318. /// </summary>
  319. /// <param name="userCode"></param>
  320. /// <param name="mute"></param>
  321. public void ChangeMuteState(string userCode, bool mute, bool pushMessage = false)
  322. {
  323. var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
  324. if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
  325. {
  326. liveMember.Mute = mute;
  327. if (pushMessage)
  328. {
  329. PushMuteStateMessage(liveMember);
  330. }
  331. }
  332. WriteDebugLogs("ChangeMuteState", liveMember, $"mute:{mute.ToString()}");
  333. }
  334. /// <summary>
  335. /// 开启关闭视频
  336. /// </summary>
  337. /// <param name="userCode"></param>
  338. /// <param name="isVideoOpen"></param>
  339. public void ChangeVideoOpenState(string userCode, bool isVideoOpen, bool pushMessage = false)
  340. {
  341. var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
  342. if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
  343. {
  344. liveMember.VideoOpend = isVideoOpen;
  345. if (pushMessage)
  346. {
  347. PushVideoOpenStateMessage(liveMember);
  348. }
  349. }
  350. WriteDebugLogs("ChangeVideoOpenState", liveMember, $"isVideoOpen:{isVideoOpen.ToString()}");
  351. }
  352. /// <summary>
  353. /// 更改调参状态
  354. /// </summary>
  355. /// <param name="userCode"></param>
  356. /// <param name="isVideoOpen"></param>
  357. public void ChangeControllingParameterState(string userCode, bool isControllingParameter)
  358. {
  359. var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
  360. if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
  361. {
  362. liveMember.IsControllingParameter = isControllingParameter;
  363. }
  364. WriteDebugLogs("ChangeControllingParameterState", liveMember, $"isControllingParameter:{isControllingParameter.ToString()}");
  365. }
  366. /// <summary>
  367. /// 会诊中邀请
  368. /// </summary>
  369. /// <param name="userCode"></param>
  370. /// <param name="clientIds"></param>
  371. public void InviteIn(string userCode, List<string> clientIds, bool pushMessage = false)
  372. {
  373. var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
  374. if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
  375. {
  376. if (pushMessage)
  377. {
  378. PushInviteInMessage(liveMember, clientIds);
  379. }
  380. }
  381. WriteDebugLogs("InviteIn", liveMember);
  382. }
  383. /// <summary>
  384. /// 取消会诊中邀请
  385. /// </summary>
  386. /// <param name="userCode"></param>
  387. /// <param name="clientIds"></param>
  388. public void CancelInviteIn(string userCode, List<string> clientIds, bool pushMessage = false)
  389. {
  390. var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
  391. if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
  392. {
  393. var notifyUserCodes = new List<string>();
  394. foreach (var clientId in clientIds)
  395. {
  396. if (Members.Any(x => x.Id == clientId && x.Status == LiveConsultationMemberStatus.Joined))
  397. {
  398. continue;
  399. }
  400. notifyUserCodes.Add(clientId);
  401. }
  402. if (notifyUserCodes.Any())
  403. {
  404. if (pushMessage)
  405. {
  406. PushCancelInviteInMessage(notifyUserCodes);
  407. }
  408. }
  409. }
  410. WriteDebugLogs("CancelInviteIn", liveMember);
  411. }
  412. /// <summary>
  413. /// 接受会诊中邀请
  414. /// </summary>
  415. /// <param name="userCode"></param>
  416. public void AcceptIn(string userCode, bool pushMessage = false)
  417. {
  418. var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
  419. if (liveMember != null)
  420. {
  421. liveMember.Status = LiveConsultationMemberStatus.Accepted;
  422. liveMember.Mute = false;
  423. liveMember.IsControllingParameter = false;
  424. liveMember.VideoOpend = true;
  425. }
  426. else
  427. {
  428. liveMember = InitLiveMemberByCode(userCode);
  429. liveMember.Status = LiveConsultationMemberStatus.Accepted;
  430. liveMember.Mute = false;
  431. liveMember.IsControllingParameter = false;
  432. liveMember.VideoOpend = true;
  433. Members.Add(liveMember);
  434. }
  435. RemoveInteractiveBoardDatasByUserCode(userCode);
  436. if (pushMessage)
  437. {
  438. PushCancelInviteInMessage(new List<string> { liveMember.Id }, true);//取消其他端的呼叫行为
  439. PushAcceptInMessage(liveMember);
  440. }
  441. WriteDebugLogs("AcceptIn", liveMember);
  442. }
  443. /// <summary>
  444. /// 拒绝会诊中邀请
  445. /// </summary>
  446. /// <param name="rejecterCode"></param>
  447. public void RejectIn(string rejecterCode, bool pushMessage = false)
  448. {
  449. if (Initiator != null && Initiator.Status == LiveConsultationMemberStatus.Joined)
  450. {
  451. var userInfo = CacheMaintenance.Instance.Get<IUserInfoManager>().Get(rejecterCode);
  452. WriteDebugLogs("RejectIn", Initiator, $"rejecter name:{userInfo.UserName};{userInfo.FullName}");
  453. if (pushMessage)
  454. {
  455. PushCancelInviteInMessage(new List<string> { userInfo.Code }, true);//取消其他端的呼叫行为
  456. PushRejectInMessage(Initiator, userInfo);
  457. }
  458. }
  459. else
  460. {
  461. WriteDebugLogs("RejectIn", Initiator);
  462. }
  463. }
  464. /// <summary>
  465. /// 发送白板交互数据
  466. /// </summary>
  467. /// <param name="userCode"></param>
  468. /// <param name="boardData"></param>
  469. /// <param name="isClear"></param>
  470. public void SendBoardData(string userCode, string boardData, DateTime interactiveTime, bool isClear, bool pushMessage = false)
  471. {
  472. var liveMember = Members.FirstOrDefault(x => x.Id == userCode);
  473. if (liveMember != null && liveMember.Status == LiveConsultationMemberStatus.Joined)
  474. {
  475. if (!isClear)
  476. {
  477. InteractiveBoardDatas.Add(new InteractiveBoardDataDTO
  478. {
  479. InteractiveTime = interactiveTime,
  480. UserCode = userCode,
  481. BoardData = boardData,
  482. });
  483. }
  484. else
  485. {
  486. RemoveInteractiveBoardDatasByUserCode(userCode);
  487. }
  488. if (pushMessage)
  489. {
  490. PushBoardDataMessage(liveMember, boardData, isClear);
  491. }
  492. }
  493. WriteDebugLogs("SendBoardData", liveMember);
  494. }
  495. /// <summary>
  496. /// 呼叫急诊专家
  497. /// </summary>
  498. /// <param name="doctor"></param>
  499. /// <param name="timeOut"></param>
  500. public void CallEmergencyDoctor(UserDTO doctor, int timeOut)
  501. {
  502. if (!EmergencyAccepted)
  503. {
  504. PushEmergencyMessage(doctor, timeOut);
  505. }
  506. }
  507. /// <summary>
  508. /// 急诊呼叫失败
  509. /// </summary>
  510. public void EmergencyFailed()
  511. {
  512. if (!EmergencyAccepted)
  513. {
  514. PushEmergencyFailedMessage();
  515. }
  516. }
  517. /// <summary>
  518. /// 切换会诊房间
  519. /// </summary>
  520. /// <param name="userCode"></param>
  521. /// <param name="current"></param>
  522. /// <param name="timeout"></param>
  523. /// <param name="sdkAppId"></param>
  524. /// <returns></returns>
  525. public void ChangeRoom(string userCode, LiveConsultationRoom current, int timeout, int sdkAppId)
  526. {
  527. current.Initiate(Initiator.Id, RoomNo, timeout, sdkAppId, false);
  528. var closeMemberCodes = new List<string>();
  529. foreach (var origMember in Members)
  530. {
  531. if (origMember.Status != LiveConsultationMemberStatus.Joined)
  532. {
  533. continue;
  534. }
  535. var liveMember = current.Members.FirstOrDefault(x => x.Id == origMember.Id);
  536. if (liveMember != null)
  537. {
  538. liveMember.Status = LiveConsultationMemberStatus.Accepted;
  539. liveMember.Mute = origMember.Mute;
  540. liveMember.VideoOpend = origMember.VideoOpend;
  541. liveMember.IsControllingParameter = origMember.IsControllingParameter;
  542. }
  543. else
  544. {
  545. closeMemberCodes.Add(origMember.Id);
  546. }
  547. }
  548. PushCloseDueToChangeMessage(closeMemberCodes);
  549. PushChangeRoomMessage(userCode, current);
  550. Close(false);
  551. }
  552. private void StartCheckConnectionTimeout(int timeout)
  553. {
  554. Task.Run(async () =>
  555. {
  556. Status = LiveConsultationRoomStatus.Initiating;
  557. await Task.Delay(timeout * 1000);
  558. if (Status != LiveConsultationRoomStatus.Connected)
  559. {
  560. Status = LiveConsultationRoomStatus.ConnectionTimeout;
  561. }
  562. });
  563. }
  564. public LiveConsultationMember InitLiveMemberByCode(string userCode)
  565. {
  566. var user = CacheMaintenance.Instance.Get<IUserInfoManager>().Get(userCode);
  567. var userName = !string.IsNullOrWhiteSpace(user.FullName) ? user.FullName : user.UserName;
  568. var liveMember = new LiveConsultationMember
  569. {
  570. Id = userCode,
  571. MemberType = LiveMemberEnum.User,
  572. Name = userName,
  573. HeadImageToken = user.HeadImageToken,
  574. IsInitiator = false,
  575. Status = LiveConsultationMemberStatus.Default,
  576. //LiveData = liveData,
  577. };
  578. var userToken = CacheMaintenance.Instance.Get<ITokensManager>().Where(t => t.ClientId == userCode)?.OrderByDescending(x => x.IsOnline)?.FirstOrDefault();
  579. if (userToken != null)
  580. {
  581. var loginSource = (LoginSource)userToken.LoginSource;
  582. liveMember.LoginServerUrl = userToken.LoginServer;
  583. liveMember.LoginSource = (LoginSource)userToken.LoginSource;
  584. liveMember.IsOnline = userToken.IsOnline;
  585. liveMember.IsBusy = false;
  586. }
  587. return liveMember;
  588. }
  589. private void RefreshMemberInfosByToken(string liveMemberId = "")
  590. {
  591. var tokenManager = CacheMaintenance.Instance.Get<ITokensManager>();
  592. foreach (var liveMember in Members)
  593. {
  594. var id = liveMember.Id;
  595. if (!string.IsNullOrWhiteSpace(liveMemberId) && id != liveMemberId)
  596. {
  597. continue;
  598. }
  599. var userToken = tokenManager.Where(t => t.ClientId == id)?.OrderByDescending(x => x.IsOnline)?.FirstOrDefault();
  600. if (userToken != null)
  601. {
  602. var loginSource = (LoginSource)userToken.LoginSource;
  603. liveMember.LoginServerUrl = userToken.LoginServer;
  604. liveMember.LoginSource = (LoginSource)userToken.LoginSource;
  605. liveMember.IsOnline = userToken.IsOnline;
  606. }
  607. var agenerateRoomUrlResult = OnRtcGenerateRoomUrl.Invoke(RoomNo, id);
  608. liveMember.LiveData = new LiveData
  609. {
  610. RtmpPullUrl = agenerateRoomUrlResult.RtmpUrl,
  611. HlsPullUrl = agenerateRoomUrlResult.HlsUrl,
  612. HttpPullUrl = agenerateRoomUrlResult.FlvUrl,
  613. };
  614. }
  615. }
  616. private void WriteDebugLogs(string actionName, LiveConsultationMember liveMember = null, string log = "")
  617. {
  618. var logs = new StringBuilder();
  619. logs.AppendLine($"LiveConsultationRoom action:{actionName}, patientName:{PatientName}, roomId:{RoomId}, room status:{Status.ToString()}");
  620. if (liveMember != null)
  621. {
  622. logs.AppendLine($"user:{liveMember.Name}, status:{liveMember.Status.ToString()}");
  623. }
  624. else
  625. {
  626. logs.AppendLine($"user:not existed");
  627. }
  628. logs.AppendLine($"log:{log}");
  629. Logger.WriteLineInfo($"{logs.ToString()}");
  630. }
  631. /// <summary>
  632. /// 清除白板数据
  633. /// </summary>
  634. /// <param name="userCode"></param>
  635. private void RemoveInteractiveBoardDatasByUserCode(string userCode)
  636. {
  637. InteractiveBoardDatas = InteractiveBoardDatas.Where(x => x.UserCode != userCode)?.ToList() ?? new List<InteractiveBoardDataDTO>();
  638. }
  639. }
  640. public class LiveConsultationRoomDTO
  641. {
  642. public LiveConsultationRoomDTO(string roomId)
  643. {
  644. RoomId = roomId;
  645. }
  646. /// <summary>
  647. /// The consultation unique id
  648. /// </summary>
  649. /// <value></value>
  650. public string RoomId { get; set; }
  651. /// <summary>
  652. /// The diagnosis room No
  653. /// </summary>
  654. /// <value></value>
  655. public int RoomNo { get; set; }
  656. public string MsgQueueId { get; set; }
  657. public IList<LiveConsultationMember> Members { get; set; } = new List<LiveConsultationMember>();
  658. public LiveConsultationMember Initiator
  659. {
  660. get
  661. {
  662. return Members.FirstOrDefault(x => x.IsInitiator);
  663. }
  664. }
  665. public IEnumerable<LiveConsultationMember> UserInfos
  666. {
  667. get
  668. {
  669. return Members.Where(x => x.MemberType == LiveMemberEnum.User);
  670. }
  671. }
  672. public IEnumerable<LiveConsultationMember> DeviceInfos
  673. {
  674. get
  675. {
  676. return Members.Where(x => x.MemberType == LiveMemberEnum.Device);
  677. }
  678. }
  679. public IEnumerable<LiveConsultationMember> MainUserInfos
  680. {
  681. get
  682. {
  683. return Members.Where(x => x.IsInitiator || x.Id == ApplyUserCode || x.Id == ExpertUserCode);
  684. }
  685. }
  686. /// <summary>
  687. /// The diagnosis room status
  688. /// </summary>
  689. /// <value></value>
  690. public LiveConsultationRoomStatus Status { get; set; }
  691. /// <summary>
  692. /// 病人名称
  693. /// </summary>
  694. public string PatientName { get; set; }
  695. /// <summary>
  696. /// 会诊时间
  697. /// </summary>
  698. public DateTime ConsultationTime { get; set; }
  699. /// <summary>
  700. /// 会诊状态
  701. /// </summary>
  702. public TransactionStatusEnum ConsultationStatus { get; set; }
  703. /// <summary>
  704. /// 申请机构编码
  705. /// </summary>
  706. public string ApplyOrganizationCode { get; set; }
  707. /// <summary>
  708. /// 申请医师编码
  709. /// </summary>
  710. public string ApplyUserCode { get; set; }
  711. /// <summary>
  712. /// 会诊机构编码
  713. /// </summary>
  714. public string ExpertOrganizationCode { get; set; }
  715. /// <summary>
  716. /// 会诊专家编码
  717. /// </summary>
  718. public string ExpertUserCode { get; set; }
  719. /// <summary>
  720. /// 是否急诊标识
  721. /// </summary>
  722. /// <value></value>
  723. public bool IsEmergency { get; set; }
  724. /// <summary>
  725. /// 急诊已接通
  726. /// </summary>
  727. /// <value></value>
  728. public bool EmergencyAccepted { get; set; }
  729. /// <summary>
  730. /// 白板数据集合
  731. /// </summary>
  732. /// <typeparam name="InteractiveBoardDataDTO"></typeparam>
  733. /// <returns></returns>
  734. public IList<InteractiveBoardDataDTO> InteractiveBoardDatas { get; set; } = new List<InteractiveBoardDataDTO>();
  735. }
  736. }