using Dicom; using FISLib.Connect; using FISLib.Remedical; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using Vinno.FIS.Sonopost.Common; using Vinno.FIS.Sonopost.Features.Dicom; using Vinno.FIS.Sonopost.Helpers; using Vinno.FIS.Sonopost.Managers.Interfaces; using Vinno.IUS.Common.Log; namespace Vinno.FIS.Sonopost.Managers { internal class RemedicalManager : SonopostManager, IRemedicalManager { private readonly IRemedicalService _fisRemedicalService; private readonly ILoginManager _loginManager; public RemedicalManager() { _loginManager = AppManager.Instance.GetManager<ILoginManager>(); _loginManager.LoginStatusChanged += OnLoginStatusChanged; _fisRemedicalService = AppManager.Instance.GetManager<IFISManager>().FISRemedicalService; _fisRemedicalService.FISScanDataChanged += OnFISScanDataChanged; } private void OnFISScanDataChanged(object sender, FISVidDataChangedEventArgs e) { try { var scanDataId = e.FISVidData.Id; Logger.WriteLineInfo($"Scan data id: {scanDataId},Status:{e.FISVidData?.Status},ChangeType:{e.ChangeType}"); if (e.FISVidData.Status == FISUploadStatus.Fail && e.ChangeType == FISVidDataChangeType.Update) { DicomUploadContextOperator.Instance.UpdateStatusByScanId(scanDataId, DicomUploadStatus.UploadFail); } else if (e.FISVidData.Status == FISUploadStatus.FailBecauseExamIsFinished && e.ChangeType == FISVidDataChangeType.Update) { DicomUploadContextOperator.Instance.UpdateStatusByScanId(scanDataId, DicomUploadStatus.UploadFailBecauseExamIsFinished); } else if ((e.FISVidData.Status == FISUploadStatus.Uploaded && e.ChangeType == FISVidDataChangeType.Removed) || e.FISVidData.Status == FISUploadStatus.Deleted && e.ChangeType == FISVidDataChangeType.Update) { var item = DicomUploadContextOperator.Instance.GetCacheByScanId(scanDataId); if (item == null) { return; } RemoveByScanDataId(scanDataId); FileHelper.DeleteFile(item.DicomPath); } else if (e.FISVidData.Status == FISUploadStatus.Uploading && e.ChangeType == FISVidDataChangeType.Update) { DicomUploadContextOperator.Instance.UpdateStatusByScanId(scanDataId, DicomUploadStatus.Uploading); } else if ((e.FISVidData.Status == FISUploadStatus.Waiting || e.FISVidData.Status == FISUploadStatus.Idle) && (e.ChangeType == FISVidDataChangeType.Update || e.ChangeType == FISVidDataChangeType.Added)) { DicomUploadContextOperator.Instance.UpdateStatusByScanId(scanDataId, DicomUploadStatus.Waiting); } } catch (Exception ex) { Logger.WriteLineError($"On scan data changed error {e.ChangeType} - {e.FISVidData.Id} : {ex}"); } } /// <summary> /// Delete OverDueRecords /// </summary> /// <param name="tempFileDays"></param> public void DeleteOverDueRecords(int tempFileDays) { if (_loginManager.DeviceStatus != DeviceStatus.Logon) { return; } var failList = DicomUploadContextOperator.Instance.GetAll(); var failScanDatas = _fisRemedicalService.LoadFailedScanDatas(); if (failScanDatas != null && failList != null) { foreach (var failScanData in failScanDatas) { if (!failList.Any(x => x.ScanId == failScanData.Id)) { _fisRemedicalService.DeleteScanDataById(failScanData.Id); } } } } /// <summary> /// upload dicom /// </summary> /// <param name="uploadVidPath"></param> /// <param name="patientId"></param> public void UploadWorkFlow(string uploadVidPath, string patientId) { Logger.WriteLineInfo($"Start Upload to Server,patientId:{patientId}"); var content = UploadContent.Parse(uploadVidPath); if (content != null) { try { if (!content.IsVidFile) { var originalDicomPath = Path.Combine(SonopostConstants.DataFolder, SonopostConstants.OriginalDicomFolder, content.Date, $"{content.Id}.{SonopostConstants.DicomFileName}"); if (File.Exists(originalDicomPath)) { var dicomFile = DicomFile.Open(originalDicomPath); var patientInfo = PatientScanInfoHelper.CreatePatientScanInfo(dicomFile.Dataset); var examId = dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, string.Empty); if (_loginManager.DeviceStatus != DeviceStatus.Logon) { DicomUploadContextOperator.Instance.UpdateStatus(content.Id, DicomUploadStatus.CreateScanDataFail); Logger.WriteLineError($"Upload vinno dicom file failed,Because the Remedical is null.PatientId:{patientId},OriginalDicomPath:{originalDicomPath}"); return; } var scanDataId = _fisRemedicalService.UploadScanData(null, examId, string.Empty, content.UploadFilePath, content.VidType, "FromSonopost", patientInfo, string.Empty); if (!string.IsNullOrEmpty(scanDataId)) { DicomUploadContextOperator.Instance.UpdateScanId(content.Id, scanDataId); return; } else { DicomUploadContextOperator.Instance.UpdateStatus(content.Id, DicomUploadStatus.CreateScanDataFail); Logger.WriteLineError($"ScanData is null.PatientId:{patientId},OriginalDicomPath:{originalDicomPath}"); return; } } else { throw new Exception($"Original Dicom File is not exist {originalDicomPath}"); } } else { if (_loginManager.DeviceStatus != DeviceStatus.Logon) { DicomUploadContextOperator.Instance.UpdateStatus(content.Id, DicomUploadStatus.CreateScanDataFail); Logger.WriteLineError($"Upload vinno dicom file failed,Because the Remedical is null.PatientId:{patientId}"); return; } string scanDataId; scanDataId = _fisRemedicalService.UploadScanData(null, "ExamIdOnlyForScreenShotVersion", string.Empty, content.UploadFilePath, content.VidType, "FromSonopost", new FISPatientScanInfo(), content.ExamRecordId, null, null, true); if (!string.IsNullOrEmpty(scanDataId)) { DicomUploadContextOperator.Instance.UpdateScanId(content.Id, scanDataId); return; } else { DicomUploadContextOperator.Instance.UpdateStatus(content.Id, DicomUploadStatus.CreateScanDataFail); Logger.WriteLineError($"ScanData is null.PatientId:{patientId},ExanRecordId:{content.ExamRecordId}"); return; } } } catch (Exception ex) { DicomUploadContextOperator.Instance.UpdateStatus(content.Id, DicomUploadStatus.Unknown); Logger.WriteLineError($"Upload vinno dicom file failed,PatientId:{patientId}:{ex}."); } } else { Logger.WriteLineError("Parse Upload content Fail"); } } public void Delete(string id) { try { var item = DicomUploadContextOperator.Instance.GetCacheById(id); if (item == null) { return; } if (string.IsNullOrEmpty(item.ScanId)) { RemoveById(id); } else { if (_loginManager.DeviceStatus == DeviceStatus.Logon) { _fisRemedicalService.DeleteScanDataById(item.ScanId); } RemoveByScanDataId(item.ScanId); } FileHelper.DeleteFile(item.DicomPath); } catch (Exception ex) { Logger.WriteLineError($"RemedicalManager Delete Error:{ex}"); } } public void Retry(string id) { var retryItem = DicomUploadContextOperator.Instance.GetCacheById(id); if (retryItem == null) return; if (retryItem.Status == DicomUploadStatus.ConvertFail) { Logger.WriteLineWarn($"Convert Fail,Can not Retry,DicomPath:{retryItem.DicomPath}"); return; } else if (retryItem.Status == DicomUploadStatus.CreateScanDataFail) { var count = retryItem.Count + 1; DicomUploadContextOperator.Instance.UpdateRetryCount(retryItem, count); Thread.Sleep(1000); DicomUploadContextOperator.Instance.UpdateStatus(id, DicomUploadStatus.Waiting); UploadWorkFlow(retryItem.VidPath, retryItem.PatientId); } else if (retryItem.Status == DicomUploadStatus.UploadFail || retryItem.Status == DicomUploadStatus.UploadFailBecauseExamIsFinished) { var count = retryItem.Count + 1; DicomUploadContextOperator.Instance.UpdateRetryCount(retryItem, count); Thread.Sleep(1000); DicomUploadContextOperator.Instance.UpdateStatus(id, DicomUploadStatus.Waiting); RetryUploadByScanId(retryItem.ScanId); } } public string GetDicomFilePath(string id) { var cache = DicomUploadContextOperator.Instance.GetCacheById(id); if (cache != null) { return cache.DicomPath; } return string.Empty; } public IList<DicomUploadContext> GetConvertFailContexts() { return DicomUploadContextOperator.Instance.GetAll(); } private void RetryUploadByScanId(string scanDataId) { if (_loginManager.DeviceStatus != DeviceStatus.Logon) { Logger.WriteLineError($"Reupload vinno dicom file failed,Because the Remedical is null."); return; } var scanData = _fisRemedicalService.LoadFailedScanDatas().FirstOrDefault(m => m.Id == scanDataId); if (scanData != null) { Reupload(scanData.Id); } else { Logger.WriteLineError($"RetryUploadByScanId Can't find ScanDataId{scanDataId} and Delete Automatically"); var item = DicomUploadContextOperator.Instance.GetCacheByScanId(scanDataId); if (item == null) { return; } RemoveByScanDataId(scanDataId); FileHelper.DeleteFile(item.DicomPath); } } private void Reupload(string scanDataId) { _fisRemedicalService.ReUploadScanDataByIds(new List<string> { scanDataId }); } private void RemoveByScanDataId(string scanDataId) { DicomUploadContextOperator.Instance.DeleteByScanId(scanDataId); } private void RemoveById(string id) { DicomUploadContextOperator.Instance.DeleteById(id); } public string GetCollcetingRecordCode() { if (_loginManager.DeviceStatus != DeviceStatus.Logon) { Logger.WriteLineError($"GetCollcetingRecordCode failed,please connect the vcloud server first."); return null; } return _fisRemedicalService.GetCollcetingRecordCode(); } /// <summary> /// 根据ExamrocordId获取详细检查信息 /// </summary> /// <param name="examRecordId"></param> /// <returns></returns> public FISvCloudExamInfo GetCloudExamInfo(string examRecordId) { if (_loginManager.DeviceStatus != DeviceStatus.Logon) { Logger.WriteLineError($"GetCloudExamInfo failed,please connect the vcloud server first."); return null; } return _fisRemedicalService.GetvCloudExamInfo(examRecordId); } public void ClearRemedicalCache() { try { if (_loginManager.DeviceStatus == DeviceStatus.Logon) { _fisRemedicalService.ClearExamRecorderCache(); ; } } catch (Exception ex) { Logger.WriteLineError($"LivePushManager ClearRemedicalCache Error:{ex}"); } } public override void DoDispose() { try { _loginManager.LoginStatusChanged -= OnLoginStatusChanged; _fisRemedicalService.FISScanDataChanged -= OnFISScanDataChanged; } catch (Exception ex) { Logger.WriteLineError($"RemedicalManager DoDispose Error:{ex}"); } base.DoDispose(); } private void OnLoginStatusChanged(object sender, DeviceStatus e) { switch (e) { case DeviceStatus.Logon: ReUploadAll(); break; } } private void ReUploadAll() { try { if (_loginManager.DeviceStatus == DeviceStatus.Logon) { var failList = _fisRemedicalService.LoadFailedScanDatas(); if (failList != null) { foreach (var fail in failList) { RetryUploadByScanId(fail.Id); } } } } catch (Exception ex) { Logger.WriteLineError($"RemedicalManager DoDispose Error:{ex}"); } base.DoDispose(); } } }