修复起草合同的销毁保存下载和删除的逻辑
This commit is contained in:
@@ -184,14 +184,17 @@ export default function ContractDraftPage() {
|
||||
searchText: string;
|
||||
replaceText: string;
|
||||
pageNumber: number;
|
||||
silentReplace?: boolean;
|
||||
} | undefined>(undefined);
|
||||
const [showFilePreview, setShowFilePreview] = useState(true); // 控制 FilePreview 显示
|
||||
const [isCompleting, setIsCompleting] = useState(false); // 标记是否正在执行完成流程
|
||||
|
||||
const filePreviewRef = useRef<FilePreviewHandle>(null);
|
||||
const hasDeletedNormally = useRef(false); // 标记是否已通过正常流程删除
|
||||
const currentPathRef = useRef(window.location.pathname); // 保存当前路由路径
|
||||
|
||||
// 从 fetcher.state 判断是否正在操作
|
||||
const isDeleting = fetcher.state !== 'idle';
|
||||
const isDeleting = fetcher.state !== 'idle' || isCompleting;
|
||||
|
||||
// 处理 fetcher 响应(文件删除)
|
||||
useEffect(() => {
|
||||
@@ -275,24 +278,25 @@ export default function ContractDraftPage() {
|
||||
const placeholder = `{{${key}}}`;
|
||||
console.log(`[Draft] 单个替换: ${placeholder} -> ${value}`);
|
||||
|
||||
// 设置 AI 建议替换参数,触发 FilePreview 中的替换
|
||||
// 设置 AI 建议替换参数,触发 FilePreview 中的静默替换
|
||||
setAiSuggestionReplace({
|
||||
searchText: placeholder,
|
||||
replaceText: value,
|
||||
pageNumber: 1 // 从第一页开始搜索
|
||||
pageNumber: 1, // 从第一页开始搜索
|
||||
silentReplace: true // 静默替换,不显示搜索替换面板
|
||||
});
|
||||
|
||||
// 短暂延迟后清除参数,以便下次可以重新触发
|
||||
setTimeout(() => {
|
||||
setAiSuggestionReplace(undefined);
|
||||
// toastService.success(`已替换 ${key}`);
|
||||
}, 1000);
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
// 字段聚焦时高亮对应占位符
|
||||
const handleFieldFocus = (key: string) => {
|
||||
const placeholder = `{{${key}}}`;
|
||||
console.log(`[Draft] 高亮占位符: ${placeholder}`);
|
||||
// console.log(`[Draft] 高亮占位符: ${placeholder}`);
|
||||
|
||||
// 设置高亮值,触发 FilePreview 中的高亮
|
||||
setHighlightValue(placeholder);
|
||||
@@ -303,7 +307,7 @@ export default function ContractDraftPage() {
|
||||
}, 100);
|
||||
};
|
||||
|
||||
// 导出文档(下载当前编辑的文件)
|
||||
// 导出文档(下载当前编辑的文件)- 不再需要手动保存
|
||||
const handleExportDocument = async () => {
|
||||
if (!draft.file_path) {
|
||||
toastService.error('文件路径不存在,无法下载');
|
||||
@@ -311,6 +315,9 @@ export default function ContractDraftPage() {
|
||||
}
|
||||
|
||||
try {
|
||||
const fileExtension = draft.file_path.split('.').pop()?.toLowerCase();
|
||||
|
||||
console.log('[Draft] 正在下载文件:', draft.file_path);
|
||||
toastService.info('正在下载文件...');
|
||||
|
||||
// 使用 axios-client 的 downloadFile 方法下载文件
|
||||
@@ -320,8 +327,7 @@ export default function ContractDraftPage() {
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
|
||||
// 清理文件名
|
||||
const fileExtension = draft.file_path.split('.').pop() || 'docx';
|
||||
const fileName = `${draft.title}.${fileExtension}`;
|
||||
const fileName = `${draft.title}.${fileExtension || 'docx'}`;
|
||||
const cleanFileName = fileName.replace(/[<>:"/\\|?*]/g, '_');
|
||||
|
||||
// 创建隐藏的a标签并点击下载
|
||||
@@ -342,24 +348,41 @@ export default function ContractDraftPage() {
|
||||
} catch (error) {
|
||||
console.error('[Draft] 下载文件失败:', error);
|
||||
toastService.error(`下载文件失败: ${error instanceof Error ? error.message : '未知错误'}`);
|
||||
throw error; // 重新抛出错误,让 handleComplete 捕获
|
||||
}
|
||||
};
|
||||
|
||||
// 完成起草(下载文件 + 删除 MinIO 文件)
|
||||
// 完成起草(触发保存 → 下载文件 → 删除 MinIO 文件)
|
||||
const handleComplete = async () => {
|
||||
try {
|
||||
// 1. 先下载文件
|
||||
setIsCompleting(true);
|
||||
|
||||
// 步骤1:隐藏 FilePreview,触发 CollaboraViewer 组件销毁和保存
|
||||
console.log('[Complete] 步骤1:隐藏 FilePreview,触发 Collabora 保存');
|
||||
toastService.info('正在保存文档...');
|
||||
setShowFilePreview(false);
|
||||
|
||||
// 步骤2:等待 Collabora 保存完成(给予充足时间让 WOPI PutFile 完成)
|
||||
console.log('[Complete] 步骤2:等待 4 秒让 WOPI PutFile 完成');
|
||||
await new Promise(resolve => setTimeout(resolve, 4000));
|
||||
|
||||
// 步骤3:下载文件
|
||||
console.log('[Complete] 步骤3:下载文件');
|
||||
await handleExportDocument();
|
||||
|
||||
// 2. 删除 MinIO 文件
|
||||
// 步骤4:删除 MinIO 文件
|
||||
console.log('[Complete] 步骤4:删除 MinIO 文件');
|
||||
const formData = new FormData();
|
||||
formData.append('_action', 'deleteFile');
|
||||
formData.append('filePath', draft.file_path);
|
||||
|
||||
fetcher.submit(formData, { method: 'post' });
|
||||
|
||||
} catch (error) {
|
||||
console.error('[Complete] 操作失败:', error);
|
||||
toastService.error('操作失败,请重试');
|
||||
setIsCompleting(false);
|
||||
setShowFilePreview(true); // 恢复显示
|
||||
}
|
||||
};
|
||||
|
||||
@@ -417,25 +440,35 @@ export default function ContractDraftPage() {
|
||||
<div className="flex-1 flex overflow-hidden gap-4 p-4">
|
||||
{/* 左侧:文档预览(60%) */}
|
||||
<div className="w-[60%] bg-white h-full overflow-hidden rounded-xl shadow-lg border border-gray-200">
|
||||
<FilePreview
|
||||
ref={filePreviewRef}
|
||||
fileContent={{
|
||||
path: draft.file_path,
|
||||
title: draft.title,
|
||||
contractNumber: '',
|
||||
parties: {
|
||||
partyA: { name: '', address: '', representative: '', phone: '' },
|
||||
partyB: { name: '', address: '', representative: '', phone: '' }
|
||||
},
|
||||
sections: []
|
||||
}}
|
||||
activeReviewPointResultId={null}
|
||||
targetPage={undefined}
|
||||
isStructuredView={false}
|
||||
isTemplate={false} // 编辑模式
|
||||
highlightValue={highlightValue}
|
||||
aiSuggestionReplace={aiSuggestionReplace}
|
||||
/>
|
||||
{showFilePreview ? (
|
||||
<FilePreview
|
||||
ref={filePreviewRef}
|
||||
fileContent={{
|
||||
path: draft.file_path,
|
||||
title: draft.title,
|
||||
contractNumber: '',
|
||||
parties: {
|
||||
partyA: { name: '', address: '', representative: '', phone: '' },
|
||||
partyB: { name: '', address: '', representative: '', phone: '' }
|
||||
},
|
||||
sections: []
|
||||
}}
|
||||
activeReviewPointResultId={null}
|
||||
targetPage={undefined}
|
||||
isStructuredView={false}
|
||||
isTemplate={false} // 编辑模式
|
||||
highlightValue={highlightValue}
|
||||
aiSuggestionReplace={aiSuggestionReplace}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex items-center justify-center h-full">
|
||||
<div className="text-center">
|
||||
<div className="inline-block animate-spin rounded-full h-12 w-12 border-b-2 border-primary mb-4"></div>
|
||||
<p className="text-gray-600 font-medium">正在保存文档...</p>
|
||||
<p className="text-sm text-gray-500 mt-2">请稍候,即将完成</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 右侧:占位符表单(40%) */}
|
||||
|
||||
Reference in New Issue
Block a user