Explorar el Código

新增对输入框和单选框的数据驱动

loki.wu hace 2 años
padre
commit
442d04ff18

+ 4 - 0
lib/main.dart

@@ -90,6 +90,10 @@ class _MyHomePageState extends State<MyHomePage> {
                 reportDate: DateTime.now(),
                 jsonStr: _jsonStr,
                 onSelect: onSelect,
+                patinentAge: '22',
+                patinentId: '20220705',
+                patinentName: 'name',
+                patinentSex: '男',
               ),
             ),
           const SizedBox(width: 40),

+ 1 - 0
lib/pages/components/input_imageList.dart

@@ -110,6 +110,7 @@ class _RInputImageListState extends State<RInputImageList> {
               (PtToPxConverter.ptToPx(inputImageList!.imageHeight!) + 3) +
           6;
       return GridView.builder(
+        controller: ScrollController(),
         gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
           crossAxisCount: inputImageList!.column!,
           crossAxisSpacing: 5,

+ 11 - 1
lib/pages/components/input_text.dart

@@ -47,6 +47,11 @@ class _RInputTextState extends State<RInputText> {
     final inputTextInfo = ReportInfo.instance.getElementInfo(widget.inputText);
     if (_inputTextInfo != inputTextInfo) {
       _inputTextInfo = inputTextInfo as InputTextInfo;
+      _inputTextInfo!.onTextChange.addListener((sender, e) {
+        setState(() {
+          _controller.text = e;
+        });
+      });
     }
     if (!_inputTextInfo!.isListening!) {
       _initDatas();
@@ -54,7 +59,7 @@ class _RInputTextState extends State<RInputText> {
     }
     try {
       if (_inputTextInfo!.text != _controller.text) {
-        _controller.text = _inputTextInfo!.text!;
+        _controller.text = _inputTextInfo!.text;
         if (_inputTextInfo!.isReadOnly! &&
             _inputTextInfo!.tag!.name == 'ReportPhysician') {
           _controller.text = ReportInfo.instance.reporter ?? '';
@@ -144,6 +149,11 @@ class _RInputTextState extends State<RInputText> {
     _isReadOnly = inputText.isReadOnly!;
     final inputTextInfo = ReportInfo.instance.getElementInfo(inputText);
     _inputTextInfo = inputTextInfo as InputTextInfo;
+    _inputTextInfo!.onTextChange.addListener((sender, e) {
+      setState(() {
+        _controller.text = e;
+      });
+    });
     if (_inputTextInfo!.isReadOnly!) {
       if (_inputTextInfo!.tag!.name == 'ReportPhysician') {
         _controller.text = ReportInfo.instance.reporter ?? '';

+ 5 - 1
lib/pages/components/single_select.dart

@@ -33,6 +33,11 @@ class _RSingleSelectState extends State<RSingleSelected> {
     final selectInfo = ReportInfo.instance.getElementInfo(singleSelected);
     if (selectInfo != null && _singleSelectedInfo != selectInfo) {
       _singleSelectedInfo = selectInfo as SingleSelectedInfo;
+      _singleSelectedInfo!.onSelectedChange.addListener((sender, e) {
+        if (_singleSelectedInfo!.items!.contains(e)) {
+          _value = _singleSelectedInfo!.selectedItem;
+        }
+      });
     }
     if (singleSelected.items!.isNotEmpty) {
       _items = singleSelected.items;
@@ -42,7 +47,6 @@ class _RSingleSelectState extends State<RSingleSelected> {
     }
     var buttonDecoration = BoxDecoration(
       border: Border.all(color: Colors.grey, width: 0.8),
-      // border: Border.all(color: Colors.grey[200]!, width: 0.5),
       borderRadius: BorderRadius.circular(0),
       color: Colors.white,
     );

+ 2 - 3
lib/pages/rt_table.dart

@@ -43,7 +43,7 @@ class _RTTableState extends State<RTTablePage> {
     for (int i = 0; i < _row! - 1; i++) {
       final children = _cells!.keys.where((element) => element.row! == i);
       List<Widget> childwidgets = [];
-      children.forEach((cellPostion) {
+      for (var cellPostion in children) {
         double width =
             widget.element.columnDefinitions![cellPostion.column!].width ?? 0.0;
         if (cellPostion.columnSpan! > 1) {
@@ -105,10 +105,9 @@ class _RTTableState extends State<RTTablePage> {
             ),
           ),
         );
-      });
+      }
       final row = SizedBox(
         child: Row(
-          //mainAxisAlignment: MainAxisAlignment.center,
           children: childwidgets,
         ),
       );

+ 14 - 1
lib/report_edit.dart

@@ -16,6 +16,10 @@ class ReportEditPage extends StatefulWidget {
     required this.jsonStr,
     required this.reportDate,
     required this.onSelect,
+    this.patinentAge,
+    this.patinentName,
+    this.patinentSex,
+    this.patinentId,
     this.isReload = true,
   }) : super(key: key);
 
@@ -23,6 +27,10 @@ class ReportEditPage extends StatefulWidget {
 
   final String jsonStr;
   final String reporter;
+  final String? patinentName;
+  final String? patinentId;
+  final String? patinentSex;
+  final String? patinentAge;
   final DateTime reportDate;
   bool isReload;
 
@@ -71,6 +79,7 @@ class _ReportEditPageState extends State<ReportEditPage> {
         width: _width,
         color: Colors.white,
         child: ListView(
+          controller: ScrollController(),
           children: [
             ..._header.map((head) {
               return Container(
@@ -135,7 +144,11 @@ class _ReportEditPageState extends State<ReportEditPage> {
     setState(() {
       final template = ReportTemplateDocument.fromJson(reportMap);
       _reportTemplate = template;
-      ReportInfo.instance.init(_reportTemplate, reportDate, reporter);
+      ReportInfo.instance.init(_reportTemplate, reportDate, reporter,
+          patientName: widget.patinentName,
+          patientAge: widget.patinentAge,
+          patientSex: widget.patinentSex,
+          patinentId: widget.patinentId);
       _initPage();
     });
     if (args != null) {

+ 13 - 0
lib/report_info/element_tag_names.dart

@@ -0,0 +1,13 @@
+class TagNames {
+  /// 病人名输入框Tag
+  static const String PATIENT_NAME_TAG = "PatientName";
+
+  ///病人性别
+  static const String PATIENT_SEX_TAG = "PatientGender";
+
+  ///病人年龄
+  static const String PATIENT_AGE_TAG = "PatientAge";
+
+  ///病人ID
+  static const String PATIENT_ID_TAG = "PatientId";
+}

+ 15 - 4
lib/report_info/input_text_info.dart

@@ -1,14 +1,25 @@
+import 'package:fis_lib_report/converts/event_type.dart';
 import 'package:fis_lib_report/report/inputText.dart';
-import 'package:fis_lib_report/report/interfaces/element.dart';
-import 'package:fis_lib_report/report/interfaces/inputText.dart';
-import 'package:fis_lib_report/report/text_element.dart';
 import 'package:fis_lib_report/report_info/text_element_info.dart';
 
 class InputTextInfo extends TextElementInfo {
+  ///是否只读
   bool? isReadOnly;
+
+  ///当前输入框是否处于输入状态
   bool? isListening;
 
-  String? text;
+  ///UI绑定的文本
+  String get text => _text ?? '';
+  set text(String v) {
+    _text = v;
+    onTextChange.emit(this, v);
+  }
+
+  ///文本改变通知UI变化
+  FEventHandler<String> onTextChange = FEventHandler<String>();
+
+  String? _text;
 
   InputTextInfo.fromElement(InputText element) : super.fromElement(element) {
     isReadOnly = element.isReadOnly;

+ 147 - 18
lib/report_info/report_info.dart

@@ -1,3 +1,5 @@
+import 'dart:html';
+
 import 'package:fis_lib_report/converts/event_type.dart';
 import 'package:fis_lib_report/report/element_tag.dart';
 import 'package:fis_lib_report/report/element_type.dart';
@@ -10,10 +12,13 @@ import 'package:fis_lib_report/report/rt_page_size.dart';
 import 'package:fis_lib_report/report/rt_table.dart';
 import 'package:fis_lib_report/report_info/block_element_info_interface.dart';
 import 'package:fis_lib_report/report_info/element_info.dart';
+import 'package:fis_lib_report/report_info/element_tag_names.dart';
 import 'package:fis_lib_report/report_info/input_image_info.dart';
 import 'package:fis_lib_report/report_info/input_image_list_info.dart';
+import 'package:fis_lib_report/report_info/input_text_info.dart';
 import 'package:fis_lib_report/report_info/paragraph_info.dart';
 import 'package:fis_lib_report/report_info/rt_table_info.dart';
+import 'package:fis_lib_report/report_info/single_selected_info.dart';
 
 class ReportInfo {
   static ReportInfo? _reportInfo;
@@ -44,29 +49,55 @@ class ReportInfo {
 
   ReportInfo._internal();
 
+  //报告页大小
   RTPageSize? pageSize;
 
-  double currentHeight = 0;
-
+//报告者
   String? reporter;
 
+  //报告病人名
+  String? patientName;
+
+  ///病人Id
+  String? patinentId;
+
+  ///病人年龄
+  String? patientAge;
+
+  ///病人性别
+  String? patientSex;
+
+  ///报告日期
   DateTime? reportDate;
 
+  ///报告模板
   ReportTemplateDocument? reportTemplate;
 
+  ///重载
   FEventHandler<ReportEventArgs> onReload = FEventHandler();
 
+  ///重载完成时触发
   FEventHandler onReloadFinsh = FEventHandler();
 
+  ///关闭页面,释放监听
   FEventHandler onClose = FEventHandler();
 
+  ///ReportInfo全局单例
   static ReportInfo get instance {
     _reportInfo ??= ReportInfo._internal();
     return _reportInfo!;
   }
 
-  void init(ReportTemplateDocument reportTemplate, DateTime reportDate,
-      String reporter) {
+  ///初始化ReportInfo
+  void init(
+    ReportTemplateDocument reportTemplate,
+    DateTime reportDate,
+    String reporter, {
+    String? patientName,
+    String? patinentId,
+    String? patientAge,
+    String? patientSex,
+  }) {
     try {
       this.reportTemplate = reportTemplate;
       this.reportDate = reportDate;
@@ -86,11 +117,36 @@ class ReportInfo {
         footers.add(_initBlockElement(element));
       }
       pageSize = reportTemplate.pageSize;
+      final nameInputInfo = getElementInfoByTagName(TagNames.PATIENT_NAME_TAG);
+      if (patientName != null &&
+          patientName.isNotEmpty &&
+          nameInputInfo != null) {
+        final inputInfo = nameInputInfo as InputTextInfo;
+        inputInfo.text = patientName;
+      }
+      final ageInputInfo = getElementInfoByTagName(TagNames.PATIENT_AGE_TAG);
+      if (patientAge != null && patientAge.isNotEmpty && ageInputInfo != null) {
+        final inputInfo = ageInputInfo as InputTextInfo;
+        inputInfo.text = patientAge;
+      }
+      final idInputInfo = getElementInfoByTagName(TagNames.PATIENT_ID_TAG);
+      if (patinentId != null && patinentId.isNotEmpty && idInputInfo != null) {
+        final inputInfo = idInputInfo as InputTextInfo;
+        inputInfo.text = patinentId;
+      }
+      final sexSelectedInfo = getElementInfoByTagName(TagNames.PATIENT_SEX_TAG);
+      if (patientSex != null &&
+          patientSex.isNotEmpty &&
+          sexSelectedInfo != null) {
+        final selectedInfo = sexSelectedInfo as SingleSelectedInfo;
+        selectedInfo.selectedItem = patientSex;
+      }
     } catch (e) {
       print(e);
     }
   }
 
+  ///ReportInfo转为Json,用于报告存储至Server
   Map<String, dynamic> toJson() {
     final map = <String, dynamic>{};
     try {
@@ -123,6 +179,7 @@ class ReportInfo {
         this, ReportEventArgs(reportDate, reporter, jsonStr, onSelect));
   }
 
+  ///获取二级ElementInfo(布局组件,非最基础的组件)
   IBlockElementInfo? getBlockElement(IBlockElement block) {
     final id = block.id;
     for (var element in headers) {
@@ -142,20 +199,7 @@ class ReportInfo {
     }
   }
 
-  IBlockElementInfo _initBlockElement(IBlockElement element) {
-    final _type = element.elementType!;
-    if (_type.name == ElementType.rtTable!.name) {
-      final table = element as RTTable;
-      return RTTableInfo.fromElement(table);
-    } else if (_type.name == ElementType.paragraph!.name) {
-      final paragraph = element as Paragraph;
-      return ParagraphInfo.fromElement(paragraph);
-    } else {
-      final inputImageList = element as InputImageList;
-      return InputImageListInfo.fromElement(inputImageList);
-    }
-  }
-
+  ///获取报告模板中当前处于选中状态的图像输入框
   void selectedInputImage(String imageUrl) {
     for (var element in headers) {
       if (_checkImageisSelected(element, imageUrl)) {
@@ -174,6 +218,43 @@ class ReportInfo {
     }
   }
 
+  ///跟据TagName获取Elementnt
+  ElementInfo? getElementInfoByTagName(String tagName) {
+    try {
+      for (var e in headers) {
+        if (e.tag != null && e.tag!.name == tagName) {
+          return e;
+        }
+        final elementInfo = _getBaseElementInfoByTagName(e, tagName);
+        if (elementInfo != null) {
+          return elementInfo;
+        }
+      }
+      for (var e in blocks) {
+        if (e.tag != null && e.tag!.name == tagName) {
+          return e;
+        }
+        final elementInfo = _getBaseElementInfoByTagName(e, tagName);
+        if (elementInfo != null) {
+          return elementInfo;
+        }
+      }
+      for (var e in footers) {
+        if (e.tag != null && e.tag!.name == tagName) {
+          return e;
+        }
+        final elementInfo = _getBaseElementInfoByTagName(e, tagName);
+        if (elementInfo != null) {
+          return elementInfo;
+        }
+      }
+    } catch (e) {
+      print(e);
+    }
+    return null;
+  }
+
+  ///跟据UI组件获取ReportInfo中的组件
   ElementInfo? getElementInfo(IElement element) {
     try {
       for (var e in headers) {
@@ -200,6 +281,20 @@ class ReportInfo {
     return null;
   }
 
+  IBlockElementInfo _initBlockElement(IBlockElement element) {
+    final _type = element.elementType!;
+    if (_type.name == ElementType.rtTable!.name) {
+      final table = element as RTTable;
+      return RTTableInfo.fromElement(table);
+    } else if (_type.name == ElementType.paragraph!.name) {
+      final paragraph = element as Paragraph;
+      return ParagraphInfo.fromElement(paragraph);
+    } else {
+      final inputImageList = element as InputImageList;
+      return InputImageListInfo.fromElement(inputImageList);
+    }
+  }
+
   bool _checkImageisSelected(IBlockElementInfo block, String url) {
     if (block is InputImageListInfo) {
       final inputImage = block;
@@ -221,6 +316,7 @@ class ReportInfo {
     return false;
   }
 
+  ///获取基础组件信息
   ElementInfo? _getBaseElementInfo(IBlockElementInfo block, IElement element) {
     ElementInfo? result;
     final type = block.elementType;
@@ -252,6 +348,39 @@ class ReportInfo {
     return result;
   }
 
+  ///获取基础组件信息
+  ElementInfo? _getBaseElementInfoByTagName(
+      IBlockElementInfo block, String tagName) {
+    ElementInfo? result;
+    final type = block.elementType;
+    if (type!.name == ElementType.paragraph!.name) {
+      final paragraph = block as ParagraphInfo;
+      for (var el in paragraph.elementInfos!) {
+        if (el.tag != null && el.tag!.name == tagName) {
+          result = el;
+          break;
+        }
+      }
+    }
+    if (result == null) {
+      if (type.name == ElementType.rtTable!.name) {
+        final table = block as RTTableInfo;
+        final cells = table.cells!;
+        for (var cell in cells.values) {
+          for (var b in cell.blocks!) {
+            final info = _getBaseElementInfoByTagName(b, tagName);
+            if (info != null) {
+              result = info;
+              break;
+            }
+          }
+        }
+      }
+    }
+
+    return result;
+  }
+
   Map<String, dynamic> _getElementInfo(IBlockElementInfo element) {
     final _type = element.elementType!;
     if (_type.name == ElementType.rtTable!.name) {

+ 14 - 4
lib/report_info/single_selected_info.dart

@@ -1,16 +1,26 @@
-import 'package:fis_lib_report/report/interfaces/element.dart';
-import 'package:fis_lib_report/report/interfaces/singleSelected.dart';
+import 'package:fis_lib_report/converts/event_type.dart';
 import 'package:fis_lib_report/report/singleSelected.dart';
-import 'package:fis_lib_report/report/text_element.dart';
 import 'package:fis_lib_report/report_info/text_element_info.dart';
 
 class SingleSelectedInfo extends TextElementInfo {
+  ///是否只读
   bool? isReadOnly;
 
+  ///所有可选项
   List<String>? items = [];
 
-  String selectedItem = '';
+  ///已选中的项
+  String get selectedItem => _selectedItem;
+  set selectedItem(String v) {
+    if (items!.contains(v)) _selectedItem = v;
+  }
+
+  ///选中项改变通知UI变化
+  FEventHandler<String> onSelectedChange = FEventHandler<String>();
+
+  String _selectedItem = '';
 
+  ///UI渲染时获取待选项数据
   SingleSelectedInfo.fromElement(SingleSelected element)
       : super.fromElement(element) {
     isReadOnly = element.isReadOnly;