fix: 文件上传优化
This commit is contained in:
@@ -413,24 +413,49 @@ onChange(async (files) => {
|
||||
// 处理图片文件
|
||||
if (isImage) {
|
||||
try {
|
||||
// 先压缩图片
|
||||
const compressedBlob = await compressImage(file, 1024, 1024, 0.8);
|
||||
// 再转换为 base64
|
||||
const base64 = await blobToBase64(compressedBlob);
|
||||
// 多级压缩策略:逐步降低质量和分辨率
|
||||
const compressionLevels = [
|
||||
{ maxWidth: 800, maxHeight: 800, quality: 0.6 },
|
||||
{ maxWidth: 600, maxHeight: 600, quality: 0.5 },
|
||||
{ maxWidth: 400, maxHeight: 400, quality: 0.4 },
|
||||
];
|
||||
|
||||
// 检查总长度(base64 保守估计占用)
|
||||
const estimatedLength = Math.floor(base64.length * 0.5);
|
||||
if (totalContentLength + estimatedLength > MAX_TOTAL_CONTENT_LENGTH) {
|
||||
ElMessage.error(`添加 ${file.name} 会超过消息总长度限制(${MAX_TOTAL_CONTENT_LENGTH} 字符),已跳过`);
|
||||
continue;
|
||||
let compressedBlob: Blob | null = null;
|
||||
let base64 = '';
|
||||
let compressionLevel = 0;
|
||||
|
||||
// 尝试不同级别的压缩
|
||||
for (const level of compressionLevels) {
|
||||
compressionLevel++;
|
||||
compressedBlob = await compressImage(file, level.maxWidth, level.maxHeight, level.quality);
|
||||
base64 = await blobToBase64(compressedBlob);
|
||||
|
||||
// 检查是否满足总长度限制
|
||||
const estimatedLength = Math.floor(base64.length * 0.5);
|
||||
if (totalContentLength + estimatedLength <= MAX_TOTAL_CONTENT_LENGTH) {
|
||||
// 满足限制,使用当前压缩级别
|
||||
totalContentLength += estimatedLength;
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果是最后一级压缩仍然超限,则跳过
|
||||
if (compressionLevel === compressionLevels.length) {
|
||||
const fileSizeMB = (file.size / 1024 / 1024).toFixed(2);
|
||||
ElMessage.error(`${file.name} (${fileSizeMB}MB) 即使压缩后仍超过总内容限制,已跳过`);
|
||||
compressedBlob = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
totalContentLength += estimatedLength;
|
||||
// 如果压缩失败,跳过此文件
|
||||
if (!compressedBlob) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 计算压缩比例
|
||||
const originalSize = (file.size / 1024).toFixed(2);
|
||||
const compressedSize = (compressedBlob.size / 1024).toFixed(2);
|
||||
console.log(`图片压缩: ${file.name} - 原始: ${originalSize}KB, 压缩后: ${compressedSize}KB`);
|
||||
console.log(`图片压缩: ${file.name} - 原始: ${originalSize}KB, 压缩后: ${compressedSize}KB (级别${compressionLevel})`);
|
||||
|
||||
arr.push({
|
||||
uid: crypto.randomUUID(),
|
||||
@@ -458,13 +483,23 @@ onChange(async (files) => {
|
||||
try {
|
||||
const result = await parseExcel(file);
|
||||
|
||||
// 检查总长度
|
||||
if (totalContentLength + result.content.length > MAX_TOTAL_CONTENT_LENGTH) {
|
||||
ElMessage.error(`添加 ${file.name} 会超过消息总长度限制(${MAX_TOTAL_CONTENT_LENGTH} 字符),已跳过`);
|
||||
// 动态裁剪内容以适应剩余空间
|
||||
let finalContent = result.content;
|
||||
let wasTruncated = result.totalRows > MAX_EXCEL_ROWS;
|
||||
|
||||
// 如果超过总内容限制,裁剪内容
|
||||
const remainingSpace = MAX_TOTAL_CONTENT_LENGTH - totalContentLength;
|
||||
if (result.content.length > remainingSpace && remainingSpace > 1000) {
|
||||
// 至少保留1000字符才有意义
|
||||
finalContent = result.content.substring(0, remainingSpace);
|
||||
wasTruncated = true;
|
||||
} else if (remainingSpace <= 1000) {
|
||||
const fileSizeKB = (file.size / 1024).toFixed(2);
|
||||
ElMessage.error(`${file.name} (${fileSizeKB}KB) 会超过总内容限制,已跳过`);
|
||||
continue;
|
||||
}
|
||||
|
||||
totalContentLength += result.content.length;
|
||||
totalContentLength += finalContent.length;
|
||||
|
||||
arr.push({
|
||||
uid: crypto.randomUUID(),
|
||||
@@ -475,16 +510,17 @@ onChange(async (files) => {
|
||||
showDelIcon: true,
|
||||
imgPreview: false,
|
||||
isUploaded: true,
|
||||
fileContent: result.content,
|
||||
fileContent: finalContent,
|
||||
fileType: 'text',
|
||||
});
|
||||
|
||||
// 提示信息
|
||||
if (result.totalRows > MAX_EXCEL_ROWS) {
|
||||
ElMessage.warning(`${file.name} 共 ${result.totalRows} 行,已提取前 ${result.extractedRows} 行`);
|
||||
if (wasTruncated) {
|
||||
const fileSizeKB = (file.size / 1024).toFixed(2);
|
||||
ElMessage.warning(`${file.name} (${fileSizeKB}KB) 内容过大,已自动截取部分内容`);
|
||||
}
|
||||
|
||||
console.log(`Excel 解析: ${file.name} - 大小: ${(file.size / 1024).toFixed(2)}KB, 总行数: ${result.totalRows}, 已提取: ${result.extractedRows} 行, 内容长度: ${result.content.length} 字符`);
|
||||
console.log(`Excel 解析: ${file.name} - 大小: ${(file.size / 1024).toFixed(2)}KB, 总行数: ${result.totalRows}, 已提取: ${result.extractedRows} 行, 内容长度: ${finalContent.length} 字符`);
|
||||
}
|
||||
catch (error) {
|
||||
console.error('解析 Excel 失败:', error);
|
||||
@@ -497,13 +533,22 @@ onChange(async (files) => {
|
||||
try {
|
||||
const result = await parseWord(file);
|
||||
|
||||
// 检查总长度
|
||||
if (totalContentLength + result.content.length > MAX_TOTAL_CONTENT_LENGTH) {
|
||||
ElMessage.error(`添加 ${file.name} 会超过消息总长度限制(${MAX_TOTAL_CONTENT_LENGTH} 字符),已跳过`);
|
||||
// 动态裁剪内容以适应剩余空间
|
||||
let finalContent = result.content;
|
||||
let wasTruncated = result.extracted;
|
||||
|
||||
// 如果超过总内容限制,裁剪内容
|
||||
const remainingSpace = MAX_TOTAL_CONTENT_LENGTH - totalContentLength;
|
||||
if (result.content.length > remainingSpace && remainingSpace > 1000) {
|
||||
finalContent = result.content.substring(0, remainingSpace);
|
||||
wasTruncated = true;
|
||||
} else if (remainingSpace <= 1000) {
|
||||
const fileSizeKB = (file.size / 1024).toFixed(2);
|
||||
ElMessage.error(`${file.name} (${fileSizeKB}KB) 会超过总内容限制,已跳过`);
|
||||
continue;
|
||||
}
|
||||
|
||||
totalContentLength += result.content.length;
|
||||
totalContentLength += finalContent.length;
|
||||
|
||||
arr.push({
|
||||
uid: crypto.randomUUID(),
|
||||
@@ -514,16 +559,17 @@ onChange(async (files) => {
|
||||
showDelIcon: true,
|
||||
imgPreview: false,
|
||||
isUploaded: true,
|
||||
fileContent: result.content,
|
||||
fileContent: finalContent,
|
||||
fileType: 'text',
|
||||
});
|
||||
|
||||
// 提示信息
|
||||
if (result.extracted) {
|
||||
ElMessage.warning(`${file.name} 共 ${result.totalLength} 字符,已提取前 ${MAX_WORD_LENGTH} 字符`);
|
||||
if (wasTruncated) {
|
||||
const fileSizeKB = (file.size / 1024).toFixed(2);
|
||||
ElMessage.warning(`${file.name} (${fileSizeKB}KB) 内容过大,已自动截取部分内容`);
|
||||
}
|
||||
|
||||
console.log(`Word 解析: ${file.name} - 大小: ${(file.size / 1024).toFixed(2)}KB, 总长度: ${result.totalLength}, 已提取: ${result.content.length} 字符`);
|
||||
console.log(`Word 解析: ${file.name} - 大小: ${(file.size / 1024).toFixed(2)}KB, 总长度: ${result.totalLength}, 已提取: ${finalContent.length} 字符`);
|
||||
}
|
||||
catch (error) {
|
||||
console.error('解析 Word 失败:', error);
|
||||
@@ -536,13 +582,22 @@ onChange(async (files) => {
|
||||
try {
|
||||
const result = await parsePDF(file);
|
||||
|
||||
// 检查总长度
|
||||
if (totalContentLength + result.content.length > MAX_TOTAL_CONTENT_LENGTH) {
|
||||
ElMessage.error(`添加 ${file.name} 会超过消息总长度限制(${MAX_TOTAL_CONTENT_LENGTH} 字符),已跳过`);
|
||||
// 动态裁剪内容以适应剩余空间
|
||||
let finalContent = result.content;
|
||||
let wasTruncated = result.totalPages > MAX_PDF_PAGES;
|
||||
|
||||
// 如果超过总内容限制,裁剪内容
|
||||
const remainingSpace = MAX_TOTAL_CONTENT_LENGTH - totalContentLength;
|
||||
if (result.content.length > remainingSpace && remainingSpace > 1000) {
|
||||
finalContent = result.content.substring(0, remainingSpace);
|
||||
wasTruncated = true;
|
||||
} else if (remainingSpace <= 1000) {
|
||||
const fileSizeKB = (file.size / 1024).toFixed(2);
|
||||
ElMessage.error(`${file.name} (${fileSizeKB}KB) 会超过总内容限制,已跳过`);
|
||||
continue;
|
||||
}
|
||||
|
||||
totalContentLength += result.content.length;
|
||||
totalContentLength += finalContent.length;
|
||||
|
||||
arr.push({
|
||||
uid: crypto.randomUUID(),
|
||||
@@ -553,16 +608,17 @@ onChange(async (files) => {
|
||||
showDelIcon: true,
|
||||
imgPreview: false,
|
||||
isUploaded: true,
|
||||
fileContent: result.content,
|
||||
fileContent: finalContent,
|
||||
fileType: 'text',
|
||||
});
|
||||
|
||||
// 提示信息
|
||||
if (result.totalPages > MAX_PDF_PAGES) {
|
||||
ElMessage.warning(`${file.name} 共 ${result.totalPages} 页,已提取前 ${result.extractedPages} 页`);
|
||||
if (wasTruncated) {
|
||||
const fileSizeKB = (file.size / 1024).toFixed(2);
|
||||
ElMessage.warning(`${file.name} (${fileSizeKB}KB) 内容过大,已自动截取部分内容`);
|
||||
}
|
||||
|
||||
console.log(`PDF 解析: ${file.name} - 大小: ${(file.size / 1024).toFixed(2)}KB, 总页数: ${result.totalPages}, 已提取: ${result.extractedPages} 页, 内容长度: ${result.content.length} 字符`);
|
||||
console.log(`PDF 解析: ${file.name} - 大小: ${(file.size / 1024).toFixed(2)}KB, 总页数: ${result.totalPages}, 已提取: ${result.extractedPages} 页, 内容长度: ${finalContent.length} 字符`);
|
||||
}
|
||||
catch (error) {
|
||||
console.error('解析 PDF 失败:', error);
|
||||
@@ -584,9 +640,14 @@ onChange(async (files) => {
|
||||
truncated = true;
|
||||
}
|
||||
|
||||
// 检查总长度
|
||||
if (totalContentLength + finalContent.length > MAX_TOTAL_CONTENT_LENGTH) {
|
||||
ElMessage.error(`添加 ${file.name} 会超过消息总长度限制(${MAX_TOTAL_CONTENT_LENGTH} 字符),已跳过`);
|
||||
// 动态裁剪内容以适应剩余空间
|
||||
const remainingSpace = MAX_TOTAL_CONTENT_LENGTH - totalContentLength;
|
||||
if (finalContent.length > remainingSpace && remainingSpace > 1000) {
|
||||
finalContent = finalContent.substring(0, remainingSpace);
|
||||
truncated = true;
|
||||
} else if (remainingSpace <= 1000) {
|
||||
const fileSizeKB = (file.size / 1024).toFixed(2);
|
||||
ElMessage.error(`${file.name} (${fileSizeKB}KB) 会超过总内容限制,已跳过`);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -607,7 +668,8 @@ onChange(async (files) => {
|
||||
|
||||
// 提示信息
|
||||
if (truncated) {
|
||||
ElMessage.warning(`${file.name} 共 ${content.length} 字符,已提取前 ${MAX_TEXT_FILE_LENGTH} 字符`);
|
||||
const fileSizeKB = (file.size / 1024).toFixed(2);
|
||||
ElMessage.warning(`${file.name} (${fileSizeKB}KB) 内容过大,已自动截取部分内容`);
|
||||
}
|
||||
|
||||
console.log(`文本文件读取: ${file.name} - 大小: ${(file.size / 1024).toFixed(2)}KB, 内容长度: ${content.length} 字符`);
|
||||
@@ -627,7 +689,7 @@ onChange(async (files) => {
|
||||
|
||||
if (arr.length > 0) {
|
||||
filesStore.setFilesList([...filesStore.filesList, ...arr]);
|
||||
ElMessage.success(`已添加 ${arr.length} 个文件,当前总内容长度约 ${totalContentLength} 字符`);
|
||||
ElMessage.success(`已添加 ${arr.length} 个文件`);
|
||||
}
|
||||
|
||||
// 重置文件选择器
|
||||
|
||||
Reference in New Issue
Block a user