生成定制简历部分默认优化选项全选
This commit is contained in:
@@ -12,148 +12,168 @@
|
||||
</button>
|
||||
<h2 class="job-resume-custom-dialog__drawer-title">生成你的岗位专属简历</h2>
|
||||
</div>
|
||||
<!-- 返回按钮(步骤四显示) -->
|
||||
<button v-if="currentStep === 4" class="job-resume-custom-dialog__back-btn mt10" @click="goToStep(3)">返回</button>
|
||||
<!-- 下载简历按钮(步骤三显示,位于步骤指示器上方) -->
|
||||
<div v-if="currentStep === 4" class="job-resume-custom-dialog__top-download mt10">
|
||||
<button class="job-resume-custom-dialog__top-download-btn" @click="toggleDownloadMenu">
|
||||
<svg viewBox="0 0 16 16" fill="none" class="job-resume-custom-dialog__top-download-icon">
|
||||
<path d="M8 2v8M8 10l-3-3M8 10l3-3" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M3 12h10" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
下载简历
|
||||
</button>
|
||||
<!-- 下载下拉菜单 -->
|
||||
<div v-if="showDownloadMenu" class="job-resume-custom-dialog__top-download-menu">
|
||||
<button class="job-resume-custom-dialog__top-download-option" @click="handleDownload('pdf')">下载PDF</button>
|
||||
<button class="job-resume-custom-dialog__top-download-option" @click="handleDownload('word')">下载Word</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 步骤指示器 -->
|
||||
<div class="job-resume-custom-dialog__steps pt10">
|
||||
<div class="job-resume-custom-dialog__step" :class="{ 'job-resume-custom-dialog__step--active': currentStep === 2 }">
|
||||
<span class="job-resume-custom-dialog__step-num">1</span><span>差距分析</span>
|
||||
</div>
|
||||
<div class="job-resume-custom-dialog__step-line"></div>
|
||||
<div class="job-resume-custom-dialog__step" :class="{ 'job-resume-custom-dialog__step--active': currentStep === 3 }">
|
||||
<span class="job-resume-custom-dialog__step-num">2</span><span>定制简历</span>
|
||||
</div>
|
||||
<div class="job-resume-custom-dialog__step-line"></div>
|
||||
<div class="job-resume-custom-dialog__step" :class="{ 'job-resume-custom-dialog__step--active': currentStep === 4 }">
|
||||
<span class="job-resume-custom-dialog__step-num">3</span><span>简历预览</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 抽屉内容区(可滚动) -->
|
||||
<div class="job-resume-custom-dialog__drawer-body">
|
||||
<!-- 步骤二:差距分析 -->
|
||||
<!-- 步骤一:差距分析 -->
|
||||
<template v-if="currentStep === 2">
|
||||
<!-- 匹配度标题区域 -->
|
||||
<div class="job-resume-custom-dialog__gap-header">
|
||||
<div class="job-resume-custom-dialog__gap-left">
|
||||
<h3 class="job-resume-custom-dialog__gap-title">你的简历与该岗位的匹配度{{ isLowMatch ? '较低' : '较高' }}</h3>
|
||||
<div v-if="isLowMatch" class="job-resume-custom-dialog__gap-warn">
|
||||
<svg viewBox="0 0 16 16" fill="none" class="job-resume-custom-dialog__warn-icon"><circle cx="8" cy="8" r="7" stroke="currentColor" stroke-width="1.2"/><path d="M8 5v3M8 10.5v.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
|
||||
<span>匹配度低于 6.0 分的简历,在筛选环节可能会被优先淘汰。我们会帮你快速优化提升。</span>
|
||||
</div>
|
||||
<h3 class="job-resume-custom-dialog__gap-title">你的简历与该岗位的<span class="job-resume-custom-dialog__gap-title-highlight">匹配度{{ isLowMatch ? '较低' : '较高' }}</span></h3>
|
||||
<p class="job-resume-custom-dialog__gap-subtitle">匹配度低于 6.0 分的简历,在筛选环节可能会被优先淘汰。我们会帮你快速优化提升。</p>
|
||||
</div>
|
||||
<!-- 右侧匹配度分数 -->
|
||||
<div class="job-resume-custom-dialog__gap-score-area">
|
||||
<div class="job-resume-custom-dialog__match-ring">
|
||||
<svg viewBox="0 0 60 60" class="job-resume-custom-dialog__ring-svg"><circle cx="30" cy="30" r="24" stroke-width="4" stroke="#E8E8E8" fill="none" opacity="0.3"/><circle cx="30" cy="30" r="24" stroke-width="4" fill="none" stroke="#4FC2C9" stroke-linecap="round" :stroke-dasharray="2*Math.PI*24" :stroke-dashoffset="2*Math.PI*24*(1-jobInfo.matchScore/10)" transform="rotate(-90 30 30)"/></svg>
|
||||
<span class="job-resume-custom-dialog__match-score">{{ jobInfo.matchScore }}</span>
|
||||
<div class="job-resume-custom-dialog__score-circle">
|
||||
<svg viewBox="0 0 72 72" class="job-resume-custom-dialog__score-svg">
|
||||
<circle cx="36" cy="36" r="32" stroke-width="5" stroke="rgba(82,202,209,0.2)" fill="none"/>
|
||||
<circle cx="36" cy="36" r="32" stroke-width="5" fill="none" stroke="#52CAD1" stroke-linecap="round" :stroke-dasharray="2*Math.PI*32" :stroke-dashoffset="2*Math.PI*32*(1-jobInfo.matchScore/10)" transform="rotate(-90 36 36)"/>
|
||||
</svg>
|
||||
<span class="job-resume-custom-dialog__score-num">{{ jobInfo.matchScore }}</span>
|
||||
</div>
|
||||
<span class="job-resume-custom-dialog__match-label">{{ matchLevelText }}</span>
|
||||
<span class="job-resume-custom-dialog__score-tag">{{ matchLevelText }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 对比卡片表格 -->
|
||||
<div class="job-resume-custom-dialog__gap-table">
|
||||
<!-- 第一行:概览 -->
|
||||
<div class="job-resume-custom-dialog__gap-row">
|
||||
<!-- 标签列 -->
|
||||
<div class="job-resume-custom-dialog__gap-cell job-resume-custom-dialog__gap-cell--label">
|
||||
<span class="job-resume-custom-dialog__gap-cell-title">概览</span>
|
||||
</div>
|
||||
<!-- 岗位信息列 -->
|
||||
<div class="job-resume-custom-dialog__gap-cell">
|
||||
<div class="job-resume-custom-dialog__gap-job-info">
|
||||
<div class="job-resume-custom-dialog__gap-company-icon">
|
||||
<img v-if="jobInfo.companyLogoUrl" :src="jobInfo.companyLogoUrl" :alt="jobInfo.company" class="job-resume-custom-dialog__gap-company-logo" />
|
||||
<svg v-else viewBox="0 0 24 24" fill="none" class="job-resume-custom-dialog__gap-company-svg"><rect x="3" y="3" width="7" height="7" rx="1" stroke="currentColor" stroke-width="1.2"/><rect x="14" y="3" width="7" height="7" rx="1" stroke="currentColor" stroke-width="1.2"/><rect x="3" y="14" width="7" height="7" rx="1" stroke="currentColor" stroke-width="1.2"/><rect x="14" y="14" width="7" height="7" rx="1" stroke="currentColor" stroke-width="1.2"/></svg>
|
||||
</div>
|
||||
<div class="job-resume-custom-dialog__gap-job-text">
|
||||
<span class="job-resume-custom-dialog__gap-job-title">{{ jobInfo.title }}</span>
|
||||
<span class="job-resume-custom-dialog__gap-job-sub">{{ jobInfo.location }} · {{ jobInfo.company }} 独角兽</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 简历选择列 -->
|
||||
<div class="job-resume-custom-dialog__gap-cell">
|
||||
<div class="job-resume-custom-dialog__resume-selector">
|
||||
<div class="job-resume-custom-dialog__resume-info">
|
||||
<svg viewBox="0 0 24 24" fill="none" class="job-resume-custom-dialog__resume-file-icon"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8l-6-6z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M14 2v6h6" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/></svg>
|
||||
<div class="job-resume-custom-dialog__resume-text">
|
||||
<span class="job-resume-custom-dialog__resume-label">你的简历</span>
|
||||
<span class="job-resume-custom-dialog__resume-name">{{ selectedResume.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="job-resume-custom-dialog__resume-select-btn" @click="toggleResumeDropdown">选择 <svg viewBox="0 0 12 12" fill="none" class="job-resume-custom-dialog__dropdown-arrow"><path d="M3 5l3 3 3-3" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
|
||||
<div v-if="showResumeDropdown" class="job-resume-custom-dialog__resume-dropdown">
|
||||
<div v-for="r in resumeList" :key="r.id" class="job-resume-custom-dialog__resume-option" :class="{'job-resume-custom-dialog__resume-option--active': r.id === selectedResume.id}" @click="selectResume(r)">{{ r.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 简历选择 -->
|
||||
<div class="job-resume-custom-dialog__section">
|
||||
<h4 class="job-resume-custom-dialog__section-title">简历选择</h4>
|
||||
<div class="job-resume-custom-dialog__resume-select-box" @click="toggleResumeDropdown">
|
||||
<span class="job-resume-custom-dialog__resume-select-name">{{ selectedResume.name }}</span>
|
||||
<svg viewBox="0 0 14 14" fill="none" class="job-resume-custom-dialog__resume-select-arrow"><path d="M4 6l3 3 3-3" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<!-- 简历下拉 -->
|
||||
<div v-if="showResumeDropdown" class="job-resume-custom-dialog__resume-dropdown">
|
||||
<div v-for="r in resumeList" :key="r.id" class="job-resume-custom-dialog__resume-option" :class="{'job-resume-custom-dialog__resume-option--active': r.id === selectedResume.id}" @click.stop="selectResume(r)">{{ r.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 第二行:岗位名称 -->
|
||||
<div class="job-resume-custom-dialog__gap-row">
|
||||
<div class="job-resume-custom-dialog__gap-cell job-resume-custom-dialog__gap-cell--label">
|
||||
<span>岗位名称</span>
|
||||
</div>
|
||||
|
||||
<!-- 岗位概览 -->
|
||||
<div class="job-resume-custom-dialog__section">
|
||||
<h4 class="job-resume-custom-dialog__section-title">岗位概览</h4>
|
||||
<div class="job-resume-custom-dialog__overview-card">
|
||||
<div class="job-resume-custom-dialog__overview-title">{{ jobInfo.company }} · {{ jobInfo.title }}</div>
|
||||
<div class="job-resume-custom-dialog__overview-sub">{{ jobInfo.location }} · {{ jobInfo.company }}</div>
|
||||
<div class="job-resume-custom-dialog__overview-tags">
|
||||
<span v-for="kw in jobInfo.keywords" :key="kw" class="job-resume-custom-dialog__overview-tag">{{ kw }}</span>
|
||||
</div>
|
||||
<div class="job-resume-custom-dialog__gap-cell">
|
||||
<span class="job-resume-custom-dialog__gap-value">{{ jobInfo.title }}</span>
|
||||
</div>
|
||||
<!-- <div class="job-resume-custom-dialog__gap-cell">
|
||||
<span class="job-resume-custom-dialog__gap-value">{{ selectedResume.targetJob || '—' }}</span>
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- 第三行:岗位关键词 -->
|
||||
<div class="job-resume-custom-dialog__gap-row">
|
||||
<div class="job-resume-custom-dialog__gap-cell job-resume-custom-dialog__gap-cell--label">
|
||||
<span>岗位关键词</span>
|
||||
</div>
|
||||
<div class="job-resume-custom-dialog__gap-cell job-resume-custom-dialog__gap-cell--keywords">
|
||||
<div class="job-resume-custom-dialog__gap-keywords">
|
||||
<span v-for="kw in jobInfo.keywords" :key="kw" class="job-resume-custom-dialog__gap-kw-tag">{{ kw }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 差距分析列表 -->
|
||||
<div class="job-resume-custom-dialog__section">
|
||||
<h4 class="job-resume-custom-dialog__section-title">差距分析</h4>
|
||||
<div class="job-resume-custom-dialog__gap-list">
|
||||
<div v-for="(gap, idx) in gapItems" :key="idx" class="job-resume-custom-dialog__gap-item">
|
||||
<div class="job-resume-custom-dialog__gap-item-num">
|
||||
<span>{{ idx + 1 }}</span>
|
||||
</div>
|
||||
<div class="job-resume-custom-dialog__gap-item-content">
|
||||
<div class="job-resume-custom-dialog__gap-item-title">{{ gap.title }}</div>
|
||||
<div class="job-resume-custom-dialog__gap-item-desc">{{ gap.description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 步骤三:定制简历 -->
|
||||
<!-- 步骤二:定制简历 -->
|
||||
<template v-if="currentStep === 3">
|
||||
<div class="job-resume-custom-dialog__custom">
|
||||
<!-- 左侧:选择要优化的部分 -->
|
||||
<div class="job-resume-custom-dialog__custom-panel">
|
||||
<h3 class="job-resume-custom-dialog__custom-panel-title">1.选择你要优化的部分</h3>
|
||||
<div class="job-resume-custom-dialog__custom-options">
|
||||
<label v-for="item in optimizeSections" :key="item.key" class="job-resume-custom-dialog__custom-checkbox">
|
||||
<input type="checkbox" v-model="item.checked" class="job-resume-custom-dialog__custom-input" />
|
||||
<span class="job-resume-custom-dialog__custom-checkmark"></span>
|
||||
<span class="job-resume-custom-dialog__custom-label">{{ item.label }}</span>
|
||||
<!-- 技能和工作经验的问号提示(使用 el-tooltip) -->
|
||||
<el-tooltip
|
||||
v-if="item.tooltip"
|
||||
:content="item.tooltip"
|
||||
placement="right"
|
||||
:show-arrow="true"
|
||||
:popper-options="{ strategy: 'fixed' }"
|
||||
effect="dark"
|
||||
>
|
||||
<span class="job-resume-custom-dialog__custom-tooltip-trigger">
|
||||
<svg viewBox="0 0 16 16" fill="none" class="job-resume-custom-dialog__custom-tooltip-icon">
|
||||
<circle cx="8" cy="8" r="7" stroke="currentColor" stroke-width="1.2"/>
|
||||
<path d="M6.5 6.5a1.5 1.5 0 112.12 1.37c-.42.18-.62.5-.62.88V9.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
|
||||
<circle cx="8" cy="11.5" r="0.6" fill="currentColor"/>
|
||||
</svg>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
<div class="job-resume-custom-dialog__custom-v2">
|
||||
<!-- 第一部分:选择你要优化的部分 -->
|
||||
<div class="job-resume-custom-dialog__custom-section">
|
||||
<div class="job-resume-custom-dialog__custom-section-header">
|
||||
<h3 class="job-resume-custom-dialog__custom-section-title">选择你要优化的部分</h3>
|
||||
<p class="job-resume-custom-dialog__custom-section-desc">选择后,系统会基于岗位要求自动重写对应模块,提升简历通过初筛的概率</p>
|
||||
</div>
|
||||
<div class="job-resume-custom-dialog__custom-cards">
|
||||
<label
|
||||
v-for="item in optimizeSections"
|
||||
:key="item.key"
|
||||
class="job-resume-custom-dialog__custom-card"
|
||||
:class="{ 'job-resume-custom-dialog__custom-card--checked': item.checked }"
|
||||
>
|
||||
<input type="checkbox" v-model="item.checked" class="job-resume-custom-dialog__custom-card-input" />
|
||||
<!-- 自定义复选框圆形 -->
|
||||
<span class="job-resume-custom-dialog__custom-card-check">
|
||||
<svg v-if="item.checked" viewBox="0 0 20 20" fill="none" class="job-resume-custom-dialog__custom-card-check-svg">
|
||||
<circle cx="10" cy="10" r="10" fill="#52CAD1"/>
|
||||
<path d="M6 10.5l2.5 2.5 5.5-5.5" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<svg v-else viewBox="0 0 20 20" fill="none" class="job-resume-custom-dialog__custom-card-check-svg">
|
||||
<circle cx="10" cy="10" r="9.33" stroke="#6A7282" stroke-width="1.33"/>
|
||||
</svg>
|
||||
</span>
|
||||
<!-- 文字内容 -->
|
||||
<span class="job-resume-custom-dialog__custom-card-text">
|
||||
<span class="job-resume-custom-dialog__custom-card-label">{{ item.label }}</span>
|
||||
<span v-if="item.tooltip" class="job-resume-custom-dialog__custom-card-tip">{{ item.tooltip }}</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧:选择要新增的技能关键词 -->
|
||||
<div class="job-resume-custom-dialog__custom-panel">
|
||||
<h3 class="job-resume-custom-dialog__custom-panel-title">2.选择你要新增的技能关键词</h3>
|
||||
<div class="job-resume-custom-dialog__custom-options">
|
||||
<label v-for="skill in newSkillOptions" :key="skill.name" class="job-resume-custom-dialog__custom-checkbox">
|
||||
<input type="checkbox" v-model="skill.checked" class="job-resume-custom-dialog__custom-input" />
|
||||
<span class="job-resume-custom-dialog__custom-checkmark"></span>
|
||||
<span class="job-resume-custom-dialog__custom-label">{{ skill.name }}</span>
|
||||
<!-- 第二部分:选择你要新增的技能关键词 -->
|
||||
<div class="job-resume-custom-dialog__custom-section">
|
||||
<div class="job-resume-custom-dialog__custom-section-header">
|
||||
<h3 class="job-resume-custom-dialog__custom-section-title">选择你要新增的技能关键词</h3>
|
||||
<p class="job-resume-custom-dialog__custom-section-desc">关键词会被自然融入经历描述中,避免生硬堆砌</p>
|
||||
</div>
|
||||
<div class="job-resume-custom-dialog__custom-cards">
|
||||
<label
|
||||
v-for="skill in newSkillOptions"
|
||||
:key="skill.name"
|
||||
class="job-resume-custom-dialog__custom-card"
|
||||
:class="{ 'job-resume-custom-dialog__custom-card--checked': skill.checked }"
|
||||
>
|
||||
<input type="checkbox" v-model="skill.checked" class="job-resume-custom-dialog__custom-card-input" />
|
||||
<!-- 自定义复选框圆形 -->
|
||||
<span class="job-resume-custom-dialog__custom-card-check">
|
||||
<svg v-if="skill.checked" viewBox="0 0 20 20" fill="none" class="job-resume-custom-dialog__custom-card-check-svg">
|
||||
<circle cx="10" cy="10" r="10" fill="#52CAD1"/>
|
||||
<path d="M6 10.5l2.5 2.5 5.5-5.5" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<svg v-else viewBox="0 0 20 20" fill="none" class="job-resume-custom-dialog__custom-card-check-svg">
|
||||
<circle cx="10" cy="10" r="9.33" stroke="#6A7282" stroke-width="1.33"/>
|
||||
</svg>
|
||||
</span>
|
||||
<!-- 文字内容 -->
|
||||
<span class="job-resume-custom-dialog__custom-card-text">
|
||||
<span class="job-resume-custom-dialog__custom-card-label">{{ skill.name }}</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 步骤四:预览 -->
|
||||
<!-- 步骤三:简历预览 -->
|
||||
<template v-if="currentStep === 4">
|
||||
<div class="job-resume-custom-dialog__preview">
|
||||
<!-- 左侧:简历模板预览(支持差异对比模式) -->
|
||||
@@ -280,18 +300,22 @@
|
||||
</div>
|
||||
<!-- 抽屉底部按钮 -->
|
||||
<div v-if="currentStep < 4" class="job-resume-custom-dialog__drawer-footer">
|
||||
<button class="job-resume-custom-dialog__primary-btn" @click="handleDrawerNext">立即定制简历</button>
|
||||
</div>
|
||||
<!-- 步骤四专属底部:下载简历 + 立即去投递 -->
|
||||
<div v-if="currentStep === 4" class="job-resume-custom-dialog__preview-footer mt10 pt30">
|
||||
<!-- 左侧:下载简历按钮(带下拉) -->
|
||||
<div class="job-resume-custom-dialog__download-wrap">
|
||||
<button class="job-resume-custom-dialog__download-btn" @click="toggleDownloadMenu">下载简历</button>
|
||||
<div v-if="showDownloadMenu" class="job-resume-custom-dialog__download-menu">
|
||||
<button class="job-resume-custom-dialog__download-option" @click="handleDownload('pdf')">下载PDF</button>
|
||||
<button class="job-resume-custom-dialog__download-option" @click="handleDownload('word')">下载Word</button>
|
||||
<!-- 步骤二(定制简历):上一步 + 下一步 -->
|
||||
<template v-if="currentStep === 3">
|
||||
<div class="job-resume-custom-dialog__footer-btns">
|
||||
<button class="job-resume-custom-dialog__prev-btn" @click="goToStep(2)">上一步</button>
|
||||
<button class="job-resume-custom-dialog__next-btn" @click="handleDrawerNext">下一步</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 步骤一(差距分析):立即定制简历 -->
|
||||
<template v-else>
|
||||
<button class="job-resume-custom-dialog__primary-btn" @click="handleDrawerNext">立即定制简历</button>
|
||||
</template>
|
||||
</div>
|
||||
<!-- 步骤三专属底部:下载简历 + 立即去投递 -->
|
||||
<div v-if="currentStep === 4" class="job-resume-custom-dialog__preview-footer mt10 pt30">
|
||||
<!-- 左侧:上一步按钮 -->
|
||||
<button class="job-resume-custom-dialog__footer-prev-btn" @click="goToStep(3)">上一步</button>
|
||||
<!-- 右侧:立即去投递按钮 -->
|
||||
<button class="job-resume-custom-dialog__submit-btn" @click="handleSubmit">立即去投递</button>
|
||||
</div>
|
||||
@@ -318,7 +342,7 @@ import JobResumeTemplate from '@/components/JobResumeTemplate.vue'
|
||||
import JobResumeCustomEditPanel from '@/components/JobResumeCustomEditPanel.vue'
|
||||
import type { ResumeTemplateData } from '@/components/JobResumeTemplate.vue'
|
||||
import { exportResumePdf, exportResumeWord } from '@/utils/resumeExport'
|
||||
import { fetchResumeList } from '@/api/resume'
|
||||
import { fetchResumeList, setDefaultResume } from '@/api/resume'
|
||||
import type { ResumeListItem } from '@/api/resume'
|
||||
import { fetchCustomizeResume, generateCustomizeResume, aiEditResume, rollbackCustomizeResume } from '@/api/jobs'
|
||||
import type { CustomizeResumeData, AiEditChatMessage } from '@/api/jobs'
|
||||
@@ -334,6 +358,13 @@ interface ResumeOption {
|
||||
targetJob: string
|
||||
}
|
||||
|
||||
/** 差距分析项 */
|
||||
interface GapItem {
|
||||
keyword: string
|
||||
title: string
|
||||
description: string
|
||||
}
|
||||
|
||||
/** 岗位信息 */
|
||||
interface JobInfo {
|
||||
title: string
|
||||
@@ -344,6 +375,8 @@ interface JobInfo {
|
||||
missingSkills: string[]
|
||||
keywords: string[]
|
||||
sourceUrl: string
|
||||
/** 差距分析列表(来自 skill-gap 接口) */
|
||||
gaps: GapItem[]
|
||||
/** 默认简历信息(来自 skill-gap 接口) */
|
||||
defaultResume: { resumeId: string; resumeName: string; targetPosition: string } | null
|
||||
}
|
||||
@@ -400,6 +433,9 @@ const matchLevelText = computed(() => {
|
||||
/** 是否为低匹配度(低于6分) */
|
||||
const isLowMatch = computed(() => props.jobInfo.matchScore < 6)
|
||||
|
||||
/** 差距分析列表(来自 jobInfo.gaps) */
|
||||
const gapItems = computed(() => props.jobInfo.gaps || [])
|
||||
|
||||
/** 跳转到指定步骤 */
|
||||
function goToStep(step: number) {
|
||||
// 从步骤4返回步骤3时,清理步骤4的状态数据(避免下次进入被旧数据影响)
|
||||
@@ -440,6 +476,11 @@ async function handleDrawerNext() {
|
||||
initSkillOptions()
|
||||
currentStep.value++
|
||||
} else if (currentStep.value === 3) {
|
||||
// 校验:至少勾选一个优化部分
|
||||
if (selectedSectionKeys.value.length === 0) {
|
||||
ElMessage.warning('请选择你要优化的部分')
|
||||
return
|
||||
}
|
||||
// 步骤3 → 步骤4:先调用定制简历接口
|
||||
await fetchAndLoadCustomResume()
|
||||
} else {
|
||||
@@ -576,7 +617,7 @@ function handleClose() {
|
||||
|
||||
|
||||
|
||||
// ==================== 定制简历选项(步骤三) ====================
|
||||
// ==================== 定制简历选项(步骤一) ====================
|
||||
|
||||
/** 优化部分选项 */
|
||||
interface OptimizeSection {
|
||||
@@ -594,19 +635,19 @@ interface SkillOption {
|
||||
|
||||
/** 左侧:可优化的简历部分 */
|
||||
const optimizeSections = ref<OptimizeSection[]>([
|
||||
{ key: 'summary', label: '个人概述', checked: false },
|
||||
{ key: 'skills', label: '技能', checked: false, tooltip: '我们将把您勾选的技能补充进简历的技能模块。这对于简历能否通过ATS关键词筛选至关重要。' },
|
||||
{ key: 'experience', label: '工作经验', checked: false, tooltip: '我们将把您选择的技能融入工作经历中,并对关键词进行润色,最大程度提升简历与岗位的匹配度。' },
|
||||
{ key: 'summary', label: '个人概述', checked: true },
|
||||
{ key: 'skills', label: '技能', checked: true, tooltip: '我们将把您勾选的技能补充进简历的技能模块。这对于简历能否通过ATS关键词筛选至关重要。' },
|
||||
{ key: 'experience', label: '工作经验', checked: true, tooltip: '我们将把您选择的技能融入工作经历中,并对关键词进行润色,最大程度提升简历与岗位的匹配度。' },
|
||||
])
|
||||
|
||||
/** 右侧:可新增的技能关键词 */
|
||||
const newSkillOptions = ref<SkillOption[]>([])
|
||||
|
||||
/** 根据缺失技能初始化技能选项 */
|
||||
/** 根据缺失技能初始化技能选项(默认全选) */
|
||||
function initSkillOptions() {
|
||||
newSkillOptions.value = missingSkills.value.map(skill => ({
|
||||
name: skill,
|
||||
checked: false,
|
||||
checked: true,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -620,7 +661,7 @@ const selectedNewSkills = computed(() =>
|
||||
newSkillOptions.value.filter(s => s.checked).map(s => s.name)
|
||||
)
|
||||
|
||||
// ==================== 简历选择(步骤二) ====================
|
||||
// ==================== 简历选择(步骤一) ====================
|
||||
|
||||
/** 简历列表(从接口获取) */
|
||||
const resumeList = ref<ResumeOption[]>([])
|
||||
@@ -680,13 +721,17 @@ function toggleResumeDropdown() {
|
||||
showResumeDropdown.value = !showResumeDropdown.value
|
||||
}
|
||||
|
||||
/** 选择简历 */
|
||||
/** 选择简历并设为默认 */
|
||||
function selectResume(r: ResumeOption) {
|
||||
selectedResume.value = r
|
||||
showResumeDropdown.value = false
|
||||
// 调用设为默认简历接口
|
||||
setDefaultResume(r.id).catch(e => {
|
||||
console.error('[JobResumeCustomDialog] 设为默认简历失败', e)
|
||||
})
|
||||
}
|
||||
|
||||
// ==================== 步骤四:预览相关 ====================
|
||||
// ==================== 步骤一:预览相关 ====================
|
||||
|
||||
/** 简历模板组件引用 */
|
||||
const resumeTemplateRef = ref()
|
||||
@@ -715,7 +760,7 @@ const customResumeRawData = ref<CustomizeResumeData>({
|
||||
/** 当前预览右侧tab:ai-AI帮写 / edit-编辑 */
|
||||
const previewTab = ref<'ai' | 'edit'>('ai')
|
||||
|
||||
/** AI优化结果列表(根据步骤三勾选的优化项动态生成) */
|
||||
/** AI优化结果列表(根据步骤一勾选的优化项动态生成) */
|
||||
const aiOptimizeResults = computed<string[]>(() => {
|
||||
const results: string[] = []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user