This commit is contained in:
dengqichen 2025-10-21 15:41:43 +08:00
parent 702c42823b
commit 3b67370c2e
4 changed files with 35 additions and 76 deletions

View File

@ -34,6 +34,7 @@
"@radix-ui/react-tooltip": "^1.2.8",
"@reduxjs/toolkit": "^2.0.1",
"@types/recharts": "^1.8.29",
"@types/uuid": "^10.0.0",
"@xyflow/react": "^12.8.6",
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
@ -52,6 +53,7 @@
"react-redux": "^9.0.4",
"react-router-dom": "^6.21.0",
"recharts": "^2.15.0",
"uuid": "^13.0.0",
"zod": "^3.24.1"
},
"devDependencies": {
@ -5113,6 +5115,12 @@
"resolved": "https://registry.npmmirror.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
},
"node_modules/@types/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmmirror.com/@types/uuid/-/uuid-10.0.0.tgz",
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "6.21.0",
"resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
@ -10206,6 +10214,19 @@
"dev": true,
"license": "MIT"
},
"node_modules/uuid": {
"version": "13.0.0",
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-13.0.0.tgz",
"integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist-node/bin/uuid"
}
},
"node_modules/victory-vendor": {
"version": "36.9.2",
"resolved": "https://registry.npmmirror.com/victory-vendor/-/victory-vendor-36.9.2.tgz",

View File

@ -36,6 +36,7 @@
"@radix-ui/react-tooltip": "^1.2.8",
"@reduxjs/toolkit": "^2.0.1",
"@types/recharts": "^1.8.29",
"@types/uuid": "^10.0.0",
"@xyflow/react": "^12.8.6",
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
@ -54,6 +55,7 @@
"react-redux": "^9.0.4",
"react-router-dom": "^6.21.0",
"recharts": "^2.15.0",
"uuid": "^13.0.0",
"zod": "^3.24.1"
},
"devDependencies": {

View File

@ -13,6 +13,7 @@ import {
Panel
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import { v4 as uuidv4 } from 'uuid';
import type { FlowNode, FlowEdge } from '../types';
import { nodeTypes } from '../nodes';
@ -49,8 +50,10 @@ const FlowCanvas: React.FC<FlowCanvasProps> = ({
// 处理连接
const onConnect = useCallback(
(params: Connection | Edge) => {
const newEdge = {
...params,
const newEdge: FlowEdge = {
id: uuidv4(), // 使用 UUID 生成唯一 ID
source: params.source!,
target: params.target!,
type: 'smoothstep',
animated: true,
style: {

View File

@ -2,6 +2,7 @@ import React, { useState, useCallback, useRef, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { message } from 'antd';
import { ReactFlowProvider, useReactFlow } from '@xyflow/react';
import { v4 as uuidv4 } from 'uuid';
import WorkflowToolbar from './components/WorkflowToolbar';
import NodePanel from './components/NodePanel';
@ -10,7 +11,6 @@ import NodeConfigModal from './components/NodeConfigModal';
import EdgeConfigModal, { type EdgeCondition } from './components/EdgeConfigModal';
import type { FlowNode, FlowEdge, FlowNodeData } from './types';
import type { WorkflowNodeDefinition } from './nodes/types';
import { NodeType } from './types';
import { useWorkflowSave } from './hooks/useWorkflowSave';
import { useWorkflowLoad } from './hooks/useWorkflowLoad';
import { useHistory } from './hooks/useHistory';
@ -97,76 +97,9 @@ const WorkflowDesignInner: React.FC = () => {
return () => clearTimeout(timer);
}, [fitView, getZoom]);
// 初始化示例节点 - 优化位置和布局
const initialNodes: FlowNode[] = [
{
id: '1',
type: 'START_EVENT',
position: { x: 250, y: 50 },
data: {
label: '开始',
nodeType: NodeType.START_EVENT,
category: 'EVENT' as any,
icon: '▶️',
color: '#10b981'
}
},
{
id: '2',
type: 'USER_TASK',
position: { x: 200, y: 150 },
data: {
label: '用户审批',
nodeType: NodeType.USER_TASK,
category: 'TASK' as any,
icon: '👤',
color: '#6366f1'
}
},
{
id: '3',
type: 'END_EVENT',
position: { x: 250, y: 250 },
data: {
label: '结束',
nodeType: NodeType.END_EVENT,
category: 'EVENT' as any,
icon: '⏹️',
color: '#ef4444'
}
}
];
const initialEdges: FlowEdge[] = [
{
id: 'e1-2',
source: '1',
target: '2',
type: 'default',
animated: true,
data: {
label: '提交',
condition: {
type: 'DEFAULT',
priority: 0
}
}
},
{
id: 'e2-3',
source: '2',
target: '3',
type: 'default',
animated: true,
data: {
label: '通过',
condition: {
type: 'DEFAULT',
priority: 0
}
}
}
];
// 初始化空白画布
const initialNodes: FlowNode[] = [];
const initialEdges: FlowEdge[] = [];
// 工具栏事件处理
const handleSave = useCallback(async () => {
@ -351,7 +284,7 @@ const WorkflowDesignInner: React.FC = () => {
});
const newNode: FlowNode = {
id: `${nodeType}-${Date.now()}`,
id: uuidv4(), // 使用 UUID 生成唯一 ID
type: nodeType,
position,
data: {
@ -362,10 +295,10 @@ const WorkflowDesignInner: React.FC = () => {
color: nodeDefinition.renderConfig.theme.primary,
// 保存原始节点定义引用,用于配置
nodeDefinition,
// 初始化配置数据
// 初始化配置数据nodeCode 使用预定义的常量值)
configs: {
nodeName: nodeDefinition.nodeName,
nodeCode: nodeDefinition.nodeCode,
nodeCode: nodeDefinition.nodeCode, // 使用预定义的 CODE如 "END_EVENT"
description: nodeDefinition.description
},
inputMapping: {},