Răsfoiți Sursa

ReportInfo实体类型创建 & 添加超声图像作为Mock数据

loki.wu 2 ani în urmă
părinte
comite
9af9f090b4

+ 15 - 0
lib/converts/margin_convert.dart

@@ -0,0 +1,15 @@
+import 'package:fis_lib_report/converts/pt_to_px_converter.dart';
+import 'package:fis_lib_report/report/rt_thickness.dart';
+import 'package:flutter/cupertino.dart';
+
+class MarginConvert {
+  static EdgeInsets marginConvert(RTThickness? value) {
+    if (value == null) return const EdgeInsets.all(0);
+    return EdgeInsets.only(
+      top: PtToPxConverter.ptToPx(value.top),
+      bottom: PtToPxConverter.ptToPx(value.bottom),
+      left: PtToPxConverter.ptToPx(value.left),
+      right: PtToPxConverter.ptToPx(value.right),
+    );
+  }
+}

+ 60 - 24
lib/main.dart

@@ -2,9 +2,11 @@ import 'dart:convert';
 
 import 'package:fis_lib_report/converts/pt_to_px_converter.dart';
 import 'package:fis_lib_report/pages/block_element_page.dart';
+import 'package:fis_lib_report/pages/components/vid_image.dart';
 import 'package:fis_lib_report/report/interfaces/block_element.dart';
 import 'package:fis_lib_report/report/report_template_document.dart';
 import 'package:fis_lib_report/report/rt_thickness.dart';
