condition render

This commit is contained in:
Yoan.liu 2025-05-19 21:59:37 +08:00
parent 6f054ee594
commit 1e67e9333e
3 changed files with 80 additions and 75 deletions

View File

@ -4,8 +4,8 @@ import { Button, Card, Popover } from "antd";
import SharedNode, { type SharedNodeProps } from "./_SharedNode"; import SharedNode, { type SharedNodeProps } from "./_SharedNode";
import AddNode from "./AddNode"; import AddNode from "./AddNode";
import ConditionNodeConfigForm, { ConditionNodeConfigFormInstance } from "./ConditionNodeConfigForm"; import ConditionNodeConfigForm, { ConditionItem, ConditionNodeConfigFormFieldValues, ConditionNodeConfigFormInstance } from "./ConditionNodeConfigForm";
import { WorkflowNodeConfigForCondition } from "@/domain/workflow"; import { Expr, WorkflowNodeConfigForCondition } from "@/domain/workflow";
import { produce } from "immer"; import { produce } from "immer";
import { useWorkflowStore } from "@/stores/workflow"; import { useWorkflowStore } from "@/stores/workflow";
import { useZustandShallowSelector } from "@/hooks"; import { useZustandShallowSelector } from "@/hooks";
@ -23,7 +23,42 @@ const ConditionNode = ({ node, disabled, branchId, branchIndex }: ConditionNodeP
const [drawerOpen, setDrawerOpen] = useState(false); const [drawerOpen, setDrawerOpen] = useState(false);
const getFormValues = () => formRef.current!.getFieldsValue() as WorkflowNodeConfigForCondition; const getFormValues = () => formRef.current!.getFieldsValue() as ConditionNodeConfigFormFieldValues;
// 将表单值转换为表达式结构
const formToExpression = (values: ConditionNodeConfigFormFieldValues): Expr => {
// 创建单个条件的表达式
const createComparisonExpr = (condition: ConditionItem): Expr => {
const left: Expr = { type: "var", selector: condition.leftSelector };
const right: Expr = { type: "const", value: condition.rightValue || "" };
return {
type: "compare",
op: condition.operator,
left,
right,
};
};
// 如果只有一个条件,直接返回比较表达式
if (values.conditions.length === 1) {
return createComparisonExpr(values.conditions[0]);
}
// 多个条件,通过逻辑运算符连接
let expr: Expr = createComparisonExpr(values.conditions[0]);
for (let i = 1; i < values.conditions.length; i++) {
expr = {
type: "logical",
op: values.logicalOperator,
left: expr,
right: createComparisonExpr(values.conditions[i]),
};
}
return expr;
};
const handleDrawerConfirm = async () => { const handleDrawerConfirm = async () => {
setFormPending(true); setFormPending(true);
@ -36,9 +71,10 @@ const ConditionNode = ({ node, disabled, branchId, branchIndex }: ConditionNodeP
try { try {
const newValues = getFormValues(); const newValues = getFormValues();
const expression = formToExpression(newValues);
const newNode = produce(node, (draft) => { const newNode = produce(node, (draft) => {
draft.config = { draft.config = {
...newValues, expression,
}; };
draft.validated = true; draft.validated = true;
}); });

View File

@ -11,19 +11,20 @@ import {
isConstExpr, isConstExpr,
isVarExpr, isVarExpr,
WorkflowNode, WorkflowNode,
workflowNodeIOOptions,
} from "@/domain/workflow"; } from "@/domain/workflow";
import { FormInstance } from "antd"; import { FormInstance } from "antd";
import { useZustandShallowSelector } from "@/hooks"; import { useZustandShallowSelector } from "@/hooks";
import { useWorkflowStore } from "@/stores/workflow"; import { useWorkflowStore } from "@/stores/workflow";
// 表单内部使用的扁平结构 - 修改后只保留必要字段 // 表单内部使用的扁平结构 - 修改后只保留必要字段
interface ConditionItem { export interface ConditionItem {
leftSelector: WorkflowNodeIOValueSelector; leftSelector: WorkflowNodeIOValueSelector;
operator: ComparisonOperator; operator: ComparisonOperator;
rightValue: string; rightValue: string;
} }
type ConditionNodeConfigFormFieldValues = { export type ConditionNodeConfigFormFieldValues = {
conditions: ConditionItem[]; conditions: ConditionItem[];
logicalOperator: LogicalOperator; logicalOperator: LogicalOperator;
}; };
@ -58,41 +59,6 @@ const initFormModel = (): ConditionNodeConfigFormFieldValues => {
}; };
}; };
// 将表单值转换为表达式结构
const formToExpression = (values: ConditionNodeConfigFormFieldValues): Expr => {
// 创建单个条件的表达式
const createComparisonExpr = (condition: ConditionItem): Expr => {
const left: Expr = { type: "var", selector: condition.leftSelector };
const right: Expr = { type: "const", value: condition.rightValue || "" };
return {
type: "compare",
op: condition.operator,
left,
right,
};
};
// 如果只有一个条件,直接返回比较表达式
if (values.conditions.length === 1) {
return createComparisonExpr(values.conditions[0]);
}
// 多个条件,通过逻辑运算符连接
let expr: Expr = createComparisonExpr(values.conditions[0]);
for (let i = 1; i < values.conditions.length; i++) {
expr = {
type: "logical",
op: values.logicalOperator,
left: expr,
right: createComparisonExpr(values.conditions[i]),
};
}
return expr;
};
// 递归提取表达式中的条件项 // 递归提取表达式中的条件项
const expressionToForm = (expr?: Expr): ConditionNodeConfigFormFieldValues => { const expressionToForm = (expr?: Expr): ConditionNodeConfigFormFieldValues => {
if (!expr) return initFormModel(); if (!expr) return initFormModel();
@ -159,12 +125,8 @@ const ConditionNodeConfigForm = forwardRef<ConditionNodeConfigFormInstance, Cond
); );
// 表单值变更处理 // 表单值变更处理
const handleFormChange = (changedValues: any, values: ConditionNodeConfigFormFieldValues) => { const handleFormChange = (_: undefined, values: ConditionNodeConfigFormFieldValues) => {
setFormModel(values); setFormModel(values);
// 转换为表达式结构并通知父组件
const expression = formToExpression(values);
onValuesChange?.({ expression });
}; };
return ( return (
@ -186,15 +148,7 @@ const ConditionNodeConfigForm = forwardRef<ConditionNodeConfigFormInstance, Cond
<Select <Select
placeholder="选择变量" placeholder="选择变量"
options={previousNodes.map((item) => { options={previousNodes.map((item) => {
return { return workflowNodeIOOptions(item);
label: item.name,
options: item.outputs?.map((output) => {
return {
label: `${item.name} - ${output.label}`,
value: `${item.id}#${output.name}`,
};
}),
};
})} })}
></Select> ></Select>
</Form.Item> </Form.Item>

View File

@ -187,27 +187,42 @@ export type WorkflowNodeIOValueSelector = {
name: string; name: string;
}; };
export const workflowNodeIOOptions = (node: WorkflowNode, io: WorkflowNodeIO) => { type WorkflowNodeIOOptions = {
switch (io.type) { label: string;
value: string;
};
export const workflowNodeIOOptions = (node: WorkflowNode) => {
const rs = {
label: node.name,
options: Array<WorkflowNodeIOOptions>(),
};
if (node.outputs) {
for (const output of node.outputs) {
switch (output.type) {
case "certificate": case "certificate":
return [ rs.options.push({
{ label: `${node.name} - ${output.label} - 是否有效`,
label: "是否有效", value: `${node.id}#${output.name}.validated`,
value: "valid", });
},
{ rs.options.push({
label: "剩余有效天数", label: `${node.name} - ${output.label} - 剩余天数`,
value: "valid", value: `${node.id}#${output.name}.daysLeft`,
}, });
]; break;
default: default:
return [ rs.options.push({
{ label: `${node.name} - ${output.label}`,
label: `${node.name} - ${io.label}`, value: `${node.id}#${output.name}`,
value: `${node.id}#${io.name}`, });
}, break;
];
} }
}
}
return rs;
}; };
// #endregion // #endregion