measure_data_helper.dart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. // ignore_for_file: constant_identifier_names
  2. import 'dart:convert';
  3. import 'package:fis_common/logger/logger.dart';
  4. import 'package:fis_jsonrpc/rpc.dart';
  5. import 'package:fis_measure/process/workspace/measure_handler.dart';
  6. import 'package:fis_measure/process/workspace/rpc_bridge.dart';
  7. import 'package:fis_i18n/i18n.dart';
  8. import 'package:flutter/foundation.dart';
  9. class MeasureDataHelper {
  10. // static VidImageSource source = VidImageSource.Remedical;
  11. static get source => RPCBridge.ins.source;
  12. // 获取图像列表
  13. static Future<List<RemedicalItemList>> getRemedicalList(
  14. String patientCode, String recordCode) async {
  15. try {
  16. // 初始化为空列表
  17. List<RemedicalItemList> remedicalItems = [];
  18. // 当数据来源是 Consultation 时
  19. if (source == VidImageSource.Consultation) {
  20. // 获取咨询图片
  21. var images = await getConsultationImages(recordCode);
  22. // 遍历图片列表,将非空的 imageInfos 添加到 remedicalItems 中
  23. for (var imageInfo in images) {
  24. var imageInfos = imageInfo.ultrasoundImageList ?? [];
  25. if (imageInfos.isNotEmpty) {
  26. remedicalItems.add(RemedicalItemList(
  27. remedicalList: imageInfos,
  28. ));
  29. }
  30. }
  31. }
  32. // 当数据来源是 Laboratory 时
  33. else if (source == VidImageSource.Laboratory) {
  34. // 获取患者的文件列表
  35. var getRecordsPage =
  36. await RPCBridge.ins.rpc.lab.getFileListByFolderAsync(
  37. GetFileListByFolderRequest(
  38. token: RPCBridge.ins.userToken,
  39. pageIndex: 1,
  40. pageSize: 100,
  41. folderCode: patientCode,
  42. ),
  43. );
  44. remedicalItems.add(RemedicalItemList(
  45. remedicalList: getRecordsPage.pageData,
  46. ));
  47. }
  48. // 当数据来源为ai结果编辑的
  49. else if (source == VidImageSource.AiResultModifier) {
  50. var result =
  51. await RPCBridge.ins.rpc.remedical.getPatientAISelectedInfosAsync(
  52. GetPatientAISelectedInfosRequest(
  53. token: RPCBridge.ins.userToken,
  54. recordCode: recordCode,
  55. ),
  56. );
  57. List<RemedicalInfoDTO> remedicalInfoList = [];
  58. for (var element in result) {
  59. remedicalInfoList.add(RemedicalInfoDTO(
  60. recordCode: element.recordCode,
  61. remedicalCode: element.remedicalAISelectedInfoCode,
  62. terminalImages: TerminalImageDTO(
  63. previewUrl: element.previewFileToken,
  64. imageUrl: element.cdnFileToken,
  65. coverImageUrl: element.previewFileToken,
  66. originImageUrl: element.orginalFileToken,
  67. recommendedDownloadMode: element.recommendedDownloadMode,
  68. ),
  69. diagnosisConclusion: element.diagnosisConclusion,
  70. diagnosisOrgans: element.diagnosisOrgans,
  71. ));
  72. }
  73. remedicalItems.add(RemedicalItemList(
  74. remedicalList: remedicalInfoList,
  75. ));
  76. } else if (source == VidImageSource.RemoteUS) {
  77. // 获取患者的病历记录
  78. PageResult<RemedicalListResult> result =
  79. PageResult<RemedicalListResult>();
  80. result.pageData = [];
  81. try {
  82. result = await RPCBridge.ins.rpc.remoteUltrasound
  83. .vitalGetRemedicalListPagesAsync(
  84. GetRecordsPageRequest(
  85. token: RPCBridge.ins.userToken,
  86. pageIndex: 1,
  87. pageSize: 100,
  88. patientCode: patientCode,
  89. ),
  90. );
  91. } catch (e) {
  92. logger.e('MeasureDataHelper vitalGetRemedicalListPagesAsync ex:$e');
  93. }
  94. // 遍历病历记录列表,当某条记录的 recordCode 与传入的 recordCode 相同时,将其 remedicalItemList 添加到 remedicalItems 中
  95. if (result.pageData!.isNotEmpty) {
  96. var recordInfo = result.pageData!.firstWhere(
  97. (element) => element.recordCode == recordCode,
  98. orElse: () => RemedicalListResult());
  99. remedicalItems = recordInfo.remedicalItemList ?? [];
  100. }
  101. }
  102. // 当数据来源为其他情况时
  103. else {
  104. // 获取患者的病历记录
  105. PageResult<RemedicalListResult> result =
  106. PageResult<RemedicalListResult>();
  107. result.pageData = [];
  108. try {
  109. result = await RPCBridge.ins.rpc.remedical.getRemedicalListPagesAsync(
  110. GetRecordsPageRequest(
  111. token: RPCBridge.ins.userToken,
  112. pageIndex: 1,
  113. pageSize: 100,
  114. patientCode: patientCode,
  115. ),
  116. );
  117. } catch (e) {
  118. logger.e('MeasureDataHelper getRemedicalListPagesAsync ex:$e');
  119. }
  120. // 遍历病历记录列表,当某条记录的 recordCode 与传入的 recordCode 相同时,将其 remedicalItemList 添加到 remedicalItems 中
  121. if (result.pageData!.isNotEmpty) {
  122. var recordInfo = result.pageData!.firstWhere(
  123. (element) => element.recordCode == recordCode,
  124. orElse: () => RemedicalListResult());
  125. remedicalItems = recordInfo.remedicalItemList ?? [];
  126. }
  127. }
  128. // 返回最终的 remedicalItems 列表
  129. return remedicalItems;
  130. } catch (e) {
  131. logger.e('MeasureHomeController getRemedicalList ex:', e);
  132. // 出现异常时返回空列表
  133. return [];
  134. }
  135. }
  136. ///获取会诊图像
  137. static Future<List<ConsultationImagesDTO>> getConsultationImages(
  138. String consultationCode) async {
  139. try {
  140. if (consultationCode.isEmpty) {
  141. return [];
  142. }
  143. var realTimeConsultationImageList =
  144. await RPCBridge.ins.rpc.liveConsultation.getConsultationFilesAsync(
  145. FindConsultationDetailRequest(
  146. consultationCode: consultationCode, token: RPCBridge.ins.userToken),
  147. );
  148. return realTimeConsultationImageList;
  149. } catch (e) {
  150. logger.e('RealTimeConsultationImageController getConsultationImages ex:' +
  151. e.toString());
  152. }
  153. return [];
  154. }
  155. ///获取图像详情
  156. static Future<RemedicalInfoDTO?> getImageInfo(
  157. String remedicalCode,
  158. String? remedicalAISelectedInfoCode,
  159. ) async {
  160. try {
  161. RemedicalInfoDTO result;
  162. print(source);
  163. if (source == VidImageSource.AiResultModifier) {
  164. final remedicalAISelectedInfo =
  165. await RPCBridge.ins.rpc.remedical.getRemedicalAISelectedInfoAsync(
  166. GetRemedicalAISelectedInfoRequest(
  167. token: RPCBridge.ins.userToken,
  168. code: remedicalAISelectedInfoCode,
  169. ),
  170. );
  171. result = RemedicalInfoDTO(
  172. diagnosisResult: jsonEncode(
  173. [
  174. {
  175. 'DiagResultsForEachOrgan':
  176. jsonDecode(remedicalAISelectedInfo.diagnosisData ?? '')[
  177. 'DiagResultsForEachOrgan'],
  178. 'Index': jsonDecode(
  179. remedicalAISelectedInfo.diagnosisData ?? '')['Index'],
  180. 'PriorityScore':
  181. jsonDecode(remedicalAISelectedInfo.diagnosisData ?? '')[
  182. 'PriorityScore'],
  183. }
  184. ],
  185. ),
  186. terminalImages: TerminalImageDTO(
  187. previewUrl: remedicalAISelectedInfo.previewFileToken,
  188. imageUrl: remedicalAISelectedInfo.cdnFileToken,
  189. coverImageUrl: remedicalAISelectedInfo.previewFileToken,
  190. originImageUrl: remedicalAISelectedInfo.orginalFileToken,
  191. recommendedDownloadMode:
  192. remedicalAISelectedInfo.recommendedDownloadMode,
  193. ),
  194. diagnosisConclusion: DiagnosisConclusionEnum.Benign,
  195. );
  196. } else if (source == VidImageSource.RemoteUS) {
  197. result = await RPCBridge.ins.rpc.remoteUltrasound
  198. .vitalFindRemedicalByCodeAsync(
  199. FindRemedicalByCodeRequest(
  200. token: RPCBridge.ins.userToken,
  201. remedicalCode: remedicalCode,
  202. existDiagnosisResult: true,
  203. ),
  204. );
  205. } else {
  206. result = await RPCBridge.ins.rpc.remedical.findRemedicalByCodeAsync(
  207. FindRemedicalByCodeRequest(
  208. token: RPCBridge.ins.userToken,
  209. remedicalCode: remedicalCode,
  210. existDiagnosisResult: true,
  211. ),
  212. );
  213. }
  214. return result;
  215. } catch (e) {
  216. logger.e('MeasureHomeController getRemedicalInfo ex:', e);
  217. return null;
  218. }
  219. }
  220. ///获取测量项
  221. static Future<MeasureApplicationDTO?> getMeasureApplication(
  222. MeasureModeSelection args) async {
  223. try {
  224. return await RPCBridge.ins.rpc.remedical.getMeasureApplicationAsync(
  225. GetMeasureApplicationRequest(
  226. token: RPCBridge.ins.userToken,
  227. applicationName: args.applicationName,
  228. categoryName: args.categoryName,
  229. measureModes: args.measureModes,
  230. ),
  231. );
  232. } catch (e) {
  233. print(e);
  234. logger.e('MeasureHomeController getMeasureApplication ex: ', e);
  235. return null;
  236. }
  237. }
  238. /// 保存测量的方法
  239. static Future<bool> saveUserDefinedMeasureApplicationAsync(
  240. MeasureModeSubmit args) async {
  241. var result = false;
  242. try {
  243. result = await RPCBridge.ins.rpc.remedical
  244. .saveUserDefinedMeasureApplicationAsync(
  245. SaveUserDefinedMeasureApplicationRequest(
  246. token: RPCBridge.ins.userToken,
  247. version: args.version,
  248. applicationName: args.applicationName,
  249. categoryName: args.categoryName,
  250. workingMode: args.workingMode,
  251. ),
  252. );
  253. } catch (e) {
  254. logger.e(
  255. 'MeasureHomeController saveUserDefinedMeasureApplicationAsync ex: ',
  256. e);
  257. }
  258. return result;
  259. }
  260. /// 保存样式
  261. static Future<void> saveMeasureSystemSettingAsync(
  262. MeasureSystemSettingDTO measureSystemSetting,
  263. ) async {
  264. await RPCBridge.ins.rpc.remedical.saveMeasureSystemSettingAsync(
  265. SaveMeasureSystemSettingRequest(
  266. systemSetting: measureSystemSetting,
  267. token: RPCBridge.ins.userToken,
  268. ),
  269. );
  270. }
  271. /// 获取样式
  272. static Future<MeasureSystemSettingDTO> getMeasureSystemSettingAsync() async {
  273. final result =
  274. await RPCBridge.ins.rpc.remedical.getMeasureSystemSettingAsync(
  275. GetMeasureSystemSettingRequest(
  276. token: RPCBridge.ins.userToken,
  277. ),
  278. );
  279. return result;
  280. }
  281. /// 分享vid
  282. static Future<String> shareImage(
  283. String examFile,
  284. ) async {
  285. try {
  286. final result = await RPCBridge.ins.rpc.remedical.queryShareExamPageAsync(
  287. QueryShareExamPageRequest(
  288. examFileToken: examFile,
  289. token: RPCBridge.ins.userToken,
  290. languageCode: i18nBook.locale.toCodeString('-'),
  291. ),
  292. );
  293. return result.shareExamPageUrl ?? '';
  294. } catch (e) {
  295. logger.e("queryShareExamPageAsync exception:", e);
  296. }
  297. return '';
  298. }
  299. /// 获取注释
  300. static Future<CommentItemResultDTO?> getCommentsByApplicationAsync(
  301. String applicationName, String categoryName) async {
  302. try {
  303. if (RPCBridge.ins.source == VidImageSource.RemoteUS) {
  304. final result = await RPCBridge.ins.rpc.remoteUltrasound
  305. .vitalGetCommentsByApplicationAsync(
  306. GetCommentsByApplicationRequest(
  307. token: RPCBridge.ins.userToken,
  308. applicationName: applicationName,
  309. categoryName: categoryName,
  310. languageCode: i18nBook.locale.toCodeString('-'),
  311. ),
  312. );
  313. return result;
  314. } else {
  315. final result =
  316. await RPCBridge.ins.rpc.remedical.getCommentsByApplicationAsync(
  317. GetCommentsByApplicationRequest(
  318. token: RPCBridge.ins.userToken,
  319. applicationName: applicationName,
  320. categoryName: categoryName,
  321. languageCode: i18nBook.locale.toCodeString('-'),
  322. ),
  323. );
  324. return result;
  325. }
  326. } catch (e) {
  327. logger.e('MeasureHomeController getCommentsByApplicationAsync ex: ', e);
  328. return null;
  329. }
  330. }
  331. /// 保存注释
  332. static Future<bool?> saveUserDefinedCommentsAsync(
  333. String applicationName,
  334. String categoryName,
  335. List<CommentItemDTO>? addCommentItems,
  336. List<CommentItemDTO>? deleteCommentItems,
  337. List<UpdateCommentItemDTO>? updateCommentItems,
  338. ) async {
  339. try {
  340. final result =
  341. await RPCBridge.ins.rpc.remedical.saveUserDefinedCommentsAsync(
  342. SaveUserDefinedCommentsRequest(
  343. token: RPCBridge.ins.userToken,
  344. applicationName: applicationName,
  345. categoryName: categoryName,
  346. languageCode: i18nBook.locale.toCodeString('-'),
  347. // Store.app.systemLocale.languageCode.toLowerCase(),
  348. addCommentItems: addCommentItems,
  349. deletedCommentItems: deleteCommentItems,
  350. updateCommentItems: updateCommentItems),
  351. );
  352. return result;
  353. } catch (e) {
  354. logger.e('MeasureHomeController getCommentsByApplicationAsync ex: ', e);
  355. return null;
  356. }
  357. }
  358. /// 重置注释
  359. static Future<bool?> resetUserCommentsAsync(
  360. String applicationName,
  361. String categoryName,
  362. ) async {
  363. try {
  364. final result = await RPCBridge.ins.rpc.remedical.resetUserCommentsAsync(
  365. ResetUserCommentsRequest(
  366. token: RPCBridge.ins.userToken,
  367. applicationName: applicationName,
  368. categoryName: categoryName,
  369. ),
  370. );
  371. return result;
  372. } catch (e) {
  373. logger.e('MeasureHomeController resetUserCommentsAsync ex: ', e);
  374. return null;
  375. }
  376. }
  377. /// 获取预置的注释项
  378. static Future<PresetCommentItemResultDTO?> getPresetCommentsAsync() async {
  379. try {
  380. final result = await RPCBridge.ins.rpc.remedical.getPresetCommentsAsync(
  381. GetPresetCommentsRequest(
  382. token: RPCBridge.ins.userToken,
  383. languageCode: i18nBook.locale.toCodeString('-'),
  384. // Store.app.systemLocale.languageCode.toLowerCase(),
  385. ),
  386. );
  387. return result;
  388. } catch (e) {
  389. logger.e('MeasureHomeController getPresetCommentsAsync ex: ', e);
  390. return null;
  391. }
  392. }
  393. static Future<RemedicalInfoDTO?> getImageInfoByIndex(
  394. String recordCode, String token, String patientCode, int index) async {
  395. var imageList = await getRemedicalList(patientCode, recordCode);
  396. int imageIndex = 0;
  397. for (RemedicalItemList r in imageList) {
  398. for (RemedicalInfoDTO i in r.remedicalList ?? []) {
  399. imageIndex++;
  400. if (imageIndex == index) {
  401. return i;
  402. }
  403. }
  404. }
  405. return null;
  406. }
  407. }