+import 'package:fis_lib_report/report_info/report_info.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 
@@ -66,32 +68,65 @@ class _MyHomePageState extends State<MyHomePage> {
 
   @override
   Widget build(BuildContext context) {
+    final demoImags = [
+      'http://192.168.6.117:9001/Flyinsono-BJ-1300984704.VCS.AP-BeiJing/compress%E8%83%8E%E5%84%BF2.VID',
+      'http://192.168.6.117:9001/Flyinsono-BJ-1300984704.VCS.AP-BeiJing/compress%E8%83%8E%E5%84%BF1.VID',
+      'http://192.168.6.117:9001/Flyinsono-BJ-1300984704.VCS.AP-BeiJing/compress%E4%B9%B3%E8%85%BA%E5%8D%95%E5%B8%A7%E5%9B%BE.VID',
+      'http://192.168.6.117:9001/Flyinsono-BJ-1300984704.VCS.AP-BeiJing/compress%E4%B9%B3%E8%85%BAVideo.VID',
+      'http://192.168.6.117:9001/Flyinsono-BJ-1300984704.VCS.AP-BeiJing/compress%E9%A2%88%E5%8A%A8%E8%84%89%E6%A8%AA%E5%88%87.VID'
+    ];
+
     return Scaffold(
-      body: Container(
-        decoration: _buildDecoration(),
-        padding: _padding,
-        alignment: Alignment.center,
-        height: _height,
-        width: _width,
-        child: Container(
-          child: Column(
-            mainAxisAlignment: MainAxisAlignment.center,
-            crossAxisAlignment: CrossAxisAlignment.center,
-            mainAxisSize: MainAxisSize.min,
-            children: [
-              ..._header.map((head) {
-                return BlockElementPage(element: head);
-              }),
-              ..._blocks.map((block) {
-                return BlockElementPage(element: block);
-              }),
-              const SizedBox(height: 10),
-              ..._footer.map((footer) {
-                return BlockElementPage(element: footer);
-              }),
-            ],
+      body: Row(
+        children: [
+          Container(
+            decoration: _buildDecoration(),
+            padding: _padding,
+            alignment: Alignment.center,
+            height: _height,
+            width: _width,
+            child: Column(
+              mainAxisAlignment: MainAxisAlignment.center,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              mainAxisSize: MainAxisSize.min,
+              children: [
+                ..._header.map((head) {
+                  return BlockElementPage(element: head);
+                }),
+                ..._blocks.map((block) {
+                  return BlockElementPage(element: block);
+                }),
+                const SizedBox(height: 10),
+                ..._footer.map((footer) {
+                  return BlockElementPage(element: footer);
+                }),
+              ],
+            ),
           ),
-        ),
+          const SizedBox(width: 20),
+          Container(
+              decoration: _buildDecoration(),
+              padding: _padding,
+              alignment: Alignment.center,
+              height: _height,
+              width: _width,
+              child: Wrap(
+                children: [
+                  ...demoImags.map((element) {
+                    return MouseRegion(
+                      cursor: SystemMouseCursors.click,
+                      child: GestureDetector(
+                        onTap: () {},
+                        child: Container(
+                          margin: const EdgeInsets.all(15),
+                          child: VidImageView.network(element),
+                        ),
+                      ),
+                    );
+                  })
+                ],
+              )),
+        ],
       ),
     );
   }
@@ -110,6 +145,7 @@ class _MyHomePageState extends State<MyHomePage> {
       final reportMap = jsonDecode(jsonStr);
       final template = ReportTemplateDocument.fromJson(reportMap);
       _reportTemplate = template;
+      ReportInfo.instance.init(_reportTemplate);
       setState(() {
         _initPage();
       });

+ 6 - 10
lib/pages/block_element_page.dart

@@ -1,3 +1,6 @@
+import 'dart:math';
+
+import 'package:fis_lib_report/pages/components/input_imageList.dart';
 import 'package:fis_lib_report/pages/helpler.dart';
 import 'package:fis_lib_report/pages/paragraph_page.dart';
 import 'package:fis_lib_report/pages/rt_table.dart';
@@ -7,6 +10,7 @@ import 'package:fis_lib_report/report/inputImageList.dart';
 import 'package:fis_lib_report/report/interfaces/block_element.dart';
 import 'package:fis_lib_report/report/paragraph.dart';
 import 'package:fis_lib_report/report/rt_table.dart';
+import 'package:fis_lib_report/report_info/report_info.dart';
 import 'package:flutter/material.dart';
 
 class BlockElementPage extends StatefulWidget {
@@ -25,9 +29,7 @@ class _BlockElementState extends State<BlockElementPage> {
   @override
   initState() {
     IBlockElement e = widget.element;
-    setState(() {
-      _type = e.elementType!;
-    });
+    _type = e.elementType!;
     super.initState();
   }
 
@@ -44,13 +46,7 @@ class _BlockElementState extends State<BlockElementPage> {
       return ParagraphPage(paragraph: paragraph);
     } else if (_type != null && _type!.name == ElementType.imageList!.name) {
       final inputImageList = widget.element as InputImageList;
-      return Container(
-        height: 180,
-        width: 580,
-        alignment: Alignment.center,
-        decoration: TestBoxDecoration.buildDecoration(),
-        child: const Text('图片选择框'),
-      );
+      return RInputImageList(inputImageList);
     }
     return Container(
       height: 20,

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

@@ -0,0 +1,70 @@
+import 'package:fis_lib_report/converts/margin_convert.dart';
+import 'package:fis_lib_report/converts/pt_to_px_converter.dart';
+import 'package:fis_lib_report/pages/helpler.dart';
+import 'package:fis_lib_report/report/inputImageList.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+class RInputImageList extends StatefulWidget {
+  final InputImageList inputImageList;
+
+  RInputImageList(this.inputImageList);
+  @override
+  State<StatefulWidget> createState() {
+    return _RInputImageListState(inputImageList);
+  }
+}
+
+class _RInputImageListState extends State<RInputImageList> {
+  final InputImageList inputImageList;
+  _RInputImageListState(this.inputImageList);
+  Color _borderColor = Colors.grey;
+  bool _isSelected = false;
+  bool _hasImageBorder = false;
+
+  @override
+  initState() {
+    _hasImageBorder = inputImageList.hasImageBorder!;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return MouseRegion(
+      cursor: SystemMouseCursors.click,
+      child: GestureDetector(
+        onTap: () {
+          if (_isSelected) {
+            setState(() {
+              _borderColor = Colors.grey;
+              _isSelected = false;
+              _hasImageBorder = false;
+            });
+          } else {
+            setState(() {
+              _borderColor = Color.fromARGB(255, 64, 159, 248);
+              _isSelected = true;
+              _hasImageBorder = true;
+            });
+          }
+        },
+        child: Container(
+          height: PtToPxConverter.ptToPx(inputImageList.imageHeight),
+          width: PtToPxConverter.ptToPx(
+              inputImageList.imageWidth! * inputImageList.column!),
+          alignment: Alignment.center,
+          margin: MarginConvert.marginConvert(inputImageList.margin),
+          decoration: BoxDecoration(
+              border: _hasImageBorder
+                  ? Border.all(
+                      width: 0.5,
+                      color: _borderColor,
+                    )
+                  : null,
+              color: Colors.transparent),
+          child: const Text('请点击此处后选择右侧图片'),
+        ),
+      ),
+    );
+  }
+}

+ 68 - 0
lib/pages/components/vid.dart

@@ -0,0 +1,68 @@
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:dio/dio.dart' as dio;
+import 'package:vid/us/vid_us_image.dart';
+import 'package:vid/us/vid_us_image_data.dart';
+
+/// Vid文件帮助工具
+class VidFileHelper {
+  /// 从文件获取单帧图像
+  ///
+  /// [file] vid单帧图像文件对象
+  static Future<VidUsImage?> getImageFromFile(File file) async {
+    final data = await getDataFromFile(file);
+    if (data != null) {
+      final frame = data.getImage(0);
+      return frame;
+    }
+    return null;
+  }
+
+  /// 从文件中获取Vid信息
+  ///
+  /// [file] vid文件对象
+  static Future<VidUsImageData?> getDataFromFile(File file) async {
+    try {
+      final fileData = await file.readAsBytes();
+      final vidData = VidUsImageData(fileData);
+      return vidData;
+    } catch (e) {
+      // logger.e
+      return null;
+    }
+  }
+
+  /// 从链接获取单帧图像
+  ///
+  /// [url] vid单帧图像链接
+  static Future<VidUsImage?> getImageFromNetwork(String url) async {
+    final data = await getDataFromNetwork(url);
+    if (data != null) {
+      final frame = data.getImage(0);
+      return frame;
+    }
+    return null;
+  }
+
+  /// 从链接获取Vid信息
+  ///
+  /// [url] vid文件链接
+  static Future<VidUsImageData?> getDataFromNetwork(String url) async {
+    try {
+      final httpClient = dio.Dio(dio.BaseOptions(
+        responseType: dio.ResponseType.bytes,
+        sendTimeout: 10 * 1000,
+      ));
+
+      final response = await httpClient.get(url);
+      httpClient.close();
+      final bytes = response.data as Uint8List;
+      final vidData = VidUsImageData(bytes);
+      return vidData;
+    } catch (e) {
+      // logger
+      return null;
+    }
+  }
+}

+ 151 - 0
lib/pages/components/vid_image.dart

@@ -0,0 +1,151 @@
+import 'dart:io';
+
+import 'package:fis_lib_report/pages/components/vid.dart';
+import 'package:flutter/material.dart';
+import 'package:vid/us/vid_us_image.dart';
+
+class VidImageView {
+  /// 创建一个从网络链接加载Vid图片的组件
+  ///
+  /// [url] vid图片链接
+  ///
+  /// 其他参数参考[Image]组件
+  static Widget network(
+    String url, {
+    Key? key,
+    double? width,
+    double? height,
+    Widget Function(BuildContext context)? loadingBuilder,
+    ImageErrorWidgetBuilder? errorBuilder,
+    Animation<double>? opacity,
+    FilterQuality filterQuality = FilterQuality.low,
+    BlendMode? colorBlendMode,
+    BoxFit? fit,
+    Alignment alignment = Alignment.center,
+    bool isAntiAlias = false,
+    bool gaplessPlayback = false,
+    double scale = 1.0,
+  }) {
+    return FutureBuilder(
+      future: VidFileHelper.getImageFromNetwork(url),
+      builder: (context, snapshot) => _buildAsyncVidWidget(
+        context,
+        snapshot,
+        loadingBuilder,
+        errorBuilder,
+        width: width,
+        height: height,
+        opacity: opacity,
+        filterQuality: filterQuality,
+        colorBlendMode: colorBlendMode,
+        fit: fit,
+        alignment: alignment,
+        isAntiAlias: isAntiAlias,
+        gaplessPlayback: gaplessPlayback,
+        scale: scale,
+      ),
+    );
+  }
+
+  /// 创建一个从文件加载Vid图片的组件
+  ///
+  /// [file] 文件对象
+  ///
+  /// 其他参数参考[Image]组件
+  static Widget file(
+    File file, {
+    Key? key,
+    double? width,
+    double? height,
+    Widget Function(BuildContext context)? loadingBuilder,
+    ImageErrorWidgetBuilder? errorBuilder,
+    Animation<double>? opacity,
+    FilterQuality filterQuality = FilterQuality.low,
+    BlendMode? colorBlendMode,
+    BoxFit? fit,
+    Alignment alignment = Alignment.center,
+    bool isAntiAlias = false,
+    bool gaplessPlayback = false,
+    double scale = 1.0,
+  }) {
+    return FutureBuilder(
+      future: VidFileHelper.getImageFromFile(file),
+      builder: (context, snapshot) => _buildAsyncVidWidget(
+        context,
+        snapshot,
+        loadingBuilder,
+        errorBuilder,
+        width: width,
+        height: height,
+        opacity: opacity,
+        filterQuality: filterQuality,
+        colorBlendMode: colorBlendMode,
+        fit: fit,
+        alignment: alignment,
+        isAntiAlias: isAntiAlias,
+        gaplessPlayback: gaplessPlayback,
+        scale: scale,
+      ),
+    );
+  }
+
+  static Widget _buildAsyncVidWidget(
+    BuildContext context,
+    AsyncSnapshot<Object?> snapshot,
+    Widget Function(BuildContext context)? loadingBuilder,
+    ImageErrorWidgetBuilder? errorBuilder, {
+    double? width,
+    double? height,
+    Animation<double>? opacity,
+    FilterQuality filterQuality = FilterQuality.low,
+    BlendMode? colorBlendMode,
+    BoxFit? fit,
+    Alignment alignment = Alignment.center,
+    bool isAntiAlias = false,
+    bool gaplessPlayback = false,
+    double scale = 1.0,
+  }) {
+    if (snapshot.connectionState == ConnectionState.done) {
+      if (snapshot.hasData) {
+        final frame = snapshot.data as VidUsImage;
+        return Image.memory(
+          frame.imageData,
+          width: width,
+          height: height,
+          opacity: opacity,
+          filterQuality: filterQuality,
+          colorBlendMode: colorBlendMode,
+          fit: fit,
+          alignment: alignment,
+          isAntiAlias: isAntiAlias,
+          gaplessPlayback: gaplessPlayback,
+          scale: scale,
+        );
+      } else {
+        final exWidget = errorBuilder != null
+            ? errorBuilder(
+                context,
+                Exception("Vid Image load fail."),
+                snapshot.stackTrace,
+              )
+            : ErrorWidget("Error");
+        return Container(
+          alignment: alignment,
+          width: width,
+          height: height,
+          child: exWidget,
+        );
+      }
+    } else {
+      final loading = loadingBuilder != null
+          ? loadingBuilder(context)
+          : const CircularProgressIndicator();
+      return Container(
+        alignment: alignment,
+        width: width,
+        height: height,
+        child: loading,
+      );
+    }
+  }
+}

+ 0 - 1
lib/pages/rt_table.dart

@@ -73,7 +73,6 @@ class _RTTableState extends State<RTTablePage> {
 
         final cell = _cells![cellPostion];
         RTCell c = cell as RTCell;
-        print('width:' + width.toString() + ' height:' + height.toString());
         childwidgets.add(
           SizedBox(
             width: PtToPxConverter.ptToPx(width),

+ 2 - 2
lib/report/multiSelected.dart

@@ -18,9 +18,9 @@ class MultiSelected extends TextElement implements IMultiSelected {
     isReadOnly = json['IsReadOnly'];
     List<dynamic> jsonItems = json['Items'];
     if (jsonItems.isNotEmpty) {
-      jsonItems.forEach((element) {
+      for (var element in jsonItems) {
         items!.add(element);
-      });
+      }
     }
   }
 }

+ 28 - 0
lib/report_info/block_element_info.dart

@@ -0,0 +1,28 @@
+import 'package:fis_lib_report/report/element_type.dart';
+import 'package:fis_lib_report/report/inputImageList.dart';
+import 'package:fis_lib_report/report/interfaces/block_element.dart';
+import 'package:fis_lib_report/report/interfaces/element.dart';
+import 'package:fis_lib_report/report/paragraph.dart';
+import 'package:fis_lib_report/report/rt_table.dart';
+import 'package:fis_lib_report/report_info/element_info.dart';
+import 'package:fis_lib_report/report_info/input_image_list_info.dart';
+import 'package:fis_lib_report/report_info/paragraph_info.dart';
+import 'package:fis_lib_report/report_info/rt_table_info.dart';
+
+class BlockElementInfo {
+  List<ElementInfo>? elementInfos = [];
+
+  BlockElementInfo.fromElement(IElement element) {
+    final _type = element.elementType!;
+    if (_type.name == ElementType.rtTable!.name) {
+      final table = element as RTTable;
+      elementInfos!.add(RTTableInfo.fromElement(table));
+    } else if (_type.name == ElementType.paragraph!.name) {
+      final paragraph = element as Paragraph;
+      elementInfos!.add(ParagraphInfo.fromElement(paragraph));
+    } else {
+      final inputImageList = element as InputImageList;
+      elementInfos!.add(InputImageListInfo.fromElement(inputImageList));
+    }
+  }
+}

+ 15 - 0
lib/report_info/date_time_info.dart

@@ -0,0 +1,15 @@
+import 'package:fis_lib_report/report/dateTimeElement.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 DateTimeInfo extends TextElementInfo {
+  String? text;
+  String? dateTimeFormat = 'yyyy-MM-dd';
+
+  DateTimeInfo.fromElement(DateTimeElement element)
+      : super.fromElement(element) {
+    dateTimeFormat = element.dateTimeFormat;
+  }
+}

+ 37 - 0
lib/report_info/element_info.dart

@@ -0,0 +1,37 @@
+import 'package:fis_lib_report/report/element_tag.dart';
+import 'package:fis_lib_report/report/element_type.dart';
+import 'package:fis_lib_report/report/interfaces/element.dart';
+import 'package:fis_lib_report/report/interfaces/position_layout.dart';
+import 'package:fis_lib_report/report/interfaces/report_element.dart';
+import 'package:fis_lib_report/report/measure_tag.dart';
+import 'package:fis_lib_report/report/rt_thickness.dart';
+import 'package:uuid/uuid.dart';
+
+abstract class ElementInfo {
+  @override
+  ElementType? elementType;
+
+  @override
+  int? index;
+
+  @override
+  MeasureTag? measureTag;
+
+  @override
+  IReportElement? parent;
+
+  @override
+  ElementTag? tag;
+
+  @override
+  String? id;
+
+  ElementInfo.fromElement(IElement element) {
+    elementType = element.elementType;
+    index = element.index;
+    measureTag = element.measureTag;
+    parent = element.parent;
+    tag = element.tag;
+    id = element.id;
+  }
+}

+ 22 - 0
lib/report_info/input_image_list_info.dart

@@ -0,0 +1,22 @@
+import 'package:fis_lib_report/report/element.dart';
+import 'package:fis_lib_report/report/inputImageList.dart';
+import 'package:fis_lib_report/report/interfaces/block_element.dart';
+import 'package:fis_lib_report/report/interfaces/element.dart';
+import 'package:fis_lib_report/report/interfaces/inputImageList.dart';
+import 'package:fis_lib_report/report_info/block_element_info.dart';
+import 'package:fis_lib_report/report_info/element_info.dart';
+
+class InputImageListInfo extends ElementInfo {
+  int? column;
+
+  bool? hasGap;
+
+  bool? isReadOnly;
+
+  InputImageListInfo.fromElement(InputImageList inputImageList)
+      : super.fromElement(inputImageList) {
+    column = inputImageList.column;
+    hasGap = inputImageList.hasGap;
+    isReadOnly = inputImageList.isReadOnly;
+  }
+}

+ 16 - 0
lib/report_info/input_text_info.dart

@@ -0,0 +1,16 @@
+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;
+
+  String? text;
+
+  InputTextInfo.fromElement(InputText element) : super.fromElement(element) {
+    isReadOnly = element.isReadOnly;
+    text = '';
+  }
+}

+ 17 - 0
lib/report_info/multi_selected_info.dart

@@ -0,0 +1,17 @@
+import 'package:fis_lib_report/report/interfaces/element.dart';
+import 'package:fis_lib_report/report/multiSelected.dart';
+import 'package:fis_lib_report/report_info/text_element_info.dart';
+
+class MulitiSelectedInfo extends TextElementInfo {
+  bool? isReadOnly = false;
+
+  List<String>? items = [];
+
+  List<String>? selectedItems = [];
+
+  MulitiSelectedInfo.fromElement(MultiSelected element)
+      : super.fromElement(element) {
+    items = element.items;
+    isReadOnly = element.isReadOnly;
+  }
+}

+ 48 - 0
lib/report_info/paragraph_info.dart

@@ -0,0 +1,48 @@
+import 'package:fis_lib_report/report/dateTimeElement.dart';
+import 'package:fis_lib_report/report/element_type.dart';
+import 'package:fis_lib_report/report/inputText.dart';
+import 'package:fis_lib_report/report/line.dart';
+import 'package:fis_lib_report/report/multiSelected.dart';
+import 'package:fis_lib_report/report/paragraph.dart';
+import 'package:fis_lib_report/report/singleSelected.dart';
+import 'package:fis_lib_report/report/staticText.dart';
+import 'package:fis_lib_report/report_info/block_element_info.dart';
+import 'package:fis_lib_report/report_info/date_time_info.dart';
+import 'package:fis_lib_report/report_info/element_info.dart';
+import 'package:fis_lib_report/report_info/input_text_info.dart';
+import 'package:fis_lib_report/report_info/multi_selected_info.dart';
+import 'package:fis_lib_report/report_info/single_selected_info.dart';
+import 'package:fis_lib_report/report_info/static_text_info.dart';
+
+class ParagraphInfo extends ElementInfo implements BlockElementInfo {
+  double? lineSpace;
+
+  @override
+  List<ElementInfo>? elementInfos = [];
+
+  bool? isEmptyFirst;
+
+  ParagraphInfo.fromElement(Paragraph paragraph)
+      : super.fromElement(paragraph) {
+    final elements = paragraph.elements;
+    for (var element in elements!) {
+      if (element.elementType!.name == ElementType.inputText!.name) {
+        InputText inputText = element as InputText;
+        elementInfos!.add(InputTextInfo.fromElement(inputText));
+      } else if (element.elementType!.name == ElementType.staticText!.name) {
+        StaticText staticText = element as StaticText;
+        elementInfos!.add(StaticTextInfo.fromElement(staticText));
+      } else if (element.elementType!.name ==
+          ElementType.singleSelected!.name) {
+        SingleSelected singleSelected = element as SingleSelected;
+        elementInfos!.add(SingleSelectedInfo.fromElement(singleSelected));
+      } else if (element.elementType!.name == ElementType.dateTime!.name) {
+        final dateTime = element as DateTimeElement;
+        elementInfos!.add(DateTimeInfo.fromElement(dateTime));
+      } else if (element.elementType!.name == ElementType.multiSelected!.name) {
+        final multiSelected = element as MultiSelected;
+        elementInfos!.add(MulitiSelectedInfo.fromElement(multiSelected));
+      }
+    }
+  }
+}

+ 59 - 0
lib/report_info/report_info.dart

@@ -0,0 +1,59 @@
+import 'package:fis_lib_report/report/element_tag.dart';
+import 'package:fis_lib_report/report/report_template_document.dart';
+import 'package:fis_lib_report/report_info/block_element_info.dart';
+
+class ReportInfo {
+  static ReportInfo? _reportInfo;
+  List<BlockElementInfo> blocks = [];
+  List<BlockElementInfo> headers = [];
+  List<BlockElementInfo> footers = [];
+
+  /// Gets the author of the report template.
+  String? author;
+
+  /// Gets or sets the value to indicate whether the report template is created by user.
+  bool? isCustom;
+
+  /// Gets the report template name.
+  String? name;
+
+  /// Gets the custom input element tags of the report template.
+  Map<String, ElementTag>? tags;
+
+  /// Gets or sets the update time.
+  DateTime? updateTime;
+
+  ///version
+  String? version;
+
+  /// Gets the id.
+  String? id;
+
+  ReportInfo._internal();
+
+  static ReportInfo get instance {
+    _reportInfo ??= ReportInfo._internal();
+    return _reportInfo!;
+  }
+
+  void init(ReportTemplateDocument reportTemplate) {
+    try {
+      isCustom = reportTemplate.isCustom;
+      name = reportTemplate.name;
+      updateTime = reportTemplate.updateTime;
+      version = reportTemplate.version;
+      id = reportTemplate.id;
+      for (var element in reportTemplate.header!) {
+        headers.add(BlockElementInfo.fromElement(element));
+      }
+      for (var element in reportTemplate.blocks!) {
+        blocks.add(BlockElementInfo.fromElement(element));
+      }
+      for (var element in reportTemplate.footer!) {
+        footers.add(BlockElementInfo.fromElement(element));
+      }
+    } catch (e) {
+      print(e);
+    }
+  }
+}

+ 21 - 0
lib/report_info/rt_cell_info.dart

@@ -0,0 +1,21 @@
+import 'package:fis_lib_report/report/element_type.dart';
+import 'package:fis_lib_report/report/interfaces/cell.dart';
+import 'package:fis_lib_report/report/paragraph.dart';
+import 'package:fis_lib_report/report_info/block_element_info.dart';
+import 'package:fis_lib_report/report_info/element_info.dart';
+import 'package:fis_lib_report/report_info/paragraph_info.dart';
+
+class RTCellInfo extends ElementInfo {
+  @override
+  List<BlockElementInfo>? blocks = [];
+
+  RTCellInfo.fromElement(ICell value) : super.fromElement(value) {
+    for (var element in value.blocks!) {
+      if (element.elementType!.name == ElementType.paragraph!.name) {
+        final paragraphInfo = element as Paragraph;
+        final block = ParagraphInfo.fromElement(paragraphInfo);
+        blocks!.add(block);
+      }
+    }
+  }
+}

+ 48 - 0
lib/report_info/rt_grid.dart

@@ -0,0 +1,48 @@
+import 'package:fis_lib_report/report/cellPostion.dart';
+import 'package:fis_lib_report/report/element_type.dart';
+import 'package:fis_lib_report/report/interfaces/cell.dart';
+import 'package:fis_lib_report/report/interfaces/grid.dart';
+import 'package:fis_lib_report/report/interfaces/report_element.dart';
+import 'package:fis_lib_report/report/rt_table.dart';
+import 'package:fis_lib_report/report_info/block_element_info.dart';
+import 'package:fis_lib_report/report_info/element_info.dart';
+import 'package:fis_lib_report/report_info/rt_cell_info.dart';
+
+class RTGridInfo extends ElementInfo {
+  @override
+  List<RTColumnDefinition>? columnDefinitions = [];
+
+  @override
+  List<RTRowDefinition>? rowDefinitions = [];
+
+  bool? isDelete;
+
+  bool? isInsertColumn;
+
+  int? deleteRowIndex;
+
+  int? deleteColumnIndex;
+
+  bool? isMergeCell;
+
+  int? mergeDeleteStartColumnIndex;
+
+  int? mergeDeleteEndColumnIndex;
+
+  Map<CellPostion, RTCellInfo>? cells = {};
+
+  RTGridInfo.fromElement(RTTable table) : super.fromElement(table) {
+    columnDefinitions = table.columnDefinitions;
+    rowDefinitions = table.rowDefinitions;
+    isDelete = table.isDelete;
+    isInsertColumn = table.isInsertColumn;
+    deleteRowIndex = table.deleteColumnIndex;
+    deleteColumnIndex = table.deleteColumnIndex;
+    isMergeCell = table.isMergeCell;
+    mergeDeleteStartColumnIndex = table.mergeDeleteStartColumnIndex;
+    mergeDeleteEndColumnIndex = table.mergeDeleteEndColumnIndex;
+    table.cells!.forEach((key, value) {
+      cells![key] = RTCellInfo.fromElement(value);
+    });
+  }
+}

+ 17 - 0
lib/report_info/rt_table_info.dart

@@ -0,0 +1,17 @@
+import 'package:fis_lib_report/report/element_type.dart';
+import 'package:fis_lib_report/report/interfaces/report_element.dart';
+import 'package:fis_lib_report/report/rt_table.dart';
+import 'package:fis_lib_report/report_info/block_element_info.dart';
+import 'package:fis_lib_report/report_info/rt_grid.dart';
+
+class RTTableInfo extends RTGridInfo {
+  bool? autoHide;
+  bool? isAverageColumnWidth;
+  bool? allowBreakAcrossPages;
+
+  RTTableInfo.fromElement(RTTable table) : super.fromElement(table) {
+    autoHide = table.autoHide;
+    isAverageColumnWidth = table.isAverageColumnWidth;
+    allowBreakAcrossPages = table.allowBreakAcrossPages;
+  }
+}

+ 19 - 0
lib/report_info/single_selected_info.dart

@@ -0,0 +1,19 @@
+import 'package:fis_lib_report/report/interfaces/element.dart';
+import 'package:fis_lib_report/report/interfaces/singleSelected.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;
+
+  SingleSelectedInfo.fromElement(SingleSelected element)
+      : super.fromElement(element) {
+    isReadOnly = element.isReadOnly;
+    items = element.items;
+  }
+}

+ 10 - 0
lib/report_info/static_text_info.dart

@@ -0,0 +1,10 @@
+import 'package:fis_lib_report/report/staticText.dart';
+import 'package:fis_lib_report/report_info/text_element_info.dart';
+
+class StaticTextInfo extends TextElementInfo {
+  String? text;
+
+  StaticTextInfo.fromElement(StaticText element) : super.fromElement(element) {
+    text = element.text;
+  }
+}

+ 9 - 0
lib/report_info/text_element_info.dart

@@ -0,0 +1,9 @@
+import 'package:fis_lib_report/report/inlineElement.dart';
+import 'package:fis_lib_report/report/interfaces/element.dart';
+import 'package:fis_lib_report/report/interfaces/textElement.dart';
+import 'package:fis_lib_report/report/rt_color.dart';
+import 'package:fis_lib_report/report_info/element_info.dart';
+
+abstract class TextElementInfo extends ElementInfo {
+  TextElementInfo.fromElement(IElement element) : super.fromElement(element);
+}

+ 9 - 0
pubspec.lock

@@ -400,6 +400,15 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "2.1.1"
+  vid:
+    dependency: "direct overridden"
+    description:
+      path: "."
+      ref: "173b68819c"
+      resolved-ref: "173b68819c6681244a08a32a74b1091baefe4b29"
+      url: "http://git.ius.plus:88/Project-Wing/flutter_vid"
+    source: git
+    version: "0.0.1"
   win32:
     dependency: transitive
     description:

+ 4 - 0
pubspec.yaml

@@ -46,6 +46,10 @@ dependency_overrides:
     git:
       url: http://git.ius.plus:88/Project-Wing/fis_lib_ui.git
       ref: f574c3bfee
+  vid:
+    git:
+      url: http://git.ius.plus:88/Project-Wing/flutter_vid
+      ref: 173b68819c
 
 dev_dependencies:
   flutter_test: