AI助手和Nova助手
This commit is contained in:
+309
-101
@@ -69,7 +69,7 @@
|
||||
<div class="resume-detail__score-bar">
|
||||
<div class="resume-detail__score-left">
|
||||
<!-- 评级 -->
|
||||
<span class="resume-detail__score-avatar">
|
||||
<span v-if="hasDiagnosis" class="resume-detail__score-avatar">
|
||||
{{ diagnosisReport.grade }}
|
||||
</span>
|
||||
<!-- 有诊断报告时显示评级和查看链接 -->
|
||||
@@ -82,15 +82,18 @@
|
||||
<!-- 有诊断报告时显示三项计数和重新诊断按钮 -->
|
||||
<template v-if="hasDiagnosis">
|
||||
<div class="resume-detail__score-item">
|
||||
<span class="resume-detail__score-num">{{ diagnosisReport.urgentTotal || 0 }}</span>
|
||||
<!-- 从 issues 中 status===0 的子项汇总(report 数据修复后未更新,暂不使用 diagnosisReport.urgentTotal) -->
|
||||
<span class="resume-detail__score-num">{{ issuesUrgentTotal }}</span>
|
||||
<span class="resume-detail__score-label">紧急修复</span>
|
||||
</div>
|
||||
<div class="resume-detail__score-item">
|
||||
<span class="resume-detail__score-num">{{ diagnosisReport.importantTotal || 0 }}</span>
|
||||
<!-- 从 issues 中 status===0 的子项汇总(report 数据修复后未更新,暂不使用 diagnosisReport.importantTotal) -->
|
||||
<span class="resume-detail__score-num">{{ issuesImportantTotal }}</span>
|
||||
<span class="resume-detail__score-label">重点优化</span>
|
||||
</div>
|
||||
<div class="resume-detail__score-item">
|
||||
<span class="resume-detail__score-num">{{ diagnosisReport.expressionTotal || 0 }}</span>
|
||||
<!-- 从 issues 中 status===0 的子项汇总(report 数据修复后未更新,暂不使用 diagnosisReport.expressionTotal) -->
|
||||
<span class="resume-detail__score-num">{{ issuesExpressionTotal }}</span>
|
||||
<span class="resume-detail__score-label">表达提升</span>
|
||||
</div>
|
||||
<button class="resume-detail__diagnose-btn" @click="handleDiagnose">重新诊断</button>
|
||||
@@ -189,7 +192,7 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- 教育背景 -->
|
||||
<!-- 教育背景经历 -->
|
||||
<div v-if="educationList.length" class="resume-detail__card">
|
||||
<div class="resume-detail__section-header">
|
||||
<h3 class="resume-detail__section-title">教育背景</h3>
|
||||
@@ -414,11 +417,22 @@ import {
|
||||
fetchResumeDiagnosis,
|
||||
triggerResumeDiagnosis,
|
||||
saveResumeMain,
|
||||
saveResumeEducation,
|
||||
saveResumeWork,
|
||||
saveResumeInternship,
|
||||
saveResumeProject,
|
||||
saveResumeCompetition,
|
||||
addResumeEducation,
|
||||
updateResumeEducation,
|
||||
deleteResumeEducation,
|
||||
addResumeWork,
|
||||
updateResumeWork,
|
||||
deleteResumeWork,
|
||||
addResumeInternship,
|
||||
updateResumeInternship,
|
||||
deleteResumeInternship,
|
||||
addResumeProject,
|
||||
updateResumeProject,
|
||||
deleteResumeProject,
|
||||
addResumeCompetition,
|
||||
updateResumeCompetition,
|
||||
deleteResumeCompetition,
|
||||
deleteResume,
|
||||
type ResumeMainData,
|
||||
type ResumeEducation,
|
||||
type ResumeWork,
|
||||
@@ -450,6 +464,36 @@ const gradeLabel = computed(() => {
|
||||
return map[diagnosisReport.value.grade || ''] || '未评级'
|
||||
})
|
||||
|
||||
/**
|
||||
* 从 issues 中 status===0 的子项汇总紧急修复数
|
||||
* (report 数据修复后未实时更新,暂用 issues 汇总代替 diagnosisReport.urgentTotal,等后面接口改了用回来)
|
||||
*/
|
||||
const issuesUrgentTotal = computed(() => {
|
||||
return diagnosisIssues.value
|
||||
.filter(i => i.status === 0)
|
||||
.reduce((sum, i) => sum + sumSubCounts(i.urgentIssues), 0)
|
||||
})
|
||||
|
||||
/**
|
||||
* 从 issues 中 status===0 的子项汇总重点优化数
|
||||
* (report 数据修复后未实时更新,暂用 issues 汇总代替 diagnosisReport.importantTotal,等后面接口改了用回来)
|
||||
*/
|
||||
const issuesImportantTotal = computed(() => {
|
||||
return diagnosisIssues.value
|
||||
.filter(i => i.status === 0)
|
||||
.reduce((sum, i) => sum + sumSubCounts(i.importantIssues), 0)
|
||||
})
|
||||
|
||||
/**
|
||||
* 从 issues 中 status===0 的子项汇总表达提升数
|
||||
* (report 数据修复后未实时更新,暂用 issues 汇总代替 diagnosisReport.expressionTotal,等后面接口改了用回来)
|
||||
*/
|
||||
const issuesExpressionTotal = computed(() => {
|
||||
return diagnosisIssues.value
|
||||
.filter(i => i.status === 0)
|
||||
.reduce((sum, i) => sum + sumSubCounts(i.expressionIssues), 0)
|
||||
})
|
||||
|
||||
/** 每个子经历的问题操作区当前选中类型,key 为 "moduleType_recordId" */
|
||||
const issueActiveTypes = reactive<Record<string, IssueType>>({})
|
||||
|
||||
@@ -458,11 +502,37 @@ function getIssuesByModule(moduleType: string): DiagnosisIssue[] {
|
||||
return diagnosisIssues.value.filter(i => i.moduleType === moduleType)
|
||||
}
|
||||
|
||||
/** 根据模块类型和记录 ID 获取对应的 issue */
|
||||
/** 根据模块类型和列表索引获取对应的 issue(用于 ID 不匹配的模块) */
|
||||
function getIssueByIndex(moduleType: string, index: number): DiagnosisIssue | undefined {
|
||||
return getIssuesByModule(moduleType)[index]
|
||||
}
|
||||
|
||||
/** 根据模块类型和记录 ID 获取对应的 issue(备用,后端 ID 修复后可恢复使用) */
|
||||
function getIssueByRecord(moduleType: string, recordId: string): DiagnosisIssue | undefined {
|
||||
return diagnosisIssues.value.find(i => i.moduleType === moduleType && i.moduleRecordId === recordId)
|
||||
}
|
||||
|
||||
/** 根据模块类型和记录 ID 获取对应的 issue — 当前因后端 ID 不一致,内部走索引匹配 */
|
||||
// function getIssueByRecord(moduleType: string, recordId: string): DiagnosisIssue | undefined {
|
||||
// // 个人概述用 resumeId 匹配
|
||||
// if (moduleType === 'summary') {
|
||||
// return diagnosisIssues.value.find(i => i.moduleType === 'summary')
|
||||
// }
|
||||
// // 其他经历模块:根据列表索引匹配(后端 moduleRecordId 与经历 id 不一致的临时方案)
|
||||
// const listMap: Record<string, any[]> = {
|
||||
// education: educationList.value,
|
||||
// work: workList.value,
|
||||
// internship: internshipList.value,
|
||||
// project: projectList.value,
|
||||
// competition: competitionList.value,
|
||||
// }
|
||||
// const list = listMap[moduleType]
|
||||
// if (!list) return undefined
|
||||
// const idx = list.findIndex((item: any) => item.id === recordId)
|
||||
// if (idx === -1) return undefined
|
||||
// return getIssueByIndex(moduleType, idx)
|
||||
// }
|
||||
|
||||
/** 计算单个 issue 的子类型计数,将 urgentIssues/importantIssues/expressionIssues 的 value 求和 */
|
||||
function sumSubCounts(obj?: Record<string, number>): number {
|
||||
if (!obj) return 0
|
||||
@@ -614,8 +684,30 @@ function handleEdit() { console.log('编辑简历信息') }
|
||||
/** 导出简历 */
|
||||
function handleExport() { console.log('导出') }
|
||||
|
||||
/** 删除简历 */
|
||||
function handleDelete() { console.log('删除') }
|
||||
/** 删除简历 — 二次确认后调用删除接口,成功后返回简历列表 */
|
||||
async function handleDelete() {
|
||||
try {
|
||||
await ElMessageBox.confirm('确定要删除这份简历吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
// 调用删除接口
|
||||
const res = await deleteResume(resumeId)
|
||||
if (res.code === '0') {
|
||||
ElMessage.success('删除成功')
|
||||
// 返回简历列表页
|
||||
router.push('/resume')
|
||||
} else {
|
||||
ElMessage.error(res.msg || '删除失败')
|
||||
}
|
||||
} catch (error) {
|
||||
// 用户取消删除或接口报错
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('删除失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 查看评估报告 */
|
||||
function handleViewReport() {
|
||||
@@ -741,8 +833,8 @@ async function handleFixSubmit(content: string[]) {
|
||||
record.description[idx].text = text
|
||||
}
|
||||
})
|
||||
// 调用对应模块的保存接口(全量覆盖)
|
||||
await saveModuleData(moduleType)
|
||||
// 调用对应模块的单条编辑接口(仅更新当前这条经历)
|
||||
await updateSingleRecord(moduleType, record)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -757,50 +849,55 @@ async function handleFixSubmit(content: string[]) {
|
||||
}
|
||||
}
|
||||
|
||||
/** 根据模块类型调用对应的保存接口(全量覆盖) */
|
||||
async function saveModuleData(moduleType: string) {
|
||||
/** 根据模块类型调用对应的单条编辑接口(问题修复场景,只更新一条经历的内容) */
|
||||
async function updateSingleRecord(moduleType: string, record: any) {
|
||||
if (moduleType === 'education') {
|
||||
await saveResumeEducation(resumeId, educationList.value.map(edu => ({
|
||||
school: edu.school,
|
||||
major: edu.major,
|
||||
degree: edu.degree,
|
||||
studyType: edu.studyType,
|
||||
startDate: edu.startDate,
|
||||
endDate: edu.endDate,
|
||||
description: edu.description,
|
||||
})))
|
||||
await updateResumeEducation({
|
||||
id: record.id,
|
||||
school: record.school,
|
||||
major: record.major,
|
||||
degree: record.degree,
|
||||
studyType: record.studyType,
|
||||
startDate: record.startDate,
|
||||
endDate: record.endDate,
|
||||
description: record.description,
|
||||
})
|
||||
} else if (moduleType === 'work') {
|
||||
await saveResumeWork(resumeId, workList.value.map(w => ({
|
||||
companyName: w.companyName,
|
||||
position: w.position,
|
||||
startDate: w.startDate,
|
||||
endDate: w.endDate,
|
||||
description: w.description,
|
||||
})))
|
||||
await updateResumeWork({
|
||||
id: record.id,
|
||||
companyName: record.companyName,
|
||||
position: record.position,
|
||||
startDate: record.startDate,
|
||||
endDate: record.endDate,
|
||||
description: record.description,
|
||||
})
|
||||
} else if (moduleType === 'internship') {
|
||||
await saveResumeInternship(resumeId, internshipList.value.map(i => ({
|
||||
companyName: i.companyName,
|
||||
position: i.position,
|
||||
startDate: i.startDate,
|
||||
endDate: i.endDate,
|
||||
description: i.description,
|
||||
})))
|
||||
await updateResumeInternship({
|
||||
id: record.id,
|
||||
companyName: record.companyName,
|
||||
position: record.position,
|
||||
startDate: record.startDate,
|
||||
endDate: record.endDate,
|
||||
description: record.description,
|
||||
})
|
||||
} else if (moduleType === 'project') {
|
||||
await saveResumeProject(resumeId, projectList.value.map(p => ({
|
||||
projectName: p.projectName,
|
||||
companyName: p.companyName,
|
||||
role: p.role,
|
||||
startDate: p.startDate,
|
||||
endDate: p.endDate,
|
||||
description: p.description,
|
||||
})))
|
||||
await updateResumeProject({
|
||||
id: record.id,
|
||||
projectName: record.projectName,
|
||||
companyName: record.companyName,
|
||||
role: record.role,
|
||||
startDate: record.startDate,
|
||||
endDate: record.endDate,
|
||||
description: record.description,
|
||||
})
|
||||
} else if (moduleType === 'competition') {
|
||||
await saveResumeCompetition(resumeId, competitionList.value.map(c => ({
|
||||
competitionName: c.competitionName,
|
||||
award: c.award,
|
||||
awardDate: c.awardDate,
|
||||
description: c.description,
|
||||
})))
|
||||
await updateResumeCompetition({
|
||||
id: record.id,
|
||||
competitionName: record.competitionName,
|
||||
award: record.award,
|
||||
awardDate: record.awardDate,
|
||||
description: record.description,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -815,6 +912,21 @@ const editModule = ref('info')
|
||||
/** 当前编辑模块的初始数据 */
|
||||
const editInitialData = ref<Record<string, any>>({})
|
||||
|
||||
/** 打开编辑抽屉时记录的教育经历ID快照,用于保存时做增删改diff */
|
||||
const editSnapshotEducationIds = ref<string[]>([])
|
||||
|
||||
/** 打开编辑抽屉时记录的工作经历ID快照 */
|
||||
const editSnapshotWorkIds = ref<string[]>([])
|
||||
|
||||
/** 打开编辑抽屉时记录的实习经历ID快照 */
|
||||
const editSnapshotInternshipIds = ref<string[]>([])
|
||||
|
||||
/** 打开编辑抽屉时记录的项目经历ID快照 */
|
||||
const editSnapshotProjectIds = ref<string[]>([])
|
||||
|
||||
/** 打开编辑抽屉时记录的竞赛经历ID快照 */
|
||||
const editSnapshotCompetitionIds = ref<string[]>([])
|
||||
|
||||
/** 打开编辑抽屉 — 根据模块名设置初始数据 */
|
||||
function openEditDrawer(section: string) {
|
||||
editModule.value = section
|
||||
@@ -832,8 +944,11 @@ function openEditDrawer(section: string) {
|
||||
summary: resumeMain.value.summary || '',
|
||||
}
|
||||
} else if (section === 'education') {
|
||||
// 记录当前教育经历的ID快照,用于保存时做增删改diff
|
||||
editSnapshotEducationIds.value = educationList.value.map(edu => edu.id || '').filter(Boolean)
|
||||
editInitialData.value = {
|
||||
education: educationList.value.map(edu => ({
|
||||
id: edu.id,
|
||||
school: edu.school || '',
|
||||
major: edu.major || '',
|
||||
studyType: edu.studyType || '全日制',
|
||||
@@ -844,8 +959,11 @@ function openEditDrawer(section: string) {
|
||||
})),
|
||||
}
|
||||
} else if (section === 'work') {
|
||||
// 记录当前工作经历的ID快照
|
||||
editSnapshotWorkIds.value = workList.value.map(w => w.id || '').filter(Boolean)
|
||||
editInitialData.value = {
|
||||
works: workList.value.map(w => ({
|
||||
id: w.id,
|
||||
companyName: w.companyName || '',
|
||||
position: w.position || '',
|
||||
startDate: w.startDate || '',
|
||||
@@ -854,8 +972,11 @@ function openEditDrawer(section: string) {
|
||||
})),
|
||||
}
|
||||
} else if (section === 'internship') {
|
||||
// 记录当前实习经历的ID快照
|
||||
editSnapshotInternshipIds.value = internshipList.value.map(i => i.id || '').filter(Boolean)
|
||||
editInitialData.value = {
|
||||
internships: internshipList.value.map(i => ({
|
||||
id: i.id,
|
||||
companyName: i.companyName || '',
|
||||
position: i.position || '',
|
||||
startDate: i.startDate || '',
|
||||
@@ -864,8 +985,11 @@ function openEditDrawer(section: string) {
|
||||
})),
|
||||
}
|
||||
} else if (section === 'project') {
|
||||
// 记录当前项目经历的ID快照
|
||||
editSnapshotProjectIds.value = projectList.value.map(p => p.id || '').filter(Boolean)
|
||||
editInitialData.value = {
|
||||
projects: projectList.value.map(p => ({
|
||||
id: p.id,
|
||||
projectName: p.projectName || '',
|
||||
companyName: p.companyName || '',
|
||||
role: p.role || '',
|
||||
@@ -875,8 +999,11 @@ function openEditDrawer(section: string) {
|
||||
})),
|
||||
}
|
||||
} else if (section === 'competition') {
|
||||
// 记录当前竞赛经历的ID快照
|
||||
editSnapshotCompetitionIds.value = competitionList.value.map(c => c.id || '').filter(Boolean)
|
||||
editInitialData.value = {
|
||||
competitions: competitionList.value.map(c => ({
|
||||
id: c.id,
|
||||
competitionName: c.competitionName || '',
|
||||
award: c.award || '',
|
||||
awardDate: c.awardDate || '',
|
||||
@@ -926,57 +1053,135 @@ async function handleSaveEdit(data: Record<string, any>) {
|
||||
})
|
||||
resumeMain.value.summary = data.summary
|
||||
} else if (editModule.value === 'education') {
|
||||
// 保存教育经历
|
||||
await saveResumeEducation(resumeId, data.education.map((edu: any) => ({
|
||||
school: edu.school,
|
||||
major: edu.major,
|
||||
degree: edu.degree,
|
||||
studyType: edu.studyType,
|
||||
startDate: edu.startDate,
|
||||
endDate: edu.endDate,
|
||||
description: edu.description,
|
||||
})))
|
||||
educationList.value = data.education.map((edu: any) => ({ ...edu, description: edu.description.map((d: any) => ({ ...d })) }))
|
||||
// 教育经历 — 通过diff对比打开编辑时的ID快照,分别调用增/改/删接口
|
||||
const oldIds = new Set(editSnapshotEducationIds.value)
|
||||
const newItems: any[] = data.education
|
||||
const newIds = new Set(newItems.filter((edu: any) => edu.id).map((edu: any) => edu.id))
|
||||
|
||||
// 1. 找出被删除的经历(旧ID中有,新数据中没有的)
|
||||
const deletedIds = editSnapshotEducationIds.value.filter(id => !newIds.has(id))
|
||||
// 2. 遍历新数据,有id且在旧快照中存在的是编辑,没有id的是新增
|
||||
const addPromises: Promise<any>[] = []
|
||||
const updatePromises: Promise<any>[] = []
|
||||
const deletePromises = deletedIds.map(id => deleteResumeEducation(id))
|
||||
|
||||
for (const edu of newItems) {
|
||||
const itemData = {
|
||||
school: edu.school,
|
||||
major: edu.major,
|
||||
degree: edu.degree,
|
||||
studyType: edu.studyType,
|
||||
startDate: edu.startDate,
|
||||
endDate: edu.endDate,
|
||||
description: edu.description,
|
||||
}
|
||||
if (edu.id && oldIds.has(edu.id)) {
|
||||
// 已有经历 — 调用编辑接口
|
||||
updatePromises.push(updateResumeEducation({ ...itemData, id: edu.id }))
|
||||
} else {
|
||||
// 新增经历 — 调用添加接口
|
||||
addPromises.push(addResumeEducation(resumeId, itemData))
|
||||
}
|
||||
}
|
||||
|
||||
// 并发执行所有增删改请求
|
||||
await Promise.all([...addPromises, ...updatePromises, ...deletePromises])
|
||||
} else if (editModule.value === 'work') {
|
||||
// 保存工作经历
|
||||
await saveResumeWork(resumeId, data.works.map((w: any) => ({
|
||||
companyName: w.companyName,
|
||||
position: w.position,
|
||||
startDate: w.startDate,
|
||||
endDate: w.endDate,
|
||||
description: w.description,
|
||||
})))
|
||||
workList.value = data.works.map((w: any) => ({ ...w, description: w.description.map((d: any) => ({ ...d })) }))
|
||||
// 工作经历 — diff增删改
|
||||
const oldIds = new Set(editSnapshotWorkIds.value)
|
||||
const newItems: any[] = data.works
|
||||
const newIds = new Set(newItems.filter((w: any) => w.id).map((w: any) => w.id))
|
||||
const deletedIds = editSnapshotWorkIds.value.filter(id => !newIds.has(id))
|
||||
const addPromises: Promise<any>[] = []
|
||||
const updatePromises: Promise<any>[] = []
|
||||
const deletePromises = deletedIds.map(id => deleteResumeWork(id))
|
||||
for (const w of newItems) {
|
||||
const itemData = {
|
||||
companyName: w.companyName,
|
||||
position: w.position,
|
||||
startDate: w.startDate,
|
||||
endDate: w.endDate,
|
||||
description: w.description,
|
||||
}
|
||||
if (w.id && oldIds.has(w.id)) {
|
||||
updatePromises.push(updateResumeWork({ ...itemData, id: w.id }))
|
||||
} else {
|
||||
addPromises.push(addResumeWork(resumeId, itemData))
|
||||
}
|
||||
}
|
||||
await Promise.all([...addPromises, ...updatePromises, ...deletePromises])
|
||||
} else if (editModule.value === 'internship') {
|
||||
// 保存实习经历
|
||||
await saveResumeInternship(resumeId, data.internships.map((i: any) => ({
|
||||
companyName: i.companyName,
|
||||
position: i.position,
|
||||
startDate: i.startDate,
|
||||
endDate: i.endDate,
|
||||
description: i.description,
|
||||
})))
|
||||
internshipList.value = data.internships.map((i: any) => ({ ...i, description: i.description.map((d: any) => ({ ...d })) }))
|
||||
// 实习经历 — diff增删改
|
||||
const oldIds = new Set(editSnapshotInternshipIds.value)
|
||||
const newItems: any[] = data.internships
|
||||
const newIds = new Set(newItems.filter((i: any) => i.id).map((i: any) => i.id))
|
||||
const deletedIds = editSnapshotInternshipIds.value.filter(id => !newIds.has(id))
|
||||
const addPromises: Promise<any>[] = []
|
||||
const updatePromises: Promise<any>[] = []
|
||||
const deletePromises = deletedIds.map(id => deleteResumeInternship(id))
|
||||
for (const i of newItems) {
|
||||
const itemData = {
|
||||
companyName: i.companyName,
|
||||
position: i.position,
|
||||
startDate: i.startDate,
|
||||
endDate: i.endDate,
|
||||
description: i.description,
|
||||
}
|
||||
if (i.id && oldIds.has(i.id)) {
|
||||
updatePromises.push(updateResumeInternship({ ...itemData, id: i.id }))
|
||||
} else {
|
||||
addPromises.push(addResumeInternship(resumeId, itemData))
|
||||
}
|
||||
}
|
||||
await Promise.all([...addPromises, ...updatePromises, ...deletePromises])
|
||||
} else if (editModule.value === 'project') {
|
||||
// 保存项目经历
|
||||
await saveResumeProject(resumeId, data.projects.map((p: any) => ({
|
||||
projectName: p.projectName,
|
||||
companyName: p.companyName,
|
||||
role: p.role,
|
||||
startDate: p.startDate,
|
||||
endDate: p.endDate,
|
||||
description: p.description,
|
||||
})))
|
||||
projectList.value = data.projects.map((p: any) => ({ ...p, description: p.description.map((d: any) => ({ ...d })) }))
|
||||
// 项目经历 — diff增删改
|
||||
const oldIds = new Set(editSnapshotProjectIds.value)
|
||||
const newItems: any[] = data.projects
|
||||
const newIds = new Set(newItems.filter((p: any) => p.id).map((p: any) => p.id))
|
||||
const deletedIds = editSnapshotProjectIds.value.filter(id => !newIds.has(id))
|
||||
const addPromises: Promise<any>[] = []
|
||||
const updatePromises: Promise<any>[] = []
|
||||
const deletePromises = deletedIds.map(id => deleteResumeProject(id))
|
||||
for (const p of newItems) {
|
||||
const itemData = {
|
||||
projectName: p.projectName,
|
||||
companyName: p.companyName,
|
||||
role: p.role,
|
||||
startDate: p.startDate,
|
||||
endDate: p.endDate,
|
||||
description: p.description,
|
||||
}
|
||||
if (p.id && oldIds.has(p.id)) {
|
||||
updatePromises.push(updateResumeProject({ ...itemData, id: p.id }))
|
||||
} else {
|
||||
addPromises.push(addResumeProject(resumeId, itemData))
|
||||
}
|
||||
}
|
||||
await Promise.all([...addPromises, ...updatePromises, ...deletePromises])
|
||||
} else if (editModule.value === 'competition') {
|
||||
// 保存竞赛经历
|
||||
await saveResumeCompetition(resumeId, data.competitions.map((c: any) => ({
|
||||
competitionName: c.competitionName,
|
||||
award: c.award,
|
||||
awardDate: c.awardDate,
|
||||
description: c.description,
|
||||
})))
|
||||
competitionList.value = data.competitions.map((c: any) => ({ ...c, description: c.description.map((d: any) => ({ ...d })) }))
|
||||
// 竞赛经历 — diff增删改
|
||||
const oldIds = new Set(editSnapshotCompetitionIds.value)
|
||||
const newItems: any[] = data.competitions
|
||||
const newIds = new Set(newItems.filter((c: any) => c.id).map((c: any) => c.id))
|
||||
const deletedIds = editSnapshotCompetitionIds.value.filter(id => !newIds.has(id))
|
||||
const addPromises: Promise<any>[] = []
|
||||
const updatePromises: Promise<any>[] = []
|
||||
const deletePromises = deletedIds.map(id => deleteResumeCompetition(id))
|
||||
for (const c of newItems) {
|
||||
const itemData = {
|
||||
competitionName: c.competitionName,
|
||||
award: c.award,
|
||||
awardDate: c.awardDate,
|
||||
description: c.description,
|
||||
}
|
||||
if (c.id && oldIds.has(c.id)) {
|
||||
updatePromises.push(updateResumeCompetition({ ...itemData, id: c.id }))
|
||||
} else {
|
||||
addPromises.push(addResumeCompetition(resumeId, itemData))
|
||||
}
|
||||
}
|
||||
await Promise.all([...addPromises, ...updatePromises, ...deletePromises])
|
||||
} else if (editModule.value === 'portfolio') {
|
||||
// 保存作品集链接到简历主表
|
||||
await saveResumeMain({
|
||||
@@ -999,6 +1204,9 @@ async function handleSaveEdit(data: Record<string, any>) {
|
||||
})
|
||||
resumeMain.value.certificates = [...data.certificates]
|
||||
}
|
||||
|
||||
// 保存成功后重新加载简历数据,确保 ID 等字段与服务端一致
|
||||
await loadResumeDetail()
|
||||
} catch {
|
||||
console.error('[ResumeDetail] 保存失败')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user