controller.dart 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. import 'package:fis_common/env/env.dart';
  2. import 'package:fis_common/js_plateform/js_platform.dart';
  3. import 'package:fis_i18n/i18n.dart';
  4. import 'package:fis_jsonrpc/rpc.dart';
  5. import 'package:fis_lib_pdf/pdf_objects/report/report_helper/report_dic.dart';
  6. import 'package:fis_lib_report/converts/event_type.dart';
  7. import 'package:fis_lib_report/report_info/element_tag_names.dart';
  8. import 'package:fis_lib_report/report_info/input_text_info.dart';
  9. import 'package:fis_lib_report/report_info/report_info.dart';
  10. import 'package:fis_ui/index.dart';
  11. import 'package:flutter/foundation.dart';
  12. import 'package:get/get.dart';
  13. import 'package:intl/intl.dart';
  14. import 'package:universal_html/html.dart' as html;
  15. import 'package:fis_lib_pdf/ultils/pdf_type_enum.dart';
  16. import 'package:vitalapp/architecture/defines.dart';
  17. import 'package:vitalapp/architecture/storage/file_storage.dart';
  18. import 'package:vitalapp/architecture/utils/prompt_box.dart';
  19. import 'package:vitalapp/managers/interfaces/report.dart';
  20. import 'package:vitalapp/pages/report_edit/widgets/report_share_dialog.dart';
  21. import 'package:vitalapp/pages/report_preview/state.dart';
  22. import 'package:vitalapp/rpc.dart';
  23. import 'package:vitalapp/store/store.dart';
  24. import '../medical_checkup_station/registration/widgets/report/qrcode_report_share_dialog.dart';
  25. ///报告预览控制器
  26. class ReportPreviewController extends FControllerBase {
  27. ///报告预览控制器状态
  28. final state = ReportPreviewState();
  29. ///选中事件
  30. final FEventHandler<String> onSelect = new FEventHandler<String>();
  31. String? recordCode;
  32. ///是否来自编辑器
  33. static bool isFromEditor = false;
  34. ///报告图片列表
  35. static List<String> imageOrFileUrls = [];
  36. /// 载入类型
  37. static PDFTypeEnum pdfType =
  38. isFromEditor ? PDFTypeEnum.report : PDFTypeEnum.pdfJpeg;
  39. final fileStorage = FileStorage(directory: "remedical/report");
  40. String _patientName = "";
  41. String _recordCode = "";
  42. ReportDTO? reportDTO;
  43. Future<bool> shareReport() async {
  44. if (imageOrFileUrls.isEmpty) {
  45. PromptBox.toast('获取分享数据失败');
  46. }
  47. Get.dialog(
  48. QRCodeShareDialog(
  49. imageOrFileUrls.first,
  50. "",
  51. isQROnly: true,
  52. pageName: 'QRCodeShareDialog',
  53. ),
  54. );
  55. return true;
  56. }
  57. @override
  58. void onReady() {
  59. initDatas();
  60. super.onReady();
  61. }
  62. @override
  63. void dispose() {
  64. super.dispose();
  65. }
  66. ///初始化数据
  67. Future<void> initDatas() async {
  68. pdfType = isFromEditor ? PDFTypeEnum.report : PDFTypeEnum.pdfJpeg;
  69. imageOrFileUrls = [];
  70. Map parameters = Get.arguments ?? {};
  71. if (parameters.containsKey('reportCode')) {
  72. var reportCode = parameters['reportCode'] ?? '';
  73. state.reportCode = reportCode;
  74. }
  75. if (parameters.containsKey('isFromEditor')) {
  76. var isFromEditorStr = parameters['isFromEditor'] ?? '';
  77. if (isFromEditorStr == 'true') {
  78. isFromEditor = true;
  79. } else {
  80. isFromEditor = false;
  81. }
  82. }
  83. if (parameters.containsKey('recordCode')) {
  84. recordCode = parameters['recordCode'] ?? '';
  85. await _initPreviewReportByRecordCode(recordCode!);
  86. state.qualityType = reportDTO?.qualityType ?? QualityType.None;
  87. } else {
  88. state.isLoaded = true;
  89. }
  90. _generateReportName();
  91. }
  92. ///关闭PDF预览
  93. void onPDFClose() {
  94. Get.back();
  95. }
  96. Future<List<ReportDTO>> findExamReportsAsync(String recordCode) async {
  97. int retries = 0;
  98. while (retries < 5) {
  99. //最多重试5次
  100. try {
  101. print('findExamReportsAsync start');
  102. print("recordCode:" + recordCode);
  103. var reportInfo = await rpc.ultrasoundReport.vitalFindReportsAsync(
  104. FindReportsRequest(
  105. token: Store.user.token,
  106. recordCode: recordCode,
  107. languageCode: i18nBook.locale.toCodeString('-'),
  108. ),
  109. );
  110. print('findExamReportsAsync end');
  111. return reportInfo;
  112. } catch (e) {
  113. print('findExamReportsAsync rpc error:' + e.toString());
  114. retries++; //重试次数增加
  115. await Future.delayed(Duration(seconds: retries)); //等待时间逐渐增加
  116. }
  117. }
  118. return []; //最终返回[],因为已经达到最大尝试次数
  119. }
  120. Future<void> _initPreviewReportByRecordCode(String recordCode) async {
  121. try {
  122. busy = true;
  123. final reportCode = state.reportCode;
  124. var reportInfos = await findExamReportsAsync(recordCode);
  125. if (reportInfos.any((element) => element.reportCode == reportCode)) {
  126. reportDTO = reportInfos
  127. .firstWhere((element) => element.reportCode == reportCode);
  128. } else if (reportInfos.isNotEmpty) {
  129. reportDTO = reportInfos.last;
  130. }
  131. /// 从 _reportDTO 中获取编号、姓名,后续用于文件命名
  132. if (reportDTO != null) {
  133. _recordCode = reportDTO!.reportCode ?? '';
  134. _patientName = reportDTO!.patientName ?? '';
  135. } else {
  136. _recordCode = recordCode;
  137. }
  138. /// 如果没有 PDF file 那么从 _reportDTO 中获取图像列表
  139. var images = reportDTO?.reportPreviewList?.where(
  140. (element) => element.fileType == UploadFileTypeEnum.JPG) ??
  141. [];
  142. List<String> imageList = images.map((e) => e.fileToken ?? '').toList();
  143. for (var image in imageList) {
  144. if (image.contains(';')) {
  145. imageOrFileUrls
  146. .addAll(image.split(';').where((element) => element.isNotEmpty));
  147. } else {
  148. imageOrFileUrls.add(image);
  149. }
  150. }
  151. if (kIsMobile && imageOrFileUrls.isNotEmpty) {
  152. ///平板预览报告使用图像
  153. busy = false;
  154. // 此时会触发 reportImageList 进入 FPDFRenderContainer 的渲染逻辑(会做图像压缩,缓存)
  155. state.isLoaded = true;
  156. return;
  157. }
  158. var pdfFiles = reportDTO?.reportPreviewList?.where(
  159. (element) => element.fileType == UploadFileTypeEnum.PDF) ??
  160. [];
  161. List<String> pdfList = pdfFiles.map((e) => e.fileToken ?? '').toList();
  162. if (pdfList.isNotEmpty) {
  163. imageOrFileUrls.clear();
  164. pdfType = PDFTypeEnum.pdfBytes;
  165. for (var pdf in pdfList) {
  166. if (pdf.contains(';')) {
  167. imageOrFileUrls
  168. .addAll(pdf.split(';').where((element) => element.isNotEmpty));
  169. } else {
  170. imageOrFileUrls.add(pdf);
  171. }
  172. }
  173. }
  174. /// 设置报告文件名
  175. if (imageOrFileUrls.isNotEmpty) {
  176. String fileName = _generateReportFileNameWithReportInfo(reportDTO!);
  177. if (state.reportName == "") {
  178. state.reportName = fileName;
  179. }
  180. }
  181. } catch (e) {
  182. print(e);
  183. }
  184. busy = false;
  185. // 此时会触发 reportImageList 进入 FPDFRenderContainer 的渲染逻辑(会做图像压缩,缓存)
  186. state.isLoaded = true;
  187. }
  188. void _generateReportName() {
  189. var reportInfo = FReportInfo.instance;
  190. var inputTextInfo;
  191. String patientName = '';
  192. var patientElement =
  193. reportInfo.getElementInfoByTagName(TagNames.PATIENT_NAME_TAG);
  194. if (patientElement != null) {
  195. inputTextInfo = patientElement as InputTextInfo;
  196. patientName = inputTextInfo.text;
  197. } else {
  198. patientName = _patientName;
  199. }
  200. var creatTime =
  201. reportInfo.reportDate ?? reportDTO?.reportTime ?? DateTime.now();
  202. var reportCode = reportInfo.id ?? _recordCode;
  203. DateFormat format = DateFormat("yyyMMddHHmmss");
  204. var dateStr = format.format(creatTime);
  205. var fileName = "[$patientName]-[$dateStr]-[$reportCode].pdf";
  206. if (state.reportName == '') {
  207. state.reportName = fileName;
  208. }
  209. }
  210. String _generateReportFileNameWithReportInfo(ReportDTO reportDTO) {
  211. var patientName = reportDTO.patientName!.replaceAll("*", "x");
  212. DateFormat format = DateFormat("yyyMMddHHmmss");
  213. var dateStr = format.format(reportDTO.reportTime!.toLocal());
  214. var fileName = "[$patientName]-[$dateStr]-[${reportDTO.reportCode!}].pdf";
  215. return fileName;
  216. }
  217. }