diff --git a/src/views/settings/workflow/index.vue b/src/views/settings/workflow/index.vue index 18daa02..f7082a5 100644 --- a/src/views/settings/workflow/index.vue +++ b/src/views/settings/workflow/index.vue @@ -873,19 +873,20 @@ const collectHttpOutputFields = (node: any, prefix = '', isRoot = true, suppress // 取节点在设计时的可引用输出字段(运行时这些字段会产出实际值) const getNodeOutputFields = (node: Node): UpstreamField[] => { const nodeCode = node.data?.nodeCode || ''; + const out: UpstreamField[] = []; // 节点库自带输出项(outputField):非空时优先作为该节点的可引用输出(脚本转写等节点) const ownOutput = nodeConfigMap.value.get(nodeCode)?.outputField || []; if (ownOutput.length > 0) { - return ownOutput.map((o: any) => ({ field: o.field || o.label || '', label: o.label || o.field || '' })); - } - if (nodeCode === 'form') { + out.push(...ownOutput.map((o: any) => ({ field: o.field || o.label || '', label: o.label || o.field || '' }))); + } else if (nodeCode === 'form') { // form 节点:自定义表单字段即输出 - return (node.data?.formConfig || []).map((f: any) => ({ - field: f.field || f.label || '', - label: f.label || f.field || '', - })); - } - if (nodeCode === 'http') { + out.push( + ...(node.data?.formConfig || []).map((f: any) => ({ + field: f.field || f.label || '', + label: f.label || f.field || '', + })), + ); + } else if (nodeCode === 'http') { // http 节点:输出 = 结果返回结构(response schema)的叶子字段 + 对象/数组容器整体。 // 结果返回方式为主动拉取(responseType === 'pull')时,取主动拉取分支下配置的结果返回结构。 const formConfig = node.data?.formConfig || []; @@ -895,32 +896,36 @@ const getNodeOutputFields = (node: Node): UpstreamField[] ? (responseTypeEntry?.expand || []).find((e: any) => e.field === 'response') : formConfig.find((f: any) => f.field === 'response'); const schema = parseSchema(responseField?.value); - if (schema) return collectHttpOutputFields(schema); - return []; - } - if (nodeCode === 'model') { + if (schema) out.push(...collectHttpOutputFields(schema)); + } else if (nodeCode === 'model') { // 模型节点:模型的返回参数(responseBodyMapping)即可被下游引用的输出; // value 为保存时从模型 responseMapping 填充的中文描述,展示优先用中文,无则兜底 key const resp = node.data?.modelConfig?.modelResponseBodyMapping; // 数组结构:元素带 field/label if (Array.isArray(resp)) { - return resp - .filter((it: any) => it && typeof it === 'object' && (it.field || it.label || it.key)) - .map((it: any) => ({ field: it.field || it.label || it.key || '', label: it.label || it.field || it.key || '' })); + out.push( + ...resp + .filter((it: any) => it && typeof it === 'object' && (it.field || it.label || it.key)) + .map((it: any) => ({ field: it.field || it.label || it.key || '', label: it.label || it.field || it.key || '' })), + ); } // 对象结构:{ key: 中文描述 } - if (resp && typeof resp === 'object') { - return Object.keys(resp) - .filter((k: any) => typeof k === 'string' && k.trim() !== '') - .map((k: string) => ({ field: k, label: (typeof resp[k] === 'string' && resp[k]) || k })); + else if (resp && typeof resp === 'object') { + out.push( + ...Object.keys(resp) + .filter((k: any) => typeof k === 'string' && k.trim() !== '') + .map((k: string) => ({ field: k, label: (typeof resp[k] === 'string' && resp[k]) || k })), + ); } - return []; - } - if (nodeCode === START_NODE_CODE) { + } else if (nodeCode === START_NODE_CODE) { // 开始节点:运行表单字段(被勾选的模型参数 + form 自定义字段) - return (node.data?.runFormFields || []).map((f: any) => ({ field: f.field || f.path || '', label: f.label || f.field || f.path || '' })); + out.push(...(node.data?.runFormFields || []).map((f: any) => ({ field: f.field || f.path || '', label: f.label || f.field || f.path || '' }))); } - return []; + // 开启贴片布局的节点:额外提供「贴片布局」输出(field=templates),供下游节点引用(后端执行后产出 templates 字段) + if (node.data?.patchLayout) { + out.push({ field: 'templates', label: '贴片布局' }); + } + return out; }; // 当前选中节点的所有前驱链路节点(含各自可引用输出字段) @@ -944,10 +949,12 @@ const upstreamNodes = computed(() => { visited.add(p); const n = nodes.value.find((x) => x.id === p); if (n) { - // 可作为下游引用来源:模型/HTTP/表单节点,或节点库声明了自带输出项(outputField)的节点(如脚本转写) + // 可作为下游引用来源:模型/HTTP/表单节点,或节点库声明了自带输出项(outputField)的节点(如脚本转写), + // 或开启了贴片布局的节点(产出 templates 供下游引用) const hasOutput = OUTPUT_NODE_CODES.includes(n.data?.nodeCode || '') || - (nodeConfigMap.value.get(n.data?.nodeCode || '')?.outputField?.length ?? 0) > 0; + (nodeConfigMap.value.get(n.data?.nodeCode || '')?.outputField?.length ?? 0) > 0 || + n.data?.patchLayout === true; if (hasOutput) { result.push({ id: n.id,