diff --git a/win_text_editor/assets/config/uft_macro_list.yaml b/win_text_editor/assets/config/uft_macro_list.yaml index 318a404..63fa523 100644 --- a/win_text_editor/assets/config/uft_macro_list.yaml +++ b/win_text_editor/assets/config/uft_macro_list.yaml @@ -4,11 +4,11 @@ templates: body: | [获取记录][{{tableName}}({{keyName}})][ {{#keyFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/keyFields}} ][ {{#selectedFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/selectedFields}} ] [继续执行] @@ -16,7 +16,7 @@ templates: { [报错返回][ERR_???][{{#keyFields}}{{name}} = @{{name}}{{^isLast}}, {{/isLast}}{{/keyFields}}] }else{ - //balabala + } @@ -27,7 +27,7 @@ templates: body: | [插入记录][{{tableName}}][ {{#fields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}} {{/fields}} ] [索引冲突] @@ -42,13 +42,13 @@ templates: [修改记录][{{tableName}}][ {{#fields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}} {{/fields}} ] [修改索引字段][{{tableName}}][ {{#keyFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/keyFields}} ] } @@ -57,7 +57,7 @@ templates: body: | [获取记录][{{tableName}}({{keyName}})][ {{#keyFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/keyFields}} ] [继续执行] @@ -65,13 +65,13 @@ templates: { [修改记录][{{tableName}}][ {{#selectedFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}} {{/selectedFields}} ] [修改索引字段][{{tableName}}][ {{#keyFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/keyFields}} ] } @@ -80,7 +80,7 @@ templates: body: | [获取记录][{{tableName}}({{keyName}})][ {{#keyFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/keyFields}} ] [继续执行] @@ -93,11 +93,11 @@ templates: body: | [遍历记录开始][{{tableName}}({{selectIndexOrKey.name}})][ {{#selectIndexOrKey.fields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/selectIndexOrKey.fields}} ][ {{#selectedFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/selectedFields}} ] { @@ -109,7 +109,7 @@ templates: body: | [插入组件][{{name}}][0][ {{#fields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}} {{/fields}} ] @@ -117,7 +117,7 @@ templates: body: | [修改组件][{{name}}][@num][ {{#selectedFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}} {{/selectedFields}} ] @@ -127,12 +127,12 @@ templates: [获取组件][{{name}}{{#hasIndex}}({{index.name}}){{/hasIndex}}][{{^hasIndex}}[@num][{{/hasIndex}} {{#hasIndex}} {{#index.fields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/index.fields}} ][ {{/hasIndex}} {{#selectedFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/selectedFields}} ] @@ -142,12 +142,12 @@ templates: [遍历组件开始][{{name}}{{#hasIndex}}({{index.name}}){{/hasIndex}}][ {{#hasIndex}} {{#index.fields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/index.fields}} {{/hasIndex}} ][ {{#selectedFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/selectedFields}} ] { @@ -162,7 +162,7 @@ templates: body: | [插入组件][{{name}}][ {{#fields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}} {{/fields}} ] @@ -177,7 +177,7 @@ templates: {{/hasIndex}} ][ {{#fields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} {{/fields}} ] { @@ -187,18 +187,18 @@ templates: 普通调用: body: | - [{{chineseName}}][ + [{{chineseName}}][ {{#input}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}},{{/isLast}} {{/input}} ][ {{#output}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}},{{/isLast}} {{/output}} ] [处理失败] { - [获取错误信息][@error_no][@error_info][@error_pathinfo] + [错误信息获取] //TODO:处理异常 [继续执行] @@ -211,18 +211,18 @@ templates: 事务调用: body: | [事务处理开始] - [{{chineseName}}][ + [{{chineseName}}][ {{#input}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}},{{/isLast}} {{/input}} ][ {{#output}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{name}}{{^isLast}},{{/isLast}} {{/output}} ] [处理失败] { - [获取错误信息][@error_no][@error_info][@error_pathinfo] + [错误信息获取] //TODO:处理异常 [事务回滚] [继续执行] diff --git a/win_text_editor/assets/config/words_classes.yaml b/win_text_editor/assets/config/words_classes.yaml index 61b6446..019559a 100644 --- a/win_text_editor/assets/config/words_classes.yaml +++ b/win_text_editor/assets/config/words_classes.yaml @@ -1,2 +1,2 @@ outline_name_black_list: - - 历史,日志,名称,比例,数量,金额,次数,属性,对应,分类,姓名,单位,总数,行使,子项,占比,记录,列表,目标,字段,字符串,动作,方式 \ No newline at end of file + - 历史,日志,名称,比例,数量,金额,次数,属性,对应,分类,姓名,单位,总数,行使,子项,占比,记录,列表,目标,字段,字符串,动作,方式,类型,类别 \ No newline at end of file diff --git a/win_text_editor/lib/main copy.dart b/win_text_editor/lib/main copy.dart new file mode 100644 index 0000000..2b3948b --- /dev/null +++ b/win_text_editor/lib/main copy.dart @@ -0,0 +1,79 @@ +import 'package:flutter/material.dart'; + +void main2() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp(home: DragIconDemo()); + } +} + +class DragIconDemo extends StatefulWidget { + @override + _DragIconDemoState createState() => _DragIconDemoState(); +} + +class _DragIconDemoState extends State { + // 跟踪图标在哪个容器中(1或2) + int iconContainer = 1; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('图标拖拽示例')), + body: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + // 第一个容器 + buildContainer( + containerNumber: 1, + child: iconContainer == 1 ? buildDraggableIcon() : null, + ), + + // 第二个容器 + buildContainer( + containerNumber: 2, + child: iconContainer == 2 ? buildDraggableIcon() : null, + ), + ], + ), + ); + } + + // 构建可拖拽图标 + Widget buildDraggableIcon() { + return Draggable( + data: iconContainer, // 传递当前容器编号作为数据 + feedback: const Icon(Icons.star, size: 50, color: Colors.amber), + childWhenDragging: const Opacity( + opacity: 0.5, + child: Icon(Icons.star, size: 50, color: Colors.amber), + ), + child: const Icon(Icons.star, size: 50, color: Colors.amber), + ); + } + + // 构建容器(同时也是拖放目标) + Widget buildContainer({required int containerNumber, Widget? child}) { + return DragTarget( + builder: (context, candidateData, rejectedData) { + return Container( + width: 150, + height: 150, + decoration: BoxDecoration( + border: Border.all(color: Colors.blue, width: 2), + borderRadius: BorderRadius.circular(10), + ), + child: Center(child: child), + ); + }, + onWillAcceptWithDetails: (data) => true, // 接受任何拖拽数据 + onAcceptWithDetails: (data) { + setState(() { + iconContainer = containerNumber; // 更新图标位置 + }); + }, + ); + } +} diff --git a/win_text_editor/lib/menus/app_menu.dart b/win_text_editor/lib/menus/app_menu.dart index 4a75804..f96574a 100644 --- a/win_text_editor/lib/menus/app_menu.dart +++ b/win_text_editor/lib/menus/app_menu.dart @@ -53,7 +53,7 @@ class AppMenu extends StatelessWidget { const PopupMenuDivider(), const PopupMenuItem( value: MenuConstants.demo, - child: ListTile(leading: Icon(Icons.code), title: Text('Demo')), + child: ListTile(leading: Icon(Icons.view_agenda), title: Text('Demo')), ), ]; } @@ -72,11 +72,11 @@ class AppMenu extends StatelessWidget { value: MenuConstants.callFunction, child: ListTile(leading: Icon(Icons.functions), title: Text('功能号调用')), ), - // const PopupMenuDivider(), - // const PopupMenuItem( - // value: MenuConstants.outline, - // child: ListTile(leading: Icon(Icons.outlined_flag_rounded), title: Text('大纲')), - // ), + const PopupMenuDivider(), + const PopupMenuItem( + value: MenuConstants.codeCreater, + child: ListTile(leading: Icon(Icons.code), title: Text('代码生成器')), + ), ]; } diff --git a/win_text_editor/lib/menus/menu_actions.dart b/win_text_editor/lib/menus/menu_actions.dart index 1d511f1..64999fd 100644 --- a/win_text_editor/lib/menus/menu_actions.dart +++ b/win_text_editor/lib/menus/menu_actions.dart @@ -22,6 +22,7 @@ class MenuActions { MenuConstants.callFunction: _callFunction, MenuConstants.demo: _demo, MenuConstants.outline: _outline, + MenuConstants.codeCreater: _codeCreater, MenuConstants.exit: _exitApplication, }; @@ -84,6 +85,10 @@ class MenuActions { await _openOrActivateTab(context, "Demo", RouterKey.demo, Icons.code); } + static Future _codeCreater(BuildContext context) async { + await _openOrActivateTab(context, "代码生成器", RouterKey.codeCreater, Icons.code); + } + static Future _outline(BuildContext context) async { await _openOrActivateTab(context, "大纲", RouterKey.outline, Icons.outlined_flag_rounded); } diff --git a/win_text_editor/lib/menus/menu_constants.dart b/win_text_editor/lib/menus/menu_constants.dart index 3df8a8d..b53e084 100644 --- a/win_text_editor/lib/menus/menu_constants.dart +++ b/win_text_editor/lib/menus/menu_constants.dart @@ -46,4 +46,6 @@ class MenuConstants { // 帮助菜单项 static const String about = 'about'; static const String help = 'help'; + + static const String codeCreater = 'code_creater'; } diff --git a/win_text_editor/lib/modules/call_function/controllers/call_function_controller.dart b/win_text_editor/lib/modules/call_function/controllers/call_function_controller.dart index 3f891b5..5b1ba82 100644 --- a/win_text_editor/lib/modules/call_function/controllers/call_function_controller.dart +++ b/win_text_editor/lib/modules/call_function/controllers/call_function_controller.dart @@ -4,6 +4,8 @@ import 'package:win_text_editor/framework/controllers/logger.dart'; import 'package:win_text_editor/framework/services/macro_template_service.dart'; import 'package:win_text_editor/modules/call_function/models/call_function.dart'; import 'package:win_text_editor/modules/call_function/services/call_function_service.dart'; +import 'package:win_text_editor/modules/outline/models/code_partner.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; import 'package:win_text_editor/shared/uft_std_fields/field_data_source.dart'; import 'package:win_text_editor/shared/base/base_content_controller.dart'; @@ -122,4 +124,10 @@ class CallFunctionController extends BaseContentController { void onOpenFolder(String folderPath) { // 不支持打开文件夹 } + + @override + void onDropOutlineNode(OutlineNode node) { + modle.codePartners.add(CodePartner.fromOutlineNode(node)); + notifyListeners(); + } } diff --git a/win_text_editor/lib/modules/call_function/models/call_function.dart b/win_text_editor/lib/modules/call_function/models/call_function.dart index 1167def..03a2d44 100644 --- a/win_text_editor/lib/modules/call_function/models/call_function.dart +++ b/win_text_editor/lib/modules/call_function/models/call_function.dart @@ -1,3 +1,4 @@ +import 'package:win_text_editor/modules/outline/models/code_partner.dart'; import 'package:win_text_editor/modules/uft_component/models/uft_component.dart'; import 'package:win_text_editor/shared/models/std_filed.dart'; @@ -10,6 +11,7 @@ class CallFunction { final List outputParameters; List? componentList; String? factorParam; + final List codePartners = []; CallFunction({ required this.functionType, @@ -36,6 +38,13 @@ class CallFunction { 'chineseName': field.chineseName, 'type': field.type, 'isLast': inputParameters.indexOf(field) == inputParameters.length - 1, + 'partnerName': + codePartners + .firstWhere( + (partner) => partner.fields.any((f) => f == field.name), + orElse: () => CodePartner(name: null, fields: []), + ) + .name, }, ) .toList(), diff --git a/win_text_editor/lib/modules/call_function/widgets/call_function_right_side.dart b/win_text_editor/lib/modules/call_function/widgets/call_function_right_side.dart index 5247636..7f24337 100644 --- a/win_text_editor/lib/modules/call_function/widgets/call_function_right_side.dart +++ b/win_text_editor/lib/modules/call_function/widgets/call_function_right_side.dart @@ -7,11 +7,7 @@ class CallFunctionRightSide extends StatefulWidget { final CallFunctionController controller; final TextEditingController codeController; - const CallFunctionRightSide({ - super.key, - required this.controller, - required this.codeController, - }); + const CallFunctionRightSide({super.key, required this.controller, required this.codeController}); @override State createState() => _CallFunctionRightSideState(); @@ -35,11 +31,10 @@ class _CallFunctionRightSideState extends State { void _updateDisplay() { if (_selectedOperation != null) { - widget.codeController.text = - widget.controller.genCodeString([_selectedOperation!]) ?? ''; + widget.codeController.text = widget.controller.genCodeString([_selectedOperation!]) ?? ''; } else { widget.codeController.text = ''; - } + } } void _selectOperation(String? operation) { @@ -56,6 +51,7 @@ class _CallFunctionRightSideState extends State { return CodeGenerationSection( title: '生成代码', codeController: widget.codeController, + onNodeDropped: (node) => widget.controller.onDropOutlineNode(node), child: OperationRadioSection( operations: operations, selectedOperation: _selectedOperation, diff --git a/win_text_editor/lib/modules/code_creater/controllers/code_creater_controller.dart b/win_text_editor/lib/modules/code_creater/controllers/code_creater_controller.dart new file mode 100644 index 0000000..e17f29a --- /dev/null +++ b/win_text_editor/lib/modules/code_creater/controllers/code_creater_controller.dart @@ -0,0 +1,19 @@ +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; +import 'package:win_text_editor/shared/base/base_content_controller.dart'; + +class CodeCreaterController extends BaseContentController { + @override + void onOpenFile(String filePath, {dynamic appendArg}) { + // TODO: implement onOpenFile + } + + @override + void onOpenFolder(String folderPath) { + // TODO: implement onOpenFolder + } + + @override + void onDropOutlineNode(OutlineNode node) { + // TODO: implement onDropOutlineNode + } +} diff --git a/win_text_editor/lib/modules/code_creater/widgets/code_creater_view.dart b/win_text_editor/lib/modules/code_creater/widgets/code_creater_view.dart new file mode 100644 index 0000000..64e7257 --- /dev/null +++ b/win_text_editor/lib/modules/code_creater/widgets/code_creater_view.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:win_text_editor/framework/controllers/tab_items_controller.dart'; +import 'package:win_text_editor/modules/code_creater/controllers/code_creater_controller.dart'; + +class CodeCreaterView extends StatefulWidget { + final String tabId; + const CodeCreaterView({super.key, required this.tabId}); + + @override + State createState() => _CodeCreaterViewState(); +} + +class _CodeCreaterViewState extends State { + late final CodeCreaterController _controller; + bool _isControllerFromTabManager = false; + + get tabManager => Provider.of(context, listen: false); + + @override + void initState() { + super.initState(); + + final controllerFromManager = tabManager.getController(widget.tabId); + if (controllerFromManager != null) { + _controller = controllerFromManager; + _isControllerFromTabManager = true; + } else { + _controller = CodeCreaterController(); + _isControllerFromTabManager = false; + tabManager.registerController(widget.tabId, _controller); + } + } + + @override + void dispose() { + if (!_isControllerFromTabManager) { + _controller.dispose(); + } + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return const Center(child: Text('demo')); + } +} diff --git a/win_text_editor/lib/modules/content_search/controllers/content_search_controller.dart b/win_text_editor/lib/modules/content_search/controllers/content_search_controller.dart index 8924f86..bd558bb 100644 --- a/win_text_editor/lib/modules/content_search/controllers/content_search_controller.dart +++ b/win_text_editor/lib/modules/content_search/controllers/content_search_controller.dart @@ -9,6 +9,7 @@ import 'package:win_text_editor/modules/content_search/models/search_mode.dart'; import 'package:win_text_editor/modules/content_search/models/search_result.dart'; import 'package:win_text_editor/modules/content_search/services/count_search_service.dart'; import 'package:win_text_editor/modules/content_search/services/locate_search_service.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; import 'package:win_text_editor/shared/base/base_content_controller.dart'; import '../services/custom_search_service.dart'; @@ -254,4 +255,9 @@ class ContentSearchController extends BaseContentController { void onOpenFolder(String folderPath) { searchDirectory = folderPath; } + + @override + void onDropOutlineNode(OutlineNode node) { + // TODO: implement onDropOutlineNode + } } diff --git a/win_text_editor/lib/modules/data_compare/controllers/data_compare_controller.dart b/win_text_editor/lib/modules/data_compare/controllers/data_compare_controller.dart index 01d1fa7..e162f7a 100644 --- a/win_text_editor/lib/modules/data_compare/controllers/data_compare_controller.dart +++ b/win_text_editor/lib/modules/data_compare/controllers/data_compare_controller.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:win_text_editor/framework/controllers/logger.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; import 'package:win_text_editor/shared/base/base_content_controller.dart'; class DataCompareController extends BaseContentController { @@ -249,4 +250,9 @@ class DataCompareController extends BaseContentController { void onOpenFolder(String folderPath) { // TODO: implement onOpenFolder } + + @override + void onDropOutlineNode(OutlineNode node) { + // TODO: implement onDropOutlineNode + } } diff --git a/win_text_editor/lib/modules/data_extract/controllers/data_extract_controller.dart b/win_text_editor/lib/modules/data_extract/controllers/data_extract_controller.dart index 546afde..2a4b065 100644 --- a/win_text_editor/lib/modules/data_extract/controllers/data_extract_controller.dart +++ b/win_text_editor/lib/modules/data_extract/controllers/data_extract_controller.dart @@ -3,6 +3,7 @@ import 'package:win_text_editor/framework/controllers/logger.dart'; import 'package:win_text_editor/modules/data_extract/models/search_result.dart'; import 'package:win_text_editor/modules/data_extract/models/xml_rule.dart'; import 'package:win_text_editor/modules/data_extract/services/xml_extract_service.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; import 'package:win_text_editor/shared/base/base_content_controller.dart'; class DataExtractController extends BaseContentController { @@ -90,4 +91,9 @@ class DataExtractController extends BaseContentController { } void cancelExtraction() {} + + @override + void onDropOutlineNode(OutlineNode node) { + // TODO: implement onDropOutlineNode + } } diff --git a/win_text_editor/lib/modules/data_format/controllers/data_format_controller.dart b/win_text_editor/lib/modules/data_format/controllers/data_format_controller.dart index 835f592..23e339b 100644 --- a/win_text_editor/lib/modules/data_format/controllers/data_format_controller.dart +++ b/win_text_editor/lib/modules/data_format/controllers/data_format_controller.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:win_text_editor/framework/controllers/logger.dart'; import 'package:win_text_editor/modules/data_format/services/mustache_service.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; import 'package:win_text_editor/shared/base/base_content_controller.dart'; import 'grid_view_controller.dart'; @@ -107,4 +108,9 @@ class DataFormatController extends BaseContentController { gridController.dispose(); super.dispose(); } + + @override + void onDropOutlineNode(OutlineNode node) { + // TODO: implement onDropOutlineNode + } } diff --git a/win_text_editor/lib/modules/demo/controllers/demo_controller.dart b/win_text_editor/lib/modules/demo/controllers/demo_controller.dart index 309d05c..da81208 100644 --- a/win_text_editor/lib/modules/demo/controllers/demo_controller.dart +++ b/win_text_editor/lib/modules/demo/controllers/demo_controller.dart @@ -1,3 +1,4 @@ +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; import 'package:win_text_editor/shared/base/base_content_controller.dart'; class DemoController extends BaseContentController { @@ -10,4 +11,9 @@ class DemoController extends BaseContentController { void onOpenFolder(String folderPath) { // TODO: implement onOpenFolder } + + @override + void onDropOutlineNode(OutlineNode node) { + // TODO: implement onDropOutlineNode + } } diff --git a/win_text_editor/lib/modules/memory_table/controllers/memory_table_controller.dart b/win_text_editor/lib/modules/memory_table/controllers/memory_table_controller.dart index ea29381..9b13a43 100644 --- a/win_text_editor/lib/modules/memory_table/controllers/memory_table_controller.dart +++ b/win_text_editor/lib/modules/memory_table/controllers/memory_table_controller.dart @@ -1,6 +1,8 @@ import 'package:syncfusion_flutter_datagrid/datagrid.dart'; import 'package:win_text_editor/framework/controllers/logger.dart'; import 'package:win_text_editor/framework/services/macro_template_service.dart'; +import 'package:win_text_editor/modules/outline/models/code_partner.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; import 'package:win_text_editor/shared/models/std_filed.dart'; import 'package:win_text_editor/shared/uft_std_fields/field_data_source.dart'; import 'package:win_text_editor/modules/memory_table/controllers/index_data_source.dart'; @@ -131,4 +133,10 @@ class MemoryTableController extends BaseContentController { void dispose() { super.dispose(); } + + @override + void onDropOutlineNode(OutlineNode node) { + _memoryTable.codePartners.add(CodePartner.fromOutlineNode(node)); + notifyListeners(); + } } diff --git a/win_text_editor/lib/modules/memory_table/models/memory_table.dart b/win_text_editor/lib/modules/memory_table/models/memory_table.dart index 9c7408c..84cbf14 100644 --- a/win_text_editor/lib/modules/memory_table/models/memory_table.dart +++ b/win_text_editor/lib/modules/memory_table/models/memory_table.dart @@ -1,3 +1,4 @@ +import 'package:win_text_editor/modules/outline/models/code_partner.dart'; import 'package:win_text_editor/shared/base/selectable_item.dart'; import 'package:win_text_editor/shared/models/std_filed.dart'; @@ -10,7 +11,6 @@ class Index implements SelectableItem { final String rule; @override bool isSelected; - String get id => indexName; List get fields => indexFields.split(',').map((e) => e.trim()).toList(); @@ -20,6 +20,7 @@ class MemoryTable { final String tableName; final List columns; final List indexes; + final List codePartners = []; MemoryTable({required this.tableName, required this.columns, required this.indexes}); @@ -79,6 +80,13 @@ class MemoryTable { 'chineseName': field.chineseName, 'type': field.type, 'isLast': columns.indexOf(field) == columns.length - 1, + 'partnerName': + codePartners + .firstWhere( + (partner) => partner.fields.any((f) => f == field.name), + orElse: () => CodePartner(name: null, fields: []), + ) + .name, }, ) .toList(), @@ -91,6 +99,13 @@ class MemoryTable { 'chineseName': field.chineseName, 'type': field.type, 'isLast': selectFields.indexOf(field) == selectFields.length - 1, + 'partnerName': + codePartners + .firstWhere( + (partner) => partner.fields.any((f) => f == field.name), + orElse: () => CodePartner(name: null, fields: []), + ) + .name, }, ) .toList(), diff --git a/win_text_editor/lib/modules/memory_table/widgets/memory_table_right_side.dart b/win_text_editor/lib/modules/memory_table/widgets/memory_table_right_side.dart index 5a1b426..fe9aa70 100644 --- a/win_text_editor/lib/modules/memory_table/widgets/memory_table_right_side.dart +++ b/win_text_editor/lib/modules/memory_table/widgets/memory_table_right_side.dart @@ -1,18 +1,14 @@ // memory_table_right_side.dart import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:win_text_editor/modules/memory_table/controllers/memory_table_controller.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; import 'package:win_text_editor/shared/components/code_generation_components.dart'; class MemoryTableRightSide extends StatefulWidget { final MemoryTableController controller; final TextEditingController codeController; - const MemoryTableRightSide({ - super.key, - required this.controller, - required this.codeController, - }); + const MemoryTableRightSide({super.key, required this.controller, required this.codeController}); @override State createState() => _MemoryTableRightSideState(); @@ -36,8 +32,7 @@ class _MemoryTableRightSideState extends State { void _updateDisplay() { if (_selectedOperation != null) { - widget.codeController.text = - widget.controller.genCodeString([_selectedOperation!]) ?? ''; + widget.codeController.text = widget.controller.genCodeString([_selectedOperation!]) ?? ''; } else { widget.codeController.text = ''; } @@ -52,13 +47,12 @@ class _MemoryTableRightSideState extends State { @override Widget build(BuildContext context) { - final operations = [ - '获取记录', '获取记录数', '插入记录', '修改记录', '删除记录', '遍历记录' - ]; + final operations = ['获取记录', '获取记录数', '插入记录', '修改记录', '删除记录', '遍历记录']; return CodeGenerationSection( title: '生成代码', codeController: widget.codeController, + onNodeDropped: (node) => widget.controller.onDropOutlineNode(node), child: OperationRadioSection( operations: operations, selectedOperation: _selectedOperation, diff --git a/win_text_editor/lib/modules/module_router.dart b/win_text_editor/lib/modules/module_router.dart index f62a9bf..f01fffa 100644 --- a/win_text_editor/lib/modules/module_router.dart +++ b/win_text_editor/lib/modules/module_router.dart @@ -3,6 +3,8 @@ import 'package:flutter/material.dart'; import 'package:win_text_editor/framework/models/tab_model.dart'; import 'package:win_text_editor/modules/call_function/controllers/call_function_controller.dart'; import 'package:win_text_editor/modules/call_function/widgets/call_function_view.dart'; +import 'package:win_text_editor/modules/code_creater/controllers/code_creater_controller.dart'; +import 'package:win_text_editor/modules/code_creater/widgets/code_creater_view.dart'; import 'package:win_text_editor/modules/data_compare/controllers/data_compare_controller.dart'; import 'package:win_text_editor/modules/data_compare/widgets/data_compare_view.dart'; import 'package:win_text_editor/modules/data_extract/controllers/data_extract_controller.dart'; @@ -36,6 +38,7 @@ class RouterKey { static const String callFunction = 'call_function'; static const String outline = 'outline'; static const String demo = 'demo'; + static const String codeCreater = 'code_creater'; } class ModuleRouter { @@ -51,6 +54,7 @@ class ModuleRouter { RouterKey.uftComponent: (tab) => UftComponentController(), RouterKey.callFunction: (tab) => CallFunctionController(), RouterKey.demo: (tab) => DemoController(), + RouterKey.codeCreater: (tab) => CodeCreaterController(), }; // 映射UI组件 @@ -65,6 +69,7 @@ class ModuleRouter { RouterKey.uftComponent: (tab, controller) => UftComponentView(tabId: tab.id), RouterKey.callFunction: (tab, controller) => CallFunctionView(tabId: tab.id), RouterKey.demo: (tab, controller) => DemoView(tabId: tab.id), + RouterKey.codeCreater: (tab, controller) => CodeCreaterView(tabId: tab.id), }; static BaseContentController? createControllerForTab(AppTab tab) { diff --git a/win_text_editor/lib/modules/outline/models/code_partner.dart b/win_text_editor/lib/modules/outline/models/code_partner.dart new file mode 100644 index 0000000..5ef8fa6 --- /dev/null +++ b/win_text_editor/lib/modules/outline/models/code_partner.dart @@ -0,0 +1,33 @@ +import 'package:path/path.dart' as path; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; +import 'package:win_text_editor/modules/outline/services/component_service.dart'; +import 'package:win_text_editor/modules/outline/services/uft_object_service.dart'; + +class CodePartner { + final String? name; + final List fields; + + CodePartner({required this.name, required this.fields}); + + factory CodePartner.fromOutlineNode(OutlineNode node) { + String? name; + List fields = []; + switch (node.value) { + case "UFTTable": + final List? values = UftObjectService.uftObjectMap[node.title]; + if (values != null && values.isNotEmpty) { + name = path.basenameWithoutExtension(values[0]); + fields.addAll(values.sublist(1)); + } + break; + case "Component": + name = node.name; + final List? values = ComponentService.componentFieldMap[node.name]; + if (values != null && values.isNotEmpty) { + fields.addAll(values.sublist(1)); + } + break; + } + return CodePartner(name: name, fields: fields); + } +} diff --git a/win_text_editor/lib/modules/outline/models/outline_node.dart b/win_text_editor/lib/modules/outline/models/outline_node.dart index 375b1b1..2af38bb 100644 --- a/win_text_editor/lib/modules/outline/models/outline_node.dart +++ b/win_text_editor/lib/modules/outline/models/outline_node.dart @@ -21,6 +21,7 @@ class OutlineNode implements TreeNode { bool isExpanded; final int frequency; + @override late String id; final String value; @@ -39,7 +40,7 @@ class OutlineNode implements TreeNode { List? children, this.title = "", }) : _children = children ?? [] { - id = DateTime.now().microsecondsSinceEpoch.toRadixString(36); + id = DateTime.now().microsecondsSinceEpoch.toRadixString(36) + value.hashCode.toRadixString(36); } OutlineNode copyWith({bool? isExpanded, List? children}) { diff --git a/win_text_editor/lib/modules/template_parser/controllers/template_parser_controller.dart b/win_text_editor/lib/modules/template_parser/controllers/template_parser_controller.dart index 5275b5f..92f5795 100644 --- a/win_text_editor/lib/modules/template_parser/controllers/template_parser_controller.dart +++ b/win_text_editor/lib/modules/template_parser/controllers/template_parser_controller.dart @@ -1,5 +1,6 @@ import 'package:file_picker/file_picker.dart'; import 'package:win_text_editor/framework/controllers/logger.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; import 'package:win_text_editor/shared/models/template_node.dart'; import 'package:win_text_editor/shared/base/base_content_controller.dart'; import 'package:xml/xml.dart' as xml; @@ -385,4 +386,9 @@ class TemplateParserController extends BaseContentController { gridController.dispose(); super.dispose(); } + + @override + void onDropOutlineNode(OutlineNode node) { + // TODO: implement onDropOutlineNode + } } diff --git a/win_text_editor/lib/modules/uft_component/controllers/uft_component_controller.dart b/win_text_editor/lib/modules/uft_component/controllers/uft_component_controller.dart index d31f2a7..7b90e7a 100644 --- a/win_text_editor/lib/modules/uft_component/controllers/uft_component_controller.dart +++ b/win_text_editor/lib/modules/uft_component/controllers/uft_component_controller.dart @@ -1,6 +1,8 @@ import 'package:syncfusion_flutter_datagrid/datagrid.dart'; import 'package:win_text_editor/framework/controllers/logger.dart'; import 'package:win_text_editor/framework/services/macro_template_service.dart'; +import 'package:win_text_editor/modules/outline/models/code_partner.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; import 'package:win_text_editor/modules/uft_component/controllers/component_source.dart'; import 'package:win_text_editor/modules/uft_component/models/uft_component.dart'; import 'package:win_text_editor/modules/uft_component/services/uft_component_service.dart'; @@ -125,4 +127,10 @@ class UftComponentController extends BaseContentController { notifyListeners(); } } + + @override + void onDropOutlineNode(OutlineNode node) { + _currentUftComponent.codePartners.add(CodePartner.fromOutlineNode(node)); + notifyListeners(); + } } diff --git a/win_text_editor/lib/modules/uft_component/models/uft_component.dart b/win_text_editor/lib/modules/uft_component/models/uft_component.dart index 03ebc74..2dd5710 100644 --- a/win_text_editor/lib/modules/uft_component/models/uft_component.dart +++ b/win_text_editor/lib/modules/uft_component/models/uft_component.dart @@ -1,4 +1,5 @@ import 'package:win_text_editor/modules/memory_table/models/memory_table.dart'; +import 'package:win_text_editor/modules/outline/models/code_partner.dart'; import 'package:win_text_editor/shared/base/selectable_item.dart'; import 'package:win_text_editor/shared/models/std_filed.dart'; @@ -11,6 +12,8 @@ class UftComponent implements SelectableItem { @override bool isSelected; + final List codePartners = []; + UftComponent({ required this.id, required this.name, @@ -37,6 +40,13 @@ class UftComponent implements SelectableItem { 'chineseName': field.chineseName, 'type': field.type, 'isLast': fields.indexOf(field) == fields.length - 1, + 'partnerName': + codePartners + .firstWhere( + (partner) => partner.fields.any((f) => f == field.name), + orElse: () => CodePartner(name: null, fields: []), + ) + .name, }, ) .toList(), @@ -49,6 +59,13 @@ class UftComponent implements SelectableItem { 'chineseName': field.chineseName, 'type': field.type, 'isLast': selectFields.indexOf(field) == selectFields.length - 1, + 'partnerName': + codePartners + .firstWhere( + (partner) => partner.fields.any((f) => f == field.name), + orElse: () => CodePartner(name: null, fields: []), + ) + .name, }, ) .toList(), diff --git a/win_text_editor/lib/modules/uft_component/widgets/uft_component_right_side.dart b/win_text_editor/lib/modules/uft_component/widgets/uft_component_right_side.dart index b645f3c..e497f79 100644 --- a/win_text_editor/lib/modules/uft_component/widgets/uft_component_right_side.dart +++ b/win_text_editor/lib/modules/uft_component/widgets/uft_component_right_side.dart @@ -7,11 +7,7 @@ class UftComponentRightSide extends StatefulWidget { final UftComponentController controller; final TextEditingController codeController; - const UftComponentRightSide({ - super.key, - required this.controller, - required this.codeController, - }); + const UftComponentRightSide({super.key, required this.controller, required this.codeController}); @override State createState() => _UftComponentRightSideState(); @@ -35,11 +31,10 @@ class _UftComponentRightSideState extends State { void _updateDisplay() { if (_selectedOperation != null) { - widget.codeController.text = - widget.controller.genCodeString([_selectedOperation!]) ?? ''; + widget.codeController.text = widget.controller.genCodeString([_selectedOperation!]) ?? ''; } else { widget.codeController.text = ''; - } + } } void _selectOperation(String? operation) { @@ -51,13 +46,12 @@ class _UftComponentRightSideState extends State { @override Widget build(BuildContext context) { - final operations = [ - '插入组件', '修改组件', '获取组件', '遍历组件', '组件大小', '尾部插入组件' - ]; + final operations = ['插入组件', '修改组件', '获取组件', '遍历组件', '组件大小', '尾部插入组件']; return CodeGenerationSection( title: '生成代码', codeController: widget.codeController, + onNodeDropped: (node) => widget.controller.onDropOutlineNode(node), child: OperationRadioSection( operations: operations, selectedOperation: _selectedOperation, diff --git a/win_text_editor/lib/modules/xml_search/controllers/xml_search_controller.dart b/win_text_editor/lib/modules/xml_search/controllers/xml_search_controller.dart index 622e7d0..80ed367 100644 --- a/win_text_editor/lib/modules/xml_search/controllers/xml_search_controller.dart +++ b/win_text_editor/lib/modules/xml_search/controllers/xml_search_controller.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:win_text_editor/framework/controllers/logger.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; import 'package:win_text_editor/modules/xml_search/models/search_result.dart'; import 'package:win_text_editor/modules/xml_search/services/xml_search_service.dart'; import 'package:win_text_editor/shared/base/base_content_controller.dart'; @@ -159,4 +160,9 @@ class XmlSearchController extends BaseContentController { notifyListeners(); } } + + @override + void onDropOutlineNode(OutlineNode node) { + // TODO: implement onDropOutlineNode + } } diff --git a/win_text_editor/lib/shared/base/base_content_controller.dart b/win_text_editor/lib/shared/base/base_content_controller.dart index b6eda0a..14beece 100644 --- a/win_text_editor/lib/shared/base/base_content_controller.dart +++ b/win_text_editor/lib/shared/base/base_content_controller.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; abstract class BaseContentController with ChangeNotifier { void onOpenFolder(String folderPath); void onOpenFile(String filePath, {dynamic appendArg}); + + void onDropOutlineNode(OutlineNode node); } diff --git a/win_text_editor/lib/shared/components/code_generation_components.dart b/win_text_editor/lib/shared/components/code_generation_components.dart index fdc17ab..7b25991 100644 --- a/win_text_editor/lib/shared/components/code_generation_components.dart +++ b/win_text_editor/lib/shared/components/code_generation_components.dart @@ -1,6 +1,7 @@ // shared/components/code_generation_components.dart import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:win_text_editor/modules/outline/models/outline_node.dart'; class CodeGenerationRadioItem extends StatelessWidget { final String label; @@ -34,42 +35,58 @@ class CodeGenerationSection extends StatelessWidget { final String title; final Widget child; final TextEditingController codeController; + final Function(OutlineNode)? onNodeDropped; // 新增拖入回调 + final bool droppable; // 新增是否可拖入属性 const CodeGenerationSection({ super.key, required this.title, required this.child, required this.codeController, + this.onNodeDropped, + this.droppable = true, // 默认允许拖入 }); @override Widget build(BuildContext context) { - return Column( - children: [ - child, - Padding( - padding: const EdgeInsets.only(left: 8.0, right: 8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text('$title:', style: const TextStyle(fontWeight: FontWeight.bold)), - IconButton( - icon: const Icon(Icons.content_copy, size: 20), - tooltip: '复制代码', - onPressed: () { - if (codeController.text.isNotEmpty) { - Clipboard.setData(ClipboardData(text: codeController.text)); - ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text('已复制到剪贴板'))); - } - }, + return DragTarget( + onWillAcceptWithDetails: (data) { + // 检查是否允许拖入 + return _checkIsDroppable(data.data); + }, + onAcceptWithDetails: (detail) { + // 触发拖入事件 + onNodeDropped?.call(detail.data); + }, + builder: (context, candidateData, rejectedData) { + return Column( + children: [ + child, + Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('$title:', style: const TextStyle(fontWeight: FontWeight.bold)), + IconButton( + icon: const Icon(Icons.content_copy, size: 20), + tooltip: '复制代码', + onPressed: () { + if (codeController.text.isNotEmpty) { + Clipboard.setData(ClipboardData(text: codeController.text)); + ScaffoldMessenger.of( + context, + ).showSnackBar(const SnackBar(content: Text('已复制到剪贴板'))); + } + }, + ), + ], ), - ], - ), - ), - Flexible(child: _buildCodeEditor(codeController)), - ], + ), + Flexible(child: _buildCodeEditor(codeController)), + ], + ); + }, ); } @@ -96,6 +113,21 @@ class CodeGenerationSection extends StatelessWidget { ), ); } + + bool _checkIsDroppable(OutlineNode outlineNode) { + if (outlineNode.depth < 3) { + return false; + } + switch (outlineNode.value) { + case "UFTTable": + case "Business": + case "Atom": + case "Component": + return true; // 允许拖入这些类型的节点 + default: + return false; // 其他类型的节点不允许拖入 + } + } } class OperationRadioSection extends StatelessWidget { diff --git a/win_text_editor/lib/test.dart b/win_text_editor/lib/test.dart new file mode 100644 index 0000000..594d8f9 --- /dev/null +++ b/win_text_editor/lib/test.dart @@ -0,0 +1,22 @@ +import 'package:mustache_template/mustache.dart'; + +void main() { + final template = Template(''' + {{#value}}Value exists: {{value}},{{/value}} + others... + '''); + + print(template.renderString({'value': '有内容'})); + + // ✅ 正确做法1:key 完全不存在 + print(template.renderString({'value': ''})); + // 输出: "No value provided" + + // ✅ 正确做法2:显式设置为 null(需确保非空安全环境) + print(template.renderString({'value': null})); + // 输出: "No value provided" + + // ❌ 以下会报错: + // print(template.renderString({'value': ''})); // 空字符串 + // print(template.renderString({'value': 'Hello'})); // 非空字符串 +} diff --git a/win_text_editor/pubspec.lock b/win_text_editor/pubspec.lock index 8f53262..b2c8a0b 100644 --- a/win_text_editor/pubspec.lock +++ b/win_text_editor/pubspec.lock @@ -141,10 +141,10 @@ packages: dependency: "direct main" description: name: file_picker - sha256: "77f8e81d22d2a07d0dee2c62e1dda71dc1da73bf43bb2d45af09727406167964" + sha256: ef9908739bdd9c476353d6adff72e88fd00c625f5b959ae23f7567bd5137db0a url: "https://pub.flutter-io.cn" source: hosted - version: "10.1.9" + version: "10.2.0" flutter: dependency: "direct main" description: flutter @@ -187,6 +187,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_treeview: + dependency: "direct main" + description: + name: flutter_treeview + sha256: ce7a66452e02877700890cb674773ea0af28d914192acfb5bf55a50ce35b5819 + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.7+1" flutter_web_plugins: dependency: transitive description: flutter @@ -408,6 +416,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "6.1.5" + quiver: + dependency: "direct main" + description: + name: quiver + sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.2.2" rxdart: dependency: transitive description: diff --git a/win_text_editor/pubspec.yaml b/win_text_editor/pubspec.yaml index 388b0ae..5d9cd99 100644 --- a/win_text_editor/pubspec.yaml +++ b/win_text_editor/pubspec.yaml @@ -29,6 +29,8 @@ dependencies: yaml: ^3.1.1 pluto_grid: ^8.0.0 jieba_flutter: ^0.2.0 + flutter_treeview: ^1.0.7+1 + quiver: ^3.2.2 dev_dependencies: flutter_test: