RemedicalManager.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. using Dicom;
  2. using FISLib.Connect;
  3. using FISLib.Remedical;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Threading;
  9. using Vinno.FIS.Sonopost.Common;
  10. using Vinno.FIS.Sonopost.Features.Dicom;
  11. using Vinno.FIS.Sonopost.Helpers;
  12. using Vinno.FIS.Sonopost.Managers.Interfaces;
  13. using Vinno.IUS.Common.Log;
  14. namespace Vinno.FIS.Sonopost.Managers
  15. {
  16. internal class RemedicalManager : SonopostManager, IRemedicalManager
  17. {
  18. private readonly IRemedicalService _fisRemedicalService;
  19. private readonly ILoginManager _loginManager;
  20. public RemedicalManager()
  21. {
  22. _loginManager = AppManager.Instance.GetManager<ILoginManager>();
  23. _loginManager.LoginStatusChanged += OnLoginStatusChanged;
  24. _fisRemedicalService = AppManager.Instance.GetManager<IFISManager>().FISRemedicalService;
  25. _fisRemedicalService.FISScanDataChanged += OnFISScanDataChanged;
  26. }
  27. private void OnFISScanDataChanged(object sender, FISVidDataChangedEventArgs e)
  28. {
  29. try
  30. {
  31. var scanDataId = e.FISVidData.Id;
  32. Logger.WriteLineInfo($"Scan data id: {scanDataId},Status:{e.FISVidData?.Status},ChangeType:{e.ChangeType}");
  33. if (e.FISVidData.Status == FISUploadStatus.Fail && e.ChangeType == FISVidDataChangeType.Update)
  34. {
  35. DicomUploadContextOperator.Instance.UpdateStatusByScanId(scanDataId, DicomUploadStatus.UploadFail);
  36. }
  37. else if (e.FISVidData.Status == FISUploadStatus.FailBecauseExamIsFinished && e.ChangeType == FISVidDataChangeType.Update)
  38. {
  39. DicomUploadContextOperator.Instance.UpdateStatusByScanId(scanDataId, DicomUploadStatus.UploadFailBecauseExamIsFinished);
  40. }
  41. else if ((e.FISVidData.Status == FISUploadStatus.Uploaded && e.ChangeType == FISVidDataChangeType.Removed) || e.FISVidData.Status == FISUploadStatus.Deleted && e.ChangeType == FISVidDataChangeType.Update)
  42. {
  43. var item = DicomUploadContextOperator.Instance.GetCacheByScanId(scanDataId);
  44. if (item == null)
  45. {
  46. return;
  47. }
  48. RemoveByScanDataId(scanDataId);
  49. FileHelper.DeleteFile(item.DicomPath);
  50. }
  51. else if (e.FISVidData.Status == FISUploadStatus.Uploading && e.ChangeType == FISVidDataChangeType.Update)
  52. {
  53. DicomUploadContextOperator.Instance.UpdateStatusByScanId(scanDataId, DicomUploadStatus.Uploading);
  54. }
  55. else if ((e.FISVidData.Status == FISUploadStatus.Waiting || e.FISVidData.Status == FISUploadStatus.Idle) && (e.ChangeType == FISVidDataChangeType.Update || e.ChangeType == FISVidDataChangeType.Added))
  56. {
  57. DicomUploadContextOperator.Instance.UpdateStatusByScanId(scanDataId, DicomUploadStatus.Waiting);
  58. }
  59. }
  60. catch (Exception ex)
  61. {
  62. Logger.WriteLineError($"On scan data changed error {e.ChangeType} - {e.FISVidData.Id} : {ex}");
  63. }
  64. }
  65. /// <summary>
  66. /// Delete OverDueRecords
  67. /// </summary>
  68. /// <param name="tempFileDays"></param>
  69. public void DeleteOverDueRecords(int tempFileDays)
  70. {
  71. if (_loginManager.DeviceStatus != DeviceStatus.Logon)
  72. {
  73. return;
  74. }
  75. var failList = DicomUploadContextOperator.Instance.GetAll();
  76. var failScanDatas = _fisRemedicalService.LoadFailedScanDatas();
  77. if (failScanDatas != null && failList != null)
  78. {
  79. foreach (var failScanData in failScanDatas)
  80. {
  81. if (!failList.Any(x => x.ScanId == failScanData.Id))
  82. {
  83. _fisRemedicalService.DeleteScanDataById(failScanData.Id);
  84. }
  85. }
  86. }
  87. }
  88. /// <summary>
  89. /// upload dicom
  90. /// </summary>
  91. /// <param name="uploadVidPath"></param>
  92. /// <param name="patientId"></param>
  93. public void UploadWorkFlow(string uploadVidPath, string patientId)
  94. {
  95. Logger.WriteLineInfo($"Start Upload to Server,patientId:{patientId}");
  96. var content = UploadContent.Parse(uploadVidPath);
  97. if (content != null)
  98. {
  99. try
  100. {
  101. if (!content.IsVidFile)
  102. {
  103. var originalDicomPath = Path.Combine(SonopostConstants.DataFolder, SonopostConstants.OriginalDicomFolder, content.Date, $"{content.Id}.{SonopostConstants.DicomFileName}");
  104. if (File.Exists(originalDicomPath))
  105. {
  106. var dicomFile = DicomFile.Open(originalDicomPath);
  107. var patientInfo = PatientScanInfoHelper.CreatePatientScanInfo(dicomFile.Dataset);
  108. var examId = dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, string.Empty);
  109. if (_loginManager.DeviceStatus != DeviceStatus.Logon)
  110. {
  111. DicomUploadContextOperator.Instance.UpdateStatus(content.Id, DicomUploadStatus.CreateScanDataFail);
  112. Logger.WriteLineError($"Upload vinno dicom file failed,Because the Remedical is null.PatientId:{patientId},OriginalDicomPath:{originalDicomPath}");
  113. return;
  114. }
  115. var scanDataId = _fisRemedicalService.UploadScanData(null, examId, string.Empty, content.UploadFilePath, content.VidType, "FromSonopost", patientInfo, string.Empty);
  116. if (!string.IsNullOrEmpty(scanDataId))
  117. {
  118. DicomUploadContextOperator.Instance.UpdateScanId(content.Id, scanDataId);
  119. return;
  120. }
  121. else
  122. {
  123. DicomUploadContextOperator.Instance.UpdateStatus(content.Id, DicomUploadStatus.CreateScanDataFail);
  124. Logger.WriteLineError($"ScanData is null.PatientId:{patientId},OriginalDicomPath:{originalDicomPath}");
  125. return;
  126. }
  127. }
  128. else
  129. {
  130. throw new Exception($"Original Dicom File is not exist {originalDicomPath}");
  131. }
  132. }
  133. else
  134. {
  135. if (_loginManager.DeviceStatus != DeviceStatus.Logon)
  136. {
  137. DicomUploadContextOperator.Instance.UpdateStatus(content.Id, DicomUploadStatus.CreateScanDataFail);
  138. Logger.WriteLineError($"Upload vinno dicom file failed,Because the Remedical is null.PatientId:{patientId}");
  139. return;
  140. }
  141. string scanDataId;
  142. scanDataId = _fisRemedicalService.UploadScanData(null, "ExamIdOnlyForScreenShotVersion", string.Empty, content.UploadFilePath, content.VidType, "FromSonopost", new FISPatientScanInfo(), content.ExamRecordId, null, null, true);
  143. if (!string.IsNullOrEmpty(scanDataId))
  144. {
  145. DicomUploadContextOperator.Instance.UpdateScanId(content.Id, scanDataId);
  146. return;
  147. }
  148. else
  149. {
  150. DicomUploadContextOperator.Instance.UpdateStatus(content.Id, DicomUploadStatus.CreateScanDataFail);
  151. Logger.WriteLineError($"ScanData is null.PatientId:{patientId},ExanRecordId:{content.ExamRecordId}");
  152. return;
  153. }
  154. }
  155. }
  156. catch (Exception ex)
  157. {
  158. DicomUploadContextOperator.Instance.UpdateStatus(content.Id, DicomUploadStatus.Unknown);
  159. Logger.WriteLineError($"Upload vinno dicom file failed,PatientId:{patientId}:{ex}.");
  160. }
  161. }
  162. else
  163. {
  164. Logger.WriteLineError("Parse Upload content Fail");
  165. }
  166. }
  167. public void Delete(string id)
  168. {
  169. try
  170. {
  171. var item = DicomUploadContextOperator.Instance.GetCacheById(id);
  172. if (item == null)
  173. {
  174. return;
  175. }
  176. if (string.IsNullOrEmpty(item.ScanId))
  177. {
  178. RemoveById(id);
  179. }
  180. else
  181. {
  182. if (_loginManager.DeviceStatus == DeviceStatus.Logon)
  183. {
  184. _fisRemedicalService.DeleteScanDataById(item.ScanId);
  185. }
  186. RemoveByScanDataId(item.ScanId);
  187. }
  188. FileHelper.DeleteFile(item.DicomPath);
  189. }
  190. catch (Exception ex)
  191. {
  192. Logger.WriteLineError($"RemedicalManager Delete Error:{ex}");
  193. }
  194. }
  195. public void Retry(string id)
  196. {
  197. var retryItem = DicomUploadContextOperator.Instance.GetCacheById(id);
  198. if (retryItem == null)
  199. return;
  200. if (retryItem.Status == DicomUploadStatus.ConvertFail)
  201. {
  202. Logger.WriteLineWarn($"Convert Fail,Can not Retry,DicomPath:{retryItem.DicomPath}");
  203. return;
  204. }
  205. else if (retryItem.Status == DicomUploadStatus.CreateScanDataFail)
  206. {
  207. var count = retryItem.Count + 1;
  208. DicomUploadContextOperator.Instance.UpdateRetryCount(retryItem, count);
  209. Thread.Sleep(1000);
  210. DicomUploadContextOperator.Instance.UpdateStatus(id, DicomUploadStatus.Waiting);
  211. UploadWorkFlow(retryItem.VidPath, retryItem.PatientId);
  212. }
  213. else if (retryItem.Status == DicomUploadStatus.UploadFail || retryItem.Status == DicomUploadStatus.UploadFailBecauseExamIsFinished)
  214. {
  215. var count = retryItem.Count + 1;
  216. DicomUploadContextOperator.Instance.UpdateRetryCount(retryItem, count);
  217. Thread.Sleep(1000);
  218. DicomUploadContextOperator.Instance.UpdateStatus(id, DicomUploadStatus.Waiting);
  219. RetryUploadByScanId(retryItem.ScanId);
  220. }
  221. }
  222. public string GetDicomFilePath(string id)
  223. {
  224. var cache = DicomUploadContextOperator.Instance.GetCacheById(id);
  225. if (cache != null)
  226. {
  227. return cache.DicomPath;
  228. }
  229. return string.Empty;
  230. }
  231. public IList<DicomUploadContext> GetConvertFailContexts()
  232. {
  233. return DicomUploadContextOperator.Instance.GetAll();
  234. }
  235. private void RetryUploadByScanId(string scanDataId)
  236. {
  237. if (_loginManager.DeviceStatus != DeviceStatus.Logon)
  238. {
  239. Logger.WriteLineError($"Reupload vinno dicom file failed,Because the Remedical is null.");
  240. return;
  241. }
  242. var scanData = _fisRemedicalService.LoadFailedScanDatas().FirstOrDefault(m => m.Id == scanDataId);
  243. if (scanData != null)
  244. {
  245. Reupload(scanData.Id);
  246. }
  247. else
  248. {
  249. Logger.WriteLineError($"RetryUploadByScanId Can't find ScanDataId{scanDataId} and Delete Automatically");
  250. var item = DicomUploadContextOperator.Instance.GetCacheByScanId(scanDataId);
  251. if (item == null)
  252. {
  253. return;
  254. }
  255. RemoveByScanDataId(scanDataId);
  256. FileHelper.DeleteFile(item.DicomPath);
  257. }
  258. }
  259. private void Reupload(string scanDataId)
  260. {
  261. _fisRemedicalService.ReUploadScanDataByIds(new List<string> { scanDataId });
  262. }
  263. private void RemoveByScanDataId(string scanDataId)
  264. {
  265. DicomUploadContextOperator.Instance.DeleteByScanId(scanDataId);
  266. }
  267. private void RemoveById(string id)
  268. {
  269. DicomUploadContextOperator.Instance.DeleteById(id);
  270. }
  271. public string GetCollcetingRecordCode()
  272. {
  273. if (_loginManager.DeviceStatus != DeviceStatus.Logon)
  274. {
  275. Logger.WriteLineError($"GetCollcetingRecordCode failed,please connect the vcloud server first.");
  276. return null;
  277. }
  278. return _fisRemedicalService.GetCollcetingRecordCode();
  279. }
  280. /// <summary>
  281. /// 根据ExamrocordId获取详细检查信息
  282. /// </summary>
  283. /// <param name="examRecordId"></param>
  284. /// <returns></returns>
  285. public FISvCloudExamInfo GetCloudExamInfo(string examRecordId)
  286. {
  287. if (_loginManager.DeviceStatus != DeviceStatus.Logon)
  288. {
  289. Logger.WriteLineError($"GetCloudExamInfo failed,please connect the vcloud server first.");
  290. return null;
  291. }
  292. return _fisRemedicalService.GetvCloudExamInfo(examRecordId);
  293. }
  294. public void ClearRemedicalCache()
  295. {
  296. try
  297. {
  298. if (_loginManager.DeviceStatus == DeviceStatus.Logon)
  299. {
  300. _fisRemedicalService.ClearExamRecorderCache(); ;
  301. }
  302. }
  303. catch (Exception ex)
  304. {
  305. Logger.WriteLineError($"LivePushManager ClearRemedicalCache Error:{ex}");
  306. }
  307. }
  308. public override void DoDispose()
  309. {
  310. try
  311. {
  312. _loginManager.LoginStatusChanged -= OnLoginStatusChanged;
  313. _fisRemedicalService.FISScanDataChanged -= OnFISScanDataChanged;
  314. }
  315. catch (Exception ex)
  316. {
  317. Logger.WriteLineError($"RemedicalManager DoDispose Error:{ex}");
  318. }
  319. base.DoDispose();
  320. }
  321. private void OnLoginStatusChanged(object sender, DeviceStatus e)
  322. {
  323. switch (e)
  324. {
  325. case DeviceStatus.Logon:
  326. ReUploadAll();
  327. break;
  328. }
  329. }
  330. private void ReUploadAll()
  331. {
  332. try
  333. {
  334. if (_loginManager.DeviceStatus == DeviceStatus.Logon)
  335. {
  336. var failList = _fisRemedicalService.LoadFailedScanDatas();
  337. if (failList != null)
  338. {
  339. foreach (var fail in failList)
  340. {
  341. RetryUploadByScanId(fail.Id);
  342. }
  343. }
  344. }
  345. }
  346. catch (Exception ex)
  347. {
  348. Logger.WriteLineError($"RemedicalManager DoDispose Error:{ex}");
  349. }
  350. base.DoDispose();
  351. }
  352. }
  353. }