From d9a4a5f3e72f6d02bf3206fb9d95ced6717ead9e Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Fri, 18 Apr 2025 15:01:18 +0800 Subject: [PATCH] fix: mongodb file oversize (#4594) --- .../zh-cn/docs/development/upgrading/497.md | 1 + .../service/common/file/gridfs/controller.ts | 5 +- .../detail/Import/components/FileSelector.tsx | 81 +++++++++++-------- .../detail/Import/components/RenderFiles.tsx | 47 +++++++---- 4 files changed, 82 insertions(+), 52 deletions(-) diff --git a/docSite/content/zh-cn/docs/development/upgrading/497.md b/docSite/content/zh-cn/docs/development/upgrading/497.md index be5c6a332..fe3f65c97 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/497.md +++ b/docSite/content/zh-cn/docs/development/upgrading/497.md @@ -16,4 +16,5 @@ weight: 793 ## 🐛 修复 +1. 文件上传分块大小限制,避免超出 MongoDB 限制。 diff --git a/packages/service/common/file/gridfs/controller.ts b/packages/service/common/file/gridfs/controller.ts index f809cc772..36dd18c38 100644 --- a/packages/service/common/file/gridfs/controller.ts +++ b/packages/service/common/file/gridfs/controller.ts @@ -65,9 +65,10 @@ export async function uploadFile({ const bucket = getGridBucket(bucketName); const fileSize = stats.size; + // 单块大小:尽可能大,但不超过 14MB,不小于512KB const chunkSizeBytes = (() => { - // 计算理想块大小:文件大小 ÷ 目标块数(10) - const idealChunkSize = Math.ceil(fileSize / 10); + // 计算理想块大小:文件大小 ÷ 目标块数(10)。 并且每个块需要小于 14MB + const idealChunkSize = Math.min(Math.ceil(fileSize / 10), 14 * 1024 * 1024); // 确保块大小至少为512KB const minChunkSize = 512 * 1024; // 512KB diff --git a/projects/app/src/pageComponents/dataset/detail/Import/components/FileSelector.tsx b/projects/app/src/pageComponents/dataset/detail/Import/components/FileSelector.tsx index f758e63e7..a20415f69 100644 --- a/projects/app/src/pageComponents/dataset/detail/Import/components/FileSelector.tsx +++ b/projects/app/src/pageComponents/dataset/detail/Import/components/FileSelector.tsx @@ -16,6 +16,7 @@ import { ImportSourceItemType } from '@/web/core/dataset/type'; import { useI18n } from '@/web/context/I18n'; import { useContextSelector } from 'use-context-selector'; import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext'; +import { getErrText } from '@fastgpt/global/common/error/utils'; export type SelectFileItemType = { fileId: string; @@ -71,39 +72,53 @@ const FileSelector = ({ { await Promise.all( files.map(async ({ fileId, file }) => { - const { fileId: uploadFileId } = await uploadFile2DB({ - file, - bucketName: BucketNameEnum.dataset, - data: { - datasetId - }, - percentListen: (e) => { - setSelectFiles((state) => - state.map((item) => - item.id === fileId - ? { - ...item, - uploadedFileRate: item.uploadedFileRate - ? Math.max(e, item.uploadedFileRate) - : e - } - : item - ) - ); - } - }); - setSelectFiles((state) => - state.map((item) => - item.id === fileId - ? { - ...item, - dbFileId: uploadFileId, - isUploading: false, - uploadedFileRate: 100 - } - : item - ) - ); + try { + const { fileId: uploadFileId } = await uploadFile2DB({ + file, + bucketName: BucketNameEnum.dataset, + data: { + datasetId + }, + percentListen: (e) => { + setSelectFiles((state) => + state.map((item) => + item.id === fileId + ? { + ...item, + uploadedFileRate: item.uploadedFileRate + ? Math.max(e, item.uploadedFileRate) + : e + } + : item + ) + ); + } + }); + setSelectFiles((state) => + state.map((item) => + item.id === fileId + ? { + ...item, + dbFileId: uploadFileId, + isUploading: false, + uploadedFileRate: 100 + } + : item + ) + ); + } catch (error) { + setSelectFiles((state) => + state.map((item) => + item.id === fileId + ? { + ...item, + isUploading: false, + errorMsg: getErrText(error) + } + : item + ) + ); + } }) ); } diff --git a/projects/app/src/pageComponents/dataset/detail/Import/components/RenderFiles.tsx b/projects/app/src/pageComponents/dataset/detail/Import/components/RenderFiles.tsx index 86aae27cb..661a07671 100644 --- a/projects/app/src/pageComponents/dataset/detail/Import/components/RenderFiles.tsx +++ b/projects/app/src/pageComponents/dataset/detail/Import/components/RenderFiles.tsx @@ -9,12 +9,16 @@ import { Td, Tbody, Progress, - IconButton + IconButton, + Box } from '@chakra-ui/react'; import { ImportSourceItemType } from '@/web/core/dataset/type.d'; import MyIcon from '@fastgpt/web/components/common/Icon'; import { useTranslation } from 'next-i18next'; import { useI18n } from '@/web/context/I18n'; +import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; +import MyTag from '@fastgpt/web/components/common/Tag/index'; +import { QuestionOutlineIcon } from '@chakra-ui/icons'; export const RenderUploadFiles = ({ files, @@ -56,22 +60,31 @@ export const RenderUploadFiles = ({ - - = 100 ? 'green' : 'blue'} - bg="myGray.200" - hasStripe - isAnimated - mr={2} - /> - {`${item.uploadedFileRate}%`} - + {item.errorMsg ? ( + + + {t('common:common.Error')} + + + + ) : ( + + = 100 ? 'green' : 'blue'} + bg="myGray.200" + hasStripe + isAnimated + mr={2} + /> + {`${item.uploadedFileRate}%`} + + )} {item.sourceSize}