fix(kb_utils): 从 content_hashes 映射中获取 content_hash,添加缺失时的异常处理 #486

This commit is contained in:
Wenjie Zhang 2026-01-20 13:05:44 +08:00
parent c587091cbd
commit 08573a6de4
2 changed files with 48 additions and 47 deletions

View File

@ -218,10 +218,13 @@ async def prepare_item_metadata(item: str, content_type: str, db_id: str, params
file_type = filename.split(".")[-1].lower() if "." in filename else "" file_type = filename.split(".")[-1].lower() if "." in filename else ""
item_path = item # 保持MinIO URL作为路径 item_path = item # 保持MinIO URL作为路径
# 从URL或params中获取content_hash如果有的话 # 从 content_hashes 映射中获取 content_hash
content_hash = None content_hash = None
if params and "content_hash" in params: if params and "content_hashes" in params and isinstance(params["content_hashes"], dict):
content_hash = params["content_hash"] content_hash = params["content_hashes"].get(item)
if not content_hash:
raise ValueError(f"Missing content_hash for file: {item}")
else: else:
# 本地文件处理 # 本地文件处理

View File

@ -714,12 +714,11 @@ const customRequest = async (options) => {
onError(e) onError(e)
} }
} else { } else {
try { const errorResp = JSON.parse(xhr.responseText)
const errorResp = JSON.parse(xhr.responseText) // file.response handleFileUpload
onError(new Error(errorResp.detail || 'Upload failed')) file.response = errorResp
} catch (e) { const error = new Error(errorResp.detail || 'Upload failed')
onError(new Error(xhr.responseText || 'Upload failed')) onError(error, file)
}
} }
} }
@ -732,15 +731,20 @@ const customRequest = async (options) => {
const handleFileUpload = (info) => { const handleFileUpload = (info) => {
if (info?.file?.status === 'error') { if (info?.file?.status === 'error') {
const errorMessage = info.file?.response?.detail || `文件上传失败:${info.file.name}` const file = info.file
message.error(errorMessage) //
const detail = file?.response?.detail || file?.error?.message || ''
if (detail.includes('same content') || detail.includes('相同内容')) {
message.error(`${file.name} 已是相同内容文件,无需重复上传`)
} else {
message.error(detail || `文件上传失败:${file.name}`)
}
} }
// //
if (info?.file?.status === 'done' && info.file.response) { if (info?.file?.status === 'done' && info.file.response) {
const response = info.file.response const response = info.file.response
if (response.has_same_name && response.same_name_files && response.same_name_files.length > 0) { if (response.has_same_name && response.same_name_files && response.same_name_files.length > 0) {
//
showSameNameFilesInUploadArea(response.same_name_files) showSameNameFilesInUploadArea(response.same_name_files)
} }
} }
@ -791,67 +795,61 @@ const chunkData = async () => {
return return
} }
let success = false const imageExtensions = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.tif']
const files = fileList.value
.filter((file) => file.status === 'done') //
.map((file) => file.response?.file_path) const items = []
// undefined null const content_hashes = {}
const validFiles = files.filter((file) => file) for (const file of fileList.value) {
if (validFiles.length === 0) { if (file.status !== 'done') continue
message.error('请先上传文件') const file_path = file.response?.file_path
return const content_hash = file.response?.content_hash
if (!file_path) continue
items.push(file_path)
if (content_hash) content_hashes[file_path] = content_hash
// OCR
const ext = file_path.substring(file_path.lastIndexOf('.')).toLowerCase()
if (imageExtensions.includes(ext) && chunkParams.value.enable_ocr === 'disable') {
message.error({
content: '检测到图片文件,必须启用 OCR 才能提取文本内容。',
duration: 5
})
return
}
} }
// OCR if (items.length === 0) {
const imageExtensions = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.tif'] message.error('请先上传文件')
const hasImageFiles = validFiles.some((filePath) => {
const ext = filePath.substring(filePath.lastIndexOf('.')).toLowerCase()
return imageExtensions.includes(ext)
})
if (hasImageFiles && chunkParams.value.enable_ocr === 'disable') {
message.error({
content:
'检测到图片文件,必须启用 OCR 才能提取文本内容。请在上方选择 OCR 方式 (RapidOCR/MinerU/MinerU Official/PP-StructureV3) 或移除图片文件。',
duration: 5
})
return return
} }
try { try {
store.state.chunkLoading = true store.state.chunkLoading = true
// const params = { ...chunkParams.value, content_hashes }
const params = { ...chunkParams.value }
if (autoIndex.value) { if (autoIndex.value) {
params.auto_index = true params.auto_index = true
Object.assign(params, indexParams.value) Object.assign(params, indexParams.value)
} }
// store addFiles
await store.addFiles({ await store.addFiles({
items: validFiles, items,
contentType: 'file', contentType: 'file',
params, params,
parentId: selectedFolderId.value // ID parentId: selectedFolderId.value
}) })
emit('success') emit('success')
handleCancel() handleCancel()
fileList.value = [] fileList.value = []
sameNameFiles.value = [] sameNameFiles.value = []
success = true
} catch (error) { } catch (error) {
console.error('文件上传失败:', error) console.error('文件上传失败:', error)
message.error('文件上传失败: ' + (error.message || '未知错误')) message.error('文件上传失败: ' + (error.message || '未知错误'))
} finally { } finally {
store.state.chunkLoading = false store.state.chunkLoading = false
} }
if (success) {
emit('update:visible', false)
emit('success')
fileList.value = []
sameNameFiles.value = [] //
}
} }
</script> </script>