From 1e67e9333ec9a7d997e8dbe1f28af42121fc13fd Mon Sep 17 00:00:00 2001 From: "Yoan.liu" Date: Mon, 19 May 2025 21:59:37 +0800 Subject: [PATCH] condition render --- .../workflow/node/ConditionNode.tsx | 44 +++++++++++++-- .../workflow/node/ConditionNodeConfigForm.tsx | 56 ++----------------- ui/src/domain/workflow.ts | 55 +++++++++++------- 3 files changed, 80 insertions(+), 75 deletions(-) diff --git a/ui/src/components/workflow/node/ConditionNode.tsx b/ui/src/components/workflow/node/ConditionNode.tsx index 63aa1aa1..69dc101d 100644 --- a/ui/src/components/workflow/node/ConditionNode.tsx +++ b/ui/src/components/workflow/node/ConditionNode.tsx @@ -4,8 +4,8 @@ import { Button, Card, Popover } from "antd"; import SharedNode, { type SharedNodeProps } from "./_SharedNode"; import AddNode from "./AddNode"; -import ConditionNodeConfigForm, { ConditionNodeConfigFormInstance } from "./ConditionNodeConfigForm"; -import { WorkflowNodeConfigForCondition } from "@/domain/workflow"; +import ConditionNodeConfigForm, { ConditionItem, ConditionNodeConfigFormFieldValues, ConditionNodeConfigFormInstance } from "./ConditionNodeConfigForm"; +import { Expr, WorkflowNodeConfigForCondition } from "@/domain/workflow"; import { produce } from "immer"; import { useWorkflowStore } from "@/stores/workflow"; import { useZustandShallowSelector } from "@/hooks"; @@ -23,7 +23,42 @@ const ConditionNode = ({ node, disabled, branchId, branchIndex }: ConditionNodeP 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 () => { setFormPending(true); @@ -36,9 +71,10 @@ const ConditionNode = ({ node, disabled, branchId, branchIndex }: ConditionNodeP try { const newValues = getFormValues(); + const expression = formToExpression(newValues); const newNode = produce(node, (draft) => { draft.config = { - ...newValues, + expression, }; draft.validated = true; }); diff --git a/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx b/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx index c83a4b68..52f2c3e2 100644 --- a/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx @@ -11,19 +11,20 @@ import { isConstExpr, isVarExpr, WorkflowNode, + workflowNodeIOOptions, } from "@/domain/workflow"; import { FormInstance } from "antd"; import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; // 表单内部使用的扁平结构 - 修改后只保留必要字段 -interface ConditionItem { +export interface ConditionItem { leftSelector: WorkflowNodeIOValueSelector; operator: ComparisonOperator; rightValue: string; } -type ConditionNodeConfigFormFieldValues = { +export type ConditionNodeConfigFormFieldValues = { conditions: ConditionItem[]; 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 => { if (!expr) return initFormModel(); @@ -159,12 +125,8 @@ const ConditionNodeConfigForm = forwardRef { + const handleFormChange = (_: undefined, values: ConditionNodeConfigFormFieldValues) => { setFormModel(values); - - // 转换为表达式结构并通知父组件 - const expression = formToExpression(values); - onValuesChange?.({ expression }); }; return ( @@ -186,15 +148,7 @@ const ConditionNodeConfigForm = forwardRef { - return { - label: item.name, - options: item.outputs?.map((output) => { - return { - label: `${item.name} - ${output.label}`, - value: `${item.id}#${output.name}`, - }; - }), - }; + return workflowNodeIOOptions(item); })} > diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index 6cccf32e..d6354e14 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -187,27 +187,42 @@ export type WorkflowNodeIOValueSelector = { name: string; }; -export const workflowNodeIOOptions = (node: WorkflowNode, io: WorkflowNodeIO) => { - switch (io.type) { - case "certificate": - return [ - { - label: "是否有效", - value: "valid", - }, - { - label: "剩余有效天数", - value: "valid", - }, - ]; - default: - return [ - { - label: `${node.name} - ${io.label}`, - value: `${node.id}#${io.name}`, - }, - ]; +type WorkflowNodeIOOptions = { + label: string; + value: string; +}; + +export const workflowNodeIOOptions = (node: WorkflowNode) => { + const rs = { + label: node.name, + options: Array(), + }; + + if (node.outputs) { + for (const output of node.outputs) { + switch (output.type) { + case "certificate": + rs.options.push({ + label: `${node.name} - ${output.label} - 是否有效`, + value: `${node.id}#${output.name}.validated`, + }); + + rs.options.push({ + label: `${node.name} - ${output.label} - 剩余天数`, + value: `${node.id}#${output.name}.daysLeft`, + }); + break; + default: + rs.options.push({ + label: `${node.name} - ${output.label}`, + value: `${node.id}#${output.name}`, + }); + break; + } + } } + + return rs; }; // #endregion