import 'dart:async'; import 'dart:convert'; import 'package:fis_common/env/env.dart'; import 'package:fis_common/js_plateform/js_platform.dart'; import 'package:fis_common/logger/logger.dart'; import 'package:fis_i18n/i18n.dart'; import 'package:fis_jsonrpc/rpc.dart'; import 'package:fis_lib_report/report_info/report_info.dart'; import 'package:get/get.dart'; import 'package:universal_html/html.dart' as html; import 'package:crypto/crypto.dart'; import 'package:fis_ui/index.dart'; import 'package:fis_common/index.dart'; import 'package:vitalapp/architecture/memory_cache/report.dart'; import 'package:vitalapp/architecture/services/entity/report_editor_setting.dart'; import 'package:vitalapp/architecture/services/report_editor_configuration.dart'; import 'package:vitalapp/pages/report_edit/controller.dart'; import 'package:vitalapp/pages/report_edit/state.dart'; import 'package:vitalapp/rpc.dart'; import 'package:vitalapp/store/store.dart'; class ReportCacheController { late final ReportEditController controller; late final ReportEditState state; /// 本地报告编辑器持久化缓存服务 LocalReportEditorService localReportEditorService = Get.find(); ReportEditorSetting reportEditorSetting = ReportEditorSetting.ins; ///定时刷新缓存 Timer? _timer; /// 本地的报告草稿【json格式的文本持久化存储】 String _localReportCache = ''; ReportCacheController(ReportEditController controller) { this.controller = controller; this.state = controller.state; } ///从Server加载报告 Future initServerReport() async { final ReportDTO report = await rpc.ultrasoundReport.vitalFindReportByCodeAsync( FindReportByCodeRequest( token: Store.user.token, reportCode: state.reportCode, language: i18nBook.locale.toCodeString('-'), ), ); final serverTempalte = ReportTemplateDTO( reportTemplateName: report.reportTemplateName, reportTemplateCode: report.reportTemplateCode, reportTemplateJson: report.reportTemplateJson, ); var selectedTemplate = state.templates.firstWhereOrNull( (element) => element.value == report.reportTemplateCode); if (selectedTemplate != null) { state.selectedTemplate = serverTempalte; } else { state.templates.add(FSelectOptionModel( value: serverTempalte.reportTemplateCode, title: serverTempalte.reportTemplateName ?? '', )); state.selectedTemplate = serverTempalte; } if (report.reportTemplateJson == null || report.reportTemplateJson!.isEmpty) { controller.initUserDefaultTemplate(); } final jsonStr = report.reportDatasJson ?? ''; final List jsonItems = jsonDecode(jsonStr) as List; final measureJsonStr = report.reportMeasureDatasJson; if (measureJsonStr.isNotNullOrEmpty) { final measureJsonItems = jsonDecode(measureJsonStr!) as List; jsonItems.addAll(measureJsonItems); } await Future.delayed(Duration(milliseconds: 500), () { FReportInfo.instance.fromJson(jsonItems); }); return report; } /// 加载报告缓存 void initReportCache() { Future.delayed( Duration(milliseconds: 200), () async { if (state.reportCode.isNotEmpty) { String jsonStr; if (ReportCache.cache.keys.contains(state.reportCode)) { final reportCache = ReportCache.cache[state.reportCode]; jsonStr = reportCache!.reportInfoJson; } else { final reportInfo = await rpc.ultrasoundReport .vitalFindReportByCodeAsync(FindReportByCodeRequest( token: Store.user.token, reportCode: state.reportCode, )); jsonStr = reportInfo.reportDatasJson ?? ''; } if (jsonStr.isNotEmpty) { final json = jsonDecode(jsonStr) as List; FReportInfo.instance.fromJson(json); } } else { if (ReportCache.cache.keys.contains(state.recordCode)) { final reportCache = ReportCache.cache[state.recordCode]; controller.initReportInfoFromJson(reportCache!); } } }, ); } /// 启动自动缓存策略,每隔5秒缓存一次报告【不同于_updateReportCache,这里的缓存是指持久化到本地】 void setScheduledCacheReport() { // 如果已经存在定时器,先取消 if (_timer != null) { _timer!.cancel(); _timer = null; } final timeout = const Duration(seconds: 5); _timer = Timer.periodic(timeout, (timer) { _cacheReportToLocal(); }); } /// 移除自动缓存策略 void removeScheduledCacheReport() { if (_timer != null) { _cacheReportToLocal(); _timer!.cancel(); } } /// 本地持久化报告的草稿 /// 存草稿 写入本地缓存做持久化 void _cacheReportToLocal() async { FReportInfo.instance.toJson(); final reportInfoJson = jsonEncode(FReportInfo.instance.jsonItems); if (_getHash(reportInfoJson) != _getHash(_localReportCache)) { // print('♻️ 当前内容 hash 为 ${_getHash(reportInfoJson)} 更新本地缓存'); _localReportCache = reportInfoJson; reportEditorSetting.setReportDraft( reportInfoJson, state.selectedTemplate.reportTemplateCode ?? ''); String draftRecordCode = ''; if (state.recordCode.isNotEmpty) { draftRecordCode = state.recordCode; } else if (state.consultationCode.isNotEmpty) { draftRecordCode = state.consultationCode; } if (draftRecordCode.isNotEmpty) { reportEditorSetting.setReportDraftRecordCode(draftRecordCode); localReportEditorService.save(); } } else { // print('⛔ 当前内容 hash 为 ${_getHash(reportInfoJson)} 与本地缓存相同,不更新本地缓存'); } } /// 取hash值 Digest _getHash(String str) { return sha1.convert(utf8.encode(str)); } /// 更新报告缓存 void _updateReportCache() { FReportInfo.instance.toJson(); if (FReportInfo.instance.jsonItems.isNotEmpty) { if (state.reportCode.isNotEmpty) { ReportCache.cache[state.reportCode] = ReportInfoItem( jsonEncode(FReportInfo.instance.jsonItems), state.selectedTemplate.reportTemplateJson ?? ''); } else { final recordCode = state.recordCode; print(recordCode); ReportCache.cache[recordCode] = ReportInfoItem( jsonEncode(FReportInfo.instance.jsonItems), state.selectedTemplate.reportTemplateJson ?? ''); } } } /// 跟据检查 Code 更新报告缓存 void updateReportCacheByRecordCode(String recordCode) async { if (_timer != null) { _timer!.cancel(); } if (ReportCache.cache.containsKey(recordCode)) { ReportCache.cache.remove(recordCode); } } /// 返回上级页面 void back() { try { if (_timer != null) { _timer!.cancel(); } } catch (e) { print(e); logger.e('report back ex:', e); } } //根据缓存实例化报告信息 void initReportInfoFromJson(ReportInfoItem reportCache) { try { final jsonStr = reportCache.reportInfoJson; final templateJson = reportCache.reportTemplateJson; ///应缓存reportTemplateJson,初始化时就选择指定模板 if (state.selectedTemplate.reportTemplateJson != templateJson) { state.selectedTemplate.reportTemplateJson = templateJson; FReportInfo.instance.reload( Store.user.displayName, DateTime.now(), templateJson, controller.onSelect, i18nBook.common.revoke.t, i18nBook.remedical.selectWord.t, i18nBook.remedical.clickAndSelectImage.t, ); } final json = jsonDecode(jsonStr) as List; FReportInfo.instance.fromJson(json); } catch (e) { print(e); logger.e('ReportEditController _initReportInfoFromJson ex:', e); } } void dispose() { if (_timer != null) { _timer!.cancel(); _timer = null; } } }