1
This commit is contained in:
parent
3b67370c2e
commit
329cb955d8
1536
backend/README.md
1536
backend/README.md
File diff suppressed because it is too large
Load Diff
@ -39,13 +39,22 @@ export interface WorkflowDefinition extends BaseResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkflowDefinitionNode {
|
export interface WorkflowDefinitionNode {
|
||||||
id: number;
|
id: number | string; // 支持数字或UUID字符串
|
||||||
nodeCode: string;
|
nodeCode: string;
|
||||||
nodeType: string;
|
nodeType: string;
|
||||||
nodeName: string;
|
nodeName: string;
|
||||||
uiVariables: JSON;
|
position?: { x: number; y: number }; // 节点位置
|
||||||
panelVariables: JSON;
|
configs?: Record<string, any>; // 基本配置
|
||||||
localVariables: JSON;
|
inputMapping?: Record<string, any>; // 输入映射
|
||||||
|
outputs?: Array<{ // 输出能力定义
|
||||||
|
name: string;
|
||||||
|
title: string;
|
||||||
|
type: 'string' | 'number' | 'boolean' | 'object' | 'array'; // 与 OutputField 保持一致
|
||||||
|
description: string;
|
||||||
|
enum?: string[];
|
||||||
|
example?: any;
|
||||||
|
required?: boolean;
|
||||||
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkflowDefinitionQuery extends BaseQuery {
|
export interface WorkflowDefinitionQuery extends BaseQuery {
|
||||||
|
|||||||
@ -46,7 +46,6 @@ const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
|||||||
// 创建Formily表单实例
|
// 创建Formily表单实例
|
||||||
const configForm = useMemo(() => createForm(), []);
|
const configForm = useMemo(() => createForm(), []);
|
||||||
const inputForm = useMemo(() => createForm(), []);
|
const inputForm = useMemo(() => createForm(), []);
|
||||||
const outputForm = useMemo(() => createForm(), []);
|
|
||||||
|
|
||||||
// 初始化表单数据
|
// 初始化表单数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -67,12 +66,9 @@ const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
|||||||
if (isConfigurableNode(nodeDefinition)) {
|
if (isConfigurableNode(nodeDefinition)) {
|
||||||
inputForm.setInitialValues(nodeData.inputMapping || {});
|
inputForm.setInitialValues(nodeData.inputMapping || {});
|
||||||
inputForm.reset();
|
inputForm.reset();
|
||||||
|
|
||||||
outputForm.setInitialValues(nodeData.outputMapping || {});
|
|
||||||
outputForm.reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [visible, node, nodeDefinition, configForm, inputForm, outputForm]);
|
}, [visible, node, nodeDefinition, configForm, inputForm]);
|
||||||
|
|
||||||
// 递归处理表单值,将JSON字符串转换为对象
|
// 递归处理表单值,将JSON字符串转换为对象
|
||||||
const processFormValues = (values: Record<string, any>, schema: ISchema | undefined): Record<string, any> => {
|
const processFormValues = (values: Record<string, any>, schema: ISchema | undefined): Record<string, any> => {
|
||||||
@ -109,15 +105,13 @@ const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
|||||||
const inputMapping = isConfigurableNode(nodeDefinition)
|
const inputMapping = isConfigurableNode(nodeDefinition)
|
||||||
? processFormValues(inputForm.values, nodeDefinition.inputMappingSchema)
|
? processFormValues(inputForm.values, nodeDefinition.inputMappingSchema)
|
||||||
: {};
|
: {};
|
||||||
const outputMapping = isConfigurableNode(nodeDefinition)
|
|
||||||
? processFormValues(outputForm.values, nodeDefinition.outputMappingSchema)
|
|
||||||
: {};
|
|
||||||
|
|
||||||
const updatedData: Partial<FlowNodeData> = {
|
const updatedData: Partial<FlowNodeData> = {
|
||||||
label: configs.nodeName || node.data.label,
|
label: configs.nodeName || node.data.label,
|
||||||
configs,
|
configs,
|
||||||
inputMapping,
|
inputMapping,
|
||||||
outputMapping,
|
// outputs 保留原值(不修改,因为它是只读的输出能力定义)
|
||||||
|
outputs: node.data.outputs || [],
|
||||||
};
|
};
|
||||||
|
|
||||||
onOk(node.id, updatedData);
|
onOk(node.id, updatedData);
|
||||||
@ -142,7 +136,6 @@ const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
|||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
configForm.reset();
|
configForm.reset();
|
||||||
inputForm.reset();
|
inputForm.reset();
|
||||||
outputForm.reset();
|
|
||||||
toast({
|
toast({
|
||||||
title: "已重置",
|
title: "已重置",
|
||||||
description: "表单已重置为初始值",
|
description: "表单已重置为初始值",
|
||||||
@ -313,18 +306,55 @@ const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
|||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 输出映射 - 条件显示 */}
|
{/* 输出能力 - 只读展示 */}
|
||||||
{isConfigurableNode(nodeDefinition) && nodeDefinition.outputMappingSchema && (
|
{isConfigurableNode(nodeDefinition) && nodeDefinition.outputs && nodeDefinition.outputs.length > 0 && (
|
||||||
<AccordionItem value="output" className="border-b">
|
<AccordionItem value="output" className="border-b">
|
||||||
<AccordionTrigger className="text-base font-semibold flex-row-reverse justify-end gap-2 hover:no-underline">
|
<AccordionTrigger className="text-base font-semibold flex-row-reverse justify-end gap-2 hover:no-underline">
|
||||||
输出映射
|
输出能力
|
||||||
</AccordionTrigger>
|
</AccordionTrigger>
|
||||||
<AccordionContent className="px-1">
|
<AccordionContent className="px-1">
|
||||||
<FormProvider form={outputForm}>
|
<div className="text-sm text-muted-foreground mb-4 p-3 bg-muted/50 rounded-md">
|
||||||
<FormLayout layout="vertical" colon={false}>
|
💡 此节点执行后会产生以下数据,下游节点可以通过 <code className="px-1 py-0.5 bg-background rounded">{'${upstream.字段名}'}</code> 引用这些数据
|
||||||
<SchemaField schema={convertToFormilySchema(nodeDefinition.outputMappingSchema)} />
|
</div>
|
||||||
</FormLayout>
|
<div className="space-y-3">
|
||||||
</FormProvider>
|
{nodeDefinition.outputs.map((output) => (
|
||||||
|
<div key={output.name} className="p-3 border rounded-md bg-background">
|
||||||
|
<div className="flex items-start justify-between mb-2">
|
||||||
|
<div className="flex-1">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="font-medium text-foreground">{output.title}</span>
|
||||||
|
<code className="px-1.5 py-0.5 text-xs bg-muted rounded">{output.name}</code>
|
||||||
|
<span className="text-xs text-muted-foreground border border-border px-1.5 py-0.5 rounded">
|
||||||
|
{output.type}
|
||||||
|
</span>
|
||||||
|
{output.required && (
|
||||||
|
<span className="text-xs text-red-500">*</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-muted-foreground mt-1">
|
||||||
|
{output.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{output.enum && (
|
||||||
|
<div className="mt-2 text-xs">
|
||||||
|
<span className="text-muted-foreground">可选值:</span>
|
||||||
|
<span className="ml-1 text-foreground">{output.enum.join(', ')}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{output.example !== undefined && (
|
||||||
|
<div className="mt-2 text-xs">
|
||||||
|
<span className="text-muted-foreground">示例:</span>
|
||||||
|
<code className="ml-1 px-1.5 py-0.5 bg-muted rounded text-foreground">
|
||||||
|
{typeof output.example === 'object'
|
||||||
|
? JSON.stringify(output.example)
|
||||||
|
: String(output.example)}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { NODE_DEFINITIONS, NodeType, getNodeCategory } from '../nodes';
|
|||||||
interface LoadedWorkflowData {
|
interface LoadedWorkflowData {
|
||||||
nodes: FlowNode[];
|
nodes: FlowNode[];
|
||||||
edges: FlowEdge[];
|
edges: FlowEdge[];
|
||||||
definition: WorkflowDefinition;
|
definition: WorkflowDefinition | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useWorkflowLoad = () => {
|
export const useWorkflowLoad = () => {
|
||||||
@ -49,7 +49,7 @@ export const useWorkflowLoad = () => {
|
|||||||
color: nodeDefinition?.renderConfig.theme.primary || getNodeColor(node.nodeType),
|
color: nodeDefinition?.renderConfig.theme.primary || getNodeColor(node.nodeType),
|
||||||
configs: node.configs || {},
|
configs: node.configs || {},
|
||||||
inputMapping: node.inputMapping || {},
|
inputMapping: node.inputMapping || {},
|
||||||
outputMapping: node.outputMapping || {},
|
outputs: node.outputs || [], // ✅ 从后端加载的输出能力定义
|
||||||
// 添加节点定义引用,用于配置弹窗
|
// 添加节点定义引用,用于配置弹窗
|
||||||
nodeDefinition
|
nodeDefinition
|
||||||
},
|
},
|
||||||
@ -168,40 +168,6 @@ export const useWorkflowLoad = () => {
|
|||||||
}
|
}
|
||||||
}, [convertToFlowFormat]);
|
}, [convertToFlowFormat]);
|
||||||
|
|
||||||
// 创建新的空白工作流
|
|
||||||
const createNewWorkflow = useCallback((): LoadedWorkflowData => {
|
|
||||||
const emptyDefinition: WorkflowDefinition = {
|
|
||||||
id: 0,
|
|
||||||
createTime: null,
|
|
||||||
createBy: null,
|
|
||||||
updateTime: null,
|
|
||||||
updateBy: null,
|
|
||||||
version: 1,
|
|
||||||
deleted: false,
|
|
||||||
extraData: null,
|
|
||||||
name: '新建工作流',
|
|
||||||
key: `workflow_${Date.now()}`,
|
|
||||||
description: '',
|
|
||||||
category: 'GENERAL',
|
|
||||||
triggers: [],
|
|
||||||
flowVersion: 1,
|
|
||||||
bpmnXml: null,
|
|
||||||
status: 'DRAFT',
|
|
||||||
graph: {
|
|
||||||
nodes: [],
|
|
||||||
edges: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
setWorkflowDefinition(emptyDefinition);
|
|
||||||
|
|
||||||
return {
|
|
||||||
nodes: [],
|
|
||||||
edges: [],
|
|
||||||
definition: emptyDefinition
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// 重置加载状态
|
// 重置加载状态
|
||||||
const resetLoad = useCallback(() => {
|
const resetLoad = useCallback(() => {
|
||||||
setWorkflowDefinition(null);
|
setWorkflowDefinition(null);
|
||||||
@ -212,7 +178,6 @@ export const useWorkflowLoad = () => {
|
|||||||
loading,
|
loading,
|
||||||
workflowDefinition,
|
workflowDefinition,
|
||||||
loadWorkflow,
|
loadWorkflow,
|
||||||
createNewWorkflow,
|
|
||||||
resetLoad
|
resetLoad
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { message } from 'antd';
|
|||||||
import * as definitionService from '../../Definition/service';
|
import * as definitionService from '../../Definition/service';
|
||||||
import type { FlowNode, FlowEdge } from '../types';
|
import type { FlowNode, FlowEdge } from '../types';
|
||||||
import { NodeType } from '../types';
|
import { NodeType } from '../types';
|
||||||
|
import { isConfigurableNode } from '../nodes/types';
|
||||||
|
|
||||||
interface WorkflowSaveData {
|
interface WorkflowSaveData {
|
||||||
nodes: FlowNode[];
|
nodes: FlowNode[];
|
||||||
@ -58,8 +59,8 @@ export const useWorkflowSave = () => {
|
|||||||
// 转换节点和边数据为后端格式
|
// 转换节点和边数据为后端格式
|
||||||
const graph = {
|
const graph = {
|
||||||
nodes: data.nodes.map(node => ({
|
nodes: data.nodes.map(node => ({
|
||||||
id: node.id, // 使用React Flow的节点ID
|
id: node.id, // 使用React Flow的节点ID(UUID)
|
||||||
nodeCode: node.id, // nodeCode与ID相同
|
nodeCode: node.data.configs?.nodeCode || node.data.nodeType, // ✅ 使用预定义的 nodeCode(如 "START_EVENT")
|
||||||
nodeType: node.data.nodeType,
|
nodeType: node.data.nodeType,
|
||||||
nodeName: node.data.label,
|
nodeName: node.data.label,
|
||||||
position: {
|
position: {
|
||||||
@ -68,7 +69,9 @@ export const useWorkflowSave = () => {
|
|||||||
},
|
},
|
||||||
configs: node.data.configs || {},
|
configs: node.data.configs || {},
|
||||||
inputMapping: node.data.inputMapping || {},
|
inputMapping: node.data.inputMapping || {},
|
||||||
outputMapping: node.data.outputMapping || {}
|
outputs: (node.data.nodeDefinition && isConfigurableNode(node.data.nodeDefinition))
|
||||||
|
? node.data.nodeDefinition.outputs || []
|
||||||
|
: [] // ✅ 输出能力定义(直接从节点定义中获取)
|
||||||
})),
|
})),
|
||||||
edges: data.edges.map(edge => ({
|
edges: data.edges.map(edge => ({
|
||||||
id: edge.id,
|
id: edge.id,
|
||||||
@ -83,28 +86,14 @@ export const useWorkflowSave = () => {
|
|||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
|
|
||||||
// 构建保存数据 - 完全模仿原始系统的逻辑
|
// ✅ 透传模式:只传递业务字段,更新 graph
|
||||||
const workflowData = data.definitionData
|
const workflowData = {
|
||||||
? {
|
...data.definitionData, // 透传原始数据
|
||||||
// 如果有原始定义数据,展开它并覆盖 graph
|
graph // 只覆盖 graph 字段
|
||||||
...data.definitionData,
|
|
||||||
graph
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
// 如果没有原始定义数据,创建新的工作流
|
|
||||||
name: data.name || '新建工作流',
|
|
||||||
description: data.description || '',
|
|
||||||
key: `workflow_${Date.now()}`,
|
|
||||||
category: 'GENERAL',
|
|
||||||
triggers: [],
|
|
||||||
flowVersion: 1,
|
|
||||||
bpmnXml: null,
|
|
||||||
status: 'DRAFT',
|
|
||||||
graph
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 无论新建还是更新,都调用 saveDefinition (POST 请求)
|
// 只有更新操作(外层列表已创建草稿,这里只更新)
|
||||||
await definitionService.saveDefinition(workflowData as any);
|
await definitionService.updateDefinition(data.workflowId!, workflowData as any);
|
||||||
message.success('工作流保存成功');
|
message.success('工作流保存成功');
|
||||||
|
|
||||||
setLastSaved(new Date());
|
setLastSaved(new Date());
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import NodeConfigModal from './components/NodeConfigModal';
|
|||||||
import EdgeConfigModal, { type EdgeCondition } from './components/EdgeConfigModal';
|
import EdgeConfigModal, { type EdgeCondition } from './components/EdgeConfigModal';
|
||||||
import type { FlowNode, FlowEdge, FlowNodeData } from './types';
|
import type { FlowNode, FlowEdge, FlowNodeData } from './types';
|
||||||
import type { WorkflowNodeDefinition } from './nodes/types';
|
import type { WorkflowNodeDefinition } from './nodes/types';
|
||||||
|
import { isConfigurableNode } from './nodes/types';
|
||||||
import { useWorkflowSave } from './hooks/useWorkflowSave';
|
import { useWorkflowSave } from './hooks/useWorkflowSave';
|
||||||
import { useWorkflowLoad } from './hooks/useWorkflowLoad';
|
import { useWorkflowLoad } from './hooks/useWorkflowLoad';
|
||||||
import { useHistory } from './hooks/useHistory';
|
import { useHistory } from './hooks/useHistory';
|
||||||
@ -302,7 +303,7 @@ const WorkflowDesignInner: React.FC = () => {
|
|||||||
description: nodeDefinition.description
|
description: nodeDefinition.description
|
||||||
},
|
},
|
||||||
inputMapping: {},
|
inputMapping: {},
|
||||||
outputMapping: {}
|
outputs: isConfigurableNode(nodeDefinition) ? nodeDefinition.outputs || [] : [] // ✅ 从节点定义中获取输出能力
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -71,40 +71,58 @@ export const JenkinsBuildNodeDefinition: ConfigurableNodeDefinition = {
|
|||||||
},
|
},
|
||||||
required: ["nodeName", "nodeCode", "jenkinsUrl"]
|
required: ["nodeName", "nodeCode", "jenkinsUrl"]
|
||||||
},
|
},
|
||||||
// 输出映射Schema
|
// ✅ 输出能力定义(只读展示,传递给后端)
|
||||||
outputMappingSchema: {
|
outputs: [
|
||||||
type: "object",
|
{
|
||||||
title: "输出映射",
|
name: "buildNumber",
|
||||||
description: "传递给下游节点的数据映射配置",
|
title: "构建编号",
|
||||||
properties: {
|
|
||||||
buildId: {
|
|
||||||
type: "string",
|
|
||||||
title: "构建ID",
|
|
||||||
description: "Jenkins构建的唯一标识符",
|
|
||||||
default: "${jenkins.buildNumber}"
|
|
||||||
},
|
|
||||||
buildStatus: {
|
|
||||||
type: "string",
|
|
||||||
title: "构建状态",
|
|
||||||
description: "构建完成状态",
|
|
||||||
enum: ["SUCCESS", "FAILURE", "UNSTABLE", "ABORTED", "NOT_BUILT"],
|
|
||||||
default: "SUCCESS"
|
|
||||||
},
|
|
||||||
buildUrl: {
|
|
||||||
type: "string",
|
|
||||||
title: "构建URL",
|
|
||||||
description: "Jenkins构建页面的URL",
|
|
||||||
default: "${jenkins.buildUrl}"
|
|
||||||
},
|
|
||||||
buildDuration: {
|
|
||||||
type: "number",
|
type: "number",
|
||||||
title: "构建耗时",
|
description: "Jenkins构建的唯一编号",
|
||||||
description: "构建耗时(毫秒)",
|
example: 123,
|
||||||
default: 0
|
required: true
|
||||||
}
|
|
||||||
},
|
},
|
||||||
required: ["buildId", "buildStatus", "buildUrl"]
|
{
|
||||||
|
name: "buildStatus",
|
||||||
|
title: "构建状态",
|
||||||
|
type: "string",
|
||||||
|
enum: ["SUCCESS", "FAILURE", "UNSTABLE", "ABORTED"],
|
||||||
|
description: "构建执行的结果状态",
|
||||||
|
example: "SUCCESS",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "buildUrl",
|
||||||
|
title: "构建URL",
|
||||||
|
type: "string",
|
||||||
|
description: "Jenkins构建页面的访问地址",
|
||||||
|
example: "http://jenkins.example.com/job/app/123/",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "artifactUrl",
|
||||||
|
title: "构建产物地址",
|
||||||
|
type: "string",
|
||||||
|
description: "构建生成的jar/war包下载地址",
|
||||||
|
example: "http://jenkins.example.com/job/app/123/artifact/target/app-1.0.0.jar",
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "gitCommitId",
|
||||||
|
title: "Git提交ID",
|
||||||
|
type: "string",
|
||||||
|
description: "本次构建使用的Git提交哈希值",
|
||||||
|
example: "a3f5e8d2c4b1a5e9f2d3e7b8c9d1a2f3e4b5c6d7",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "buildDuration",
|
||||||
|
title: "构建时长",
|
||||||
|
type: "number",
|
||||||
|
description: "构建执行的时长(秒)",
|
||||||
|
example: 120,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
// ✅ 不再需要单独的渲染组件,使用 BaseNode 即可
|
// ✅ 不再需要单独的渲染组件,使用 BaseNode 即可
|
||||||
|
|||||||
@ -47,6 +47,22 @@ export const getNodeCategory = (nodeType: NodeType | string): NodeCategory => {
|
|||||||
import type { ISchema } from '@formily/react';
|
import type { ISchema } from '@formily/react';
|
||||||
export type JSONSchema = ISchema;
|
export type JSONSchema = ISchema;
|
||||||
|
|
||||||
|
// ========== 输出字段定义 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出字段定义 - 描述节点执行后产生的数据
|
||||||
|
* 用于在节点配置面板中展示,供下游节点引用
|
||||||
|
*/
|
||||||
|
export interface OutputField {
|
||||||
|
name: string; // 字段名(用于表达式引用 ${upstream.buildNumber})
|
||||||
|
title: string; // 显示名称
|
||||||
|
description: string; // 详细说明
|
||||||
|
type: 'string' | 'number' | 'boolean' | 'object' | 'array'; // 数据类型
|
||||||
|
enum?: string[]; // 枚举值(可选)
|
||||||
|
example?: any; // 示例值
|
||||||
|
required?: boolean; // 是否必定产生(默认 true)
|
||||||
|
}
|
||||||
|
|
||||||
// ========== 渲染配置(配置驱动节点渲染) ==========
|
// ========== 渲染配置(配置驱动节点渲染) ==========
|
||||||
|
|
||||||
// 节点尺寸
|
// 节点尺寸
|
||||||
@ -107,10 +123,10 @@ export interface BaseNodeDefinition {
|
|||||||
configSchema: JSONSchema; // 基本配置Schema(包含基本信息+节点配置)
|
configSchema: JSONSchema; // 基本配置Schema(包含基本信息+节点配置)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 可配置节点定义(有3个TAB:基本配置、输入、输出)
|
// 可配置节点定义(有3个面板:基本配置、输入映射、输出能力)
|
||||||
export interface ConfigurableNodeDefinition extends BaseNodeDefinition {
|
export interface ConfigurableNodeDefinition extends BaseNodeDefinition {
|
||||||
inputMappingSchema?: JSONSchema; // 输入映射的Schema定义
|
inputMappingSchema?: JSONSchema; // 输入映射的Schema定义(用户配置)
|
||||||
outputMappingSchema?: JSONSchema; // 输出映射的Schema定义
|
outputs?: OutputField[]; // 输出能力定义(只读展示)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 工作流节点定义(联合类型)
|
// 工作流节点定义(联合类型)
|
||||||
@ -124,10 +140,10 @@ export interface NodeInstanceData {
|
|||||||
category: NodeCategory;
|
category: NodeCategory;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
// 运行时数据(key/value格式)
|
// 运行时数据
|
||||||
configs?: Record<string, any>; // 基本配置数据(包含基本信息+节点配置)
|
configs?: Record<string, any>; // 基本配置数据(包含基本信息+节点配置)
|
||||||
inputMapping?: Record<string, any>;
|
inputMapping?: Record<string, any>; // 输入映射(用户配置)
|
||||||
outputMapping?: Record<string, any>;
|
outputs?: OutputField[]; // 输出能力定义(从节点定义中获取)
|
||||||
|
|
||||||
// UI位置信息
|
// UI位置信息
|
||||||
position: { x: number; y: number };
|
position: { x: number; y: number };
|
||||||
@ -135,5 +151,5 @@ export interface NodeInstanceData {
|
|||||||
|
|
||||||
// 判断是否为可配置节点
|
// 判断是否为可配置节点
|
||||||
export const isConfigurableNode = (def: WorkflowNodeDefinition): def is ConfigurableNodeDefinition => {
|
export const isConfigurableNode = (def: WorkflowNodeDefinition): def is ConfigurableNodeDefinition => {
|
||||||
return 'inputMappingSchema' in def || 'outputMappingSchema' in def;
|
return 'inputMappingSchema' in def || 'outputs' in def;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -41,10 +41,10 @@ export interface FlowNodeData extends Record<string, unknown> {
|
|||||||
icon: string;
|
icon: string;
|
||||||
color: string;
|
color: string;
|
||||||
|
|
||||||
// 运行时数据(与原系统兼容的格式)
|
// 运行时数据
|
||||||
configs?: Record<string, any>; // 基本配置数据(包含基本信息+节点配置)
|
configs?: Record<string, any>; // 基本配置数据(包含基本信息+节点配置)
|
||||||
inputMapping?: Record<string, any>; // 输入参数映射
|
inputMapping?: Record<string, any>; // 输入映射(用户配置)
|
||||||
outputMapping?: Record<string, any>; // 输出参数映射
|
outputs?: import('./nodes/types').OutputField[]; // 输出能力定义(从节点定义中获取)
|
||||||
|
|
||||||
// 原始节点定义(使用新的节点定义接口)
|
// 原始节点定义(使用新的节点定义接口)
|
||||||
nodeDefinition?: import('./nodes/types').WorkflowNodeDefinition;
|
nodeDefinition?: import('./nodes/types').WorkflowNodeDefinition;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user