diff --git a/win_text_editor/.vscode/settings.json b/win_text_editor/.vscode/settings.json index 9e26dfe..a27a16d 100644 --- a/win_text_editor/.vscode/settings.json +++ b/win_text_editor/.vscode/settings.json @@ -1 +1,3 @@ -{} \ No newline at end of file +{ + "cmake.sourceDirectory": "D:/aigc/manta/win_text_editor/linux" +} \ No newline at end of file diff --git a/win_text_editor/assets/config/uft_macro_list.yaml b/win_text_editor/assets/config/uft_macro_list.yaml index 63fa523..628985b 100644 --- a/win_text_editor/assets/config/uft_macro_list.yaml +++ b/win_text_editor/assets/config/uft_macro_list.yaml @@ -18,6 +18,15 @@ templates: }else{ } + + 获取记录_ALL: + body: | + [获取记录][{{tableName}}({{keyName}})][ + {{#keyFields}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} + {{/keyFields}} + ][] + 获取记录数: @@ -36,7 +45,7 @@ templates: [获取记录][{{tableName}}({{keyName}})][ {{#keyFields}} - {{name}} = @{{name}} {{^isLast}}, {{/isLast}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}} {{^isLast}}, {{/isLast}} {{/keyFields}} ] @@ -48,7 +57,7 @@ templates: [修改索引字段][{{tableName}}][ {{#keyFields}} - {{name}} = @{{name}}{{^isLast}}, {{/isLast}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}}, {{/isLast}} {{/keyFields}} ] } @@ -104,6 +113,23 @@ templates: //balabala } [遍历记录结束] + + 遍历记录_ALL: + body: | + [遍历记录开始][{{tableName}}({{selectIndexOrKey.name}})][ + {{#selectIndexOrKey.fields}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} + {{/selectIndexOrKey.fields}} + ][ + {{#selectedFields}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} + {{/selectedFields}} + ] + + + 遍历记录结束_ALL: + body: | + [遍历记录结束] 插入组件: body: | @@ -136,6 +162,17 @@ templates: {{/selectedFields}} ] + 获取组件_ALL: + body: | + {{#hasIndex}}[组件排序][{{name}}(index.name)]{{/hasIndex}} + [获取组件][{{name}}{{#hasIndex}}({{index.name}}){{/hasIndex}}][{{^hasIndex}}[@num][{{/hasIndex}} + {{#hasIndex}} + {{#index.fields}} + {{name}} = @{{name}}{{^isLast}}, {{/isLast}} + {{/index.fields}} + ][ + {{/hasIndex}}] + 遍历组件: body: | {{#hasIndex}}[组件排序][{{name}}({{index.name}})]{{/hasIndex}} @@ -153,7 +190,7 @@ templates: { } - "[遍历组件结束]" + [遍历组件结束] 组件大小: body: "[组件大小][{{name}}][@num]" @@ -166,7 +203,7 @@ templates: {{/fields}} ] - 遍历组件所有: + 遍历组件_ALL: body: | {{#hasIndex}}[组件排序][{{name}}({{index.name}})]{{/hasIndex}} [遍历组件开始][{{name}}{{#hasIndex}}({{index.name}}){{/hasIndex}}][ @@ -175,19 +212,16 @@ templates: {{name}} = @{{name}} {{^isLast}}, {{/isLast}} {{/index.fields}} {{/hasIndex}} - ][ - {{#fields}} - {{name}} = @{{name}}{{^isLast}}, {{/isLast}} - {{/fields}} ] - { - } - "[遍历组件结束]" + + 遍历组件结束_ALL: + body: | + [遍历组件结束] - 普通调用: + 普通调用_ALL: body: | - [{{chineseName}}][ + [{{chineseName}}][ {{#input}} {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}},{{/isLast}} {{/input}} @@ -196,6 +230,19 @@ templates: {{name}} = @{{name}}{{^isLast}},{{/isLast}} {{/output}} ] + + + 普通调用: + body: | + [{{chineseName}}][ + {{#selectedInput}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}},{{/isLast}} + {{/selectedInput}} + ][ + {{#selectedOutput}} + {{name}} = @{{name}}{{^isLast}},{{/isLast}} + {{/selectedOutput}} + ] [处理失败] { [错误信息获取] @@ -206,9 +253,33 @@ templates: else { //balabala - } + } 事务调用: + body: | + [事务处理开始] + [{{chineseName}}][ + {{#selectedInput}} + {{name}} = @{{#partnerName}}{{partnerName}}.{{/partnerName}}{{name}}{{^isLast}},{{/isLast}} + {{/selectedInput}} + ][ + {{#selectedOutput}} + {{name}} = @{{name}}{{^isLast}},{{/isLast}} + {{/selectedOutput}} + ] + [处理失败] + { + [错误信息获取] + //TODO:处理异常 + [事务回滚] + [继续执行] + } + else + { + [事务处理结束] + } + + 事务调用_ALL: body: | [事务处理开始] [{{chineseName}}][ @@ -230,7 +301,7 @@ templates: else { [事务处理结束] - } + } 因子服务: body: | 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 a7c5ec1..70a68ce 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 @@ -10,6 +10,7 @@ class CallFunction { final List inputParameters; final List outputParameters; List? componentList; + List? outComponentList; String? factorParam; final List codePartners = []; @@ -20,6 +21,7 @@ class CallFunction { required this.inputParameters, required this.outputParameters, this.componentList, + this.outComponentList, this.factorParam, }); diff --git a/win_text_editor/lib/modules/call_function/services/call_function_service.dart b/win_text_editor/lib/modules/call_function/services/call_function_service.dart index 157ca42..1d2c6f9 100644 --- a/win_text_editor/lib/modules/call_function/services/call_function_service.dart +++ b/win_text_editor/lib/modules/call_function/services/call_function_service.dart @@ -50,6 +50,8 @@ class CallFunctionService { List componentList = []; + List outComponentList = []; + // 5. Process inputParameters (fields) final inputParameters = document.findAllElements( extendFileName == "uftfactorservice" ? 'internalParams' : 'inputParameters', @@ -65,7 +67,7 @@ class CallFunctionService { // 6. Process outputParameters final outputParameters = document.findAllElements('outputParameters'); - final outputFields = await parserFields(filePath, outputParameters, componentList); + final outputFields = await parserFields(filePath, outputParameters, outComponentList); return CallFunction( functionType: extendFileName, @@ -74,6 +76,7 @@ class CallFunctionService { inputParameters: inputFields, outputParameters: outputFields, componentList: componentList, + outComponentList: outComponentList, factorParam: factorParam, ); } on xml.XmlParserException catch (e) { 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 index a1d610e..812e50d 100644 --- 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 @@ -43,7 +43,16 @@ class CodeCreaterController extends BaseContentController { return; } + if (members.contains(node)) { + Logger().error('不支持重复节点: ${node.title}'); + return; + } + + //新节点重新设置默认操作 + node.selectedAction = CodeCreateService.getNodeActions(node.name)[0]; + members.add(node); + notifyListeners(); } @@ -52,7 +61,31 @@ class CodeCreaterController extends BaseContentController { } void handleActionTypeChange(int index, String newAction) { - members[index].selectedAction = newAction; + final memberName = members[index].name; + + if (newAction == "遍历记录") { + members.add( + OutlineNode( + name: '${members[index].name}_END', + title: members[index].title, + value: '${members[index].value}_END', + selectedAction: "遍历记录结束", + ), + ); + } else if (newAction == "遍历组件") { + members.add( + OutlineNode( + name: '${members[index].name}_END', + title: members[index].title, + value: '${members[index].value}_END', + selectedAction: "遍历组件结束", + ), + ); + } else { + members.removeWhere((member) => member.name == '${memberName}_END'); + } + + // members[index].selectedAction = newAction; notifyListeners(); } } diff --git a/win_text_editor/lib/modules/code_creater/services/code_create_service.dart b/win_text_editor/lib/modules/code_creater/services/code_create_service.dart new file mode 100644 index 0000000..bd2409d --- /dev/null +++ b/win_text_editor/lib/modules/code_creater/services/code_create_service.dart @@ -0,0 +1,290 @@ +import 'package:flutter/material.dart'; +import 'package:win_text_editor/framework/common/constants.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/memory_table/models/memory_table.dart'; +import 'package:win_text_editor/modules/memory_table/services/memory_table_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/models/uft_component.dart'; +import 'package:win_text_editor/modules/uft_component/services/uft_component_service.dart'; + +class CodeCreateService { + static List getNodeActions(String type) { + switch (type) { + case Constants.atomFunction: + case Constants.atomService: + case Constants.business: + return ['普通调用', '事务调用']; + case Constants.uftTable: + return ['获取记录', '遍历记录', '插入记录', '修改记录', '删除记录']; + case Constants.component: + return ['获取组件', '遍历组件', '插入组件', '修改组件', '尾部插入组件']; + case "${Constants.component}_END": + return ['遍历组件结束']; + case "${Constants.uftTable}_END": + return ['遍历记录结束']; + default: + return ['']; // 确保返回非空列表 + } + } + + static final MacroTemplateService templateService = MacroTemplateService(); + + static void initTemplateService() { + if (!templateService.inited) { + templateService.init(); + } + } + + static Future genCodeString(List members, String selectedOperation) async { + initTemplateService(); + + //遍历members,获取每个节点的value + StringBuffer codeBuffer = StringBuffer("//生成$selectedOperation代码\n\n"); + + List inputFields = []; //各个节点入参字段名 + List outputFields = []; //各个节点出参字段名 + List macroCodeList = []; //各个节点生成代码 + List beforePartner = []; //前序参数伙伴 + Map> iterateOutputFields = {}; //遍历出参字段-不能在遍历外部使用 + Map> iteratePartnerMap = {}; //遍历出参伙伴 + List iterateStack = []; //遍历栈 + + //处理关系 + Future parseRelationShips(List nodes, String selectedOperation) async { + for (int i = 0; i < members.length; i++) { + final member = members[i]; + final action = + member.selectedAction!.isEmpty + ? getNodeActions(member.value)[0] + : member.selectedAction; + + //遍历结束特殊处理 + if (action!.startsWith("遍历") && action.endsWith("结束")) { + //将当前遍历块内变量清除 + final memberName = iterateStack.removeLast(); + debugPrint('删除遍历块:$memberName'); + iterateOutputFields.remove(memberName); + iteratePartnerMap.remove(memberName); + + final macroCode = templateService.renderTemplate([action], {}, selectAll: true); + macroCodeList.add(macroCode); + continue; + } + + switch (member.value) { + case Constants.atomFunction: + case Constants.atomService: + case Constants.business: + CallFunction model = await CallFunctionService.parseXmlFile(member.path!); + model.codePartners.clear(); //清除原有的伙伴 + + //将不包含在全局出参中入参加入全局入参中 + inputFields.addAll( + model.inputParameters + .where( + (field) => + !outputFields.contains(field.name) && + !inputFields.contains(field.name) && + !iterateOutputFields.values.expand((list) => list).contains(field.name), + ) + .map((field) => field.name), + ); + + //全局前序伙伴加入到节点中 + model.codePartners.addAll(beforePartner.toSet()); + + //遍历作用域前序伙伴加入到节点中 + model.codePartners.addAll( + iteratePartnerMap.values.expand((partners) => partners).toList(), + ); + + //将出参加入作用域出参列表中 + if (iterateStack.isNotEmpty) { + //仍在遍历块内,加入最近遍历块中 + iterateOutputFields + .putIfAbsent(iterateStack.last, () => []) + .addAll(model.outputParameters.map((field) => field.name).toSet()); + + //出参组件处理:将出参组件加入遍历块的出参列表和伙伴列表中 + for (UftComponent component in model.outComponentList!) { + List fieldNames = []; + for (var field in component.fields) { + fieldNames.add(field.name); + } + iterateOutputFields + .putIfAbsent(iterateStack.last, () => []) + .addAll(component.fields.map((field) => field.name).toSet()); + iteratePartnerMap + .putIfAbsent(component.name, () => []) + .add(CodePartner(name: component.name, fields: fieldNames)); + } + } else { + //加入全局出参中 + outputFields.addAll( + model.outputParameters + .where((field) => !outputFields.contains(field.name)) + .map((field) => field.name), + ); + + //出参组件处理 + for (UftComponent component in model.outComponentList!) { + List fieldNames = component.fields.map((col) => col.name).toList(); + outputFields.addAll(fieldNames.toSet()); + beforePartner.add(CodePartner(name: member.name, fields: fieldNames)); + } + } + + final macroCode = templateService.renderTemplate( + [action], + model.toMap(), + selectAll: true, + ); + macroCodeList.add(macroCode); + + break; + case Constants.uftTable: + TableData tableData = await MemoryTableService.parseStructureFile(member.path!); + + final memoryTable = MemoryTable( + tableName: tableData.tableName, + columns: tableData.fields, + indexes: tableData.indexes, + ); + + memoryTable.codePartners.clear(); + + //全局前序伙伴加入到节点中 + memoryTable.codePartners.addAll(beforePartner.toSet()); + + //遍历作用域前序伙伴加入到节点中 + memoryTable.codePartners.addAll( + iteratePartnerMap.values.expand((partners) => partners).toList(), + ); + + List fieldNames = memoryTable.columns.map((col) => col.name).toList(); + + switch (action) { + case '获取记录': + for (var fieldName in memoryTable.keyFields) { + if (!outputFields.contains(fieldName) && + !inputFields.contains(fieldName) && + !iterateOutputFields.values.expand((list) => list).contains(fieldName)) { + inputFields.add(fieldName); + } + } + + if (iterateStack.isNotEmpty) { + //仍在遍历块内,加入最近遍历块中 + iterateOutputFields.putIfAbsent(iterateStack.last, () => []).addAll(fieldNames); + iteratePartnerMap + .putIfAbsent(member.name, () => []) + .add(CodePartner(name: member.name, fields: fieldNames)); + } else { + //加入全局出参中 + outputFields.addAll(fieldNames); + beforePartner.add(CodePartner(name: member.name, fields: fieldNames)); + } + break; + case '遍历记录': + List fieldNames = memoryTable.columns.map((col) => col.name).toList(); + iterateStack.add(memoryTable.tableName); //入栈 + + //仍在遍历块内,加入最近遍历块中 + iterateOutputFields.putIfAbsent(iterateStack.last, () => []).addAll(fieldNames); + iteratePartnerMap + .putIfAbsent(member.name, () => []) + .add(CodePartner(name: member.name, fields: fieldNames)); + + break; + case '插入记录': + case '修改记录': + case '删除记录': + for (var fieldName in memoryTable.keyFields) { + if (!outputFields.contains(fieldName) && + !inputFields.contains(fieldName) && + !iterateOutputFields.values.expand((list) => list).contains(fieldName)) { + inputFields.add(fieldName); + } + } + + break; + } + + final macroCode = templateService.renderTemplate( + [action!], + memoryTable.toMap(), + selectAll: true, + ); + macroCodeList.add(macroCode); + break; + case Constants.component: + final component = await UftComponentService.getUftComponent(member.path!, member.name); + component!.codePartners.clear(); + + component.codePartners.addAll(beforePartner); + component.codePartners.addAll( + iteratePartnerMap.values.expand((partners) => partners).toList(), + ); + + switch (action) { + case "获取组件": + case "遍历组件": + List fieldNames = component.fields.map((col) => col.name).toList(); + + //将出参加入作用域出参列表中 + if (iterateStack.isNotEmpty) { + //仍在遍历块内,加入最近遍历块中 + iterateOutputFields.putIfAbsent(iterateStack.last, () => []).addAll(fieldNames); + iteratePartnerMap + .putIfAbsent(member.name, () => []) + .add(CodePartner(name: member.name, fields: fieldNames)); + } else { + //加入全局出参中 + outputFields.addAll(fieldNames); + beforePartner.add(CodePartner(name: member.name, fields: fieldNames)); + } + + iterateStack.add(component.name); //入栈 + break; + + default: + for (var field in component.fields) { + if (!outputFields.contains(field.name) && + !inputFields.contains(field.name) && + !iterateOutputFields.values.expand((list) => list).contains(field.name)) { + inputFields.add(field.name); + } + } + break; + } + + final macroCode = templateService.renderTemplate( + [action], + component.toMap(), + selectAll: true, + ); + macroCodeList.add(macroCode); + break; + default: + macroCodeList.add('//未知类型: ${member.name}'); + } + } + } + + await parseRelationShips(members, selectedOperation); + + codeBuffer.writeln("//可能需要传入的参数"); + for (var field in inputFields) { + codeBuffer.writeln('@$field = ,'); + } + codeBuffer.writeln(''); + + for (final mc in macroCodeList) { + codeBuffer.write(mc); + } + return codeBuffer.toString(); + } +} 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 index f807c94..36775e1 100644 --- 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 @@ -135,6 +135,10 @@ class _CodeCreaterViewState extends State { void _deleteMember(int index) { setState(() { + final memberName = _controller.members[index].name; + //同时删除遍历结束节点 + _controller.members.removeWhere((member) => member.name == '${memberName}_END'); + _controller.members.removeAt(index); _updateDisplay(); }); diff --git a/win_text_editor/lib/modules/code_creater/widgets/node_table.dart b/win_text_editor/lib/modules/code_creater/widgets/node_table.dart index 92eaeeb..7f813dc 100644 --- a/win_text_editor/lib/modules/code_creater/widgets/node_table.dart +++ b/win_text_editor/lib/modules/code_creater/widgets/node_table.dart @@ -202,7 +202,7 @@ class NodeTableState extends State { MyPlutoColumn( title: '成员', field: 'content', - width: 300, + width: 200, enableRowChecked: false, // 允许整行选中 ), MyPlutoDropdownColumn( diff --git a/win_text_editor/lib/modules/uft_component/services/uft_component_service.dart b/win_text_editor/lib/modules/uft_component/services/uft_component_service.dart index 64c901a..c6987b7 100644 --- a/win_text_editor/lib/modules/uft_component/services/uft_component_service.dart +++ b/win_text_editor/lib/modules/uft_component/services/uft_component_service.dart @@ -17,7 +17,8 @@ class UftComponentService { static Future getUftComponent(String filePath, String componentName) async { if (_components.isNotEmpty) { - return _components.firstWhereOrNull((c) => c.name == componentName); + final com = _components.firstWhereOrNull((c) => c.name == componentName); + if (com != null) return com; } return parseComponentFile( filePath,