diff --git a/src/assets/images/agent-setting/setting-success.gif b/src/assets/images/agent-setting/setting-success.gif new file mode 100644 index 0000000..52e1412 Binary files /dev/null and b/src/assets/images/agent-setting/setting-success.gif differ diff --git a/src/assets/styles/pages/agent.scss b/src/assets/styles/pages/agent.scss index 4cba009..284c37a 100644 --- a/src/assets/styles/pages/agent.scss +++ b/src/assets/styles/pages/agent.scss @@ -1156,7 +1156,6 @@ // 完成页占位图标 &__complete-icon { - width: 1.2rem; height: 1.2rem; margin-bottom: 0.32rem; diff --git a/src/assets/styles/pages/jobs.scss b/src/assets/styles/pages/jobs.scss index ac797f7..530a346 100644 --- a/src/assets/styles/pages/jobs.scss +++ b/src/assets/styles/pages/jobs.scss @@ -1157,3 +1157,109 @@ } } } + +// ==================== 简历快照抽屉 ==================== + +/* 遮罩层 */ +.jobs-resume-drawer-mask { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: var(--app-height, 100vh); + background: rgba(0, 0, 0, 0.3); + z-index: 2000; + display: flex; + justify-content: flex-end; +} + +/* 抽屉主体 */ +.jobs-resume-drawer { + width: 9.6rem; + max-width: 9.6rem; + height: var(--app-height, 100vh); + background: $bg-white; + display: flex; + flex-direction: column; + font-size: 0.14rem; + box-shadow: -4px 0 20px rgba(0, 0, 0, 0.08); + + /* 顶部标题栏 */ + &__header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.2rem 0.24rem; + height: 0.64rem; + box-sizing: border-box; + border-bottom: 1px solid $border-color; + } + + &__header-left { + display: flex; + align-items: center; + gap: 0.16rem; + } + + /* 关闭按钮 */ + &__close { + width: 0.24rem; + height: 0.24rem; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + } + + &__close-icon { + width: 0.24rem; + height: 0.24rem; + color: $text-middle; + } + + /* 标题文字 */ + &__title { + font-size: 0.18rem; + font-weight: 520; + color: $text-dark; + line-height: 0.24rem; + } + + /* 加载状态 */ + &__loading { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 1rem 0; + gap: 0.12rem; + color: $text-light; + font-size: 0.13rem; + } + + /* 内容区域(可滚动) */ + &__body { + flex: 1; + overflow-y: auto; + padding: 0.24rem; + } +} + +/* 抽屉动画 */ +.jobs-resume-drawer-enter-active, +.jobs-resume-drawer-leave-active { + transition: opacity 0.3s ease; + + .jobs-resume-drawer { + transition: transform 0.3s ease; + } +} + +.jobs-resume-drawer-enter-from, +.jobs-resume-drawer-leave-to { + opacity: 0; + + .jobs-resume-drawer { + transform: translateX(100%); + } +} diff --git a/src/components/AgentSetupWizard.vue b/src/components/AgentSetupWizard.vue index a8a2b8b..d614f69 100644 --- a/src/components/AgentSetupWizard.vue +++ b/src/components/AgentSetupWizard.vue @@ -345,7 +345,9 @@ @@ -347,13 +378,15 @@ import JobCategorySelector from '@/components/tools/JobCategorySelector.vue' import RegionSelector from '@/components/tools/RegionSelector.vue' -import { fetchJobList, fetchFavoriteList, toggleJobFavorite, removeJobFavorite, fetchFavoriteCount, fetchApplyList, fetchApplyCount, removeJobFromList } from '@/api/jobs' +import { fetchJobList, fetchFavoriteList, toggleJobFavorite, removeJobFavorite, fetchFavoriteCount, fetchApplyList, fetchApplyCount, removeJobFromList, fetchCustomizeResume } from '@/api/jobs' import type { JobListItem, JobListParams, FavoriteListParams, ApplyListParams, ApplyCountData } from '@/api/jobs' import { getTimeEvent, setTimeEvent, timestampToLocalDateTime } from '@/utils/time' import { fetchIndustryTree, fetchJobCategoryTree } from '@/api/common' import type { IndustryItem, JobCategoryItem } from '@/api/common' import { fetchAgentConfig, applyJob } from '@/api/agent' import { ElMessage } from 'element-plus' +import JobResumeTemplate from '@/components/JobResumeTemplate.vue' +import type { ResumeTemplateData } from '@/components/JobResumeTemplate.vue' // 2. 注意:这里的字符串不需要再手动转义双引号了 @@ -1524,4 +1557,99 @@ function openFeedbackDialog(job: JobItem) { feedbackDialogRef.value?.resetForm() showFeedbackDialog.value = true } + +// ==================== 简历快照抽屉 ==================== + +/** 简历快照抽屉是否显示 */ +const showResumeSnapshotDrawer = ref(false) + +/** 简历快照加载状态 */ +const resumeSnapshotLoading = ref(false) + +/** 简历快照数据 */ +const resumeSnapshotData = ref(null) + +/** 学历文字转数字 */ +function degreeToNumber(degree?: string): number { + const map: Record = { '大专': 1, '本科': 2, '硕士': 3, '博士': 4 } + return map[degree || ''] || 2 +} + +/** 将匹配度接口返回的简历数据映射为 ResumeTemplateData */ +function mapResumeToTemplate(data: any): ResumeTemplateData { + const r = data.resume || {} + return { + name: r.name || '未填写姓名', + email: r.email || '', + mobileNumber: r.mobileNumber || '', + wechatNumber: r.wechatNumber || '', + summary: r.summary || '', + educations: (data.education || []).map((e: any) => ({ + school: e.school || '', + major: e.major || '', + degree: degreeToNumber(e.degree), + startDate: e.startDate || '', + endDate: e.endDate || '', + description: (e.description || []).map((d: any) => ({ id: d.id, text: d.text || '' })), + })), + workExperiences: (data.work || []).map((w: any) => ({ + companyName: w.companyName || '', + position: w.position || '', + startDate: w.startDate || '', + endDate: w.endDate || '', + description: (w.description || []).map((d: any) => ({ id: d.id, text: d.text || '' })), + })), + internships: (data.internship || []).map((i: any) => ({ + companyName: i.companyName || '', + position: i.position || '', + startDate: i.startDate || '', + endDate: i.endDate || '', + description: (i.description || []).map((d: any) => ({ id: d.id, text: d.text || '' })), + })), + projects: (data.project || []).map((p: any) => ({ + projectName: p.projectName || '', + companyName: p.companyName || '', + role: p.role || '', + startDate: p.startDate || '', + endDate: p.endDate || '', + description: (p.description || []).map((d: any) => ({ id: d.id, text: d.text || '' })), + })), + competitions: (data.competition || []).map((c: any) => ({ + competitionName: c.competitionName || '', + award: c.award || '', + awardDate: c.awardDate || '', + description: (c.description || []).map((d: any) => ({ id: d.id, text: d.text || '' })), + })), + skills: r.skills || [], + certificates: r.certificates || [], + } +} + +/** 点击查看简历快照按钮 */ +async function handleViewResumeSnapshot(job: JobItem) { + showResumeSnapshotDrawer.value = true + resumeSnapshotLoading.value = true + resumeSnapshotData.value = null + try { + const res = await fetchCustomizeResume(String(job.id)) + if (res.code === 0 && res.data) { + resumeSnapshotData.value = mapResumeToTemplate(res.data) + } else { + ElMessage.error('获取简历快照失败') + showResumeSnapshotDrawer.value = false + } + } catch (e) { + console.error('获取简历快照失败', e) + ElMessage.error('获取简历快照失败') + showResumeSnapshotDrawer.value = false + } finally { + resumeSnapshotLoading.value = false + } +} + +/** 关闭简历快照抽屉 */ +function closeResumeSnapshotDrawer() { + showResumeSnapshotDrawer.value = false + resumeSnapshotData.value = null +}