节点验证。

This commit is contained in:
dengqichen 2024-12-06 17:15:06 +08:00
parent 4cb2b0b685
commit 84012dd98d
2 changed files with 55 additions and 21 deletions

View File

@ -1,5 +1,5 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { Space, Button, Tooltip, Divider } from 'antd'; import { Space, Button, Tooltip, Divider, message } from 'antd';
import { import {
ZoomInOutlined, ZoomInOutlined,
ZoomOutOutlined, ZoomOutOutlined,
@ -11,6 +11,7 @@ import {
RedoOutlined, RedoOutlined,
CopyOutlined, CopyOutlined,
SnippetsOutlined, SnippetsOutlined,
CheckCircleOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { Graph, Cell } from '@antv/x6'; import { Graph, Cell } from '@antv/x6';
import { Selection } from '@antv/x6-plugin-selection'; import { Selection } from '@antv/x6-plugin-selection';
@ -18,6 +19,7 @@ import { History } from '@antv/x6-plugin-history';
import { Clipboard } from '@antv/x6-plugin-clipboard'; import { Clipboard } from '@antv/x6-plugin-clipboard';
import { Transform } from '@antv/x6-plugin-transform'; import { Transform } from '@antv/x6-plugin-transform';
import { Keyboard } from '@antv/x6-plugin-keyboard'; import { Keyboard } from '@antv/x6-plugin-keyboard';
import { validateFlow, hasCycle } from '../../validate';
import './index.less'; import './index.less';
interface ToolbarProps { interface ToolbarProps {
@ -232,6 +234,26 @@ const Toolbar: React.FC<ToolbarProps> = ({ graph }) => {
return !clipboard?.isEmpty(); return !clipboard?.isEmpty();
}; };
// 验证流程
const validateWorkflow = () => {
if (!graph) return;
const result = validateFlow(graph);
const hasCycleResult = hasCycle(graph);
if (hasCycleResult) {
message.error('流程图中存在循环,请检查');
return;
}
if (!result.valid) {
message.error(result.errors.join('\n'));
return;
}
message.success('流程验证通过');
};
return ( return (
<div className="workflow-toolbar"> <div className="workflow-toolbar">
<Space split={<Divider type="vertical" />}> <Space split={<Divider type="vertical" />}>
@ -249,47 +271,35 @@ const Toolbar: React.FC<ToolbarProps> = ({ graph }) => {
<Button icon={<OneToOneOutlined />} onClick={resetZoom} /> <Button icon={<OneToOneOutlined />} onClick={resetZoom} />
</Tooltip> </Tooltip>
</Space> </Space>
<Space> <Space>
<Tooltip title="全选 (Ctrl + A)"> <Tooltip title="全选">
<Button icon={<SelectOutlined />} onClick={selectAll} /> <Button icon={<SelectOutlined />} onClick={selectAll} />
</Tooltip> </Tooltip>
<Tooltip title="删除 (Delete)"> <Tooltip title="删除">
<Button <Button
icon={<DeleteOutlined />} icon={<DeleteOutlined />}
onClick={deleteSelected} onClick={deleteSelected}
disabled={!hasSelection()} disabled={!hasSelection()}
danger
/> />
</Tooltip> </Tooltip>
</Space> </Space>
<Space> <Space>
<Tooltip title="撤销 (Ctrl + Z)"> <Tooltip title="撤销">
<Button <Button icon={<UndoOutlined />} onClick={undo} />
icon={<UndoOutlined />}
onClick={undo}
disabled={!graph?.getPlugin<History>('history')?.canUndo()}
/>
</Tooltip> </Tooltip>
<Tooltip title="重做 (Ctrl + Shift + Z)"> <Tooltip title="重做">
<Button <Button icon={<RedoOutlined />} onClick={redo} />
icon={<RedoOutlined />}
onClick={redo}
disabled={!graph?.getPlugin<History>('history')?.canRedo()}
/>
</Tooltip> </Tooltip>
</Space> </Space>
<Space> <Space>
<Tooltip title="复制 (Ctrl + C)"> <Tooltip title="复制">
<Button <Button
icon={<CopyOutlined />} icon={<CopyOutlined />}
onClick={copy} onClick={copy}
disabled={!hasSelection()} disabled={!hasSelection()}
/> />
</Tooltip> </Tooltip>
<Tooltip title="粘贴 (Ctrl + V)"> <Tooltip title="粘贴">
<Button <Button
icon={<SnippetsOutlined />} icon={<SnippetsOutlined />}
onClick={paste} onClick={paste}
@ -297,6 +307,15 @@ const Toolbar: React.FC<ToolbarProps> = ({ graph }) => {
/> />
</Tooltip> </Tooltip>
</Space> </Space>
<Space>
<Tooltip title="验证流程">
<Button
icon={<CheckCircleOutlined />}
onClick={validateWorkflow}
type="primary"
/>
</Tooltip>
</Space>
</Space> </Space>
</div> </div>
); );

View File

@ -20,6 +20,7 @@ import Toolbar from './components/Toolbar';
import {NodeType, getNodeTypes} from './service'; import {NodeType, getNodeTypes} from './service';
import {DeleteOutlined, CopyOutlined, SettingOutlined, ClearOutlined, FullscreenOutlined} from '@ant-design/icons'; import {DeleteOutlined, CopyOutlined, SettingOutlined, ClearOutlined, FullscreenOutlined} from '@ant-design/icons';
import EdgeConfig from './components/EdgeConfig'; import EdgeConfig from './components/EdgeConfig';
import { validateFlow, hasCycle } from './validate';
const {Sider, Content} = Layout; const {Sider, Content} = Layout;
@ -681,6 +682,20 @@ const FlowDesigner: React.FC = () => {
if (!id || !detail || !graphRef.current || detail.status !== WorkflowStatus.DRAFT) return; if (!id || !detail || !graphRef.current || detail.status !== WorkflowStatus.DRAFT) return;
try { try {
// 验证流程
const result = validateFlow(graphRef.current);
const hasCycleResult = hasCycle(graphRef.current);
if (hasCycleResult) {
message.error('流程图中存在循环,请检查');
return;
}
if (!result.valid) {
message.error(result.errors.join('\n'));
return;
}
const graphData = graphRef.current.toJSON(); const graphData = graphRef.current.toJSON();
// 收集节点配置数据 // 收集节点配置数据