import 'package:fis_common/index.dart'; import 'package:fis_i18n/i18n.dart'; import 'package:fis_lib_business_components/index.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:fis_ui/base_define/page.dart'; import 'package:fis_ui/index.dart'; import 'package:fis_jsonrpc/rpc.dart'; import 'package:vitalapp/managers/interfaces/models/image_report_list_params.dart'; import 'package:vitalapp/managers/interfaces/report.dart'; import 'package:vitalapp/pages/image_report_inner_view/widgets/expansion_panel.dart'; import 'package:fis_measure/process/workspace/rpc_bridge.dart'; import 'controller.dart'; import 'widgets/cloud_image_item.dart'; import 'widgets/icon_tab_list.dart'; import 'widgets/image_zoom_preview_plugin.dart'; import 'widgets/report_cards_view.dart'; class ImageReportInnerView extends GetView<ImagereportinnerviewController> implements FPage { @override String get pageName => 'ImageReportInnerView'; final double _verticalSpacing = 20.0; const ImageReportInnerView({Key? key, required this.args}) : super(key: key); /// 页面入参 final ImageReportListParams args; @override Widget build(BuildContext context) { return GetBuilder<ImagereportinnerviewController>( init: ImagereportinnerviewController(args), //tag: args.recordCode, dispose: (_) { print('ImagereportinnerviewController dispose'); }, id: MainViewId, builder: (_) { return Column( children: [ FSizedBox( height: _verticalSpacing, ), IconTabList( { i18nBook.remedical.cloudImageShort.t: Icons.cloud_outlined, i18nBook.measure.measureImageShort.t: Icons.straighten_outlined, i18nBook.remedical.checkReportShort.t: FIcons.report_a4, }, selectedValue: [ i18nBook.remedical.cloudImageShort.t, i18nBook.measure.measureImageShort.t, i18nBook.remedical.checkReportShort.t ][controller.selectedTabIndex], onPressed: (v) { controller.selectedTabIndex = v; if (v <= 1) { controller.loadImages(); } else { controller.loadReports(); } }, ), FExpanded(child: _buildGridView()), const FSizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () { if (controller.selectedTabIndex == 2) { controller.loadReports(); } else { controller.loadImages(); } }, style: ButtonStyle( fixedSize: MaterialStateProperty.all<Size>( Size(140, 25), ), ), child: FText(i18nBook.common.refresh.t), ), if (controller.isCanWriteReport) ...[ FSizedBox( width: 30, ), ElevatedButton( onPressed: () { controller.reportManager.openReportEdit( controller.patientCode, recordCode: controller.recordCode, referralRecordCode: controller.isReferral ? controller.recordCode : "", ); }, style: ButtonStyle( fixedSize: MaterialStateProperty.all<Size>( Size(140, 25), ), ), child: FText(i18nBook.remedical.writeReport.t), ), ], ], ), const FSizedBox(height: 8), ], ); }, ); } FWidget _buildGridView() { if (controller.selectedTabIndex == 0) { return _cloudImages(); } else if (controller.selectedTabIndex == 1) { return _buildAllMeasureImages(); } else { return FReportCardsView(); } } FWidget _cloudImages() { final decoration = BoxDecoration( border: Border.all( color: Colors.grey, width: 0.5, ), ); List<FWidget> normalChildren = []; List<FWidget> expansionPanelChildren = []; var remedicalItemList = controller.remedicalListResult?.remedicalItemList; if (remedicalItemList?.isNotEmpty ?? false) { for (var remedicalItem in remedicalItemList!) { var applicationCategory = controller.languageConfigManager .getApplicationLanguageValue( remedicalItem.applicationCategory ?? ''); var application = controller.languageConfigManager .getApplicationLanguageValue(remedicalItem.application ?? ''); if (remedicalItem.patientScanTypeDesc.isNotNullOrEmpty) { ///左颈动脉图像集合 var carotidLeftImages = remedicalItem.remedicalList ?.where((element) => element.carotidResult?.carotidScanType == CarotidScanTypeEnum.CarotidLeft) .toList() ?? []; ///右颈动脉图像集合 var carotidRightImages = remedicalItem.remedicalList ?.where((element) => element.carotidResult?.carotidScanType == CarotidScanTypeEnum.CarotidRight) .toList() ?? []; ///非颈动脉(或未识别左右颈)图像集合 var notCarotidImages = remedicalItem.remedicalList ?.where( (element) => ![ CarotidScanTypeEnum.CarotidRight, CarotidScanTypeEnum.CarotidLeft ].contains(element.carotidResult?.carotidScanType), ) .toList() ?? []; expansionPanelChildren.add( FExpansionPanel( body: FColumn( children: [ if (carotidLeftImages.isNotEmpty || carotidRightImages.isNotEmpty) ...[ _buildCarotidTabs(carotidLeftImages.isNotEmpty, carotidRightImages.isNotEmpty), ], if (controller.carotidVAS == CarotidScanTypeEnum.CarotidLeft && carotidLeftImages.isNotEmpty) ...[ FContainer( decoration: decoration, padding: EdgeInsets.all(5), margin: EdgeInsets.only(bottom: 5), child: _buildGridCloudImagesView(carotidLeftImages), ), ] else if (controller.carotidVAS == CarotidScanTypeEnum.CarotidRight && carotidRightImages.isNotEmpty) ...[ FContainer( decoration: decoration, padding: EdgeInsets.all(5), margin: EdgeInsets.only(bottom: 5), child: _buildGridCloudImagesView(carotidRightImages), ), ], _buildGridCloudImagesView( notCarotidImages, ), ], ), title: application.isNullOrEmpty ? applicationCategory : '$applicationCategory-$application', ), ); } else { normalChildren.add( _buildGridCloudImagesView(remedicalItem.remedicalList ?? []), ); } } } else { return _noDataWidget(); } return FListView( shrinkWrap: true, children: [...expansionPanelChildren, ...normalChildren], ); } FWidget _buildGridCloudImagesView(List<RemedicalInfoDTO> images) { if (images.isEmpty) { return FSizedBox(); } List<RemedicalInfoDTO> allCloudImages = controller.allCloudImages; return FGridView( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, ), shrinkWrap: true, children: images.map((imageInfo) { var result = CloudImageItem( allCloudImages.indexOf(imageInfo), imageInfo, onTap: () {}, onDoubleTap: () { _handleDoubleClick( imageInfo.terminalImages?.imageUrl ?? '', images.indexOf(imageInfo), imageInfo.remedicalCode ?? '', imageInfo.remedicalCode, ); }, description: '', //TODO(Loki):翻译 // translation_delegate_helper.translateDescription( // imageInfo.application, // imageInfo.applicationCategory, // ), isSelected: false, //imageWidth: 300, ); return result; }).toList(), ); } FWidget _noDataWidget() { return NoDataWidget(); } void _handleDoubleClick(String imageUrl, int index, String remedicalCode, String? remedicalAISelectedInfoCode) { final reportManager = Get.find<IReportManager>(); RPCBridge.ins.source = VidImageSource.Remedical; reportManager.enterVidMeasurePage( imageUrl: imageUrl, imageindex: index, remedicalCode: remedicalCode, patientCode: controller.patientCode, recordCode: controller.recordCode, remedicalAISelectedInfoCode: remedicalAISelectedInfoCode, ); } FWidget _buildIndex(int index) { return FPositioned( left: 15, top: 15, child: FText( (index + 1).toString(), style: TextStyle(color: Colors.white), ), ); } FWidget _buildAllMeasureImages() { if (controller.measureImages.isNotEmpty) { return FColumn( mainAxisAlignment: MainAxisAlignment.start, children: [ if (controller.measureImages.isNotEmpty) ...[ if (controller.isExpandMeasureImages) ...[ FContainer( constraints: BoxConstraints( maxHeight: Get.height * 0.9, ), margin: EdgeInsets.symmetric(horizontal: 10), color: Colors.grey[200], child: _buildMeasureImages(), ), ], ], ], ); } return _noDataWidget(); } FWidget _buildMeasureImages() { return FGridView( shrinkWrap: true, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, ), children: controller.measureImages .map( (imageInfo) => FStack( children: [ FPositioned( top: 0, bottom: 0, right: 0, left: 0, child: FContainer( margin: EdgeInsets.all(2), color: Colors.black, child: FImage.network(imageInfo.measuredFileToken ?? ''), ), ), _buildIndex(controller.measureImages.indexOf(imageInfo)), FPositioned( right: 15, top: 15, child: FImageZoomInPlugin( imageUrl: imageInfo.measuredFileToken, child: FIcon( Icons.zoom_in, color: Colors.white, size: 32, ), ), ), ], ), ) .toList(), ); } FWidget _buildCarotidTabs( bool carotidLeftIsNotEmpty, bool carotidRightIsNotEmpty) { return FContainer( margin: EdgeInsets.only(top: 5, left: 0), child: FRow( children: [ if (carotidLeftIsNotEmpty) ...[ _buildInkWell( CarotidScanTypeEnum.CarotidLeft, ), ], if (carotidRightIsNotEmpty) ...[ _buildInkWell( CarotidScanTypeEnum.CarotidRight, ) ], ], ), ); } FWidget _buildInkWell( CarotidScanTypeEnum carotidScanType, ) { final isChooseLeftCarotid = controller.carotidVAS == carotidScanType; final isLeftCarotid = carotidScanType == CarotidScanTypeEnum.CarotidLeft; return FInkWell( onTap: () { controller.carotidVAS = carotidScanType; controller.update([MainViewId]); }, child: FContainer( decoration: BoxDecoration( border: Border.all( width: 0.5, color: Colors.grey, ), color: isChooseLeftCarotid ? const Color(0xff2c77e5) : Colors.transparent, borderRadius: isLeftCarotid ? BorderRadius.only( topLeft: Radius.circular(4), ) : BorderRadius.only( topRight: Radius.circular(4), ), ), padding: EdgeInsets.symmetric( horizontal: 20, vertical: 5, ), child: FText( isLeftCarotid ? i18nBook.remedical.leftNeck.t : i18nBook.remedical.rightNeck.t, style: TextStyle( color: isChooseLeftCarotid ? Colors.white : Colors.black, ), ), ), ); } }