using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Data.Common; using System.IO; using System.Linq; using System.Threading.Tasks; using Vinno.IUS.Common.IO; using Vinno.IUS.Common.Log; using Vinno.IUS.Common.Network.Leaf; using Vinno.IUS.Common.Network.Transfer; using Vinno.vCloud.Client.Proxy.Interfaces; using Vinno.vCloud.Common.Client.Managers; using Vinno.vCloud.Common.Client.Managers.Interfaces; using Vinno.vCloud.Common.Client.Managers.Interfaces.Data; using Vinno.vCloud.Common.Client.Managers.Interfaces.Data.RemoteConsultation; using Vinno.vCloud.Common.Client.Plugins.Account.ViewModels; using Vinno.vCloud.Common.Storage; using Vinno.vCloud.Common.Storage.Download; using Vinno.vCloud.Common.Storage.ObjectStorageInfo; using Vinno.vCloud.Common.Storage.Upload; using Vinno.vCloud.Protocol.Infrastructures; using Vinno.vCloud.Protocol.Messages.Admin.RemoteDiagnosis; using Vinno.vCloud.Protocol.Messages.Client; using Vinno.vCloud.Protocol.Messages.Client.Account; using Vinno.vCloud.Protocol.Messages.Client.Chat; using Vinno.vCloud.Protocol.Messages.Client.Live; using Vinno.vCloud.Protocol.Messages.Client.LiveTalking; using Vinno.vCloud.Protocol.Messages.Client.Remedical.Reports; using Vinno.vCloud.Protocol.Messages.Client.Remedical.TerminalDatas; using Vinno.vCloud.Protocol.Messages.Client.Remedical.TerminialReords; using Vinno.vCloud.Protocol.Messages.Client.RemoteDiagnosis; using Vinno.vCloud.Protocol.Messages.Common; using Vinno.vCloud.Protocol.Messages.Live; using Vinno.vCloud.Protocol.Messages.Report; namespace Vinno.vCloud.Client.Proxy { class VCloudClient : IFlyinsonoClient { private volatile int _livingTime; private readonly int _sessionLifecycle = 10; //30*10 minutes private readonly ClientManager _clientManager; private string _currentUserName; private string _accountId; /// <summary> /// 是否单点登录 /// </summary> private bool _isSingleLogin; /// <summary> ///单点登录的模式 /// </summary> private int _singleMode; private bool _isMeeting; private LoginSource _loginSource = LoginSource.ClientProxy; private LanguageType _languageType = LanguageType.Chinese; private GetAccountDetailInfoSuccess8 _getAccountDetailInfo; private object _storageInfoLocker = new object(); private StorageInfo _storageInfo; private readonly string _fileCacheFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FileCacheFolder"); public int LeftTime => _sessionLifecycle - _livingTime; public VCloudClient(string openId, string hostUrl) { OpenId = openId; _clientManager = new ClientManager(hostUrl); _clientManager.MessageArrived += OnMessageArrived; } public event EventHandler<MeetingMemberNotification> MeetingMemberNotificationArrived;//成员改变通知 public event EventHandler<MeetingHangupNotification> MeetingHangupNotificationArrived;//挂断通知 public event EventHandler<StartMeetingNotification> StartMeetingNotificationArrived; public event EventHandler<CancelStartMeetingNotification> CancelStartMeetingNotificationArrived; public event EventHandler<AcceptMeetingNotification> AcceptMeetingNotificationArrived; public event EventHandler<RejectMeetingNotification> RejectMeetingNotificationArrived; public event EventHandler<ChatPendingMemberTimeoutNotification> ChatPendingMemberTimeoutNotificationArrived; public event EventHandler<ChatMemberHeartbeatStatusNotification> ChatMemberHeartbeatStatusNotificationArrived; public event EventHandler<MuteVideoUserChangeNotification> MuteVideoUserChangeNotificationArrived; /// <summary> /// OpenId /// </summary> public string OpenId { get; private set; } public int OnlineTimes { get; private set; } private void OnMessageArrived(object sender, Message e) { Logger.WriteLineInfo($"Message arrived -{e.Tag.Description}"); #region 会诊 var meetingMemberNotification = MeetingMemberNotification.Convert(e); //用户发生变化 if (meetingMemberNotification != null) { Logger.WriteLineInfo($"UserName:{_currentUserName} LiveMeeting MeetingMemberNotification Arrived"); MeetingMemberNotificationArrived?.Invoke(this, meetingMemberNotification); } var startMeetingNotification = StartMeetingNotification.Convert(e); //接收者收到被邀请通知 if (startMeetingNotification != null) { Logger.WriteLineInfo($"UserName:{_currentUserName} LiveMeeting StartMeetingNotification Arrived"); StartMeetingNotificationArrived?.Invoke(this, startMeetingNotification); } var cancelStartMeetingNotification = CancelStartMeetingNotification.Convert(e); //取消会诊通知 if (cancelStartMeetingNotification != null) { Logger.WriteLineInfo($"UserName:{_currentUserName} LiveMeeting CancelStartMeetingNotification Arrived"); CancelStartMeetingNotificationArrived?.Invoke(this, cancelStartMeetingNotification); } var acceptMeetingNotification = AcceptMeetingNotification.Convert(e); if (acceptMeetingNotification != null) { Logger.WriteLineInfo($"UserName:{_currentUserName} LiveMeeting AcceptMeetingNotification Arrived"); AcceptMeetingNotificationArrived?.Invoke(this, acceptMeetingNotification); } var rejectChatNotification = RejectMeetingNotification.Convert(e); //拒绝会诊通知 if (rejectChatNotification != null) { Logger.WriteLineInfo($"UserName:{_currentUserName} LiveMeeting RejectMeetingNotification Arrived"); RejectMeetingNotificationArrived?.Invoke(this, rejectChatNotification); } var meetingHangupNotification = MeetingHangupNotification.Convert(e); if (meetingHangupNotification != null) { Logger.WriteLineInfo($"UserName:{_currentUserName} LiveMeeting MeetingHangupNotification Arrived"); MeetingHangupNotificationArrived?.Invoke(this, meetingHangupNotification); } var chatPendingMemberTimeoutNotification = ChatPendingMemberTimeoutNotification.Convert(e); if (chatPendingMemberTimeoutNotification != null) { Logger.WriteLineInfo($"UserName:{_currentUserName} LiveMeeting ChatPendingMemberTimeoutNotification Arrived"); ChatPendingMemberTimeoutNotificationArrived?.Invoke(this, chatPendingMemberTimeoutNotification); } var chatMemberHeartBeatStatusNotification = ChatMemberHeartbeatStatusNotification.Convert(e); if (chatMemberHeartBeatStatusNotification != null) { Logger.WriteLineInfo($"UserName:{_currentUserName} LiveMeeting ChatMemberHeartbeatStatusNotification Arrived"); ChatMemberHeartbeatStatusNotificationArrived?.Invoke(this, chatMemberHeartBeatStatusNotification); } var muteVideoUserChangeNotification = MuteVideoUserChangeNotification.Convert(e); if (muteVideoUserChangeNotification != null) { Logger.WriteLineInfo($"UserName:{_currentUserName} LiveMeeting MuteVideoUserChangeNotification Arrived"); MuteVideoUserChangeNotificationArrived?.Invoke(this, muteVideoUserChangeNotification); } #endregion } /// <summary> /// Client login /// </summary> /// <param name="username">vCloud user name</param> /// <param name="password">vCloud password</param> /// <returns></returns> public LoginStatus LoginByOpenId(string openId, string username = "", string password = "") { try { var result = _clientManager.LoginByOpenId(openId, username, password); if (result == LoginStatus.Success) { _currentUserName = GetUserInfoByOpenId(openId)?.NickName; _accountId = _clientManager.AccountId; _getAccountDetailInfo = GetCurrentAccountDetails(); } return result; } catch (Exception ex) { Logger.WriteLineError($"VCloudClient Login ex:{ex}"); } return LoginStatus.Unknown; } /// <summary> /// Log out the logined user /// </summary> /// <returns></returns> public bool Logout() { return false; } /// <summary> /// 查询系统默认报告模板 /// </summary> /// <param name="languageCode"></param> /// <returns></returns> public List<ReportTemplateMessage> GetReportTemplates(string languageCode) { var resultData = new List<ReportTemplateMessage>(); if (string.IsNullOrWhiteSpace(languageCode) || languageCode == "zh-CN") { resultData.Add(new ReportTemplateMessage { ReportFileName = "Default", ReportTemplateUrl = "1!U$https://cdn-bj.fis.plus/Default_zh-CN_flyinsono1.7_2023.json", }); resultData.Add(new ReportTemplateMessage { ReportFileName = "Pet", ReportTemplateUrl = "1!U$https://cdn-bj.fis.plus/Pet_zh-CN_flyinsono1.7_2023.json", }); resultData.Add(new ReportTemplateMessage { ReportFileName = "AI", ReportTemplateUrl = "1!U$https://cdn-bj.fis.plus/AI_zh-CN_flyinsono1.7_2023.json", }); } else { resultData.Add(new ReportTemplateMessage { ReportFileName = "Default", ReportTemplateUrl = "1!U$https://cdn-bj.fis.plus/Default_en-US_flyinsono1.7_2023.json", }); resultData.Add(new ReportTemplateMessage { ReportFileName = "Pet", ReportTemplateUrl = "1!U$https://cdn-bj.fis.plus/Pet_en-US_flyinsono1.7_2023.json", }); resultData.Add(new ReportTemplateMessage { ReportFileName = "AI", ReportTemplateUrl = "1!U$https://cdn-bj.fis.plus/AI_en-US_flyinsono1.7_2023.json", }); } if (_getAccountDetailInfo != null && _getAccountDetailInfo.ReportTemplates != null && _getAccountDetailInfo.ReportTemplates.Any()) { resultData.AddRange(_getAccountDetailInfo.ReportTemplates); } return resultData; } /// <summary> /// 查询系统默认词条 /// </summary> /// <param name="languageCode"></param> /// <returns></returns> public List<ReportTemplateMessage> GetThesaurusTemplates(string languageCode) { var resultData = new List<ReportTemplateMessage>(); if (string.IsNullOrWhiteSpace(languageCode) || languageCode == "zh-CN") { resultData.Add(new ReportTemplateMessage { ReportFileName = "Default", ReportTemplateUrl = "1!U$https://cdn-bj.fis.plus/Thesaurus_General_zh-CN_flyinsono1.7_2023.json", }); resultData.Add(new ReportTemplateMessage { ReportFileName = "Pet", ReportTemplateUrl = "1!U$https://cdn-bj.fis.plus/Thesaurus_Pet_zh-CN_flyinsono1.7_2023.json", }); } else { resultData.Add(new ReportTemplateMessage { ReportFileName = "Default", ReportTemplateUrl = "1!U$https://cdn-bj.fis.plus/Thesaurus_General_en-US_flyinsono1.7_2023.json", }); resultData.Add(new ReportTemplateMessage { ReportFileName = "Pet", ReportTemplateUrl = "1!U$https://cdn-bj.fis.plus/Thesaurus_Pet_en-US_flyinsono1.7_2023.json", }); } return resultData; } /// <summary> /// 查询报告标签 /// </summary> /// <returns></returns> public List<LabelInfoMessage> GetCustomerLabels() { try { var request = new GetReportTagsTreeRequest { UserId = _accountId, }; var result = SendMessage(request); if (result != null) { var getReportTagsSuccess = GetReportTagsTreeResult.Convert(result); if (getReportTagsSuccess != null && getReportTagsSuccess.CustomLabels != null && getReportTagsSuccess.CustomLabels.Any()) { return getReportTagsSuccess.CustomLabels; } } } catch (Exception ex) { Logger.WriteLineError($"VCloudClient userName:{_currentUserName} GetCustomerLabels ex:{ex}"); } return new List<LabelInfoMessage>(); } /// <summary> /// 开始会诊 /// </summary> /// <param name="roomId"></param> /// <param name="recipientInfos"></param> /// <param name="terminalIds"></param> /// <param name="initiatorName"></param> /// <param name="consultationId"></param> /// <returns></returns> public ConsultationResult StartConversation(string roomId, string consultationId) { //获取会诊单子信息 var consultation = FindConsultationById(consultationId); if (_isSingleLogin && _singleMode != 1) { using (var request = MessagePool.GetMessage<StartIndependConversationRequest2>()) { request.RoomId = roomId; request.InitiatorId = _accountId; request.InitiatorName = _currentUserName; request.Mode = LiveTalkingMode.Video; request.FeatureSource = FeatureSource.RemoteDiagnosis; request.Source = _loginSource; request.TerminalId = consultation?.TerminalId;//会诊单子查询 request.ConsulationRecordId = consultationId; request.ClientLanguage = _languageType; var result = SendMessage(request); if (result != null) { var resultMessage = MeetingResult.Convert(result); if (resultMessage != null) { List<MeetingMemberInfo> meetingMemberInfos = new List<MeetingMemberInfo>(); foreach (var member in resultMessage.Members) { var meetingMemberInfo = new MeetingMemberInfo { OperationType = member.OperationType, RoleType = member.RoleType, RoomId = member.RoomId, LoginSource = member.LoginSource, State = member.State, Id = member.Id, Name = member.Name, DisplayName = member.DisplayName, Avatar = member.Avatar, UserSign = member.UserSign, PushUrl = member.PushUrl, PullRtmpUrl = member.PullRtmpUrl, PullFlvUrl = member.PullFlvUrl, PullHlsUrl = member.PullHlsUrl }; meetingMemberInfos.Add(meetingMemberInfo); } List<LiveTerminalInfo> terminalInfos = new List<LiveTerminalInfo>(); foreach (var liveTerminal in resultMessage.LiveTerminals) { if (liveTerminal.IsMultiChannels) { var mainTerminalInfo = liveTerminal.Channels.Select(f => f.Name).Contains("Main") ? liveTerminal.Channels.FirstOrDefault(f => f.Name == "Main") : liveTerminal.Channels.FirstOrDefault(); var cameraInfo = liveTerminal.Channels.Count > 1 ? liveTerminal.Channels[1] : null; if (mainTerminalInfo != null) { var terminalInfo = new LiveTerminalInfo() { IsMultiChannels = liveTerminal.IsMultiChannels, OperationType = liveTerminal.OperationType, TerminalLiveEnabled = mainTerminalInfo.Enable, CameraLiveEnabled = cameraInfo?.Enable ?? false, IsMergeChannel = liveTerminal.IsMergeChannel, TerminalWidth = mainTerminalInfo.Width, TerminalHeight = mainTerminalInfo.Height, // TerminalUrl = mainTerminalInfo.RtmpUrl, CameraWidth = cameraInfo?.Width ?? 0, CameraHeight = cameraInfo?.Height ?? 0, // CameraUrl = cameraInfo?.RtmpUrl, // TerminalLiveProtocol = liveTerminal.LiveProtocol, IntegerRoomId = liveTerminal.IntegerRoomId, TerminalIntegerRoomId = liveTerminal.TerminalIntegerRoomId, State = liveTerminal.State, Id = mainTerminalInfo.UserId, CameraId = cameraInfo?.UserId, }; terminalInfos.Add(terminalInfo); } } else { var terminalInfo = new LiveTerminalInfo() { OperationType = liveTerminal.OperationType, TerminalLiveEnabled = liveTerminal.TerminalLiveEnabled, CameraLiveEnabled = liveTerminal.CameraLiveEnabled, IsMergeChannel = liveTerminal.IsMergeChannel, TerminalWidth = liveTerminal.TerminalWidth, TerminalHeight = liveTerminal.TerminalHeight, // TerminalUrl = liveTerminal.TerminalUrl, CameraWidth = liveTerminal.CameraWidth, CameraHeight = liveTerminal.CameraHeight, // CameraUrl = liveTerminal.CameraUrl, // TerminalLiveProtocol = liveTerminal.LiveProtocol, IntegerRoomId = liveTerminal.IntegerRoomId, TerminalIntegerRoomId = liveTerminal.TerminalIntegerRoomId, State = liveTerminal.State, Id = liveTerminal.Id }; terminalInfos.Add(terminalInfo); } } var requestResult = new ConsultationResult(resultMessage.State) { AppId = resultMessage.AppId, RoomId = resultMessage.RoomId, LiveProtocol = resultMessage.LiveProtocol, State = resultMessage.State, IntegerRoomId = resultMessage.IntegerRoomId, TerminalInfos = terminalInfos, MeetingMemberInfos = meetingMemberInfos }; return requestResult; } } } } using (var request = MessagePool.GetMessage<StartMeetingRequest2>()) { request.RoomId = roomId; request.InitiatorId = _accountId; request.InitiatorName = _currentUserName; request.Mode = LiveTalkingMode.Video; request.FeatureSource = FeatureSource.RemoteDiagnosis; request.Source = _loginSource; request.RecipientIds = new List<RecipientInfo>() { new RecipientInfo() { Id = consultation.DoctorId, RoleType = MeetingRoleType.Recipient } }; request.TerminalIds = new List<string>() { consultation?.TerminalId };//会诊单子查询; request.ConsulationRecordId = consultationId; request.ClientLanguage = _languageType; var result = SendMessage(request); if (result != null) { var resultMessage = MeetingResult.Convert(result); if (resultMessage != null) { List<MeetingMemberInfo> meetingMemberInfos = new List<MeetingMemberInfo>(); foreach (var member in resultMessage.Members) { var meetingMemberInfo = new MeetingMemberInfo { OperationType = member.OperationType, RoleType = member.RoleType, RoomId = member.RoomId, LoginSource = member.LoginSource, State = member.State, Id = member.Id, Name = member.Name, DisplayName = member.DisplayName, Avatar = member.Avatar, UserSign = member.UserSign, PushUrl = member.PushUrl, PullRtmpUrl = member.PullRtmpUrl, PullFlvUrl = member.PullFlvUrl, PullHlsUrl = member.PullHlsUrl }; meetingMemberInfos.Add(meetingMemberInfo); } List<LiveTerminalInfo> terminalInfos = new List<LiveTerminalInfo>(); foreach (var liveTerminal in resultMessage.LiveTerminals) { if (liveTerminal.IsMultiChannels) { var mainTerminalInfo = liveTerminal.Channels.Select(f => f.Name).Contains("Main") ? liveTerminal.Channels.FirstOrDefault(f => f.Name == "Main") : liveTerminal.Channels.FirstOrDefault(); var cameraInfo = liveTerminal.Channels.Count > 1 ? liveTerminal.Channels[1] : null; if (mainTerminalInfo != null) { var terminalInfo = new LiveTerminalInfo() { IsMultiChannels = liveTerminal.IsMultiChannels, OperationType = liveTerminal.OperationType, TerminalLiveEnabled = mainTerminalInfo.Enable, CameraLiveEnabled = cameraInfo?.Enable ?? false, IsMergeChannel = liveTerminal.IsMergeChannel, TerminalWidth = mainTerminalInfo.Width, TerminalHeight = mainTerminalInfo.Height, // TerminalUrl = mainTerminalInfo.RtmpUrl, CameraWidth = cameraInfo?.Width ?? 0, CameraHeight = cameraInfo?.Height ?? 0, // CameraUrl = cameraInfo?.RtmpUrl, // TerminalLiveProtocol = liveTerminal.LiveProtocol, IntegerRoomId = liveTerminal.IntegerRoomId, TerminalIntegerRoomId = liveTerminal.TerminalIntegerRoomId, State = liveTerminal.State, Id = mainTerminalInfo.UserId, CameraId = cameraInfo?.UserId, }; terminalInfos.Add(terminalInfo); } } else { var terminalInfo = new LiveTerminalInfo() { OperationType = liveTerminal.OperationType, TerminalLiveEnabled = liveTerminal.TerminalLiveEnabled, CameraLiveEnabled = liveTerminal.CameraLiveEnabled, IsMergeChannel = liveTerminal.IsMergeChannel, TerminalWidth = liveTerminal.TerminalWidth, TerminalHeight = liveTerminal.TerminalHeight, // TerminalUrl = liveTerminal.TerminalUrl, CameraWidth = liveTerminal.CameraWidth, CameraHeight = liveTerminal.CameraHeight, // CameraUrl = liveTerminal.CameraUrl, // TerminalLiveProtocol = liveTerminal.LiveProtocol, IntegerRoomId = liveTerminal.IntegerRoomId, TerminalIntegerRoomId = liveTerminal.TerminalIntegerRoomId, State = liveTerminal.State, Id = liveTerminal.Id }; terminalInfos.Add(terminalInfo); } } var requestResult = new ConsultationResult(resultMessage.State) { AppId = resultMessage.AppId, RoomId = resultMessage.RoomId, LiveProtocol = resultMessage.LiveProtocol, State = resultMessage.State, IntegerRoomId = resultMessage.IntegerRoomId, TerminalInfos = terminalInfos, MeetingMemberInfos = meetingMemberInfos }; if (resultMessage.State == LiveStates.OK) { if (consultation.State < ConsultationState.Started) { UpdateRecordState(new UpdateAppointmentStateRequest() { Id = consultationId, State = ConsultationState.Started }); } } return requestResult; } } } return new ConsultationResult(LiveStates.UnknowException); } public ConsultationMessage FindConsultationById(string id) { try { using (var request = MessagePool.GetMessage<FindConsultationRequest>()) { request.ConsultationId = id; var result = SendMessage(request); if (result != null) { var resultMessage = ConsultationMessage.Convert(result); if (resultMessage != null) { return resultMessage; } } } } catch (Exception ex) { Logger.WriteLineError($"FindConsultation exception:{ex}"); } return null; } /// <summary> /// 取消发起过程中的会诊 /// </summary> /// <param name="roomId"></param> /// <param name="recipientInfos"></param> /// <param name="terminalIds"></param> /// <param name="initiatorName"></param> /// <param name="consultationId"></param> /// <returns></returns> public LiveStates CancelStartConversation(string roomId) { try { using (var request = MessagePool.GetMessage<CancelStartMeetingtRequest>()) { request.RoomId = roomId; request.InitiatorId = _accountId; if (_isMeeting) { request.ForceClosed = false; } else { request.ForceClosed = true; } request.LoginSource = LoginSource.ClientProxy; var result = SendMessage(request); if (result != null) { var resultMessage = CancelStartMeetingtResult.Convert(result); if (resultMessage != null) { return resultMessage.State; } } } } catch (Exception exception) { Logger.WriteLineError($" userName:{_currentUserName} GetUserInfoByOpenId error:{exception}"); } return LiveStates.UnknowException; } /// <summary> /// 会诊过程中邀请会诊成员 /// </summary> /// <param name="roomId"></param> /// <param name="feature"></param> /// <param name="recipientInfos"></param> /// <returns></returns> public ConsultationResult InviteConsultationMember(string roomId, FeatureSource feature, List<RecipientInfo> recipientInfos) { try { using (var request = new InviteMeetingMembersRequest()) { request.InitiatorId = _accountId; request.RoomId = roomId; request.FeatureSource = feature; request.Source = _loginSource; request.RecipientIds = recipientInfos; request.ClientLanguage = _languageType; var result = SendMessage(request); if (result != null) { var resultMessage = InviteMeetingMembersResult.Convert(result); if (resultMessage != null) { var inviteMeeting = new ConsultationResult(resultMessage.State); inviteMeeting.TerminalInfos = resultMessage.LiveTerminals.Select(liveTerminal => new LiveTerminalInfo() { TerminalLiveEnabled = liveTerminal.TerminalLiveEnabled, CameraLiveEnabled = liveTerminal.CameraLiveEnabled, IsMergeChannel = liveTerminal.IsMergeChannel, TerminalWidth = liveTerminal.TerminalWidth, TerminalHeight = liveTerminal.TerminalHeight, // TerminalUrl = liveTerminal.TerminalUrl, CameraWidth = liveTerminal.CameraWidth, CameraHeight = liveTerminal.CameraHeight, // CameraUrl = liveTerminal.CameraUrl, // TerminalLiveProtocol = liveTerminal.LiveProtocol, IntegerRoomId = liveTerminal.IntegerRoomId, State = liveTerminal.State, Id = liveTerminal.Id }).ToList(); inviteMeeting.MeetingMemberInfos = resultMessage.Recipients.Select(member => new MeetingMemberInfo() { OperationType = member.OperationType, RoleType = member.RoleType, RoomId = member.RoomId, LoginSource = member.LoginSource, State = member.State, Id = member.Id, Name = member.Name, DisplayName = member.DisplayName, Avatar = member.Avatar, UserSign = member.UserSign, PushUrl = member.PushUrl, PullRtmpUrl = member.PullRtmpUrl, PullFlvUrl = member.PullFlvUrl, PullHlsUrl = member.PullHlsUrl }).ToList(); return inviteMeeting; } } } } catch (Exception exception) { Logger.WriteLineError($" userName:{_currentUserName} InviteConsultationMember error:{exception}"); } return new ConsultationResult(LiveStates.UnknowException); } /// <summary> /// 退出会诊 /// </summary> /// <param name="roomId"></param> /// <param name="forceClosed"></param> /// <param name="name"></param> /// <param name="terminalId"></param> /// <returns></returns> public LiveStates ExitConsultation(string roomId, bool forceClosed, string terminalId, string consultationId) { try { if (_isSingleLogin && _singleMode != 1) { using (var request = new ExitIndependConversationRequest()) { request.RoomId = roomId; request.InitiatorId = _accountId; request.InitiatorName = _currentUserName; request.ClientLanguage = _languageType; request.Source = _loginSource; request.TerminalId = terminalId; var result = SendMessage(request); if (result != null) { var resultMessage = ResultMessage.Convert(result); if (resultMessage != null && resultMessage == CCR.OK) { return LiveStates.OK; } } } } else { using (var request = new ExitMeetingRequest()) { request.UserId = _accountId; request.RoomId = roomId; request.RecipientIds = new List<string> { _accountId }; request.LoginSource = _loginSource; request.ForceClosed = forceClosed; request.ClientLanguage = _languageType; var result = SendMessage(request); if (result != null) { var resultMessage = ExitMeetingResult.Convert(result); if (resultMessage != null) { var consultationResult = FindConsultationById(consultationId); if (consultationResult?.State != ConsultationState.WaitForReportUpload) { UpdateRecordState(new UpdateAppointmentStateRequest() { Id = consultationId, State = ConsultationState.WaitForReportUpload }); } return resultMessage.State; } } } } _isMeeting = false; } catch (Exception exception) { Logger.WriteLineError($" userName:{_currentUserName} ExitConsultation error:{exception}"); } return LiveStates.UnknowException; } /// <summary> /// 接受会诊邀请 /// </summary> /// <param name="roomId"></param> /// <param name="featureSource"></param> /// <param name="liveStates"></param> /// <param name="initiatorId"></param> /// <returns></returns> public LiveStates AcceptConsultation(string roomId, FeatureSource featureSource, LiveStates liveStates, string initiatorId) { using (var request = new AcceptMeetingRequest()) { request.RoomId = roomId; request.RecipientId = _accountId; request.FeatureSource = featureSource; request.InitiatorId = initiatorId; request.Source = _loginSource; request.PushLiveState = liveStates; request.ClientLanguage = _languageType; var result = SendMessage(request); if (result != null) { var resultMessage = AcceptMeetingResult.Convert(result); if (resultMessage != null) { return resultMessage.State; } } } return LiveStates.UnknowException; } /// <summary> /// 拒绝会诊邀请 /// </summary> /// <param name="roomId"></param> /// <param name="initiatorId"></param> /// <returns></returns> public LiveStates RejectConsultation(string roomId, string initiatorId) { using (var request = new RejectMeetingRequest()) { request.RoomId = roomId; request.RecipientId = _accountId; request.InitiatorId = initiatorId; request.LoginSource = _loginSource; request.ClientLanguage = _languageType; var result = SendMessage(request); if (result != null) { var resultMessage = MeetingResult.Convert(result); //拒绝会诊result if (resultMessage != null) { return resultMessage.State; } } } return LiveStates.UnknowException; } public WechatUserInfo GetUserInfoByOpenId(string openId) { try { using (var request = MessagePool.GetMessage<GetAccountByOpenIdRequest>()) { request.Openid = openId; var messages = SendMessage(request); if (messages == null) return null; var result = GetAccountByOpenIdResult.Convert(messages); if (result == null || string.IsNullOrEmpty(result.UserId)) return null; _getAccountDetailInfo = GetCurrentAccountDetails(); return new WechatUserInfo { NickName = result.NickName, PhoneNumber = result.Phone, Openid = request.Openid, Hospital = _getAccountDetailInfo.Hospital, UserId = result.UserId, }; } } catch (Exception exception) { Logger.WriteLineError($" userName:{_currentUserName} GetUserInfoByOpenId error:{exception}"); } return null; } /// <summary> /// 创建会诊 /// </summary> /// <param name="request"></param> /// <returns></returns> public string CreateConsultationRecord(CreateAppointmentRequest1 request) { try { request.InspectionItems = GetEnglishCheckPointEnName(request.InspectionItems); request.CreatorId = _accountId; var result = SendMessage(request); if (result != null) { var resultMessage = AddConsultationResult.Convert(result); if (resultMessage != null) { return resultMessage.Id; } } } catch (Exception exception) { Logger.WriteLineError($" userName:{_currentUserName} Create Appointment error:{exception}"); } return string.Empty; } public FindNewAppointmentsResult6 FindConsultationRecords(int startIndex, int pageSize, AppointmentsFilterMessage filter) { var pageIndex = startIndex % pageSize == 0 ? startIndex / pageSize : startIndex / pageSize + 1; try { _getAccountDetailInfo = GetCurrentAccountDetails(); filter.SuperiorHospitalIds = _getAccountDetailInfo.HospitalMessage.SuperiorHospitals.Select(v => v.OrganizationId).ToList(); filter.LowerHospitalIds = _getAccountDetailInfo.HospitalMessage.LowerHospitals.Select(v => v.OrganizationId).ToList(); using (var request = MessagePool.GetMessage<FindNewAppointmentsRequest6>()) { request.UserId = _accountId; request.PageIndex = pageIndex; request.PageSize = pageSize; request.Filter = AppointmentsFilterMessage.ConvertToFilterMessage(filter); request.FollowUpVisitStatus = FollowUpVisitStatus.Unknown; request.EvaluateGrade = EvaluateGrade.UnSet; var result = SendMessage(request); if (result != null) { var resultMessage = FindNewAppointmentsResult6.Convert(result); if (resultMessage != null) { foreach (var item in resultMessage.AppointmentsMessages) { item.CheckPoint = GetCnCheckPointCnName(item.CheckPoint); } return resultMessage; } } } } catch (Exception ex) { Logger.WriteLineError($" userName:{_currentUserName} Find Appointments error:{ex}"); } return null; } /// <summary> /// 获取自己的医院列表 /// </summary> /// <returns></returns> public List<OrganBaseInfoMessage> GetMyHospitals() { var hospitals = new List<OrganBaseInfoMessage>(); try { using (var request = MessagePool.GetMessage<GetHospitalsRequest2>()) { request.UserId = _accountId; var result = SendMessage(request); if (result != null) { var resultMessage = GetHospitalsResult.Convert(result); if (resultMessage != null && resultMessage.Hospitals != null) { hospitals = resultMessage.Hospitals.ToList(); } } } } catch (Exception exception) { Logger.WriteLineError($"GetHospitalsAsync userName:{_currentUserName} error:{exception}"); } return hospitals; } /// <summary> /// 获取自己超声机 /// </summary> /// <returns></returns> public List<Interfaces.TerminalInfo> GetMyTerminals() { try { using (var request = MessagePool.GetMessage<FindTerminalsRequest5>()) { request.UserId = _accountId; var result = SendMessage(request); if (result != null) { var terminalsResult = FindTerminalsResult5.Convert(result); return terminalsResult?.EntityMessages.Select(m => new Interfaces.TerminalInfo() { Id = m.Id, OrganizationId = m.OrganizationId, OrganizationDecription = m.OrganizationDescription, OrganizationName = m.OrganizationName, Name = m.TerminalName, Model = m.TerminalModel, Description = m.Description, UniqueId = m.UniquedId, }).ToList(); } } } catch (Exception ex) { Logger.WriteLineError($"VCloudClient userName:{_currentUserName} GetMyTerminals ex:{ex}"); } return new List<Interfaces.TerminalInfo>(); } /// <summary> /// 查询专家 /// </summary> /// <param name="hospitalId"></param> /// <returns></returns> public List<ExpertDetailMessage> FindMyExpertsByHospitalId(string hospitalId) { try { using (var request = MessagePool.GetMessage<FindAllExpertsWithShiftsRequest>()) { request.HospitalId = hospitalId; var result = SendMessage(request); if (result != null) { var resultMessage = FindAllExpertsWithShiftsResult.Convert(result); if (resultMessage != null && resultMessage.ExpertDetails != null) { return resultMessage.ExpertDetails.Select(v => v as ExpertDetailMessage).ToList(); } } } } catch (Exception ex) { Logger.WriteLineError($"VCloudClient userName:{_currentUserName} FindMyExpertsByHospitalId ex:{ex}"); } return null; } /// <summary> /// 获取检查部位 /// </summary> /// <returns></returns> public List<string> GetCheckPoint() { return new List<string>() { "胎儿", "子宫","附件","盆腔","肝脏", "胆囊", "胆管","胰腺","脾脏","双肾","输尿管","膀胱","前列腺","肠系膜淋巴结","乳腺","甲状腺","颈部血管","椎动脉","外周浅表", "淋巴结","心脏", "睾丸","附睾","精索静脉" }; } private string GetCnCheckPointCnName(string enName) { string cnName = enName; switch (enName) { case "Fetu": cnName = "胎儿"; break; case "Uterus": cnName = "子宫"; break; case "Appendages": cnName = "附件"; break; case "PelvicCavity": cnName = "盆腔"; break; case "Liver": cnName = "肝脏"; break; case "GB": cnName = "胆囊"; break; case "BileDuct": cnName = "胆管"; break; case "Pancreas": cnName = "胰腺"; break; case "Spleen": cnName = "脾脏"; break; case "DoubleKidney": cnName = "双肾"; break; case "Ureter": cnName = "输尿管"; break; case "Bladder": cnName = "膀胱"; break; case "Prostate": cnName = "前列腺"; break; case "MesentericLymphNode": cnName = "肠系膜淋巴结"; break; case "Breast": cnName = "乳腺"; break; case "CervicalVessels": cnName = "颈部血管"; break; case "VertebralArtery": cnName = "椎动脉"; break; case "PeripheralSuperficial": cnName = "外周浅表"; break; case "LymphNode": cnName = "淋巴结"; break; case "Cardiac": cnName = "心脏"; break; case "Testicle": cnName = "睾丸"; break; case "Epididymis": cnName = "附睾"; break; case "VenaeSpermatica": cnName = "精索静脉"; break; } return cnName; } private string GetEnglishCheckPointEnName(string cnName) { string enName = cnName; switch (cnName) { case "胎儿": enName = "Fetu"; break; case "子宫": enName = "Uterus"; break; case "附件": enName = "Appendages"; break; case "盆腔": enName = "PelvicCavity"; break; case "肝脏": enName = "Liver"; break; case "胆囊": enName = "GB"; break; case "胆管": enName = "BileDuct"; break; case "胰腺": enName = "Pancreas"; break; case "脾脏": enName = "Spleen"; break; case "双肾": enName = "DoubleKidney"; break; case "输尿管": enName = "Ureter"; break; case "膀胱": enName = "Bladder"; break; case "前列腺": enName = "Prostate"; break; case "肠系膜淋巴结": enName = "MesentericLymphNode"; break; case "乳腺": enName = "Breast"; break; case "颈部血管": enName = "CervicalVessels"; break; case "椎动脉": enName = "VertebralArtery"; break; case "外周浅表": enName = "PeripheralSuperficial"; break; case "淋巴结": enName = "LymphNode"; break; case "心脏": enName = "Cardiac"; break; case "睾丸": enName = "Testicle"; break; case "附睾": enName = "Epididymis"; break; case "精索静脉": enName = "VenaeSpermatica"; break; } return enName; } /// <summary> ///通过远程记录Id查询图像 /// </summary> /// <param name="request"></param> /// <returns></returns> public GetPatientRecordDatasSuccess9 GetPatientRecordImageById(GetPatientRecordDatasRequest11 request) { try { var result = SendMessage(request); if (result != null) { var getRecordsSuccess = GetPatientRecordDatasSuccess9.Convert(result); if (getRecordsSuccess != null) { return getRecordsSuccess; } } } catch (Exception ex) { Logger.WriteLineError($"VCloudClient userName:{_currentUserName} GetPatientRecordImageById ex:{ex}"); } return null; } /// <summary> /// 通过记录Id获取报告 /// </summary> /// <param name="request"></param> /// <returns></returns> public NewGetReportsSuccess5 GetReportByecordId(NewGetReportsRequest5 request) { try { request.UserId = _accountId; var result = SendMessage(request); if (result != null) { var getRecordsSuccess = NewGetReportsSuccess5.Convert(result); if (getRecordsSuccess != null) { return getRecordsSuccess; } } } catch (Exception ex) { Logger.WriteLineError($"VCloudClient userName:{_currentUserName} GetReportByecordId ex:{ex}"); } return null; } /// <summary> /// 查询报告详情 /// </summary> /// <param name="request"></param> /// <returns></returns> public NewReportInfoMessage5 GetReportById(string recordId, string reportId) { try { var request = new NewGetReportsRequest5 { UserId = _accountId, TerminalRecordId = recordId, }; var result = GetReportByecordId(request); return result?.Reports?.FirstOrDefault(x => x.Id == reportId); } catch (Exception ex) { Logger.WriteLineError($"VCloudClient userName:{_currentUserName} GetReportById ex:{ex}"); } return null; } /// <summary> /// 查询分时远程诊断记录 /// </summary> /// <param name="request"></param> /// <returns></returns> public GetRecords11Success GetExamRecords(GetClientRecord11Request request) { try { _getAccountDetailInfo = GetCurrentAccountDetails(); request.Filter.TerminalIds = _getAccountDetailInfo?.AssignedTerminals.Select(v => v.Id).ToList(); request.Filter.OrganizationIds = _getAccountDetailInfo?.AssignedOrganizations.Select(v => v.OrganizationId).ToList(); request.UserId = _accountId; var result = SendMessage(request); if (result != null) { var getRecordsSuccess = GetRecords11Success.Convert(result); if (getRecordsSuccess != null) { return getRecordsSuccess; } } } catch (Exception ex) { Logger.WriteLineError($"VCloudClient userName:{_currentUserName} GetExamRecords ex:{ex}"); } return null; } /// <summary> /// 安排会诊申请单 /// </summary> /// <param name="id"></param> /// <param name="arrangeDt"></param> /// <param name="expertId"></param> /// <returns></returns> public bool ArrangeConsultation(ArrangeAppointmentRequest request) { try { var result = SendMessage(request); if (result != null) { var resultMessage = ResultMessage.Convert(result); if (resultMessage == CCR.OK) { return true; } } } catch (Exception exception) { Logger.WriteLineError($" VCloudClient Finished Appointment error:{exception}"); } return false; } public GetAccountDetailInfoSuccess8 GetCurrentAccountDetails() { try { using (var request = MessagePool.GetMessage<GetAccountDetailInfoRequest8>()) { request.AccountId = _accountId; var result = SendMessage(request); if (result != null) { var accountInfoResult = GetAccountDetailInfoSuccess8.Convert(result); if (accountInfoResult != null) { return accountInfoResult; } } } } catch (Exception ex) { Logger.WriteLineError($"VCloudClient userName:{_currentUserName} GetCurrentAccountDetails ex:{ex}"); } return null; } /// <summary> /// 上传会诊状态 /// </summary> /// <param name=""></param> /// <returns></returns> public bool UpdateRecordState(UpdateAppointmentStateRequest request) { try { var result = SendMessage(request); if (result != null) { var resultMessage = ResultMessage.Convert(result); if (resultMessage == CCR.OK) { return true; } } } catch (Exception exception) { Logger.WriteLineError($" VCloudClient UpdateRecordState error:{exception}"); } return false; } /// Active the session, it will reset the living time of this session. /// </summary> public virtual void Activate() { _livingTime = 0; } /// <summary> /// Deactive the session, it will increase the living time of this session. /// </summary> public virtual void DeActivate() { _livingTime++; } /// <summary> ///会诊过程上传截图 /// </summary> /// <param name="consulationId"></param> /// <param name="imageToken"></param> /// <param name="userName"></param> /// <returns></returns> public bool UploadConsultationImages(string consulationId, string imageToken) { try { using (var request = MessagePool.GetMessage<AddImageAndVideoTokensRequest2>()) { request.ConsultationRecordId = consulationId; request.GraphicInfos = new List<GraphicInfoClientMessage> { new GraphicInfoClientMessage() { GraphicType = 0, GraphicToken = imageToken, PreviewGraphicToken = imageToken, UserId = _accountId, UserName = _currentUserName } }; var result = SendMessage(request); if (result != null) { var resultMessage = ResultMessage.Convert(result); if (resultMessage == CCR.OK) { return true; } } return false; } } catch (Exception e) { Logger.WriteLineError($"UploadConsultationImages Error:{e}"); } return false; } /// <summary> ///会诊过程上传截图视频 /// </summary> /// <param name="consulationId"></param> /// <param name="imageToken"></param> /// <param name="userName"></param> /// <returns></returns> public bool UploadConsulationVideos(string consulationId, string videoToken, string previewToken) { try { using (var request = MessagePool.GetMessage<AddImageAndVideoTokensRequest2>()) { request.ConsultationRecordId = consulationId; request.GraphicInfos = new List<GraphicInfoClientMessage> { new GraphicInfoClientMessage() { GraphicType = 1, GraphicToken = videoToken, PreviewGraphicToken = previewToken, UserId = _accountId, UserName = _currentUserName } }; var result = SendMessage(request); if (result != null) { var resultMessage = ResultMessage.Convert(result); if (resultMessage == CCR.OK) { return true; } } return false; } } catch (Exception e) { Logger.WriteLineError($"UploadConsulationVideos Error:{e}"); } return false; } /// <summary> /// 获取会诊报告 /// </summary> /// <param name="consulationId"></param> /// <param name="imageToken"></param> /// <returns></returns> public NewGetReportsSuccess5 GetConsultationReports(GetConsultationReportsRequest5 request) { try { request.UserId = _accountId; var result = SendMessage(request); if (result != null) { var getRecordsSuccess = NewGetReportsSuccess5.Convert(result); if (getRecordsSuccess != null) { return getRecordsSuccess; } } } catch (Exception ex) { Logger.WriteLineError($"VCloudClient userName:{_currentUserName} GetConsultationReports ex:{ex}"); } return null; } /// <summary> /// 保存报告 /// </summary> /// <param name=""></param> /// <returns></returns> public string SaveReport(NewAddReportRequest4 request) { try { request.UserId = _accountId; var reportElementValues = request.ReportInfo.ReportElementValues.ToList(); reportElementValues.Add(new ReportElementMessage { ElementTag = new ReportElementTagMessage { Id = "9a7baa61-a91d-4399-a3f4-df29117d2d59", Name = "CreateUserId" }, ElementValue = new ReportTextElementValueMessage { Text = _accountId }, }); request.ReportInfo.ReportElementValues = reportElementValues; Logger.WriteLineInfo($" VCloudClient SaveReport, recordId:{request.TerminalRecordId}, Detail:{JsonConvert.SerializeObject(request)}"); var result = SendMessage(request); if (result != null) { var resultMessage = AddReportSuccess.Convert(result); if (resultMessage != null) { FinishRecordByUserId(request.TerminalRecordId, request.UserId); FinishConsultation(request.TerminalRecordId); return resultMessage.ReportCode; } } } catch (Exception exception) { Logger.WriteLineError($" VCloudClient SaveReport error:{exception}"); } return string.Empty; } private void FinishRecordByUserId(string recordId, string userId) { try { var request = new FinishRecordRequest { TerminalRecordId = recordId, UserId = userId, }; var result = SendMessage(request); } catch (Exception exception) { Logger.WriteLineError($" VCloudClient FinishRecordByUserId error:{exception}"); } } private void FinishConsultation(string recordId) { try { var request = new UpdateAppointmentStateRequest { Id = recordId, State = ConsultationState.ReportUploaded, }; var result = SendMessage(request); } catch (Exception exception) { Logger.WriteLineError($" VCloudClient FinishConsultation error:{exception}"); } } public string UploadFile(byte[] fileData) { var storageInfo = GetStorageInfo(); return UploadHelper.UploadFile(storageInfo, fileData); } private StorageInfo GetStorageInfo() { lock (_storageInfoLocker) { if (_storageInfo == null) { using (var request = MessagePool.GetMessage<GetStorageServerRequest2>()) { var result = SendMessage(request); var getDisplayServerInfoResult = GetStorageServerResult2.Convert(result); if (getDisplayServerInfoResult != null) { var url = getDisplayServerInfoResult.ServerUrl; var storageType = getDisplayServerInfoResult.StorageType; var config = getDisplayServerInfoResult.Config; _storageInfo = new StorageInfo() { Url = url, StorageType = storageType, Config = config }; NodeMapping.NodeMappingInilization(_storageInfo.StorageNodeItems); } } } return _storageInfo; } } public byte[] DownloadFile(string fileToken) { var data = new byte[0]; var buffer = DownloadHelper.GetFile(fileToken, _fileCacheFolder, null, null, 0); if (buffer is ByteBuffer byteBuffer) { data = byteBuffer.GetBytes(); } else if (buffer is FileBuffer fileBuffer) { data = fileBuffer.ReadBytes(0, fileBuffer.Size); fileBuffer.DeleteFile(); Logger.WriteLineWarn($" Get file size large than fileName {fileToken} ,it shoud be fileBuffer"); } return data; } private Message SendMessage(Message message) { return _clientManager.Leaf.Send(message, 1000 * 3); } public void Dispose() { _livingTime = 0; if (_clientManager != null) { _clientManager.MessageArrived -= OnMessageArrived; _clientManager.Dispose(); } } } }