feat:完善合同起草页面点击高亮以及页面跳转问题
This commit is contained in:
@@ -3,9 +3,9 @@
|
||||
* 用于合同起草时填写占位符值
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import type { PlaceholderSchema } from '~/types/contract-draft';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { messageService } from '~/components/ui/MessageModal';
|
||||
import type { PlaceholderSchema } from '~/types/contract-draft';
|
||||
|
||||
interface PlaceholderFormProps {
|
||||
schema: PlaceholderSchema | null;
|
||||
@@ -28,6 +28,8 @@ export function PlaceholderForm({
|
||||
}: PlaceholderFormProps) {
|
||||
const [localValues, setLocalValues] = useState<Record<string, string>>(values);
|
||||
const [replacingFields, setReplacingFields] = useState<Set<string>>(new Set());
|
||||
// 【新增】记录当前高亮的字段(只存一个值),避免重复高亮导致焦点被抢
|
||||
const [currentHighlightedField, setCurrentHighlightedField] = useState<string | null>(null);
|
||||
|
||||
// 同步外部 values 到本地状态
|
||||
useEffect(() => {
|
||||
@@ -41,11 +43,44 @@ export function PlaceholderForm({
|
||||
onChange(newValues);
|
||||
};
|
||||
|
||||
// 处理字段聚焦(高亮文档中的占位符)
|
||||
const handleFieldFocus = (key: string) => {
|
||||
// 处理字段点击(高亮文档中的占位符)
|
||||
const handleFieldClick = async (e: React.MouseEvent<HTMLInputElement | HTMLTextAreaElement>, key: string) => {
|
||||
// 1. 检查是否已经高亮当前字段
|
||||
if (currentHighlightedField === key) {
|
||||
console.log(`[PlaceholderForm] 字段 "${key}" 已高亮,跳过高亮操作`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 捕获当前输入框 DOM 元素
|
||||
const inputElement = e.currentTarget;
|
||||
|
||||
// 3. 更新当前高亮字段(只保存一个)
|
||||
setCurrentHighlightedField(key);
|
||||
console.log(`[PlaceholderForm] 切换高亮字段到 "${key}"`);
|
||||
|
||||
// 4. 调用父组件的高亮回调
|
||||
if (onFieldFocus) {
|
||||
onFieldFocus(key);
|
||||
}
|
||||
|
||||
// 5. 【核心】延迟后强制夺回焦点(UNO 命令会让 iframe 抢焦点)
|
||||
// 分多次确保焦点回到输入框,防止被 iframe 再次抢走
|
||||
const refocusWithRetry = () => {
|
||||
console.log(`[PlaceholderForm] 夺回焦点到输入框 "${key}"`);
|
||||
inputElement.focus();
|
||||
|
||||
// 保持光标在文字最后
|
||||
const len = inputElement.value.length;
|
||||
if ('setSelectionRange' in inputElement) {
|
||||
inputElement.setSelectionRange(len, len);
|
||||
}
|
||||
};
|
||||
|
||||
// 第一次夺回焦点:150ms(高亮操作完成时)
|
||||
setTimeout(refocusWithRetry, 150);
|
||||
|
||||
// 第二次确认焦点:300ms(确保没有被再次抢走)
|
||||
setTimeout(refocusWithRetry, 300);
|
||||
};
|
||||
|
||||
// 处理单个字段替换
|
||||
@@ -125,11 +160,10 @@ export function PlaceholderForm({
|
||||
<button
|
||||
onClick={handleCompleteClick}
|
||||
disabled={isDeleting}
|
||||
className={`flex items-center justify-center gap-1.5 px-6 py-2 text-sm font-medium rounded-lg transition-all duration-150 ${
|
||||
isDeleting
|
||||
? 'bg-gray-200 text-gray-400 cursor-not-allowed'
|
||||
: 'bg-green-600 text-white hover:bg-green-700 hover:shadow-md active:scale-[0.98]'
|
||||
}`}
|
||||
className={`flex items-center justify-center gap-1.5 px-6 py-2 text-sm font-medium rounded-lg transition-all duration-150 ${isDeleting
|
||||
? 'bg-gray-200 text-gray-400 cursor-not-allowed'
|
||||
: 'bg-green-600 text-white hover:bg-green-700 hover:shadow-md active:scale-[0.98]'
|
||||
}`}
|
||||
>
|
||||
{isDeleting ? (
|
||||
<>
|
||||
@@ -163,7 +197,7 @@ export function PlaceholderForm({
|
||||
<textarea
|
||||
value={localValues[field.key] || ''}
|
||||
onChange={(e) => handleFieldChange(field.key, e.target.value)}
|
||||
onFocus={() => handleFieldFocus(field.key)}
|
||||
onClick={(e) => handleFieldClick(e, field.key)}
|
||||
placeholder={field.placeholder || `请输入${field.label}`}
|
||||
className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all duration-150 resize-none bg-white text-gray-900 placeholder-gray-400 text-sm"
|
||||
rows={3}
|
||||
@@ -173,7 +207,7 @@ export function PlaceholderForm({
|
||||
type={field.type}
|
||||
value={localValues[field.key] || ''}
|
||||
onChange={(e) => handleFieldChange(field.key, e.target.value)}
|
||||
onFocus={() => handleFieldFocus(field.key)}
|
||||
onClick={(e) => handleFieldClick(e, field.key)}
|
||||
placeholder={field.placeholder || `请输入${field.label}`}
|
||||
className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all duration-150 bg-white text-gray-900 placeholder-gray-400 text-sm"
|
||||
/>
|
||||
@@ -183,11 +217,10 @@ export function PlaceholderForm({
|
||||
<button
|
||||
onClick={() => handleSingleReplace(field.key)}
|
||||
disabled={!localValues[field.key] || replacingFields.has(field.key)}
|
||||
className={`px-3 py-2 rounded-lg transition-all duration-150 flex items-center gap-1.5 text-sm font-medium whitespace-nowrap ${
|
||||
!localValues[field.key] || replacingFields.has(field.key)
|
||||
? 'bg-gray-100 text-gray-400 cursor-not-allowed'
|
||||
: 'bg-primary text-white hover:bg-primary-hover shadow-sm hover:shadow'
|
||||
}`}
|
||||
className={`px-3 py-2 rounded-lg transition-all duration-150 flex items-center gap-1.5 text-sm font-medium whitespace-nowrap ${!localValues[field.key] || replacingFields.has(field.key)
|
||||
? 'bg-gray-100 text-gray-400 cursor-not-allowed'
|
||||
: 'bg-primary text-white hover:bg-primary-hover shadow-sm hover:shadow'
|
||||
}`}
|
||||
title="替换此占位符"
|
||||
>
|
||||
{replacingFields.has(field.key) ? (
|
||||
|
||||
Reference in New Issue
Block a user