增加工具栏提示。

This commit is contained in:
dengqichen 2024-12-13 09:48:04 +08:00
parent d2f67d060c
commit 2df3cb3074
2 changed files with 149 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import { getDefinitionDetail, saveDefinition } from '../service';
import NodePanel from './components/NodePanel'; import NodePanel from './components/NodePanel';
import NodeConfigDrawer from './components/NodeConfigModal'; import NodeConfigDrawer from './components/NodeConfigModal';
import { NodeDefinition } from './types'; import { NodeDefinition } from './types';
import { validateWorkflow } from './utils/validator';
import { import {
NODE_REGISTRY_CONFIG, NODE_REGISTRY_CONFIG,
GRID_CONFIG, GRID_CONFIG,
@ -208,6 +209,13 @@ const WorkflowDesign: React.FC = () => {
if (!graph || !definitionData) return; if (!graph || !definitionData) return;
try { try {
// 校验流程图
const validationResult = validateWorkflow(graph);
if (!validationResult.valid) {
message.error(validationResult.message);
return;
}
// 获取所有节点和边的数据 // 获取所有节点和边的数据
const nodes = graph.getNodes().map(node => { const nodes = graph.getNodes().map(node => {
const nodeDefinition = node.getProp('nodeDefinition'); const nodeDefinition = node.getProp('nodeDefinition');
@ -215,7 +223,7 @@ const WorkflowDesign: React.FC = () => {
return { return {
id: node.id, id: node.id,
code: nodeType, // 设置 code 为节点的 type code: nodeType,
type: nodeType, type: nodeType,
name: node.attr('label/text'), name: node.attr('label/text'),
graph: { graph: {

View File

@ -0,0 +1,140 @@
import { Graph, Cell } from '@antv/x6';
interface ValidationResult {
valid: boolean;
message?: string;
}
/**
*
* @param node
* @param nodeDefinition
*/
const validateNodeConfig = (node: Cell, nodeDefinition: any): ValidationResult => {
const config = node.getProp('config');
const configSchema = nodeDefinition?.graphConfig.configSchema;
if (!config) {
return {
valid: false,
message: `节点 "${node.attr('label/text')}" 未配置`
};
}
// 检查必填字段
if (configSchema?.required) {
for (const field of configSchema.required) {
if (!config[field]) {
const fieldTitle = configSchema.properties[field]?.title || field;
return {
valid: false,
message: `节点 "${node.attr('label/text')}" 的 "${fieldTitle}" 是必填项`
};
}
}
}
return { valid: true };
};
/**
*
* @param graph
*/
const validateGraphNotEmpty = (graph: Graph): ValidationResult => {
const nodes = graph.getNodes();
if (nodes.length === 0) {
return {
valid: false,
message: '流程图中没有任何节点'
};
}
return { valid: true };
};
/**
*
* @param graph
*/
const validateRequiredNodes = (graph: Graph): ValidationResult => {
const nodes = graph.getNodes();
// 检查开始节点
const hasStartNode = nodes.some(node => node.getProp('type') === 'START_EVENT');
if (!hasStartNode) {
return {
valid: false,
message: '流程图中必须包含开始节点'
};
}
// 检查结束节点
const hasEndNode = nodes.some(node => node.getProp('type') === 'END_EVENT');
if (!hasEndNode) {
return {
valid: false,
message: '流程图中必须包含结束节点'
};
}
return { valid: true };
};
/**
*
* @param graph
*/
const validateNodeConnections = (graph: Graph): ValidationResult => {
const nodes = graph.getNodes();
const edges = graph.getEdges();
if (edges.length < nodes.length - 1) {
return {
valid: false,
message: '存在未连接的节点,请确保所有节点都已正确连接'
};
}
return { valid: true };
};
/**
*
* @param graph
*/
const validateAllNodesConfig = (graph: Graph): ValidationResult => {
const nodes = graph.getNodes();
for (const node of nodes) {
const nodeDefinition = node.getProp('nodeDefinition');
const result = validateNodeConfig(node, nodeDefinition);
if (!result.valid) {
return result;
}
}
return { valid: true };
};
/**
*
* @param graph
*/
export const validateWorkflow = (graph: Graph): ValidationResult => {
// 按顺序执行所有验证
const validators = [
validateGraphNotEmpty,
validateRequiredNodes,
validateAllNodesConfig,
validateNodeConnections
];
for (const validator of validators) {
const result = validator(graph);
if (!result.valid) {
return result;
}
}
return { valid: true };
};