瀏覽代碼

fix(measure): 注释面板添加拖拽删除功能 #0009566 Review by loki

gavin.chen 2 年之前
父節點
當前提交
1746fa61f7

+ 11 - 2
lib/measure_page_test.dart

@@ -78,8 +78,16 @@ class MeasureDataTester {
     return null;
   }
 
-  static Future<bool?> saveUserDefinedCommentsAsync(String applicationName,
-      String categoryName, List<CommentItemDTO> commentItems) async {
+  static Future<PresetCommentItemResultDTO?> getPresetCommentsAsync() async {
+    return null;
+  }
+
+  static Future<bool?> saveUserDefinedCommentsAsync(
+      String applicationName,
+      String categoryName,
+      List<CommentItemDTO>? add,
+      List<CommentItemDTO>? delete,
+      List<UpdateCommentItemDTO>? update) async {
     return null;
   }
 }
@@ -123,6 +131,7 @@ class _MeasureTestPageState extends State<MeasureTestPage> {
     MeasureDataTester.shareImage,
     MeasureDataTester.getCommentsByApplicationAsync,
     MeasureDataTester.saveUserDefinedCommentsAsync,
+    MeasureDataTester.getPresetCommentsAsync,
   ));
   final measureHandler = Get.put(MeasureHandler());
   final controller = Get.put<IMeasureController>(MeasureController(

+ 132 - 18
lib/process/workspace/measure_data_controller.dart

@@ -1,10 +1,14 @@
 import 'dart:typed_data';
 
 import 'package:fis_common/event/event_type.dart';
+import 'package:fis_i18n/i18n.dart';
 import 'package:fis_jsonrpc/rpc.dart';
 import 'package:fis_measure/interfaces/process/items/item_metas.dart';
+import 'package:fis_measure/interfaces/process/workspace/application.dart';
 import 'package:fis_measure/process/workspace/measure_handler.dart';
+import 'package:fis_measure/utils/prompt_box.dart';
 import 'package:fis_measure/view/measure/measure_config/measure_configuation_page.dart';
+import 'package:get/get.dart';
 import 'package:vid/us/vid_us_mode.dart';
 
 class MeasureImageData {
@@ -73,10 +77,18 @@ abstract class IMeasureDataController {
   List<ItemMeta> get curItemMetaList;
   set curItemMetaList(List<ItemMeta> value);
 
-  /// 注释工具list
+  /// 当前所有的注释项
   List<String> get annotationList;
   set annotationList(List<String> value);
 
+  /// 所有的预置的注释项
+  PresetCommentItemResultDTO get allPresetAnnotationList;
+  set allPresetAnnotationList(PresetCommentItemResultDTO value);
+
+  /// 当前模式下预置的注释项
+  List<String> get currPresetAnnotationList;
+  set currPresetAnnotationList(List<String> value);
+
   /// 注释List
   List<CommentItemDTO> get measureCommentItemResult;
   set measureCommentItemResult(List<CommentItemDTO> value);
@@ -120,7 +132,10 @@ class MeasureDataController implements IMeasureDataController {
   List<VidUsMode> _applicationModes = [];
   List<MeasureModeDTO> _availableModes = [];
   List<ItemMeta> _curItemMetaList = [];
-  List<String> _getAnnotationList = [];
+  List<String> _annotationList = [];
+  List<String> _presetAnnotationList = [];
+  PresetCommentItemResultDTO _allPresetAnnotationList =
+      PresetCommentItemResultDTO();
   List<CommentItemDTO> _measureCommentItemResult = [];
   List<ItemMetaGroup> _itemMetaListGroup = [];
   @override
@@ -174,15 +189,34 @@ class MeasureDataController implements IMeasureDataController {
   }
 
   @override
-  List<String> get annotationList => _getAnnotationList;
+  List<String> get annotationList => _annotationList;
   @override
   set annotationList(List<String> value) {
-    if (value != _getAnnotationList) {
-      _getAnnotationList = value;
+    if (value != _annotationList) {
+      _annotationList = value;
       _onGetCommentsListChanged();
     }
   }
 
+  @override
+  List<String> get currPresetAnnotationList => _presetAnnotationList;
+  @override
+  set currPresetAnnotationList(List<String> value) {
+    if (value != _presetAnnotationList) {
+      _presetAnnotationList = value;
+    }
+  }
+
+  @override
+  PresetCommentItemResultDTO get allPresetAnnotationList =>
+      _allPresetAnnotationList;
+  @override
+  set allPresetAnnotationList(PresetCommentItemResultDTO value) {
+    if (value != _allPresetAnnotationList) {
+      _allPresetAnnotationList = value;
+    }
+  }
+
   @override
   List<CommentItemDTO> get measureCommentItemResult =>
       _measureCommentItemResult;
@@ -332,17 +366,50 @@ class MeasureDataController implements IMeasureDataController {
   }
 
   MeasureDataController(
-    this.getRemedicalList,
-    this.getImageInfo,
-    this.getMeasureApplication,
-    this.saveUserDefinedMeasureApplicationAsync,
-    this.saveImage,
-    this.saveMeasureSystemSettingAsync,
-    this.getMeasureSystemSettingAsync,
-    this.shareImage,
-    this.getCommentsByApplicationAsync,
-    this.saveUserDefinedCommentsAsync,
-  );
+      this.getRemedicalList,
+      this.getImageInfo,
+      this.getMeasureApplication,
+      this.saveUserDefinedMeasureApplicationAsync,
+      this.saveImage,
+      this.saveMeasureSystemSettingAsync,
+      this.getMeasureSystemSettingAsync,
+      this.shareImage,
+      this.getCommentsByApplicationAsync,
+      this.saveUserDefinedCommentsAsync,
+      this.getPresetCommentsAsync,
+      {this.needInitAnnotation = false}) {
+    _init();
+  }
+  _init() async {
+    if (needInitAnnotation) {
+      // TODO:[Gavin] 初始化时获取所有注释
+      // _initPresetAnnotation();
+    }
+  }
+
+  // 初始化预设注释
+  void _initPresetAnnotation() async {
+    var result = await getPresetCommentsAsync();
+    if (result != null) {
+      _allPresetAnnotationList = result;
+    }
+  }
+
+  void _getPresetAnnotationByCategoryName(String categoryName) {
+    // TODO:[Gavin] 根据分类名称、应用名 获取预设注释【大概率不走这套方案、暂时留着】
+    _presetAnnotationList = [];
+    _allPresetAnnotationList.presetCommentItems?.forEach((element) {
+      element.categoryList?.forEach((category) {
+        if (category == categoryName) {
+          if (element.text is String) {
+            _presetAnnotationList.add(element.text!);
+          }
+        }
+      });
+    });
+  }
+
+  bool needInitAnnotation;
 
   ///参数1:patientCode,参数2:recordCode,参数3:token
   Future<List<RemedicalItemList>> Function(String, String, String)
@@ -375,8 +442,55 @@ class MeasureDataController implements IMeasureDataController {
   Future<CommentItemResultDTO?> Function(String, String)
       getCommentsByApplicationAsync;
 
-  Future<bool?> Function(String, String, List<CommentItemDTO>)
-      saveUserDefinedCommentsAsync;
+  /// 获取预置的注释项
+  Future<PresetCommentItemResultDTO?> Function() getPresetCommentsAsync;
+
+  Future<bool?> Function(
+      String,
+      String,
+      List<CommentItemDTO>?,
+      List<CommentItemDTO>?,
+      List<UpdateCommentItemDTO>?) saveUserDefinedCommentsAsync;
+
+  /// 添加注释项
+  Future<bool?> addAnnotation(
+      IApplication application, String annotationName) async {
+    final result = await saveUserDefinedCommentsAsync(
+        application.applicationName,
+        application.categoryName,
+        [CommentItemDTO(text: annotationName)],
+        null,
+        null);
+    return result;
+  }
+
+  /// 删除注释项
+  Future<bool?> deleteAnnotation(
+      IApplication application, String annotationName) async {
+    final result = await saveUserDefinedCommentsAsync(
+        application.applicationName,
+        application.categoryName,
+        null,
+        [CommentItemDTO(text: annotationName)],
+        null);
+    return result;
+  }
+
+  /// 更新注释项
+  Future<bool?> updateAnnotation(IApplication application,
+      String oldAnnotationName, String newAnnotationName) async {
+    final result = await saveUserDefinedCommentsAsync(
+      application.applicationName,
+      application.categoryName,
+      null,
+      null,
+      [
+        UpdateCommentItemDTO(
+            oldText: oldAnnotationName, newText: newAnnotationName)
+      ],
+    );
+    return result;
+  }
 
   void _onRemedicalListChanged() {
     remedicalListResultChanged.emit(this, remedicalList);

+ 6 - 0
lib/process/workspace/measure_handler.dart

@@ -69,6 +69,9 @@ abstract class IMeasureHandler {
   /// 注释箭头还是标签
   late FEventHandler<AnnotationType> onChangedAnnotationType;
 
+  /// 拖拽状态发生改变
+  late FEventHandler<bool> onDragStateChanged;
+
   /// 图片加载loadding
   late FEventHandler<bool> onChangeImageLoaded;
 
@@ -139,6 +142,9 @@ class MeasureHandler implements IMeasureHandler {
 
   @override
   var onChangedAnnotationType = FEventHandler<AnnotationType>();
+  @override
+  var onDragStateChanged = FEventHandler<bool>();
+
   @override
   FEventHandler<bool> onChangeImageLoaded = FEventHandler<bool>();
 

+ 82 - 0
lib/view/measure/drag_delete_area.dart

@@ -0,0 +1,82 @@
+import 'package:fis_i18n/i18n.dart';
+import 'package:fis_measure/interfaces/process/workspace/application.dart';
+import 'package:fis_measure/process/workspace/measure_data_controller.dart';
+import 'package:fis_measure/utils/prompt_box.dart';
+import 'package:fis_ui/index.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+
+class DragDeleteArea extends FStatefulWidget {
+  const DragDeleteArea({Key? key}) : super(key: key);
+  @override
+  FState<DragDeleteArea> createState() => DragDeleteAreaState();
+}
+
+class DragDeleteAreaState extends FState<DragDeleteArea> {
+  final measureData = Get.find<MeasureDataController>();
+  bool _isDragOn = false;
+
+  @override
+  void initState() {
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    super.dispose();
+  }
+
+  @override
+  FWidget build(BuildContext context) {
+    return FDragTarget<String>(
+      onAccept: (data) async {
+        measureData.annotationList.remove(data);
+        final application = Get.find<IApplication>();
+        final result = await measureData.deleteAnnotation(application, data);
+        if (result ?? false) {
+          PromptBox.toast(i18nBook.measure.annotationDeleted.translate([data]));
+        }
+      },
+      onWillAccept: (data) {
+        setState(() {
+          _isDragOn = true;
+        });
+        return true;
+      },
+      onLeave: (data) {
+        setState(() {
+          _isDragOn = false;
+        });
+      },
+      builder: (context, candidateData, rejectedData) {
+        return FContainer(
+          width: 300,
+          height: 50,
+          padding: const EdgeInsets.only(left: 10, top: 5, bottom: 5),
+          child: FContainer(
+            decoration: BoxDecoration(
+              color: const Color.fromARGB(255, 243, 108, 99),
+              borderRadius: BorderRadius.circular(5),
+            ),
+            child: FCenter(
+              child:
+                  FRow(mainAxisAlignment: MainAxisAlignment.center, children: [
+                const FIcon(
+                  Icons.delete,
+                  color: Colors.white,
+                ),
+                FText(
+                  _isDragOn
+                      ? i18nBook.measure.releaseToDelete.t
+                      : i18nBook.measure.dragHereToDelete.t,
+                  textAlign: TextAlign.center,
+                  style: const TextStyle(color: Colors.white),
+                ),
+              ]),
+            ),
+          ),
+        );
+      },
+    );
+  }
+}

+ 10 - 0
lib/view/measure/measure_left_annotation.dart

@@ -98,8 +98,18 @@ class _MeasureLeftAnnotationState extends State<MeasureLeftAnnotation> {
             ),
             onDragStarted: () {
               measureHandler.changedAnnotationType = AnnotationType.label;
+              measureHandler.onDragStateChanged.emit(this, true);
               application.switchAnnotation(AnnotationType.label, tools);
             },
+            onDragEnd: (details) {
+              measureHandler.onDragStateChanged.emit(this, false);
+            },
+            onDragCompleted: () {
+              measureHandler.onDragStateChanged.emit(this, false);
+            },
+            onDraggableCanceled: (velocity, offset) {
+              measureHandler.onDragStateChanged.emit(this, false);
+            },
           ),
         ),
         const FSizedBox(

+ 4 - 5
lib/view/measure/measure_search_input.dart

@@ -30,7 +30,7 @@ class _LeftSelectInputState extends FState<LeftSelectInput> {
 
   String annotationItem = '';
 
-  /// 注释获取
+  /// 添加操作后更新注释
   void getAnnotationList() async {
     List<String> annotationList = [];
     var measureCommentItemResult =
@@ -73,10 +73,9 @@ class _LeftSelectInputState extends FState<LeftSelectInput> {
                   if (annotationItem.isEmpty) {
                     PromptBox.toast(i18nBook.measure.AddCcomment.t);
                   } else {
-                    var result = await measureData.saveUserDefinedCommentsAsync(
-                      application.applicationName,
-                      application.categoryName,
-                      [CommentItemDTO(text: annotationItem)],
+                    var result = await measureData.addAnnotation(
+                      application,
+                      annotationItem,
                     );
                     if (result ?? false) {
                       measureHandler.changedTab = TabEnum.tabMeasureTool;

+ 19 - 1
lib/view/measure/measure_view.dart

@@ -12,7 +12,9 @@ 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/process/workspace/measure_3d_view_controller.dart';
+import 'package:fis_measure/utils/prompt_box.dart';
 import 'package:fis_measure/view/gesture/positioned_cursor.dart';
+import 'package:fis_measure/view/measure/drag_delete_area.dart';
 import 'package:fis_measure/view/measure/measure_config/widgets/measure_configuration_style.dart';
 import 'package:fis_measure/view/measure/measure_images_bar.dart';
 import 'package:fis_measure/view/measure/measure_left_annotation.dart';
@@ -421,6 +423,9 @@ class _MeasureLeftBoardState extends State<_MeasureLeftBoard> {
   /// 是否显示测量项
   bool hideMeasureItems = false;
 
+  /// 是否正在拖拽
+  bool isDragging = false;
+
   bool isMeasureTool = true;
   bool get isArrowMeasureAnnotationType =>
       measureHandler.changedAnnotationType == AnnotationType.arrow;
@@ -448,12 +453,20 @@ class _MeasureLeftBoardState extends State<_MeasureLeftBoard> {
     });
   }
 
+  /// 拖拽状态发生改变
+  _onDragStateChanged(Object sender, bool e) {
+    setState(() {
+      isDragging = e;
+    });
+  }
+
   @override
   void initState() {
     measureHandler.onChangedTab.addListener(_onChangedTab);
     measure3DViewController.updatePlayerMode.addListener(_onModeChanged);
     measureData.curItemMetaListChanged.addListener(_onCurItemMetaListChanged);
     measureHandler.onChangeImageLoaded.addListener(_onChangeImage);
+    measureHandler.onDragStateChanged.addListener(_onDragStateChanged);
     super.initState();
   }
 
@@ -464,6 +477,7 @@ class _MeasureLeftBoardState extends State<_MeasureLeftBoard> {
     measureData.curItemMetaListChanged
         .removeListener(_onCurItemMetaListChanged);
     measureHandler.onChangeImageLoaded.removeListener(_onChangeImage);
+    measureHandler.onDragStateChanged.removeListener(_onDragStateChanged);
     super.dispose();
   }
 
@@ -551,7 +565,11 @@ class _MeasureLeftBoardState extends State<_MeasureLeftBoard> {
           ),
         ),
         FOffstage(
-            offstage: hideMeasureItems || hideCommentTab,
+          offstage: hideMeasureItems || hideCommentTab || !isDragging,
+          child: const DragDeleteArea(),
+        ),
+        FOffstage(
+            offstage: hideMeasureItems || hideCommentTab || isDragging,
             child: _MeasureArrow()),
         FOffstage(
           offstage: !hideMeasureItems,

+ 1 - 1
pubspec.yaml

@@ -96,7 +96,7 @@ dependency_overrides:
   fis_i18n:
     git:
       url: http://git.ius.plus:88/Project-Wing/fis_lib_i18n.git
-      ref: e2016d4
+      ref: dfc63b7
   fis_jsonrpc:
     git:
       url: http://git.ius.plus:88/Project-Wing/fis_lib_jsonrpc.git