From 695c00aed590091929fd63cf489d54a4ac61d458 Mon Sep 17 00:00:00 2001 From: qhd <1766646056@qq.com> Date: Tue, 16 Jun 2026 13:26:27 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E6=89=A7=E8=A1=8C=E5=9B=BE=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E4=B8=8E=E8=8A=82=E7=82=B9=E4=B8=8A=E4=B8=8B=E6=96=87=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- workflow/consts/node/node_template.go | 22 ++- .../service/flow/flow_execution_service.go | 179 ++++++------------ workflow/service/flow/lambda_node.go | 116 +++++++++--- workflow/service/flow/lambda_node_imp.go | 128 ++++--------- 4 files changed, 205 insertions(+), 240 deletions(-) diff --git a/workflow/consts/node/node_template.go b/workflow/consts/node/node_template.go index ae5a104..7db8827 100644 --- a/workflow/consts/node/node_template.go +++ b/workflow/consts/node/node_template.go @@ -15,17 +15,19 @@ const ( NodeNameVideoModel = "生成视频" NodeNameAudioModel = "生成音频" NodeNameBatchModel = "批量处理一起返回" + NodeNameDataConversionModel = "参数转换" NodeNameSenseOptimizeModel = "语义优化" NodeNameStoryOptimizeModel = "分镜优化" NodeNameScriptOptimizeModel = "剧本优化" - NodeNameDataConversionModel = "参数转换" NodeNameModel = "模型" NodeNameMerge = "结果合并" NodeNameDataMerge = "结果汇集" NodeNameJudge = "条件判断" + NodeNameLoop = "循环" NodeNameForm = "表单" NodeNameHttp = "HTTP(S)接口" NodeNameCustomNode = "自定义节点" + NodeNameSystemSum = "系统-结果汇总" ) // 表单字段 Label @@ -54,20 +56,22 @@ const ( NodeTypeAudioModel NodeType = "audio_model" NodeTypeBatchModel NodeType = "batch_model" + NodeTypeDataConversionModel NodeType = "data_conversion_model" NodeTypeSenseOptimizeModel NodeType = "sense_optimize_model" NodeTypeStoryOptimizeModel NodeType = "story_optimize_model" NodeTypeScriptOptimizeModel NodeType = "script_optimize_model" // 基础 - NodeTypeDataConversionModel NodeType = "data_conversion_model" - NodeTypeModel NodeType = "model" - NodeTypeMerge NodeType = "merge" - NodeTypeDataMerge NodeType = "data_merge" - NodeTypeJudge NodeType = "judge" - NodeTypeForm NodeType = "form" - NodeTypeIntent NodeType = "intent" - NodeTypeHttp NodeType = "http" + NodeTypeModel NodeType = "model" + NodeTypeMerge NodeType = "merge" + NodeTypeDataMerge NodeType = "data_merge" + NodeTypeJudge NodeType = "judge" + NodeTypeForm NodeType = "form" + NodeTypeIntent NodeType = "intent" + NodeTypeHttp NodeType = "http" // 自定义 NodeTypeCustomNode NodeType = "custom_node" + // 系统 + NodeTypeSystemSum NodeType = "system_sum" ) const ( diff --git a/workflow/service/flow/flow_execution_service.go b/workflow/service/flow/flow_execution_service.go index 3bc103f..f85d309 100644 --- a/workflow/service/flow/flow_execution_service.go +++ b/workflow/service/flow/flow_execution_service.go @@ -363,49 +363,12 @@ func (s *flowExecutionService) Execute(ctx context.Context, req *flowDto.Execute } return nil, errors.New("文件格式不支持") } - - // ========================================================================= - // ✅【第1步】给所有判断节点自动生成意图识别节点 - // ========================================================================= - judge2IntentNodeMap := make(map[string]string) - finalNodes := make([]entity.FlowNode, 0, len(req.FlowContent.Nodes)*2) - for _, item := range req.FlowContent.Nodes { - finalNodes = append(finalNodes, item) - // 判断节点自动加 intent 节点 - if item.NodeCode == node.NodeTypeJudge { - intentNodeID := fmt.Sprintf("intent_%s", item.Id) - intentNode := entity.FlowNode{ - Id: intentNodeID, - NodeCode: node.NodeTypeIntent, - Name: fmt.Sprintf("意图识别-%s", item.Name), - InputSource: item.InputSource, // ✅ 正确赋值 - FormConfig: item.FormConfig, // ✅ 用户配置 - ModelConfig: item.ModelConfig, // ✅ 系统配置 - } - finalNodes = append(finalNodes, intentNode) - judge2IntentNodeMap[item.Id] = intentNodeID - } - } - - summaryNodeID := "summary_node" - summaryNode := entity.FlowNode{ - Id: summaryNodeID, - NodeCode: node.NodeTypeCustomNode, // 复用自定义节点类型,也可新增专属类型 - Name: "结果汇总节点", - InputSource: []entity.FlowNodeInputSource{}, // 后续自动聚合所有节点输出 - FormConfig: nil, - ModelConfig: node.ModelItem{}, - } - finalNodes = append(finalNodes, summaryNode) - - // 替换节点列表 - req.FlowContent.Nodes = finalNodes - // ========================================================================= // ✅【第2步】构建执行图 // ========================================================================= + var nodeList []entity.FlowNode var runGraph compose.Runnable[any, any] - runGraph, err = BuildGraphFromFlowContent(execCtx, req.FlowContent, judge2IntentNodeMap, summaryNodeID) + nodeList, runGraph, err = BuildGraphFromFlowContent(execCtx, req.FlowContent) if err != nil { executionReq := flowDto.UpdateFlowExecutionReq{ Id: executionId, @@ -418,7 +381,6 @@ func (s *flowExecutionService) Execute(ctx context.Context, req *flowDto.Execute } return nil, fmt.Errorf("执行工作流失败: %v", err) } - // ========================================================================= // ✅【第3步】构建 ConfigMap // ========================================================================= @@ -426,15 +388,9 @@ func (s *flowExecutionService) Execute(ctx context.Context, req *flowDto.Execute for _, cfg := range req.NodeInputParams { configMap[cfg.Id] = cfg } - // 自动给意图节点复制配置 - for judgeID, intentID := range judge2IntentNodeMap { - if cfg, ok := configMap[judgeID]; ok { - configMap[intentID] = cfg - } + for _, i := range nodeList { + configMap[i.Id] = &i } - // 初始化汇总节点配置 - configMap[summaryNodeID] = &summaryNode - // ========================================================================= // ✅【第4步】构建全局执行入参(现在 schemaMap 是有值的!) // ========================================================================= @@ -475,7 +431,7 @@ func (s *flowExecutionService) Execute(ctx context.Context, req *flowDto.Execute } // BuildGraphFromFlowContent 根据前端保存的工作流JSON,自动构建执行图 -func BuildGraphFromFlowContent(ctx context.Context, flowContent *entity.FlowInfo, judge2IntentNodeMap map[string]string, summaryNodeID string) (compose.Runnable[any, any], error) { +func BuildGraphFromFlowContent(ctx context.Context, flowContent *entity.FlowInfo) ([]entity.FlowNode, compose.Runnable[any, any], error) { // 注册自定义合并函数:处理 *flowDto.FlowExecutionInput 类型合并 // 由于 ConfigMap 是 map 引用类型,所有并行分支修改已经写入共享内存 // 直接返回第一个实例即可,所有修改都已经可见 @@ -488,9 +444,26 @@ func BuildGraphFromFlowContent(ctx context.Context, flowContent *entity.FlowInfo }) graph := compose.NewGraph[any, any]() - nodeMap := make(map[string]entity.FlowNode) + + var nodeList []entity.FlowNode + nodeId := uuid.NewString() + originalEndNodes := findEndNodes(flowContent.StartNodeId, flowContent.Edges) + for i := range originalEndNodes { + sprintf := fmt.Sprintf("%v_%d", nodeId, i) + summaryNode := entity.FlowNode{ + Id: sprintf, + NodeCode: node.NodeTypeSystemSum, + Name: node.NodeNameSystemSum, + InputSource: []entity.FlowNodeInputSource{}, // 后续自动聚合所有节点输出 + FormConfig: nil, + ModelConfig: node.ModelItem{}, + } + nodeList = append(nodeList, summaryNode) + flowContent.Nodes = append(flowContent.Nodes, summaryNode) + } // 注册所有节点 + nodeMap := make(map[string]entity.FlowNode) for _, item := range flowContent.Nodes { nodeMap[item.Id] = item if item.NodeCode != node.NodeTypeJudge { @@ -498,6 +471,16 @@ func BuildGraphFromFlowContent(ctx context.Context, flowContent *entity.FlowInfo } } + // 注册所有边 + if flowContent.StartNodeId != "" { + _ = graph.AddEdge(compose.START, flowContent.StartNodeId) + } + for i, endID := range originalEndNodes { + sprintf := fmt.Sprintf("%v_%d", nodeId, i) + _ = graph.AddEdge(endID, sprintf) + _ = graph.AddEdge(sprintf, compose.END) + } + // 构建边关系 upstreamMap := make(map[string][]string) edgeMap := make(map[string][]entity.FlowEdge) @@ -510,15 +493,8 @@ func BuildGraphFromFlowContent(ctx context.Context, flowContent *entity.FlowInfo for fromNodeID, edges := range edgeMap { fromNode := nodeMap[fromNodeID] - // -------------------------- // 判断节点 → 分支处理 - // -------------------------- if fromNode.NodeCode == node.NodeTypeJudge { - intentNodeID, ok := judge2IntentNodeMap[fromNodeID] - if !ok { - return nil, fmt.Errorf("判断节点[%s]未生成意图节点", fromNodeID) - } - branchMap := make(map[string]bool) for _, e := range edges { branchMap[e.To] = true @@ -553,11 +529,6 @@ func BuildGraphFromFlowContent(ctx context.Context, flowContent *entity.FlowInfo m["branch_id_name_map"] = branchIdNameMap // 传递ID-名称映射 currentConfig.Config = m - // 从意图节点取输出 - if intentCfg, ok := execInput.ConfigMap[intentNodeID]; ok { - currentConfig.OutputResult = intentCfg.OutputResult - } - // 关键修改:构造 NodeExecutionInput 传入 JudgeLambda nodeExecInput := &flowDto.NodeExecutionInput{ Config: currentConfig, // 当前判断节点配置 @@ -566,34 +537,21 @@ func BuildGraphFromFlowContent(ctx context.Context, flowContent *entity.FlowInfo return JudgeLambda(ctx, nodeExecInput) // 传入 NodeExecutionInput 类型 } - _ = graph.AddBranch(intentNodeID, compose.NewGraphBranch(judgeLambda, branchMap)) + _ = graph.AddBranch(upstreamMap[fromNodeID][0], compose.NewGraphBranch(judgeLambda, branchMap)) continue } - // -------------------------- // 普通节点连线 - // -------------------------- for _, e := range edges { toNode := nodeMap[e.To] if toNode.NodeCode == node.NodeTypeJudge { - _ = graph.AddEdge(e.From, fmt.Sprintf("intent_%s", toNode.Id)) continue } _ = graph.AddEdge(e.From, e.To) } } - - // ==================== 第四步:处理开始/结束节点 ==================== - if flowContent.StartNodeId != "" { - _ = graph.AddEdge(compose.START, flowContent.StartNodeId) - } - originalEndNodes := findEndNodes(flowContent.StartNodeId, flowContent.Edges) - for _, endID := range originalEndNodes { - _ = graph.AddEdge(endID, summaryNodeID) - } - _ = graph.AddEdge(summaryNodeID, compose.END) - - return graph.Compile(ctx, compose.WithGraphName("auto_build_workflow"), compose.WithNodeTriggerMode(compose.AllPredecessor)) + compile, err := graph.Compile(ctx, compose.WithGraphName("auto_build_workflow")) + return nodeList, compile, err } // -------------------------- 节点自动注册器(核心分发) -------------------------- @@ -703,13 +661,11 @@ func registerNodeToGraph(graph *compose.Graph[any, any], flowNode entity.FlowNod return execInput, nil } } - if nodeID == "summary_node" { - _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(SummaryLambda))) - return - } switch code { case "__start__": _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(StartLambda))) + case node.NodeTypeSystemSum: + _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(SummaryLambda))) case node.NodeTypeTextModel: _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(TextModelLambda))) case node.NodeTypeImageModel: @@ -722,12 +678,6 @@ func registerNodeToGraph(graph *compose.Graph[any, any], flowNode entity.FlowNod _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(BatchModelLambda))) case node.NodeTypeDataConversionModel: _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(DataConversionLambda))) - //case node.NodeTypeSenseOptimizeModel: - // _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(SenseOptimizeModelLambda))) - //case node.NodeTypeStoryOptimizeModel: - // _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(StoryOptimizeModelLambda))) - //case node.NodeTypeScriptOptimizeModel: - // _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(ScriptOptimizeModelLambda))) case node.NodeTypeCustomNode: _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(CustomLambda))) case node.NodeTypeForm: @@ -737,49 +687,42 @@ func registerNodeToGraph(graph *compose.Graph[any, any], flowNode entity.FlowNod case node.NodeTypeMerge: _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(MergeLambda))) case node.NodeTypeDataMerge: - _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(DataMergeLambda))) + _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(DataMergeLambda)), compose.WithGraphCompileOptions(compose.WithNodeTriggerMode(compose.AllPredecessor))) case node.NodeTypeHttp: _ = graph.AddLambdaNode(nodeID, compose.InvokableLambda(wrapLambda(HttpLambda))) } } -// -------------------------------------------------------------------- -// ✅【工具方法】找出所有没有出边的节点 → 作为结束节点连接 END -// -------------------------------------------------------------------- func findEndNodes(startNodeId string, edges []entity.FlowEdge) []string { - // 构建 节点 → 后续节点 的映射 nextMap := make(map[string][]string) for _, e := range edges { nextMap[e.From] = append(nextMap[e.From], e.To) } endNodeSet := make(map[string]struct{}) + visited := make(map[string]struct{}) + queue := []string{startNodeId} - // 🚀 只从【开始节点】递归遍历(关键修复) - findLeafNodes(startNodeId, nextMap, endNodeSet) + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] - // 转成数组返回 - endNodes := make([]string, 0, len(endNodeSet)) - for id := range endNodeSet { - endNodes = append(endNodes, id) - } - return endNodes -} - -// -------------------------------------------------------------------- -// ✅ 递归:查找以 nodeId 开头的所有叶子节点 -// -------------------------------------------------------------------- -func findLeafNodes(nodeId string, nextMap map[string][]string, endNodeSet map[string]struct{}) { - nextNodes := nextMap[nodeId] - - // 🚩 没有下一个节点 = 真实结束节点 - if len(nextNodes) == 0 { - endNodeSet[nodeId] = struct{}{} - return - } - - // 递归继续找下一个 - for _, nextId := range nextNodes { - findLeafNodes(nextId, nextMap, endNodeSet) + if _, exist := visited[node]; exist { + continue + } + visited[node] = struct{}{} + + nextList := nextMap[node] + if len(nextList) == 0 { + endNodeSet[node] = struct{}{} + continue + } + queue = append(queue, nextList...) } + + res := make([]string, 0, len(endNodeSet)) + for k := range endNodeSet { + res = append(res, k) + } + return res } diff --git a/workflow/service/flow/lambda_node.go b/workflow/service/flow/lambda_node.go index 93894a8..55d4ddc 100644 --- a/workflow/service/flow/lambda_node.go +++ b/workflow/service/flow/lambda_node.go @@ -41,19 +41,35 @@ func JudgeLambda(ctx context.Context, input any) (string, error) { if !ok { return "", fmt.Errorf("入参类型错误,期望 *flowDto.NodeExecutionInput,实际 %T", input) } + //inputMap, outputMap, modelMap := GetNodeContextContent(nodeInput.Global, nodeInput.Config) + //fmt.Printf("JudgeLambda路由:输入=%s\n", gjson.MustEncode(inputMap)) + //fmt.Printf("JudgeLambda路由:输出=%s\n", gjson.MustEncode(outputMap)) + //fmt.Printf("JudgeLambda路由:模型=%s\n", gjson.MustEncode(modelMap)) + //configMap := gconv.Map(nodeInput.Config.Config) + //ids := gconv.Strings(configMap["branch_ids"]) + //fmt.Printf("JudgeLambda路由:目标节点ID=%s\n", gconv.String(ids)) + // + //m := map[string]bool{ + // "80000a50-81e1-4c15-adae-aab6c0d781ad": true, + // "59a6ffa2-3252-4535-b6ed-d3e49cdf6c55": true, + //} + // + //return m, nil // 1. 直接用你原来的方法(返回两个 map) inputMap, outputMap, modelMap := GetNodeContextContent(nodeInput.Global, nodeInput.Config) var outputResult []node.NodeFormField - for _, valueAny := range inputMap { - if field, ok := valueAny.(node.NodeFormField); ok { - outputResult = append(outputResult, field) - } - } - for _, valueAny := range outputMap { - if field, ok := valueAny.(node.NodeFormField); ok { - outputResult = append(outputResult, field) - } - } + outputResult = append(outputResult, inputMap...) + outputResult = append(outputResult, outputMap...) + //for _, valueAny := range inputMap { + // if field, ok := valueAny.(node.NodeFormField); ok { + // outputResult = append(outputResult, field) + // } + //} + //for _, valueAny := range outputMap { + // if field, ok := valueAny.(node.NodeFormField); ok { + // outputResult = append(outputResult, field) + // } + //} for _, valueAny := range modelMap { if field, ok := valueAny.(node.NodeFormField); ok { outputResult = append(outputResult, field) @@ -204,6 +220,8 @@ func TextModelLambda(ctx context.Context, input any) (any, error) { return nil, err } nodeInput.Config.OutputResult = outputRes + //} + return nodeInput, nil } @@ -281,14 +299,13 @@ func VideoModelLambda(ctx context.Context, input any) (any, error) { Label: fmt.Sprintf("video_oss_url:content:%d", 0), Type: "string", }) - } else { - outputRes = append(outputRes, node.NodeFormField{ - Field: fmt.Sprintf("concat_video_url:content:%d", 0), - Value: urlPrefix + msg.FileURL, - Label: fmt.Sprintf("concat_video_url:content:%d", 0), - Type: "string", - }) } + outputRes = append(outputRes, node.NodeFormField{ + Field: fmt.Sprintf("concat_video_url:content:%d", 0), + Value: urlPrefix + msg.FileURL, + Label: fmt.Sprintf("视频内容:content:%d", 0), + Type: "string", + }) nodeInput.Config.OutputResult = outputRes return nodeInput, nil @@ -303,6 +320,64 @@ func HttpLambda(ctx context.Context, input any) (any, error) { outputRes := make([]node.NodeFormField, 0) var err error outputRes, err = HttpNode(ctx, nodeInput) + //if nodeInput.Config.Name == "生成视频" { + // outputRes, err = HttpNode(ctx, nodeInput) + //} else { + // a := []map[string]any{ + // { + // "timeline": "0.0-2.1", + // "url": "https://ark-auto-2127201628-cn-beijing-default.tos-cn-beijing.volces.com/%E8%A7%86%E9%A2%91/1.mp4", + // }, + // { + // "timeline": "2.1-4.5", + // "url": "https://ark-auto-2127201628-cn-beijing-default.tos-cn-beijing.volces.com/%E8%A7%86%E9%A2%91/2.mp4", + // }, + // { + // "timeline": "4.5-12.2", + // "url": "https://ark-auto-2127201628-cn-beijing-default.tos-cn-beijing.volces.com/%E8%A7%86%E9%A2%91/3.mp4", + // }, + // { + // "timeline": "12.2-13.6", + // "url": "https://ark-auto-2127201628-cn-beijing-default.tos-cn-beijing.volces.com/%E8%A7%86%E9%A2%91/4.mp4", + // }, + // { + // "timeline": "13.6-17.7", + // "url": "https://ark-auto-2127201628-cn-beijing-default.tos-cn-beijing.volces.com/%E8%A7%86%E9%A2%91/5.mp4model-gateway", + // }, + // { + // "timeline": "17.7-31.0", + // "url": "https://ark-auto-2127201628-cn-beijing-default.tos-cn-beijing.volces.com/%E8%A7%86%E9%A2%91/6.mp4", + // }, + // { + // "timeline": "31.0-33.2", + // "url": "https://ark-auto-2127201628-cn-beijing-default.tos-cn-beijing.volces.com/%E8%A7%86%E9%A2%91/7.mp4", + // }, + // { + // "timeline": "33.2-37.4", + // "url": "https://ark-auto-2127201628-cn-beijing-default.tos-cn-beijing.volces.com/%E8%A7%86%E9%A2%91/8.mp4", + // }, + // { + // "timeline": "37.4-38.9", + // "url": "https://ark-auto-2127201628-cn-beijing-default.tos-cn-beijing.volces.com/%E8%A7%86%E9%A2%91/9.mp4", + // }, + // { + // "timeline": "38.9-57.9", + // "url": "https://ark-auto-2127201628-cn-beijing-default.tos-cn-beijing.volces.com/%E8%A7%86%E9%A2%91/10.mp4", + // }, + // } + // outputRes = append(outputRes, node.NodeFormField{ + // Field: fmt.Sprintf("segments"), + // Value: a, + // Label: fmt.Sprintf("segments"), + // Type: "string", + // }) + // outputRes = append(outputRes, node.NodeFormField{ + // Field: fmt.Sprintf("audioUrl"), + // Value: "http://116.204.74.41:9000/tenantid-94/2026-06-11/9915351c-55b9-46d8-b783-3815126b.m4a", + // Label: fmt.Sprintf("audioUrl"), + // Type: "string", + // }) + //} if err != nil { return nil, err } @@ -437,11 +512,8 @@ func MergeLambda(ctx context.Context, input any) (res any, err error) { // 1. 把所有节点输出拍平成 字段名->内容 的map dataMap := make(map[string]node.NodeFormField) _, outputMap, _ := GetNodeContextContent(nodeInput.Global, nodeInput.Config) - for _, valueAny := range outputMap { - field := node.NodeFormField{} - if field, ok = valueAny.(node.NodeFormField); ok { - dataMap[field.Field] = field - } + for _, field := range outputMap { + dataMap[field.Field] = field } // 2. 提取所有文案:text_content_0,1,2... diff --git a/workflow/service/flow/lambda_node_imp.go b/workflow/service/flow/lambda_node_imp.go index 55cc100..c57bb54 100644 --- a/workflow/service/flow/lambda_node_imp.go +++ b/workflow/service/flow/lambda_node_imp.go @@ -583,7 +583,7 @@ func ImgNode(ctx context.Context, nodeInput *flowDto.NodeExecutionInput, skillNa outputRes = append(outputRes, node.NodeFormField{ Field: fmt.Sprintf("img_url:%v:%d", k, i), Value: v, - Label: fmt.Sprintf("img_url%v:%d", k, i), + Label: fmt.Sprintf("图片内容%v:%d", k, i), Type: "string", }) } @@ -674,7 +674,7 @@ func AudioOptimizeNode(ctx context.Context, nodeInput *flowDto.NodeExecutionInpu outputRes = append(outputRes, node.NodeFormField{ Field: fmt.Sprintf("audio_url:%v:%d", k, i), Value: v, - Label: fmt.Sprintf("audio_url:%v:%d", k, i), + Label: fmt.Sprintf("音频内容:%v:%d", k, i), Type: "string", }) } @@ -939,23 +939,17 @@ func HttpNode(ctx context.Context, nodeInput *flowDto.NodeExecutionInput) ([]nod func BuildParam(nodeInput *flowDto.NodeExecutionInput) (skillName string, resultFrom []map[string]any, resultUserFrom []map[string]any) { inputMap, outputMap, modelMap := GetNodeContextContent(nodeInput.Global, nodeInput.Config) var outputResult []node.NodeFormField - for _, valueAny := range inputMap { - if field, ok := valueAny.(node.NodeFormField); ok { - outputResult = append(outputResult, field) - } - } + outputResult = append(outputResult, inputMap...) resultUserFrom = []map[string]any{} - for _, valueAny := range outputMap { - if field, ok := valueAny.(node.NodeFormField); ok { - if !strings.Contains(field.Field, "text_url") && !strings.Contains(field.Field, "img_url") { - if strings.Contains(field.Field, "text_content") { - field.Value = StripHtmlTags(gconv.String(field.Value)) - } - resultUserFrom = append(resultUserFrom, map[string]any{ - field.Label: field.Value, - }) + for _, field := range outputMap { + if !strings.Contains(field.Field, "text_url") && !strings.Contains(field.Field, "img_url") { + if strings.Contains(field.Field, "text_content") { + field.Value = StripHtmlTags(gconv.String(field.Value)) } + resultUserFrom = append(resultUserFrom, map[string]any{ + field.Label: field.Value, + }) } } for _, valueAny := range modelMap { @@ -963,18 +957,13 @@ func BuildParam(nodeInput *flowDto.NodeExecutionInput) (skillName string, result outputResult = append(outputResult, field) } } - //if !nodeInput.Global.IsDialogue { - for _, item := range outputResult { - resultUserFrom = append(resultUserFrom, map[string]any{ - item.Label: item.Value, - }) + if !nodeInput.Global.IsDialogue { + for _, item := range outputResult { + resultUserFrom = append(resultUserFrom, map[string]any{ + item.Label: item.Value, + }) + } } - for _, item := range nodeInput.Config.FormConfig { - resultUserFrom = append(resultUserFrom, map[string]any{ - item.Label: item.Value, - }) - } - //} if !g.IsEmpty(nodeInput.Global.Desc) { resultUserFrom = append(resultUserFrom, map[string]any{ "desc": nodeInput.Global.Desc, @@ -998,83 +987,40 @@ func BuildParam(nodeInput *flowDto.NodeExecutionInput) (skillName string, result return skillName, resultFrom, resultUserFrom } -func GetNodeContextContent(execInput *flowDto.FlowExecutionInput, nodeEntity *entity.FlowNode) (map[string]any, map[string]any, map[string]any) { - input := make(map[string]any) - output := make(map[string]any) +func GetNodeContextContent(execInput *flowDto.FlowExecutionInput, nodeEntity *entity.FlowNode) ([]node.NodeFormField, []node.NodeFormField, map[string]any) { + var input []node.NodeFormField + var output []node.NodeFormField model := make(map[string]any) - // 1. 有引用 → 取引用节点的字段值 if len(nodeEntity.InputSource) > 0 { for _, source := range nodeEntity.InputSource { - refNodeID := source.NodeId - fields := source.Field - - refNode, ok := execInput.ConfigMap[refNodeID] + refNode, ok := execInput.ConfigMap[source.NodeId] if !ok { continue } - - inputMap := buildInputMap(refNode) - outputMap := mergeOutput(refNode.OutputResult) - modelMap := mergeModel(refNode.ModelConfig) - if len(fields) > 0 { + if len(source.Field) > 0 { // 取指定字段 - for _, f := range fields { - if v, ok := inputMap[f]; ok { - input[f] = v - } - if v, ok := modelMap[f]; ok { - model[f] = v - } - for k, v := range outputMap { - if strings.Contains(k, f) { - model[k] = v + for _, f := range source.Field { + for _, v := range refNode.FormConfig { + if strings.Contains(v.Label, f) { + input = append(input, v) } } - } - } else { - // 取全部 - if refNode.NodeCode != node.NodeTypeHttp { - for k, v := range inputMap { - input[k] = v + for _, v := range refNode.ModelConfig.ModelForm { + if g.IsEmpty(v.Value) { + continue + } + if strings.Contains(v.Label, f) { + model[f] = v + } + } + for _, v := range refNode.OutputResult { + if strings.Contains(v.Label, f) { + output = append(output, v) + } } - } - for k, v := range modelMap { - model[k] = v } } } } return input, output, model } - -// buildInputMap 从 FormConfig 构造输入map -func buildInputMap(node *entity.FlowNode) map[string]any { - m := make(map[string]any) - for _, item := range node.FormConfig { - m[item.Label] = item - } - return m -} - -// mergeOutput 合并节点输出 []map → 单map -func mergeOutput(output []node.NodeFormField) map[string]any { - m := make(map[string]any) - for _, item := range output { - m[item.Label] = item - } - return m -} - -// mergeOutput 合并节点输出 []map → 单map -func mergeModel(output node.ModelItem) map[string]any { - m := make(map[string]any) - // 遍历 output.ModelForm 里的每一个 key 和原始值 - for _, rawValue := range output.ModelForm { - if g.IsEmpty(rawValue.Value) { - continue - } - // 包装成 { "value": 原始值 } - m[rawValue.Label] = rawValue.Value - } - return m -}