From e54efdacee3f73f28fb2265efabe7eb546c51db5 Mon Sep 17 00:00:00 2001 From: liangxu Date: Fri, 8 May 2026 18:42:14 +0800 Subject: [PATCH] fix(knowledge): enforce upload type and size limits on client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Why: 添加知识库弹窗只在 hint 文案里写了「docx/pdf/txt/md/xls/xlsx,<=30M」, beforeUpload 没做校验,用户可以提交任意大小、任意格式的文件后再被后端拒绝。 现在前端按白名单扩展名 + 30MB 阈值拦截,并给 dragger 加 accept 让系统选择器 默认过滤非法格式。 Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/admin-web/src/views/KnowledgeView.vue | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/admin-web/src/views/KnowledgeView.vue b/apps/admin-web/src/views/KnowledgeView.vue index e5f4434..9aa44b6 100644 --- a/apps/admin-web/src/views/KnowledgeView.vue +++ b/apps/admin-web/src/views/KnowledgeView.vue @@ -21,6 +21,10 @@ type KnowledgeSourceType = 'document' | 'website' | 'text' type KnowledgeGroupLevel = 'root' | 'child' const MAX_WEBSITE_URLS = 3 const MAX_TEXT_NAME_LENGTH = 20 +const MAX_UPLOAD_SIZE_MB = 30 +const MAX_UPLOAD_SIZE_BYTES = MAX_UPLOAD_SIZE_MB * 1024 * 1024 +const ALLOWED_UPLOAD_EXTENSIONS = ['docx', 'pdf', 'txt', 'md', 'xls', 'xlsx'] as const +const UPLOAD_ACCEPT_ATTR = ALLOWED_UPLOAD_EXTENSIONS.map((ext) => `.${ext}`).join(',') interface TreeNode { title: string @@ -458,7 +462,19 @@ function handleTreeSelect(keys: (string | number)[]): void { } const beforeUpload: UploadProps['beforeUpload'] = (file) => { - uploadFiles.value.push(file as File) + const rawFile = file as File + const ext = rawFile.name.includes('.') + ? rawFile.name.slice(rawFile.name.lastIndexOf('.') + 1).toLowerCase() + : '' + if (!ALLOWED_UPLOAD_EXTENSIONS.includes(ext as (typeof ALLOWED_UPLOAD_EXTENSIONS)[number])) { + message.error(`「${rawFile.name}」格式不支持,仅支持 ${ALLOWED_UPLOAD_EXTENSIONS.join('、')}`) + return false + } + if (rawFile.size > MAX_UPLOAD_SIZE_BYTES) { + message.error(`「${rawFile.name}」超过 ${MAX_UPLOAD_SIZE_MB}MB 大小限制`) + return false + } + uploadFiles.value.push(rawFile) return false } @@ -718,6 +734,7 @@ function closeItemDetail(): void { :before-upload="beforeUpload" :file-list="uploadFiles" :multiple="true" + :accept="UPLOAD_ACCEPT_ATTR" class="custom-dragger" @remove="handleRemoveFile" >