/** * 占位符表单组件 * 用于合同起草时填写占位符值 */ import { useState, useEffect } from 'react'; import type { PlaceholderSchema } from '~/types/contract-draft'; interface PlaceholderFormProps { schema: PlaceholderSchema | null; values: Record; onChange: (values: Record) => void; onBatchReplace: () => void; onExportDocument: () => void; // 改名:导出文档 onComplete: () => void; isReplacing: boolean; isDeleting: boolean; // 改名:是否正在删除 onSingleReplace?: (key: string, value: string) => void; // 单个替换 onFieldFocus?: (key: string) => void; // 字段聚焦(高亮) } export function PlaceholderForm({ schema, values, onChange, onBatchReplace, onExportDocument, onComplete, isReplacing, isDeleting, onSingleReplace, onFieldFocus }: PlaceholderFormProps) { const [localValues, setLocalValues] = useState>(values); const [replacingFields, setReplacingFields] = useState>(new Set()); // 同步外部 values 到本地状态 useEffect(() => { setLocalValues(values); }, [values]); // 处理字段变化 const handleFieldChange = (key: string, value: string) => { const newValues = { ...localValues, [key]: value }; setLocalValues(newValues); onChange(newValues); }; // 处理字段聚焦(高亮文档中的占位符) const handleFieldFocus = (key: string) => { if (onFieldFocus) { onFieldFocus(key); } }; // 处理单个字段替换 const handleSingleReplace = async (key: string) => { const value = localValues[key]; if (!value || !onSingleReplace) return; setReplacingFields(prev => new Set(prev).add(key)); try { await onSingleReplace(key, value); } finally { setReplacingFields(prev => { const next = new Set(prev); next.delete(key); return next; }); } }; // 检查是否有未填写的必填字段 const getMissingRequiredFields = () => { if (!schema) return []; return schema.fields .filter(f => f.required && !localValues[f.key]) .map(f => f.label); }; const handleCompleteClick = () => { const missing = getMissingRequiredFields(); if (missing.length > 0) { alert(`请填写以下必填字段:\n${missing.join('\n')}`); return; } onComplete(); }; if (!schema || !schema.fields || schema.fields.length === 0) { return (

暂无占位符配置

该模板尚未配置占位符字段

请联系管理员配置模板占位符

); } return (
{/* 表单头部 */}

填写合同信息

{/* 表单内容区域 */}
{schema?.fields.map((field) => (
{field.type === 'textarea' ? (