using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Vinno.IUS.Common; using Vinno.IUS.Common.Log; using Vinno.IUS.Common.Network.Transfer; using Vinno.vCloud.Client.Proxy.Interfaces; using Vinno.vCloud.Protocol.Infrastructures; using Vinno.vCloud.Protocol.Initializers; using Vinno.vCloud.Protocol.Messages.Client.Account; 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 { public class VCloudClientsProxy { private DefaultLogEngine _logEngine; private ConcurrentDictionary _vCloudClients = new ConcurrentDictionary(); private string _hostUrl; private static VCloudClientsProxy _instance; /// /// The unique instance of app manager /// public static VCloudClientsProxy Instance => _instance ?? (_instance = new VCloudClientsProxy()); public event EventHandler MeetingMemberNotificationArrived;//成员改变通知 public event EventHandler MeetingHangupNotificationArrived;//挂断通知 public event EventHandler MeetingRejectNotificationArrived;//对方拒绝通知 public event EventHandler MeetingAcceptNotificationArrived;//发起者收到对方接受通知 public event EventHandler MeetingPendingMemberTimeoutNotificationArrived;//应答超时通知 private readonly ManualResetEvent _closeEvent = new ManualResetEvent(false); private readonly int _sessionCheckInterval = 30 * 60 * 1000; /// /// instance intialize /// public void Initialize(string hostUrl) { _hostUrl = hostUrl; ClientTagsInitializer.Initialize(); var logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VCloudClientsProxyLogs"); CommonParameters.DataFolder = logPath; _logEngine = new DefaultLogEngine(); Logger.RegisterEngine(_logEngine); StartCheckSessions(); } /// /// Login with specified wechat token, vCloud user name and password /// /// /// /// /// public LoginStatus Login(string openId, string userName, string password) { Logger.WriteLineInfo($"VCloudClient Login openId:{openId} Name:{userName}"); var client = CreateCloudClient(openId, _hostUrl); var result = client.LoginByOpenId(openId, userName, password); if (result == LoginStatus.Success) { _vCloudClients.AddOrUpdate(openId, client, (k, c) => client); } else { CloudClientDispose(client); } return result; } private VCloudClient CreateCloudClient(string openId, string hostUrl) { Logger.WriteLineInfo($"VCloudClient CreateCloudClient openId:{openId} hostUrl:{hostUrl}"); var client = new VCloudClient(openId, hostUrl); client.MeetingMemberNotificationArrived += OnMeetingMemberNotificationArrived; client.MeetingHangupNotificationArrived += OnMeetingHangupNotificationArrived; client.RejectMeetingNotificationArrived += OnMeetingRejectNotificationArrived; client.AcceptMeetingNotificationArrived += OnMeetingAcceptNotificationArrived; client.ChatPendingMemberTimeoutNotificationArrived += OnMneetingPendingMemberTimeoutNotificationArrived; return client; } private void CloudClientDispose(VCloudClient vCloudClient) { vCloudClient.MeetingMemberNotificationArrived -= OnMeetingMemberNotificationArrived; vCloudClient.MeetingHangupNotificationArrived -= OnMeetingHangupNotificationArrived; vCloudClient.RejectMeetingNotificationArrived -= OnMeetingRejectNotificationArrived; vCloudClient.AcceptMeetingNotificationArrived -= OnMeetingAcceptNotificationArrived; vCloudClient.ChatPendingMemberTimeoutNotificationArrived -= OnMneetingPendingMemberTimeoutNotificationArrived; vCloudClient.Dispose(); } private void OnMeetingAcceptNotificationArrived(object sender, AcceptMeetingNotification e) { if (sender is VCloudClient vCloudClient) { MeetingAcceptNotificationArrived?.Invoke(this, new AcceptConversationNotification { OpenId = vCloudClient.OpenId, AcceptMeetingNotification = e }); } } private void OnMeetingRejectNotificationArrived(object sender, RejectMeetingNotification e) { if (sender is VCloudClient vCloudClient) { MeetingRejectNotificationArrived?.Invoke(this, new RejectConversationNotification { OpenId = vCloudClient.OpenId, RejectMeetingNotification = e }); } } private void OnMeetingHangupNotificationArrived(object sender, MeetingHangupNotification e) { if (sender is VCloudClient vCloudClient) { MeetingHangupNotificationArrived?.Invoke(this, new HangupConversationMemberNotification { OpenId = vCloudClient.OpenId, MeetingHangupNotification = e }); } } private void OnMeetingMemberNotificationArrived(object sender, MeetingMemberNotification e) { if (sender is VCloudClient vCloudClient) { MeetingMemberNotificationArrived?.Invoke(this, new ConversationMemberNotification { OpenId = vCloudClient.OpenId, MeetingMemberNotification = e }); } } private void OnMneetingPendingMemberTimeoutNotificationArrived(object sender, ChatPendingMemberTimeoutNotification e) { if (sender is VCloudClient vCloudClient) { MeetingPendingMemberTimeoutNotificationArrived?.Invoke(this, new PendingTimeoutConversationNotification() { OpenId = vCloudClient.OpenId, Notification = e }); } } /// /// 开始会诊 /// /// /// /// /// public ConsultationResult StartConversation(string openId, string roomId, string consultationId) { Logger.WriteLineInfo($"VCloudClient StartConversation openId:{openId} roomId:{roomId} consultationId:{consultationId}"); var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { var consultationMessage = vCloudClient.FindConsultationById(consultationId); vCloudClient.ArrangeConsultation(new ArrangeAppointmentRequest() { Id = consultationId, AppointDate = DateTime.UtcNow, ExpertId = consultationMessage?.ExpertId }); return vCloudClient.StartConversation(roomId, consultationId); } return null; } public LiveStates CancelStartConversation(string openId, string roomId) { Logger.WriteLineInfo($"VCloudClient CancelStartConversation openId:{openId} roomId:{roomId}"); var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.CancelStartConversation(roomId); } return LiveStates.UnknowException; } public LiveStates ExitConsultation(string openId, string roomId, bool forceClosed, string terminalId, string consultationId) { Logger.WriteLineInfo($"VCloudClient ExitConsultation openId:{openId} roomId:{roomId} consultationId:consultationId"); var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.ExitConsultation(roomId, forceClosed, terminalId, consultationId); } return LiveStates.UnknowException; } /// /// /// /// /// 发起者 /// public LiveStates AcceptConsultation(string openId, string roomId, string initiatorId) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.AcceptConsultation(roomId, FeatureSource.RemoteDiagnosis, LiveStates.OK, initiatorId); } return LiveStates.UnknowException; } public LiveStates RejectConsultation(string openId, string roomId, string initiatorId) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.RejectConsultation(roomId, initiatorId); } return LiveStates.UnknowException; } public ConsultationResult InviteConsultationMember(string openId, string roomId, List recipientInfos) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.InviteConsultationMember(roomId, FeatureSource.RemoteDiagnosis, recipientInfos); } return new ConsultationResult(LiveStates.UnknowException); } /// /// 通过openId获取用户信息 /// /// /// public WechatUserInfo GetUserInfoByOpenId(string openId) { Logger.WriteLineInfo($"VCloudClient GetUserInfoByOpenId {openId}"); _vCloudClients.TryGetValue(openId, out IFlyinsonoClient vCloudClient); if (vCloudClient != null) { var userInfo = vCloudClient.GetUserInfoByOpenId(openId); Logger.WriteLineInfo($"VCloudClient GetUserInfoByOpenId, client existed, openId:{openId}, name:{userInfo.UserId} {userInfo.NickName}"); return userInfo; } var client = CreateCloudClient(openId, _hostUrl); var result = client.LoginByOpenId(openId); if (result == LoginStatus.Success) { _vCloudClients.AddOrUpdate(openId, client, (k, c) => client); var userInfo= client.GetUserInfoByOpenId(openId); Logger.WriteLineInfo($"VCloudClient GetUserInfoByOpenId, login success, openId:{openId}, name:{userInfo.UserId} {userInfo.NickName}"); return userInfo; } else { Logger.WriteLineInfo($"VCloudClient GetUserInfoByOpenId, login failed, openId:{openId}"); CloudClientDispose(client); } return null; } private IFlyinsonoClient GetVCloudClient(string openId) { Logger.WriteLineInfo($"VCloudClient GetVCloudClient openId:{openId}"); _vCloudClients.TryGetValue(openId, out IFlyinsonoClient vCloudClient); if (vCloudClient != null) { vCloudClient.Activate(); return vCloudClient; } else { var client = CreateCloudClient(openId, _hostUrl); var result = client.LoginByOpenId(openId); if (result == LoginStatus.Success) { _vCloudClients.AddOrUpdate(openId, client, (k, c) => client); return client; } else { CloudClientDispose(client); } } return null; } /// /// 获取会诊我的超声机 /// /// /// public List GetMyTerminals(string openId) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.GetMyTerminals(); } return null; } /// /// 获取会诊我的医院 /// /// /// public List GetMyHospitals(string openId) { Logger.WriteLineInfo($"VCloudClient GetMyHospitals openId:{openId}"); var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.GetMyHospitals(); } return null; } /// /// 查询会诊记录 /// public FindNewAppointmentsResult6 FindConsultationRecords(string openId, int startIndex, int pageSize, AppointmentsFilterMessage filter) { Logger.WriteLineInfo($"VCloudClient FindConsultationRecords openId:{openId} startIndex:{startIndex} pageSize:{pageSize}"); var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.FindConsultationRecords(startIndex, pageSize, filter); } return null; } /// /// 创建会诊 /// public string CreateConsultationRecord(string openId, CreateAppointmentRequest1 request) { Logger.WriteLineInfo($"VCloudClient CreateConsultationRecord openId:{openId}"); var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.CreateConsultationRecord(request); } return null; } /// /// 通过医院获取专家列表 /// /// /// public List FindMyExpertsByHospitalId(string openId, string hospitalId) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.FindMyExpertsByHospitalId(hospitalId); } return null; } /// /// 获取检查部位 /// /// /// public List GetCheckPoint(string openId) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.GetCheckPoint(); } return null; } /// ///通过远程记录Id查询图像 /// /// /// public GetPatientRecordDatasSuccess9 GetPatientRecordImageById(string openId, GetPatientRecordDatasRequest11 request) { Logger.WriteLineInfo($"VCloudClient GetPatientRecordImageById openId:{openId}"); var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.GetPatientRecordImageById(request); } return null; } /// /// 通过记录Id获取报告 /// /// /// public NewGetReportsSuccess5 GetReportByecordId(string openId, NewGetReportsRequest5 request) { Logger.WriteLineInfo($"VCloudClient GetReportByecordId openId:{openId}"); var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.GetReportByecordId(request); } return null; } /// /// 查询报告详情 /// /// /// /// /// public NewReportInfoMessage5 GetReportById(string openId, string recordId, string reportId) { Logger.WriteLineInfo($"VCloudClient GetReportById openId:{openId}"); var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.GetReportById(recordId, reportId); } return null; } /// /// 查询分时远程诊断记录 /// /// /// public GetRecords11Success GetExamRecords(string openId, GetClientRecord11Request request) { Logger.WriteLineInfo($"VCloudClient GetExamRecords openId:{openId}"); var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.GetExamRecords(request); } return null; } /// /// Log out with specifed wechat token /// /// /// public bool Logout(string openId) { var result = _vCloudClients.TryRemove(openId, out var client); if (result && client != null) { client.Logout(); CloudClientDispose(client as VCloudClient); return true; } return false; } /// /// 查询系统默认报告模板 /// /// /// /// public List GetReportTemplates(string openId, string languageCode) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.GetReportTemplates(languageCode); } return new List(); } /// /// 查询系统默认词条 /// /// /// /// public List GetThesaurusTemplates(string openId, string languageCode) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.GetThesaurusTemplates(languageCode); } return new List(); } /// /// 获取会诊信息 /// /// /// public ConsultationMessage FindConsultationById(string openId, string id) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.FindConsultationById(id); } return null; } /// /// 上传会诊状态 /// /// /// public bool UpdateRecordState(string openId, UpdateAppointmentStateRequest request) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.UpdateRecordState(request); } return false; } /// /// 安排申请单 /// /// /// public bool ArrangeConsultation(string openId, ArrangeAppointmentRequest request) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.ArrangeConsultation(request); } return false; } /// /// 安排申请单 /// /// /// public NewGetReportsSuccess5 GetConsultationReports(string openId, GetConsultationReportsRequest5 request) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.GetConsultationReports(request); } return null; } /// /// 保存报告 /// /// /// /// public string SaveReport(string openId, NewAddReportRequest4 request) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.SaveReport(request); } return string.Empty; } /// /// Start a thread to check sessions intervally. /// private async void StartCheckSessions() { Logger.WriteLineInfo("SessionManager start check sessions."); await Task.Run(() => { while (!_closeEvent.WaitOne(_sessionCheckInterval)) { try { var removeSessionId = new List(); foreach (var session in _vCloudClients.Values) { session.DeActivate(); if (session.LeftTime <= 0) { removeSessionId.Add(session.OpenId); } } foreach (var openId in removeSessionId) { _vCloudClients.TryRemove(openId, out IFlyinsonoClient vCloudClient); CloudClientDispose(vCloudClient as VCloudClient); } } catch (Exception ex) { Logger.WriteLineError($"CheckSessions error:{ex.Message}"); } Logger.WriteLineVerbose("Sessions checked."); } }); } /// /// 上传会诊截图 /// /// /// /// public bool UploadConsultationImages(string openId, string consulationId, string imageToken) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.UploadConsultationImages(consulationId, imageToken); } return false; } /// /// 上传会诊视频 /// /// /// /// public bool UploadConsulationVideos(string openId, string consulationId, string videoToken, string previewToken) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.UploadConsulationVideos(consulationId, videoToken, previewToken); } return false; } public string UploadFile(string openId, byte[] fileData) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.UploadFile(fileData); } return null; } public byte[] DownloadFile(string openId, string fileToken) { var vCloudClient = GetVCloudClient(openId); if (vCloudClient != null) { return vCloudClient.DownloadFile(fileToken); } return null; } /// /// Stop the session check thread. /// public void StopCheckSessions() { _closeEvent.Set(); } } }