优化业务逻辑和基础库的大标题区间和字段的识别精度
This commit is contained in:
@@ -865,6 +865,28 @@ export async function handleAutoFillCommon(params: AutoFillCommonParams): Promis
|
||||
const allTitles = getAllPageTitles(sectionResults)
|
||||
const FIVE_EXP_SECTIONS_JSON = new Set(["education", "work", "internship", "project", "competition"])
|
||||
|
||||
// 从简历数据中提取所有值,构建排除集合(避免将已填值误认为标签)
|
||||
const excludeTexts = new Set<string>()
|
||||
if (currentResumeData) {
|
||||
const main = currentResumeData.main
|
||||
if (main) {
|
||||
for (const val of Object.values(main)) {
|
||||
if (typeof val === "string" && val.trim()) excludeTexts.add(val.trim())
|
||||
if (Array.isArray(val)) val.forEach((v) => { if (typeof v === "string" && v.trim()) excludeTexts.add(v.trim()) })
|
||||
}
|
||||
}
|
||||
const expKeys: ("education" | "work" | "internship" | "project" | "competition")[] = ["education", "work", "internship", "project", "competition"]
|
||||
for (const sec of expKeys) {
|
||||
const items = currentResumeData[sec]
|
||||
if (!Array.isArray(items)) continue
|
||||
for (const item of items) {
|
||||
for (const val of Object.values(item as Record<string, any>)) {
|
||||
if (typeof val === "string" && val.trim()) excludeTexts.add(val.trim())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 判断某个字段是否属于简历数据格式(JOB_FORM_LABELS 里 resumeField 非空的) */
|
||||
const resumeFormatInputs = new Set<Element>()
|
||||
// 阶段A和B的所有 input 都是简历格式字段
|
||||
@@ -928,6 +950,17 @@ export async function handleAutoFillCommon(params: AutoFillCommonParams): Promis
|
||||
type FieldItem = { label: string; value: string; inputEl: Element }
|
||||
const collectedFields: FieldItem[] = []
|
||||
|
||||
// 构建当前大标题范围内所有已填 input 的值集合
|
||||
// 用于排除误将已填值(如"香港理工大学"、"硕士"、"2026"等)当作标签的情况
|
||||
const filledInputValues = new Set<string>()
|
||||
for (const inp of Array.from(allInputs)) {
|
||||
const afterT = !!(titleEl.compareDocumentPosition(inp) & Node.DOCUMENT_POSITION_FOLLOWING)
|
||||
const beforeN = !nextTitleEl || !!(nextTitleEl.compareDocumentPosition(inp) & Node.DOCUMENT_POSITION_PRECEDING)
|
||||
if (!afterT || !beforeN) continue
|
||||
const val = (inp as HTMLInputElement | HTMLTextAreaElement).value?.trim()
|
||||
if (val) filledInputValues.add(val)
|
||||
}
|
||||
|
||||
for (const inp of Array.from(allInputs)) {
|
||||
// 范围检查
|
||||
const afterTitle = !!(titleEl.compareDocumentPosition(inp) & Node.DOCUMENT_POSITION_FOLLOWING)
|
||||
@@ -946,8 +979,12 @@ export async function handleAutoFillCommon(params: AutoFillCommonParams): Promis
|
||||
|
||||
// 查找标签(使用统一封装的 labelFinder)
|
||||
const titleElementSet = new Set<Element>(allTitles.map((t) => t.element))
|
||||
const { labelText: detectedLabel } = findLabelForInput(inp, titleElementSet)
|
||||
const labelText = detectedLabel
|
||||
const { labelText: detectedLabel } = findLabelForInput(inp, titleElementSet, excludeTexts)
|
||||
const labelText = detectedLabel?.trim()
|
||||
|
||||
// 跳过无效标签:空、纯数字、已知排除词、或检测到的"标签"实际是某个已填 input 的值
|
||||
if (!labelText || /^\d+$/.test(labelText) || JSON_EXCLUDE_LABELS.some((ex) => labelText === ex)) continue
|
||||
if (filledInputValues.has(labelText)) continue
|
||||
|
||||
// 非经历类型:跳过简历格式字段
|
||||
// 【注意】简历格式字段通过 resumeFormatInputs(阶段A/B实际匹配到的input元素集合)精确跳过
|
||||
|
||||
Reference in New Issue
Block a user