fix(knowledge): enforce upload type and size limits on client

Why: 添加知识库弹窗只在 hint 文案里写了「docx/pdf/txt/md/xls/xlsx,<=30M」,
beforeUpload 没做校验,用户可以提交任意大小、任意格式的文件后再被后端拒绝。
现在前端按白名单扩展名 + 30MB 阈值拦截,并给 dragger 加 accept 让系统选择器
默认过滤非法格式。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 18:42:14 +08:00
parent 846a509c7d
commit e54efdacee
+18 -1
View File
@@ -21,6 +21,10 @@ type KnowledgeSourceType = 'document' | 'website' | 'text'
type KnowledgeGroupLevel = 'root' | 'child' type KnowledgeGroupLevel = 'root' | 'child'
const MAX_WEBSITE_URLS = 3 const MAX_WEBSITE_URLS = 3
const MAX_TEXT_NAME_LENGTH = 20 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 { interface TreeNode {
title: string title: string
@@ -458,7 +462,19 @@ function handleTreeSelect(keys: (string | number)[]): void {
} }
const beforeUpload: UploadProps['beforeUpload'] = (file) => { 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 return false
} }
@@ -718,6 +734,7 @@ function closeItemDetail(): void {
:before-upload="beforeUpload" :before-upload="beforeUpload"
:file-list="uploadFiles" :file-list="uploadFiles"
:multiple="true" :multiple="true"
:accept="UPLOAD_ACCEPT_ATTR"
class="custom-dragger" class="custom-dragger"
@remove="handleRemoveFile" @remove="handleRemoveFile"
> >