diff --git a/frontend/src/pages/Workflow2/Design/nodes/JenkinsBuildNode.tsx b/frontend/src/pages/Workflow2/Design/nodes/JenkinsBuildNode.tsx new file mode 100644 index 00000000..42a55ac2 --- /dev/null +++ b/frontend/src/pages/Workflow2/Design/nodes/JenkinsBuildNode.tsx @@ -0,0 +1,327 @@ +import React, { memo } from 'react'; +import { Handle, Position, NodeProps } from '@xyflow/react'; +import { ConfigurableNodeDefinition, NodeType, NodeCategory } from './types'; +import type { FlowNodeData } from '../types'; + +/** + * Jenkins构建节点定义(元数据) + */ +export const JenkinsBuildNodeDefinition: ConfigurableNodeDefinition = { + nodeCode: "JENKINS_BUILD", + nodeName: "Jenkins构建", + nodeType: NodeType.JENKINS_BUILD, + category: NodeCategory.TASK, + description: "通过Jenkins执行构建任务", + + uiConfig: { + size: { width: 160, height: 80 }, + style: { + fill: '#52c41a', + stroke: '#389e08', + strokeWidth: 2, + icon: 'jenkins', + iconColor: '#fff' + } + }, + + // 基本配置Schema + configSchema: { + type: "object", + title: "基本配置", + description: "节点的基本信息和Jenkins构建配置参数", + properties: { + nodeName: { + type: "string", + title: "节点名称", + description: "节点在流程图中显示的名称", + default: "Jenkins构建" + }, + nodeCode: { + type: "string", + title: "节点编码", + description: "节点的唯一标识符", + default: "JENKINS_BUILD" + }, + description: { + type: "string", + title: "节点描述", + description: "节点的详细说明", + default: "通过Jenkins执行构建任务" + }, + jenkinsUrl: { + type: "string", + title: "Jenkins服务器地址", + description: "Jenkins服务器的完整URL地址", + default: "http://jenkins.example.com:8080", + format: "uri" + }, + jobName: { + type: "string", + title: "Job名称", + description: "要执行的Jenkins Job名称", + default: "" + }, + username: { + type: "string", + title: "用户名", + description: "Jenkins认证用户名", + default: "" + }, + apiToken: { + type: "string", + title: "API Token", + description: "Jenkins API Token或密码", + default: "", + format: "password" + }, + timeout: { + type: "number", + title: "超时时间(秒)", + description: "构建超时时间", + default: 600, + minimum: 60, + maximum: 7200 + }, + waitForCompletion: { + type: "boolean", + title: "等待构建完成", + description: "是否等待Jenkins构建完成", + default: true + }, + retryCount: { + type: "number", + title: "重试次数", + description: "构建失败时的重试次数", + default: 1, + minimum: 0, + maximum: 5 + }, + branchName: { + type: "string", + title: "分支名称", + description: "要构建的Git分支名称", + default: "main" + } + }, + required: ["nodeName", "nodeCode", "jenkinsUrl", "jobName", "username", "apiToken"] + }, + + // 输入映射Schema + inputMappingSchema: { + type: "object", + title: "输入映射", + description: "从上游节点接收的数据映射配置", + properties: { + sourceCodeUrl: { + type: "string", + title: "源代码仓库地址", + description: "Git仓库的URL地址", + default: "${upstream.gitUrl}" + }, + buildParameters: { + type: "object", + title: "构建参数", + description: "传递给Jenkins Job的构建参数", + properties: {}, + additionalProperties: true, + default: {} + }, + environmentVariables: { + type: "object", + title: "环境变量", + description: "构建时的环境变量", + properties: {}, + additionalProperties: true, + default: {} + }, + commitId: { + type: "string", + title: "提交ID", + description: "要构建的Git提交ID", + default: "${upstream.commitId}" + }, + projectName: { + type: "string", + title: "项目名称", + description: "项目的名称标识", + default: "${upstream.projectName}" + }, + buildVersion: { + type: "string", + title: "构建版本", + description: "构建版本号", + default: "${upstream.version}" + } + }, + required: ["sourceCodeUrl", "buildParameters"] + }, + + // 输出映射Schema + outputMappingSchema: { + type: "object", + title: "输出映射", + description: "传递给下游节点的数据映射配置", + 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", + title: "构建耗时", + description: "构建耗时(毫秒)", + default: 0 + }, + artifactsUrl: { + type: "string", + title: "构建产物URL", + description: "构建产物的下载地址", + default: "${jenkins.artifactsUrl}" + }, + consoleLog: { + type: "string", + title: "控制台日志", + description: "构建的控制台输出日志", + default: "${jenkins.consoleText}" + }, + testResults: { + type: "object", + title: "测试结果", + description: "构建中的测试结果统计", + properties: { + totalCount: { type: "number", title: "总测试数", default: 0 }, + passCount: { type: "number", title: "通过数", default: 0 }, + failCount: { type: "number", title: "失败数", default: 0 }, + skipCount: { type: "number", title: "跳过数", default: 0 } + }, + default: { + totalCount: 0, + passCount: 0, + failCount: 0, + skipCount: 0 + } + } + }, + required: ["buildId", "buildStatus", "buildUrl"] + } +}; + +/** + * Jenkins构建节点渲染组件 + */ +const JenkinsBuildNode: React.FC = ({ data, selected }) => { + const nodeData = data as FlowNodeData; + + return ( +
+ {/* 输入连接点 */} + + + {/* 节点内容 */} +
+ {/* 图标 */} +
+ 🔨 +
+ + {/* 标签 */} +
+ {nodeData.label || 'Jenkins构建'} +
+
+ + {/* 输出连接点 */} + + + {/* 配置指示器 */} + {nodeData.configs && Object.keys(nodeData.configs).length > 3 && ( +
+ ✓ +
+ )} +
+ ); +}; + +export default memo(JenkinsBuildNode); + diff --git a/frontend/src/pages/Workflow2/Design/nodes/ServiceTaskNode.tsx b/frontend/src/pages/Workflow2/Design/nodes/ServiceTaskNode.tsx deleted file mode 100644 index 9f1dc1c0..00000000 --- a/frontend/src/pages/Workflow2/Design/nodes/ServiceTaskNode.tsx +++ /dev/null @@ -1,177 +0,0 @@ -import React, { memo } from 'react'; -import { Handle, Position, NodeProps } from '@xyflow/react'; -import { ConfigurableNodeDefinition, NodeType, NodeCategory } from './types'; -import type { FlowNodeData } from '../types'; - -/** - * 服务任务节点定义(元数据) - */ -export const ServiceTaskNodeDefinition: ConfigurableNodeDefinition = { - nodeCode: "SERVICE_TASK", - nodeName: "服务任务", - nodeType: NodeType.SERVICE_TASK, - category: NodeCategory.TASK, - description: "自动执行的服务任务节点", - - uiConfig: { - size: { width: 120, height: 80 }, - style: { - fill: '#722ed1', - stroke: '#531dab', - strokeWidth: 2, - icon: 'api', - iconColor: '#fff' - } - }, - - configSchema: { - type: "object", - title: "基本配置", - description: "节点的基本信息和服务配置", - properties: { - nodeName: { - type: "string", - title: "节点名称", - default: "服务任务" - }, - nodeCode: { - type: "string", - title: "节点编码", - default: "SERVICE_TASK" - }, - description: { - type: "string", - title: "节点描述", - default: "自动执行的服务任务节点" - }, - serviceUrl: { - type: "string", - title: "服务地址", - description: "调用的服务URL", - format: "uri" - }, - method: { - type: "string", - title: "请求方法", - enum: ["GET", "POST", "PUT", "DELETE"], - default: "POST" - }, - timeout: { - type: "number", - title: "超时时间(秒)", - default: 30, - minimum: 1, - maximum: 300 - }, - retryCount: { - type: "number", - title: "重试次数", - default: 0, - minimum: 0, - maximum: 5 - } - }, - required: ["nodeName", "nodeCode", "serviceUrl"] - }, - - inputMappingSchema: { - type: "object", - title: "输入映射", - properties: { - requestBody: { - type: "object", - title: "请求体" - }, - headers: { - type: "object", - title: "请求头" - } - } - }, - - outputMappingSchema: { - type: "object", - title: "输出映射", - properties: { - responseData: { - type: "object", - title: "响应数据" - }, - statusCode: { - type: "number", - title: "状态码" - } - } - } -}; - -/** - * 服务任务节点渲染组件 - */ -const ServiceTaskNode: React.FC = ({ data, selected }) => { - const nodeData = data as FlowNodeData; - - return ( -
- {/* 输入连接点 */} - - - {/* 图标和标签 */} -
- ⚙️ - - {nodeData.label || '服务任务'} - -
- - {/* 输出连接点 */} - -
- ); -}; - -export default memo(ServiceTaskNode); - diff --git a/frontend/src/pages/Workflow2/Design/nodes/UserTaskNode.tsx b/frontend/src/pages/Workflow2/Design/nodes/UserTaskNode.tsx deleted file mode 100644 index 8bdf9112..00000000 --- a/frontend/src/pages/Workflow2/Design/nodes/UserTaskNode.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import React, { memo } from 'react'; -import { Handle, Position, NodeProps } from '@xyflow/react'; -import { ConfigurableNodeDefinition, NodeType, NodeCategory } from './types'; -import type { FlowNodeData } from '../types'; - -/** - * 用户任务节点定义(元数据) - */ -export const UserTaskNodeDefinition: ConfigurableNodeDefinition = { - nodeCode: "USER_TASK", - nodeName: "用户任务", - nodeType: NodeType.USER_TASK, - category: NodeCategory.TASK, - description: "需要用户手动处理的任务节点", - - uiConfig: { - size: { width: 120, height: 80 }, - style: { - fill: '#1890ff', - stroke: '#096dd9', - strokeWidth: 2, - icon: 'user', - iconColor: '#fff' - } - }, - - configSchema: { - type: "object", - title: "基本配置", - description: "节点的基本信息和任务配置", - properties: { - nodeName: { - type: "string", - title: "节点名称", - default: "用户任务" - }, - nodeCode: { - type: "string", - title: "节点编码", - default: "USER_TASK" - }, - description: { - type: "string", - title: "节点描述", - default: "需要用户手动处理的任务节点" - }, - assignee: { - type: "string", - title: "处理人", - description: "指定任务处理人" - }, - candidateGroups: { - type: "string", - title: "候选组", - description: "候选用户组,多个用逗号分隔" - }, - dueDate: { - type: "string", - title: "截止日期", - format: "date-time" - } - }, - required: ["nodeName", "nodeCode"] - }, - - inputMappingSchema: { - type: "object", - title: "输入映射", - properties: { - taskData: { - type: "object", - title: "任务数据" - } - } - }, - - outputMappingSchema: { - type: "object", - title: "输出映射", - properties: { - result: { - type: "string", - title: "处理结果" - } - } - } -}; - -/** - * 用户任务节点渲染组件 - */ -const UserTaskNode: React.FC = ({ data, selected }) => { - const nodeData = data as FlowNodeData; - - return ( -
- {/* 输入连接点 */} - - - {/* 图标和标签 */} -
- 👤 - - {nodeData.label || '用户任务'} - -
- - {/* 输出连接点 */} - -
- ); -}; - -export default memo(UserTaskNode); - diff --git a/frontend/src/pages/Workflow2/Design/nodes/index.ts b/frontend/src/pages/Workflow2/Design/nodes/index.ts index 2653f481..cafc6725 100644 --- a/frontend/src/pages/Workflow2/Design/nodes/index.ts +++ b/frontend/src/pages/Workflow2/Design/nodes/index.ts @@ -7,8 +7,7 @@ import StartEventNode, { StartEventNodeDefinition } from './StartEventNode'; import EndEventNode, { EndEventNodeDefinition } from './EndEventNode'; -import UserTaskNode, { UserTaskNodeDefinition } from './UserTaskNode'; -import ServiceTaskNode, { ServiceTaskNodeDefinition } from './ServiceTaskNode'; +import JenkinsBuildNode, { JenkinsBuildNodeDefinition } from './JenkinsBuildNode'; import type { WorkflowNodeDefinition } from './types'; /** @@ -17,8 +16,7 @@ import type { WorkflowNodeDefinition } from './types'; export const NODE_DEFINITIONS: WorkflowNodeDefinition[] = [ StartEventNodeDefinition, EndEventNodeDefinition, - UserTaskNodeDefinition, - ServiceTaskNodeDefinition, + JenkinsBuildNodeDefinition, ]; /** @@ -27,8 +25,7 @@ export const NODE_DEFINITIONS: WorkflowNodeDefinition[] = [ export const nodeTypes = { START_EVENT: StartEventNode, END_EVENT: EndEventNode, - USER_TASK: UserTaskNode, - SERVICE_TASK: ServiceTaskNode, + JENKINS_BUILD: JenkinsBuildNode, }; /** @@ -38,16 +35,13 @@ export { // 组件 StartEventNode, EndEventNode, - UserTaskNode, - ServiceTaskNode, + JenkinsBuildNode, // 定义 StartEventNodeDefinition, EndEventNodeDefinition, - UserTaskNodeDefinition, - ServiceTaskNodeDefinition, + JenkinsBuildNodeDefinition, }; // 导出类型 export * from './types'; - diff --git a/frontend/src/pages/Workflow2/Design/nodes/types.ts b/frontend/src/pages/Workflow2/Design/nodes/types.ts index efe95791..f3fa0374 100644 --- a/frontend/src/pages/Workflow2/Design/nodes/types.ts +++ b/frontend/src/pages/Workflow2/Design/nodes/types.ts @@ -10,14 +10,9 @@ export enum NodeCategory { export enum NodeType { START_EVENT = 'START_EVENT', END_EVENT = 'END_EVENT', - USER_TASK = 'USER_TASK', - SERVICE_TASK = 'SERVICE_TASK', SCRIPT_TASK = 'SCRIPT_TASK', - DEPLOY_NODE = 'DEPLOY_NODE', JENKINS_BUILD = 'JENKINS_BUILD', GATEWAY_NODE = 'GATEWAY_NODE', - SUB_PROCESS = 'SUB_PROCESS', - CALL_ACTIVITY = 'CALL_ACTIVITY' } // JSON Schema 定义