MigrateService.cs 107 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128
  1. using Flyinsono.DBCopy.Tool.Entities;
  2. using Flyinsono.DBCopy.Tool.RpcService;
  3. using Flyinsono.DBCopy.Tool.Service.Repositories;
  4. using MongoDB.Driver;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Security;
  10. using System.Reflection;
  11. using System.Threading.Tasks;
  12. using System.Windows.Controls;
  13. using System.Xml.Linq;
  14. using WingInterfaceLibrary.DTO.Common;
  15. using WingInterfaceLibrary.DTO.DataCenter;
  16. using WingInterfaceLibrary.DTO.Management;
  17. using WingInterfaceLibrary.DTO.Record;
  18. using WingInterfaceLibrary.Enum;
  19. using WingInterfaceLibrary.Enum.CourseEnum;
  20. using WingInterfaceLibrary.Internal.Request;
  21. using WingInterfaceLibrary.Request;
  22. using WingInterfaceLibrary.Request.DBCopy;
  23. using WingServerCommon.Mapper;
  24. using MongoDB.Bson.IO;
  25. using JsonConvert = Newtonsoft.Json.JsonConvert;
  26. using WingInterfaceLibrary.Request.AIDiagnosis;
  27. using DnsClient.Protocol;
  28. using System.Text.RegularExpressions;
  29. using WingInterfaceLibrary.Result.AppletAPI;
  30. using WingInterfaceLibrary.DTO.Comment;
  31. using WingInterfaceLibrary.Request.Report;
  32. using WingInterfaceLibrary.DTO.Report;
  33. using WingInterfaceLibrary.LiveConsultation.Consultation;
  34. using WingInterfaceLibrary.DTO.Consultation;
  35. using System.Net.Http;
  36. using System.Net;
  37. using WingInterfaceLibrary.Request.Storage;
  38. using SharpCompress.Common;
  39. using System.Security.Policy;
  40. using System.Net.Http.Headers;
  41. using WingServerCommon.Interfaces.FileTransfer;
  42. using WingInterfaceLibrary.LiveConsultation;
  43. using WingInterfaceLibrary.Request.Report;
  44. using WingInterfaceLibrary.DTO.Report;
  45. using WingInterfaceLibrary.LiveConsultation.Consultation;
  46. using WingInterfaceLibrary.DTO.Consultation;
  47. using WingInterfaceLibrary.Request.User;
  48. using MongoDB.Driver.Core.Operations;
  49. namespace Flyinsono.DBCopy.Tool.Service
  50. {
  51. internal partial class MigrateService
  52. {
  53. private JsonRpcProxy _jsonRpcProxy;
  54. static HttpClient _httpClient = new HttpClient();
  55. private readonly string _tempFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DownloadTemp");
  56. private TerminalRecordDBRepository _terminalRecordDBRepository;
  57. private TerminalDatasDBRepository _terminalDatasDBRepository;
  58. private TerminalAIDatasDBRepository _terminalAIDatasDBRepository;
  59. private Carotid3dModelDatasDBRepository _carotid3dModelDatasDBRepository;
  60. private TerminalRecordReportStatesDBRepository _terminalRecordReportStatesDBRepository;
  61. private OrganizationsDBRepository _organizationsDBRepository;
  62. private TerminalsDBRepository _terminalsDBRepository;
  63. private PosterConfigsDBRepository _posterConfigsDBRepository;
  64. private MigrateRecordDTO _migrateRecord;
  65. private readonly string DefaultToken = "637f02a065ad47fbbe01b956919419c2";
  66. private ConsultationRecordDBRepository _consultationRecordDBRepository;
  67. private UsersDBRepository _usersDBRepository;
  68. private VideoDBRepository _videoDBRepository;
  69. private UserGroupDBRepository _userGroupDBRepository;
  70. private UltrasonicClassDBRepository _ultrasonicClassDBRepository;
  71. private CoursesDBRepository _coursesDBRepository;
  72. private AdminDBRepository _adminDBRepository;
  73. private ExaminationPaperDBPepository _examinationPaperDBPepository;
  74. private ExamScoreDBRepository _examScoreDBRepository;
  75. private ReportTemplateDBRepository _reportTemplateDBRepository;
  76. private ReportInfoResultDBRepository _reportInfoResultDBRepository;
  77. private CustomLabelDBRepository _customLabelDBRepository;
  78. protected readonly object locker = new object();
  79. public MigrateService(string dcServiceUrl)
  80. {
  81. _jsonRpcProxy = new JsonRpcProxy(dcServiceUrl);
  82. _httpClient.Timeout = TimeSpan.FromMinutes(15);
  83. _terminalRecordDBRepository = new TerminalRecordDBRepository();
  84. _terminalDatasDBRepository = new TerminalDatasDBRepository();
  85. _carotid3dModelDatasDBRepository = new Carotid3dModelDatasDBRepository();
  86. _terminalRecordReportStatesDBRepository = new TerminalRecordReportStatesDBRepository();
  87. _organizationsDBRepository = new OrganizationsDBRepository();
  88. _terminalsDBRepository = new TerminalsDBRepository();
  89. _posterConfigsDBRepository = new PosterConfigsDBRepository();
  90. _migrateRecord = GetQueryMigrateTimeRange();
  91. _terminalAIDatasDBRepository = new TerminalAIDatasDBRepository();
  92. _consultationRecordDBRepository = new ConsultationRecordDBRepository();
  93. _usersDBRepository = new UsersDBRepository();
  94. _videoDBRepository = new VideoDBRepository();
  95. _userGroupDBRepository = new UserGroupDBRepository();
  96. _ultrasonicClassDBRepository = new UltrasonicClassDBRepository();
  97. _coursesDBRepository = new CoursesDBRepository();
  98. _adminDBRepository = new AdminDBRepository();
  99. _examinationPaperDBPepository = new ExaminationPaperDBPepository();
  100. _examScoreDBRepository = new ExamScoreDBRepository();
  101. _reportTemplateDBRepository = new ReportTemplateDBRepository();
  102. _adminDBRepository = new AdminDBRepository();
  103. _reportInfoResultDBRepository = new ReportInfoResultDBRepository();
  104. _customLabelDBRepository = new CustomLabelDBRepository();
  105. }
  106. public async Task WriteMigrateStaticAsync()
  107. {
  108. Logger.WriteLineInfo($"Migrate Static Starting");
  109. Logger.WriteLineInfo($"terminal record totalCount:{_terminalRecordDBRepository.GetTerminalRecords(Builders<TerminalRecords>.Filter.Where(x => x.IsDelete == false)).Count()}");
  110. Logger.WriteLineInfo($"consultation record totalCount:{_consultationRecordDBRepository.GetTerminalRecords(Builders<ConsultationRecords>.Filter.Where(x => x.IsDeleted == false)).Count()}");
  111. Logger.WriteLineInfo($"video totalCount:{_videoDBRepository.GetVideos(Builders<Video>.Filter.Where(x => x.IsDeleted == false)).Count()}");
  112. Logger.WriteLineInfo($"course totalCount:{_coursesDBRepository.GetCourses(Builders<Courses>.Filter.Where(x => x.IsDeleted == false)).Count()}");
  113. Logger.WriteLineInfo($"exam paper totalCount:{_examinationPaperDBPepository.GetExaminationPapers(Builders<ExaminationPaper>.Filter.Where(x => x.IsDeleted == false)).Count()}");
  114. Logger.WriteLineInfo($"report totalCount:{_reportInfoResultDBRepository.GetReports(Builders<ReportInfoResults>.Filter.Where(x => true)).Count()}");
  115. Logger.WriteLineInfo($"terminal ai data totalCount:{_terminalAIDatasDBRepository.GetTerminalAIDatas(Builders<TerminalAIDatas>.Filter.Where(x => true)).Count()}");
  116. Logger.WriteLineInfo($"Migrate Static Successfully");
  117. }
  118. /// <summary>
  119. /// 查询同步数据的时间范围
  120. /// </summary>
  121. /// <returns></returns>
  122. private MigrateRecordDTO GetQueryMigrateTimeRange()
  123. {
  124. lock (locker)
  125. {
  126. if (_migrateRecord != null && _migrateRecord.EndTime > DateTime.MinValue)
  127. {
  128. return _migrateRecord;
  129. }
  130. var request = new QueryMigrateTimeRequest
  131. {
  132. Token = DefaultToken,
  133. IsInitMigreate = true
  134. };
  135. var result = _jsonRpcProxy.User.QueryMigrateTimeAsync(request).Result;
  136. return result;
  137. }
  138. }
  139. /// <summary>
  140. /// 备份库迁移分时诊断数据
  141. /// </summary>
  142. /// <returns></returns>
  143. public async Task MigrateRemoteDiagnosisInfosAsync()
  144. {
  145. Logger.WriteLineInfo($"Remote Diagnosis Infos Migrate Starting");
  146. var source = _terminalRecordDBRepository.GetTerminalRecords(Builders<TerminalRecords>.Filter.Where(x => x.IsDelete == false))
  147. .OrderByDescending(x => x.CreateTime).ThenBy(x => x.Id).ToList();
  148. OnMigrate("terminal record", source, SendRemoteDiagnosisInfos);
  149. source.Clear();
  150. Logger.WriteLineInfo($"Remote Diagnosis Infos Migrate Successfully");
  151. }
  152. /// <summary>
  153. /// 备份库迁移实时会诊数据
  154. /// </summary>
  155. /// <returns></returns>
  156. public async Task MigrateLiveConsultationInfosAsync()
  157. {
  158. Logger.WriteLineInfo($"Live Consultation Infos Migrate Starting");
  159. var source = _consultationRecordDBRepository.GetTerminalRecords(Builders<ConsultationRecords>.Filter.Where(x => x.IsDeleted == false))
  160. .OrderByDescending(x => x.CreateTime).ThenBy(x => x.Id).ToList();
  161. OnMigrate("consultation record", source, SendLiveConsultationInfos);
  162. source.Clear();
  163. Logger.WriteLineInfo($"Live Consultation Infos Migrate Successfully");
  164. }
  165. /// <summary>
  166. /// 备份库迁移在线视频数据
  167. /// </summary>
  168. /// <returns></returns>
  169. public async Task MigrateOnlineVideoInfosAsync()
  170. {
  171. Logger.WriteLineInfo($"Online Video Infos Migrate Starting");
  172. var videos = _videoDBRepository.GetVideos(Builders<Video>.Filter.Where(x => x.IsDeleted == false))
  173. .OrderByDescending(x => x.CreateTime).ThenBy(x => x.Id).ToList();
  174. OnMigrate("video", videos, SendVideoInfos);
  175. videos.Clear();
  176. Logger.WriteLineInfo($"Online Video Infos Migrate Successfully");
  177. }
  178. /// <summary>
  179. /// 备份库迁移在线培训数据
  180. /// </summary>
  181. /// <returns></returns>
  182. public async Task MigrateOnlineTrainingInfosAsync()
  183. {
  184. Logger.WriteLineInfo($"Online Training Infos Migrate Starting");
  185. var videos = _coursesDBRepository.GetCourses(Builders<Courses>.Filter.Where(x => x.IsDeleted == false))
  186. .OrderByDescending(x => x.CreateTime).ThenBy(x => x.Id).ToList();
  187. OnMigrate("course", videos, SendCourseInfos);
  188. videos.Clear();
  189. Logger.WriteLineInfo($"Online Training Infos Migrate Successfully");
  190. }
  191. /// <summary>
  192. /// 备份库迁移教培试卷数据
  193. /// </summary>
  194. /// <returns></returns>
  195. public async Task MigrateExamPaperInfosAsync()
  196. {
  197. Logger.WriteLineInfo($"Exam Paper Infos Migrate Starting");
  198. var examPapers = _examinationPaperDBPepository.GetExaminationPapers(Builders<ExaminationPaper>.Filter.Where(x => x.IsDeleted == false))
  199. .OrderByDescending(x => x.CreateTime).ThenBy(x => x.Id).ToList();
  200. OnMigrate("exam paper", examPapers, SendExaminationPaperInfos);
  201. examPapers.Clear();
  202. Logger.WriteLineInfo($"Exam Paper Infos Migrate Successfully");
  203. }
  204. /// <summary>
  205. /// 备份库迁移报告数据
  206. /// </summary>
  207. /// <returns></returns>
  208. public async Task MigrateReportInfosAsync()
  209. {
  210. Logger.WriteLineInfo($"Report Infos Migrate Starting");
  211. var reports = _reportInfoResultDBRepository.GetReports(Builders<ReportInfoResults>.Filter.Where(x => true))
  212. .OrderByDescending(x => x.CreateTime).ThenBy(x => x.Id).ToList();
  213. OnMigrate("report", reports, SendReportInfos);
  214. reports.Clear();
  215. Logger.WriteLineInfo($"Report Infos Migrate Successfully");
  216. }
  217. /// <summary>
  218. /// 备份库迁移图像诊断结果数据
  219. /// </summary>
  220. /// <returns></returns>
  221. public async Task MigrateTerminalAIDataInfosAsync()
  222. {
  223. Logger.WriteLineInfo($"Terminal AI Data Infos Migrate Starting");
  224. var terminalAIDatas = _terminalAIDatasDBRepository.GetTerminalAIDatas(Builders<TerminalAIDatas>.Filter.Where(x => true))
  225. .OrderByDescending(x => x.CreateTime).ThenBy(x => x.Id).ToList();
  226. OnMigrate("terminal ai data", terminalAIDatas, SendTerminalAIDataInfos);
  227. terminalAIDatas.Clear();
  228. Logger.WriteLineInfo($"Terminal AI Data Infos Migrate Successfully");
  229. }
  230. private void OnMigrate<IEntity>(string name, IList<IEntity> source, Action<IList<IEntity>, SyncDBEnum> migrateAction, SyncDBEnum syncType = SyncDBEnum.Migrate,int processNumber=100)
  231. {
  232. Logger.WriteLineInfo($"{name} totalCount:{source.Count}");
  233. var totalCount = source.Count;
  234. var processedCount = 0;
  235. var minute = DateTime.Now.Minute;
  236. while (true)
  237. {
  238. var pendingRecords = source.Skip(processedCount).Take(processNumber)?.ToList() ?? new List<IEntity>();
  239. var pendingCount = pendingRecords.Count;
  240. if (pendingCount > 0)
  241. {
  242. migrateAction.Invoke(pendingRecords, syncType);
  243. processedCount += pendingCount;
  244. }
  245. if (DateTime.Now.Minute != minute)
  246. {
  247. minute = DateTime.Now.Minute;
  248. Logger.WriteLineInfo($"{name} processing: {processedCount * 100 / totalCount}%");
  249. }
  250. if (pendingCount < processNumber)
  251. {
  252. Logger.WriteLineInfo($"{name} processing: 100%");
  253. break;
  254. }
  255. }
  256. }
  257. private void SendRemoteDiagnosisInfos(IList<TerminalRecords> terminalRecords, SyncDBEnum syncType)
  258. {
  259. try
  260. {
  261. var terminalRecordCodes = terminalRecords.Select(x => x.Id).ToList();
  262. var terminalDatas = _terminalDatasDBRepository.GetTerminalDatasByCodes(terminalRecordCodes)?.ToList() ?? new List<TerminalDatas>();
  263. var terminalRecordStates = _terminalRecordReportStatesDBRepository.GetTerminalRecordReportStatesByCodes(terminalRecordCodes)?.ToList() ?? new List<TerminalRecordReportStates>();
  264. var deviceCodes = terminalRecords.Select(x => x.Terminal?.Id ?? string.Empty).ToList();
  265. var terminals = _terminalsDBRepository.GetTerminalByCodes(deviceCodes)?.ToList() ?? new List<Terminals>();
  266. var orgCodes = terminalRecords.Select(x => x.Organization?.Id ?? string.Empty).ToList();
  267. if (terminals.Any())
  268. {
  269. var terminalOrgs = terminals.Select(x => x.Organization?.Id ?? string.Empty);
  270. orgCodes = orgCodes.Union(terminalOrgs).ToList();
  271. }
  272. var organizations = _organizationsDBRepository.GetOrganizationByCodes(orgCodes)?.ToList() ?? new List<Organizations>();
  273. var remoteDiagnosisInfos = new List<RemoteDiagnosisDTO>();
  274. foreach (var terminalRecord in terminalRecords)
  275. {
  276. var terminalRecordId = terminalRecord.Id;
  277. var patientInfo = terminalRecord.PatientInfo;
  278. var terminalDataInfos = terminalDatas.Where(x => x.TerminalRecordId == terminalRecordId)?.ToList() ?? new List<TerminalDatas>();
  279. var terminalRecordStateInfos = terminalRecordStates.Where(x => x.TerminalRecordId == terminalRecordId)?.ToList() ?? new List<TerminalRecordReportStates>();
  280. var remoteDiagnosisInfo = new RemoteDiagnosisDTO
  281. {
  282. Code = terminalRecordId,
  283. CreateTime = terminalRecord.CreateTime,
  284. UpdateTime = terminalRecord.UpdateTime,
  285. ExamId = terminalRecord.ExamId,
  286. OrganizationInfo = MapToOrganizationView(organizations, terminalRecord.Organization?.Id),
  287. DeviceInfo = MapToDeviceView(terminals, terminalRecord.Terminal?.Id),
  288. QualifiedInfo = new QualifiedView
  289. {
  290. QualifiedState = (WingInterfaceLibrary.Enum.QualifiedState)terminalRecord.QualifiedState,
  291. QualityType = (WingInterfaceLibrary.Enum.QualityType)terminalRecord.QualityType,
  292. },
  293. DiagnosisInfos = new List<DiagnosisView>(),
  294. ShareUserCodes = terminalRecord.SharerIds?.ToList() ?? new List<string>(),
  295. CustomDoctor = terminalRecord.CustomDoctor,
  296. CustomOrganzation = terminalRecord.CustomOrganzation,
  297. EquipmentSN = terminalRecord.EquipmentSN,
  298. FileInfos = terminalDataInfos.Select(x =>
  299. {
  300. var fileInfo = x.Files.FirstOrDefault(f => f.ImageQuality == ImageQuality.High);
  301. var fileUrl = GetFileUrl(fileInfo?.FileName);
  302. var terminalData = new RemoteDiagnosisFileView
  303. {
  304. DataType = (WingInterfaceLibrary.Enum.RemedicalFileDataTypeEnum)x.DataType,
  305. OriginalUrl = fileUrl,
  306. CdnUrl = fileUrl,
  307. PreviewUrl = GetFileUrl(x.PreviewImageFileToken),
  308. ConverUrl = "",
  309. Application = x.Application,
  310. };
  311. if (x.ImageLocation != null)
  312. {
  313. if (x.ImageLocation is BreastImageLocation bi)
  314. {
  315. terminalData.ImageLocationInfo = new ImageLocationView
  316. {
  317. Group = "BreastImageLocation",
  318. Position = bi.Position.ToString(),
  319. Quadrant = bi.Quadrant.ToString(),
  320. };
  321. }
  322. if (x.ImageLocation is LiverImageLocation li)
  323. {
  324. terminalData.ImageLocationInfo = new ImageLocationView
  325. {
  326. Group = "LiverImageLocation",
  327. Position = li.Position.ToString(),
  328. };
  329. }
  330. if (x.ImageLocation is PositionImageLocation pi)
  331. {
  332. terminalData.ImageLocationInfo = new ImageLocationView
  333. {
  334. Group = pi.Position,
  335. Position = pi.Position.ToString(),
  336. };
  337. }
  338. }
  339. return terminalData;
  340. }).ToList(),
  341. CompletedUsers = terminalRecordStateInfos.Select(x => x.UserId).ToList(),
  342. };
  343. if (patientInfo != null)
  344. {
  345. remoteDiagnosisInfo.PatientInfo = new PatientView
  346. {
  347. IdentityCardId = patientInfo.IdentityCardId,
  348. Name = patientInfo.LastName,
  349. Gender = patientInfo.GenderType.ToString(),
  350. Age = patientInfo.Age,
  351. };
  352. }
  353. if (terminalRecord.TerminalRecordSource == TerminalRecordSource.Screenshot)
  354. {
  355. remoteDiagnosisInfo.ScreenshotInfo = new ScreenshotView
  356. {
  357. CreateUserCode = terminalRecord.CreatorUserId,
  358. CreateUserName = "",
  359. PrelDiagnosis = terminalRecord.PrelDiagnosis,
  360. ExamDoctor = terminalRecord.ExamDoctor,
  361. };
  362. }
  363. if (terminalRecord.AIDiagnosisInfos != null && terminalRecord.AIDiagnosisInfos.Any())
  364. {
  365. remoteDiagnosisInfo.DiagnosisInfos = terminalRecord.AIDiagnosisInfos.Select(x => new DiagnosisView
  366. {
  367. Organ = (WingInterfaceLibrary.Enum.DiagnosisOrganEnum)x.Organ,
  368. DiagnosisStatus = (WingInterfaceLibrary.Enum.DiagnosisConclusionEnum)x.Status,
  369. }).ToList();
  370. }
  371. remoteDiagnosisInfos.Add(remoteDiagnosisInfo);
  372. }
  373. var request = new ReceiveRemoteDiagnosisRequest
  374. {
  375. RemoteDiagnosisInfos = remoteDiagnosisInfos,
  376. };
  377. var result = _jsonRpcProxy.DataCenter.ReceiveRemoteDiagnosisAsync(request).Result;
  378. }
  379. catch (Exception ex)
  380. {
  381. Logger.WriteLineWarn($"SendRemoteDiagnosisInfos err, ex:{ex}");
  382. }
  383. }
  384. private void SendLiveConsultationInfos(IList<ConsultationRecords> consultationRecords, SyncDBEnum syncType)
  385. {
  386. try
  387. {
  388. var userIds = consultationRecords.Select(x => x.DoctorInfo?.ID ?? string.Empty)
  389. .Union(consultationRecords.Select(x => x.ExpertInfo?.ID ?? string.Empty))
  390. .Distinct().ToList();
  391. var users = _usersDBRepository.GetUserByCodes(userIds);
  392. var orgIds = consultationRecords.Select(x => x.PrimaryHosptial?.Id ?? string.Empty)
  393. .Union(consultationRecords.Select(x => x.CentralHospital?.Id ?? string.Empty))
  394. .Union(users.Select(x => x.HospitalId))
  395. .Distinct().ToList();
  396. var organizations = _organizationsDBRepository.GetOrganizationByCodes(orgIds);
  397. var terminalIds = consultationRecords.Select(x => x.TerminalInfo?.Id ?? string.Empty).Distinct().ToList();
  398. var terminals = _terminalsDBRepository.GetTerminalByCodes(terminalIds);
  399. var liveConsultationInfos = new List<LiveConsultationDTO>();
  400. foreach (var consultationRecord in consultationRecords)
  401. {
  402. var patient = consultationRecord.PatientInfo;
  403. var liveConsultationInfo = new LiveConsultationDTO
  404. {
  405. Code = consultationRecord.Id,
  406. CreateTime = consultationRecord.CreateTime,
  407. UpdateTime = consultationRecord.UpdateTime,
  408. ScanUserName = consultationRecord.ScanDoctor,
  409. ConsultationTime = consultationRecord.AppointmentTime,
  410. DoctorInfo = MapToUserView(organizations, users, consultationRecord.DoctorInfo?.ID),
  411. ExpertInfo = MapToUserView(organizations, users, consultationRecord.ExpertInfo?.ID),
  412. PrimaryHosptial = MapToOrganizationView(organizations, consultationRecord.PrimaryHosptial?.Id),
  413. CentralHospital = MapToOrganizationView(organizations, consultationRecord.CentralHospital?.Id),
  414. DeviceInfo = MapToDeviceView(terminals, consultationRecord.TerminalInfo?.Id),
  415. CheckPoint = consultationRecord.CheckPoint,
  416. ConsultationNumber = consultationRecord.ConsultationNumber,
  417. QueuingNumber = consultationRecord.QueuingNumber,
  418. IsNeedFollowUpVisit = consultationRecord.IsNeedFollowUpVisit,
  419. State = (WingInterfaceLibrary.Enum.ConsultationState)consultationRecord.State,
  420. QualityType = (WingInterfaceLibrary.Enum.QualityType)consultationRecord.QualityType,
  421. FollowUpVisitStatus = (FollowUpVisitStatusEnum)consultationRecord.FollowUpVisitStatus,
  422. EvaluateGrade = (EvaluateGradeEnum)consultationRecord.EvaluateGrade,
  423. FileInfos = new List<LiveConsultationFileView>(),
  424. ReportConclusionInfos = new List<ReportConclusionView>(),
  425. };
  426. if (patient != null)
  427. {
  428. liveConsultationInfo.PatientInfo = new PatientView
  429. {
  430. IdentityCardId = patient.ID,
  431. Name = patient.Name,
  432. Mobile = patient.ContactInfo,
  433. Gender = patient.GenderType.ToString(),
  434. Age = patient.Age,
  435. //PastHistory = patient.PastHistory,
  436. //Diagnosis = patient.Diagnosis,
  437. };
  438. }
  439. if (consultationRecord.ImageTokens != null && consultationRecord.ImageTokens.Any())
  440. {
  441. foreach (var item in consultationRecord.ImageTokens)
  442. {
  443. liveConsultationInfo.FileInfos.Add(new LiveConsultationFileView
  444. {
  445. Type = "FileTokens",
  446. DataType = RemedicalFileDataTypeEnum.VinnoVidSingle,
  447. OriginalUrl = GetFileUrl(item),
  448. CdnUrl = GetFileUrl(item),
  449. PreviewUrl = "",
  450. ConverUrl = "",
  451. });
  452. }
  453. }
  454. if (consultationRecord.VideoTokens != null && consultationRecord.VideoTokens.Any())
  455. {
  456. foreach (var item in consultationRecord.VideoTokens)
  457. {
  458. liveConsultationInfo.FileInfos.Add(new LiveConsultationFileView
  459. {
  460. Type = "FileTokens",
  461. DataType = RemedicalFileDataTypeEnum.VinnoVidMovie,
  462. OriginalUrl = GetFileUrl(item.VideoToken),
  463. CdnUrl = GetFileUrl(item.VideoToken),
  464. PreviewUrl = GetFileUrl(item.PreviewImageToken),
  465. ConverUrl = "",
  466. });
  467. }
  468. }
  469. if (consultationRecord.GraphicData != null && consultationRecord.GraphicData.Any())
  470. {
  471. foreach (var item in consultationRecord.GraphicData)
  472. {
  473. liveConsultationInfo.FileInfos.Add(new LiveConsultationFileView
  474. {
  475. Type = "GraphicData",
  476. DataType = item.GraphicType == 0 ? RemedicalFileDataTypeEnum.ThirdVidSingle : RemedicalFileDataTypeEnum.ThirdVidMovie,
  477. OriginalUrl = GetFileUrl(item.GraphicToken),
  478. CdnUrl = GetFileUrl(item.GraphicToken),
  479. PreviewUrl = GetFileUrl(item.PreviewGraphicToken),
  480. ConverUrl = "",
  481. UserCode = item.UserId,
  482. });
  483. }
  484. }
  485. if (consultationRecord.PreFileItems != null && consultationRecord.PreFileItems.Any())
  486. {
  487. foreach (var item in consultationRecord.PreFileItems)
  488. {
  489. liveConsultationInfo.FileInfos.Add(new LiveConsultationFileView
  490. {
  491. Type = "PreFileItems",
  492. DataType = item.FileType == 0 ? RemedicalFileDataTypeEnum.ThirdVidSingle : RemedicalFileDataTypeEnum.ThirdVidMovie,
  493. OriginalUrl = GetFileUrl(item.OriginalFileUrl),
  494. CdnUrl = GetFileUrl(item.OriginalFileUrl),
  495. PreviewUrl = GetFileUrl(item.ThumbnailUrl),
  496. ConverUrl = "",
  497. UserCode = item.Uploader,
  498. FileName = item.FileName,
  499. });
  500. }
  501. }
  502. if (consultationRecord.ReportConclusionInfos != null && consultationRecord.ReportConclusionInfos.Any())
  503. {
  504. foreach (var item in consultationRecord.ReportConclusionInfos)
  505. {
  506. liveConsultationInfo.ReportConclusionInfos.Add(new ReportConclusionView
  507. {
  508. ReportId = item.ReportId,
  509. DiseaseName = item.DiseaseName,
  510. DiseaseConclusion = (WingInterfaceLibrary.Enum.DiseaseConclusion)item.DiseaseConclusion,
  511. });
  512. }
  513. }
  514. liveConsultationInfos.Add(liveConsultationInfo);
  515. }
  516. var request = new ReceiveLiveConsultationRequest
  517. {
  518. LiveConsultationInfos = liveConsultationInfos,
  519. };
  520. var result = _jsonRpcProxy.DataCenter.ReceiveLiveConsultationAsync(request).Result;
  521. }
  522. catch (Exception ex)
  523. {
  524. Logger.WriteLineWarn($"SendLiveConsultationInfos err, ex:{ex}");
  525. }
  526. }
  527. private void SendVideoInfos(IList<Video> videos, SyncDBEnum syncType)
  528. {
  529. try
  530. {
  531. var userIds = videos.Select(x => x.CreatorId)
  532. .Union(videos.SelectMany(x => x.UserIds ?? new List<string>()))
  533. .Union(videos.SelectMany(x => x.FinishedUserIds ?? new List<string>()))
  534. .Distinct().ToList();
  535. var users = _usersDBRepository.GetUserByCodes(userIds);
  536. var orgIds = users.Select(x => x.HospitalId).Distinct().ToList();
  537. var organizations = _organizationsDBRepository.GetOrganizationByCodes(orgIds);
  538. var userGroupIds = videos.SelectMany(x => x.UserGroupIds ?? new List<string>()).Distinct().ToList();
  539. var userGroups = _userGroupDBRepository.GetUserGroupByCodes(userGroupIds);
  540. var classIds = videos.SelectMany(x => x.ClassIds ?? new List<string>()).Distinct().ToList();
  541. var classes = _ultrasonicClassDBRepository.GetUltrasonicClassByCodes(classIds);
  542. //var courseIds = videos.SelectMany(x => x.Courses ?? new List<VideoLinkCourseInfo>()).Select(x => x.Id).Distinct().ToList();
  543. //var courses = _coursesDBRepository.GetCourseByCodes(courseIds);
  544. var onlineVideoInfos = new List<OnlineVideoDTO>();
  545. foreach (var video in videos)
  546. {
  547. var creator = MapToUserView(organizations, users, video.CreatorId);
  548. var videoInfo = new OnlineVideoDTO
  549. {
  550. Code = video.Id,
  551. CreateTime = video.CreateTime,
  552. UpdateTime = video.UpdateTime,
  553. Name = video.Title,
  554. Poster = GetFileUrl(video.PosterToken),
  555. Duration = video.Duration,
  556. VideoSize = video.Size,
  557. Description = video.Description,
  558. VideoToken = video.Url,
  559. Importance = (VideoImportanceEnum)video.Importance,
  560. CreatorCode = video.CreatorId,
  561. CreatorName = creator?.Name,
  562. Permissions = (VideoPermissionsEnum)video.Permissions,
  563. Users = new List<UserView>(),
  564. UserGroups = new List<GroupView>(),
  565. Courses = new List<OnlineTrainingDTO>(),
  566. ClassInfos = new List<ClassView>(),
  567. Labels = new List<VideoLabelEnum>(),
  568. TeachingDocumentName = video.TeachingDocumentName,
  569. TeachingDocument = GetFileUrl(video.TeachingDocument),
  570. RealBrowsedCount = video.RealBrowsedCount,
  571. BaseBrowsedCount = video.BaseBrowsedCount,
  572. FinishedUsers = new List<UserView>(),
  573. };
  574. if (video.UserIds != null && video.UserIds.Any())
  575. {
  576. foreach (var item in video.UserIds)
  577. {
  578. var user = MapToUserView(organizations, users, item);
  579. if (user != null)
  580. {
  581. videoInfo.Users.Add(user);
  582. }
  583. }
  584. }
  585. if (video.FinishedUserIds != null && video.FinishedUserIds.Any())
  586. {
  587. foreach (var item in video.FinishedUserIds)
  588. {
  589. var user = MapToUserView(organizations, users, item);
  590. if (user != null)
  591. {
  592. videoInfo.FinishedUsers.Add(user);
  593. }
  594. }
  595. }
  596. if (video.Labels != null && video.Labels.Any())
  597. {
  598. foreach (var item in video.Labels)
  599. {
  600. videoInfo.Labels.Add((VideoLabelEnum)item);
  601. }
  602. }
  603. if (video.Courses != null && video.Courses.Any())
  604. {
  605. foreach (var item in video.Courses)
  606. {
  607. videoInfo.Courses.Add(new OnlineTrainingDTO
  608. {
  609. Code = item.Id,
  610. Name = item.Name,
  611. });
  612. }
  613. }
  614. if (video.UserGroupIds != null && video.UserGroupIds.Any())
  615. {
  616. foreach (var item in video.UserGroupIds)
  617. {
  618. var userGroup = MapToUserGroupView(userGroups, item);
  619. if (userGroup != null)
  620. {
  621. videoInfo.UserGroups.Add(userGroup);
  622. }
  623. }
  624. }
  625. if (video.ClassIds != null && video.ClassIds.Any())
  626. {
  627. foreach (var item in video.ClassIds)
  628. {
  629. var classInfo = MapToClassView(classes, item);
  630. if (classInfo != null)
  631. {
  632. videoInfo.ClassInfos.Add(classInfo);
  633. }
  634. }
  635. }
  636. onlineVideoInfos.Add(videoInfo);
  637. }
  638. var request = new ReceiveOnlineVideoRequest
  639. {
  640. OnlineVideoInfos = onlineVideoInfos,
  641. };
  642. var result = _jsonRpcProxy.DataCenter.ReceiveOnlineVideoAsync(request).Result;
  643. }
  644. catch (Exception ex)
  645. {
  646. Logger.WriteLineWarn($"SendVideoInfos err, ex:{ex}");
  647. }
  648. }
  649. private void SendCourseInfos(IList<Courses> courses, SyncDBEnum syncType)
  650. {
  651. try
  652. {
  653. var userIds = courses.SelectMany(x => x.AssistantIds ?? new List<string>())
  654. .Union(courses.SelectMany(x => x.GuestIds ?? new List<string>()))
  655. .Union(courses.SelectMany(x => x.MeetingMemberIds ?? new List<string>()))
  656. .Distinct().ToList();
  657. var users = _usersDBRepository.GetUserByCodes(userIds);
  658. var orgIds = users.Select(x => x.HospitalId).Distinct().ToList();
  659. var organizations = _organizationsDBRepository.GetOrganizationByCodes(orgIds);
  660. var onlineTrainingInfos = new List<OnlineTrainingDTO>();
  661. foreach (var course in courses)
  662. {
  663. var teacher = course.Teacher;
  664. var createAdmin = course.CreateAdmin;
  665. var courseInfo = new OnlineTrainingDTO
  666. {
  667. Code = course.Id,
  668. CreateTime = course.CreateTime,
  669. UpdateTime = course.UpdateTime,
  670. Name = course.Name,
  671. CourseIntro = course.Information,
  672. Price = (decimal)course.Price,
  673. Status = (CourseStatusEnum)course.State,//TODO
  674. StartTime = course.StarTime,
  675. Duration = course.Duration,
  676. Deadline = course.Deadline,
  677. ApplyState = (ApplyStateEnum)course.ApplyState,//TODO
  678. Poster = GetFileUrl(course.Poster),
  679. Students = new List<SignStudentView>(),
  680. ConversationId = course.ConversationId,//TODO
  681. ChannelDatas = new List<ChannelDataView>(),
  682. Owners = new List<AdminView>(),
  683. TeacherOnlineState = course.TeacherState == TeacherState.OnLine,
  684. StartCourseInAdvance = course.StartCourseInAdvance,
  685. ActualStartTime = course.ActualStartTime ?? DateTime.MinValue,
  686. ActualEndTime = course.ActualEndTime ?? DateTime.MinValue,
  687. AssistantInfos = new List<UserView>(),
  688. GuestInfos = new List<UserView>(),
  689. CredentialCode = course.CredentialCode,
  690. CourseNotice = course.CourseNotice,
  691. MeetingMemberInfos = new List<UserView>(),
  692. };
  693. if (teacher != null)
  694. {
  695. var name = !string.IsNullOrWhiteSpace(teacher.FullName) ? teacher.FullName
  696. : !string.IsNullOrWhiteSpace(teacher.LastName) ? teacher.LastName
  697. : !string.IsNullOrWhiteSpace(teacher.FirstName) ? teacher.FirstName
  698. : !string.IsNullOrWhiteSpace(teacher.NickName) ? teacher.NickName
  699. : teacher.Name;
  700. courseInfo.TeacherCode = teacher.Id;
  701. courseInfo.TeacherName = name;
  702. }
  703. if (course.ChannelDatas != null && course.ChannelDatas.Any())
  704. {
  705. foreach (var item in course.ChannelDatas)
  706. {
  707. courseInfo.ChannelDatas.Add(new ChannelDataView
  708. {
  709. ChannelId = item.ChannelId,
  710. DownLoadUrl = item.DownLoadUrl,
  711. UpLoadUrl = item.UpLoadUrl,
  712. Description = (ChannelDescriptionEnum)item.Description,
  713. HttpUrl = item.HttpUrl,
  714. HlsUrl = item.HlsUrl,
  715. });
  716. }
  717. }
  718. if (course.Students != null && course.Students.Any())
  719. {
  720. foreach (var item in course.Students)
  721. {
  722. courseInfo.Students.Add(new SignStudentView
  723. {
  724. StudentCode = item.Id,
  725. StudentName = item.Name,
  726. SmallHeadImage = item.SmallHeadImage,
  727. IsNoSpeaking = item.IsNoSpeaking,
  728. IsAssistant = item.IsAssistant,
  729. });
  730. }
  731. }
  732. if (createAdmin != null)
  733. {
  734. courseInfo.CreateAdmin = new AdminView
  735. {
  736. Code = createAdmin._id,
  737. Name = createAdmin.Name,
  738. };
  739. }
  740. if (course.Owners != null && course.Owners.Any())
  741. {
  742. foreach (var item in course.Owners)
  743. {
  744. courseInfo.Owners.Add(new AdminView
  745. {
  746. Code = item._id,
  747. Name = item.Name,
  748. });
  749. }
  750. }
  751. if (course.AssistantIds != null && course.AssistantIds.Any())
  752. {
  753. foreach (var item in course.AssistantIds)
  754. {
  755. var user = MapToUserView(organizations, users, item);
  756. if (user != null)
  757. {
  758. courseInfo.AssistantInfos.Add(user);
  759. }
  760. }
  761. }
  762. if (course.GuestIds != null && course.GuestIds.Any())
  763. {
  764. foreach (var item in course.GuestIds)
  765. {
  766. var user = MapToUserView(organizations, users, item);
  767. if (user != null)
  768. {
  769. courseInfo.GuestInfos.Add(user);
  770. }
  771. }
  772. }
  773. if (course.MeetingMemberIds != null && course.MeetingMemberIds.Any())
  774. {
  775. foreach (var item in course.MeetingMemberIds)
  776. {
  777. var user = MapToUserView(organizations, users, item);
  778. if (user != null)
  779. {
  780. courseInfo.MeetingMemberInfos.Add(user);
  781. }
  782. }
  783. }
  784. onlineTrainingInfos.Add(courseInfo);
  785. }
  786. var request = new ReceiveOnlineTrainingRequest
  787. {
  788. OnlineTrainingInfos = onlineTrainingInfos,
  789. };
  790. var result = _jsonRpcProxy.DataCenter.ReceiveOnlineTrainingAsync(request).Result;
  791. }
  792. catch (Exception ex)
  793. {
  794. Logger.WriteLineWarn($"SendCourseInfos err, ex:{ex}");
  795. }
  796. }
  797. private void SendExaminationPaperInfos(IList<ExaminationPaper> examPapers, SyncDBEnum syncType)
  798. {
  799. try
  800. {
  801. var userIds = examPapers.Select(x => x.CreatorId)
  802. .Union(examPapers.SelectMany(x => x.ExaminerIds ?? new List<string>()))
  803. .Distinct().ToList();
  804. var users = _usersDBRepository.GetUserByCodes(userIds);
  805. var admins = _adminDBRepository.GetAdminByCodes(userIds);
  806. var orgIds = users.Select(x => x.HospitalId).Distinct().ToList();
  807. var organizations = _organizationsDBRepository.GetOrganizationByCodes(orgIds);
  808. var userGroupIds = examPapers.SelectMany(x => x.ExaminerUserGroupIds ?? new List<string>()).Distinct().ToList();
  809. var userGroups = _userGroupDBRepository.GetUserGroupByCodes(userGroupIds);
  810. var classIds = examPapers.SelectMany(x => x.ClassIds ?? new List<string>()).Distinct().ToList();
  811. var classes = _ultrasonicClassDBRepository.GetUltrasonicClassByCodes(classIds);
  812. var examIds = examPapers.Select(x => x.Id).ToList();
  813. var examScores = _examScoreDBRepository.GetExamScoresByCodes(examIds);
  814. var examPaperInfos = new List<ExamPaperDTO>();
  815. foreach (var examPaper in examPapers)
  816. {
  817. var creatorName = MapToUserView(organizations, users, examPaper.CreatorId)?.Name;
  818. if (string.IsNullOrWhiteSpace(creatorName))
  819. {
  820. var admin = admins.FirstOrDefault(x => x._id == examPaper.CreatorId);
  821. if (admin != null)
  822. {
  823. var adminName = !string.IsNullOrWhiteSpace(admin.FullName) ? admin.FullName
  824. : !string.IsNullOrWhiteSpace(admin.LastName) ? admin.LastName
  825. : !string.IsNullOrWhiteSpace(admin.FirstName) ? admin.FirstName
  826. : admin.Name;
  827. creatorName = adminName;
  828. }
  829. }
  830. var examPaperInfo = new ExamPaperDTO
  831. {
  832. Code = examPaper.Id,
  833. CreateTime = examPaper.CreateTime,
  834. UpdateTime = examPaper.UpdateTime,
  835. Name = examPaper.Title,
  836. Description = examPaper.Description,
  837. StarTime = examPaper.StarTime,
  838. EndTime = examPaper.EndTime,
  839. TotalScore = examPaper.TotalScore,
  840. LimitCount = examPaper.LimitCount,
  841. Result = examPaper.Result,
  842. Examiners = new List<UserView>(),
  843. ExaminerUserGroups = new List<GroupView>(),
  844. ExaminationAvailability = (ExaminationAvailabilityEnum)examPaper.ExaminationAvailability,
  845. Classes = new List<ClassView>(),
  846. CreatorId = examPaper.CreatorId,
  847. CreatorName = creatorName,
  848. ExamType = (ExamTypeEnum)examPaper.ExamType,
  849. HasPassScore = examPaper.HasPassScore,
  850. PassScore = examPaper.PassScore,
  851. IsDisplayAnswer = examPaper.IsDisplayAnswer,
  852. ExamVideoInfos = new List<ExamVideoView>(),
  853. ExamScoreInfos = new List<ExamScoreView>(),
  854. };
  855. if (examPaper.ExaminerIds != null && examPaper.ExaminerIds.Any())
  856. {
  857. foreach (var item in examPaper.ExaminerIds)
  858. {
  859. var user = MapToUserView(organizations, users, item);
  860. if (user != null)
  861. {
  862. examPaperInfo.Examiners.Add(user);
  863. }
  864. }
  865. }
  866. if (examPaper.ExaminerUserGroupIds != null && examPaper.ExaminerUserGroupIds.Any())
  867. {
  868. foreach (var item in examPaper.ExaminerUserGroupIds)
  869. {
  870. var userGroup = MapToUserGroupView(userGroups, item);
  871. if (userGroup != null)
  872. {
  873. examPaperInfo.ExaminerUserGroups.Add(userGroup);
  874. }
  875. }
  876. }
  877. if (examPaper.ClassIds != null && examPaper.ClassIds.Any())
  878. {
  879. foreach (var item in examPaper.ClassIds)
  880. {
  881. var classInfo = MapToClassView(classes, item);
  882. if (classInfo != null)
  883. {
  884. examPaperInfo.Classes.Add(classInfo);
  885. }
  886. }
  887. }
  888. if (examPaper.ExamVideoInfos != null && examPaper.ExamVideoInfos.Any())
  889. {
  890. foreach (var item in examPaper.ExamVideoInfos)
  891. {
  892. examPaperInfo.ExamVideoInfos.Add(new ExamVideoView
  893. {
  894. Id = item.Id,
  895. VideoName = item.VideoName,
  896. CreateTime = item.CreateTime,
  897. PosterToken = GetFileUrl(item.PosterToken),
  898. Duration = item.Duration,
  899. Size = item.Size,
  900. Description = item.Description,
  901. Url = GetFileUrl(item.Url),
  902. });
  903. }
  904. }
  905. if (examPaper.ExamTemplate != null)
  906. {
  907. var examTemplate = examPaper.ExamTemplate.MappingTo<ExamTemplateView>();
  908. if (examTemplate != null && examTemplate.Subjects != null && examTemplate.Subjects.Any())
  909. {
  910. foreach (var item in examTemplate.Subjects)
  911. {
  912. item.Images = item.Images?.Select(x => GetFileUrl(x))?.ToList() ?? new List<string>();
  913. if (item.Videos != null && item.Videos.Any())
  914. {
  915. item.Videos?.ForEach(x =>
  916. {
  917. x.VideoImageToken = GetFileUrl(x.VideoImageToken);
  918. x.VideoToken = GetFileUrl(x.VideoToken);
  919. });
  920. }
  921. }
  922. }
  923. examPaperInfo.ExamTemplate = examTemplate;
  924. }
  925. var examScoreInfos = examScores.Where(x => x.ExamId == examPaper.Id)?.ToList() ?? new List<ExamScores>();
  926. if (examScoreInfos.Any())
  927. {
  928. examPaperInfo.ExamScoreInfos = examScoreInfos.MappingTo<List<ExamScoreView>>();
  929. }
  930. examPaperInfos.Add(examPaperInfo);
  931. }
  932. var request = new ReceiveExamPaperInfosRequest
  933. {
  934. ExamPaperInfos = examPaperInfos,
  935. };
  936. var result = _jsonRpcProxy.DataCenter.ReceiveExamPaperAsync(request).Result;
  937. }
  938. catch (Exception ex)
  939. {
  940. Logger.WriteLineWarn($"SendCourseInfos err, ex:{ex}");
  941. }
  942. }
  943. private void SendReportInfos(IList<ReportInfoResults> reports, SyncDBEnum syncType)
  944. {
  945. try
  946. {
  947. var customLabelIds = reports.SelectMany(x => x.CustomLabels ?? new List<string>()).Distinct().ToList();
  948. var customerLabels = _customLabelDBRepository.GetCustomLabelByCodes(customLabelIds);
  949. var reportInfos = new List<ReportInfoResultDTO>();
  950. foreach (var report in reports)
  951. {
  952. var reportInfo = new ReportInfoResultDTO
  953. {
  954. Code = report.Id,
  955. CreateTime = report.CreateTime,
  956. UpdateTime = report.UpdateTime,
  957. ReportTemplateJson = report.Template,
  958. ElementCollectionJson = Newtonsoft.Json.JsonConvert.SerializeObject(report.ElementCollection),
  959. MeasureElementCollectionJson = Newtonsoft.Json.JsonConvert.SerializeObject(report.MeasureElementCollection),
  960. ReportUserCode = report.User?._id,
  961. ReportUserName = report.User?.Name,
  962. RecordCode = report.RecordId,
  963. PatientPerfPhysician = report.PatientPerfPhysician,
  964. PatientRefPhysician = report.PatientRefPhysician,
  965. PatientName = report.PatientName,
  966. PreviewImages = report.PreviewImages.MappingTo<List<WingInterfaceLibrary.DTO.DataCenter.ReportImageInfo>>(),
  967. CustomLabels = new List<CustomLabelView>(),
  968. ReportOrgan = (DiagnosisOrganEnum)report.Organ,
  969. QualifiedState = (WingInterfaceLibrary.Enum.QualifiedState)report.QualifiedState,
  970. QualityType = (WingInterfaceLibrary.Enum.QualityType)report.QualityType,
  971. ReportPreviewPdf = GetFileUrl(report.ReportPreviewPdf),
  972. QualityControlDatas = new List<QualityControlDataView>(),
  973. };
  974. if (report.CustomLabels != null && report.CustomLabels.Any())
  975. {
  976. foreach (var item in report.CustomLabels)
  977. {
  978. var customLabel = customerLabels.FirstOrDefault(x => x.Code == item);
  979. if (customLabel != null)
  980. {
  981. reportInfo.CustomLabels.Add(customLabel.MappingTo<CustomLabelView>());
  982. }
  983. }
  984. }
  985. if (report.QualityControlDatas != null && report.QualityControlDatas.Any())
  986. {
  987. reportInfo.QualityControlDatas = report.QualityControlDatas.MappingTo<List<QualityControlDataView>>();
  988. }
  989. reportInfos.Add(reportInfo);
  990. }
  991. var request = new ReceiveReportInfosRequest
  992. {
  993. ReportInfos = reportInfos,
  994. };
  995. var result = _jsonRpcProxy.DataCenter.ReceiveReportAsync(request).Result;
  996. }
  997. catch (Exception ex)
  998. {
  999. Logger.WriteLineWarn($"SendReportInfos err, ex:{ex}");
  1000. }
  1001. }
  1002. private void SendTerminalAIDataInfos(IList<TerminalAIDatas> terminalAIDatas, SyncDBEnum syncType)
  1003. {
  1004. try
  1005. {
  1006. var fileDiagnosisInfos = new List<FileDiagnosisResultDTO>();
  1007. foreach (var terminalAIData in terminalAIDatas)
  1008. {
  1009. var fileDiagnosisResult = new FileDiagnosisResultDTO
  1010. {
  1011. Code = terminalAIData.Id,
  1012. CreateTime = terminalAIData.CreateTime,
  1013. UpdateTime = terminalAIData.UpdateTime,
  1014. RemedicalCode = terminalAIData.TerminalDataId,
  1015. };
  1016. var diagnosisDatas = new List<AIDiagnosisPerImg>();
  1017. foreach (var item in terminalAIData.DiagResults)
  1018. {
  1019. diagnosisDatas.Add(new AIDiagnosisPerImg
  1020. {
  1021. Index = item.Index,
  1022. PriorityScore = item.ImageDiagResult.PriorityScore,
  1023. DiagResultsForEachOrgan = item.ImageDiagResult.DiagResultsForEachOrgan,
  1024. });
  1025. }
  1026. fileDiagnosisResult.DiagnosisOrgans = GetDiagnosisOrgans(diagnosisDatas);
  1027. fileDiagnosisResult.DiagnosisConclusion = GetDiagnosisConclusion(diagnosisDatas);
  1028. fileDiagnosisResult.DiagnosisResult = Newtonsoft.Json.JsonConvert.SerializeObject(diagnosisDatas);
  1029. fileDiagnosisInfos.Add(fileDiagnosisResult);
  1030. }
  1031. var request = new ReceiveFileDiagnosisResultInfosRequest
  1032. {
  1033. FileDiagnosisResultInfos = fileDiagnosisInfos,
  1034. };
  1035. var result = _jsonRpcProxy.DataCenter.ReceiveFileDiagnosisResultAsync(request).Result;
  1036. }
  1037. catch (Exception ex)
  1038. {
  1039. Logger.WriteLineWarn($"SendTerminalAIDataInfos err, ex:{ex}");
  1040. }
  1041. }
  1042. /// <summary>
  1043. /// 同步热数据到2.0
  1044. /// </summary>
  1045. /// <returns></returns>
  1046. public async Task MigrateRemedicalAndConsultationToWingServerAsync()
  1047. {
  1048. Logger.WriteLineInfo($"Remote diagnosis infos migrate to wingServer starting");
  1049. //远程
  1050. MigrateRemedicalRecords(SyncDBEnum.Synchronize);
  1051. //远程图像
  1052. MigrateRemedicalDatas(SyncDBEnum.Synchronize);
  1053. //AI
  1054. MigrateRemedicalAIDatas(SyncDBEnum.Synchronize);
  1055. //颈动脉
  1056. MigrateRemedicalCarotidDatas(SyncDBEnum.Synchronize);
  1057. //会诊
  1058. MigrateConsultationResults(SyncDBEnum.Synchronize);
  1059. //报告
  1060. MigrateReportInfoResults(SyncDBEnum.Synchronize);
  1061. Logger.WriteLineInfo($"Remote diagnosis infos migrate to wingServer successfully");
  1062. }
  1063. public async Task MigrateRemedicalRecords(SyncDBEnum syncType)
  1064. {
  1065. Logger.WriteLineInfo($"Remote diagnosis records migrate to wingServer starting");
  1066. //获取上次同步到的时间
  1067. var builder = Builders<TerminalRecords>.Filter;
  1068. var startTime = GetFactBeginTime(_migrateRecord.StartTime, _migrateRecord.EndTime);
  1069. var filter = builder.Where(x => x.IsDelete == false && ((x.CreateTime > startTime && x.CreateTime <= _migrateRecord.EndTime) || (x.UpdateTime > startTime && x.UpdateTime <= _migrateRecord.EndTime)));
  1070. var terminalRecords = _terminalRecordDBRepository.GetTerminalRecords(filter).OrderByDescending(x=>x.CreateTime).ToList();
  1071. OnMigrate("Remote diagnosis records", terminalRecords, SendRemedicalRecordInfos, syncType,1000);
  1072. terminalRecords.Clear();
  1073. Logger.WriteLineInfo($"Remote diagnosis records migrate to wingServer successfully");
  1074. }
  1075. private void SendRemedicalRecordInfos(IList<TerminalRecords> terminalRecords, SyncDBEnum syncType)
  1076. {
  1077. try
  1078. {
  1079. var terminalRecordCodes = terminalRecords.Select(x => x.Id).ToList();
  1080. var terminalRecordStates = _terminalRecordReportStatesDBRepository.GetTerminalRecordReportStatesByCodes(terminalRecordCodes)?.ToList() ?? new List<TerminalRecordReportStates>();
  1081. var syncBatchRemedicalRecordRequest = new SyncBatchRemedicalRecordRequest();
  1082. syncBatchRemedicalRecordRequest.SyncType = syncType;
  1083. syncBatchRemedicalRecordRequest.RemedicalRecordList = new List<SyncRemedicalRecordRequest>();
  1084. foreach (var terminalRecord in terminalRecords)
  1085. {
  1086. try
  1087. {
  1088. var terminalRecordId = terminalRecord.Id;
  1089. var terminalRecordStateInfos = terminalRecordStates.Where(x => x.TerminalRecordId == terminalRecordId)?.ToList() ?? new List<TerminalRecordReportStates>();
  1090. var patientInfo = terminalRecord.PatientInfo;
  1091. var remoteDiagnosisInfo = new SyncRemedicalRecordRequest
  1092. {
  1093. Code = terminalRecordId,
  1094. OrganizationCode = terminalRecord.Organization?.Id,
  1095. DeviceCode = terminalRecord.Terminal?.Id,
  1096. CreateTime = terminalRecord.CreateTime,
  1097. Creator = terminalRecord.CreatorUserId,
  1098. UpdateTime = terminalRecord.UpdateTime < new DateTime(2000, 1, 1) ? terminalRecord.CreateTime : terminalRecord.UpdateTime,
  1099. IsUploadReport = terminalRecordStateInfos.Count > 0,
  1100. PatientInfo = new List<DataItemDTO>
  1101. {
  1102. new DataItemDTO{Key="Name",Value=$"{patientInfo.LastName} {patientInfo.FirstName}".Trim()},
  1103. new DataItemDTO{Key="Phone",Value=patientInfo.Mobile},
  1104. new DataItemDTO{Key="ID",Value=patientInfo.IdentityCardId},//设备病人ID
  1105. new DataItemDTO{Key="Sex",Value = patientInfo.GenderType.ToString()=="Unassigned"?"NotFilled":patientInfo.GenderType.ToString()}
  1106. }
  1107. };
  1108. if (patientInfo.Birthday != null && patientInfo.Birthday > new DateTime(1900, 1, 1))
  1109. {
  1110. remoteDiagnosisInfo.PatientInfo.Add(new DataItemDTO { Key = "Birthday", Value = ((DateTime)patientInfo.Birthday).ToString("yyyy-MM-dd") });
  1111. }
  1112. if (terminalRecord.AIDiagnosisInfos != null && terminalRecord.AIDiagnosisInfos.Any())
  1113. {
  1114. remoteDiagnosisInfo.AIDiagnosisInfos = terminalRecord.AIDiagnosisInfos.Select(x => new DiagnosisInfoDTO
  1115. {
  1116. DiagnosisOrgan = (WingInterfaceLibrary.Enum.DiagnosisOrganEnum)x.Organ,
  1117. Conclusion = (WingInterfaceLibrary.Enum.DiagnosisConclusionEnum)x.Status,
  1118. }).ToList();
  1119. remoteDiagnosisInfo.DiagnosisStatus = DiagnosisStatusEnum.Completed;
  1120. }
  1121. syncBatchRemedicalRecordRequest.RemedicalRecordList.Add(remoteDiagnosisInfo);
  1122. }
  1123. catch (Exception ex)
  1124. {
  1125. Logger.WriteLineWarn($"SendRemedicalRecordInfos err, ex:{ex}");
  1126. }
  1127. }
  1128. var result = _jsonRpcProxy.RemedicalService.SyncBatchRemedicalRecordsAsync(syncBatchRemedicalRecordRequest).Result;
  1129. }
  1130. catch (Exception ex)
  1131. {
  1132. Logger.WriteLineWarn($"SendRemedicalRecordInfos err, ex:{ex}");
  1133. }
  1134. }
  1135. public async Task MigrateRemedicalDatas(SyncDBEnum syncType)
  1136. {
  1137. Logger.WriteLineInfo($"Remote diagnosis datas migrate to wingServer starting");
  1138. //获取上次同步到的时间
  1139. var builder = Builders<TerminalDatas>.Filter;
  1140. var startTime = GetFactBeginTime(_migrateRecord.StartTime, _migrateRecord.EndTime);
  1141. var filter = builder.Where(x => (x.CreateTime > startTime && x.CreateTime <= _migrateRecord.EndTime) || (x.UpdateTime > startTime && x.UpdateTime <= _migrateRecord.EndTime));
  1142. var terminalDatas = _terminalDatasDBRepository.GetTerminalDatas(filter).OrderByDescending(x => x.CreateTime).ToList();
  1143. OnMigrate("Remote diagnosis datas", terminalDatas, SendRemedicalDatas, syncType,1000);
  1144. terminalDatas.Clear();
  1145. Logger.WriteLineInfo($"Remote diagnosis datas migrate to wingServer successfully");
  1146. }
  1147. private void SendRemedicalDatas(IList<TerminalDatas> terminalDatas, SyncDBEnum syncType)
  1148. {
  1149. try
  1150. {
  1151. var builder = Builders<TerminalRecords>.Filter;
  1152. var recordCodes = terminalDatas.Select(x => x.TerminalRecordId);
  1153. var filter = builder.Where(x => x.IsDelete == false && recordCodes.Contains(x.Id));
  1154. var records = _terminalRecordDBRepository.GetTerminalRecords(filter);
  1155. var syncBatchRemedicalRecordRequest = new SyncBatchUploadRemedicalDatasRequest();
  1156. syncBatchRemedicalRecordRequest.SyncType = syncType;
  1157. syncBatchRemedicalRecordRequest.SyncUploadRemedicalDataList = new List<SyncUploadRemedicalDataRequest>();
  1158. foreach (var terminalData in terminalDatas)
  1159. {
  1160. try
  1161. {
  1162. var record = records.FirstOrDefault(x => x.Id == terminalData.TerminalRecordId);
  1163. var fileInfo = terminalData.Files.FirstOrDefault(f => f.ImageQuality == ImageQuality.High);
  1164. var fileUrl = GetFileUrl(fileInfo?.FileName);
  1165. var imageLocation = new ImageLocationDTO();
  1166. if (terminalData.ImageLocation != null)
  1167. {
  1168. if (terminalData.ImageLocation is BreastImageLocation bi)
  1169. {
  1170. imageLocation = new ImageLocationDTO
  1171. {
  1172. Group = "BreastImageLocation",
  1173. Position = bi.Position.ToString(),
  1174. Quadrant = bi.Quadrant.ToString(),
  1175. };
  1176. }
  1177. if (terminalData.ImageLocation is LiverImageLocation li)
  1178. {
  1179. imageLocation = new ImageLocationDTO
  1180. {
  1181. Group = "LiverImageLocation",
  1182. Position = li.Position.ToString(),
  1183. };
  1184. }
  1185. if (terminalData.ImageLocation is PositionImageLocation pi)
  1186. {
  1187. imageLocation = new ImageLocationDTO
  1188. {
  1189. Group = pi.Position,
  1190. Position = pi.Position.ToString(),
  1191. };
  1192. }
  1193. }
  1194. var syncUploadRemedicalDataRequest = new SyncUploadRemedicalDataRequest
  1195. {
  1196. Code = terminalData.Id,
  1197. CreateTime = terminalData.CreateTime,
  1198. UpdateTime = terminalData.UpdateTime < new DateTime(2000, 1, 1) ? terminalData.CreateTime : terminalData.UpdateTime,
  1199. ExamCode = terminalData.TerminalRecordId,
  1200. FileDataType = (WingInterfaceLibrary.Enum.RemedicalFileDataTypeEnum)terminalData.DataType,
  1201. FileToken = fileUrl,
  1202. PreviewFileToken = GetFileUrl(terminalData.PreviewImageFileToken),
  1203. Application = terminalData.Application,
  1204. ImageLocation = imageLocation,
  1205. DeviceCode = record?.Terminal?.Id
  1206. };
  1207. syncBatchRemedicalRecordRequest.SyncUploadRemedicalDataList.Add(syncUploadRemedicalDataRequest);
  1208. }
  1209. catch (Exception ex)
  1210. {
  1211. Logger.WriteLineWarn($"SendRemedicalDatas err, ex:{ex}");
  1212. }
  1213. }
  1214. var result = _jsonRpcProxy.RemedicalService.SyncBatchUploadRemedicalDatasAsync(syncBatchRemedicalRecordRequest).Result;
  1215. }
  1216. catch (Exception ex)
  1217. {
  1218. Logger.WriteLineWarn($"SendRemedicalDatas err, ex:{ex}");
  1219. }
  1220. }
  1221. public async Task MigrateRemedicalAIDatas(SyncDBEnum syncType)
  1222. {
  1223. Logger.WriteLineInfo($"Remote diagnosis ai datas migrate to wingServer starting");
  1224. //获取上次同步到的时间
  1225. //判断热数据
  1226. var builder = Builders<TerminalAIDatas>.Filter;
  1227. var startTime = GetFactBeginTime(_migrateRecord.StartTime, _migrateRecord.EndTime);
  1228. var filter = builder.Where(x => (x.CreateTime > startTime && x.CreateTime <= _migrateRecord.EndTime) || (x.UpdateTime > startTime && x.UpdateTime <= _migrateRecord.EndTime));
  1229. var terminalDatas = _terminalAIDatasDBRepository.GetTerminalAIDatas(filter).OrderByDescending(x => x.CreateTime).ToList();
  1230. OnMigrate("Remote diagnosis ai datas", terminalDatas, SendRemedicalAIDatas, syncType, 10);
  1231. terminalDatas.Clear();
  1232. Logger.WriteLineInfo($"Remote diagnosis datas migrate to wingServer successfully");
  1233. }
  1234. private void SendRemedicalAIDatas(IList<TerminalAIDatas> terminalAIDatas, SyncDBEnum syncType)
  1235. {
  1236. try
  1237. {
  1238. var syncBatchAIResultRequest = new SyncBatchAIResultRequest();
  1239. syncBatchAIResultRequest.SyncType = syncType;
  1240. syncBatchAIResultRequest.SyncAIResultList = new List<SyncAIResultRequest>();
  1241. foreach (var terminalAIData in terminalAIDatas)
  1242. {
  1243. try
  1244. {
  1245. var syncAIResultRequest = new SyncAIResultRequest
  1246. {
  1247. RemedicalCode = terminalAIData.TerminalDataId,
  1248. CreateTime = terminalAIData.CreateTime,
  1249. UpdateTime = terminalAIData.UpdateTime < new DateTime(2000, 1, 1) ? terminalAIData.CreateTime : terminalAIData.UpdateTime,
  1250. DiagnosisResult = JsonConvert.SerializeObject(terminalAIData.DiagResults),
  1251. };
  1252. syncBatchAIResultRequest.SyncAIResultList.Add(syncAIResultRequest);
  1253. }
  1254. catch (Exception ex)
  1255. {
  1256. Logger.WriteLineWarn($"SendRemedicalAIDatas err, ex:{ex}");
  1257. }
  1258. }
  1259. var result = _jsonRpcProxy.RemedicalService.SyncBatchAIResultAsync(syncBatchAIResultRequest).Result;
  1260. }
  1261. catch (Exception ex)
  1262. {
  1263. Logger.WriteLineWarn($"SendRemedicalAIDatas err, ex:{ex}");
  1264. }
  1265. }
  1266. public async Task MigrateRemedicalCarotidDatas(SyncDBEnum syncType)
  1267. {
  1268. Logger.WriteLineInfo($"Remote diagnosis carotid datas migrate to wingServer starting");
  1269. //获取上次同步到的时间
  1270. //判断热数据
  1271. var builder = Builders<Carotid3dModelData>.Filter;
  1272. var startTime = GetFactBeginTime(_migrateRecord.StartTime, _migrateRecord.EndTime);
  1273. var filter = builder.Where(x =>(x.CreateTime > startTime && x.CreateTime <= _migrateRecord.EndTime) || (x.UpdateTime > startTime && x.UpdateTime <= _migrateRecord.EndTime));
  1274. var carotid3dModelDatas = _carotid3dModelDatasDBRepository.GetCarotid3dModelDatas(filter).OrderByDescending(x => x.CreateTime).ToList();
  1275. OnMigrate("Remote diagnosis carotid datas", carotid3dModelDatas, SendRemedicalCarotidDatas, syncType, 100);
  1276. carotid3dModelDatas.Clear();
  1277. Logger.WriteLineInfo($"Remote diagnosis carotid datas migrate to wingServer successfully");
  1278. }
  1279. private void SendRemedicalCarotidDatas(IList<Carotid3dModelData> carotid3dModelDatas, SyncDBEnum syncType)
  1280. {
  1281. try
  1282. {
  1283. var syncBatchCarotidResultRequest = new SyncBatchCarotidResultRequest();
  1284. syncBatchCarotidResultRequest.SyncType = syncType;
  1285. syncBatchCarotidResultRequest.SyncCarotidResultRequest = new List<GetCarotidResultRequest>();
  1286. foreach (var carotid3dModelData in carotid3dModelDatas)
  1287. {
  1288. try
  1289. {
  1290. var getCarotidResultRequest = new GetCarotidResultRequest
  1291. {
  1292. RemedicalCode = carotid3dModelData.ExamDataId,
  1293. SurfaceToken = GetFileUrl(carotid3dModelData.SurfaceToken),
  1294. MdlToken = GetFileUrl(carotid3dModelData.MdlToken),
  1295. CarotidScanDirection = (CarotidScanDirectionEnum)carotid3dModelData.CarotidScanDirection,
  1296. CarotidScanType = (CarotidScanTypeEnum)carotid3dModelData.CarotidScanType,
  1297. MeasureImageFiles = new List<MeasureImageFileDTO>()
  1298. };
  1299. if (!string.IsNullOrWhiteSpace(carotid3dModelData.CarotidAIMeasureImageToken))
  1300. {
  1301. string[] keyValuePairs = carotid3dModelData.CarotidAIMeasureImageToken.Split(';');
  1302. foreach (string keyValuePair in keyValuePairs)
  1303. {
  1304. string[] parts = keyValuePair.Split('=');
  1305. if (parts.Length != 2) continue;
  1306. if (Enum.TryParse(parts[0], out CarotidAIImageTypeEnum imageType))
  1307. {
  1308. string url = GetFileUrl(parts[1]);
  1309. getCarotidResultRequest.MeasureImageFiles.Add(new MeasureImageFileDTO { ImageType = imageType, ImageFile = url });
  1310. }
  1311. }
  1312. }
  1313. getCarotidResultRequest.MeasureResult = carotid3dModelData.CarotidAIMeasureResult;
  1314. syncBatchCarotidResultRequest.SyncCarotidResultRequest.Add(getCarotidResultRequest);
  1315. }
  1316. catch (Exception ex)
  1317. {
  1318. Logger.WriteLineWarn($"SendRemedicalCarotidDatas err, ex:{ex}");
  1319. }
  1320. }
  1321. var result = _jsonRpcProxy.RemedicalService.SyncBatchCarotidResultAsync(syncBatchCarotidResultRequest).Result;
  1322. }
  1323. catch (Exception ex)
  1324. {
  1325. Logger.WriteLineWarn($"SendRemedicalCarotidDatas err, ex:{ex}");
  1326. }
  1327. }
  1328. public async Task MigrateConsultationResults(SyncDBEnum syncType)
  1329. {
  1330. Logger.WriteLineInfo($"consultations migrate to wingServer starting");
  1331. //获取上次同步到的时间
  1332. var builder = Builders<ConsultationRecords>.Filter;
  1333. var startTime = GetFactBeginTime(_migrateRecord.StartTime, _migrateRecord.EndTime);
  1334. var filter = builder.Where(x => x.IsDeleted == false && ((x.CreateTime > startTime && x.CreateTime <= _migrateRecord.EndTime) || (x.UpdateTime > startTime && x.UpdateTime <= _migrateRecord.EndTime)));
  1335. var consultations = _consultationRecordDBRepository.GetTerminalRecords(filter).OrderByDescending(x => x.CreateTime).ToList();
  1336. OnMigrate("consultations", consultations, SendConsultations, syncType, 1000);
  1337. consultations.Clear();
  1338. Logger.WriteLineInfo($"consultations migrate to wingServer successfully");
  1339. }
  1340. private void SendConsultations(IList<ConsultationRecords> consultations, SyncDBEnum syncType)
  1341. {
  1342. try
  1343. {
  1344. var builder = Builders<FollowUpVisitInfos>.Filter;
  1345. var startTime = GetFactBeginTime(_migrateRecord.StartTime, _migrateRecord.EndTime);
  1346. var filter = builder.Where(x => (x.CreateTime > startTime && x.CreateTime <= _migrateRecord.EndTime) || (x.UpdateTime > startTime && x.UpdateTime <= _migrateRecord.EndTime));
  1347. var followVistorList = _consultationRecordDBRepository.GetAllFollowUpVisitInfosRecords(filter).OrderByDescending(x => x.CreateTime).ToList();
  1348. var evaluatesBuilder = Builders<ConsultationEvaluates>.Filter;
  1349. var evaluatesFilter = evaluatesBuilder.Where(x => (x.CreateTime > startTime && x.CreateTime <= _migrateRecord.EndTime) || (x.UpdateTime > startTime && x.UpdateTime <= _migrateRecord.EndTime));
  1350. var valuatesList = _consultationRecordDBRepository.GetAllConsultationEvaluatesRecords(evaluatesFilter).OrderByDescending(x => x.CreateTime).ToList();
  1351. var syncBatchConsultationRequest = new SyncBatchConsultationRequest();
  1352. syncBatchConsultationRequest.SyncType = syncType;
  1353. syncBatchConsultationRequest.SyncConsultations = new List<SyncConsultationRequest>();
  1354. foreach (var consultation in consultations)
  1355. {
  1356. try
  1357. {
  1358. if (consultation.TerminalInfo == null)
  1359. {
  1360. continue;
  1361. }
  1362. var patientInfo = consultation.PatientInfo;
  1363. var syncReportInfoRequest = new SyncConsultationRequest
  1364. {
  1365. ConsultationCode = consultation.Id,
  1366. CreateTime = consultation.CreateTime,
  1367. UpdateTime = consultation.UpdateTime,
  1368. ApplyOrganizationCode = consultation.PrimaryHosptial.Id,
  1369. ApplyUserCode = consultation.DoctorInfo.ID,
  1370. ExpertOrganizationCode = consultation.CentralHospital.Id,
  1371. ExpertUserCode = consultation.ExpertInfo.ID,
  1372. DeviceCode = consultation.TerminalInfo.Id,
  1373. ScanUser = consultation.ScanDoctor,
  1374. PatientInfo = new List<DataItemDTO>
  1375. {
  1376. new DataItemDTO{Key="Name",Value=patientInfo.Name},
  1377. new DataItemDTO{Key="Phone",Value=patientInfo.ContactInfo},
  1378. new DataItemDTO{Key="ID",Value=patientInfo.ID},//设备病人ID
  1379. new DataItemDTO{Key="Sex",Value = patientInfo.GenderType.ToString()=="Unassigned"?"NotFilled":patientInfo.GenderType.ToString()},
  1380. new DataItemDTO{Key="Anamnesis",Value=patientInfo.PastHistory},
  1381. },
  1382. ScanPosition = consultation.CheckPoint,
  1383. ConsultationTime = consultation.AppointmentTime,
  1384. ConsultationTimeEnd = consultation.AppointmentTime.AddHours(2),
  1385. PrimaryDiagnosis = consultation.PatientInfo.Diagnosis,
  1386. ConsultationStatus = GetStatusEnum(consultation.State),
  1387. FollowUpVisitStatus = (FollowUpVisitStatusEnum)consultation.FollowUpVisitStatus,
  1388. EvaluateGradeEnum = (EvaluateGradeEnum)consultation.EvaluateGrade,
  1389. ConsultationFileList = new List<ConsultationFileDTO>()
  1390. };
  1391. if (valuatesList?.Count > 0)
  1392. {
  1393. var findEntity = valuatesList.OrderByDescending(c => c.CreateTime).FirstOrDefault(c => c.ConsultationRecordId == consultation.Id) ?? new ConsultationEvaluates();
  1394. if (!string.IsNullOrEmpty(findEntity.Id))
  1395. {
  1396. syncReportInfoRequest.EvaluateGradeEnum = (EvaluateGradeEnum)findEntity.EvaluateGrade;
  1397. }
  1398. }
  1399. //查询随访记录
  1400. if (followVistorList?.Count > 0)
  1401. {
  1402. var findList = followVistorList.Where(c => c.ConsultationRecordId == consultation.Id)?.ToList();
  1403. if (findList?.Count > 0)
  1404. {
  1405. var followUpVistorList = findList.Select(c => new SyncFollowUpVisitRequest()
  1406. {
  1407. IsDelete = c.IsDeleted,
  1408. CreateTime = c.CreateTime,
  1409. UpdateTime = c.UpdateTime,
  1410. FollowUpVisitCode = c.Id,
  1411. ConsultationRecordCode = c.ConsultationRecordId,
  1412. PatientName = c.PatientName,
  1413. PatientPhone = c.PatientPhone,
  1414. GeneralCase = c.GeneralCase,
  1415. ClinicalSituation = c.ClinicalSituation,
  1416. DoctorCode = c.Doctor,
  1417. OccurredTime = c.OccurredTime
  1418. }).ToList();
  1419. syncReportInfoRequest.SyncFollowUpVisitList = followUpVistorList;
  1420. }
  1421. }
  1422. if (consultation.ImageTokens != null && consultation.ImageTokens.Any())
  1423. {
  1424. foreach (var item in consultation.ImageTokens)
  1425. {
  1426. var consultationFileDTO = new ConsultationFileDTO();
  1427. consultationFileDTO.FileDataType = RemedicalFileDataTypeEnum.VinnoVidSingle;
  1428. consultationFileDTO.SourceUrl = GetFileUrl(item);
  1429. consultationFileDTO.PreviewImageUrl = ConvertToJpg(item);
  1430. syncReportInfoRequest.ConsultationFileList.Add(consultationFileDTO);
  1431. }
  1432. }
  1433. if (consultation.VideoTokens != null && consultation.VideoTokens.Any())
  1434. {
  1435. foreach (var item in consultation.VideoTokens)
  1436. {
  1437. var consultationFileDTO = new ConsultationFileDTO();
  1438. consultationFileDTO.FileDataType = RemedicalFileDataTypeEnum.VinnoVidMovie;
  1439. consultationFileDTO.SourceUrl = GetFileUrl(item.VideoToken);
  1440. consultationFileDTO.PreviewImageUrl = ConvertToJpg(item.PreviewImageToken);
  1441. syncReportInfoRequest.ConsultationFileList.Add(consultationFileDTO);
  1442. }
  1443. }
  1444. if (consultation.GraphicData != null && consultation.GraphicData.Any())
  1445. {
  1446. foreach (var item in consultation.GraphicData)
  1447. {
  1448. var consultationFileDTO = new ConsultationFileDTO();
  1449. consultationFileDTO.FileDataType = item.GraphicType == 0 ? RemedicalFileDataTypeEnum.ThirdVidSingle : RemedicalFileDataTypeEnum.ThirdVidMovie;
  1450. consultationFileDTO.SourceUrl = GetFileUrl(item.GraphicToken);
  1451. consultationFileDTO.PreviewImageUrl = ConvertToJpg(item.PreviewGraphicToken);
  1452. consultationFileDTO.CreateTime = (consultation.UpdateTime <= DateTime.MinValue ? consultation.CreateTime : consultation.UpdateTime);
  1453. syncReportInfoRequest.ConsultationFileList.Add(consultationFileDTO);
  1454. }
  1455. }
  1456. if (consultation.PreFileItems != null && consultation.PreFileItems.Any())
  1457. {
  1458. foreach (var item in consultation.PreFileItems)
  1459. {
  1460. var consultationFileDTO = new ConsultationFileDTO();
  1461. consultationFileDTO.FileDataType = item.FileType == 0 ? RemedicalFileDataTypeEnum.ThirdVidSingle : RemedicalFileDataTypeEnum.ThirdVidMovie;
  1462. consultationFileDTO.SourceUrl = GetFileUrl(item.OriginalFileUrl);
  1463. consultationFileDTO.PreviewImageUrl = ConvertToJpg(item.ThumbnailUrl);
  1464. syncReportInfoRequest.ConsultationFileList.Add(consultationFileDTO);
  1465. }
  1466. }
  1467. syncBatchConsultationRequest.SyncConsultations.Add(syncReportInfoRequest);
  1468. }
  1469. catch (Exception ex)
  1470. {
  1471. Logger.WriteLineWarn($"SendConsultations err, ex:{ex}");
  1472. }
  1473. }
  1474. var result = _jsonRpcProxy.LiveConsultationService.SyncBatchConsultationAsync(syncBatchConsultationRequest).Result;
  1475. }
  1476. catch (Exception ex)
  1477. {
  1478. Logger.WriteLineWarn($"SendConsultations err, ex:{ex}");
  1479. }
  1480. }
  1481. private TransactionStatusEnum GetStatusEnum(Entities.ConsultationState state)
  1482. {
  1483. TransactionStatusEnum transactionStatusEnum = TransactionStatusEnum.Applied;
  1484. switch (state)
  1485. {
  1486. case Entities.ConsultationState.Unhandled:
  1487. transactionStatusEnum = TransactionStatusEnum.Applied;
  1488. break;
  1489. case Entities.ConsultationState.Withdrawn:
  1490. transactionStatusEnum = TransactionStatusEnum.Withdrawn;
  1491. break;
  1492. case Entities.ConsultationState.Handled:
  1493. transactionStatusEnum = TransactionStatusEnum.ToStart;
  1494. break;
  1495. case Entities.ConsultationState.Started:
  1496. transactionStatusEnum = TransactionStatusEnum.InProgress;
  1497. break;
  1498. case Entities.ConsultationState.WaitForReportUpload:
  1499. transactionStatusEnum = TransactionStatusEnum.PendingReport;
  1500. break;
  1501. case Entities.ConsultationState.ReportUploading:
  1502. transactionStatusEnum = TransactionStatusEnum.PendingReport;
  1503. break;
  1504. case Entities.ConsultationState.ReportUploaded:
  1505. transactionStatusEnum = TransactionStatusEnum.End;
  1506. break;
  1507. case Entities.ConsultationState.ReportUploadFailed:
  1508. transactionStatusEnum = TransactionStatusEnum.PendingReport;
  1509. break;
  1510. case Entities.ConsultationState.Expired:
  1511. transactionStatusEnum = TransactionStatusEnum.End;
  1512. break;
  1513. case Entities.ConsultationState.Qualified:
  1514. transactionStatusEnum = TransactionStatusEnum.End;
  1515. break;
  1516. case Entities.ConsultationState.UnQualified:
  1517. transactionStatusEnum = TransactionStatusEnum.End;
  1518. break;
  1519. default:
  1520. break;
  1521. }
  1522. return transactionStatusEnum;
  1523. }
  1524. public async Task MigrateReportInfoResults(SyncDBEnum syncType)
  1525. {
  1526. Logger.WriteLineInfo($"ReportInfoResults migrate to wingServer starting");
  1527. //获取上次同步到的时间
  1528. var builder = Builders<ReportInfoResults>.Filter;
  1529. var startTime = GetFactBeginTime(_migrateRecord.StartTime, _migrateRecord.EndTime);
  1530. var filter = builder.Where(x => (x.CreateTime > startTime && x.CreateTime <= _migrateRecord.EndTime) || (x.UpdateTime > startTime && x.UpdateTime <= _migrateRecord.EndTime));
  1531. var reportInfoResults = _reportInfoResultDBRepository.GetReports(filter).OrderByDescending(x => x.CreateTime).ToList();
  1532. OnMigrate("reportInfoResults", reportInfoResults, SendRemedicalreportInfoResults, syncType, 1000);
  1533. reportInfoResults.Clear();
  1534. Logger.WriteLineInfo($"reportInfoResults migrate to wingServer successfully");
  1535. }
  1536. private void SendRemedicalreportInfoResults(IList<ReportInfoResults> reportInfoResults, SyncDBEnum syncType)
  1537. {
  1538. try
  1539. {
  1540. var syncBatchReportInfoRequest = new SyncBatchReportInfoRequest();
  1541. syncBatchReportInfoRequest.SyncType = syncType;
  1542. syncBatchReportInfoRequest.SyncReportInfos = new List<SyncReportInfoRequest>();
  1543. foreach (var reportInfoResult in reportInfoResults)
  1544. {
  1545. try
  1546. {
  1547. var diagnosisLabels = new List<string>();
  1548. var reportUserCode = "";
  1549. var isAI = false;
  1550. if (reportInfoResult?.User?.Name == "AI")
  1551. {
  1552. diagnosisLabels = new List<string> { "VAid" };
  1553. isAI = true;
  1554. }
  1555. else
  1556. {
  1557. reportUserCode = reportInfoResult.User._id;
  1558. }
  1559. var syncReportInfoRequest = new SyncReportInfoRequest
  1560. {
  1561. ReportCode = reportInfoResult.Id,
  1562. CreateTime = reportInfoResult.CreateTime,
  1563. UpdateTime = reportInfoResult.UpdateTime,
  1564. RecordCode = reportInfoResult.RecordId,
  1565. ReportTemplateJson = reportInfoResult.Template,
  1566. ReportDatasJson = ReportElementsSerializer.ConvertReportElementsToJson(isAI, reportInfoResult.Template, reportInfoResult.ElementCollection),
  1567. ReportPreviewList = new List<ReportPreviewDTO>(),
  1568. ReportOrgan = (DiagnosisOrganEnum)reportInfoResult.Organ,
  1569. DiagnosisLabels = diagnosisLabels,
  1570. ReportUserCode = reportUserCode
  1571. };
  1572. if (reportInfoResult.PreviewImages != null && reportInfoResult.PreviewImages.Count > 0)
  1573. {
  1574. foreach (var item in reportInfoResult.PreviewImages)
  1575. {
  1576. var reportPreviewDTO = new ReportPreviewDTO();
  1577. reportPreviewDTO.FileToken = GetFileUrl(item.Name);
  1578. reportPreviewDTO.FileType = UploadFileTypeEnum.JPG;
  1579. syncReportInfoRequest.ReportPreviewList.Add(reportPreviewDTO);
  1580. }
  1581. }
  1582. syncBatchReportInfoRequest.SyncReportInfos.Add(syncReportInfoRequest);
  1583. }
  1584. catch (Exception ex)
  1585. {
  1586. Logger.WriteLineWarn($"SendRemedicalreportInfoResults err, ex:{ex}");
  1587. }
  1588. }
  1589. var result = _jsonRpcProxy.ReportService.SyncBatchReportInfoAsync(syncBatchReportInfoRequest).Result;
  1590. }
  1591. catch (Exception ex)
  1592. {
  1593. Logger.WriteLineWarn($"SendRemedicalreportInfoResults err, ex:{ex}");
  1594. }
  1595. }
  1596. private string GetFileUrl(string fileUrl)
  1597. {
  1598. var prefix = "1!U$";
  1599. if (!string.IsNullOrWhiteSpace(fileUrl) && fileUrl.StartsWith(prefix))
  1600. {
  1601. return fileUrl.Replace(prefix, "");
  1602. }
  1603. return fileUrl ?? string.Empty;
  1604. }
  1605. private string ConvertToJpg(string oldFileToken)
  1606. {
  1607. try
  1608. {
  1609. var prefix = "1!U$";
  1610. if (!string.IsNullOrWhiteSpace(oldFileToken) && oldFileToken.StartsWith(prefix))
  1611. {
  1612. var fileUrl = oldFileToken.Replace(prefix, "");
  1613. var localPath = DownloadAsync(fileUrl, $"{Guid.NewGuid():N}.jpg").Result;
  1614. if (!string.IsNullOrWhiteSpace(localPath))
  1615. {
  1616. var newUrl = UploadAsync(localPath).Result;
  1617. if (!string.IsNullOrWhiteSpace(newUrl))
  1618. {
  1619. return newUrl;
  1620. }
  1621. }
  1622. }
  1623. return oldFileToken;
  1624. }
  1625. catch (Exception ex)
  1626. {
  1627. Logger.WriteLineWarn($"ConvertToJpg err, ex:{ex}");
  1628. return oldFileToken;
  1629. }
  1630. }
  1631. private OrganizationView MapToOrganizationView(IList<Organizations> organizations, string? hospitalId)
  1632. {
  1633. var hospital = organizations.FirstOrDefault(x => x.Id == hospitalId);
  1634. if (hospital != null)
  1635. {
  1636. return new OrganizationView
  1637. {
  1638. Code = hospital.Id,
  1639. Name = hospital.Name,
  1640. Description = hospital.Description,
  1641. CountryCode = hospital.Country?.Id,
  1642. CountryName = hospital.Country?.Name,
  1643. ProvinceCode = hospital.Province?.Id,
  1644. ProvinceName = hospital.Province?.Name,
  1645. CityCode = hospital.City?.Id,
  1646. CityName = hospital.City?.Name,
  1647. };
  1648. }
  1649. return null;
  1650. }
  1651. private UserView MapToUserView(IList<Organizations> organizations, IList<Users> users, string? userId)
  1652. {
  1653. var user = users.FirstOrDefault(x => x._id == userId);
  1654. if (user != null)
  1655. {
  1656. var hospital = organizations.FirstOrDefault(x => x.Id == user.HospitalId);
  1657. var name = !string.IsNullOrWhiteSpace(user.FullName) ? user.FullName
  1658. : !string.IsNullOrWhiteSpace(user.LastName) ? user.LastName
  1659. : !string.IsNullOrWhiteSpace(user.FirstName) ? user.FirstName
  1660. : !string.IsNullOrWhiteSpace(user.NickName) ? user.NickName
  1661. : user.Name;
  1662. return new UserView
  1663. {
  1664. Code = user._id,
  1665. Name = name,
  1666. OrganizationCode = user.HospitalId,
  1667. OrganizationName = hospital?.Name,
  1668. };
  1669. }
  1670. return null;
  1671. }
  1672. private DeviceView MapToDeviceView(IList<Terminals> terminals, string? terminalId)
  1673. {
  1674. var terminal = terminals.FirstOrDefault(x => x.Id == terminalId);
  1675. if (terminal != null)
  1676. {
  1677. return new DeviceView
  1678. {
  1679. Code = terminal.Id,
  1680. Name = terminal.Name,
  1681. Description = terminal.Description,
  1682. UniqueCode = terminal.UniquedId,
  1683. DeviceType = terminal.IsSonopost ? "sonopost" : "US",
  1684. DeviceModel = terminal.Model,
  1685. OrganizationCode = terminal.Organization?.Id,
  1686. OrganizationName = terminal.Organization?.Name,
  1687. };
  1688. }
  1689. return null;
  1690. }
  1691. private GroupView MapToUserGroupView(IList<UserGroup> userGroups, string? userGroupId)
  1692. {
  1693. var userGroup = userGroups.FirstOrDefault(x => x.Id == userGroupId);
  1694. if (userGroup != null)
  1695. {
  1696. return new GroupView
  1697. {
  1698. Code = userGroup.Id,
  1699. Name = userGroup.Name,
  1700. };
  1701. }
  1702. return null;
  1703. }
  1704. private ClassView MapToClassView(IList<UltrasonicClass> classes, string? classId)
  1705. {
  1706. var classInfo = classes.FirstOrDefault(x => x.Id == classId);
  1707. if (classInfo != null)
  1708. {
  1709. return new ClassView
  1710. {
  1711. Code = classInfo.Id,
  1712. Name = classInfo.Name,
  1713. };
  1714. }
  1715. return null;
  1716. }
  1717. private List<DiagnosisOrganEnum> GetDiagnosisOrgans(List<AIDiagnosisPerImg> results)
  1718. {
  1719. var diagnosisOrgans = new List<DiagnosisOrganEnum>();
  1720. foreach (var imageResult in results)
  1721. {
  1722. foreach (var diagnosisResult in imageResult.DiagResultsForEachOrgan)
  1723. {
  1724. var organName = Enum.GetName(typeof(DiagnosisOrganEnum), (int)diagnosisResult.Organ);
  1725. if (!string.IsNullOrWhiteSpace(organName) && diagnosisResult.Organ != EnumOrgans.Null && diagnosisResult.DetectedObjects?.Any() == true)
  1726. {
  1727. diagnosisOrgans.Add((DiagnosisOrganEnum)diagnosisResult.Organ);
  1728. }
  1729. }
  1730. }
  1731. return diagnosisOrgans.Distinct().ToList();
  1732. }
  1733. private DiagnosisConclusionEnum GetDiagnosisConclusion(List<AIDiagnosisPerImg> results)
  1734. {
  1735. var diagnosisConclusions = new List<DiagnosisConclusionEnum>();
  1736. foreach (var imageResult in results)
  1737. {
  1738. foreach (var diagnosisResult in imageResult.DiagResultsForEachOrgan)
  1739. {
  1740. var benignLabels = new List<int>();
  1741. var malignantLabels = new List<int>();
  1742. if (diagnosisResult.Organ == EnumOrgans.Breast)
  1743. {
  1744. benignLabels = new List<int> { 1, 2, 3 };
  1745. malignantLabels = new List<int> { 4, 5, 6, 7 };
  1746. }
  1747. else if (diagnosisResult.Organ == EnumOrgans.Liver)
  1748. {
  1749. benignLabels = new List<int> { 1, 2, 3, 5, 6, 7, 8 };
  1750. malignantLabels = new List<int> { 4 };
  1751. }
  1752. else if (diagnosisResult.Organ == EnumOrgans.Thyroid)
  1753. {
  1754. benignLabels = new List<int> { 1, 2, 7 };
  1755. malignantLabels = new List<int> { 3, 4, 5, 6 };
  1756. }
  1757. var labels = diagnosisResult.DetectedObjects.Select(x => x.Label);
  1758. if (labels.Contains(0))
  1759. {
  1760. diagnosisConclusions.Add(DiagnosisConclusionEnum.NoObviousLesion);
  1761. }
  1762. if (labels.Intersect(benignLabels).Any())
  1763. {
  1764. diagnosisConclusions.Add(DiagnosisConclusionEnum.Benign);
  1765. }
  1766. if (labels.Intersect(malignantLabels).Any())
  1767. {
  1768. diagnosisConclusions.Add(DiagnosisConclusionEnum.Malignant);
  1769. }
  1770. }
  1771. }
  1772. var containsBenign = diagnosisConclusions.Contains(DiagnosisConclusionEnum.Benign);
  1773. var containsMalignant = diagnosisConclusions.Contains(DiagnosisConclusionEnum.Malignant);
  1774. var containsNoObviousLesion = diagnosisConclusions.Contains(DiagnosisConclusionEnum.NoObviousLesion);
  1775. if (containsBenign && containsMalignant)
  1776. {
  1777. return DiagnosisConclusionEnum.BenignAndMalignant;
  1778. }
  1779. else if (containsBenign)
  1780. {
  1781. return DiagnosisConclusionEnum.Benign;
  1782. }
  1783. else if (containsMalignant)
  1784. {
  1785. return DiagnosisConclusionEnum.Malignant;
  1786. }
  1787. else if (containsNoObviousLesion)
  1788. {
  1789. return DiagnosisConclusionEnum.NoObviousLesion;
  1790. }
  1791. else
  1792. {
  1793. return DiagnosisConclusionEnum.Unrecognized;
  1794. }
  1795. }
  1796. /// <summary>下载文件</summary>
  1797. /// <param name="fileUrl"></param>
  1798. /// <returns></returns>
  1799. private async Task<string> DownloadAsync(string fileUrl, string fileNameAndExtension = "")
  1800. {
  1801. try
  1802. {
  1803. if (string.IsNullOrEmpty(fileUrl))
  1804. {
  1805. return string.Empty;
  1806. }
  1807. if (!Directory.Exists(_tempFolder))
  1808. {
  1809. Directory.CreateDirectory(_tempFolder);
  1810. }
  1811. var fileName = Path.GetFileName(fileUrl);
  1812. if (!string.IsNullOrWhiteSpace(fileNameAndExtension))
  1813. {
  1814. fileName = fileNameAndExtension;
  1815. }
  1816. var tempFile = Path.Combine(_tempFolder, fileName);
  1817. if (File.Exists(tempFile))
  1818. {
  1819. return tempFile;
  1820. }
  1821. long fileSize = 0;
  1822. using (var request = new HttpRequestMessage())
  1823. {
  1824. request.RequestUri = new Uri(fileUrl);
  1825. request.Method = HttpMethod.Get;
  1826. var response = await _httpClient.SendAsync(request);
  1827. if (response != null && response.StatusCode == HttpStatusCode.OK)
  1828. {
  1829. var contentLength = response.Content.Headers.ContentLength;
  1830. fileSize = contentLength == null ? 0 : contentLength.Value;
  1831. }
  1832. }
  1833. if (fileSize <= 0)
  1834. {
  1835. throw new NotSupportedException($"fileSize is {fileSize}");
  1836. }
  1837. byte[] bytes = await _httpClient.GetByteArrayAsync(fileUrl);
  1838. File.WriteAllBytes(tempFile, bytes);
  1839. return tempFile;
  1840. }
  1841. catch (Exception ex)
  1842. {
  1843. Logger.WriteLineWarn($"MigrateService download file err, url: {fileUrl}, {ex}");
  1844. }
  1845. finally
  1846. {
  1847. //Logger.WriteLineInfo($"download file:{fileUrl}");
  1848. }
  1849. return string.Empty;
  1850. }
  1851. private async Task<string> UploadAsync(string localPath)
  1852. {
  1853. var authorizationResult = await _jsonRpcProxy.Storage.GetAuthorizationAsync(new FileServiceRequest
  1854. {
  1855. Token = DefaultToken,
  1856. FileName = Path.GetFileName(localPath),
  1857. IsRechristen = true,
  1858. });
  1859. var fileUrl = authorizationResult.StorageUrl;
  1860. using (var fileStream = new FileStream(localPath, FileMode.Open))
  1861. {
  1862. var size = fileStream.Length;
  1863. byte[] buffer = new byte[fileStream.Length];
  1864. fileStream.Read(buffer, 0, buffer.Length);
  1865. var requestHeads = new Dictionary<string, string>();
  1866. requestHeads.Add("Authorization", authorizationResult.Authorization);
  1867. using (var request = new HttpRequestMessage())
  1868. {
  1869. var fileExtension = Path.GetExtension(localPath);
  1870. var mimeType = FileHelper.GetMimeType(fileExtension);
  1871. var contentType = MediaTypeHeaderValue.Parse(mimeType);
  1872. using (UploadContent content = new UploadContent(buffer, contentType))
  1873. {
  1874. request.RequestUri = new Uri(fileUrl);
  1875. request.Method = HttpMethod.Put;
  1876. request.Content = content;
  1877. foreach (var head in requestHeads)
  1878. {
  1879. request.Headers.TryAddWithoutValidation(head.Key, head.Value);
  1880. }
  1881. var result = await ExecuteRequest(request);
  1882. if (result)
  1883. {
  1884. return fileUrl;
  1885. }
  1886. }
  1887. }
  1888. }
  1889. return null;
  1890. }
  1891. /// <summary>
  1892. /// 执行请求
  1893. /// </summary>
  1894. /// <param name="httpRequestMessage"></param>
  1895. /// <typeparam name="T"></typeparam>
  1896. /// <returns></returns>
  1897. private async Task<bool> ExecuteRequest(HttpRequestMessage httpRequestMessage)
  1898. {
  1899. try
  1900. {
  1901. var response = await _httpClient.SendAsync(httpRequestMessage);
  1902. if (response != null && response.StatusCode == HttpStatusCode.OK)
  1903. {
  1904. return true;
  1905. }
  1906. return false;
  1907. }
  1908. catch (Exception ex)
  1909. {
  1910. throw ex;
  1911. }
  1912. }
  1913. /// <summary>
  1914. /// 获取实际时间
  1915. /// </summary>
  1916. /// <param name="beginTime"></param>
  1917. /// <param name="endTime"></param>
  1918. /// <returns></returns>
  1919. private DateTime GetFactBeginTime(DateTime beginTime, DateTime endTime)
  1920. {
  1921. var dateDiff = endTime - beginTime;
  1922. if (dateDiff.TotalDays > 365)
  1923. {
  1924. beginTime = endTime.AddYears(-1);
  1925. }
  1926. return beginTime;
  1927. }
  1928. }
  1929. public class AIDiagnosisPerImg
  1930. {
  1931. /// <summary>
  1932. /// Index
  1933. /// </summary>
  1934. public int Index { get; set; }
  1935. /// <summary>
  1936. /// Priority Score
  1937. /// </summary>
  1938. public float PriorityScore { get; set; }
  1939. /// <summary>
  1940. /// DiagResults of each Organ
  1941. /// </summary>
  1942. public IList<AIDiagResultPerOrganForDB> DiagResultsForEachOrgan { get; set; }
  1943. }
  1944. public class UploadContent : HttpContent
  1945. {
  1946. private const int ChunkSize = 2097152;//2M;
  1947. private readonly Stream _uploadStream;
  1948. private readonly long _fileSize;
  1949. public event EventHandler<double> ProgressChanged;
  1950. public UploadContent(string filePath)
  1951. {
  1952. if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
  1953. {
  1954. throw new Exception("UploadFile not find");
  1955. }
  1956. var fileName = Path.GetFileName(filePath);
  1957. _uploadStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
  1958. var mimeType = FileHelper.GetMimeType(fileName.Substring(fileName.LastIndexOf(".")));
  1959. Headers.ContentType = MediaTypeHeaderValue.Parse(mimeType);
  1960. Headers.ContentLength = _uploadStream.Length;
  1961. _fileSize = _uploadStream.Length;
  1962. }
  1963. public UploadContent(byte[] fileData, MediaTypeHeaderValue mediaTypeHeaderValue)
  1964. {
  1965. if (fileData == null || fileData.Length == 0)
  1966. {
  1967. throw new Exception("FileData is empty");
  1968. }
  1969. _uploadStream = new MemoryStream(fileData);
  1970. Headers.ContentType = mediaTypeHeaderValue;
  1971. Headers.ContentLength = _uploadStream.Length;
  1972. _fileSize = _uploadStream.Length;
  1973. }
  1974. /// <summary>
  1975. /// 将内容写入流
  1976. /// </summary>
  1977. /// <param name="stream"></param>
  1978. /// <param name="context"></param>
  1979. /// <returns></returns>
  1980. protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
  1981. {
  1982. for (long i = 0; i < _uploadStream.Length; i += ChunkSize)
  1983. {
  1984. var dataToWrite = new byte[Math.Min(ChunkSize, _uploadStream.Length - i)];
  1985. await _uploadStream.ReadAsync(dataToWrite, 0, dataToWrite.Length);
  1986. await stream.WriteAsync(dataToWrite, 0, dataToWrite.Length);
  1987. OnProgressChanged((double)(i * 100 / _uploadStream.Length));
  1988. }
  1989. OnProgressChanged(100);
  1990. }
  1991. /// <summary>
  1992. /// 比较文件大小
  1993. /// </summary>
  1994. /// <returns></returns>
  1995. public bool CompareFileSizes(long webFileSize)
  1996. {
  1997. return _fileSize == webFileSize;
  1998. }
  1999. protected override bool TryComputeLength(out long length)
  2000. {
  2001. length = _uploadStream.Length;
  2002. return true;
  2003. }
  2004. private void OnProgressChanged(double e)
  2005. {
  2006. ProgressChanged?.Invoke(this, e);
  2007. }
  2008. public new void Dispose()
  2009. {
  2010. base.Dispose();
  2011. _uploadStream.Close();
  2012. ProgressChanged = null;
  2013. }
  2014. }
  2015. }