multi language support

This commit is contained in:
Yoan.liu 2025-05-20 14:55:48 +08:00
parent 6353f0139b
commit b546cf3ad0
4 changed files with 84 additions and 24 deletions

View File

@ -5,7 +5,7 @@ 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, { ConditionItem, ConditionNodeConfigFormFieldValues, ConditionNodeConfigFormInstance } from "./ConditionNodeConfigForm"; import ConditionNodeConfigForm, { ConditionItem, ConditionNodeConfigFormFieldValues, ConditionNodeConfigFormInstance } from "./ConditionNodeConfigForm";
import { Expr, WorkflowNodeConfigForCondition, WorkflowNodeIoValueType } from "@/domain/workflow"; import { Expr, WorkflowNodeIoValueType } 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";

View File

@ -1,6 +1,7 @@
import { forwardRef, memo, useEffect, useImperativeHandle, useState } from "react"; import { forwardRef, memo, useEffect, useImperativeHandle, useState } from "react";
import { Button, Card, Form, Input, Select, Space, Radio, DatePicker } from "antd"; import { Button, Card, Form, Input, Select, Radio } from "antd";
import { PlusOutlined, DeleteOutlined } from "@ant-design/icons"; import { PlusOutlined, DeleteOutlined } from "@ant-design/icons";
import i18n from "@/i18n";
import { import {
WorkflowNodeConfigForCondition, WorkflowNodeConfigForCondition,
@ -17,6 +18,7 @@ import {
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";
import { useTranslation } from "react-i18next";
// 表单内部使用的扁平结构 - 修改后只保留必要字段 // 表单内部使用的扁平结构 - 修改后只保留必要字段
export interface ConditionItem { export interface ConditionItem {
@ -98,15 +100,15 @@ const getOperatorsByType = (type: string): { value: ComparisonOperator; label: s
case "number": case "number":
case "string": case "string":
return [ return [
{ value: "==", label: "等于 (==)" }, { value: "==", label: i18n.t("workflow_node.condition.form.comparison.equal") },
{ value: "!=", label: "不等于 (!=)" }, { value: "!=", label: i18n.t("workflow_node.condition.form.comparison.not_equal") },
{ value: ">", label: "大于 (>)" }, { value: ">", label: i18n.t("workflow_node.condition.form.comparison.greater_than") },
{ value: ">=", label: "大于等于 (>=)" }, { value: ">=", label: i18n.t("workflow_node.condition.form.comparison.greater_than_or_equal") },
{ value: "<", label: "小于 (<)" }, { value: "<", label: i18n.t("workflow_node.condition.form.comparison.less_than") },
{ value: "<=", label: "小于等于 (<=)" }, { value: "<=", label: i18n.t("workflow_node.condition.form.comparison.less_than_or_equal") },
]; ];
case "boolean": case "boolean":
return [{ value: "is", label: "为" }]; return [{ value: "is", label: i18n.t("workflow_node.condition.form.comparison.is") }];
default: default:
return []; return [];
} }
@ -126,6 +128,9 @@ const getVariableTypeFromSelector = (selector: string): string => {
const ConditionNodeConfigForm = forwardRef<ConditionNodeConfigFormInstance, ConditionNodeConfigFormProps>( const ConditionNodeConfigForm = forwardRef<ConditionNodeConfigFormInstance, ConditionNodeConfigFormProps>(
({ className, style, disabled, initialValues, onValuesChange, nodeId }, ref) => { ({ className, style, disabled, initialValues, onValuesChange, nodeId }, ref) => {
const { t } = useTranslation();
const prefix = "workflow_node.condition.form";
const { getWorkflowOuptutBeforeId } = useWorkflowStore(useZustandShallowSelector(["updateNode", "getWorkflowOuptutBeforeId"])); const { getWorkflowOuptutBeforeId } = useWorkflowStore(useZustandShallowSelector(["updateNode", "getWorkflowOuptutBeforeId"]));
const [form] = Form.useForm<ConditionNodeConfigFormFieldValues>(); const [form] = Form.useForm<ConditionNodeConfigFormFieldValues>();
@ -182,9 +187,14 @@ const ConditionNodeConfigForm = forwardRef<ConditionNodeConfigFormInstance, Cond
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
{/* 左侧变量选择器 */} {/* 左侧变量选择器 */}
<Form.Item {...restField} name={[name, "leftSelector"]} className="mb-0 flex-1" rules={[{ required: true, message: "请选择变量" }]}> <Form.Item
{...restField}
name={[name, "leftSelector"]}
className="mb-0 flex-1"
rules={[{ required: true, message: t(`${prefix}.variable.errmsg`) }]}
>
<Select <Select
placeholder="选择变量" placeholder={t(`${prefix}.variable.placeholder`)}
options={previousNodes.map((item) => { options={previousNodes.map((item) => {
return workflowNodeIOOptions(item); return workflowNodeIOOptions(item);
})} })}
@ -204,7 +214,12 @@ const ConditionNodeConfigForm = forwardRef<ConditionNodeConfigFormInstance, Cond
const operators = getOperatorsByType(varType); const operators = getOperatorsByType(varType);
return ( return (
<Form.Item {...restField} name={[name, "operator"]} className="mb-0 w-32" rules={[{ required: true, message: "请选择" }]}> <Form.Item
{...restField}
name={[name, "operator"]}
className="mb-0 w-32"
rules={[{ required: true, message: t(`${prefix}.operator.errmsg`) }]}
>
<Select options={operators} /> <Select options={operators} />
</Form.Item> </Form.Item>
); );
@ -223,18 +238,21 @@ const ConditionNodeConfigForm = forwardRef<ConditionNodeConfigFormInstance, Cond
const varType = getVariableTypeFromSelector(leftSelector); const varType = getVariableTypeFromSelector(leftSelector);
return ( return (
<Form.Item {...restField} name={[name, "rightValue"]} className="mb-0 flex-1" rules={[{ required: true, message: "请输入值" }]}> <Form.Item
{...restField}
name={[name, "rightValue"]}
className="mb-0 flex-1"
rules={[{ required: true, message: t(`${prefix}.value.errmsg`) }]}
>
{varType === "boolean" ? ( {varType === "boolean" ? (
<Select placeholder="选择值"> <Select placeholder={t(`${prefix}.value.boolean.placeholder`)}>
<Select.Option value="true"></Select.Option> <Select.Option value="true">{t(`${prefix}.value.boolean.true`)}</Select.Option>
<Select.Option value="false"></Select.Option> <Select.Option value="false">{t(`${prefix}.value.boolean.false`)}</Select.Option>
</Select> </Select>
) : varType === "number" ? ( ) : varType === "number" ? (
<Input type="number" placeholder="输入数值" /> <Input type="number" placeholder={t(`${prefix}.value.number.placeholder`)} />
) : varType === "date" ? (
<DatePicker style={{ width: "100%" }} placeholder="选择日期" format="YYYY-MM-DD" />
) : ( ) : (
<Input placeholder="输入值" /> <Input placeholder={t(`${prefix}.value.string.placeholder`)} />
)} )}
</Form.Item> </Form.Item>
); );
@ -258,7 +276,7 @@ const ConditionNodeConfigForm = forwardRef<ConditionNodeConfigFormInstance, Cond
block block
icon={<PlusOutlined />} icon={<PlusOutlined />}
> >
{t(`${prefix}.add_condition.button`)}
</Button> </Button>
</Form.Item> </Form.Item>
</> </>
@ -266,10 +284,10 @@ const ConditionNodeConfigForm = forwardRef<ConditionNodeConfigFormInstance, Cond
</Form.List> </Form.List>
{formModel.conditions && formModel.conditions.length > 1 && ( {formModel.conditions && formModel.conditions.length > 1 && (
<Form.Item name="logicalOperator" label="条件逻辑"> <Form.Item name="logicalOperator" label={t(`${prefix}.logical_operator.label`)}>
<Radio.Group buttonStyle="solid"> <Radio.Group buttonStyle="solid">
<Radio.Button value="and"> (AND)</Radio.Button> <Radio.Button value="and">{t(`${prefix}.logical_operator.and`)}</Radio.Button>
<Radio.Button value="or"> (OR)</Radio.Button> <Radio.Button value="or">{t(`${prefix}.logical_operator.or`)}</Radio.Button>
</Radio.Group> </Radio.Group>
</Form.Item> </Form.Item>
)} )}

View File

@ -790,6 +790,26 @@
"workflow_node.branch.label": "Parallel branch", "workflow_node.branch.label": "Parallel branch",
"workflow_node.condition.label": "Branch", "workflow_node.condition.label": "Branch",
"workflow_node.condition.form.variable.placeholder": "Please select variable",
"workflow_node.condition.form.variable.errmsg": "Please select variable",
"workflow_node.condition.form.operator.errmsg": "Please select operator",
"workflow_node.condition.form.value.errmsg": "Please enter value",
"workflow_node.condition.form.value.string.placeholder": "Please enter value",
"workflow_node.condition.form.value.number.placeholder": "Please enter value",
"workflow_node.condition.form.value.boolean.placeholder": "Please select value",
"workflow_node.condition.form.value.boolean.true": "True",
"workflow_node.condition.form.value.boolean.false": "False",
"workflow_node.condition.form.add_condition.button": "Add condition",
"workflow_node.condition.form.logical_operator.label": "Logical operator",
"workflow_node.condition.form.logical_operator.and": "Meet all conditions (AND)",
"workflow_node.condition.form.logical_operator.or": "Meet any condition (OR)",
"workflow_node.condition.form.comparison.equal": "Equal",
"workflow_node.condition.form.comparison.not_equal": "Not equal",
"workflow_node.condition.form.comparison.greater_than": "Greater than",
"workflow_node.condition.form.comparison.greater_than_or_equal": "Greater than or equal",
"workflow_node.condition.form.comparison.less_than": "Less than",
"workflow_node.condition.form.comparison.less_than_or_equal": "Less than or equal",
"workflow_node.condition.form.comparison.is": "Is",
"workflow_node.execute_result_branch.label": "Execution result branch", "workflow_node.execute_result_branch.label": "Execution result branch",
@ -797,3 +817,4 @@
"workflow_node.execute_failure.label": "If the previous node failed ..." "workflow_node.execute_failure.label": "If the previous node failed ..."
} }

View File

@ -789,6 +789,26 @@
"workflow_node.branch.label": "并行分支", "workflow_node.branch.label": "并行分支",
"workflow_node.condition.label": "分支", "workflow_node.condition.label": "分支",
"workflow_node.condition.form.variable.placeholder": "选择变量",
"workflow_node.condition.form.variable.errmsg": "请选择变量",
"workflow_node.condition.form.operator.errmsg": "请选择操作符",
"workflow_node.condition.form.value.errmsg": "请输入值",
"workflow_node.condition.form.value.string.placeholder": "输入值",
"workflow_node.condition.form.value.number.placeholder": "输入数值",
"workflow_node.condition.form.value.boolean.placeholder": "选择值",
"workflow_node.condition.form.value.boolean.true": "是",
"workflow_node.condition.form.value.boolean.false": "否",
"workflow_node.condition.form.add_condition.button": "添加条件",
"workflow_node.condition.form.logical_operator.label": "条件逻辑",
"workflow_node.condition.form.logical_operator.and": "满足所有条件 (AND)",
"workflow_node.condition.form.logical_operator.or": "满足任一条件 (OR)",
"workflow_node.condition.form.comparison.equal": "等于",
"workflow_node.condition.form.comparison.not_equal": "不等于",
"workflow_node.condition.form.comparison.greater_than": "大于",
"workflow_node.condition.form.comparison.greater_than_or_equal": "大于等于",
"workflow_node.condition.form.comparison.less_than": "小于",
"workflow_node.condition.form.comparison.less_than_or_equal": "小于等于",
"workflow_node.condition.form.comparison.is": "为",
"workflow_node.execute_result_branch.label": "执行结果分支", "workflow_node.execute_result_branch.label": "执行结果分支",
@ -796,3 +816,4 @@
"workflow_node.execute_failure.label": "若前序节点执行失败…" "workflow_node.execute_failure.label": "若前序节点执行失败…"
} }