feat: 1. 实现一键替换。

2. 优化追加附件和模板上传的样式。
This commit is contained in:
2025-12-03 12:07:56 +08:00
parent 2897423404
commit d88cfc818b
13 changed files with 627 additions and 141 deletions
+128 -34
View File
@@ -35,7 +35,7 @@ export function links() {
// 面包屑导航
export const handle = {
breadcrumb: "文档列表",
breadcrumb: "文档上传",
previousRoute: {
title: "文档列表",
to: "/documents/list"
@@ -647,7 +647,7 @@ export default function FilesUpload() {
if (hasInvalidFiles) {
// 显示错误提示
messageService.error('只支持PDF、Word格式的文件', {
messageService.error('只支持.pdf、.docx格式的文件', {
title: '文件类型错误',
confirmText: '确定',
cancelText: '',
@@ -742,7 +742,7 @@ export default function FilesUpload() {
if (hasInvalidFiles) {
// 显示错误提示
console.error('【调试-handleContractMainFilesSelected】存在无效的文件类型');
messageService.error('只支持PDF、Word格式的文件', {
messageService.error('只支持.pdf、.docx格式的文件', {
title: '文件类型错误',
confirmText: '确定',
cancelText: '',
@@ -799,7 +799,7 @@ export default function FilesUpload() {
if (hasInvalidFiles) {
// 显示错误提示
console.error('【调试-handleContractAttachmentFilesSelected】存在无效的文件类型');
messageService.error('只支持PDF、Word格式的文件', {
messageService.error('只支持.pdf、.docx格式的文件', {
title: '文件类型错误',
confirmText: '确定',
cancelText: '',
@@ -856,7 +856,7 @@ export default function FilesUpload() {
if (hasInvalidFiles) {
// 显示错误提示
console.error('【调试-handleContractTemplateFilesSelected】存在无效的文件类型');
messageService.error('只支持PDF、Word格式的文件', {
messageService.error('只支持.pdf、.docx格式的文件', {
title: '文件类型错误',
confirmText: '确定',
cancelText: '',
@@ -883,21 +883,34 @@ export default function FilesUpload() {
const handleAttachmentFilesSelected = (files: FileList) => {
try {
console.log('【附件追加】开始处理附件文件选择, 文件数量:', files.length);
if (files.length > 0) {
// 检查主文件类型
const selectedDocument = queueFiles.find(doc => doc.id === selectedDocumentId);
const isMainFileDocx = selectedDocument?.path.toLowerCase().endsWith('.docx');
// 验证文件类型,支持PDF、Word、ZIP、RAR
const validFiles: File[] = [];
let hasInvalidFiles = false;
let hasPdfForDocx = false;
Array.from(files).forEach(file => {
const fileName = file.name.toLowerCase();
const isValidType =
file.type === 'application/pdf' || fileName.endsWith('.pdf') ||
const isPdf = file.type === 'application/pdf' || fileName.endsWith('.pdf');
const isValidType =
isPdf ||
file.type === 'application/msword' || fileName.endsWith('.doc') ||
file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || fileName.endsWith('.docx') ||
file.type === 'application/zip' || fileName.endsWith('.zip') ||
file.type === 'application/x-rar-compressed' || fileName.endsWith('.rar');
// 如果主文件是docx,不允许上传pdf附件
if (isMainFileDocx && isPdf) {
hasPdfForDocx = true;
console.error(`【附件追加】主文件为DOCX格式时不允许上传PDF附件: ${file.name}`);
return;
}
if (isValidType) {
validFiles.push(file);
} else {
@@ -905,15 +918,21 @@ export default function FilesUpload() {
console.error(`【附件追加】无效的文件类型: ${file.name}, 类型: ${file.type}`);
}
});
if (hasInvalidFiles) {
if (hasPdfForDocx) {
messageService.error('主文件为DOCX格式时,附件不可以是PDF格式', {
title: '文件类型限制',
confirmText: '确定',
cancelText: '',
});
} else if (hasInvalidFiles) {
messageService.error('只支持PDF、Word、ZIP、RAR格式的文件', {
title: '文件类型错误',
confirmText: '确定',
cancelText: '',
});
}
if (validFiles.length > 0) {
setAttachmentFiles(validFiles);
console.log('【附件追加】有效文件数量:', validFiles.length);
@@ -984,7 +1003,7 @@ export default function FilesUpload() {
setTemplateFile(file);
console.log('【合同模板上传】有效文件:', file.name);
} else {
messageService.error('只支持PDF、Word格式的文件', {
messageService.error('只支持.pdf、.docx格式的文件', {
title: '文件类型错误',
confirmText: '确定',
cancelText: '',
@@ -1166,6 +1185,11 @@ export default function FilesUpload() {
clearInterval(uploadProgressIntervalRef.current);
uploadProgressIntervalRef.current = null;
}
// 清空合同模板文件缓存
setContractTemplateFiles([]);
console.log('【合同上传失败】已清空合同模板文件缓存');
resetUpload();
}
};
@@ -1304,7 +1328,7 @@ export default function FilesUpload() {
if (invalidFiles.length > 0) {
console.error('【调试-startUpload】文件类型验证失败:', invalidFiles.map(f => f.name));
throw new Error('只支持PDF、Word格式的文件');
throw new Error('只支持.pdf、.docx格式的文件');
}
setUploadStage("uploading");
@@ -2235,7 +2259,7 @@ export default function FilesUpload() {
ref={uploadAreaRef}
onFilesSelected={handleFilesSelected}
multiple={true}
accept=".pdf,.doc,.docx"
accept=".pdf,.docx"
tipText="支持单个或多个文件上传,文件格式:PDF/Word"
shouldPreventFileSelect={!fileType}
/>
@@ -2243,12 +2267,29 @@ export default function FilesUpload() {
// 合同文件上传区域 - 三区域布局
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<h4 className="font-medium mb-2"></h4>
<UploadArea
<div className="flex items-center gap-4 mb-2">
<h4 className="font-medium"></h4>
{contractMainFiles.length > 0 && (
<button
type="button"
onClick={() => {
setContractMainFiles([]);
if (contractMainFileRef.current) {
contractMainFileRef.current.resetFileInput();
}
}}
className="text-red-500 hover:text-red-700 transition-colors"
title="清空已选择的主文件"
>
<i className="ri-delete-bin-line"></i>
</button>
)}
</div>
<UploadArea
onFilesSelected={handleContractMainFilesSelected}
ref={contractMainFileRef}
multiple={false}
accept=".pdf,.doc,.docx"
accept=".pdf,.docx"
tipText="请上传合同主文件,格式:PDF/Word"
mainText="上传合同主文件"
buttonText="选择主文件"
@@ -2257,18 +2298,35 @@ export default function FilesUpload() {
/>
{contractMainFiles.length > 0 && (
<div className="mt-2 text-sm text-green-600">
<i className="ri-checkbox-circle-line"></i>
<i className="ri-checkbox-circle-line"></i>
: <span className="font-medium">{contractMainFiles[0].name}</span>
</div>
)}
</div>
<div>
<h4 className="font-medium mb-2"></h4>
<UploadArea
<div className="flex items-center gap-4 mb-2">
<h4 className="font-medium"></h4>
{contractAttachmentFiles.length > 0 && (
<button
type="button"
onClick={() => {
setContractAttachmentFiles([]);
if (contractAttachmentFileRef.current) {
contractAttachmentFileRef.current.resetFileInput();
}
}}
className="text-red-500 hover:text-red-700 transition-colors"
title="清空已选择的附件"
>
<i className="ri-delete-bin-line"></i>
</button>
)}
</div>
<UploadArea
onFilesSelected={handleContractAttachmentFilesSelected}
ref={contractAttachmentFileRef}
multiple={false}
accept=".pdf,.doc,.docx"
accept=".pdf,.docx"
tipText="请上传合同附件,格式:PDF/Word"
mainText="上传合同附件"
buttonText="选择附件"
@@ -2277,7 +2335,7 @@ export default function FilesUpload() {
/>
{contractAttachmentFiles.length > 0 && (
<div className="mt-2 text-sm text-green-600">
<i className="ri-checkbox-circle-line"></i>
<i className="ri-checkbox-circle-line"></i>
: {contractAttachmentFiles.map((file, index) => (
<span key={index} className="font-medium">{file.name}</span>
))}
@@ -2285,11 +2343,25 @@ export default function FilesUpload() {
)}
</div>
<div>
<h4 className="font-medium mb-2"></h4>
<UploadArea
<div className="flex gap-4 items-center mb-2">
<h4 className="font-medium"></h4>
{contractTemplateFiles.length > 0 && (
<button
type="button"
onClick={() => {
setContractTemplateFiles([]);
}}
className="text-red-500 hover:text-red-700 transition-colors"
title="清空已选择的模板"
>
<i className="ri-delete-bin-line"></i>
</button>
)}
</div>
<UploadArea
onFilesSelected={handleContractTemplateFilesSelected}
multiple={false}
accept=".pdf,.doc,.docx"
accept=".pdf,.docx"
tipText="请上传合同模板,格式:PDF/Word"
mainText="上传合同模板"
buttonText="选择模板"
@@ -2298,7 +2370,7 @@ export default function FilesUpload() {
/>
{contractTemplateFiles.length > 0 && (
<div className="mt-2 text-sm text-green-600">
<i className="ri-checkbox-circle-line"></i>
<i className="ri-checkbox-circle-line"></i>
: <span className="font-medium">{contractTemplateFiles[0].name}</span>
</div>
)}
@@ -2521,7 +2593,19 @@ export default function FilesUpload() {
{/* 附件追加模态框 */}
{showAttachmentUpload && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div
className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-[9999]"
onClick={(e) => {
// 点击蒙层关闭模态框
if (e.target === e.currentTarget) {
setShowAttachmentUpload(false);
setSelectedDocumentId(null);
setAttachmentFiles([]);
setAttachmentRemark("");
setAttachmentMergeMode('overwrite');
}
}}
>
<div className="bg-white rounded-lg p-6 w-full max-w-2xl mx-4 max-h-[90vh] overflow-y-auto">
<div className="flex justify-between items-center mb-4">
<h3 className="text-lg font-semibold"></h3>
@@ -2557,7 +2641,7 @@ export default function FilesUpload() {
<UploadArea
onFilesSelected={handleAttachmentFilesSelected}
multiple={true}
accept=".pdf,.doc,.docx,.zip,.rar"
accept=".pdf,.docx,.zip,.rar"
tipText="支持PDF、Word、ZIP、RAR格式,可多选"
mainText="选择附件文件"
buttonText="选择文件"
@@ -2655,7 +2739,17 @@ export default function FilesUpload() {
{/* 合同模板上传模态框 */}
{showTemplateUpload && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div
className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-[9999]"
onClick={(e) => {
// 点击蒙层关闭模态框
if (e.target === e.currentTarget) {
setShowTemplateUpload(false);
setSelectedDocumentId(null);
setTemplateFile(null);
}
}}
>
<div className="bg-white rounded-lg p-6 w-full max-w-lg mx-4">
<div className="flex justify-between items-center mb-4">
<h3 className="text-lg font-semibold"></h3>
@@ -2678,7 +2772,7 @@ export default function FilesUpload() {
ID: <span className="font-medium">{selectedDocumentId}</span>
</p>
<p className="text-xs text-gray-500 mt-1">
PDFWord格式
.pdf.docx格式
</p>
</div>
@@ -2690,8 +2784,8 @@ export default function FilesUpload() {
<UploadArea
onFilesSelected={handleTemplateFileSelected}
multiple={false}
accept=".pdf,.doc,.docx"
tipText="支持PDF、Word格式"
accept=".pdf,.docx"
tipText="支持.pdf、.docx格式"
mainText="选择模板文件"
buttonText="选择文件"
icon="ri-file-copy-line"