'use client' import { useState, useEffect, useMemo } from 'react' import { cn } from '@/lib/ui-styles' import { ValidationRule, parseValidationRules, serializeValidationRules, validateValidationRules, getSupportedValidations, DEFAULT_VALIDATION_RULES, } from '@/lib/field-validation' interface FieldValidationConfigProps { fieldType: string validations: string onChange: (validations: string) => void className?: string } export default function FieldValidationConfig({ fieldType, validations, onChange, className, }: FieldValidationConfigProps) { // 解析当前验证规则 const currentRules = useMemo(() => { return parseValidationRules(validations) || { ...DEFAULT_VALIDATION_RULES } }, [validations]) // 本地状态用于编辑 const [rules, setRules] = useState(currentRules) const [error, setError] = useState(null) const [isExpanded, setIsExpanded] = useState(false) // 当外部 validations 变化时同步 useEffect(() => { setRules(currentRules) }, [currentRules]) // 获取当前字段类型支持的验证规则 const supportedValidations = useMemo(() => { return getSupportedValidations(fieldType) }, [fieldType]) // 更新规则并通知父组件 const updateRules = (patch: Partial) => { const newRules = { ...rules, ...patch } setRules(newRules) // 验证规则是否有效 const validation = validateValidationRules(newRules) if (!validation.valid) { setError(validation.error || '验证规则配置无效') return } setError(null) // 序列化并通知父组件 const serialized = serializeValidationRules(newRules) onChange(serialized) } // 检查是否有任何验证规则配置 const hasAnyRules = useMemo(() => { return ( rules.required || (typeof rules.minLength === 'number' && rules.minLength > 0) || (typeof rules.maxLength === 'number' && rules.maxLength > 0) || typeof rules.min === 'number' || typeof rules.max === 'number' || !!rules.pattern ) }, [rules]) 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' const labelClass = 'block text-xs font-medium text-slate-700 dark:text-slate-300 mb-1' const hintClass = 'text-[10px] text-slate-500 dark:text-slate-400 mt-1' return (
{/* 折叠标题 */} {/* 展开的配置面板 */} {isExpanded && (
{/* 错误提示 */} {error && (
{error}
)} {/* 必填验证 - 所有类型都支持 */} {supportedValidations.includes('required') && (
{rules.required && (
updateRules({ requiredMessage: e.target.value || undefined })} placeholder="例如:请填写商品型号" className={inputClass} />
)}
)} {/* 长度验证 - text/textarea */} {supportedValidations.includes('minLength') && (
updateRules({ minLength: e.target.value ? parseInt(e.target.value, 10) : undefined, }) } placeholder="不限制" className={inputClass} />
updateRules({ maxLength: e.target.value ? parseInt(e.target.value, 10) : undefined, }) } placeholder="不限制" className={inputClass} />
)} {/* 自定义长度错误提示 */} {supportedValidations.includes('minLength') && (typeof rules.minLength === 'number' || typeof rules.maxLength === 'number') && (
{typeof rules.minLength === 'number' && (
updateRules({ minLengthMessage: e.target.value || undefined }) } placeholder={`至少${rules.minLength}个字符`} className={inputClass} />
)} {typeof rules.maxLength === 'number' && (
updateRules({ maxLengthMessage: e.target.value || undefined }) } placeholder={`最多${rules.maxLength}个字符`} className={inputClass} />
)}
)} {/* 数值范围验证 - number */} {supportedValidations.includes('min') && (
updateRules({ min: e.target.value ? parseFloat(e.target.value) : undefined, }) } placeholder="不限制" className={inputClass} />
updateRules({ max: e.target.value ? parseFloat(e.target.value) : undefined, }) } placeholder="不限制" className={inputClass} />
)} {/* 自定义数值范围错误提示 */} {supportedValidations.includes('min') && (typeof rules.min === 'number' || typeof rules.max === 'number') && (
{typeof rules.min === 'number' && (
updateRules({ minMessage: e.target.value || undefined })} placeholder={`不能小于${rules.min}`} className={inputClass} />
)} {typeof rules.max === 'number' && (
updateRules({ maxMessage: e.target.value || undefined })} placeholder={`不能大于${rules.max}`} className={inputClass} />
)}
)} {/* 正则表达式验证 - text/textarea */} {supportedValidations.includes('pattern') && (
updateRules({ pattern: e.target.value || undefined })} placeholder="例如:^[A-Z]{2}\d{4}$" className={inputClass} />

输入正则表达式来验证输入格式,例如:^[A-Z]{2}\d{4}$ 匹配两个大写字母加四位数字

{rules.pattern && (
updateRules({ patternMessage: e.target.value || undefined })} placeholder="例如:请输入正确的编码格式(如:AB1234)" className={inputClass} />
)}
)} {/* 清除所有规则按钮 */} {hasAnyRules && (
)}
)}
) }