'use client' import { useState, useEffect, useMemo } from 'react' import { cn } from '@/lib/ui-styles' import { FieldConditions, SingleCondition, ConditionOperator, LogicOperator, parseFieldConditions, serializeFieldConditions, getAllOperators, DEFAULT_FIELD_CONDITIONS, } from '@/lib/field-conditions' interface FieldOption { key: string label: string } interface FieldConditionsConfigProps { currentFieldKey: string conditions: string availableFields: FieldOption[] onChange: (conditions: string) => void className?: string } export default function FieldConditionsConfig({ currentFieldKey, conditions, availableFields, onChange, className, }: FieldConditionsConfigProps) { // 解析当前条件配置 const currentConditions = useMemo(() => { return parseFieldConditions(conditions) || { ...DEFAULT_FIELD_CONDITIONS } }, [conditions]) // 本地状态 const [config, setConfig] = useState(currentConditions) const [isExpanded, setIsExpanded] = useState(false) // 同步外部变化 useEffect(() => { setConfig(currentConditions) }, [currentConditions]) // 过滤掉当前字段,避免自引用 const selectableFields = useMemo(() => { return availableFields.filter(f => f.key !== currentFieldKey) }, [availableFields, currentFieldKey]) // 所有运算符 const operators = useMemo(() => getAllOperators(), []) // 更新配置并通知父组件 const updateConfig = (newConfig: FieldConditions) => { setConfig(newConfig) const serialized = serializeFieldConditions(newConfig) onChange(serialized) } // 添加条件 const addCondition = () => { const firstField = selectableFields[0] if (!firstField) return const newCondition: SingleCondition = { fieldKey: firstField.key, operator: 'notEmpty', } updateConfig({ ...config, conditions: [...config.conditions, newCondition], }) } // 更新单个条件 const updateCondition = (index: number, patch: Partial) => { const newConditions = [...config.conditions] newConditions[index] = { ...newConditions[index], ...patch } updateConfig({ ...config, conditions: newConditions }) } // 删除条件 const removeCondition = (index: number) => { const newConditions = config.conditions.filter((_, i) => i !== index) updateConfig({ ...config, conditions: newConditions }) } // 切换逻辑运算符 const toggleLogic = () => { updateConfig({ ...config, logic: config.logic === 'AND' ? 'OR' : 'AND', }) } // 检查是否有条件配置 const hasConditions = config.conditions.length > 0 const inputClass = 'w-full px-3 py-2 text-sm border border-slate-300 dark:border-slate-600 dark:bg-slate-900 dark:text-white rounded-lg focus:ring-2 focus:ring-slate-200 dark:focus:ring-slate-700 focus:border-slate-500 dark:focus:border-slate-500 outline-none transition-colors duration-150' // 如果没有可选字段,不显示此功能 if (selectableFields.length === 0) { return null } return (
{/* 折叠标题 */} {/* 展开的配置面板 */} {isExpanded && (

设置此字段的显示条件,只有满足条件时才会显示此字段

{/* 条件列表 */} {config.conditions.length > 0 && (
{config.conditions.map((condition, index) => { const operator = operators.find(o => o.value === condition.operator) const needsValue = operator?.needsValue ?? true return (
{/* 逻辑运算符(第二个条件开始显示) */} {index > 0 && ( )} {index === 0 &&
} {/* 条件配置 */}
{/* 字段选择 */} {/* 运算符选择 */} {/* 值输入(如果需要) */} {needsValue ? ( updateCondition(index, { value: e.target.value })} placeholder="比较值" className={inputClass} /> ) : (
无需输入值
)}
{/* 删除按钮 */}
) })}
)} {/* 添加条件按钮 */} {/* 清除所有条件 */} {hasConditions && (
)} {/* 说明 */}

满足条件时显示此字段;多个条件可切换“全部”或“任一”。

)}
) }