502 lines
23 KiB
Vue
502 lines
23 KiB
Vue
<template>
|
||
<!-- 简历HTML模板组件:用于预览和后续导出PDF/Word -->
|
||
<div class="job-resume-template" ref="resumeRef">
|
||
<div class="resume-html" :class="{ 'resume-html--export': props.mode === 'export' }">
|
||
<!-- 姓名 -->
|
||
<h1 class="resume-html__name">
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffText(oldResumeData?.name, resumeData.name)" :key="'name-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span>
|
||
<template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ resumeData.name }}</template>
|
||
</h1>
|
||
|
||
<!-- 联系方式 -->
|
||
<div class="resume-html__contact">
|
||
<span v-if="resumeData.email">邮箱:{{ resumeData.email }}</span>
|
||
<div class="resume-html__contact-row">
|
||
<span v-if="resumeData.mobileNumber">手机:{{ resumeData.mobileNumber }}</span>
|
||
<span v-if="resumeData.wechatNumber" class="resume-html__separator">丨</span>
|
||
<span v-if="resumeData.wechatNumber">微信号:{{ resumeData.wechatNumber }}</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 个人概述 -->
|
||
<template v-if="resumeData.summary">
|
||
<div class="resume-html__section-title">个人概述</div>
|
||
<div class="resume-html__divider"></div>
|
||
<div class="resume-html__summary" :class="{ 'resume-html__diff-block': isSummaryDiffBlock() }">
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffText(oldResumeData?.summary, resumeData.summary)" :key="'sum-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span>
|
||
<template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ resumeData.summary }}</template>
|
||
</div>
|
||
</template>
|
||
|
||
<!-- 教育背景 -->
|
||
<template v-if="resumeData.educations && resumeData.educations.length">
|
||
<div class="resume-html__section-title">教育背景</div>
|
||
<div class="resume-html__divider"></div>
|
||
<div v-for="(edu, idx) in resumeData.educations" :key="'edu-' + idx" class="resume-html__item" :class="{ 'resume-html__diff-block': isEduDiffBlock(idx) }">
|
||
<div class="resume-html__item-header">
|
||
<span class="resume-html__item-main">
|
||
<!-- 教育经历标题差异对比 -->
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffText(
|
||
oldResumeData?.educations?.[idx] ? (oldResumeData.educations[idx].school + ',' + oldResumeData.educations[idx].major + ',' + degreeText(oldResumeData.educations[idx].degree)) : '',
|
||
edu.school + ',' + edu.major + ',' + degreeText(edu.degree)
|
||
)" :key="'eduh-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span><template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ edu.school }},{{ edu.major }},{{ degreeText(edu.degree) }}</template>
|
||
</span>
|
||
<div class="resume-html__item-right">
|
||
<span class="resume-html__item-location" v-if="edu.location">{{ edu.location }}</span>
|
||
<span class="resume-html__item-date">{{ edu.startDate }} — {{ edu.endDate || '至今' }}</span>
|
||
</div>
|
||
</div>
|
||
<!-- 教育经历描述独立一行,避免被header的flex布局挤压 -->
|
||
<div v-if="edu.description && edu.description.length" class="resume-html__item-desc">
|
||
<template v-if="showDiff">
|
||
主修课程:<template v-for="(desc, di) in edu.description" :key="'ed-' + di"><template v-if="di > 0">、</template><template v-for="(seg, si) in diffDescText(oldResumeData?.educations, idx, di, desc.text)" :key="'eds-' + si"><span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span><template v-else>{{ seg.text }}</template></template></template>等;
|
||
</template>
|
||
<template v-else>
|
||
主修课程:{{ edu.description.map(d => d.text).join('、') }}等;
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<!-- 工作经历 -->
|
||
<template v-if="resumeData.workExperiences && resumeData.workExperiences.length">
|
||
<div class="resume-html__section-title">工作经历</div>
|
||
<div class="resume-html__divider"></div>
|
||
<div v-for="(work, idx) in resumeData.workExperiences" :key="'work-' + idx" class="resume-html__item" :class="{ 'resume-html__diff-block': isWorkDiffBlock(idx) }">
|
||
<div class="resume-html__item-header">
|
||
<span class="resume-html__item-main">
|
||
<!-- 工作经历标题差异对比 -->
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffText(
|
||
oldResumeData?.workExperiences?.[idx] ? (oldResumeData.workExperiences[idx].companyName + ',' + oldResumeData.workExperiences[idx].position) : '',
|
||
work.companyName + ',' + work.position
|
||
)" :key="'workh-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span><template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ work.companyName }},{{ work.position }}</template>
|
||
</span>
|
||
<div class="resume-html__item-right">
|
||
<span class="resume-html__item-location" v-if="work.location">{{ work.location }}</span>
|
||
<span class="resume-html__item-date">{{ work.startDate }} — {{ work.endDate || '至今' }}</span>
|
||
</div>
|
||
</div>
|
||
<ul v-if="work.description && work.description.length" class="resume-html__desc-list">
|
||
<li v-for="(desc, di) in work.description" :key="'wd-' + di">
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffListText(oldResumeData?.workExperiences, idx, di, desc.text)" :key="'wds-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span>
|
||
<template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ desc.text }}</template>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</template>
|
||
|
||
<!-- 实习经历 -->
|
||
<template v-if="resumeData.internships && resumeData.internships.length">
|
||
<div class="resume-html__section-title">实习经历</div>
|
||
<div class="resume-html__divider"></div>
|
||
<div v-for="(intern, idx) in resumeData.internships" :key="'intern-' + idx" class="resume-html__item" :class="{ 'resume-html__diff-block': isInternDiffBlock(idx) }">
|
||
<div class="resume-html__item-header">
|
||
<span class="resume-html__item-main">
|
||
<!-- 实习经历标题差异对比 -->
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffText(
|
||
oldResumeData?.internships?.[idx] ? (oldResumeData.internships[idx].companyName + ',' + oldResumeData.internships[idx].position) : '',
|
||
intern.companyName + ',' + intern.position
|
||
)" :key="'internh-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span><template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ intern.companyName }},{{ intern.position }}</template>
|
||
</span>
|
||
<div class="resume-html__item-right">
|
||
<span class="resume-html__item-location" v-if="intern.location">{{ intern.location }}</span>
|
||
<span class="resume-html__item-date">{{ intern.startDate }} — {{ intern.endDate || '至今' }}</span>
|
||
</div>
|
||
</div>
|
||
<ul v-if="intern.description && intern.description.length" class="resume-html__desc-list">
|
||
<li v-for="(desc, di) in intern.description" :key="'id-' + di">
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffListText(oldResumeData?.internships, idx, di, desc.text)" :key="'ids-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span>
|
||
<template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ desc.text }}</template>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</template>
|
||
|
||
<!-- 项目经历 -->
|
||
<template v-if="resumeData.projects && resumeData.projects.length">
|
||
<div class="resume-html__section-title">项目经历</div>
|
||
<div class="resume-html__divider"></div>
|
||
<div v-for="(proj, idx) in resumeData.projects" :key="'proj-' + idx" class="resume-html__item" :class="{ 'resume-html__diff-block': isProjDiffBlock(idx) }">
|
||
<div class="resume-html__item-header">
|
||
<span class="resume-html__item-main">
|
||
<!-- 项目经历标题差异对比 -->
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffText(
|
||
oldResumeData?.projects?.[idx] ? (oldResumeData.projects[idx].projectName + (oldResumeData.projects[idx].role ? ',' + oldResumeData.projects[idx].role : '')) : '',
|
||
proj.projectName + (proj.role ? ',' + proj.role : '')
|
||
)" :key="'projh-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span><template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ proj.projectName }}{{ proj.role ? ',' + proj.role : '' }}</template>
|
||
</span>
|
||
<div class="resume-html__item-right">
|
||
<span class="resume-html__item-location" v-if="proj.companyName">
|
||
<!-- 项目所属公司差异对比 -->
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffText(getOldFieldText(oldResumeData?.projects, idx, 'companyName'), proj.companyName)" :key="'projc-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span><template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ proj.companyName }}</template>
|
||
</span>
|
||
<span class="resume-html__item-date">{{ proj.startDate }} — {{ proj.endDate || '至今' }}</span>
|
||
</div>
|
||
</div>
|
||
<ul v-if="proj.description && proj.description.length" class="resume-html__desc-list">
|
||
<li v-for="(desc, di) in proj.description" :key="'pd-' + di">
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffListText(oldResumeData?.projects, idx, di, desc.text, 'projects')" :key="'pds-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span>
|
||
<template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ desc.text }}</template>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</template>
|
||
|
||
<!-- 竞赛/获奖经历 -->
|
||
<template v-if="resumeData.competitions && resumeData.competitions.length">
|
||
<div class="resume-html__section-title">获奖经历</div>
|
||
<div class="resume-html__divider"></div>
|
||
<div v-for="(comp, idx) in resumeData.competitions" :key="'comp-' + idx" class="resume-html__item" :class="{ 'resume-html__diff-block': isCompDiffBlock(idx) }">
|
||
<div class="resume-html__item-header">
|
||
<span class="resume-html__item-main">
|
||
<!-- 竞赛经历标题差异对比 -->
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffText(
|
||
oldResumeData?.competitions?.[idx] ? (oldResumeData.competitions[idx].competitionName + (oldResumeData.competitions[idx].award ? ',' + oldResumeData.competitions[idx].award : '')) : '',
|
||
comp.competitionName + (comp.award ? ',' + comp.award : '')
|
||
)" :key="'comph-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span><template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ comp.competitionName }}{{ comp.award ? ',' + comp.award : '' }}</template>
|
||
</span>
|
||
<span class="resume-html__item-date" v-if="comp.awardDate">{{ comp.awardDate }}</span>
|
||
</div>
|
||
<ul v-if="comp.description && comp.description.length" class="resume-html__desc-list">
|
||
<li v-for="(desc, di) in comp.description" :key="'cd-' + di">
|
||
<template v-if="showDiff">
|
||
<template v-for="(seg, si) in diffListText(oldResumeData?.competitions, idx, di, desc.text, 'competitions')" :key="'cds-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span>
|
||
<template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</template>
|
||
<template v-else>{{ desc.text }}</template>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</template>
|
||
|
||
<!-- 专业技能 -->
|
||
<template v-if="hasSkillsSection">
|
||
<div class="resume-html__section-title">专业技能</div>
|
||
<div class="resume-html__divider"></div>
|
||
<div class="resume-html__skills">
|
||
<div v-if="resumeData.skills && resumeData.skills.length" class="resume-html__skill-row">
|
||
<span class="resume-html__skill-label">技能:</span>
|
||
<template v-if="showDiff">
|
||
<span>
|
||
<template v-for="(seg, si) in diffText(oldResumeData?.skills?.join('、'), resumeData.skills.join('、'))" :key="'sk-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span>
|
||
<template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</span>
|
||
</template>
|
||
<span v-else>{{ resumeData.skills.join('、') }}</span>
|
||
</div>
|
||
<div v-if="resumeData.certificates && resumeData.certificates.length" class="resume-html__skill-row">
|
||
<span class="resume-html__skill-label">证书:</span>
|
||
<template v-if="showDiff">
|
||
<span>
|
||
<template v-for="(seg, si) in diffText(oldResumeData?.certificates?.join('、'), resumeData.certificates.join('、'))" :key="'ct-' + si">
|
||
<span v-if="seg.highlight" class="resume-html__diff-highlight">{{ seg.text }}</span>
|
||
<template v-else>{{ seg.text }}</template>
|
||
</template>
|
||
</span>
|
||
</template>
|
||
<span v-else>{{ resumeData.certificates.join('、') }}</span>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, computed } from 'vue'
|
||
import { computeDiff, type DiffSegment } from '@/utils/textDiff'
|
||
|
||
// ==================== 类型定义 ====================
|
||
|
||
/** 描述段落 */
|
||
interface DescParagraph {
|
||
id?: string
|
||
text: string
|
||
}
|
||
|
||
/** 教育经历 */
|
||
interface ResumeEducation {
|
||
school: string
|
||
major: string
|
||
degree: number
|
||
startDate: string
|
||
endDate: string
|
||
location?: string
|
||
description?: DescParagraph[]
|
||
}
|
||
|
||
/** 工作/实习经历 */
|
||
interface ResumeWork {
|
||
companyName: string
|
||
position: string
|
||
startDate: string
|
||
endDate?: string
|
||
location?: string
|
||
description?: DescParagraph[]
|
||
}
|
||
|
||
/** 项目经历 */
|
||
interface ResumeProject {
|
||
projectName: string
|
||
companyName?: string
|
||
role?: string
|
||
startDate: string
|
||
endDate?: string
|
||
description?: DescParagraph[]
|
||
}
|
||
|
||
/** 竞赛/获奖经历 */
|
||
interface ResumeCompetition {
|
||
competitionName: string
|
||
award?: string
|
||
awardDate?: string
|
||
description?: DescParagraph[]
|
||
}
|
||
|
||
/** 简历完整数据结构 */
|
||
export interface ResumeTemplateData {
|
||
/** 姓名 */
|
||
name: string
|
||
/** 邮箱 */
|
||
email?: string
|
||
/** 手机号 */
|
||
mobileNumber?: string
|
||
/** 微信号 */
|
||
wechatNumber?: string
|
||
/** 个人概述 */
|
||
summary?: string
|
||
/** 教育背景 */
|
||
educations?: ResumeEducation[]
|
||
/** 工作经历 */
|
||
workExperiences?: ResumeWork[]
|
||
/** 实习经历 */
|
||
internships?: ResumeWork[]
|
||
/** 项目经历 */
|
||
projects?: ResumeProject[]
|
||
/** 竞赛/获奖经历 */
|
||
competitions?: ResumeCompetition[]
|
||
/** 技能标签 */
|
||
skills?: string[]
|
||
/** 证书标签 */
|
||
certificates?: string[]
|
||
}
|
||
|
||
// ==================== Props ====================
|
||
|
||
const props = defineProps<{
|
||
/** 简历数据 */
|
||
resumeData: ResumeTemplateData
|
||
/** 是否显示差异对比模式,默认false显示普通模板 */
|
||
showDiff?: boolean
|
||
/** 旧简历数据(差异对比时使用,与resumeData对比) */
|
||
oldResumeData?: ResumeTemplateData
|
||
/** 模式:preview=预览(小padding),export=导出(大padding),默认preview */
|
||
mode?: 'preview' | 'export'
|
||
}>()
|
||
|
||
// ==================== DOM引用(供父组件获取HTML内容) ====================
|
||
|
||
const resumeRef = ref<HTMLElement>()
|
||
|
||
/** 暴露DOM引用,方便后续导出PDF/Word */
|
||
defineExpose({ resumeRef })
|
||
|
||
// ==================== 工具方法 ====================
|
||
|
||
/** 学历数字转文字 */
|
||
function degreeText(degree: number): string {
|
||
const map: Record<number, string> = { 1: '大专', 2: '本科', 3: '硕士', 4: '博士' }
|
||
return map[degree] || ''
|
||
}
|
||
|
||
/** 是否有技能相关内容 */
|
||
const hasSkillsSection = computed(() => {
|
||
return (props.resumeData.skills && props.resumeData.skills.length > 0) ||
|
||
(props.resumeData.certificates && props.resumeData.certificates.length > 0)
|
||
})
|
||
|
||
// ==================== 差异块背景判断方法 ====================
|
||
|
||
/** 个人概述是否有差异 */
|
||
function isSummaryDiffBlock(): boolean {
|
||
if (!props.showDiff || !props.oldResumeData) return false
|
||
return props.oldResumeData.summary !== props.resumeData.summary
|
||
}
|
||
|
||
/** 教育经历某项是否有差异 */
|
||
function isEduDiffBlock(idx: number): boolean {
|
||
if (!props.showDiff || !props.oldResumeData) return false
|
||
const oldEdu = props.oldResumeData.educations?.[idx]
|
||
const newEdu = props.resumeData.educations?.[idx]
|
||
if (!oldEdu || !newEdu) return true
|
||
if (oldEdu.school !== newEdu.school || oldEdu.major !== newEdu.major || oldEdu.degree !== newEdu.degree) return true
|
||
const oldDescs = oldEdu.description?.map(d => d.text).join('') || ''
|
||
const newDescs = newEdu.description?.map(d => d.text).join('') || ''
|
||
return oldDescs !== newDescs
|
||
}
|
||
|
||
/** 工作经历某项是否有差异 */
|
||
function isWorkDiffBlock(idx: number): boolean {
|
||
if (!props.showDiff || !props.oldResumeData) return false
|
||
const oldItem = props.oldResumeData.workExperiences?.[idx]
|
||
const newItem = props.resumeData.workExperiences?.[idx]
|
||
if (!oldItem || !newItem) return true
|
||
if (oldItem.companyName !== newItem.companyName || oldItem.position !== newItem.position) return true
|
||
const oldDescs = oldItem.description?.map(d => d.text).join('') || ''
|
||
const newDescs = newItem.description?.map(d => d.text).join('') || ''
|
||
return oldDescs !== newDescs
|
||
}
|
||
|
||
/** 实习经历某项是否有差异 */
|
||
function isInternDiffBlock(idx: number): boolean {
|
||
if (!props.showDiff || !props.oldResumeData) return false
|
||
const oldItem = props.oldResumeData.internships?.[idx]
|
||
const newItem = props.resumeData.internships?.[idx]
|
||
if (!oldItem || !newItem) return true
|
||
if (oldItem.companyName !== newItem.companyName || oldItem.position !== newItem.position) return true
|
||
const oldDescs = oldItem.description?.map(d => d.text).join('') || ''
|
||
const newDescs = newItem.description?.map(d => d.text).join('') || ''
|
||
return oldDescs !== newDescs
|
||
}
|
||
|
||
/** 项目经历某项是否有差异 */
|
||
function isProjDiffBlock(idx: number): boolean {
|
||
if (!props.showDiff || !props.oldResumeData) return false
|
||
const oldItem = props.oldResumeData.projects?.[idx]
|
||
const newItem = props.resumeData.projects?.[idx]
|
||
if (!oldItem || !newItem) return true
|
||
if (oldItem.projectName !== newItem.projectName || oldItem.role !== newItem.role || oldItem.companyName !== newItem.companyName) return true
|
||
const oldDescs = oldItem.description?.map(d => d.text).join('') || ''
|
||
const newDescs = newItem.description?.map(d => d.text).join('') || ''
|
||
return oldDescs !== newDescs
|
||
}
|
||
|
||
/** 竞赛经历某项是否有差异 */
|
||
function isCompDiffBlock(idx: number): boolean {
|
||
if (!props.showDiff || !props.oldResumeData) return false
|
||
const oldItem = props.oldResumeData.competitions?.[idx]
|
||
const newItem = props.resumeData.competitions?.[idx]
|
||
if (!oldItem || !newItem) return true
|
||
if (oldItem.competitionName !== newItem.competitionName || oldItem.award !== newItem.award) return true
|
||
const oldDescs = oldItem.description?.map(d => d.text).join('') || ''
|
||
const newDescs = newItem.description?.map(d => d.text).join('') || ''
|
||
return oldDescs !== newDescs
|
||
}
|
||
|
||
// ==================== 差异对比工具方法 ====================
|
||
|
||
/**
|
||
* 对比两段纯文本,返回差异片段数组
|
||
* @param oldText 旧文本
|
||
* @param newText 新文本
|
||
*/
|
||
function diffText(oldText?: string, newText?: string): DiffSegment[] {
|
||
if (!newText) return []
|
||
if (!oldText) return [{ text: newText, highlight: true }]
|
||
if (oldText === newText) return [{ text: newText, highlight: false }]
|
||
return computeDiff(oldText, newText)
|
||
}
|
||
|
||
/**
|
||
* 从旧数据列表中取出指定索引项的某个字段值
|
||
* @param oldList 旧数据列表
|
||
* @param itemIdx 项索引
|
||
* @param field 字段名
|
||
*/
|
||
function getOldFieldText(oldList: any[] | undefined, itemIdx: number, field: string): string {
|
||
if (!oldList || !oldList[itemIdx]) return ''
|
||
return oldList[itemIdx][field] || ''
|
||
}
|
||
|
||
/**
|
||
* 对比带description数组的经历列表中某一项描述文本的差异
|
||
* @param oldList 旧数据列表
|
||
* @param itemIdx 经历项索引
|
||
* @param descIdx 描述段落索引
|
||
* @param newText 新文本
|
||
*/
|
||
function diffListText(oldList: any[] | undefined, itemIdx: number, descIdx: number, newText: string, _type?: string): DiffSegment[] {
|
||
if (!oldList || !oldList[itemIdx] || !oldList[itemIdx].description || !oldList[itemIdx].description[descIdx]) {
|
||
return [{ text: newText, highlight: true }]
|
||
}
|
||
const oldText = oldList[itemIdx].description[descIdx].text || ''
|
||
if (oldText === newText) return [{ text: newText, highlight: false }]
|
||
return computeDiff(oldText, newText)
|
||
}
|
||
|
||
/**
|
||
* 对比教育经历描述文本的差异
|
||
* @param oldEducations 旧教育经历列表
|
||
* @param eduIdx 教育经历索引
|
||
* @param descIdx 描述段落索引
|
||
* @param newText 新文本
|
||
*/
|
||
function diffDescText(oldEducations: ResumeEducation[] | undefined, eduIdx: number, descIdx: number, newText: string): DiffSegment[] {
|
||
if (!oldEducations || !oldEducations[eduIdx] || !oldEducations[eduIdx].description || !oldEducations[eduIdx].description![descIdx]) {
|
||
return [{ text: newText, highlight: true }]
|
||
}
|
||
const oldText = oldEducations[eduIdx].description![descIdx].text || ''
|
||
if (oldText === newText) return [{ text: newText, highlight: false }]
|
||
return computeDiff(oldText, newText)
|
||
}
|
||
</script>
|