/** * 占位符表单组件 * 用于合同起草时填写占位符值 */ import { useState, useEffect } from 'react'; import type { PlaceholderSchema } from '~/types/contract-draft'; import { messageService } from '~/components/ui/MessageModal'; interface PlaceholderFormProps { schema: PlaceholderSchema | null; values: Record; onChange: (values: Record) => void; onComplete: () => void; isDeleting: boolean; // 是否正在删除 onSingleReplace?: (key: string, value: string) => void; // 单个替换 onFieldFocus?: (key: string) => void; // 字段聚焦(高亮) } export function PlaceholderForm({ schema, values, onChange, onComplete, 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) { messageService.show({ type: 'warning', title: '字段校验失败', message: '请填写以下必填字段:', children: (
    {missing.map((field, index) => (
  • {field}
  • ))}
), confirmText: '确定' }); return; } onComplete(); }; if (!schema || !schema.fields || schema.fields.length === 0) { return (

暂无占位符配置

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

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

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

填写合同信息

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