Commit 966bdc6a authored by 李文光's avatar 李文光

fix: 修复候选人简历上传 on-change 回调非 DOM 事件导致的报错

Element Plus el-upload 的 on-change 回调传的是 uploadFile 对象而非 DOM 事件,
原代码读取 event.target.files 会抛 TypeError。改为取 uploadFile.raw;
批量上传弹窗存在同类隐患,一并修复,并移除一个多余花括号的语法错误。
parent babbc4bc
...@@ -59,11 +59,12 @@ const setBatchSource = (source) => { ...@@ -59,11 +59,12 @@ const setBatchSource = (source) => {
store.candidateBatchSource = source store.candidateBatchSource = source
} }
const handleFiles = async (event) => { const handleFiles = async (uploadFile) => {
const files = [...(event.target.files || [])] const file = uploadFile.raw
if (!files.length) return if (!file || !store.candidateBatchOpen) return
const cacheOriginalFiles = files.reduce((total, file) => total + file.size, 0) <= 2 * 1024 * 1024 const totalSize = store.candidateBatchEntries.reduce((total, entry) => total + (entry.file?.size || 0), 0)
store.candidateBatchEntries = files.map((file) => ({ const cacheOriginalFiles = totalSize + file.size <= 2 * 1024 * 1024
const entry = {
id: uid('batch-resume'), id: uid('batch-resume'),
file, file,
status: 'parsing', status: 'parsing',
...@@ -75,47 +76,47 @@ const handleFiles = async (event) => { ...@@ -75,47 +76,47 @@ const handleFiles = async (event) => {
parseWarning: '', parseWarning: '',
resumeFileDataUrl: '', resumeFileDataUrl: '',
resumeFilePreviewWarning: '', resumeFilePreviewWarning: '',
})) }
store.candidateBatchEntries.push(entry)
store.candidateBatchParsing = true store.candidateBatchParsing = true
parsing.value = true parsing.value = true
event.target.value = ''
for (const entry of store.candidateBatchEntries) { try {
if (!store.candidateBatchOpen) break const parsed = await store.parseResumeFile(entry.file)
try { if (!store.candidateBatchOpen) return
const parsed = await store.parseResumeFile(entry.file) const suggestions = store.suggestJobs({
const suggestions = store.suggestJobs({ jobTitle: parsed.jobTitle || '',
jobTitle: parsed.jobTitle || '', resumeText: parsed.resumeText || '',
resumeText: parsed.resumeText || '', education: parsed.education || '',
education: parsed.education || '', school: parsed.school || '',
school: parsed.school || '', major: parsed.major || '',
major: parsed.major || '', schoolTags: parsed.schoolTags || [],
schoolTags: parsed.schoolTags || [], skills: parsed.skills || [],
skills: parsed.skills || [], })
}) entry.parsed = parsed
entry.parsed = parsed entry.suggestions = suggestions
entry.suggestions = suggestions entry.recommendedJobId = suggestions[0]?.jobId || ''
entry.recommendedJobId = suggestions[0]?.jobId || '' entry.parseWarning = parsed.parseWarning || ''
entry.parseWarning = parsed.parseWarning || '' entry.status = 'ready'
entry.status = 'ready' entry.jobId = store.candidateBatchMode === 'job' ? store.candidateBatchJobId : store.smartBatchJobId(entry)
entry.jobId = store.candidateBatchMode === 'job' ? store.candidateBatchJobId : store.smartBatchJobId(entry) if (cacheOriginalFiles && entry.file.size <= 2 * 1024 * 1024) {
if (cacheOriginalFiles && entry.file.size <= 2 * 1024 * 1024) { try {
try { entry.resumeFileDataUrl = await fileToDataUrl(entry.file)
entry.resumeFileDataUrl = await fileToDataUrl(entry.file) } catch (error) {
} catch (error) { entry.resumeFilePreviewWarning = error.message
entry.resumeFilePreviewWarning = error.message
}
} else {
entry.resumeFilePreviewWarning = '批次文件较大,仅保存解析结果,未缓存原文件预览。'
} }
} catch (error) { } else {
entry.status = 'error' entry.resumeFilePreviewWarning = '批次文件较大,仅保存解析结果,未缓存原文件预览。'
entry.error = error.message || '解析失败'
} }
} catch (error) {
entry.status = 'error'
entry.error = error.message || '解析失败'
} finally {
const stillParsing = store.candidateBatchEntries.some((item) => item.status === 'parsing')
store.candidateBatchParsing = stillParsing
parsing.value = stillParsing
if (!stillParsing) showToast('批量简历解析完成,请确认关联岗位')
} }
store.candidateBatchParsing = false
parsing.value = false
showToast('批量简历解析完成,请确认关联岗位')
} }
const removeEntry = (id) => { const removeEntry = (id) => {
......
...@@ -44,8 +44,8 @@ const close = () => { ...@@ -44,8 +44,8 @@ const close = () => {
store.candidateCreateDraft = null store.candidateCreateDraft = null
} }
const onFileChange = async (event) => { const onFileChange = async (uploadFile) => {
const file = event.target.files?.[0] const file = uploadFile.raw
if (!file) return if (!file) return
resumeFile.value = file resumeFile.value = file
parsing.value = true parsing.value = true
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment