1
This commit is contained in:
parent
702c42823b
commit
3b67370c2e
21
frontend/package-lock.json
generated
21
frontend/package-lock.json
generated
@ -34,6 +34,7 @@
|
|||||||
"@radix-ui/react-tooltip": "^1.2.8",
|
"@radix-ui/react-tooltip": "^1.2.8",
|
||||||
"@reduxjs/toolkit": "^2.0.1",
|
"@reduxjs/toolkit": "^2.0.1",
|
||||||
"@types/recharts": "^1.8.29",
|
"@types/recharts": "^1.8.29",
|
||||||
|
"@types/uuid": "^10.0.0",
|
||||||
"@xyflow/react": "^12.8.6",
|
"@xyflow/react": "^12.8.6",
|
||||||
"ajv": "^8.17.1",
|
"ajv": "^8.17.1",
|
||||||
"ajv-formats": "^3.0.1",
|
"ajv-formats": "^3.0.1",
|
||||||
@ -52,6 +53,7 @@
|
|||||||
"react-redux": "^9.0.4",
|
"react-redux": "^9.0.4",
|
||||||
"react-router-dom": "^6.21.0",
|
"react-router-dom": "^6.21.0",
|
||||||
"recharts": "^2.15.0",
|
"recharts": "^2.15.0",
|
||||||
|
"uuid": "^13.0.0",
|
||||||
"zod": "^3.24.1"
|
"zod": "^3.24.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -5113,6 +5115,12 @@
|
|||||||
"resolved": "https://registry.npmmirror.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
||||||
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
|
"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": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "6.21.0",
|
"version": "6.21.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
|
||||||
@ -10206,6 +10214,19 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"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": {
|
"node_modules/victory-vendor": {
|
||||||
"version": "36.9.2",
|
"version": "36.9.2",
|
||||||
"resolved": "https://registry.npmmirror.com/victory-vendor/-/victory-vendor-36.9.2.tgz",
|
"resolved": "https://registry.npmmirror.com/victory-vendor/-/victory-vendor-36.9.2.tgz",
|
||||||
|
|||||||
@ -36,6 +36,7 @@
|
|||||||
"@radix-ui/react-tooltip": "^1.2.8",
|
"@radix-ui/react-tooltip": "^1.2.8",
|
||||||
"@reduxjs/toolkit": "^2.0.1",
|
"@reduxjs/toolkit": "^2.0.1",
|
||||||
"@types/recharts": "^1.8.29",
|
"@types/recharts": "^1.8.29",
|
||||||
|
"@types/uuid": "^10.0.0",
|
||||||
"@xyflow/react": "^12.8.6",
|
"@xyflow/react": "^12.8.6",
|
||||||
"ajv": "^8.17.1",
|
"ajv": "^8.17.1",
|
||||||
"ajv-formats": "^3.0.1",
|
"ajv-formats": "^3.0.1",
|
||||||
@ -54,6 +55,7 @@
|
|||||||
"react-redux": "^9.0.4",
|
"react-redux": "^9.0.4",
|
||||||
"react-router-dom": "^6.21.0",
|
"react-router-dom": "^6.21.0",
|
||||||
"recharts": "^2.15.0",
|
"recharts": "^2.15.0",
|
||||||
|
"uuid": "^13.0.0",
|
||||||
"zod": "^3.24.1"
|
"zod": "^3.24.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import {
|
|||||||
Panel
|
Panel
|
||||||
} from '@xyflow/react';
|
} from '@xyflow/react';
|
||||||
import '@xyflow/react/dist/style.css';
|
import '@xyflow/react/dist/style.css';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
import type { FlowNode, FlowEdge } from '../types';
|
import type { FlowNode, FlowEdge } from '../types';
|
||||||
import { nodeTypes } from '../nodes';
|
import { nodeTypes } from '../nodes';
|
||||||
@ -49,8 +50,10 @@ const FlowCanvas: React.FC<FlowCanvasProps> = ({
|
|||||||
// 处理连接
|
// 处理连接
|
||||||
const onConnect = useCallback(
|
const onConnect = useCallback(
|
||||||
(params: Connection | Edge) => {
|
(params: Connection | Edge) => {
|
||||||
const newEdge = {
|
const newEdge: FlowEdge = {
|
||||||
...params,
|
id: uuidv4(), // 使用 UUID 生成唯一 ID
|
||||||
|
source: params.source!,
|
||||||
|
target: params.target!,
|
||||||
type: 'smoothstep',
|
type: 'smoothstep',
|
||||||
animated: true,
|
animated: true,
|
||||||
style: {
|
style: {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import React, { useState, useCallback, useRef, useEffect } from 'react';
|
|||||||
import { useParams, useNavigate } from 'react-router-dom';
|
import { useParams, useNavigate } from 'react-router-dom';
|
||||||
import { message } from 'antd';
|
import { message } from 'antd';
|
||||||
import { ReactFlowProvider, useReactFlow } from '@xyflow/react';
|
import { ReactFlowProvider, useReactFlow } from '@xyflow/react';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
import WorkflowToolbar from './components/WorkflowToolbar';
|
import WorkflowToolbar from './components/WorkflowToolbar';
|
||||||
import NodePanel from './components/NodePanel';
|
import NodePanel from './components/NodePanel';
|
||||||
@ -10,7 +11,6 @@ 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 { NodeType } from './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';
|
||||||
@ -97,76 +97,9 @@ const WorkflowDesignInner: React.FC = () => {
|
|||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [fitView, getZoom]);
|
}, [fitView, getZoom]);
|
||||||
|
|
||||||
// 初始化示例节点 - 优化位置和布局
|
// 初始化空白画布
|
||||||
const initialNodes: FlowNode[] = [
|
const initialNodes: FlowNode[] = [];
|
||||||
{
|
const initialEdges: FlowEdge[] = [];
|
||||||
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 handleSave = useCallback(async () => {
|
const handleSave = useCallback(async () => {
|
||||||
@ -351,7 +284,7 @@ const WorkflowDesignInner: React.FC = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const newNode: FlowNode = {
|
const newNode: FlowNode = {
|
||||||
id: `${nodeType}-${Date.now()}`,
|
id: uuidv4(), // 使用 UUID 生成唯一 ID
|
||||||
type: nodeType,
|
type: nodeType,
|
||||||
position,
|
position,
|
||||||
data: {
|
data: {
|
||||||
@ -362,10 +295,10 @@ const WorkflowDesignInner: React.FC = () => {
|
|||||||
color: nodeDefinition.renderConfig.theme.primary,
|
color: nodeDefinition.renderConfig.theme.primary,
|
||||||
// 保存原始节点定义引用,用于配置
|
// 保存原始节点定义引用,用于配置
|
||||||
nodeDefinition,
|
nodeDefinition,
|
||||||
// 初始化配置数据
|
// 初始化配置数据(nodeCode 使用预定义的常量值)
|
||||||
configs: {
|
configs: {
|
||||||
nodeName: nodeDefinition.nodeName,
|
nodeName: nodeDefinition.nodeName,
|
||||||
nodeCode: nodeDefinition.nodeCode,
|
nodeCode: nodeDefinition.nodeCode, // 使用预定义的 CODE(如 "END_EVENT")
|
||||||
description: nodeDefinition.description
|
description: nodeDefinition.description
|
||||||
},
|
},
|
||||||
inputMapping: {},
|
inputMapping: {},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user