增加GIT代码检测节点
This commit is contained in:
parent
ee65e204c6
commit
61ff98737d
@ -121,14 +121,8 @@ const EdgeConfigModal: React.FC<EdgeConfigModalProps> = ({
|
|||||||
const expr = values.expression?.trim();
|
const expr = values.expression?.trim();
|
||||||
const isDefault = !expr;
|
const isDefault = !expr;
|
||||||
|
|
||||||
// 1. 检查多个默认分支
|
// 1. 检查多个默认分支(已在UI上显示红色警告框,此处直接阻止提交)
|
||||||
if (isDefault && hasOtherDefaultBranch) {
|
if (isDefault && hasOtherDefaultBranch) {
|
||||||
toast({
|
|
||||||
variant: 'destructive',
|
|
||||||
title: '冲突:多个默认分支',
|
|
||||||
description: `节点"${sourceNode?.data.label}"已有默认分支。一个节点只能有一个默认分支,请为此分支配置条件表达式。`,
|
|
||||||
duration: 5000,
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,20 +254,21 @@ const EdgeConfigModal: React.FC<EdgeConfigModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 🔴 错误提示:多个默认分支(网关节点) */}
|
{/* 错误提示:多个默认分支(网关节点) */}
|
||||||
{isFromGateway && gatewayType && gatewayType !== 'parallelGateway' && hasOtherDefaultBranch && isDefaultBranch && (
|
{isFromGateway && gatewayType && gatewayType !== 'parallelGateway' && hasOtherDefaultBranch && isDefaultBranch && (
|
||||||
<div className="rounded-md bg-red-50 dark:bg-red-950/20 border-2 border-red-400 dark:border-red-600 p-4 text-sm mb-6">
|
<div className="rounded-lg bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-800 p-4 mb-6">
|
||||||
<div className="flex items-start gap-3">
|
<div className="flex items-start gap-3">
|
||||||
<span className="text-2xl">❌</span>
|
<div className="flex-shrink-0 w-5 h-5 mt-0.5 rounded-full bg-red-500 flex items-center justify-center">
|
||||||
<div className="flex-1 space-y-2">
|
<svg className="w-3 h-3 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<p className="font-bold text-red-900 dark:text-red-200 text-base">
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div className="flex-1">
|
||||||
|
<p className="font-semibold text-red-900 dark:text-red-200 mb-2">
|
||||||
已存在默认分支
|
已存在默认分支
|
||||||
</p>
|
</p>
|
||||||
<p className="text-red-800 dark:text-red-300">
|
<p className="text-sm text-red-800 dark:text-red-300 mb-2">
|
||||||
一个{gatewayType === 'exclusiveGateway' ? '排他' : '包容'}网关只能有<strong>一个</strong>默认分支!其他分支必须配置条件表达式。
|
当前网关已有一个默认分支,请将此分支设置为"表达式"类型并配置条件表达式。
|
||||||
</p>
|
|
||||||
<p className="text-red-800 dark:text-red-300 font-medium">
|
|
||||||
💡 建议操作:将此分支设置为<strong>"表达式"</strong>类型,并配置条件表达式。
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -281,23 +276,10 @@ const EdgeConfigModal: React.FC<EdgeConfigModalProps> = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
{/* 并行网关:直接显示说明,不允许配置条件 */}
|
{/* 并行网关:简洁提示 */}
|
||||||
{isFromGateway && gatewayType === 'parallelGateway' ? (
|
{isFromGateway && gatewayType === 'parallelGateway' ? (
|
||||||
<div className="rounded-md bg-green-50 dark:bg-green-950/20 border border-green-200 dark:border-green-800 p-4 text-sm">
|
<div className="py-8 text-center text-gray-500 dark:text-gray-400">
|
||||||
<div className="flex items-start gap-3">
|
<p className="text-sm">并行网关的所有分支自动执行,无需配置条件。</p>
|
||||||
<span className="text-2xl">✅</span>
|
|
||||||
<div className="flex-1 space-y-2">
|
|
||||||
<p className="font-medium text-green-900 dark:text-green-200 text-base">
|
|
||||||
并行网关分支(自动执行)
|
|
||||||
</p>
|
|
||||||
<p className="text-green-800 dark:text-green-300">
|
|
||||||
并行网关的所有分支会同时执行,无需配置条件表达式、优先级或默认路径。
|
|
||||||
</p>
|
|
||||||
<p className="text-green-800 dark:text-green-300">
|
|
||||||
💡 此分支将自动执行,与其他分支并行运行(Fork 模式)。
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
@ -319,8 +301,8 @@ const EdgeConfigModal: React.FC<EdgeConfigModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* ✅ 错误提示:多个默认分支 */}
|
{/* ✅ 错误提示:多个默认分支(仅非网关节点) */}
|
||||||
{isDefaultBranch && hasOtherDefaultBranch && (
|
{!isFromGateway && isDefaultBranch && hasOtherDefaultBranch && (
|
||||||
<div className="rounded-md bg-red-50 dark:bg-red-950/20 border-2 border-red-400 dark:border-red-600 p-4 text-sm">
|
<div className="rounded-md bg-red-50 dark:bg-red-950/20 border-2 border-red-400 dark:border-red-600 p-4 text-sm">
|
||||||
<div className="flex items-start gap-2">
|
<div className="flex items-start gap-2">
|
||||||
<span className="text-red-600 dark:text-red-400">❌</span>
|
<span className="text-red-600 dark:text-red-400">❌</span>
|
||||||
@ -399,9 +381,9 @@ const EdgeConfigModal: React.FC<EdgeConfigModalProps> = ({
|
|||||||
|
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button type="button" variant="outline" onClick={handleClose}>
|
<Button type="button" variant="outline" onClick={handleClose}>
|
||||||
取消
|
{isFromGateway && gatewayType === 'parallelGateway' ? '关闭' : '取消'}
|
||||||
</Button>
|
</Button>
|
||||||
{/* 并行网关不需要确定按钮,只需要关闭 */}
|
{/* 并行网关不需要确定按钮 */}
|
||||||
{(!isFromGateway || gatewayType !== 'parallelGateway') && (
|
{(!isFromGateway || gatewayType !== 'parallelGateway') && (
|
||||||
<Button type="submit" onClick={form.handleSubmit(handleSubmit)}>
|
<Button type="submit" onClick={form.handleSubmit(handleSubmit)}>
|
||||||
确定
|
确定
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogBody } from '@/components/ui/dialog';
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogBody } from '@/components/ui/dialog';
|
||||||
import { Keyboard } from 'lucide-react';
|
import { Keyboard } from 'lucide-react';
|
||||||
|
|
||||||
interface KeyboardShortcutsPanelProps {
|
interface KeyboardShortcutsPanelProps {
|
||||||
@ -58,6 +58,9 @@ const KeyboardShortcutsPanel: React.FC<KeyboardShortcutsPanelProps> = ({ open, o
|
|||||||
<Keyboard className="h-5 w-5" />
|
<Keyboard className="h-5 w-5" />
|
||||||
键盘快捷键
|
键盘快捷键
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
查看所有可用的键盘快捷键,提升工作效率
|
||||||
|
</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<DialogBody>
|
<DialogBody>
|
||||||
|
|||||||
@ -61,7 +61,7 @@ const MultiSelect: React.FC<MultiSelectProps> = ({ options, value = [], onChange
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Popover open={open} onOpenChange={setOpen}>
|
<Popover open={open} onOpenChange={setOpen} modal={false}>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|||||||
@ -91,10 +91,21 @@ export const useWorkflowSave = () => {
|
|||||||
: [] // ✅ 输出能力定义(直接从节点定义中获取)
|
: [] // ✅ 输出能力定义(直接从节点定义中获取)
|
||||||
})),
|
})),
|
||||||
edges: data.edges.map(edge => {
|
edges: data.edges.map(edge => {
|
||||||
// 检查源节点是否为并行网关
|
// 检查源节点类型
|
||||||
const sourceNode = data.nodes.find(n => n.id === edge.source);
|
const sourceNode = data.nodes.find(n => n.id === edge.source);
|
||||||
const isFromParallelGateway = sourceNode?.data?.nodeType === 'GATEWAY_NODE'
|
const isGateway = sourceNode?.data?.nodeType === 'GATEWAY_NODE';
|
||||||
&& sourceNode?.data?.inputMapping?.gatewayType === 'parallelGateway';
|
const gatewayType = isGateway ? (sourceNode?.data?.inputMapping?.gatewayType || sourceNode?.data?.configs?.gatewayType) : null;
|
||||||
|
|
||||||
|
// 检查是否需要过滤条件配置
|
||||||
|
const isFromParallelGateway = isGateway && gatewayType === 'parallelGateway';
|
||||||
|
|
||||||
|
// 检查是否为汇聚网关(多入1出)
|
||||||
|
const incomingEdges = data.edges.filter(e => e.target === sourceNode?.id);
|
||||||
|
const outgoingEdges = data.edges.filter(e => e.source === sourceNode?.id);
|
||||||
|
const isConvergingGateway = isGateway && incomingEdges.length >= 2 && outgoingEdges.length === 1;
|
||||||
|
|
||||||
|
// 并行网关或汇聚网关不传递条件配置
|
||||||
|
const shouldRemoveCondition = isFromParallelGateway || isConvergingGateway;
|
||||||
|
|
||||||
// ⚠️⚠️⚠️ 关键:兜底转换边的表达式(可能从旧数据加载,从未编辑过)
|
// ⚠️⚠️⚠️ 关键:兜底转换边的表达式(可能从旧数据加载,从未编辑过)
|
||||||
const originalCondition = edge.data?.condition;
|
const originalCondition = edge.data?.condition;
|
||||||
@ -121,8 +132,8 @@ export const useWorkflowSave = () => {
|
|||||||
targetHandle: edge.targetHandle, // 保存目标连接点
|
targetHandle: edge.targetHandle, // 保存目标连接点
|
||||||
config: {
|
config: {
|
||||||
type: "sequence", // 固定为sequence类型
|
type: "sequence", // 固定为sequence类型
|
||||||
// ⚠️ 并行网关的边线不传递条件配置(BPMN 规范不允许)
|
// ⚠️ 并行网关或汇聚网关的边线不传递条件配置(BPMN 规范)
|
||||||
condition: isFromParallelGateway ? undefined : finalCondition
|
condition: shouldRemoveCondition ? undefined : finalCondition
|
||||||
},
|
},
|
||||||
// 优先保存多个拐点;若无则回退到单个控制点;否则为空
|
// 优先保存多个拐点;若无则回退到单个控制点;否则为空
|
||||||
vertices: Array.isArray((edge as any)?.data?.vertices) && (edge as any).data.vertices.length > 0
|
vertices: Array.isArray((edge as any)?.data?.vertices) && (edge as any).data.vertices.length > 0
|
||||||
|
|||||||
@ -435,10 +435,24 @@ const WorkflowDesignInner: React.FC = () => {
|
|||||||
const handleEdgeClick = useCallback((event: React.MouseEvent, edge: FlowEdge) => {
|
const handleEdgeClick = useCallback((event: React.MouseEvent, edge: FlowEdge) => {
|
||||||
if (event.detail === 2) {
|
if (event.detail === 2) {
|
||||||
console.log('双击边,打开配置:', edge);
|
console.log('双击边,打开配置:', edge);
|
||||||
|
|
||||||
|
// 检查源节点是否为并行网关
|
||||||
|
const sourceNode = getNodes().find(n => n.id === edge.source);
|
||||||
|
const gatewayType = (sourceNode?.data?.inputMapping as any)?.gatewayType
|
||||||
|
|| (sourceNode?.data?.configs as any)?.gatewayType;
|
||||||
|
const isParallelGateway = sourceNode?.data?.nodeType === 'GATEWAY_NODE'
|
||||||
|
&& gatewayType === 'parallelGateway';
|
||||||
|
|
||||||
|
// 并行网关的边无需配置,直接提示
|
||||||
|
if (isParallelGateway) {
|
||||||
|
message.info('并行网关的所有分支自动执行,无需配置条件');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setConfigEdge(edge);
|
setConfigEdge(edge);
|
||||||
setEdgeConfigModalVisible(true);
|
setEdgeConfigModalVisible(true);
|
||||||
}
|
}
|
||||||
}, []);
|
}, [getNodes]);
|
||||||
|
|
||||||
// 处理节点配置更新
|
// 处理节点配置更新
|
||||||
const handleNodeConfigUpdate = useCallback((nodeId: string, updatedData: Partial<FlowNodeData>) => {
|
const handleNodeConfigUpdate = useCallback((nodeId: string, updatedData: Partial<FlowNodeData>) => {
|
||||||
|
|||||||
@ -1,5 +1,19 @@
|
|||||||
import type { FlowNode, FlowEdge } from '../types';
|
import type { FlowNode, FlowEdge } from '../types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网关模式(BPMN 2.0 标准)
|
||||||
|
*/
|
||||||
|
export enum GatewayMode {
|
||||||
|
/** 分支模式(Diverging):1入口 → 多出口 */
|
||||||
|
DIVERGING = 'diverging',
|
||||||
|
/** 汇聚模式(Converging):多入口 → 1出口 */
|
||||||
|
CONVERGING = 'converging',
|
||||||
|
/** 混合模式(Mixed):多入口 → 多出口(不推荐) */
|
||||||
|
MIXED = 'mixed',
|
||||||
|
/** 未完成:连线不足或无效 */
|
||||||
|
INCOMPLETE = 'incomplete'
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网关节点验证结果
|
* 网关节点验证结果
|
||||||
*/
|
*/
|
||||||
@ -10,7 +24,36 @@ export interface GatewayValidationResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证网关节点配置
|
* 检测网关模式(基于连线数量)
|
||||||
|
* @param incomingCount 入口连线数量
|
||||||
|
* @param outgoingCount 出口连线数量
|
||||||
|
* @returns 网关模式
|
||||||
|
*/
|
||||||
|
export const detectGatewayMode = (
|
||||||
|
incomingCount: number,
|
||||||
|
outgoingCount: number
|
||||||
|
): GatewayMode => {
|
||||||
|
// 分支模式:1入口 + 多出口(≥2)
|
||||||
|
if (incomingCount === 1 && outgoingCount >= 2) {
|
||||||
|
return GatewayMode.DIVERGING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 汇聚模式:多入口(≥2)+ 1出口
|
||||||
|
if (incomingCount >= 2 && outgoingCount === 1) {
|
||||||
|
return GatewayMode.CONVERGING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 混合模式:多入口 + 多出口(不推荐,视为分支处理)
|
||||||
|
if (incomingCount >= 2 && outgoingCount >= 2) {
|
||||||
|
return GatewayMode.MIXED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他情况:未完成或无效
|
||||||
|
return GatewayMode.INCOMPLETE;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证网关节点配置(支持分支和汇聚模式)
|
||||||
* @param node 网关节点
|
* @param node 网关节点
|
||||||
* @param edges 所有边
|
* @param edges 所有边
|
||||||
* @returns 验证结果
|
* @returns 验证结果
|
||||||
@ -27,26 +70,57 @@ export const validateGatewayNode = (
|
|||||||
return { valid: true, errors: [], warnings: [] };
|
return { valid: true, errors: [], warnings: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
const gatewayType = node.data.configs?.gatewayType;
|
// 获取网关类型(优先从 inputMapping,兼容 configs)
|
||||||
|
const gatewayType = node.data.inputMapping?.gatewayType || node.data.configs?.gatewayType;
|
||||||
const nodeName = node.data.label || '网关节点';
|
const nodeName = node.data.label || '网关节点';
|
||||||
|
|
||||||
// 获取出口连线
|
// 获取入口和出口连线
|
||||||
|
const incomingEdges = edges.filter(e => e.target === node.id);
|
||||||
const outgoingEdges = edges.filter(e => e.source === node.id);
|
const outgoingEdges = edges.filter(e => e.source === node.id);
|
||||||
|
|
||||||
// 1. 检查出口连线数量
|
// 1. 检测网关模式
|
||||||
|
const mode = detectGatewayMode(incomingEdges.length, outgoingEdges.length);
|
||||||
|
|
||||||
|
// 1.1 特殊情况:1入1出透传模式(兼容老数据)
|
||||||
|
if (incomingEdges.length === 1 && outgoingEdges.length === 1) {
|
||||||
|
warnings.push(
|
||||||
|
`${nodeName}:网关只有1入1出,等同于直接连线,建议移除网关节点以简化流程`
|
||||||
|
);
|
||||||
|
// 透传模式不需要条件配置,直接返回通过
|
||||||
|
return { valid: true, errors, warnings };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据模式进行验证
|
||||||
|
if (mode === GatewayMode.DIVERGING || mode === GatewayMode.MIXED) {
|
||||||
|
// ========== 分支模式验证 ==========
|
||||||
|
// 分支网关:1入口 + 多出口(混合模式也按分支处理)
|
||||||
|
|
||||||
|
// 2.1 验证连线数量
|
||||||
|
if (incomingEdges.length !== 1) {
|
||||||
|
errors.push(`${nodeName}(分支网关):需要1条入口连线(当前${incomingEdges.length}条)`);
|
||||||
|
}
|
||||||
|
if (outgoingEdges.length < 2) {
|
||||||
|
errors.push(`${nodeName}(分支网关):至少需要2条出口连线(当前${outgoingEdges.length}条)`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果混合模式,给出警告
|
||||||
|
if (mode === GatewayMode.MIXED) {
|
||||||
|
warnings.push(`${nodeName}:检测到混合模式(多入多出),按分支网关处理,建议拆分为多个网关`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果连线数量不足,不再进行条件验证
|
||||||
if (outgoingEdges.length < 2) {
|
if (outgoingEdges.length < 2) {
|
||||||
errors.push(`${nodeName}:网关节点至少需要2条出口连线(当前${outgoingEdges.length}条)`);
|
|
||||||
return { valid: false, errors, warnings };
|
return { valid: false, errors, warnings };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 排他网关 / 包容网关特殊验证
|
// 2.2 排他网关 / 包容网关:验证条件配置
|
||||||
if (gatewayType === 'exclusiveGateway' || gatewayType === 'inclusiveGateway') {
|
if (gatewayType === 'exclusiveGateway' || gatewayType === 'inclusiveGateway') {
|
||||||
// 检查默认分支
|
// 检查默认分支
|
||||||
const defaultBranches = outgoingEdges.filter(e => e.data?.condition?.type === 'DEFAULT');
|
const defaultBranches = outgoingEdges.filter(e => e.data?.condition?.type === 'DEFAULT');
|
||||||
if (defaultBranches.length === 0) {
|
if (defaultBranches.length === 0) {
|
||||||
errors.push(`${nodeName}:${gatewayType === 'exclusiveGateway' ? '排他' : '包容'}网关必须有一个默认分支`);
|
errors.push(`${nodeName}(分支):${gatewayType === 'exclusiveGateway' ? '排他' : '包容'}网关必须有一个默认分支`);
|
||||||
} else if (defaultBranches.length > 1) {
|
} else if (defaultBranches.length > 1) {
|
||||||
errors.push(`${nodeName}:只能有一个默认分支(当前${defaultBranches.length}个)`);
|
errors.push(`${nodeName}(分支):只能有一个默认分支(当前${defaultBranches.length}个)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查条件分支
|
// 检查条件分支
|
||||||
@ -57,7 +131,7 @@ export const validateGatewayNode = (
|
|||||||
const priorities = expressionBranches.map(e => e.data?.condition?.priority);
|
const priorities = expressionBranches.map(e => e.data?.condition?.priority);
|
||||||
const uniquePriorities = new Set(priorities);
|
const uniquePriorities = new Set(priorities);
|
||||||
if (priorities.length !== uniquePriorities.size) {
|
if (priorities.length !== uniquePriorities.size) {
|
||||||
errors.push(`${nodeName}:排他网关的分支优先级不能重复`);
|
errors.push(`${nodeName}(分支):排他网关的分支优先级不能重复`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否所有条件分支都有优先级
|
// 检查是否所有条件分支都有优先级
|
||||||
@ -66,7 +140,7 @@ export const validateGatewayNode = (
|
|||||||
e.data?.condition?.priority === null
|
e.data?.condition?.priority === null
|
||||||
);
|
);
|
||||||
if (noPriorityBranches.length > 0) {
|
if (noPriorityBranches.length > 0) {
|
||||||
errors.push(`${nodeName}:有${noPriorityBranches.length}条分支未设置优先级`);
|
errors.push(`${nodeName}(分支):有${noPriorityBranches.length}条分支未设置优先级`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,20 +150,48 @@ export const validateGatewayNode = (
|
|||||||
e.data?.condition?.expression.trim() === ''
|
e.data?.condition?.expression.trim() === ''
|
||||||
);
|
);
|
||||||
if (emptyExpressionBranches.length > 0) {
|
if (emptyExpressionBranches.length > 0) {
|
||||||
warnings.push(`${nodeName}:有${emptyExpressionBranches.length}条分支的条件表达式为空`);
|
warnings.push(`${nodeName}(分支):有${emptyExpressionBranches.length}条分支的条件表达式为空`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 并行网关验证
|
// 2.3 并行网关:不需要条件配置
|
||||||
if (gatewayType === 'PARALLEL') {
|
if (gatewayType === 'parallelGateway') {
|
||||||
// 并行网关不需要条件,但可以给出提示
|
|
||||||
const expressionBranches = outgoingEdges.filter(e => e.data?.condition?.type === 'EXPRESSION');
|
const expressionBranches = outgoingEdges.filter(e => e.data?.condition?.type === 'EXPRESSION');
|
||||||
if (expressionBranches.length > 0) {
|
if (expressionBranches.length > 0) {
|
||||||
warnings.push(`${nodeName}:并行网关的所有分支都会执行,条件表达式将被忽略`);
|
warnings.push(`${nodeName}(分支):并行网关的所有分支都会执行,条件表达式将被忽略`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 检查是否所有出口都有连接
|
} else if (mode === GatewayMode.CONVERGING) {
|
||||||
|
// ========== 汇聚模式验证 ==========
|
||||||
|
// 汇聚网关:多入口 + 1出口,不需要条件配置
|
||||||
|
|
||||||
|
// 2.4 验证连线数量
|
||||||
|
if (incomingEdges.length < 2) {
|
||||||
|
errors.push(`${nodeName}(汇聚网关):至少需要2条入口连线(当前${incomingEdges.length}条)`);
|
||||||
|
}
|
||||||
|
if (outgoingEdges.length !== 1) {
|
||||||
|
errors.push(`${nodeName}(汇聚网关):只能有1条出口连线(当前${outgoingEdges.length}条)`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.5 汇聚网关不需要条件配置,如果配置了给出警告
|
||||||
|
const hasConditions = outgoingEdges.some(e =>
|
||||||
|
e.data?.condition?.type === 'EXPRESSION' ||
|
||||||
|
e.data?.condition?.type === 'DEFAULT'
|
||||||
|
);
|
||||||
|
if (hasConditions) {
|
||||||
|
warnings.push(`${nodeName}(汇聚网关):汇聚模式不需要条件配置,条件将被忽略`);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// ========== 未完成状态 ==========
|
||||||
|
errors.push(
|
||||||
|
`${nodeName}:网关连线配置不完整(当前:${incomingEdges.length}入${outgoingEdges.length}出)。` +
|
||||||
|
`需要配置为分支模式(1入≥2出)或汇聚模式(≥2入1出)`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查是否所有出口都有连接
|
||||||
const unconnectedEdges = outgoingEdges.filter(e => !e.target);
|
const unconnectedEdges = outgoingEdges.filter(e => !e.target);
|
||||||
if (unconnectedEdges.length > 0) {
|
if (unconnectedEdges.length > 0) {
|
||||||
errors.push(`${nodeName}:有${unconnectedEdges.length}条出口连线未连接到目标节点`);
|
errors.push(`${nodeName}:有${unconnectedEdges.length}条出口连线未连接到目标节点`);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user