123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- import 'dart:convert';
- import 'package:fis_common/logger/logger.dart';
- import 'package:fis_jsonrpc/rpc.dart';
- import 'package:fis_measure/interfaces/process/workspace/exam_info.dart';
- import 'package:fis_measure/process/language/measure_language.dart';
- import 'package:fis_measure/process/workspace/measure_controller.dart';
- import 'package:fis_measure/process/workspace/measure_data_controller.dart';
- import 'package:fis_measure/process/workspace/measure_handler.dart';
- import 'package:fis_measure/view/measure/measure_images_bar.dart';
- export 'package:fis_lib_business_components/index.dart';
- import 'package:fis_ui/index.dart';
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- class MeasureImagesBar extends StatefulWidget implements FWidget {
- const MeasureImagesBar({
- Key? key,
- this.hasQualityControlPermission = false,
- }) : super(key: key);
- final bool hasQualityControlPermission;
- @override
- State<MeasureImagesBar> createState() => _MeasureImagesBarState();
- }
- class _MeasureImagesBarState extends State<MeasureImagesBar>
- with WidgetsBindingObserver {
- /// 图片滑动控制器
- ScrollController scrollController = ScrollController();
- /// 数据
- final measureData = Get.find<MeasureDataController>();
- /// 全部图片list
- final measureController = Get.find<MeasureController>();
- /// 当前可滑动的范围宽度
- late double width = 0;
- ///Listview item的宽度
- late double itemWidth = 160;
- /// 是否滑到最后
- bool _isEnd = false;
- /// 计算下标
- int _currentPage = 0;
- /// 左边能否滑动
- bool get isLeftCanScroll => _currentPage <= 0;
- /// 右边能否滑动
- bool get isRightCanScroll => _isEnd;
- /// 滑动区域的key值
- final GlobalKey globalKey = GlobalKey();
- double get devicePixelRatio =>
- kIsMobile ? 1 : MediaQuery.of(context).devicePixelRatio;
- ///当前分辨率下ListView里面的item个数
- int _itemsPerPage = 0;
- /// 图片左划事件
- void onLeftMoveImage() async {
- _currentPage--;
- await scrollController.animateTo(
- (160 * _currentPage * _itemsPerPage).toDouble(),
- duration: const Duration(milliseconds: 300),
- curve: Curves.linear,
- );
- }
- /// 图片右划事件
- void onRightMoveImage() async {
- if (!isRightCanScroll) {
- _currentPage++;
- await scrollController.animateTo(
- (160 * _currentPage * _itemsPerPage).toDouble(),
- duration: const Duration(milliseconds: 300),
- curve: Curves.linear,
- );
- }
- }
- @override
- Widget build(BuildContext context) {
- return LayoutBuilder(
- builder: (BuildContext context, BoxConstraints constraints) {
- return FContainer(
- height: 120 / devicePixelRatio,
- margin: EdgeInsets.symmetric(
- vertical: devicePixelRatio > 1.25
- ? 5
- : devicePixelRatio > 1
- ? 10
- : 15,
- ),
- child: FRow(
- children: [
- _buildImageListIcon(
- FIcons.fis_left_arrow,
- isLeftCanScroll,
- onLeftMoveImage,
- ),
- FExpanded(
- child: ScrollableImageList(
- scrollController: scrollController,
- globalKey: globalKey,
- remedicalList: measureData.remedicalList,
- hasQualityControlPermission:
- widget.hasQualityControlPermission,
- ),
- ),
- _buildImageListIcon(
- FIcons.fis_right_arrow,
- isRightCanScroll,
- onRightMoveImage,
- ),
- ],
- ),
- );
- },
- );
- }
- @override
- void didChangeMetrics() {
- width = globalKey.currentContext!.size!.width;
- print('width:$width,itemWidth:$itemWidth');
- _isEnd = width >= measureData.remedicalList.length * itemWidth;
- _itemsPerPage = (width / itemWidth).toInt();
- var currentIndex = measureController.examInfo.selectedImageIndex;
- if (currentIndex * itemWidth > scrollController.position.maxScrollExtent) {
- currentIndex = scrollController.position.maxScrollExtent ~/ itemWidth;
- }
- scrollController.animateTo(
- (itemWidth * currentIndex).toDouble(),
- duration: const Duration(milliseconds: 300),
- curve: Curves.linear,
- );
- setState(
- () {},
- );
- }
- @override
- void initState() {
- WidgetsBinding.instance.addObserver(this);
- scrollController.addListener(
- () async {
- // 如果滑动到最右边
- if (scrollController.position.pixels ==
- scrollController.position.maxScrollExtent) {
- setState(() {
- _isEnd = true;
- });
- } else {
- setState(
- () {
- _isEnd = false;
- },
- );
- }
- },
- );
- super.initState();
- }
- @override
- void didChangeDependencies() {
- super.didChangeDependencies();
- WidgetsBinding.instance.addPostFrameCallback(
- (mag) {
- width = globalKey.currentContext!.size!.width;
- setState(
- () {
- _isEnd = width >= measureData.remedicalList.length * itemWidth;
- _itemsPerPage = (width / itemWidth).toInt();
- var currentIndex = measureController.examInfo.selectedImageIndex;
- if (currentIndex * itemWidth >
- scrollController.position.maxScrollExtent) {
- currentIndex =
- scrollController.position.maxScrollExtent ~/ itemWidth;
- }
- scrollController.animateTo(
- (itemWidth * currentIndex).toDouble(),
- duration: const Duration(milliseconds: 300),
- curve: Curves.linear,
- );
- },
- );
- },
- );
- }
- @override
- void dispose() {
- WidgetsBinding.instance.removeObserver(this);
- super.dispose();
- }
- FWidget _buildImageListIcon(
- IconData iconsData, bool isCanClick, Function onIconTap) {
- return FInkWell(
- onTap: () => onIconTap.call(),
- child: FContainer(
- width: 100 / devicePixelRatio,
- child: FIcon(
- iconsData,
- color: isCanClick ? Colors.grey : Colors.white,
- size: 30 / devicePixelRatio,
- ),
- ),
- );
- }
- }
- /// 可滑动的图片组,显示当前测量组的所有图片
- class ScrollableImageList extends StatefulWidget implements FWidget {
- const ScrollableImageList({
- required this.scrollController,
- required this.globalKey,
- required this.remedicalList,
- this.hasQualityControlPermission = false,
- Key? key,
- this.description = '',
- }) : super(key: key);
- /// 图片滑动控制器
- final ScrollController scrollController;
- final GlobalKey globalKey;
- final List<RemedicalInfoDTO> remedicalList;
- final String? description;
- final bool hasQualityControlPermission;
- @override
- State<ScrollableImageList> createState() => _ScrollableImageListState();
- }
- class _ScrollableImageListState extends State<ScrollableImageList> {
- /// 当前测量的图片
- // final measureCurrentImage = Get.put(MeasureGetCurrentImage());
- double get devicePixelRatio =>
- kIsMobile ? 1 : MediaQuery.of(context).devicePixelRatio;
- /// 测量AI数据
- final measureData = Get.find<MeasureDataController>();
- MeasureController measureController = Get.find<MeasureController>();
- late final measureHandler = Get.put(MeasureHandler());
- /// 测量语言包
- final measureLanguage = MeasureLanguage();
- /// 图像数据列表
- List<RemedicalInfoDTO> remedicalList = [];
- /// 获取图片地址
- void onChangeImage(
- String imageUrl,
- String remedicalCode,
- ) async {
- final selectedIndex = measureController.examInfo.images.indexWhere(
- (element) => element.remedicalCode == remedicalCode,
- );
- if (selectedIndex < 0) {
- return;
- }
- if (measureData.itemCurrentImage == imageUrl &&
- measureController.examInfo.selectedImageIndex == selectedIndex) {
- return;
- }
- measureData.itemCurrentImage = imageUrl;
- // remedicalAISelectedInfoCode是因为选择ai编辑过的图片code和remedicalCode等级一样
- measureHandler.newImageLoading = true;
- measureData.measureInfoData = MeasureInfoData(
- patientCode: measureData.measureInfoData.patientCode,
- recordCode: measureData.measureInfoData.recordCode,
- remedicalCode: remedicalCode,
- remedicalAISelectedInfoCode: remedicalCode,
- );
- measureHandler.currSelectedImage = CurrImageInfo(
- imageUrl,
- remedicalCode,
- );
- measureController.examInfo.selectedImageIndex = selectedIndex;
- setState(() {});
- }
- /// 获取图像Code来更新图像
- void onChangeImageByRemedicalCode(_, String e) {
- final url = findImageUrlByRemedicalCode(e);
- onChangeImage(url, e);
- }
- /// 更新图像集合
- void onChangeImageList(_, e) {
- measureController = Get.find<MeasureController>();
- setState(() {
- remedicalList = e;
- });
- }
- String findImageUrlByRemedicalCode(String remedicalCode) {
- final item =
- remedicalList.firstWhere((e) => e.remedicalCode == remedicalCode);
- final imgInfo = item.terminalImages!;
- return measureData.chooseImageUrl(imgInfo);
- }
- @override
- void initState() {
- remedicalList = widget.remedicalList;
- measureHandler.changeImageByRemedicalCode
- .addListener(onChangeImageByRemedicalCode);
- measureHandler.changeImageList.addListener(onChangeImageList);
- super.initState();
- }
- @override
- void dispose() {
- measureHandler.changeImageByRemedicalCode
- .removeListener(onChangeImageByRemedicalCode);
- measureHandler.changeImageList.removeListener(onChangeImageList);
- super.dispose();
- }
- @override
- FWidget build(BuildContext context) {
- return FContainer(
- key: ValueKey(measureData.itemCurrentImage),
- alignment: Alignment.topCenter,
- child: _buildImageList(remedicalList),
- );
- }
- ///翻译图片描述
- String _translateDescription(RemedicalInfoDTO remedicalInfo) {
- String description = '';
- try {
- if (remedicalInfo.application != null) {
- //判断是否是老数据,老数据里面没有applicationCategory的字段
- if (remedicalInfo.applicationCategory != null) {
- //如果不是老数据
- description = _getDescription(
- remedicalInfo.application ?? '',
- remedicalInfo.applicationCategory ?? '',
- );
- } else {
- //如果是老数据
- description = "Old data";
- }
- }
- } on Exception catch (e) {
- logger.e("Picture translation exception" + e.toString());
- } catch (e) {
- logger.e("Picture translation exception" + e.toString());
- }
- return description;
- }
- /// 翻译图片位置的描述
- String _translateLocationDescription(RemedicalInfoDTO remedicalInfo) {
- String description = '';
- try {
- description = _getLocationDescription(
- remedicalInfo.imageLocation?.quadrant,
- remedicalInfo.imageLocation?.position);
- } on Exception catch (e) {
- logger.e("Picture translation exception" + e.toString());
- } catch (e) {
- logger.e("Picture translation exception" + e.toString());
- }
- return description;
- }
- /// 获取翻译值
- String _getLanguageValue(String type, String code) {
- return measureLanguage.t(type, code);
- }
- String _getDescription(String application, String applicationCategory) {
- String description = '';
- if ([application, applicationCategory].contains('FromSonopost')) {
- description = _getLanguageValue('application', 'FromSonopost');
- } else {
- if (application.isNotEmpty || applicationCategory.isNotEmpty) {
- description = _getLanguageValue('application', applicationCategory) +
- "-" +
- _getLanguageValue('application', application);
- } else {
- description = '';
- }
- }
- return description;
- }
- String _getLocationDescription(String? quadrant, String? position) {
- String description = '';
- if (quadrant != '' || quadrant != '') {
- description = _getLanguageValue('location', quadrant ?? '') +
- "-" +
- _getLanguageValue('location', position ?? '');
- } else {
- description = '';
- }
- return description;
- }
- FWidget _buildImageList(List<RemedicalInfoDTO> remedicalItemList) {
- var currentIndex = measureController.examInfo.selectedImageIndex;
- return FContainer(
- key: widget.globalKey,
- child: FListView.builder(
- scrollDirection: Axis.horizontal,
- shrinkWrap: true,
- controller: widget.scrollController,
- itemCount: remedicalItemList.toList().length,
- itemBuilder: (BuildContext context, int index) {
- final item = remedicalItemList[index];
- FWidget image = FContentImage(
- remedicalInfo: item,
- isMeasure: true,
- onTap: () {
- final code = item.remedicalCode!;
- final url = findImageUrlByRemedicalCode(code);
- onChangeImage(url, code);
- },
- serialNo: index + 1,
- description: _translateDescription(item),
- locationDescription: _translateLocationDescription(item),
- isQualityControlled:
- widget.hasQualityControlPermission && item.isQualityControlled,
- );
- bool isCurrentSelect = index == currentIndex;
- return FContainer(
- key: ValueKey(measureData.itemCurrentImage),
- width: 160 / devicePixelRatio,
- alignment: Alignment.center,
- decoration: BoxDecoration(
- border: Border.all(
- width: 3,
- color: isCurrentSelect ? Colors.blue : Colors.grey,
- ),
- ),
- child: image,
- );
- },
- ),
- );
- }
- }
|