import { forwardRef, memo, useEffect, useImperativeHandle, useState } from "react"; import { Button, Card, Form, Input, Select, Radio } from "antd"; import { PlusOutlined, DeleteOutlined } from "@ant-design/icons"; import i18n from "@/i18n"; import { WorkflowNodeConfigForCondition, Expr, WorkflowNodeIOValueSelector, ComparisonOperator, LogicalOperator, isConstExpr, isVarExpr, WorkflowNode, workflowNodeIOOptions, WorkflowNodeIoValueType, } from "@/domain/workflow"; import { FormInstance } from "antd"; import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; import { useTranslation } from "react-i18next"; // 表单内部使用的扁平结构 - 修改后只保留必要字段 export interface ConditionItem { leftSelector: string; operator: ComparisonOperator; rightValue: string; } export type ConditionNodeConfigFormFieldValues = { conditions: ConditionItem[]; logicalOperator: LogicalOperator; }; export type ConditionNodeConfigFormProps = { className?: string; style?: React.CSSProperties; disabled?: boolean; initialValues?: Partial; onValuesChange?: (values: WorkflowNodeConfigForCondition) => void; availableSelectors?: WorkflowNodeIOValueSelector[]; nodeId: string; }; export type ConditionNodeConfigFormInstance = { getFieldsValue: () => ReturnType["getFieldsValue"]>; resetFields: FormInstance["resetFields"]; validateFields: FormInstance["validateFields"]; }; // 初始表单值 const initFormModel = (): ConditionNodeConfigFormFieldValues => { return { conditions: [ { leftSelector: "", operator: "==", rightValue: "", }, ], logicalOperator: "and", }; }; // 递归提取表达式中的条件项 const expressionToForm = (expr?: Expr): ConditionNodeConfigFormFieldValues => { if (!expr) return initFormModel(); const conditions: ConditionItem[] = []; let logicalOp: LogicalOperator = "and"; const extractComparisons = (expr: Expr): void => { if (expr.type === "compare") { // 确保左侧是变量,右侧是常量 if (isVarExpr(expr.left) && isConstExpr(expr.right)) { conditions.push({ leftSelector: `${expr.left.selector.id}#${expr.left.selector.name}#${expr.left.selector.type}`, operator: expr.op, rightValue: String(expr.right.value), }); } } else if (expr.type === "logical") { logicalOp = expr.op; extractComparisons(expr.left); extractComparisons(expr.right); } }; extractComparisons(expr); return { conditions: conditions.length > 0 ? conditions : initFormModel().conditions, logicalOperator: logicalOp, }; }; // 根据变量类型获取适当的操作符选项 const getOperatorsByType = (type: string): { value: ComparisonOperator; label: string }[] => { switch (type) { case "number": case "string": return [ { value: "==", label: i18n.t("workflow_node.condition.form.comparison.equal") }, { value: "!=", label: i18n.t("workflow_node.condition.form.comparison.not_equal") }, { value: ">", label: i18n.t("workflow_node.condition.form.comparison.greater_than") }, { value: ">=", label: i18n.t("workflow_node.condition.form.comparison.greater_than_or_equal") }, { value: "<", label: i18n.t("workflow_node.condition.form.comparison.less_than") }, { value: "<=", label: i18n.t("workflow_node.condition.form.comparison.less_than_or_equal") }, ]; case "boolean": return [{ value: "is", label: i18n.t("workflow_node.condition.form.comparison.is") }]; default: return []; } }; // 从选择器字符串中提取变量类型 const getVariableTypeFromSelector = (selector: string): string => { if (!selector) return "string"; // 假设选择器格式为 "id#name#type" const parts = selector.split("#"); if (parts.length >= 3) { return parts[2].toLowerCase() || "string"; } return "string"; }; const ConditionNodeConfigForm = forwardRef( ({ className, style, disabled, initialValues, onValuesChange, nodeId }, ref) => { const { t } = useTranslation(); const prefix = "workflow_node.condition.form"; const { getWorkflowOuptutBeforeId } = useWorkflowStore(useZustandShallowSelector(["updateNode", "getWorkflowOuptutBeforeId"])); const [form] = Form.useForm(); const [formModel, setFormModel] = useState(initFormModel()); const [previousNodes, setPreviousNodes] = useState([]); useEffect(() => { const previousNodes = getWorkflowOuptutBeforeId(nodeId); setPreviousNodes(previousNodes); }, [nodeId]); // 初始化表单值 useEffect(() => { if (initialValues?.expression) { const formValues = expressionToForm(initialValues.expression); form.setFieldsValue(formValues); setFormModel(formValues); } }, [form, initialValues]); // 公开表单方法 useImperativeHandle( ref, () => ({ getFieldsValue: form.getFieldsValue, resetFields: form.resetFields, validateFields: form.validateFields, }), [form] ); // 表单值变更处理 const handleFormChange = (_: undefined, values: ConditionNodeConfigFormFieldValues) => { setFormModel(values); if (onValuesChange) { // 将表单值转换为表达式 const expression = formToExpression(values); onValuesChange({ expression }); } }; return (
{(fields, { add, remove }) => ( <> {fields.map(({ key, name, ...restField }) => ( 1 ? )} {formModel.conditions && formModel.conditions.length > 1 && ( {t(`${prefix}.logical_operator.and`)} {t(`${prefix}.logical_operator.or`)} )}
); } ); // 表单值转换为表达式结构 (需要添加) const formToExpression = (values: ConditionNodeConfigFormFieldValues): Expr => { const createComparisonExpr = (condition: ConditionItem): Expr => { const [id, name, typeStr] = condition.leftSelector.split("#"); const type = typeStr as WorkflowNodeIoValueType; const left: Expr = { type: "var", selector: { id, name, type }, }; let rightValue: any = condition.rightValue; if (type === "number") { rightValue = Number(condition.rightValue); } else if (type === "boolean") { rightValue = condition.rightValue === "true"; } const right: Expr = { type: "const", value: rightValue, valueType: type, }; 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; }; export default memo(ConditionNodeConfigForm);