feat: 1. 重构交叉评查任务的文档列表的显示,对接接口查询当前任务的文档相关信息。

2.文档上传通过接口去查询是否存在同名的文件,做上传前拦截提示。
3.交叉评查的评查结果也同步添加企查查的企业信息查询模块。
4. 封装上传附件和上传模板的模态框的组件,在交叉评查的文档列表中引入显示。
5. 交叉评查的评查结果中关于合同类型的文档同步加入结构比对的功能。
This commit is contained in:
2025-12-13 07:18:37 +08:00
parent daa53289af
commit 1658bb1c6f
11 changed files with 3368 additions and 363 deletions
+76 -43
View File
@@ -10,18 +10,19 @@ import { ProcessingSteps, Step } from "~/components/ui/ProcessingSteps";
import uploadStyles from "~/styles/pages/files_upload.css?url";
import { messageService } from "~/components/ui/MessageModal";
import { toastService } from "~/components/ui/Toast";
import {
getTodayDocuments,
getDocumentTypes,
getDocumentsStatus,
import {
getTodayDocuments,
getDocumentTypes,
getDocumentsStatus,
uploadFileToBinary,
uploadDocumentToServer,
appendContractAttachments,
uploadContractTemplate,
type Document,
type DocumentType,
checkDocumentDuplicate,
type Document,
type DocumentType,
type FileUploadResponse,
DocumentStatus
DocumentStatus
} from "~/api/files/files-upload";
import { updateDocumentAuditStatus } from "~/api/evaluation_points/rules-files";
import { links as fileTypeTagLinks } from "~/components/ui/FileTypeTag";
@@ -631,21 +632,21 @@ export default function FilesUpload() {
// 验证文件类型,支持PDF和Word文件
const validFiles: File[] = [];
let hasInvalidFiles = false;
Array.from(files).forEach(file => {
const fileName = file.name.toLowerCase();
const isValidType =
const isValidType =
file.type === 'application/pdf' || fileName.endsWith('.pdf') ||
file.type === 'application/msword' || fileName.endsWith('.doc') ||
file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || fileName.endsWith('.docx');
if (isValidType) {
validFiles.push(file);
} else {
hasInvalidFiles = true;
}
});
if (hasInvalidFiles) {
// 显示错误提示
messageService.error('只支持.pdf、.docx格式的文件', {
@@ -654,11 +655,14 @@ export default function FilesUpload() {
cancelText: '',
});
}
if (validFiles.length > 0) {
setCurrentFiles(validFiles);
if (fileType) {
startUpload(validFiles);
// 通过 checkAndPrepareUpload 进行重名检查后再上传
checkAndPrepareUpload(validFiles, [], []);
} else {
// 如果没有选择文件类型,先保存文件等待用户选择
setCurrentFiles(validFiles);
}
}
}
@@ -694,7 +698,8 @@ export default function FilesUpload() {
// 如果已经有选中的文件,且选择了文件类型,且不是合同类型,则开始上传
if (currentFiles.length > 0 && !isContract) {
// console.log('【调试-handleFileTypeChange】自动开始上传非合同类型文件');
startUpload(currentFiles);
// 通过 checkAndPrepareUpload 进行重名检查后再上传
checkAndPrepareUpload(currentFiles, [], []);
} else if (currentFiles.length > 0 && isContract) {
// console.log('【调试-handleFileTypeChange】合同类型需要手动点击开始上传按钮');
// 合同类型不自动上传,需要用户先上传主文件和附件,然后点击开始上传按钮
@@ -1063,6 +1068,20 @@ export default function FilesUpload() {
// 只允许一个主文件
const mainFile = mainFiles[0];
// 检查文档名称是否重复
const duplicateResult = await checkDocumentDuplicate(mainFile.name, Number(fileType));
if (duplicateResult.is_duplicate) {
const confirmed = window.confirm(
'存在同名文件,会归纳到历史版本中。如需纳入历史版本请点击确定,否则点击取消并重新命名文档后再上传。'
);
if (!confirmed) {
// 用户取消时,清空合同主文件输入框以便重新选择文件
contractMainFileRef.current?.resetFileInput();
setContractMainFiles([]);
return;
}
}
// 为进度条提供文件集合与阶段
const filesForProgress = [mainFile, ...attachmentFiles, ...templateFiles];
setCurrentFiles(filesForProgress);
@@ -1198,38 +1217,38 @@ export default function FilesUpload() {
};
// 检查并准备上传
const checkAndPrepareUpload = (mainFiles: File[], attachmentFiles: File[], templateFiles: File[] = []) => {
const checkAndPrepareUpload = async (mainFiles: File[], attachmentFiles: File[], templateFiles: File[] = []) => {
try {
console.log('【调试-checkAndPrepareUpload】开始检查并准备上传文件', {
mainFilesCount: mainFiles.length,
attachmentFilesCount: attachmentFiles.length,
templateFilesCount: templateFiles.length,
fileType
});
// console.log('【调试-checkAndPrepareUpload】开始检查并准备上传文件', {
// mainFilesCount: mainFiles.length,
// attachmentFilesCount: attachmentFiles.length,
// templateFilesCount: templateFiles.length,
// fileType
// });
// 检查组件是否已卸载
if (!isMountedRef.current) {
console.error('【调试-checkAndPrepareUpload】组件已卸载,取消操作');
return;
}
// 检查是否选择了文件类型
if (!fileType) {
console.error('【调试-checkAndPrepareUpload】未选择文件类型');
toastService.error('请先选择文件类型');
return;
}
// 检查是否为合同类型
const selectedType = loaderData.documentTypes.find(t => t.id.toString() === fileType);
const isContract = !!(selectedType && selectedType.name.includes('合同'));
// console.log('【调试-checkAndPrepareUpload】文件类型检查', {
// selectedType,
// isContract,
// typeName: selectedType?.name
// });
if (isContract) {
// 合同类型:走首传即合并的专用链路
if(mainFiles.length === 0) {
@@ -1239,25 +1258,39 @@ export default function FilesUpload() {
startContractUpload(mainFiles, attachmentFiles, templateFiles);
return;
}
if (mainFiles.length > 0) {
// 合并所有文件
let allFiles = [...mainFiles];
// console.log('【调试-checkAndPrepareUpload】合并文件后总数:', allFiles.length);
// 检查组件是否已卸载
if (!isMountedRef.current) {
console.error('【调试-checkAndPrepareUpload】组件已卸载,取消操作');
return;
}
// 检查主文件名称是否重复(在任何状态变化之前进行检查)
const mainFile = allFiles[0];
const duplicateResult = await checkDocumentDuplicate(mainFile.name, Number(fileType));
if (duplicateResult.is_duplicate) {
const confirmed = window.confirm(
'存在同名文件,会归纳到历史版本中。如需纳入历史版本请点击确定,否则点击取消并重新命名文档后再上传。'
);
if (!confirmed) {
// 用户取消时,清空文件输入框以便重新选择文件
uploadAreaRef.current?.resetFileInput();
return;
}
}
// 这里的currentFiles的长度是上传进度条是否显示的关键
setCurrentFiles(allFiles);
// 将准备上传的操作移到这里,暂时不执行
console.log('【调试-checkAndPrepareUpload】准备上传', allFiles.length, '个文件');
// console.log('【调试-checkAndPrepareUpload】准备上传', allFiles.length, '个文件');
if (fileType) {
try {
// 再次检查组件是否已卸载
@@ -1265,9 +1298,9 @@ export default function FilesUpload() {
console.error('【调试-checkAndPrepareUpload】组件已卸载,取消上传');
return;
}
// console.log('【调试-checkAndPrepareUpload】开始调用startUpload函数');
// 使用 setTimeout 延迟调用,确保状态已更新
setTimeout(() => {
if (isMountedRef.current) {
@@ -1281,10 +1314,10 @@ export default function FilesUpload() {
console.error('【调试-checkAndPrepareUpload】组件已卸载,取消延迟上传');
}
}, 0);
} catch (uploadError) {
console.error('【调试-checkAndPrepareUpload】调用startUpload失败:', uploadError);
// 检查组件是否已卸载
if (isMountedRef.current) {
toastService.error(`准备上传文件失败: ${uploadError instanceof Error ? uploadError.message : '未知错误'}`);
@@ -1300,7 +1333,7 @@ export default function FilesUpload() {
}
} catch (error) {
console.error('【调试-checkAndPrepareUpload】准备上传文件过程中发生错误:', error);
// 检查组件是否已卸载
if (isMountedRef.current) {
toastService.error(`准备上传文件失败: ${error instanceof Error ? error.message : '未知错误'}`);
@@ -1312,28 +1345,28 @@ export default function FilesUpload() {
const startUpload = async (files: File[]) => {
try {
console.log('【调试-startUpload】开始上传过程,文件数量:', files.length);
// 检查组件是否已卸载
if (!isMountedRef.current) {
console.error('【调试-startUpload】组件已卸载,取消上传');
return;
}
// 再次验证所有文件类型,确保只有PDF文件
const invalidFiles = files.filter(file => {
const fileName = file.name.toLowerCase();
const isValidType =
const isValidType =
file.type === 'application/pdf' || fileName.endsWith('.pdf') ||
file.type === 'application/msword' || fileName.endsWith('.doc') ||
file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || fileName.endsWith('.docx');
return !isValidType;
});
if (invalidFiles.length > 0) {
console.error('【调试-startUpload】文件类型验证失败:', invalidFiles.map(f => f.name));
throw new Error('只支持.pdf、.docx格式的文件');
}
setUploadStage("uploading");
setUploadProgress(0);