新增文件上传功能,支持附件上传,优化合同上传逻辑,调整接口调用方式。

This commit is contained in:
2025-09-12 16:21:55 +08:00
parent 75fcaa4885
commit 75923b7b04
2 changed files with 74 additions and 31 deletions
+12 -2
View File
@@ -310,7 +310,8 @@ export async function uploadDocumentToServer(
isTestDocument: boolean = false, isTestDocument: boolean = false,
documentId?: number | null, documentId?: number | null,
isReupload: boolean = false, isReupload: boolean = false,
jwtToken?: string jwtToken?: string,
attachments?: File[]
): Promise<{data: FileUploadResponse; error?: never} | {data?: never; error: string; status?: number}> { ): Promise<{data: FileUploadResponse; error?: never} | {data?: never; error: string; status?: number}> {
try { try {
// console.log('【调试】开始上传文档:', { fileName, fileSize: binaryData.byteLength }); // console.log('【调试】开始上传文档:', { fileName, fileSize: binaryData.byteLength });
@@ -338,8 +339,17 @@ export async function uploadDocumentToServer(
formData.append('upload_info', JSON.stringify(uploadInfo)); formData.append('upload_info', JSON.stringify(uploadInfo));
// console.log('【调试】FormData准备完成:', JSON.stringify(uploadInfo)); // console.log('【调试】FormData准备完成:', JSON.stringify(uploadInfo));
// 如果提供了附件(仅当后端支持首传合并时使用),按照后端规范追加到 FormData
if (attachments && attachments.length > 0) {
attachments.forEach(att => {
formData.append('attachments', att);
});
}
// 根据是否有documentId决定使用哪个接口 // 根据是否有documentId决定使用哪个接口
const uploadEndpoint = documentId ? '/upload_contract_template' : '/upload'; // 首传合并:无论是否有附件,都应走 /upload
// 仅当要上传“合同模板”时,使用独立的 uploadContractTemplate 接口(不在本函数中处理)。
const uploadEndpoint = '/upload';
const uploadUrl = UPLOAD_URL + uploadEndpoint; const uploadUrl = UPLOAD_URL + uploadEndpoint;
// console.log('【调试】准备发送请求到服务器:', uploadUrl); // console.log('【调试】准备发送请求到服务器:', uploadUrl);
+62 -29
View File
@@ -126,7 +126,8 @@ async function handleFileUpload(
isTestDocument: boolean, isTestDocument: boolean,
documentId?: number | null, documentId?: number | null,
isReupload: boolean = false, isReupload: boolean = false,
jwtToken?: string jwtToken?: string,
attachments?: File[]
): Promise<FileUploadResponse> { ): Promise<FileUploadResponse> {
const response = await uploadDocumentToServer( const response = await uploadDocumentToServer(
binaryData, binaryData,
@@ -139,7 +140,8 @@ async function handleFileUpload(
isTestDocument, isTestDocument,
documentId, documentId,
isReupload, isReupload,
jwtToken jwtToken,
attachments
); );
if (response.error || !response.data) { if (response.error || !response.data) {
@@ -1016,6 +1018,61 @@ export default function FilesUpload() {
} }
}; };
// 合同专用:首传即合并的上传链路
const startContractUpload = async (mainFiles: File[], attachmentFiles: File[], templateFiles: File[] = []) => {
try {
// 只允许一个主文件
const mainFile = mainFiles[0];
setUploadStage("uploading");
setUploadProgress(0);
// 转二进制
const binaryData = await uploadFileToBinary(mainFile);
// 首传:将附件通过 attachments 一起带上
const uploadResp = await handleFileUpload(
binaryData,
mainFile.name,
mainFile.type,
fileType as FileType,
priority,
documentNumber || null,
remark || null,
isTestDocument,
null,
false,
loaderData.frontendJWT || undefined,
attachmentFiles
);
if (!uploadResp.result) throw new Error('主文件上传失败');
const documentId = uploadResp.result.id;
// 可选:模板上传
if (templateFiles && templateFiles.length > 0) {
const tpl = templateFiles[0];
const tplResult = await uploadContractTemplate(
tpl,
documentId,
undefined,
loaderData.frontendJWT as string | undefined
);
if ('error' in tplResult && tplResult.error) {
throw new Error(tplResult.error);
}
}
toastService.success('上传成功,已触发处理');
// 刷新队列
await filterDocuments(reviewType);
setUploadStage("processing");
} catch (error) {
console.error('合同首传上传失败:', error);
messageService.error(`合同上传失败:${error instanceof Error ? error.message : '未知错误'}`);
setUploadStage("idle");
}
};
// 检查并准备上传 // 检查并准备上传
const checkAndPrepareUpload = (mainFiles: File[], attachmentFiles: File[], templateFiles: File[] = []) => { const checkAndPrepareUpload = (mainFiles: File[], attachmentFiles: File[], templateFiles: File[] = []) => {
try { try {
@@ -1050,43 +1107,19 @@ export default function FilesUpload() {
// }); // });
if (isContract) { if (isContract) {
// console.log('【调试-checkAndPrepareUpload】合同文档类型特殊处理'); // 合同类型:走首传即合并的专用链路
// 检查主文件
if(mainFiles.length === 0) { if(mainFiles.length === 0) {
console.error('【调试-checkAndPrepareUpload】缺少合同主文件');
toastService.error('请上传合同主文件'); toastService.error('请上传合同主文件');
return; return;
} }
startContractUpload(mainFiles, attachmentFiles, templateFiles);
// 记录主文件、附件文件和模板文件信息 return;
console.log('【调试-checkAndPrepareUpload】合同主文件:', mainFiles.map(f => ({ name: f.name, size: f.size, type: f.type })));
if (attachmentFiles.length > 0) {
console.log('【调试-checkAndPrepareUpload】合同附件文件:', attachmentFiles.map(f => ({ name: f.name, size: f.size, type: f.type })));
} else {
console.log('【调试-checkAndPrepareUpload】无合同附件文件');
}
if (templateFiles.length > 0) {
console.log('【调试-checkAndPrepareUpload】合同模板文件:', templateFiles.map(f => ({ name: f.name, size: f.size, type: f.type })));
} else {
console.log('【调试-checkAndPrepareUpload】无合同模板文件');
}
} }
if (mainFiles.length > 0) { if (mainFiles.length > 0) {
// 合并所有文件 // 合并所有文件
let allFiles = [...mainFiles]; let allFiles = [...mainFiles];
// 如果附件文件存在,则合并
if (attachmentFiles.length > 0) {
allFiles = [...allFiles, ...attachmentFiles];
}
// 如果模板文件存在,则合并
if (templateFiles.length > 0) {
allFiles = [...allFiles, ...templateFiles];
}
// console.log('【调试-checkAndPrepareUpload】合并文件后总数:', allFiles.length); // console.log('【调试-checkAndPrepareUpload】合并文件后总数:', allFiles.length);
// 检查组件是否已卸载 // 检查组件是否已卸载