Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8cd21e7b98 | ||
|
|
e8e2e09e62 | ||
|
|
4be35ced80 | ||
|
|
0e5c7d14d0 | ||
|
|
cf268520e1 | ||
|
|
cd64ded6ae | ||
|
|
ec6ba7ee35 | ||
|
|
72339f332d | ||
|
|
b25f2dde3a | ||
|
|
38e3957da2 |
@@ -53,6 +53,7 @@ declare module 'vue' {
|
||||
MemberAccessDialog: typeof import('./src/components/MemberAccessDialog.vue')['default']
|
||||
MemberDialog: typeof import('./src/components/MemberDialog.vue')['default']
|
||||
MentorAsidePanel: typeof import('./src/components/MentorAsidePanel.vue')['default']
|
||||
MentorQrCodeDialog: typeof import('./src/components/MentorQrCodeDialog.vue')['default']
|
||||
ProfileEditDrawer: typeof import('./src/components/ProfileEditDrawer.vue')['default']
|
||||
ProfilePageContent: typeof import('./src/components/ProfilePageContent.vue')['default']
|
||||
ProfileWelcomeDialog: typeof import('./src/components/ProfileWelcomeDialog.vue')['default']
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface AgentConfig {
|
||||
autoOptimizeResume?: number
|
||||
/** 自动匹配分析 0=关闭 1=开启 */
|
||||
autoMatchAnalysis?: number
|
||||
/** 是否愿意接受部门调剂 */
|
||||
/** 是否开启深度人岗匹配分析,可选值:是/否(null或空字符串视为关闭) */
|
||||
acceptDeptTransfer?: string
|
||||
/** 是否接受地点调剂 */
|
||||
acceptLocationTransfer?: string
|
||||
@@ -71,8 +71,8 @@ export interface AgentJobMatchDetail {
|
||||
|
||||
/** 推荐岗位项 */
|
||||
export interface AgentRecommendJob {
|
||||
/** 岗位 ID */
|
||||
id: number
|
||||
/** 岗位 ID(字符串,避免大整数精度丢失) */
|
||||
id: string | number
|
||||
/** 岗位名称 */
|
||||
title: string
|
||||
/** 薪资描述 */
|
||||
@@ -103,6 +103,10 @@ export interface AgentRecommendJob {
|
||||
matchScore: number
|
||||
/** 匹配度详情 */
|
||||
matchDetail: AgentJobMatchDetail
|
||||
/** 学历要求 0=不限 1=大专 2=本科 3=硕士 4=博士 */
|
||||
education?: number
|
||||
/** 招聘分类 0=社招 1=校招 2=实习 3=其他 */
|
||||
recruitCategory?: number
|
||||
}
|
||||
|
||||
/** 求职助手岗位推荐返回数据 */
|
||||
@@ -302,3 +306,24 @@ export function optimizeAgentResume(params: OptimizeResumeParams) {
|
||||
},
|
||||
}).then(res => res.data)
|
||||
}
|
||||
|
||||
// ==================== 岗位匹配度评分(Python 后端) ====================
|
||||
|
||||
/** 匹配度评分请求参数 */
|
||||
export interface MatchScoreParams {
|
||||
/** 定制简历 ID(字符串,避免大整数精度丢失) */
|
||||
customizeResumeId?: string
|
||||
/** 普通简历 ID(关闭优化时使用) */
|
||||
resumeId?: string
|
||||
/** 岗位 ID(字符串,避免大整数精度丢失) */
|
||||
jobId: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 岗位匹配度评分
|
||||
* POST /job-agent/match-score
|
||||
* @returns data 为匹配度分数(0-100)
|
||||
*/
|
||||
export function fetchMatchScore(params: MatchScoreParams) {
|
||||
return aiService.post<any, { data: AiResult<number> }>('/job-agent/match-score', params).then(res => res.data)
|
||||
}
|
||||
|
||||
@@ -483,6 +483,9 @@ export function fetchSkillGap(jobId: string) {
|
||||
/** 定制简历接口返回的简历数据 */
|
||||
export interface CustomizeResumeData {
|
||||
/** 简历基本信息 */
|
||||
id?: string
|
||||
resumeId?: string
|
||||
resumeName?: string
|
||||
resume: {
|
||||
avatarUrl?: string
|
||||
name?: string
|
||||
|
||||
@@ -243,10 +243,8 @@ export function fetchMentorMockChat(mentorId: string): Promise<MentorMockChatRes
|
||||
*/
|
||||
export function fetchMentorQrCode(teacherId: string): Promise<any> {
|
||||
return request.post('/public/mentor/getQrCode', {
|
||||
key: {
|
||||
path: 'pages/teacher/teacher',
|
||||
teacherId,
|
||||
loginAppid: 'wx3adfa65f9d8db17d',
|
||||
},
|
||||
path: 'pages/teacher/teacher',
|
||||
teacherId,
|
||||
loginAppid: 'wx3adfa65f9d8db17d',
|
||||
})
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 19 KiB |
@@ -361,7 +361,9 @@ body:not(#_) {
|
||||
.aliite-e{
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.aliite-st{
|
||||
align-items: stretch;
|
||||
}
|
||||
//英文字母或数字一行溢出超出,打断
|
||||
.word-bra{
|
||||
word-break: break-all;
|
||||
@@ -620,7 +622,12 @@ body:not(#_) {
|
||||
.border-red1{
|
||||
border: 0.01rem solid #C86667;
|
||||
}
|
||||
|
||||
.border-EDF9FA-bottom-2{
|
||||
border: 0.02rem solid #EDF9FA;
|
||||
}
|
||||
.border-F0F0F0-bottom-1{
|
||||
border: 0.01rem solid #F0F0F0;
|
||||
}
|
||||
//圆角
|
||||
.border-ra0{border-radius: 0rem;}
|
||||
.border-ra1{border-radius: 0.01rem;}
|
||||
@@ -700,6 +707,11 @@ body:not(#_) {
|
||||
background: $bg-white;
|
||||
}
|
||||
|
||||
.bg-linear-1{
|
||||
background: linear-gradient(to right, #52CAD1, #9FD051)
|
||||
}
|
||||
|
||||
|
||||
/*文字超出隐藏*/
|
||||
.text-over-h{
|
||||
white-space: nowrap; /* 保持文本在一行内显示 */
|
||||
@@ -905,6 +917,8 @@ body:not(#_) {
|
||||
.w192{width: 1.92rem;}
|
||||
.w200{width: 2rem;}
|
||||
.w244{width: 2.44rem;}
|
||||
.w263{width: 2.63rem;}
|
||||
.w444{width: 4.44rem;}
|
||||
.w1200{width:12rem}
|
||||
|
||||
/*height*/
|
||||
|
||||
@@ -1,317 +1,240 @@
|
||||
@use '../variables' as *;
|
||||
|
||||
// 申请进度消息组件
|
||||
// 投递进度卡片组件(新版4步骤)
|
||||
.agent-apply-progress {
|
||||
background: $bg-middle;
|
||||
border-radius: 0.12rem;
|
||||
padding: 0.2rem;
|
||||
font-size: 0.14rem;
|
||||
background: $bg-white;
|
||||
border: 1px solid #F0F0F0;
|
||||
border-radius: 0.08rem;
|
||||
padding: 0.16rem 0.2rem;
|
||||
|
||||
// 顶部标题栏
|
||||
&__header {
|
||||
// 已完成状态
|
||||
&--completed {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
// 顶部区域:岗位信息 + 步骤条
|
||||
&__top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.16rem;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 0.15rem;
|
||||
font-weight: 600;
|
||||
color: $text-dark;
|
||||
|
||||
// 可点击状态(暂停/恢复)
|
||||
&--clickable {
|
||||
cursor: pointer;
|
||||
color: $accent;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__cancel {
|
||||
font-size: 0.13rem;
|
||||
color: $text-middle;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $text-dark;
|
||||
}
|
||||
}
|
||||
|
||||
// 岗位信息卡片
|
||||
&__job-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.12rem;
|
||||
background: $bg-white;
|
||||
border-radius: 0.1rem;
|
||||
padding: 0.14rem 0.16rem;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
&__job-icon {
|
||||
width: 0.36rem;
|
||||
height: 0.36rem;
|
||||
border-radius: 0.08rem;
|
||||
background: $bg-main;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
color: $text-middle;
|
||||
|
||||
svg {
|
||||
width: 0.2rem;
|
||||
height: 0.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
&__job-info {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
&__job-company {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 600;
|
||||
color: $text-dark;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
&__job-title {
|
||||
font-size: 0.12rem;
|
||||
color: $text-middle;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
// 步骤列表
|
||||
&__steps {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.14rem;
|
||||
}
|
||||
|
||||
&__step {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.1rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
// 勾选框
|
||||
&__step-check {
|
||||
width: 0.18rem;
|
||||
height: 0.18rem;
|
||||
border: 1.5px solid $text-light;
|
||||
border-radius: 0.03rem;
|
||||
// 岗位信息
|
||||
&__job-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
margin-top: 0.01rem;
|
||||
|
||||
svg {
|
||||
width: 0.12rem;
|
||||
height: 0.12rem;
|
||||
}
|
||||
|
||||
// 已完成态
|
||||
&--done {
|
||||
border-color: $text-dark;
|
||||
background: $text-dark;
|
||||
color: $bg-white;
|
||||
}
|
||||
gap: 0.28rem;
|
||||
}
|
||||
|
||||
&__step-label {
|
||||
font-size: 0.14rem;
|
||||
&__job-title {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
color: $text-dark;
|
||||
line-height: 0.2rem;
|
||||
line-height: 0.27rem;
|
||||
}
|
||||
|
||||
// 步骤展开内容
|
||||
&__step-content {
|
||||
width: 100%;
|
||||
margin-top: 0.08rem;
|
||||
padding-left: 0.28rem;
|
||||
}
|
||||
|
||||
// 第2步:简历确认区域
|
||||
&__resume-confirm {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: $bg-white;
|
||||
border-radius: 0.08rem;
|
||||
padding: 0.1rem 0.14rem;
|
||||
}
|
||||
|
||||
&__resume-file {
|
||||
&__company {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.08rem;
|
||||
}
|
||||
|
||||
&__file-icon {
|
||||
width: 0.18rem;
|
||||
height: 0.18rem;
|
||||
color: $text-dark;
|
||||
}
|
||||
&__company-logo {
|
||||
width: 0.24rem;
|
||||
height: 0.24rem;
|
||||
border-radius: 0.04rem;
|
||||
object-fit: cover;
|
||||
|
||||
&__resume-name {
|
||||
font-size: 0.13rem;
|
||||
color: $text-dark;
|
||||
}
|
||||
&--placeholder {
|
||||
background: $bg-main;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: $text-middle;
|
||||
|
||||
&__confirm-btn {
|
||||
height: 0.28rem;
|
||||
padding: 0 0.16rem;
|
||||
background: $btn-dark;
|
||||
color: $bg-white;
|
||||
border: none;
|
||||
border-radius: 0.14rem;
|
||||
font-size: 0.12rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: $btn-dark-hover;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: $text-light;
|
||||
cursor: not-allowed;
|
||||
svg {
|
||||
width: 0.14rem;
|
||||
height: 0.14rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 第3步:投递操作区域
|
||||
&__apply-area {
|
||||
background: $bg-white;
|
||||
border-radius: 0.08rem;
|
||||
padding: 0.14rem 0.16rem;
|
||||
&__company-name {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 330;
|
||||
color: $text-dark;
|
||||
line-height: 0.27rem;
|
||||
}
|
||||
|
||||
&__apply-desc {
|
||||
font-size: 0.12rem;
|
||||
color: $text-middle;
|
||||
line-height: 1.8;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__apply-actions {
|
||||
// 步骤条
|
||||
&__steps {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 0.1rem;
|
||||
margin-top: 0.14rem;
|
||||
gap: 0.12rem;
|
||||
}
|
||||
|
||||
&__skip-btn {
|
||||
font-size: 0.12rem;
|
||||
color: $text-middle;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
// 步骤项
|
||||
&__step-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.08rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
// 步骤图标
|
||||
&__step-icon {
|
||||
width: 0.40rem;
|
||||
height: 0.40rem;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
svg {
|
||||
width: 0.20rem;
|
||||
height: 0.20rem;
|
||||
}
|
||||
|
||||
// 已完成
|
||||
&--done {
|
||||
background: $accent;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
// 进行中
|
||||
&--active {
|
||||
background: #EDF9FA;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
// 待处理
|
||||
&--pending {
|
||||
background: $bg-main;
|
||||
color: $text-middle;
|
||||
}
|
||||
}
|
||||
|
||||
// 步骤文字区域
|
||||
&__step-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.04rem;
|
||||
}
|
||||
|
||||
// 步骤名称
|
||||
&__step-name {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 520;
|
||||
line-height: 0.19rem;
|
||||
|
||||
&--done {
|
||||
color: $text-dark;
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
color: $text-light;
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
&--active {
|
||||
color: $text-dark;
|
||||
}
|
||||
|
||||
&--pending {
|
||||
color: $text-middle;
|
||||
}
|
||||
}
|
||||
|
||||
&__applied-btn {
|
||||
height: 0.28rem;
|
||||
padding: 0 0.14rem;
|
||||
background: $btn-dark;
|
||||
color: $bg-white;
|
||||
border: none;
|
||||
border-radius: 0.14rem;
|
||||
// 步骤状态文字
|
||||
&__step-status {
|
||||
font-size: 0.12rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-weight: 330;
|
||||
line-height: 0.16rem;
|
||||
|
||||
&:hover {
|
||||
background: $btn-dark-hover;
|
||||
&--done {
|
||||
color: #9FD051;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: $text-light;
|
||||
cursor: not-allowed;
|
||||
&--active {
|
||||
color: #F59E0B;
|
||||
}
|
||||
|
||||
&--pending {
|
||||
color: $text-middle;
|
||||
}
|
||||
}
|
||||
|
||||
&__goto-btn {
|
||||
height: 0.28rem;
|
||||
padding: 0 0.14rem;
|
||||
background: $btn-dark;
|
||||
color: $bg-white;
|
||||
border: none;
|
||||
border-radius: 0.14rem;
|
||||
font-size: 0.12rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: $btn-dark-hover;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: $text-light;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 右侧面板:简历生成进度
|
||||
.agent-resume-generating {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
padding: 0.4rem;
|
||||
|
||||
// 进度条容器
|
||||
&__progress-bar {
|
||||
width: 100%;
|
||||
max-width: 3rem;
|
||||
height: 0.04rem;
|
||||
background: $border-color;
|
||||
border-radius: 0.02rem;
|
||||
overflow: hidden;
|
||||
margin-bottom: 0.2rem;
|
||||
// 步骤连接线
|
||||
&__step-line {
|
||||
width: 0.40rem;
|
||||
height: 0.02rem;
|
||||
background: #E5E7EB;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__progress-fill {
|
||||
height: 100%;
|
||||
background: $text-dark;
|
||||
border-radius: 0.02rem;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 700;
|
||||
color: $text-dark;
|
||||
margin-bottom: 0.1rem;
|
||||
// 底部区域:提示 + 按钮
|
||||
&__bottom {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
margin-top: 0.16rem;
|
||||
}
|
||||
|
||||
// 提示文字
|
||||
&__hint {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 450;
|
||||
color: $text-middle;
|
||||
line-height: 0.19rem;
|
||||
|
||||
// 警告色(橙色)
|
||||
&--warning {
|
||||
color: #F59E0B;
|
||||
}
|
||||
|
||||
// 匹配度偏低(红橙色)
|
||||
&--low-match {
|
||||
color: #FE6D52;
|
||||
}
|
||||
|
||||
// 强调色(品牌色)
|
||||
&--accent {
|
||||
color: $accent;
|
||||
}
|
||||
}
|
||||
|
||||
// 操作按钮区
|
||||
&__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.06rem;
|
||||
font-size: 0.12rem;
|
||||
color: $text-middle;
|
||||
gap: 0.16rem;
|
||||
}
|
||||
|
||||
&__hint-icon {
|
||||
width: 0.14rem;
|
||||
height: 0.14rem;
|
||||
color: $accent;
|
||||
// 按钮基础样式
|
||||
&__btn {
|
||||
height: 0.27rem;
|
||||
padding: 0.04rem 0.12rem;
|
||||
border-radius: 0.08rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 380;
|
||||
line-height: 0.19rem;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
transition: opacity 0.2s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
// 边框按钮
|
||||
&--outline {
|
||||
background: transparent;
|
||||
border: 1px solid $accent;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
// 实心按钮
|
||||
&--primary {
|
||||
background: $accent;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,25 +2,50 @@
|
||||
|
||||
// ==================== Agent推荐岗位列表组件样式 ====================
|
||||
.agent-chat-job-list {
|
||||
background: $bg-middle;
|
||||
background: $bg-white;
|
||||
border: 1px solid #F0F0F0;
|
||||
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.04);
|
||||
border-radius: 0.12rem;
|
||||
padding: 0.24rem;
|
||||
font-size: 0.14rem;
|
||||
|
||||
// 标题
|
||||
&__header {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 700;
|
||||
font-size: 0.22rem;
|
||||
font-weight: 520;
|
||||
color: $text-dark;
|
||||
margin-bottom: 0.06rem;
|
||||
margin-bottom: 0.04rem;
|
||||
line-height: 0.29rem;
|
||||
}
|
||||
|
||||
// 推荐说明文字
|
||||
&__summary {
|
||||
font-size: 0.13rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 330;
|
||||
color: $text-middle;
|
||||
margin-bottom: 0.18rem;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 0.16rem;
|
||||
line-height: 0.19rem;
|
||||
}
|
||||
|
||||
// 可滚动岗位列表区域(默认显示约3.5个岗位高度)
|
||||
&__scroll {
|
||||
max-height: 3.64rem;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: $border-color transparent;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: $border-color;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
// 单个岗位项
|
||||
@@ -28,31 +53,38 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: $bg-white;
|
||||
border-radius: 0.1rem;
|
||||
flex-wrap: wrap;
|
||||
padding: 0.16rem 0.2rem;
|
||||
margin-bottom: 0.1rem;
|
||||
border: 1px solid #F0F0F0;
|
||||
border-radius: 0.08rem;
|
||||
margin-bottom: 0.08rem;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s ease;
|
||||
|
||||
&:last-of-type {
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: $accent;
|
||||
}
|
||||
}
|
||||
|
||||
// 左侧信息区域(可点击)
|
||||
&__info {
|
||||
// 左侧区域(匹配度 + 岗位信息)
|
||||
&__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.14rem;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.16rem;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// 匹配度环形容器
|
||||
&__score {
|
||||
width: 0.62rem;
|
||||
height: 0.62rem;
|
||||
position: relative;
|
||||
width: 0.48rem;
|
||||
height: 0.48rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -68,98 +100,148 @@
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 0.11rem;
|
||||
font-weight: 700;
|
||||
color: $text-dark;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 630;
|
||||
color: #9FD051;
|
||||
line-height: 0.22rem;
|
||||
}
|
||||
|
||||
// 岗位详情
|
||||
// 岗位详情区域
|
||||
&__detail {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
gap: 0.24rem;
|
||||
}
|
||||
|
||||
// 岗位标题行(岗位名 + 公司名)
|
||||
// 岗位标题行(岗位名 + 公司)
|
||||
&__title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.08rem;
|
||||
margin-bottom: 0.04rem;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.32rem;
|
||||
}
|
||||
|
||||
// 岗位名称
|
||||
&__title {
|
||||
font-size: 0.15rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
color: $text-dark;
|
||||
line-height: 1.4;
|
||||
line-height: 0.27rem;
|
||||
}
|
||||
|
||||
// 公司名前的圆点
|
||||
&__company-dot {
|
||||
font-size: 0.08rem;
|
||||
color: $text-light;
|
||||
// 公司信息容器
|
||||
&__company {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.08rem;
|
||||
}
|
||||
|
||||
// 公司 Logo
|
||||
&__company-logo {
|
||||
width: 0.24rem;
|
||||
height: 0.24rem;
|
||||
border-radius: 0.04rem;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
// 公司名称
|
||||
&__company {
|
||||
font-size: 0.13rem;
|
||||
color: $text-middle;
|
||||
&__company-name {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 330;
|
||||
color: $text-dark;
|
||||
line-height: 0.27rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// 标签行
|
||||
&__tags {
|
||||
display: flex;
|
||||
gap: 0.06rem;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.12rem;
|
||||
}
|
||||
|
||||
// 单个标签
|
||||
&__tag {
|
||||
font-size: 0.11rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 330;
|
||||
color: $text-middle;
|
||||
background: $bg-main;
|
||||
padding: 0.02rem 0.08rem;
|
||||
border-radius: 0.03rem;
|
||||
line-height: 0.19rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.02rem;
|
||||
|
||||
svg {
|
||||
width: 0.16rem;
|
||||
height: 0.16rem;
|
||||
color: $text-middle;
|
||||
}
|
||||
|
||||
// 招聘分类标签(校招等)
|
||||
&--category {
|
||||
padding: 0.02rem 0.04rem;
|
||||
background: #EDF9FA;
|
||||
border-radius: 0.04rem;
|
||||
font-size: 0.12rem;
|
||||
color: $accent;
|
||||
}
|
||||
}
|
||||
|
||||
// 右侧操作按钮区域
|
||||
&__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.14rem;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.08rem;
|
||||
flex-shrink: 0;
|
||||
margin-left: 0.16rem;
|
||||
}
|
||||
|
||||
// 不再推荐按钮
|
||||
&__dismiss-btn {
|
||||
font-size: 0.12rem;
|
||||
color: $text-light;
|
||||
height: 0.35rem;
|
||||
padding: 0 0.12rem;
|
||||
background: transparent;
|
||||
border: none;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 520;
|
||||
color: $accent;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
transition: color 0.2s ease;
|
||||
transition: opacity 0.2s ease;
|
||||
border-radius: 0.08rem;
|
||||
|
||||
&:hover {
|
||||
color: $text-middle;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
// 加入投递按钮
|
||||
&__add-btn {
|
||||
height: 0.32rem;
|
||||
padding: 0 0.16rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.04rem;
|
||||
height: 0.35rem;
|
||||
padding: 0 0.12rem;
|
||||
background: $accent;
|
||||
color: $bg-white;
|
||||
border: none;
|
||||
border-radius: 0.16rem;
|
||||
font-size: 0.12rem;
|
||||
font-weight: 500;
|
||||
border-radius: 0.08rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 520;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
transition: all 0.2s ease;
|
||||
line-height: 0.32rem;
|
||||
|
||||
svg {
|
||||
width: 0.16rem;
|
||||
height: 0.16rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
@@ -172,37 +254,55 @@
|
||||
|
||||
// 已加入状态
|
||||
&--added {
|
||||
background: $bg-main;
|
||||
color: $text-middle;
|
||||
border: 1px solid $border-color;
|
||||
background: transparent;
|
||||
color: $accent;
|
||||
border: 1px solid $accent;
|
||||
}
|
||||
}
|
||||
|
||||
// 空状态
|
||||
&__empty {
|
||||
text-align: center;
|
||||
color: $text-light;
|
||||
padding: 0.4rem 0;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
// 底部按钮区域
|
||||
&__footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 0.16rem;
|
||||
margin-top: 0.2rem;
|
||||
gap: 0.32rem;
|
||||
margin-top: 0.24rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
// 换一批按钮
|
||||
&__refresh-btn {
|
||||
height: 0.4rem;
|
||||
padding: 0 0.4rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.04rem;
|
||||
height: 0.43rem;
|
||||
padding: 0 0.16rem;
|
||||
min-width: 2.8rem;
|
||||
background: $bg-white;
|
||||
color: $text-dark;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: 0.2rem;
|
||||
color: $accent;
|
||||
border: 1px solid $accent;
|
||||
border-radius: 0.22rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 500;
|
||||
font-weight: 520;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
line-height: 0.4rem;
|
||||
|
||||
svg {
|
||||
width: 0.16rem;
|
||||
height: 0.16rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: $accent;
|
||||
color: $accent;
|
||||
background: #EDF9FA;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
@@ -213,17 +313,27 @@
|
||||
|
||||
// 全部添加按钮
|
||||
&__add-all-btn {
|
||||
height: 0.4rem;
|
||||
padding: 0 0.4rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.04rem;
|
||||
height: 0.43rem;
|
||||
padding: 0 0.16rem;
|
||||
min-width: 2.8rem;
|
||||
background: $accent;
|
||||
color: $bg-white;
|
||||
border: none;
|
||||
border-radius: 0.2rem;
|
||||
border-radius: 0.22rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 500;
|
||||
font-weight: 520;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
line-height: 0.4rem;
|
||||
|
||||
svg {
|
||||
width: 0.16rem;
|
||||
height: 0.16rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
|
||||
@@ -1,187 +1,113 @@
|
||||
@use '../variables' as *;
|
||||
|
||||
/* Agent岗位预览面板样式 */
|
||||
.agent-job-preview-panel {
|
||||
/* Agent岗位预览抽屉 — 从浏览器右侧弹出 */
|
||||
|
||||
/* 遮罩层 */
|
||||
.agent-job-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;
|
||||
}
|
||||
|
||||
/* 抽屉主体 */
|
||||
.agent-job-drawer {
|
||||
width: 6.4rem;
|
||||
height: var(--app-height, 100vh);
|
||||
background: $bg-white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background: $bg-white;
|
||||
border-radius: 0.2rem;
|
||||
overflow: hidden;
|
||||
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.16rem 0.2rem;
|
||||
border-bottom: 1px solid $border-color;
|
||||
padding: 0.2rem 0.24rem;
|
||||
height: 0.64rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 返回按钮 */
|
||||
&__back {
|
||||
&__header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.06rem;
|
||||
gap: 0.16rem;
|
||||
}
|
||||
|
||||
/* 关闭按钮 */
|
||||
&__close {
|
||||
width: 0.24rem;
|
||||
height: 0.24rem;
|
||||
cursor: pointer;
|
||||
font-size: 0.15rem;
|
||||
font-weight: 500;
|
||||
color: $text-dark;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&__back-icon {
|
||||
width: 0.16rem;
|
||||
height: 0.16rem;
|
||||
}
|
||||
|
||||
/* 添加按钮 */
|
||||
&__add-btn {
|
||||
padding: 0.06rem 0.16rem;
|
||||
background: $btn-dark;
|
||||
color: $bg-white;
|
||||
border: none;
|
||||
border-radius: 0.06rem;
|
||||
font-size: 0.13rem;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: $btn-dark-hover;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
/* 移出按钮 */
|
||||
&__remove-btn {
|
||||
padding: 0.06rem 0.16rem;
|
||||
background: $bg-white;
|
||||
&__close-icon {
|
||||
width: 0.24rem;
|
||||
height: 0.24rem;
|
||||
color: $text-middle;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: 0.06rem;
|
||||
font-size: 0.13rem;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s, color 0.2s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $bg-main;
|
||||
color: $danger;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
/* 标题文字 */
|
||||
&__title {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
color: $text-dark;
|
||||
line-height: 0.24rem;
|
||||
}
|
||||
|
||||
/* 内容区域(可滚动) */
|
||||
&__body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0.2rem;
|
||||
padding: 0.24rem;
|
||||
}
|
||||
|
||||
/* 岗位卡片 */
|
||||
&__card {
|
||||
background: $bg-main;
|
||||
border-radius: 0.12rem;
|
||||
padding: 0.2rem;
|
||||
margin-bottom: 0.16rem;
|
||||
}
|
||||
|
||||
&__card-top {
|
||||
/* 岗位标题区域 */
|
||||
&__job-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 0.24rem;
|
||||
margin-bottom: 0.24rem;
|
||||
}
|
||||
|
||||
&__card-left {
|
||||
&__job-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* 公司行 */
|
||||
&__company-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.08rem;
|
||||
margin-bottom: 0.08rem;
|
||||
}
|
||||
|
||||
&__company-icon {
|
||||
width: 0.28rem;
|
||||
height: 0.28rem;
|
||||
border-radius: 0.06rem;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: $bg-middle;
|
||||
flex-shrink: 0;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 0.18rem;
|
||||
height: 0.18rem;
|
||||
color: $text-middle;
|
||||
}
|
||||
}
|
||||
|
||||
&__company-name {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 500;
|
||||
color: $text-dark;
|
||||
}
|
||||
|
||||
&__time {
|
||||
font-size: 0.12rem;
|
||||
color: $text-light;
|
||||
margin-left: 0.06rem;
|
||||
}
|
||||
|
||||
/* 岗位标题 */
|
||||
&__job-title {
|
||||
font-size: 0.17rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.24rem;
|
||||
font-weight: 520;
|
||||
color: $text-dark;
|
||||
margin: 0.06rem 0 0.1rem;
|
||||
line-height: 0.32rem;
|
||||
margin: 0 0 0.08rem;
|
||||
}
|
||||
|
||||
/* 元信息 */
|
||||
&__meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.16rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&__meta-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.04rem;
|
||||
font-size: 0.12rem;
|
||||
color: $text-middle;
|
||||
}
|
||||
|
||||
&__meta-icon {
|
||||
width: 0.14rem;
|
||||
height: 0.14rem;
|
||||
flex-shrink: 0;
|
||||
line-height: 0.16rem;
|
||||
font-weight: 330;
|
||||
}
|
||||
|
||||
/* 匹配度环 */
|
||||
&__match {
|
||||
position: relative;
|
||||
width: 0.6rem;
|
||||
height: 0.6rem;
|
||||
width: 0.62rem;
|
||||
height: 0.62rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -195,28 +121,141 @@
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 0.13rem;
|
||||
font-weight: 600;
|
||||
color: $text-dark;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 630;
|
||||
color: #9FD051;
|
||||
}
|
||||
|
||||
/* 内容段落 */
|
||||
&__section {
|
||||
margin-bottom: 0.2rem;
|
||||
margin-bottom: 0.24rem;
|
||||
}
|
||||
|
||||
&__section-title {
|
||||
font-size: 0.14rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 600;
|
||||
color: $text-dark;
|
||||
margin-bottom: 0.1rem;
|
||||
line-height: 0.24rem;
|
||||
margin-bottom: 0.16rem;
|
||||
|
||||
/* 加分项标题样式 */
|
||||
&--bonus {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 330;
|
||||
color: $text-dark;
|
||||
line-height: 0.19rem;
|
||||
}
|
||||
}
|
||||
|
||||
&__section-content {
|
||||
font-size: 0.13rem;
|
||||
font-size: 0.14rem;
|
||||
color: $text-middle;
|
||||
line-height: 1.8;
|
||||
line-height: 0.19rem;
|
||||
font-weight: 330;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
/* 技能标签 */
|
||||
&__tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.08rem;
|
||||
margin-bottom: 0.12rem;
|
||||
}
|
||||
|
||||
&__tag {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0.04rem 0.06rem;
|
||||
background: $bg-main;
|
||||
border-radius: 0.04rem;
|
||||
font-size: 0.12rem;
|
||||
color: $text-middle;
|
||||
line-height: 0.18rem;
|
||||
font-weight: 330;
|
||||
}
|
||||
|
||||
/* 公司概况 */
|
||||
&__company {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.12rem;
|
||||
}
|
||||
|
||||
&__company-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.12rem;
|
||||
}
|
||||
|
||||
&__company-logo {
|
||||
width: 0.48rem;
|
||||
height: 0.48rem;
|
||||
border-radius: 0.08rem;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
background: #EDF9FA;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 0.32rem;
|
||||
height: 0.32rem;
|
||||
}
|
||||
}
|
||||
|
||||
&__company-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.06rem;
|
||||
}
|
||||
|
||||
&__company-name {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
color: $text-dark;
|
||||
line-height: 0.24rem;
|
||||
}
|
||||
|
||||
&__company-detail {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 400;
|
||||
color: $text-middle;
|
||||
line-height: 0.19rem;
|
||||
}
|
||||
|
||||
&__company-desc {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 330;
|
||||
color: $text-middle;
|
||||
line-height: 0.24rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 抽屉动画 */
|
||||
.agent-job-drawer-enter-active,
|
||||
.agent-job-drawer-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
|
||||
.agent-job-drawer {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
||||
.agent-job-drawer-enter-from,
|
||||
.agent-job-drawer-leave-to {
|
||||
opacity: 0;
|
||||
|
||||
.agent-job-drawer {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,185 +1,625 @@
|
||||
@use '../variables' as *;
|
||||
|
||||
// ==================== Agent设置面板样式(精简版) ====================
|
||||
// ==================== Agent设置面板样式(重新设计) ====================
|
||||
.agent-setting-panel {
|
||||
height: 100%;
|
||||
background: $bg-middle;
|
||||
border-radius: 0.12rem;
|
||||
position: relative;
|
||||
width: 3.60rem;
|
||||
height: var(--app-height, 100vh);
|
||||
background: #FFFFFF;
|
||||
font-size: 0.14rem;
|
||||
overflow-y: auto;
|
||||
|
||||
// 隐藏滚动条
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
&::-webkit-scrollbar { display: none; }
|
||||
|
||||
// 内容区域
|
||||
&__body {
|
||||
padding: 0.28rem 0.24rem;
|
||||
// 头部标题区
|
||||
&__header {
|
||||
padding: 0.24rem 0.24rem 0;
|
||||
}
|
||||
|
||||
// 每个设置区块
|
||||
&__title {
|
||||
font-size: 0.20rem;
|
||||
font-weight: 630;
|
||||
line-height: 0.27rem;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
&__subtitle {
|
||||
margin-top: 0.04rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 330;
|
||||
line-height: 0.19rem;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
// 分隔线
|
||||
&__divider {
|
||||
width: 3.12rem;
|
||||
height: 1px;
|
||||
margin: 0.24rem auto;
|
||||
background: #F0F0F0;
|
||||
}
|
||||
|
||||
// 通用区块
|
||||
&__section {
|
||||
margin-bottom: 0.28rem;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
padding: 0 0.24rem;
|
||||
margin-bottom: 0.08rem;
|
||||
}
|
||||
|
||||
// 区块头部(标题 + 编辑按钮)
|
||||
// 区块头部
|
||||
&__section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.1rem;
|
||||
margin-bottom: 0.12rem;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.08rem;
|
||||
}
|
||||
|
||||
// 区块标题
|
||||
&__section-title {
|
||||
font-size: 0.16rem;
|
||||
font-weight: 700;
|
||||
color: $text-dark;
|
||||
font-weight: 520;
|
||||
line-height: 0.21rem;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
// 编辑按钮
|
||||
&__edit-btn {
|
||||
font-size: 0.13rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.04rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 450;
|
||||
color: $accent;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
|
||||
svg {
|
||||
width: 0.14rem;
|
||||
height: 0.14rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
// 个人资料信息
|
||||
&__profile-info {
|
||||
padding-left: 0.02rem;
|
||||
}
|
||||
|
||||
&__profile-name {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 600;
|
||||
color: $text-dark;
|
||||
margin-bottom: 0.04rem;
|
||||
}
|
||||
|
||||
&__profile-sub {
|
||||
font-size: 0.13rem;
|
||||
// 个人信息文字
|
||||
&__info-text {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 330;
|
||||
line-height: 0.19rem;
|
||||
color: $text-middle;
|
||||
}
|
||||
|
||||
// 求职目标标签
|
||||
&__goal-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.08rem;
|
||||
// 求职偏好内容
|
||||
&__goal-content {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 330;
|
||||
line-height: 0.24rem;
|
||||
color: $text-middle;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__goal-tag {
|
||||
padding: 0.06rem 0.14rem;
|
||||
border: 1px solid $accent;
|
||||
border-radius: 0.16rem;
|
||||
font-size: 0.13rem;
|
||||
color: $accent;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
// 空状态文字
|
||||
// 空状态
|
||||
&__empty-text {
|
||||
font-size: 0.13rem;
|
||||
font-size: 0.14rem;
|
||||
color: $text-light;
|
||||
}
|
||||
|
||||
// 简历选择下拉
|
||||
&__resume-select {
|
||||
width: 100%;
|
||||
margin-top: 0.06rem;
|
||||
|
||||
.el-input__wrapper {
|
||||
border-radius: 0.08rem;
|
||||
}
|
||||
}
|
||||
|
||||
// 投递偏好项
|
||||
&__pref-item {
|
||||
// 简历下拉
|
||||
&__resume-dropdown {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.12rem 0;
|
||||
padding: 0.08rem 0.12rem;
|
||||
margin-top: 0.08rem;
|
||||
background: #F3F4F6;
|
||||
border-radius: 0.08rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
& + & {
|
||||
border-top: none;
|
||||
&__resume-name {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 450;
|
||||
color: $text-middle;
|
||||
}
|
||||
|
||||
&__resume-arrow {
|
||||
width: 0.14rem;
|
||||
height: 0.14rem;
|
||||
transition: transform 0.2s;
|
||||
|
||||
&--open {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
&__pref-left {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.1rem;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
&__resume-options {
|
||||
margin-top: 0.04rem;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #F0F0F0;
|
||||
border-radius: 0.08rem;
|
||||
box-shadow: 0 0.02rem 0.08rem rgba(0, 0, 0, 0.06);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// 勾选图标
|
||||
&__pref-check {
|
||||
width: 0.2rem;
|
||||
height: 0.2rem;
|
||||
flex-shrink: 0;
|
||||
color: $text-light;
|
||||
margin-top: 0.02rem;
|
||||
&__resume-option {
|
||||
padding: 0.08rem 0.12rem;
|
||||
font-size: 0.14rem;
|
||||
color: $text-dark;
|
||||
cursor: pointer;
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
&:hover {
|
||||
background: #F6FCFC;
|
||||
}
|
||||
|
||||
&--active {
|
||||
color: $text-dark;
|
||||
color: $accent;
|
||||
background: #F6FCFC;
|
||||
}
|
||||
}
|
||||
|
||||
// 偏好文字
|
||||
&__pref-text {
|
||||
// 开关项
|
||||
&__switch-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.16rem 0;
|
||||
}
|
||||
|
||||
&__switch-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.03rem;
|
||||
gap: 0.04rem;
|
||||
}
|
||||
|
||||
&__pref-label {
|
||||
&__switch-label {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 500;
|
||||
color: $text-dark;
|
||||
font-weight: 450;
|
||||
line-height: 0.19rem;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
&__pref-desc {
|
||||
&__switch-desc {
|
||||
font-size: 0.12rem;
|
||||
color: $text-light;
|
||||
line-height: 1.4;
|
||||
font-weight: 330;
|
||||
line-height: 0.16rem;
|
||||
color: $text-middle;
|
||||
}
|
||||
|
||||
// 浏览器按钮
|
||||
// 自定义开关
|
||||
&__toggle {
|
||||
position: relative;
|
||||
width: 0.42rem;
|
||||
height: 0.24rem;
|
||||
background: #F3F4F6;
|
||||
border-radius: 0.12rem;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
flex-shrink: 0;
|
||||
|
||||
&--on {
|
||||
background: $accent;
|
||||
|
||||
.agent-setting-panel__toggle-dot {
|
||||
left: 0.20rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__toggle-dot {
|
||||
position: absolute;
|
||||
width: 0.18rem;
|
||||
height: 0.18rem;
|
||||
left: 0.04rem;
|
||||
top: 0.03rem;
|
||||
background: #FFFFFF;
|
||||
border-radius: 50%;
|
||||
transition: left 0.2s;
|
||||
}
|
||||
|
||||
// 浏览器插件按钮
|
||||
&__browser-btns {
|
||||
display: flex;
|
||||
gap: 0.1rem;
|
||||
margin-top: 0.08rem;
|
||||
gap: 0.16rem;
|
||||
margin-top: 0.12rem;
|
||||
}
|
||||
|
||||
&__browser-btn {
|
||||
padding: 0.08rem 0.2rem;
|
||||
background: $bg-white;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: 0.2rem;
|
||||
font-size: 0.13rem;
|
||||
color: $text-dark;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.04rem;
|
||||
padding: 0.12rem 0.16rem;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #F0F0F0;
|
||||
border-radius: 0.08rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 450;
|
||||
color: $text-middle;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
transition: border-color 0.2s;
|
||||
|
||||
svg {
|
||||
width: 0.16rem;
|
||||
height: 0.16rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: $accent;
|
||||
color: $accent;
|
||||
}
|
||||
|
||||
&--active {
|
||||
border-color: $accent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ==================== 编辑弹窗 ====================
|
||||
&__edit-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
z-index: 2000;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-end;
|
||||
padding-top: 1.20rem;
|
||||
padding-right: 0.30rem;
|
||||
}
|
||||
|
||||
&__edit-dialog {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: 0.24rem 0.32rem;
|
||||
gap: 0.24rem;
|
||||
width: 4.80rem;
|
||||
background: linear-gradient(180deg, #EDF9FA 0%, #FFFFFF 20.63%);
|
||||
border: 1px solid #F0F0F0;
|
||||
box-shadow: 0 0 0.16rem rgba(0, 0, 0, 0.05);
|
||||
border-radius: 0.12rem;
|
||||
font-size: 0.14rem;
|
||||
}
|
||||
|
||||
&__edit-dialog-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__edit-dialog-title {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
line-height: 0.24rem;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
&__edit-dialog-close {
|
||||
width: 0.24rem;
|
||||
height: 0.24rem;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
&__edit-dialog-body {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.16rem;
|
||||
}
|
||||
|
||||
&__edit-row {
|
||||
display: flex;
|
||||
gap: 0.08rem;
|
||||
}
|
||||
|
||||
&__edit-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.08rem;
|
||||
flex: 1;
|
||||
|
||||
&--full {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__edit-label {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 330;
|
||||
line-height: 0.19rem;
|
||||
color: $text-middle;
|
||||
}
|
||||
|
||||
&__edit-input {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
padding: 0.08rem 0.16rem;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #AEE6EA;
|
||||
border-radius: 0.08rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 330;
|
||||
line-height: 0.19rem;
|
||||
color: #1A1A1A;
|
||||
outline: none;
|
||||
transition: border-color 0.2s;
|
||||
|
||||
&:focus {
|
||||
border-color: $accent;
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
color: $text-light;
|
||||
}
|
||||
}
|
||||
|
||||
&__edit-city {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__edit-dialog-save {
|
||||
width: 100%;
|
||||
padding: 0.12rem 0.16rem;
|
||||
background: $accent;
|
||||
border: none;
|
||||
border-radius: 0.08rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 450;
|
||||
line-height: 0.19rem;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 浏览器插件安装教程抽屉 ====================
|
||||
|
||||
/* 遮罩层 */
|
||||
.agent-browser-guide-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;
|
||||
}
|
||||
|
||||
/* 抽屉主体 */
|
||||
.agent-browser-guide-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;
|
||||
padding: 0.2rem 0.24rem;
|
||||
height: 0.64rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
&__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;
|
||||
}
|
||||
|
||||
/* 内容区域 */
|
||||
&__body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0 0.32rem 0.32rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.16rem;
|
||||
}
|
||||
|
||||
/* 步骤卡片 */
|
||||
&__card {
|
||||
border: 1px solid #F0F0F0;
|
||||
border-radius: 0.12rem;
|
||||
padding: 0.16rem 0.2rem;
|
||||
}
|
||||
|
||||
&__step-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.12rem;
|
||||
margin-bottom: 0.16rem;
|
||||
}
|
||||
|
||||
&__step-num {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 0.32rem;
|
||||
height: 0.32rem;
|
||||
background: #EDF9FA;
|
||||
border-radius: 0.08rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
color: $accent;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__step-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__step-title {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
color: $text-dark;
|
||||
line-height: 0.24rem;
|
||||
margin: 0 0 0.04rem;
|
||||
}
|
||||
|
||||
&__step-desc {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 330;
|
||||
color: $text-middle;
|
||||
line-height: 0.19rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 下载按钮区域 */
|
||||
&__download-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.16rem;
|
||||
padding: 0.04rem 0.04rem 0.04rem 0.16rem;
|
||||
background: $bg-main;
|
||||
border-radius: 0.12rem;
|
||||
height: 0.44rem;
|
||||
}
|
||||
|
||||
&__download-name {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 450;
|
||||
color: $text-dark;
|
||||
line-height: 0.19rem;
|
||||
}
|
||||
|
||||
&__download-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.04rem;
|
||||
padding: 0.08rem 0.12rem;
|
||||
background: $accent;
|
||||
border: none;
|
||||
border-radius: 0.08rem;
|
||||
color: $bg-white;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 520;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: $accent-hover;
|
||||
}
|
||||
}
|
||||
|
||||
/* 浏览器链接区域 */
|
||||
&__browser-links {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.24rem;
|
||||
margin-bottom: 0.16rem;
|
||||
}
|
||||
|
||||
&__browser-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.04rem;
|
||||
padding: 0.12rem 0.16rem;
|
||||
background: $bg-white;
|
||||
border: 1px solid #F0F0F0;
|
||||
border-radius: 0.08rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 450;
|
||||
color: $text-middle;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s;
|
||||
|
||||
&:hover {
|
||||
border-color: $accent;
|
||||
}
|
||||
|
||||
svg {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
span {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
&__copy-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.04rem;
|
||||
color: $accent;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 450;
|
||||
margin-left: 0.12rem;
|
||||
}
|
||||
|
||||
/* 步骤示意图 */
|
||||
&__step-img {
|
||||
width: 100%;
|
||||
max-width: 4rem;
|
||||
border-radius: 0.08rem;
|
||||
margin-top: 0.12rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 抽屉动画 */
|
||||
.agent-browser-guide-drawer-enter-active,
|
||||
.agent-browser-guide-drawer-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
|
||||
.agent-browser-guide-drawer {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
||||
.agent-browser-guide-drawer-enter-from,
|
||||
.agent-browser-guide-drawer-leave-to {
|
||||
opacity: 0;
|
||||
|
||||
.agent-browser-guide-drawer {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
@use '../variables' as *;
|
||||
|
||||
/* 投递任务抽屉 — 从浏览器右侧弹出 */
|
||||
|
||||
/* 遮罩层 */
|
||||
.agent-task-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;
|
||||
}
|
||||
|
||||
/* 抽屉主体 */
|
||||
.agent-task-drawer {
|
||||
width: 6.4rem;
|
||||
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;
|
||||
}
|
||||
|
||||
&__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;
|
||||
}
|
||||
|
||||
/* Tab 切换按钮区域 */
|
||||
&__tabs {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.16rem;
|
||||
padding: 0 0.24rem 0.2rem;
|
||||
}
|
||||
|
||||
&__tab {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.08rem 0.12rem;
|
||||
gap: 0.04rem;
|
||||
border-radius: 0.08rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 450;
|
||||
line-height: 0.19rem;
|
||||
cursor: pointer;
|
||||
border: 1px solid #F0F0F0;
|
||||
background: $bg-white;
|
||||
color: $text-middle;
|
||||
transition: all 0.2s;
|
||||
|
||||
&--active {
|
||||
background: $accent;
|
||||
color: $bg-white;
|
||||
border-color: $accent;
|
||||
}
|
||||
}
|
||||
|
||||
/* 列表内容区域 */
|
||||
&__body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0 0.24rem 0.2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.16rem;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
&__empty {
|
||||
text-align: center;
|
||||
color: $text-light;
|
||||
font-size: 0.14rem;
|
||||
padding: 0.4rem 0;
|
||||
}
|
||||
|
||||
/* 岗位卡片 */
|
||||
&__card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.16rem 0.2rem;
|
||||
background: $bg-white;
|
||||
border: 1px solid #F0F0F0;
|
||||
border-radius: 0.08rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
&__card-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.12rem;
|
||||
}
|
||||
|
||||
/* 岗位标题 */
|
||||
&__card-title {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
color: $text-dark;
|
||||
line-height: 0.27rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 公司信息行 */
|
||||
&__card-company {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.08rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 330;
|
||||
color: $text-dark;
|
||||
line-height: 0.27rem;
|
||||
}
|
||||
|
||||
&__card-logo {
|
||||
width: 0.24rem;
|
||||
height: 0.24rem;
|
||||
border-radius: 0.04rem;
|
||||
object-fit: cover;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__card-logo-placeholder {
|
||||
width: 0.24rem;
|
||||
height: 0.24rem;
|
||||
color: $text-light;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 移出任务按钮 */
|
||||
&__remove-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.08rem 0.12rem;
|
||||
gap: 0.04rem;
|
||||
border: 1px solid $accent;
|
||||
border-radius: 0.08rem;
|
||||
background: $bg-white;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 450;
|
||||
color: $accent;
|
||||
line-height: 0.19rem;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
transition: all 0.2s;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
background: $accent;
|
||||
color: $bg-white;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 抽屉动画 */
|
||||
.agent-task-drawer-enter-active,
|
||||
.agent-task-drawer-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
|
||||
.agent-task-drawer {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
||||
.agent-task-drawer-enter-from,
|
||||
.agent-task-drawer-leave-to {
|
||||
opacity: 0;
|
||||
|
||||
.agent-task-drawer {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
&__name {
|
||||
font-size: 0.15rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
line-height: 0.22rem;
|
||||
color: $text-dark;
|
||||
}
|
||||
@@ -99,7 +99,7 @@
|
||||
|
||||
&__welcome-title {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
line-height: 0.16rem;
|
||||
color: $text-dark;
|
||||
}
|
||||
@@ -299,7 +299,7 @@
|
||||
|
||||
&__topics-title {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
line-height: 0.19rem;
|
||||
color: #52CAD1;
|
||||
}
|
||||
|
||||
@@ -1,145 +1,125 @@
|
||||
@use '../variables' as *;
|
||||
|
||||
// ==================== 求职偏好弹窗样式(重新设计) ====================
|
||||
|
||||
// 遮罩层 — 右上角定位
|
||||
.job-goal-dialog__overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
z-index: 2000;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-end;
|
||||
padding-top: 1.20rem;
|
||||
padding-right: 0.30rem;
|
||||
}
|
||||
|
||||
.job-goal-dialog {
|
||||
.el-dialog__header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 0;
|
||||
}
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: 0.24rem 0.32rem;
|
||||
gap: 0.24rem;
|
||||
width: 4.80rem;
|
||||
background: linear-gradient(180deg, #EDF9FA 0%, #FFFFFF 20.63%);
|
||||
border: 1px solid #F0F0F0;
|
||||
box-shadow: 0 0 0.16rem rgba(0, 0, 0, 0.05);
|
||||
border-radius: 0.12rem;
|
||||
font-size: 0.14rem;
|
||||
|
||||
// 头部
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.12rem;
|
||||
padding: 0.2rem 0.24rem 0.16rem;
|
||||
}
|
||||
|
||||
&__close-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
color: $text-dark;
|
||||
font-size: 0.16rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.04rem;
|
||||
border-radius: 0.04rem;
|
||||
transition: background 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: $bg-main;
|
||||
}
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 0.16rem;
|
||||
font-weight: 700;
|
||||
color: $text-dark;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
line-height: 0.24rem;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
&__close-btn {
|
||||
width: 0.24rem;
|
||||
height: 0.24rem;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
// 表单区块
|
||||
&__section {
|
||||
padding: 0.12rem 0.24rem;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.08rem;
|
||||
}
|
||||
|
||||
&__label {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 600;
|
||||
color: $text-dark;
|
||||
margin-bottom: 0.12rem;
|
||||
}
|
||||
|
||||
&__tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.08rem;
|
||||
margin-bottom: 0.1rem;
|
||||
}
|
||||
|
||||
&__tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.06rem;
|
||||
background: $bg-main;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: 0.16rem;
|
||||
padding: 0.05rem 0.12rem;
|
||||
font-size: 0.13rem;
|
||||
color: $text-dark;
|
||||
}
|
||||
|
||||
&__tag-close {
|
||||
cursor: pointer;
|
||||
font-size: 0.12rem;
|
||||
color: $text-light;
|
||||
transition: color 0.2s;
|
||||
|
||||
&:hover {
|
||||
color: $danger;
|
||||
}
|
||||
}
|
||||
|
||||
&__select {
|
||||
width: 100%;
|
||||
|
||||
.el-select__wrapper {
|
||||
background: $bg-main;
|
||||
border-radius: 0.08rem;
|
||||
box-shadow: none;
|
||||
border: 1px solid $border-color;
|
||||
}
|
||||
font-weight: 330;
|
||||
line-height: 0.19rem;
|
||||
color: $text-middle;
|
||||
}
|
||||
|
||||
// 招聘类型按钮组
|
||||
&__type-group {
|
||||
display: flex;
|
||||
gap: 0.12rem;
|
||||
gap: 0.10rem;
|
||||
}
|
||||
|
||||
&__type-btn {
|
||||
flex: 1;
|
||||
padding: 0.1rem 0;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: 0.2rem;
|
||||
background: $bg-white;
|
||||
color: $text-dark;
|
||||
font-size: 0.13rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.08rem 0.16rem;
|
||||
width: 0.96rem;
|
||||
height: 0.35rem;
|
||||
background: #F3F4F6;
|
||||
border: none;
|
||||
border-radius: 0.08rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 330;
|
||||
color: #1A1A1A;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
border-color: $text-light;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&--active {
|
||||
background: $btn-dark;
|
||||
border-color: $btn-dark;
|
||||
color: $bg-white;
|
||||
font-weight: 500;
|
||||
background: $accent;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
&__footer {
|
||||
padding: 0.3rem 0.24rem 0.24rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
// 保存按钮
|
||||
&__save-btn {
|
||||
width: 100%;
|
||||
padding: 0.12rem 0;
|
||||
padding: 0.12rem 0.16rem;
|
||||
background: $accent;
|
||||
color: $bg-white;
|
||||
border: none;
|
||||
border-radius: 0.24rem;
|
||||
font-size: 0.16rem;
|
||||
font-weight: 600;
|
||||
border-radius: 0.08rem;
|
||||
font-size: 0.14rem;
|
||||
font-weight: 450;
|
||||
line-height: 0.19rem;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
transition: opacity 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: $accent-hover;
|
||||
opacity: 0.85;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,7 +524,7 @@
|
||||
|
||||
&__gap-item-title {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
color: $text-dark;
|
||||
line-height: 0.19rem;
|
||||
margin-bottom: 0.04rem;
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
font-size: 0.18rem;
|
||||
line-height: 0.24rem;
|
||||
color: $text-dark;
|
||||
@@ -196,7 +196,7 @@
|
||||
font-size: 0.1rem;
|
||||
padding: 0.02rem 0.08rem;
|
||||
border-radius: 0.08rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
}
|
||||
|
||||
&__plan-name {
|
||||
@@ -360,7 +360,7 @@
|
||||
}
|
||||
|
||||
&__payment-text {
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
font-size: 0.12rem;
|
||||
line-height: 0.18rem;
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
}
|
||||
|
||||
&__stat-num {
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
font-size: 0.24rem;
|
||||
line-height: 0.32rem;
|
||||
background: linear-gradient(128.17deg, #52CAD1 0%, #82D79B 100%);
|
||||
@@ -107,7 +107,7 @@
|
||||
}
|
||||
|
||||
&__section-text {
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
font-size: 0.16rem;
|
||||
line-height: 0.21rem;
|
||||
background: linear-gradient(128.17deg, #52CAD1 0%, #82D79B 100%);
|
||||
@@ -159,7 +159,7 @@
|
||||
}
|
||||
|
||||
&__reason-title {
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.19rem;
|
||||
color: $text-dark;
|
||||
@@ -195,7 +195,7 @@
|
||||
}
|
||||
|
||||
&__direction-name {
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.19rem;
|
||||
color: $text-dark;
|
||||
@@ -234,7 +234,7 @@
|
||||
background: linear-gradient(128.17deg, #52CAD1 0%, #82D79B 100%);
|
||||
border-radius: 0.12rem;
|
||||
border: none;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.19rem;
|
||||
color: $bg-white;
|
||||
@@ -383,7 +383,7 @@
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
font-size: 0.18rem;
|
||||
line-height: 0.24rem;
|
||||
color: #1A1A1A;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
line-height: 1.5;
|
||||
background: #F7F7F7;
|
||||
border-radius: 0.12rem;
|
||||
padding: 0.1rem;
|
||||
padding: 0.16rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
// 表单内容区
|
||||
@@ -305,7 +305,7 @@
|
||||
|
||||
// AI润色结果区域
|
||||
&__ai-result {
|
||||
margin-top: 0.16rem;
|
||||
margin-top: 0.04rem;
|
||||
}
|
||||
|
||||
&__ai-result-label {
|
||||
@@ -317,7 +317,7 @@
|
||||
|
||||
&__ai-result-card {
|
||||
padding: 0.1rem 0.12rem;
|
||||
background: linear-gradient(to bottom,#F5FFFD,#ffffff);
|
||||
background: linear-gradient(to bottom, #EDF9FA 0, #fff 0.5rem);
|
||||
border-radius: 0.06rem;
|
||||
}
|
||||
|
||||
@@ -438,13 +438,13 @@
|
||||
}
|
||||
|
||||
&__save-btn {
|
||||
padding: 0.06rem 0.2rem;
|
||||
padding: 0.06rem 0.24rem;
|
||||
font-size: 0.13rem;
|
||||
font-weight: 600;
|
||||
color: $bg-white;
|
||||
background: $btn-dark;
|
||||
border: none;
|
||||
border-radius: 0.2rem;
|
||||
border-radius: 0.08rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
@@ -454,13 +454,13 @@
|
||||
}
|
||||
|
||||
&__cancel-btn {
|
||||
padding: 0.06rem 0.2rem;
|
||||
padding: 0.06rem 0.24rem;
|
||||
font-size: 0.13rem;
|
||||
font-weight: 600;
|
||||
color: $accent;
|
||||
background: transparent;
|
||||
border: 1px solid $accent;
|
||||
border-radius: 0.2rem;
|
||||
border-radius: 0.08rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
|
||||
@@ -112,29 +112,30 @@
|
||||
|
||||
// ---- 卡片容器 ----
|
||||
&__card {
|
||||
background: transparent;
|
||||
background: #fff;
|
||||
border-radius: 0.1rem;
|
||||
padding: 0.16rem;
|
||||
border: 1px solid $border-color;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&--ai {
|
||||
border: 1px solid rgba($accent, 0.3);
|
||||
|
||||
/* 顶部渐变背景层,不遮挡内容 */
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 0.1rem;
|
||||
background: linear-gradient(to bottom, #EDF9FA 0, #fff 0.5rem);
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 顶部渐变背景层,不遮挡内容 */
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 0.1rem;
|
||||
background: linear-gradient(to bottom, #EDF9FA 0, #fff 0.8rem);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
|
||||
/* 让卡片内所有内容在渐变之上 */
|
||||
> * {
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
|
||||
&__mcard-title {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
color: #FFFFFF;
|
||||
line-height: 0.24rem;
|
||||
|
||||
@@ -242,7 +242,7 @@
|
||||
|
||||
&__mcard-remain-days {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
color: #FFFFFF;
|
||||
line-height: 0.24rem;
|
||||
}
|
||||
@@ -328,7 +328,7 @@
|
||||
|
||||
&__feedback-label {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
color: #1A1A1A;
|
||||
line-height: 0.19rem;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
&__title {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
line-height: 0.24rem;
|
||||
color: $text-dark;
|
||||
margin: 0;
|
||||
@@ -217,7 +217,7 @@
|
||||
|
||||
span {
|
||||
font-size: 0.14rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
line-height: 0.19rem;
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
.side-nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 2rem;
|
||||
width: 2.2rem;
|
||||
height: var(--app-height, 100vh);
|
||||
background: $bg-white;
|
||||
color: #fff;
|
||||
@@ -88,7 +88,7 @@
|
||||
}
|
||||
|
||||
&__item-label {
|
||||
flex: 1;
|
||||
|
||||
}
|
||||
|
||||
&__badge {
|
||||
@@ -100,6 +100,26 @@
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 索引0菜单项的"全网"小标签 */
|
||||
&__tag-quanwang {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.02rem 0.04rem;
|
||||
min-width: 0.28rem;
|
||||
height: 0.17rem;
|
||||
background: linear-gradient(128.17deg, #52CAD1 0%, #82D79B 100%);
|
||||
border-radius: 0.04rem;
|
||||
font-family: 'MiSans';
|
||||
font-style: normal;
|
||||
font-weight: 620;
|
||||
font-size: 0.10rem;
|
||||
line-height: 0.13rem;
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -192,7 +212,7 @@
|
||||
flex-shrink: 0;
|
||||
|
||||
span:first-child {
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
font-size: 0.18rem;
|
||||
line-height: 0.24rem;
|
||||
color: $text-dark;
|
||||
@@ -264,7 +284,7 @@
|
||||
}
|
||||
|
||||
.side-nav__message-list-title {
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
font-size: 0.14rem;
|
||||
line-height: 0.19rem;
|
||||
color: $text-dark;
|
||||
@@ -504,7 +524,7 @@
|
||||
|
||||
.side-nav__referral-value {
|
||||
font-size: 0.10rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
color: #52CAD1;
|
||||
line-height: 0.13rem;
|
||||
}
|
||||
@@ -544,7 +564,7 @@
|
||||
|
||||
.side-nav__referral-action {
|
||||
font-size: 0.11rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
color: #52CAD1;
|
||||
line-height: 0.15rem;
|
||||
text-align: center;
|
||||
@@ -596,7 +616,7 @@
|
||||
padding: 0.02rem 0.04rem;
|
||||
border-radius: 0.04rem;
|
||||
font-size: 0.10rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
line-height: 0.13rem;
|
||||
width: fit-content;
|
||||
|
||||
@@ -672,6 +692,19 @@
|
||||
padding: 0.16rem;
|
||||
background: linear-gradient(180deg, #EDF9FA 0%, #FFFFFF 38.18%);
|
||||
border-radius: 0.08rem 0.08rem 0 0;
|
||||
|
||||
/* 正式会员背景 */
|
||||
&--formal {
|
||||
background: linear-gradient(180deg, #EDF9FA 0%, #FFFFFF 38.18%);
|
||||
}
|
||||
/* 试用会员背景 */
|
||||
&--trial {
|
||||
background: linear-gradient(180deg, #FEF5E7 0%, #FFFFFF 38.18%);
|
||||
}
|
||||
/* 免费用户背景 */
|
||||
&--free {
|
||||
background: linear-gradient(180deg, #F1F2F4 0%, #FFFFFF 38.18%);
|
||||
}
|
||||
}
|
||||
|
||||
.side-nav__account-popup-header-row {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
font-size: 0.14rem;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 2000;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -49,7 +49,7 @@
|
||||
}
|
||||
|
||||
.step-progress-overlay__title {
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
font-size: 0.18rem;
|
||||
line-height: 0.24rem;
|
||||
color: $text-dark;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
// 主内容区域
|
||||
&__content {
|
||||
margin-left: 2rem;
|
||||
margin-left: 2.2rem;
|
||||
flex: 1;
|
||||
padding: 0.4rem 0.6rem;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// ==================== 岗位详情页 ====================
|
||||
.job-detail {
|
||||
&__content {
|
||||
margin-left: 2rem;
|
||||
margin-left: 2.2rem;
|
||||
margin-right: var(--chat-width, 3.6rem);
|
||||
flex: 1;
|
||||
height: var(--app-height, 100vh);
|
||||
@@ -227,7 +227,7 @@
|
||||
|
||||
&__match-label {
|
||||
font-size: 0.13rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
line-height: 0.17rem;
|
||||
color: #9FD051;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
display: flex;
|
||||
|
||||
&__content {
|
||||
margin-left: 2rem;
|
||||
margin-left: 2.2rem;
|
||||
margin-right: var(--chat-width, 3.6rem);
|
||||
flex: 1;
|
||||
padding-bottom: 0.18rem;
|
||||
@@ -131,10 +131,25 @@
|
||||
&__ai-tip {
|
||||
position: relative;
|
||||
background: $bg-white;
|
||||
border: 1px solid $accent;
|
||||
border-radius: 0.08rem;
|
||||
padding: 0.08rem 0.12rem 0.07rem 0.12rem;
|
||||
z-index: 1;
|
||||
|
||||
// 渐变边框:从上到下 #9FD051 → #52CAD1(与导师页 stats 一致)
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 0.08rem;
|
||||
padding: 0.01rem;
|
||||
background: linear-gradient(180deg, #9FD051 0%, #52CAD1 100%);
|
||||
-webkit-mask:
|
||||
linear-gradient(#fff 0 0) content-box,
|
||||
linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask-composite: exclude;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
// 提示条内容行
|
||||
@@ -334,7 +349,7 @@
|
||||
|
||||
&__job-name {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
color: #000000;
|
||||
line-height: 0.24rem;
|
||||
}
|
||||
@@ -665,7 +680,7 @@
|
||||
|
||||
&__match-score {
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
line-height: 0.62rem;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -677,7 +692,7 @@
|
||||
|
||||
&__match-level {
|
||||
font-size: 0.13rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
line-height: 0.19rem;
|
||||
margin-top: 0.04rem;
|
||||
}
|
||||
@@ -843,7 +858,7 @@
|
||||
&__apply-method-title {
|
||||
position: relative;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 520;
|
||||
font-weight: 620;
|
||||
color: $text-dark;
|
||||
text-align: center;
|
||||
margin: 0 0 0.2rem 0;
|
||||
|
||||
@@ -401,12 +401,12 @@
|
||||
|
||||
.login-view__otp-box--active {
|
||||
background: #F3FFFD;
|
||||
border: 2px solid #12C7BE;
|
||||
border: 2px solid $accent;
|
||||
}
|
||||
|
||||
.login-view__otp-box--filled {
|
||||
background: #F3FFFD;
|
||||
border: 2px solid #12C7BE;
|
||||
border: 2px solid $accent;
|
||||
}
|
||||
|
||||
.login-view__otp-digit {
|
||||
@@ -421,7 +421,7 @@
|
||||
display: inline-block;
|
||||
width: 2px;
|
||||
height: 0.28rem;
|
||||
background: #12C7BE;
|
||||
background: $accent;
|
||||
border-radius: 1px;
|
||||
animation: login-otp-blink 1s ease-in-out infinite;
|
||||
}
|
||||
@@ -451,7 +451,7 @@
|
||||
.login-view__status-btn {
|
||||
width: 100%;
|
||||
height: 0.4rem;
|
||||
background: linear-gradient(90deg, #12C7BE 0%, #06B6D4 100%);
|
||||
background: linear-gradient(90deg, $btn-dark 0%, $btn-dark-hover 100%);
|
||||
border-radius: 0.12rem;
|
||||
border: none;
|
||||
font-weight: 600;
|
||||
@@ -565,7 +565,7 @@
|
||||
transition: border-color 0.2s;
|
||||
|
||||
&:hover {
|
||||
border-color: #12C7BE;
|
||||
border-color: $accent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,7 +593,7 @@
|
||||
.login-view__upload-btn {
|
||||
height: 0.4rem;
|
||||
line-height: 0.4rem;
|
||||
background: linear-gradient(90deg, #12C7BE 0%, #06B6D4 100%);
|
||||
background: linear-gradient(90deg, $btn-dark 0%, $btn-dark-hover 100%);
|
||||
border: none;
|
||||
border-radius: 0.08rem;
|
||||
font-size: 0.16rem;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
margin-left: 2rem;
|
||||
margin-left: 2.2rem;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
margin-left: 2rem;
|
||||
margin-left: 2.2rem;
|
||||
}
|
||||
|
||||
// 左侧主内容区
|
||||
@@ -63,17 +63,48 @@
|
||||
margin-top: 0.02rem;
|
||||
}
|
||||
|
||||
// 推荐搜索标签
|
||||
&__quick-tags {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.08rem;
|
||||
margin-right: 0.16rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&__quick-label {
|
||||
font-size: 0.13rem;
|
||||
color: $text-middle;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__quick-tag {
|
||||
font-size: 0.12rem;
|
||||
color: $accent;
|
||||
border: 0.012rem solid $accent;
|
||||
border-radius: 0.04rem;
|
||||
padding: 0.03rem 0.08rem;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
background: #fff;
|
||||
transition: background 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: #EDF9FA;
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索框
|
||||
&__search-wrap {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 2.8rem;
|
||||
width: 3rem;
|
||||
background: $bg-white;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: 0.2rem;
|
||||
border-radius: 0.08rem;
|
||||
padding: 0 0.12rem;
|
||||
height: 0.36rem;
|
||||
height: 0.32rem;
|
||||
|
||||
&:focus-within {
|
||||
border-color: $accent;
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
// ==================== 个人资料页 ====================
|
||||
.profile-page {
|
||||
&__content {
|
||||
margin-left: 2rem;
|
||||
margin-left: 2.2rem;
|
||||
flex: 1;
|
||||
padding: 0.12rem 0.36rem;
|
||||
padding-bottom: 0.12rem;
|
||||
height: var(--app-height, 100vh);
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
// 页面标题区
|
||||
&__header {
|
||||
margin-bottom: 0.16rem;
|
||||
padding: 0.16rem 0.24rem;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
&__title {
|
||||
@@ -51,6 +52,7 @@
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
margin: 0.16rem 0.24rem;
|
||||
}
|
||||
|
||||
// 右侧边栏
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// ==================== 简历详情页 ====================
|
||||
.resume-detail {
|
||||
&__content {
|
||||
margin-left: 2rem;
|
||||
margin-left: 2.2rem;
|
||||
flex: 1;
|
||||
padding-bottom: 0.24rem;
|
||||
height: var(--app-height, 100vh);
|
||||
@@ -21,7 +21,7 @@
|
||||
margin-bottom: 0.16rem;
|
||||
background: #fff;
|
||||
>h2{
|
||||
font-size: 0.24rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 700;
|
||||
color: $text-dark;
|
||||
}
|
||||
@@ -116,8 +116,7 @@
|
||||
justify-content: space-between;
|
||||
background: $bg-white;
|
||||
border-radius: 0.12rem;
|
||||
padding: 0.18rem 0.24rem;
|
||||
padding-top: 0.3rem;
|
||||
padding: 0.28rem 0.32rem;
|
||||
margin-bottom: 0.16rem;
|
||||
|
||||
/* B/C/D 评级渐变背景 */
|
||||
@@ -305,7 +304,7 @@
|
||||
&__card {
|
||||
background: $bg-white;
|
||||
border-radius: 0.1rem;
|
||||
margin: 0.4rem 0.18rem;
|
||||
margin: 0.24rem 0.18rem;
|
||||
|
||||
&:hover .resume-detail__section-header {
|
||||
background: #F0FAFA;
|
||||
@@ -445,7 +444,7 @@
|
||||
bottom: 0.02rem;
|
||||
width: 100%;
|
||||
height: 0.06rem;
|
||||
background: #12C7BE;
|
||||
background: $accent;
|
||||
border-radius: 0.02rem;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// ==================== 简历列表页 ====================
|
||||
.resume-page {
|
||||
&__content {
|
||||
margin-left: 2rem;
|
||||
margin-left: 2.2rem;
|
||||
flex: 1;
|
||||
height: var(--app-height, 100vh);
|
||||
box-sizing: border-box;
|
||||
@@ -23,7 +23,7 @@
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 0.24rem;
|
||||
font-size: 0.18rem;
|
||||
font-weight: 700;
|
||||
color: $text-dark;
|
||||
margin: 0;
|
||||
@@ -138,6 +138,13 @@
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s;
|
||||
}
|
||||
|
||||
&--ellipsis {
|
||||
max-width: 3.6rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
&__row:hover &__td--action {
|
||||
@@ -166,6 +173,10 @@
|
||||
|
||||
&__name {
|
||||
font-weight: 500;
|
||||
max-width: 3.6rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__default-tag {
|
||||
|
||||
@@ -1,88 +1,153 @@
|
||||
<template>
|
||||
<!-- 申请进度消息组件 -->
|
||||
<div class="agent-apply-progress">
|
||||
<!-- 顶部标题栏 -->
|
||||
<div class="agent-apply-progress__header">
|
||||
<!-- 三重状态:投递完成 / 暂停投递 / 开始投递 -->
|
||||
<span
|
||||
class="agent-apply-progress__title"
|
||||
:class="{ 'agent-apply-progress__title--clickable': titleClickable }"
|
||||
@click="handleTitleClick"
|
||||
>{{ titleText }}</span>
|
||||
<span v-if="currentStep < 4" class="agent-apply-progress__cancel" @click="handleCancel">取消</span>
|
||||
</div>
|
||||
|
||||
<!-- 岗位信息卡片 -->
|
||||
<div class="agent-apply-progress__job-card">
|
||||
<div class="agent-apply-progress__job-icon">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<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>
|
||||
<!-- 投递进度卡片组件(新版4步骤) -->
|
||||
<div class="agent-apply-progress" :class="{ 'agent-apply-progress--completed': isCompleted }">
|
||||
<!-- 顶部:岗位信息 + 步骤条 -->
|
||||
<div class="agent-apply-progress__top">
|
||||
<!-- 左侧岗位名称和公司 -->
|
||||
<div class="agent-apply-progress__job-info">
|
||||
<div class="agent-apply-progress__job-company">{{ jobInfo?.companyShortName || jobInfo?.companyName || '' }}</div>
|
||||
<div class="agent-apply-progress__job-title">{{ jobInfo?.title || '' }}</div>
|
||||
<span class="agent-apply-progress__job-title">{{ jobInfo?.title || '' }}</span>
|
||||
<div class="agent-apply-progress__company">
|
||||
<img
|
||||
v-if="(jobInfo as any)?.companyLogoUrl"
|
||||
:src="(jobInfo as any).companyLogoUrl"
|
||||
class="agent-apply-progress__company-logo"
|
||||
alt="logo"
|
||||
/>
|
||||
<div v-else class="agent-apply-progress__company-logo agent-apply-progress__company-logo--placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="none"><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>
|
||||
<span class="agent-apply-progress__company-name">{{ jobInfo?.companyShortName || jobInfo?.companyName || '' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧步骤条 -->
|
||||
<div class="agent-apply-progress__steps">
|
||||
<!-- 第1步:优化简历 -->
|
||||
<div class="agent-apply-progress__step-item">
|
||||
<div class="agent-apply-progress__step-icon" :class="stepIconClass(1)">
|
||||
<!-- 已完成图标 -->
|
||||
<svg v-if="currentStep > 1" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_517_2052)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.875 2.08333C11.875 2.02808 11.8531 1.97509 11.814 1.93602C11.7749 1.89695 11.7219 1.875 11.6667 1.875H5.83335C5.22557 1.875 4.64267 2.11644 4.2129 2.54621C3.78313 2.97598 3.54169 3.55888 3.54169 4.16667V15.8333C3.54169 16.4411 3.78313 17.024 4.2129 17.4538C4.64267 17.8836 5.22557 18.125 5.83335 18.125H14.1667C14.7745 18.125 15.3574 17.8836 15.7871 17.4538C16.2169 17.024 16.4584 16.4411 16.4584 15.8333V7.6225C16.4584 7.56725 16.4364 7.51426 16.3973 7.47519C16.3583 7.43612 16.3053 7.41417 16.25 7.41417H12.5C12.3343 7.41417 12.1753 7.34832 12.0581 7.23111C11.9409 7.1139 11.875 6.95493 11.875 6.78917V2.08333ZM12.5 10.2083C12.6658 10.2083 12.8248 10.2742 12.942 10.3914C13.0592 10.5086 13.125 10.6676 13.125 10.8333C13.125 10.9991 13.0592 11.1581 12.942 11.2753C12.8248 11.3925 12.6658 11.4583 12.5 11.4583H7.50002C7.33426 11.4583 7.17529 11.3925 7.05808 11.2753C6.94087 11.1581 6.87502 10.9991 6.87502 10.8333C6.87502 10.6676 6.94087 10.5086 7.05808 10.3914C7.17529 10.2742 7.33426 10.2083 7.50002 10.2083H12.5ZM12.5 13.5417C12.6658 13.5417 12.8248 13.6075 12.942 13.7247C13.0592 13.8419 13.125 14.0009 13.125 14.1667C13.125 14.3324 13.0592 14.4914 12.942 14.6086C12.8248 14.7258 12.6658 14.7917 12.5 14.7917H7.50002C7.33426 14.7917 7.17529 14.7258 7.05808 14.6086C6.94087 14.4914 6.87502 14.3324 6.87502 14.1667C6.87502 14.0009 6.94087 13.8419 7.05808 13.7247C7.17529 13.6075 7.33426 13.5417 7.50002 13.5417H12.5Z" fill="white"/>
|
||||
<path d="M13.125 2.35322C13.125 2.19988 13.2858 2.10238 13.405 2.19822C13.5061 2.27988 13.5958 2.37488 13.6742 2.48322L16.185 5.98072C16.2417 6.06072 16.18 6.16405 16.0817 6.16405H13.3333C13.2781 6.16405 13.2251 6.1421 13.186 6.10303C13.1469 6.06396 13.125 6.01097 13.125 5.95572V2.35322Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_517_2052">
|
||||
<rect width="20" height="20" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<!-- 进行中/待处理图标:简历 -->
|
||||
<svg v-else width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_481_4042)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.875 2.08333C11.875 2.02808 11.8531 1.97509 11.814 1.93602C11.7749 1.89695 11.7219 1.875 11.6667 1.875H5.83335C5.22557 1.875 4.64267 2.11644 4.2129 2.54621C3.78313 2.97598 3.54169 3.55888 3.54169 4.16667V15.8333C3.54169 16.4411 3.78313 17.024 4.2129 17.4538C4.64267 17.8836 5.22557 18.125 5.83335 18.125H14.1667C14.7745 18.125 15.3574 17.8836 15.7871 17.4538C16.2169 17.024 16.4584 16.4411 16.4584 15.8333V7.6225C16.4584 7.56725 16.4364 7.51426 16.3973 7.47519C16.3583 7.43612 16.3053 7.41417 16.25 7.41417H12.5C12.3343 7.41417 12.1753 7.34832 12.0581 7.23111C11.9409 7.1139 11.875 6.95493 11.875 6.78917V2.08333ZM12.5 10.2083C12.6658 10.2083 12.8248 10.2742 12.942 10.3914C13.0592 10.5086 13.125 10.6676 13.125 10.8333C13.125 10.9991 13.0592 11.1581 12.942 11.2753C12.8248 11.3925 12.6658 11.4583 12.5 11.4583H7.50002C7.33426 11.4583 7.17529 11.3925 7.05808 11.2753C6.94087 11.1581 6.87502 10.9991 6.87502 10.8333C6.87502 10.6676 6.94087 10.5086 7.05808 10.3914C7.17529 10.2742 7.33426 10.2083 7.50002 10.2083H12.5ZM12.5 13.5417C12.6658 13.5417 12.8248 13.6075 12.942 13.7247C13.0592 13.8419 13.125 14.0009 13.125 14.1667C13.125 14.3324 13.0592 14.4914 12.942 14.6086C12.8248 14.7258 12.6658 14.7917 12.5 14.7917H7.50002C7.33426 14.7917 7.17529 14.7258 7.05808 14.6086C6.94087 14.4914 6.87502 14.3324 6.87502 14.1667C6.87502 14.0009 6.94087 13.8419 7.05808 13.7247C7.17529 13.6075 7.33426 13.5417 7.50002 13.5417H12.5Z" fill="currentColor"/>
|
||||
<path d="M13.125 2.35322C13.125 2.19988 13.2858 2.10238 13.405 2.19822C13.5061 2.27988 13.5958 2.37488 13.6742 2.48322L16.185 5.98072C16.2417 6.06072 16.18 6.16405 16.0817 6.16405H13.3333C13.2781 6.16405 13.2251 6.1421 13.186 6.10303C13.1469 6.06396 13.125 6.01097 13.125 5.95572V2.35322Z" fill="currentColor"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_481_4042">
|
||||
<rect width="20" height="20" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="agent-apply-progress__step-text">
|
||||
<span class="agent-apply-progress__step-name" :class="stepNameClass(1)">优化简历</span>
|
||||
<span class="agent-apply-progress__step-status" :class="stepStatusClass(1)">{{ stepStatusText(1) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 连接线 -->
|
||||
<div class="agent-apply-progress__step-line"></div>
|
||||
|
||||
<!-- 第2步:匹配分析 -->
|
||||
<div class="agent-apply-progress__step-item">
|
||||
<div class="agent-apply-progress__step-icon" :class="stepIconClass(2)">
|
||||
<svg v-if="currentStep > 2" width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.84365 2.87333C6.34198 1.415 8.35698 1.37083 8.94782 2.74083L8.99782 2.87417L9.67032 4.84083C9.82444 5.29186 10.0735 5.70459 10.4007 6.05119C10.7279 6.39778 11.1256 6.67018 11.567 6.85L11.7478 6.9175L13.7145 7.58917C15.1728 8.0875 15.217 10.1025 13.8478 10.6933L13.7145 10.7433L11.7478 11.4158C11.2966 11.5699 10.8837 11.8189 10.537 12.146C10.1903 12.4732 9.91773 12.871 9.73782 13.3125L9.67032 13.4925L8.99865 15.46C8.50032 16.9183 6.48531 16.9625 5.89531 15.5933L5.84365 15.46L5.17198 13.4933C5.01796 13.0422 4.76896 12.6293 4.44177 12.2825C4.11457 11.9358 3.71681 11.6632 3.27532 11.4833L3.09531 11.4158L1.12865 10.7442C-0.330519 10.2458 -0.374685 8.23083 0.995315 7.64083L1.12865 7.58917L3.09531 6.9175C3.54634 6.76338 3.95907 6.51433 4.30567 6.18714C4.65226 5.85995 4.92466 5.46224 5.10448 5.02083L5.17198 4.84083L5.84365 2.87333ZM14.0878 1.50573e-07C14.2437 -1.96643e-07 14.3965 0.0437319 14.5288 0.126226C14.6611 0.208721 14.7676 0.326669 14.8362 0.466667L14.8761 0.564167L15.1678 1.41917L16.0236 1.71083C16.1799 1.76391 16.3168 1.86218 16.4172 1.99318C16.5175 2.12418 16.5767 2.28202 16.5872 2.44668C16.5977 2.61135 16.5592 2.77544 16.4763 2.91816C16.3935 3.06087 16.2702 3.17578 16.122 3.24833L16.0236 3.28833L15.1686 3.58L14.877 4.43583C14.8238 4.59202 14.7255 4.72892 14.5944 4.82916C14.4634 4.92941 14.3055 4.98849 14.1409 4.99894C13.9762 5.00938 13.8121 4.9707 13.6695 4.88782C13.5268 4.80493 13.412 4.68156 13.3395 4.53333L13.2995 4.43583L13.0078 3.58083L12.152 3.28917C11.9957 3.23609 11.8588 3.13782 11.7585 3.00682C11.6581 2.87582 11.599 2.71799 11.5884 2.55332C11.5779 2.38865 11.6165 2.22456 11.6993 2.08184C11.7821 1.93913 11.9054 1.82422 12.0536 1.75167L12.152 1.71167L13.007 1.42L13.2986 0.564167C13.3548 0.399521 13.4612 0.256591 13.6027 0.155416C13.7442 0.0542408 13.9138 -0.000104401 14.0878 1.50573e-07Z" fill="white"/>
|
||||
</svg>
|
||||
<!-- 匹配分析图标 -->
|
||||
<svg v-else width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.84365 2.87333C6.34198 1.415 8.35698 1.37083 8.94782 2.74083L8.99782 2.87417L9.67032 4.84083C9.82444 5.29186 10.0735 5.70459 10.4007 6.05119C10.7279 6.39778 11.1256 6.67018 11.567 6.85L11.7478 6.9175L13.7145 7.58917C15.1728 8.0875 15.217 10.1025 13.8478 10.6933L13.7145 10.7433L11.7478 11.4158C11.2966 11.5699 10.8837 11.8189 10.537 12.146C10.1903 12.4732 9.91773 12.871 9.73782 13.3125L9.67032 13.4925L8.99865 15.46C8.50032 16.9183 6.48531 16.9625 5.89531 15.5933L5.84365 15.46L5.17198 13.4933C5.01796 13.0422 4.76896 12.6293 4.44177 12.2825C4.11457 11.9358 3.71681 11.6632 3.27532 11.4833L3.09531 11.4158L1.12865 10.7442C-0.330519 10.2458 -0.374685 8.23083 0.995315 7.64083L1.12865 7.58917L3.09531 6.9175C3.54634 6.76338 3.95907 6.51433 4.30567 6.18714C4.65226 5.85995 4.92466 5.46224 5.10448 5.02083L5.17198 4.84083L5.84365 2.87333ZM14.0878 1.50573e-07C14.2437 -1.96643e-07 14.3965 0.0437319 14.5288 0.126226C14.6611 0.208721 14.7676 0.326669 14.8362 0.466667L14.8761 0.564167L15.1678 1.41917L16.0236 1.71083C16.1799 1.76391 16.3168 1.86218 16.4172 1.99318C16.5175 2.12418 16.5767 2.28202 16.5872 2.44668C16.5977 2.61135 16.5592 2.77544 16.4763 2.91816C16.3935 3.06087 16.2702 3.17578 16.122 3.24833L16.0236 3.28833L15.1686 3.58L14.877 4.43583C14.8238 4.59202 14.7255 4.72892 14.5944 4.82916C14.4634 4.92941 14.3055 4.98849 14.1409 4.99894C13.9762 5.00938 13.8121 4.9707 13.6695 4.88782C13.5268 4.80493 13.412 4.68156 13.3395 4.53333L13.2995 4.43583L13.0078 3.58083L12.152 3.28917C11.9957 3.23609 11.8588 3.13782 11.7585 3.00682C11.6581 2.87582 11.599 2.71799 11.5884 2.55332C11.5779 2.38865 11.6165 2.22456 11.6993 2.08184C11.7821 1.93913 11.9054 1.82422 12.0536 1.75167L12.152 1.71167L13.007 1.42L13.2986 0.564167C13.3548 0.399521 13.4612 0.256591 13.6027 0.155416C13.7442 0.0542408 13.9138 -0.000104401 14.0878 1.50573e-07Z" fill="#6A7282"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="agent-apply-progress__step-text">
|
||||
<span class="agent-apply-progress__step-name" :class="stepNameClass(2)">匹配分析</span>
|
||||
<span class="agent-apply-progress__step-status" :class="stepStatusClass(2)">{{ stepStatusText(2) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 连接线 -->
|
||||
<div class="agent-apply-progress__step-line"></div>
|
||||
|
||||
<!-- 第3步:前往投递 -->
|
||||
<div class="agent-apply-progress__step-item">
|
||||
<div class="agent-apply-progress__step-icon" :class="stepIconClass(3)">
|
||||
<svg v-if="currentStep > 3" width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.5965 1.67729C14.9565 0.681458 13.9915 -0.283541 12.9957 0.0772919L0.824837 4.47896C-0.17433 4.84063 -0.295164 6.20396 0.624003 6.73646L4.509 8.98563L7.97817 5.51646C8.13534 5.36466 8.34584 5.28066 8.56434 5.28256C8.78283 5.28446 8.99185 5.3721 9.14635 5.52661C9.30086 5.68112 9.3885 5.89013 9.3904 6.10862C9.3923 6.32712 9.3083 6.53762 9.1565 6.69479L5.68734 10.164L7.93734 14.049C8.469 14.9681 9.83234 14.8465 10.194 13.8481L14.5965 1.67729Z" fill="white"/>
|
||||
</svg>
|
||||
<!-- 前往投递图标:箭头 -->
|
||||
<svg v-else width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.5965 1.67729C14.9565 0.681458 13.9915 -0.283541 12.9957 0.0772919L0.824837 4.47896C-0.17433 4.84063 -0.295164 6.20396 0.624003 6.73646L4.509 8.98563L7.97817 5.51646C8.13534 5.36466 8.34584 5.28066 8.56434 5.28256C8.78283 5.28446 8.99185 5.3721 9.14635 5.52661C9.30086 5.68112 9.3885 5.89013 9.3904 6.10862C9.3923 6.32712 9.3083 6.53762 9.1565 6.69479L5.68734 10.164L7.93734 14.049C8.469 14.9681 9.83234 14.8465 10.194 13.8481L14.5965 1.67729Z" fill="#6A7282"/>
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
<div class="agent-apply-progress__step-text">
|
||||
<span class="agent-apply-progress__step-name" :class="stepNameClass(3)">前往投递</span>
|
||||
<span class="agent-apply-progress__step-status" :class="stepStatusClass(3)">{{ stepStatusText(3) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 连接线 -->
|
||||
<div class="agent-apply-progress__step-line"></div>
|
||||
|
||||
<!-- 第4步:结果确认 -->
|
||||
<div class="agent-apply-progress__step-item">
|
||||
<div class="agent-apply-progress__step-icon" :class="stepIconClass(4)">
|
||||
<svg v-if="currentStep > 4" width="15" height="17" viewBox="0 0 15 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.83333 13.3333L2.5 10L3.675 8.825L5.83333 10.975L11.325 5.48333L12.5 6.66667M7.5 1.66667C7.72101 1.66667 7.93297 1.75446 8.08926 1.91074C8.24554 2.06702 8.33333 2.27899 8.33333 2.5C8.33333 2.72101 8.24554 2.93298 8.08926 3.08926C7.93297 3.24554 7.72101 3.33333 7.5 3.33333C7.27899 3.33333 7.06702 3.24554 6.91074 3.08926C6.75446 2.93298 6.66667 2.72101 6.66667 2.5C6.66667 2.27899 6.75446 2.06702 6.91074 1.91074C7.06702 1.75446 7.27899 1.66667 7.5 1.66667ZM13.3333 1.66667H9.85C9.5 0.7 8.58333 0 7.5 0C6.41667 0 5.5 0.7 5.15 1.66667H1.66667C1.22464 1.66667 0.800716 1.84226 0.488155 2.15482C0.175595 2.46738 0 2.89131 0 3.33333V15C0 15.442 0.175595 15.8659 0.488155 16.1785C0.800716 16.4911 1.22464 16.6667 1.66667 16.6667H13.3333C13.7754 16.6667 14.1993 16.4911 14.5118 16.1785C14.8244 15.8659 15 15.442 15 15V3.33333C15 2.89131 14.8244 2.46738 14.5118 2.15482C14.1993 1.84226 13.7754 1.66667 13.3333 1.66667Z" fill="white"/>
|
||||
</svg>
|
||||
<!-- 结果确认图标:勾选框 -->
|
||||
<svg v-else width="15" height="17" viewBox="0 0 15 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.83333 13.3333L2.5 10L3.675 8.825L5.83333 10.975L11.325 5.48333L12.5 6.66667M7.5 1.66667C7.72101 1.66667 7.93297 1.75446 8.08926 1.91074C8.24554 2.06702 8.33333 2.27899 8.33333 2.5C8.33333 2.72101 8.24554 2.93298 8.08926 3.08926C7.93297 3.24554 7.72101 3.33333 7.5 3.33333C7.27899 3.33333 7.06702 3.24554 6.91074 3.08926C6.75446 2.93298 6.66667 2.72101 6.66667 2.5C6.66667 2.27899 6.75446 2.06702 6.91074 1.91074C7.06702 1.75446 7.27899 1.66667 7.5 1.66667ZM13.3333 1.66667H9.85C9.5 0.7 8.58333 0 7.5 0C6.41667 0 5.5 0.7 5.15 1.66667H1.66667C1.22464 1.66667 0.800716 1.84226 0.488155 2.15482C0.175595 2.46738 0 2.89131 0 3.33333V15C0 15.442 0.175595 15.8659 0.488155 16.1785C0.800716 16.4911 1.22464 16.6667 1.66667 16.6667H13.3333C13.7754 16.6667 14.1993 16.4911 14.5118 16.1785C14.8244 15.8659 15 15.442 15 15V3.33333C15 2.89131 14.8244 2.46738 14.5118 2.15482C14.1993 1.84226 13.7754 1.66667 13.3333 1.66667Z" fill="#6A7282"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="agent-apply-progress__step-text">
|
||||
<span class="agent-apply-progress__step-name" :class="stepNameClass(4)">结果确认</span>
|
||||
<span class="agent-apply-progress__step-status" :class="stepStatusClass(4)">{{ stepStatusText(4) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 步骤列表 -->
|
||||
<div class="agent-apply-progress__steps">
|
||||
<!-- 第1步:优化简历 -->
|
||||
<div class="agent-apply-progress__step">
|
||||
<div class="agent-apply-progress__step-check" :class="{ 'agent-apply-progress__step-check--done': currentStep > 1 }">
|
||||
<svg v-if="currentStep > 1" viewBox="0 0 16 16" fill="none"><path d="M3 8l4 4 6-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<span class="agent-apply-progress__step-label">优化简历</span>
|
||||
</div>
|
||||
<!-- 底部:提示文字 + 操作按钮 -->
|
||||
<div class="agent-apply-progress__bottom">
|
||||
<!-- 提示文字 -->
|
||||
<span class="agent-apply-progress__hint" :class="hintClass">{{ hintText }}</span>
|
||||
|
||||
<!-- 第2步:确认简历 -->
|
||||
<div class="agent-apply-progress__step">
|
||||
<div class="agent-apply-progress__step-check" :class="{ 'agent-apply-progress__step-check--done': currentStep > 2 }">
|
||||
<svg v-if="currentStep > 2" viewBox="0 0 16 16" fill="none"><path d="M3 8l4 4 6-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<span class="agent-apply-progress__step-label">确认简历</span>
|
||||
<!-- 第2步展开内容:简历确认区域 -->
|
||||
<div v-if="currentStep === 2" class="agent-apply-progress__step-content">
|
||||
<div class="agent-apply-progress__resume-confirm">
|
||||
<div class="agent-apply-progress__resume-file">
|
||||
<svg viewBox="0 0 24 24" fill="none" class="agent-apply-progress__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>
|
||||
<span class="agent-apply-progress__resume-name">{{ resumeName }}</span>
|
||||
</div>
|
||||
<button class="agent-apply-progress__confirm-btn" :disabled="paused" @click="handleConfirmResume">确定</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 操作按钮区域 -->
|
||||
<div v-if="showActions" class="agent-apply-progress__actions">
|
||||
<!-- 第1步完成:查看优化简历 + 确认简历 -->
|
||||
<template v-if="currentStep === 1 && stepPhase === 'done'">
|
||||
<button class="agent-apply-progress__btn agent-apply-progress__btn--outline" @click="handleViewResume">查看优化简历</button>
|
||||
<button class="agent-apply-progress__btn agent-apply-progress__btn--primary" @click="handleConfirmResume">确认简历</button>
|
||||
</template>
|
||||
|
||||
<!-- 第3步:分析投递页面 -->
|
||||
<div class="agent-apply-progress__step">
|
||||
<div class="agent-apply-progress__step-check" :class="{ 'agent-apply-progress__step-check--done': currentStep > 3 }">
|
||||
<svg v-if="currentStep > 3" viewBox="0 0 16 16" fill="none"><path d="M3 8l4 4 6-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<span class="agent-apply-progress__step-label">分析投递页面</span>
|
||||
<!-- 第3步展开内容:投递操作区域 -->
|
||||
<div v-if="currentStep === 3" class="agent-apply-progress__step-content">
|
||||
<div class="agent-apply-progress__apply-area">
|
||||
<p class="agent-apply-progress__apply-desc">该职位仅支持在申请网站原地址使用自动填充功能。</p>
|
||||
<p class="agent-apply-progress__apply-desc">请点击"去投递",打开申请网站,我们的自动填写插件将自动弹出。</p>
|
||||
<p class="agent-apply-progress__apply-desc">点击"自动填写",核对信息并提交申请,然后返回本页点击"我已申请"继续。</p>
|
||||
<div class="agent-apply-progress__apply-actions">
|
||||
<span class="agent-apply-progress__skip-btn" :class="{ 'agent-apply-progress__skip-btn--disabled': paused }" @click="handleSkip">跳过</span>
|
||||
<button class="agent-apply-progress__applied-btn" :disabled="paused" @click="handleApplied">我已投递</button>
|
||||
<button class="agent-apply-progress__goto-btn" :disabled="paused" @click="handleGoApply">去投递</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 第2步匹配度偏低:不投递 + 继续投递 -->
|
||||
<template v-if="currentStep === 2 && stepPhase === 'low-match'">
|
||||
<button class="agent-apply-progress__btn agent-apply-progress__btn--outline" @click="handleNotApply">不投递</button>
|
||||
<button class="agent-apply-progress__btn agent-apply-progress__btn--primary" @click="handleContinueApply">继续投递</button>
|
||||
</template>
|
||||
|
||||
<!-- 第4步:提交申请 -->
|
||||
<div class="agent-apply-progress__step">
|
||||
<div class="agent-apply-progress__step-check" :class="{ 'agent-apply-progress__step-check--done': currentStep > 3 }">
|
||||
<svg v-if="currentStep > 3" viewBox="0 0 16 16" fill="none"><path d="M3 8l4 4 6-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</div>
|
||||
<span class="agent-apply-progress__step-label">提交申请</span>
|
||||
<!-- 第3步:前往投递 -->
|
||||
<template v-if="currentStep === 3 && stepPhase === 'ready'">
|
||||
<button class="agent-apply-progress__btn agent-apply-progress__btn--primary" @click="handleGoApply">前往投递</button>
|
||||
</template>
|
||||
|
||||
<!-- 第4步:不投递 + 已投递 -->
|
||||
<template v-if="currentStep === 4 && stepPhase === 'confirm'">
|
||||
<button class="agent-apply-progress__btn agent-apply-progress__btn--outline" @click="handleNotApply">不投递</button>
|
||||
<button class="agent-apply-progress__btn agent-apply-progress__btn--primary" @click="handleApplied">已投递</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -97,81 +162,137 @@ import type { JobListItem } from '@/api/jobs'
|
||||
const props = defineProps<{
|
||||
/** 岗位信息 */
|
||||
jobInfo: JobListItem | null
|
||||
/** 当前步骤(1-4,大于该步骤表示已完成) */
|
||||
/** 当前步骤(1-4,大于4表示全部完成) */
|
||||
currentStep: number
|
||||
/** 简历名称(第2步确认时显示) */
|
||||
resumeName?: string
|
||||
/** 是否暂停状态 */
|
||||
paused?: boolean
|
||||
/** 当前步骤的阶段:loading=请求中, done=完成可操作, low-match=匹配度偏低, ready=准备就绪, confirm=待确认 */
|
||||
stepPhase?: 'loading' | 'done' | 'low-match' | 'ready' | 'confirm'
|
||||
/** 匹配度分数(第2步用) */
|
||||
matchScore?: number
|
||||
/** 投递完成时间(第4步完成后显示) */
|
||||
completedTime?: string
|
||||
}>()
|
||||
|
||||
// ==================== 计算属性 ====================
|
||||
|
||||
/** 标题文字:投递完成 / 暂停投递 / 开始投递 */
|
||||
const titleText = computed(() => {
|
||||
if (props.currentStep >= 4) return '投递完成'
|
||||
if (props.paused && props.currentStep > 1) return '开始投递'
|
||||
if (!props.paused && props.currentStep > 1) return '暂停投递'
|
||||
return '开始投递'
|
||||
/** 是否为已完成状态 */
|
||||
const isCompleted = computed(() => props.currentStep > 4)
|
||||
|
||||
/** 提示文字 */
|
||||
const hintText = computed(() => {
|
||||
if (isCompleted.value && props.completedTime) {
|
||||
return `投递时间:${props.completedTime}`
|
||||
}
|
||||
if (props.currentStep === 1) {
|
||||
if (props.stepPhase === 'done') return '已完成岗位专属简历优化,请确认本次投递使用的简历'
|
||||
return '正在根据岗位信息优化简历...'
|
||||
}
|
||||
if (props.currentStep === 2) {
|
||||
if (props.stepPhase === 'low-match') return `当前匹配度偏低:${props.matchScore ?? 0}分,是否仍要继续投递?`
|
||||
return '正在根据最终投递简历复核岗位匹配度...'
|
||||
}
|
||||
if (props.currentStep === 3) {
|
||||
return '已准备好投递信息,请前往招聘官网完成申请'
|
||||
}
|
||||
if (props.currentStep === 4) {
|
||||
return '请确认该岗位是否已经完成投递'
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
/** 标题是否可点击(暂停投递 或 暂停后的开始投递) */
|
||||
const titleClickable = computed(() => {
|
||||
if (props.currentStep >= 4) return false
|
||||
return props.currentStep > 1
|
||||
/** 提示文字样式class */
|
||||
const hintClass = computed(() => {
|
||||
if (isCompleted.value) return ''
|
||||
if (props.currentStep === 1 && props.stepPhase === 'done') return 'agent-apply-progress__hint--warning'
|
||||
if (props.currentStep === 2 && props.stepPhase === 'low-match') return 'agent-apply-progress__hint--low-match'
|
||||
if (props.currentStep === 3) return 'agent-apply-progress__hint--accent'
|
||||
if (props.currentStep === 4) return 'agent-apply-progress__hint--accent'
|
||||
return ''
|
||||
})
|
||||
|
||||
/** 是否显示操作按钮 */
|
||||
const showActions = computed(() => {
|
||||
if (isCompleted.value) return false
|
||||
if (props.currentStep === 1 && props.stepPhase === 'done') return true
|
||||
if (props.currentStep === 2 && props.stepPhase === 'low-match') return true
|
||||
if (props.currentStep === 3 && props.stepPhase === 'ready') return true
|
||||
if (props.currentStep === 4 && props.stepPhase === 'confirm') return true
|
||||
return false
|
||||
})
|
||||
|
||||
/** 步骤图标样式class */
|
||||
function stepIconClass(step: number) {
|
||||
if (props.currentStep > step) return 'agent-apply-progress__step-icon--done'
|
||||
if (props.currentStep === step) return 'agent-apply-progress__step-icon--active'
|
||||
return 'agent-apply-progress__step-icon--pending'
|
||||
}
|
||||
|
||||
/** 步骤名称样式class */
|
||||
function stepNameClass(step: number) {
|
||||
if (props.currentStep > step) return 'agent-apply-progress__step-name--done'
|
||||
if (props.currentStep === step) return 'agent-apply-progress__step-name--active'
|
||||
return 'agent-apply-progress__step-name--pending'
|
||||
}
|
||||
|
||||
/** 步骤状态文字样式class */
|
||||
function stepStatusClass(step: number) {
|
||||
if (props.currentStep > step) return 'agent-apply-progress__step-status--done'
|
||||
if (props.currentStep === step) return 'agent-apply-progress__step-status--active'
|
||||
return 'agent-apply-progress__step-status--pending'
|
||||
}
|
||||
|
||||
/** 步骤状态文字 */
|
||||
function stepStatusText(step: number) {
|
||||
if (props.currentStep > step) return '已完成'
|
||||
if (props.currentStep === step) return '进行中'
|
||||
return '待处理'
|
||||
}
|
||||
|
||||
// ==================== 事件 ====================
|
||||
|
||||
const emit = defineEmits<{
|
||||
/** 取消投递流程 */
|
||||
(e: 'cancel'): void
|
||||
/** 确认简历(第2步) */
|
||||
/** 查看优化简历(第1步完成) */
|
||||
(e: 'viewResume'): void
|
||||
/** 确认简历(第1步完成 → 进入第2步) */
|
||||
(e: 'confirmResume'): void
|
||||
/** 跳过投递(第3步) */
|
||||
(e: 'skip'): void
|
||||
/** 我已投递(第3步) */
|
||||
(e: 'applied'): void
|
||||
/** 去投递(第3步,打开原链接) */
|
||||
/** 不投递(第2步匹配度低 或 第4步取消) */
|
||||
(e: 'notApply'): void
|
||||
/** 继续投递(第2步匹配度低时继续) */
|
||||
(e: 'continueApply'): void
|
||||
/** 前往投递(第3步) */
|
||||
(e: 'goApply'): void
|
||||
/** 暂停/恢复投递 */
|
||||
(e: 'togglePause'): void
|
||||
/** 已投递(第4步确认) */
|
||||
(e: 'applied'): void
|
||||
}>()
|
||||
|
||||
// ==================== 事件处理 ====================
|
||||
|
||||
/** 点击标题(暂停/恢复) */
|
||||
function handleTitleClick() {
|
||||
if (!titleClickable.value) return
|
||||
emit('togglePause')
|
||||
}
|
||||
|
||||
/** 取消 */
|
||||
function handleCancel() {
|
||||
emit('cancel')
|
||||
/** 查看优化简历 */
|
||||
function handleViewResume() {
|
||||
emit('viewResume')
|
||||
}
|
||||
|
||||
/** 确认简历 */
|
||||
function handleConfirmResume() {
|
||||
if (props.paused) return
|
||||
emit('confirmResume')
|
||||
}
|
||||
|
||||
/** 跳过 */
|
||||
function handleSkip() {
|
||||
if (props.paused) return
|
||||
emit('skip')
|
||||
/** 不投递 */
|
||||
function handleNotApply() {
|
||||
emit('notApply')
|
||||
}
|
||||
|
||||
/** 我已投递 */
|
||||
function handleApplied() {
|
||||
if (props.paused) return
|
||||
emit('applied')
|
||||
/** 继续投递 */
|
||||
function handleContinueApply() {
|
||||
emit('continueApply')
|
||||
}
|
||||
|
||||
/** 去投递 */
|
||||
/** 前往投递 */
|
||||
function handleGoApply() {
|
||||
if (props.paused) return
|
||||
emit('goApply')
|
||||
}
|
||||
|
||||
/** 已投递 */
|
||||
function handleApplied() {
|
||||
emit('applied')
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,106 +1,127 @@
|
||||
<template>
|
||||
<!-- Agent推荐岗位列表组件 — 展示推荐岗位卡片 -->
|
||||
<!-- Agent推荐岗位列表组件 — 展示推荐岗位卡片(可滚动) -->
|
||||
<div class="agent-chat-job-list">
|
||||
<!-- 标题 -->
|
||||
<div class="agent-chat-job-list__header">为你推荐的岗位</div>
|
||||
<!-- 推荐说明文字 -->
|
||||
<div class="agent-chat-job-list__summary">{{ summary || '根据求职目标和简历信息智能推荐' }}</div>
|
||||
|
||||
<!-- 岗位列表(显示前3个) -->
|
||||
<div
|
||||
v-for="job in displayJobs"
|
||||
:key="job.id"
|
||||
class="agent-chat-job-list__item"
|
||||
>
|
||||
<!-- 左侧:匹配度环形 + 岗位信息 -->
|
||||
<div class="agent-chat-job-list__info" @click="handleClickJob(job)">
|
||||
<!-- 匹配度环形 -->
|
||||
<div class="agent-chat-job-list__score">
|
||||
<svg class="agent-chat-job-list__ring" viewBox="0 0 44 44">
|
||||
<circle cx="22" cy="22" r="18" fill="none" stroke="#E8E8E8" stroke-width="3" />
|
||||
<circle
|
||||
cx="22" cy="22" r="18" fill="none"
|
||||
stroke="#4FC2C9" stroke-width="3"
|
||||
stroke-linecap="round"
|
||||
:stroke-dasharray="2 * Math.PI * 18"
|
||||
:stroke-dashoffset="2 * Math.PI * 18 * (1 - (job.matchScore || 0) / 100)"
|
||||
transform="rotate(-90 22 22)"
|
||||
/>
|
||||
</svg>
|
||||
<span class="agent-chat-job-list__score-text">{{ job.matchScore || 0 }}%</span>
|
||||
</div>
|
||||
<!-- 岗位详情 -->
|
||||
<div class="agent-chat-job-list__detail">
|
||||
<div class="agent-chat-job-list__title-row">
|
||||
<span class="agent-chat-job-list__title">{{ job.title }}</span>
|
||||
<span v-if="job.companyShortName || job.companyName" class="agent-chat-job-list__company-dot">●</span>
|
||||
<span class="agent-chat-job-list__company">{{ job.companyShortName || job.companyName }}</span>
|
||||
<!-- 岗位列表(可滚动区域,默认展示约3.5个高度) -->
|
||||
<div class="agent-chat-job-list__scroll">
|
||||
<div
|
||||
v-for="job in jobs"
|
||||
:key="job.id"
|
||||
class="agent-chat-job-list__item"
|
||||
@click="handleClickJob(job)"
|
||||
>
|
||||
<!-- 左侧:匹配度方块 + 岗位信息 -->
|
||||
<div class="agent-chat-job-list__left">
|
||||
<!-- 匹配度环形 -->
|
||||
<div class="agent-chat-job-list__score">
|
||||
<svg class="agent-chat-job-list__ring" viewBox="0 0 62 62">
|
||||
<circle cx="31" cy="31" r="27" fill="none" stroke="#E9F4D7" stroke-width="4" />
|
||||
<circle
|
||||
cx="31" cy="31" r="27" fill="none"
|
||||
stroke="#9FD051" stroke-width="4"
|
||||
stroke-linecap="round"
|
||||
:stroke-dasharray="2 * Math.PI * 27"
|
||||
:stroke-dashoffset="2 * Math.PI * 27 * (1 - (job.matchScore || 0) / 100)"
|
||||
transform="rotate(-90 31 31)"
|
||||
/>
|
||||
</svg>
|
||||
<span class="agent-chat-job-list__score-text">{{ job.matchScore || 0 }}%</span>
|
||||
</div>
|
||||
<!-- 标签 -->
|
||||
<div class="agent-chat-job-list__tags">
|
||||
<span v-if="job.regionName" class="agent-chat-job-list__tag">{{ job.regionName }}</span>
|
||||
<span v-if="job.categoryName" class="agent-chat-job-list__tag">{{ job.categoryName }}</span>
|
||||
<span v-for="tag in job.tags?.slice(0, 2)" :key="tag" class="agent-chat-job-list__tag">{{ tag }}</span>
|
||||
<!-- 岗位详情 -->
|
||||
<div class="agent-chat-job-list__detail">
|
||||
<!-- 第一行:岗位名称 + 公司 -->
|
||||
<div class="agent-chat-job-list__title-row">
|
||||
<span class="agent-chat-job-list__title">{{ job.title }}</span>
|
||||
<!-- 公司信息 -->
|
||||
<span v-if="job.companyShortName || job.companyName" class="agent-chat-job-list__company">
|
||||
<img v-if="job.companyLogoUrl" :src="job.companyLogoUrl" class="agent-chat-job-list__company-logo" alt="" />
|
||||
<span class="agent-chat-job-list__company-name">{{ job.companyShortName || job.companyName }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- 第二行:标签(地区、学历、招聘类型等) -->
|
||||
<div class="agent-chat-job-list__tags">
|
||||
<span v-if="job.regionName" class="agent-chat-job-list__tag agent-chat-job-list__tag--location">
|
||||
<svg viewBox="0 0 16 16" fill="none" width="14" height="14"><path d="M8 1.5A4.5 4.5 0 0 0 3.5 6C3.5 9.5 8 14.5 8 14.5s4.5-5 4.5-8.5A4.5 4.5 0 0 0 8 1.5Z" stroke="currentColor" stroke-width="1.2"/><circle cx="8" cy="6" r="1.5" stroke="currentColor" stroke-width="1.2"/></svg>
|
||||
{{ job.regionName }}
|
||||
</span>
|
||||
<span v-if="formatEducation(job.education)" class="agent-chat-job-list__tag">{{ formatEducation(job.education) }}</span>
|
||||
<span v-if="formatEmploymentType(job.recruitCategory)" class="agent-chat-job-list__tag agent-chat-job-list__tag--category">{{ formatEmploymentType(job.recruitCategory) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:操作按钮 -->
|
||||
<div class="agent-chat-job-list__actions">
|
||||
<!-- 不再推荐 -->
|
||||
<span class="agent-chat-job-list__dismiss-btn" @click.stop="handleDismiss(job)">不再推荐</span>
|
||||
<!-- 添加/已加入按钮 -->
|
||||
<button
|
||||
v-if="job.applicationStatus === -1"
|
||||
class="agent-chat-job-list__add-btn agent-chat-job-list__add-btn--added"
|
||||
disabled
|
||||
>✓已加入</button>
|
||||
<button
|
||||
v-else
|
||||
class="agent-chat-job-list__add-btn"
|
||||
:disabled="loadingJobIds.includes(job.id)"
|
||||
@click.stop="handleAdd(job)"
|
||||
>+ 加入投递</button>
|
||||
<!-- 右侧:操作按钮 -->
|
||||
<div class="agent-chat-job-list__actions" @click.stop>
|
||||
<!-- 不再推荐按钮(已加入时不显示) -->
|
||||
<button
|
||||
v-if="job.applicationStatus !== -1"
|
||||
class="agent-chat-job-list__dismiss-btn"
|
||||
@click="handleDismiss(job)"
|
||||
>不再推荐</button>
|
||||
<!-- 已加入状态 -->
|
||||
<button
|
||||
v-if="job.applicationStatus === -1"
|
||||
class="agent-chat-job-list__add-btn agent-chat-job-list__add-btn--added"
|
||||
disabled
|
||||
>
|
||||
<svg viewBox="0 0 16 16" fill="none" width="14" height="14"><path d="M3 8.5l3.5 3.5 6.5-7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
已加入
|
||||
</button>
|
||||
<!-- 加入投递按钮 -->
|
||||
<button
|
||||
v-else
|
||||
class="agent-chat-job-list__add-btn"
|
||||
:disabled="loadingJobIds?.includes(job.id)"
|
||||
@click="handleAdd(job)"
|
||||
>
|
||||
<svg viewBox="0 0 16 16" fill="none" width="14" height="14"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
加入投递
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<div class="color-9" v-if="displayJobs.length === 0">
|
||||
暂无相关职位推荐
|
||||
</div>
|
||||
<div v-if="jobs.length === 0" class="agent-chat-job-list__empty">暂无相关职位推荐</div>
|
||||
|
||||
<!-- 底部按钮区域 -->
|
||||
<div v-if="displayJobs.length > 0" class="agent-chat-job-list__footer">
|
||||
<div v-if="jobs.length > 0" class="agent-chat-job-list__footer">
|
||||
<!-- 换一批按钮 -->
|
||||
<button class="agent-chat-job-list__refresh-btn" :disabled="refreshing" @click="handleRefresh">
|
||||
<svg viewBox="0 0 16 16" fill="none" width="16" height="16"><path d="M2.5 8a5.5 5.5 0 0 1 9.9-3.2M13.5 8a5.5 5.5 0 0 1-9.9 3.2" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/><path d="M12 2v3h-3M4 14v-3h3" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
{{ refreshing ? '加载中...' : '换一批' }}
|
||||
</button>
|
||||
<!-- 全部添加按钮 -->
|
||||
<button class="agent-chat-job-list__add-all-btn" @click="handleAddAll">全部添加</button>
|
||||
<button class="agent-chat-job-list__add-all-btn" @click="handleAddAll">
|
||||
<svg viewBox="0 0 16 16" fill="none" width="16" height="16"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
全部添加
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import type { AgentRecommendJob } from '@/api/agent'
|
||||
import { formatEducation, formatEmploymentType } from '@/stores/index'
|
||||
|
||||
/** 组件 Props */
|
||||
const props = defineProps<{
|
||||
/** 推荐说明文字 */
|
||||
summary: string
|
||||
/** 当前展示的岗位列表数据(父组件已随机抽取10个) */
|
||||
/** 当前展示的岗位列表数据 */
|
||||
jobs: AgentRecommendJob[]
|
||||
/** 正在请求中的岗位 ID 列表 */
|
||||
loadingJobIds?: number[]
|
||||
loadingJobIds?: (string | number)[]
|
||||
/** 是否正在换一批加载中 */
|
||||
refreshing?: boolean
|
||||
}>()
|
||||
|
||||
/** 事件 */
|
||||
const emit = defineEmits<{
|
||||
/** 点击查看全部岗位(打开右侧面板) */
|
||||
(e: 'viewAll'): void
|
||||
/** 点击岗位查看详情 */
|
||||
(e: 'clickJob', job: AgentRecommendJob): void
|
||||
/** 添加单个岗位到待投递 */
|
||||
@@ -113,9 +134,6 @@ const emit = defineEmits<{
|
||||
(e: 'dismiss', job: AgentRecommendJob): void
|
||||
}>()
|
||||
|
||||
/** 只显示前3个岗位 */
|
||||
const displayJobs = computed(() => props.jobs.slice(0, 3))
|
||||
|
||||
/** 点击岗位 — 通知父组件打开岗位预览 */
|
||||
function handleClickJob(job: AgentRecommendJob) {
|
||||
emit('clickJob', job)
|
||||
|
||||
@@ -1,118 +1,121 @@
|
||||
<template>
|
||||
<!-- Agent岗位预览面板 — 右侧面板显示岗位详情 -->
|
||||
<div class="agent-job-preview-panel" v-loading="loading" element-loading-text="加载中...">
|
||||
<!-- 顶部标题栏 -->
|
||||
<div class="agent-job-preview-panel__header">
|
||||
<div class="agent-job-preview-panel__back" @click="handleBack">
|
||||
<svg viewBox="0 0 16 16" fill="none" class="agent-job-preview-panel__back-icon">
|
||||
<path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<span>岗位详情</span>
|
||||
</div>
|
||||
<!-- 添加按钮 — 仅未投递时显示 -->
|
||||
<button
|
||||
v-if="jobDetail && (jobDetail.applicationStatus === null || jobDetail.applicationStatus === undefined)"
|
||||
class="agent-job-preview-panel__add-btn"
|
||||
:disabled="addLoading"
|
||||
@click="handleAdd"
|
||||
>+ 添加</button>
|
||||
<!-- 移出按钮 — 仅待投递状态时显示 -->
|
||||
<button
|
||||
v-else-if="jobDetail && jobDetail.applicationStatus === -1"
|
||||
class="agent-job-preview-panel__remove-btn"
|
||||
:disabled="addLoading"
|
||||
@click="handleRemove"
|
||||
>移出</button>
|
||||
</div>
|
||||
|
||||
<!-- 岗位详情内容 -->
|
||||
<div v-if="jobDetail" class="agent-job-preview-panel__body">
|
||||
<!-- 岗位卡片 -->
|
||||
<div class="agent-job-preview-panel__card">
|
||||
<div class="agent-job-preview-panel__card-top">
|
||||
<!-- 左侧信息 -->
|
||||
<div class="agent-job-preview-panel__card-left">
|
||||
<div class="agent-job-preview-panel__company-row">
|
||||
<div class="agent-job-preview-panel__company-icon">
|
||||
<img v-if="jobDetail.companyLogoUrl" :src="jobDetail.companyLogoUrl" :alt="jobDetail.companyShortName" />
|
||||
<svg v-else viewBox="0 0 24 24" fill="none">
|
||||
<rect x="3" y="7" width="18" height="14" rx="2" stroke="currentColor" stroke-width="1.5"/>
|
||||
<path d="M7 7V5a2 2 0 012-2h6a2 2 0 012 2v2" stroke="currentColor" stroke-width="1.5"/>
|
||||
<!-- Agent岗位预览抽屉 — 从浏览器右侧弹出 -->
|
||||
<Teleport to="body">
|
||||
<Transition name="agent-job-drawer">
|
||||
<div v-if="visible" class="agent-job-drawer-mask" @click.self="handleBack">
|
||||
<div class="agent-job-drawer" v-loading="loading" element-loading-text="加载中...">
|
||||
<!-- 顶部标题栏 -->
|
||||
<div class="agent-job-drawer__header border-F0F0F0-bottom-1">
|
||||
<div class="agent-job-drawer__header-left">
|
||||
<!-- 关闭按钮 -->
|
||||
<div class="agent-job-drawer__close" @click="handleBack">
|
||||
<svg viewBox="0 0 24 24" fill="none" class="agent-job-drawer__close-icon">
|
||||
<path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="agent-job-preview-panel__company-name">{{ jobDetail.companyShortName || jobDetail.companyName }}</span>
|
||||
<span class="agent-job-preview-panel__time">{{ formatTime }}</span>
|
||||
</div>
|
||||
<h3 class="agent-job-preview-panel__job-title">{{ jobDetail.jobTitle }}</h3>
|
||||
<!-- 岗位元信息 -->
|
||||
<div class="agent-job-preview-panel__meta">
|
||||
<span v-if="jobDetail.regionName" class="agent-job-preview-panel__meta-item">
|
||||
<svg viewBox="0 0 16 16" fill="none" class="agent-job-preview-panel__meta-icon">
|
||||
<circle cx="8" cy="6.5" r="2.5" stroke="currentColor" stroke-width="1.2"/>
|
||||
<path d="M8 14s-5-4-5-7.5a5 5 0 0110 0C13 10 8 14 8 14z" stroke="currentColor" stroke-width="1.2"/>
|
||||
</svg>
|
||||
{{ jobDetail.regionName }}
|
||||
</span>
|
||||
<span class="agent-job-preview-panel__meta-item">
|
||||
<svg viewBox="0 0 16 16" fill="none" class="agent-job-preview-panel__meta-icon">
|
||||
<rect x="2" y="3" width="12" height="11" rx="1.5" stroke="currentColor" stroke-width="1.2"/>
|
||||
<path d="M2 6.5h12" stroke="currentColor" stroke-width="1.2"/>
|
||||
</svg>
|
||||
{{ formatEmploymentType(jobDetail.employmentType) }}
|
||||
</span>
|
||||
<span v-if="jobDetail.salary" class="agent-job-preview-panel__meta-item">
|
||||
<svg viewBox="0 0 16 16" fill="none" class="agent-job-preview-panel__meta-icon">
|
||||
<path d="M8 1v14M4 4h8M3 8h10M5 12h6" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
{{ jobDetail.salary }}
|
||||
</span>
|
||||
<span class="agent-job-drawer__title">岗位详情</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧匹配度环 -->
|
||||
<div class="agent-job-preview-panel__match">
|
||||
<svg viewBox="0 0 60 60" class="agent-job-preview-panel__ring-svg">
|
||||
<circle cx="30" cy="30" r="25" stroke-width="4" stroke="#E8E8E8" fill="none" />
|
||||
<circle cx="30" cy="30" r="25" stroke-width="4" fill="none"
|
||||
stroke="#4FC2C9" stroke-linecap="round"
|
||||
:stroke-dasharray="2 * Math.PI * 25"
|
||||
:stroke-dashoffset="2 * Math.PI * 25 * (1 - (jobDetail.matchScore || 0) / 100)"
|
||||
transform="rotate(-90 30 30)"
|
||||
/>
|
||||
</svg>
|
||||
<span class="agent-job-preview-panel__match-text">{{ jobDetail.matchScore || 0 }}%</span>
|
||||
|
||||
<!-- 岗位详情内容 -->
|
||||
<div v-if="jobDetail" class="agent-job-drawer__body">
|
||||
<!-- 岗位标题区域 -->
|
||||
<div class="agent-job-drawer__job-header">
|
||||
<!-- 左侧信息 -->
|
||||
<div class="agent-job-drawer__job-info">
|
||||
<h2 class="agent-job-drawer__job-title">{{ jobDetail.jobTitle }}</h2>
|
||||
<!-- 岗位元信息 -->
|
||||
<div class="agent-job-drawer__meta">
|
||||
<span v-if="jobDetail.regionName">{{ jobDetail.regionName }}</span>
|
||||
<span v-if="jobDetail.regionName && formatExperience"> · </span>
|
||||
<span v-if="formatExperience">{{ formatExperience }}</span>
|
||||
<span v-if="formatExperience && formatRecruitCategory"> · </span>
|
||||
<span v-if="formatRecruitCategory">{{ formatRecruitCategory }}</span>
|
||||
<span v-if="formatRecruitCategory && formatEducation"> · </span>
|
||||
<span v-if="formatEducation">{{ formatEducation }}</span>
|
||||
<span v-if="formatEducation && jobDetail.salary"> · </span>
|
||||
<span v-if="jobDetail.salary">{{ jobDetail.salary }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧匹配度环 -->
|
||||
<div class="agent-job-drawer__match">
|
||||
<svg viewBox="0 0 62 62" class="agent-job-drawer__ring-svg">
|
||||
<circle cx="31" cy="31" r="27" stroke-width="4" stroke="#E8E8E8" fill="none" />
|
||||
<circle cx="31" cy="31" r="27" stroke-width="4" fill="none"
|
||||
stroke="#9FD051" stroke-linecap="round"
|
||||
:stroke-dasharray="2 * Math.PI * 27"
|
||||
:stroke-dashoffset="2 * Math.PI * 27 * (1 - (jobDetail.matchScore || 0) / 100)"
|
||||
transform="rotate(-90 31 31)"
|
||||
/>
|
||||
</svg>
|
||||
<span class="agent-job-drawer__match-text">{{ jobDetail.matchScore || 0 }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 岗位职责 -->
|
||||
<div v-if="jobDetail.description" class="agent-job-drawer__section">
|
||||
<h4 class="agent-job-drawer__section-title">岗位职责</h4>
|
||||
<div class="agent-job-drawer__section-content">{{ jobDetail.description }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 任职要求 -->
|
||||
<div v-if="jobDetail.requirement || (jobDetail.skillTags && jobDetail.skillTags.length)" class="agent-job-drawer__section">
|
||||
<h4 class="agent-job-drawer__section-title">任职要求</h4>
|
||||
<!-- 技能标签 -->
|
||||
<div v-if="jobDetail.skillTags && jobDetail.skillTags.length" class="agent-job-drawer__tags">
|
||||
<span v-for="tag in jobDetail.skillTags" :key="tag" class="agent-job-drawer__tag">{{ tag }}</span>
|
||||
</div>
|
||||
<div v-if="jobDetail.requirement" class="agent-job-drawer__section-content">{{ jobDetail.requirement }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 加分项 -->
|
||||
<div v-if="jobDetail.bonus" class="agent-job-drawer__section">
|
||||
<h4 class="agent-job-drawer__section-title agent-job-drawer__section-title--bonus">加分项:{{ jobDetail.bonus }}</h4>
|
||||
</div>
|
||||
|
||||
<!-- 公司概况 -->
|
||||
<div v-if="jobDetail.companyName || jobDetail.companyShortName" class="agent-job-drawer__section">
|
||||
<h4 class="agent-job-drawer__section-title">公司概况</h4>
|
||||
<div class="agent-job-drawer__company">
|
||||
<!-- 公司信息行 -->
|
||||
<div class="agent-job-drawer__company-row">
|
||||
<div class="agent-job-drawer__company-logo">
|
||||
<img v-if="jobDetail.companyLogoUrl" :src="jobDetail.companyLogoUrl" :alt="jobDetail.companyShortName" />
|
||||
<svg v-else viewBox="0 0 32 32" fill="none">
|
||||
<rect width="32" height="32" rx="4" fill="#EDF9FA"/>
|
||||
<path d="M8 12h16v12H8z" stroke="#52CAD1" stroke-width="1.5"/>
|
||||
<path d="M12 12V9a2 2 0 012-2h4a2 2 0 012 2v3" stroke="#52CAD1" stroke-width="1.5"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="agent-job-drawer__company-info">
|
||||
<span class="agent-job-drawer__company-name">{{ jobDetail.companyShortName || jobDetail.companyName }}</span>
|
||||
<span class="agent-job-drawer__company-detail">
|
||||
{{ [jobDetail.companyIndustryName, jobDetail.companyType, jobDetail.companyScale].filter(Boolean).join(' · ') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 公司简介 -->
|
||||
<div v-if="jobDetail.companySummary || jobDetail.companyDescription" class="agent-job-drawer__company-desc">
|
||||
{{ jobDetail.companySummary || jobDetail.companyDescription }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 岗位职责 -->
|
||||
<div v-if="jobDetail.description" class="agent-job-preview-panel__section">
|
||||
<h4 class="agent-job-preview-panel__section-title">岗位职责</h4>
|
||||
<div class="agent-job-preview-panel__section-content">{{ jobDetail.description }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 任职要求 -->
|
||||
<div v-if="jobDetail.requirement" class="agent-job-preview-panel__section">
|
||||
<h4 class="agent-job-preview-panel__section-title">任职要求</h4>
|
||||
<div class="agent-job-preview-panel__section-content">{{ jobDetail.requirement }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 加分项 -->
|
||||
<div v-if="jobDetail.bonus" class="agent-job-preview-panel__section">
|
||||
<h4 class="agent-job-preview-panel__section-title">加分项</h4>
|
||||
<div class="agent-job-preview-panel__section-content">{{ jobDetail.bonus }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, watch } from 'vue'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { fetchJobDetail } from '@/api/jobs'
|
||||
import type { JobDetailData } from '@/api/jobs'
|
||||
import { formatEmploymentType } from '@/stores/index'
|
||||
|
||||
/** 组件 Props */
|
||||
const props = defineProps<{
|
||||
/** 是否显示抽屉 */
|
||||
visible: boolean
|
||||
/** 岗位 ID */
|
||||
jobId: string
|
||||
/** 投递状态(用于控制添加按钮显示) */
|
||||
@@ -121,23 +124,36 @@ const props = defineProps<{
|
||||
|
||||
/** 事件 */
|
||||
const emit = defineEmits<{
|
||||
/** 返回上一个面板模式 */
|
||||
/** 关闭抽屉 */
|
||||
(e: 'back'): void
|
||||
/** 添加岗位到待投递 */
|
||||
(e: 'add', jobId: string): void
|
||||
/** 从待投递移除岗位 */
|
||||
(e: 'remove', jobId: string): void
|
||||
/** 更新visible */
|
||||
(e: 'update:visible', val: boolean): void
|
||||
}>()
|
||||
|
||||
/** 加载状态 */
|
||||
const loading = ref(false)
|
||||
|
||||
/** 添加按钮加载状态 */
|
||||
const addLoading = ref(false)
|
||||
|
||||
/** 岗位详情数据(扩展 applicationStatus 字段) */
|
||||
/** 岗位详情数据 */
|
||||
const jobDetail = ref<(JobDetailData & { applicationStatus?: number | null }) | null>(null)
|
||||
|
||||
/** 监听 visible 变化来加载数据 */
|
||||
watch(() => props.visible, (newVal) => {
|
||||
if (newVal && props.jobId) {
|
||||
loadDetail()
|
||||
}
|
||||
})
|
||||
|
||||
/** 监听 jobId 变化,如果面板已打开则重新加载 */
|
||||
watch(() => props.jobId, (newVal) => {
|
||||
if (props.visible && newVal) {
|
||||
loadDetail()
|
||||
}
|
||||
})
|
||||
|
||||
/** 监听 applicationStatus prop 变化,同步到 jobDetail */
|
||||
watch(() => props.applicationStatus, (newVal) => {
|
||||
if (jobDetail.value) {
|
||||
@@ -145,13 +161,27 @@ watch(() => props.applicationStatus, (newVal) => {
|
||||
}
|
||||
})
|
||||
|
||||
/** 格式化时间显示 */
|
||||
const formatTime = computed(() => {
|
||||
// 暂时不显示具体时间,可后续扩展
|
||||
return ''
|
||||
/** 格式化经验要求 */
|
||||
const formatExperience = computed(() => {
|
||||
if (!jobDetail.value) return ''
|
||||
const min = jobDetail.value.minExperience
|
||||
if (min === 0 || min === undefined || min === null) return '经验不限'
|
||||
return `${min}年以上`
|
||||
})
|
||||
|
||||
/** 工作类型映射 — 使用全局统一的 formatEmploymentType */
|
||||
/** 格式化招聘分类 */
|
||||
const formatRecruitCategory = computed(() => {
|
||||
if (!jobDetail.value) return ''
|
||||
const map: Record<number, string> = { 0: '社招', 1: '校招', 2: '实习', 3: '其他' }
|
||||
return map[jobDetail.value.recruitCategory] || ''
|
||||
})
|
||||
|
||||
/** 格式化学历要求 */
|
||||
const formatEducation = computed(() => {
|
||||
if (!jobDetail.value) return ''
|
||||
const map: Record<number, string> = { 0: '不限', 1: '大专', 2: '本科', 3: '硕士', 4: '博士' }
|
||||
return map[jobDetail.value.education] || ''
|
||||
})
|
||||
|
||||
/** 加载岗位详情 */
|
||||
async function loadDetail() {
|
||||
@@ -169,24 +199,11 @@ async function loadDetail() {
|
||||
}
|
||||
}
|
||||
|
||||
/** 返回按钮 */
|
||||
/** 关闭抽屉 */
|
||||
function handleBack() {
|
||||
emit('back')
|
||||
emit('update:visible', false)
|
||||
}
|
||||
|
||||
/** 添加到待投递 */
|
||||
function handleAdd() {
|
||||
emit('add', props.jobId)
|
||||
}
|
||||
|
||||
/** 从待投递移除 */
|
||||
function handleRemove() {
|
||||
emit('remove', props.jobId)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadDetail()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -1,105 +1,404 @@
|
||||
<template>
|
||||
<!-- Agent设置面板 — 右侧常驻面板(精简版) -->
|
||||
<!-- Agent设置面板 — 右侧常驻面板 -->
|
||||
<div class="agent-setting-panel">
|
||||
<div class="agent-setting-panel__body">
|
||||
<!-- 头部标题 -->
|
||||
<div class="agent-setting-panel__header">
|
||||
<div class="agent-setting-panel__title">投递助手设置</div>
|
||||
<div class="agent-setting-panel__subtitle">调整你的投递偏好</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== 个人资料 ========== -->
|
||||
<div class="agent-setting-panel__section">
|
||||
<div class="agent-setting-panel__section-header">
|
||||
<span class="agent-setting-panel__section-title">个人资料</span>
|
||||
<span class="agent-setting-panel__edit-btn" @click="handleEditProfile">编辑 ✎</span>
|
||||
<!-- 分隔线1 -->
|
||||
<div class="agent-setting-panel__divider"></div>
|
||||
|
||||
<!-- ========== 个人信息 ========== -->
|
||||
<div class="agent-setting-panel__section mb20">
|
||||
<div class="agent-setting-panel__section-header">
|
||||
<span class="agent-setting-panel__section-title">个人信息</span>
|
||||
<span class="agent-setting-panel__edit-btn" @click="handleEditProfile">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.5 2.5L11.5 5.5M1.5 12.5L2.5 9L10.5 1L13 3.5L5 11.5L1.5 12.5Z" stroke="#52CAD1" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<span>编辑</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- 一行简要信息:姓名 · 电话 · 城市 -->
|
||||
<div class="agent-setting-panel__info-text">
|
||||
{{ profileSummaryText }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== 求职偏好 ========== -->
|
||||
<div class="agent-setting-panel__section">
|
||||
<div class="agent-setting-panel__section-header">
|
||||
<span class="agent-setting-panel__section-title">求职偏好</span>
|
||||
<span class="agent-setting-panel__edit-btn" @click="showJobGoalDialog = true">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.5 2.5L11.5 5.5M1.5 12.5L2.5 9L10.5 1L13 3.5L5 11.5L1.5 12.5Z" stroke="#52CAD1" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<span>编辑</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- 求职偏好内容:多行文字展示 -->
|
||||
<div class="agent-setting-panel__goal-content">
|
||||
<p v-if="intentionRegionText">{{ intentionRegionText }}</p>
|
||||
<p v-if="intentionCategoryText">{{ intentionCategoryText }}</p>
|
||||
<p v-if="intentionIndustryText">{{ intentionIndustryText }}</p>
|
||||
<p v-if="intentionEmpText">{{ intentionEmpText }}</p>
|
||||
<p v-if="intentionTags.length === 0" class="agent-setting-panel__empty-text">暂未设置</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分隔线2 -->
|
||||
<div class="agent-setting-panel__divider"></div>
|
||||
|
||||
<!-- ========== 投递简历 ========== -->
|
||||
<div class="agent-setting-panel__section">
|
||||
<div class="agent-setting-panel__section-title">投递简历</div>
|
||||
<div class="agent-setting-panel__resume-dropdown" @click="showResumeDropdown = !showResumeDropdown">
|
||||
<span class="agent-setting-panel__resume-name">{{ selectedResumeName || '请选择简历' }}</span>
|
||||
<svg class="agent-setting-panel__resume-arrow" :class="{ 'agent-setting-panel__resume-arrow--open': showResumeDropdown }" width="14" height="14" viewBox="0 0 14 14" fill="none">
|
||||
<path d="M4 6L7 9L10 6" stroke="#6A7282" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- 下拉选项 -->
|
||||
<div v-if="showResumeDropdown" class="agent-setting-panel__resume-options">
|
||||
<div
|
||||
v-for="r in resumeList"
|
||||
:key="r.id"
|
||||
class="agent-setting-panel__resume-option"
|
||||
:class="{ 'agent-setting-panel__resume-option--active': selectedResumeId === r.id }"
|
||||
@click="handleSelectResume(r)"
|
||||
>{{ r.resumeName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分隔线3 -->
|
||||
<div class="agent-setting-panel__divider"></div>
|
||||
|
||||
<!-- ========== 投递偏好 ========== -->
|
||||
<div class="agent-setting-panel__section">
|
||||
<div class="agent-setting-panel__section-title">投递偏好</div>
|
||||
<!-- 开启简历针对性优化 -->
|
||||
<div class="agent-setting-panel__switch-item">
|
||||
<div class="agent-setting-panel__switch-text">
|
||||
<span class="agent-setting-panel__switch-label">开启简历针对性优化</span>
|
||||
<span class="agent-setting-panel__switch-desc">结合岗位要求,自动优化简历表达</span>
|
||||
</div>
|
||||
<!-- 简要信息展示 -->
|
||||
<div class="agent-setting-panel__profile-info">
|
||||
<div class="agent-setting-panel__profile-name">{{ profile.name || '未填写' }}</div>
|
||||
<div class="agent-setting-panel__profile-sub">{{ profileSubText }}</div>
|
||||
<div class="agent-setting-panel__toggle" :class="{ 'agent-setting-panel__toggle--on': autoOptimizeSwitch }" @click="toggleOptimize">
|
||||
<div class="agent-setting-panel__toggle-dot"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== 求职目标 ========== -->
|
||||
<div class="agent-setting-panel__section">
|
||||
<div class="agent-setting-panel__section-header">
|
||||
<span class="agent-setting-panel__section-title">求职目标</span>
|
||||
<span class="agent-setting-panel__edit-btn" @click="showJobGoalDialog = true">编辑 ✎</span>
|
||||
<!-- 开启深度人岗匹配分析 -->
|
||||
<div class="agent-setting-panel__switch-item">
|
||||
<div class="agent-setting-panel__switch-text">
|
||||
<span class="agent-setting-panel__switch-label">开启深度人岗匹配分析</span>
|
||||
<span class="agent-setting-panel__switch-desc">分析你的匹配优势与差距</span>
|
||||
</div>
|
||||
<!-- 求职意向标签 -->
|
||||
<div class="agent-setting-panel__goal-tags">
|
||||
<span v-for="name in intentionTags" :key="name" class="agent-setting-panel__goal-tag">{{ name }}</span>
|
||||
<span v-if="intentionTags.length === 0" class="agent-setting-panel__empty-text">暂未设置</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== 投递简历 ========== -->
|
||||
<div class="agent-setting-panel__section">
|
||||
<div class="agent-setting-panel__section-title">投递简历</div>
|
||||
<el-select v-model="selectedResumeId" placeholder="请选择简历" class="agent-setting-panel__resume-select" @change="handleResumeChange">
|
||||
<el-option v-for="r in resumeList" :key="r.id" :label="r.resumeName" :value="r.id || ''" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<!-- ========== 投递偏好 ========== -->
|
||||
<div class="agent-setting-panel__section">
|
||||
<div class="agent-setting-panel__section-title">投递偏好</div>
|
||||
<!-- 简历针对性优化 -->
|
||||
<div class="agent-setting-panel__pref-item">
|
||||
<div class="agent-setting-panel__pref-left">
|
||||
<span class="agent-setting-panel__pref-check" :class="{ 'agent-setting-panel__pref-check--active': autoOptimizeSwitch }">
|
||||
<svg v-if="autoOptimizeSwitch" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="7" stroke="currentColor" stroke-width="1.2"/><path d="M5 8l2 2 4-4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<svg v-else viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="7" stroke="currentColor" stroke-width="1.2"/></svg>
|
||||
</span>
|
||||
<div class="agent-setting-panel__pref-text">
|
||||
<span class="agent-setting-panel__pref-label">开启简历针对性优化</span>
|
||||
<span class="agent-setting-panel__pref-desc">结合岗位要求,自动优化简历表达</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-switch v-model="autoOptimizeSwitch" active-color="#4FC2C9" @change="handleSavePreference" />
|
||||
</div>
|
||||
<!-- 深度人岗匹配分析 -->
|
||||
<div class="agent-setting-panel__pref-item">
|
||||
<div class="agent-setting-panel__pref-left">
|
||||
<span class="agent-setting-panel__pref-check" :class="{ 'agent-setting-panel__pref-check--active': autoMatchAnalysisSwitch }">
|
||||
<svg v-if="autoMatchAnalysisSwitch" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="7" stroke="currentColor" stroke-width="1.2"/><path d="M5 8l2 2 4-4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<svg v-else viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="7" stroke="currentColor" stroke-width="1.2"/></svg>
|
||||
</span>
|
||||
<div class="agent-setting-panel__pref-text">
|
||||
<span class="agent-setting-panel__pref-label">开启深度人岗匹配分析</span>
|
||||
<span class="agent-setting-panel__pref-desc">根据岗位要求,分析你的匹配优势与差距</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-switch v-model="autoMatchAnalysisSwitch" active-color="#4FC2C9" @change="handleSavePreference" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== 浏览器插件 ========== -->
|
||||
<div class="agent-setting-panel__section">
|
||||
<div class="agent-setting-panel__section-title">浏览器插件</div>
|
||||
<div class="agent-setting-panel__browser-btns">
|
||||
<button class="agent-setting-panel__browser-btn" @click="openBrowserGuide('chrome')">Chrome浏览器</button>
|
||||
<button class="agent-setting-panel__browser-btn" @click="openBrowserGuide('edge')">Edge浏览器</button>
|
||||
<div class="agent-setting-panel__toggle" :class="{ 'agent-setting-panel__toggle--on': autoMatchAnalysisSwitch }" @click="toggleMatch">
|
||||
<div class="agent-setting-panel__toggle-dot"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 个人资料编辑抽屉 -->
|
||||
<ProfileEditDrawer
|
||||
v-model="showEditDrawer"
|
||||
:module="editModule"
|
||||
:initial-data="editInitialData"
|
||||
:saving="saving"
|
||||
@save="handleSaveEdit"
|
||||
/>
|
||||
<!-- 分隔线4 -->
|
||||
<div class="agent-setting-panel__divider"></div>
|
||||
|
||||
<!-- ========== 浏览器插件 ========== -->
|
||||
<div class="agent-setting-panel__section">
|
||||
<div class="agent-setting-panel__section-title">浏览器插件</div>
|
||||
<div class="agent-setting-panel__browser-btns">
|
||||
<button class="agent-setting-panel__browser-btn" @click="openBrowserGuide('chrome')">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_498_4683)">
|
||||
<path d="M8.00014 12.4507C10.4586 12.4507 12.4515 10.4577 12.4515 7.99929C12.4515 5.54085 10.4586 3.54785 8.00014 3.54785C5.54171 3.54785 3.54871 5.54085 3.54871 7.99929C3.54871 10.4577 5.54164 12.4507 8.00008 12.4507" fill="white"/>
|
||||
<path d="M2.24315 5.81204C1.91106 5.23683 1.52073 4.63314 1.07215 4.00098C0.369879 5.21706 0.000145925 6.59661 0.000122071 8.0009C9.82178e-05 9.4052 0.369785 10.7848 1.07201 12.0009C1.77424 13.217 2.78426 14.2268 4.00052 14.9288C5.21678 15.6307 6.59641 16.0001 8.00071 15.9998C8.737 14.9671 9.23692 14.2225 9.50046 13.766C10.0066 12.8893 10.6613 11.6341 11.4644 10.0004V9.99941C11.1135 10.6077 10.6087 11.113 10.0006 11.4643C9.39254 11.8156 8.70268 12.0006 8.00042 12.0007C7.29817 12.0008 6.60826 11.816 6.00008 11.4649C5.3919 11.1138 4.88689 10.6087 4.53584 10.0005C3.44509 7.96623 2.68086 6.57004 2.24315 5.81204Z" fill="#229342"/>
|
||||
<path d="M8.00046 16.0002C9.05106 16.0004 10.0914 15.7936 11.0621 15.3916C12.0327 14.9896 12.9147 14.4003 13.6575 13.6574C14.4004 12.9145 14.9896 12.0325 15.3915 11.0619C15.7935 10.0912 16.0002 9.05084 16 8.00024C15.9997 6.59593 15.6297 5.21644 14.9273 4.00043C13.4118 3.85105 12.2933 3.77637 11.5719 3.77637C10.7539 3.77637 9.56323 3.85105 7.9999 4.00043L7.99902 4.00105C8.7013 4.00071 9.39128 4.18529 9.99958 4.53623C10.6079 4.88717 11.113 5.39211 11.4643 6.00024C11.8155 6.60838 12.0004 7.29828 12.0004 8.00056C12.0004 8.70284 11.8155 9.39274 11.4642 10.0009L8.00046 16.0002Z" fill="#FBC116"/>
|
||||
<path d="M8.00013 11.1677C9.74913 11.1677 11.1669 9.74992 11.1669 8.00086C11.1669 6.2518 9.74913 4.83398 8.00006 4.83398C6.25113 4.83398 4.83325 6.25186 4.83325 8.00086C4.83325 9.74986 6.25113 11.1677 8.00013 11.1677Z" fill="#1A73E8"/>
|
||||
<path d="M8.00014 4.00027H14.9275C14.2255 2.78399 13.2157 1.77397 11.9995 1.07176C10.7834 0.369547 9.40384 -9.50021e-05 7.99953 1.83149e-08C6.59522 9.50388e-05 5.21569 0.369924 3.99965 1.0723C2.78362 1.77467 1.77394 2.78484 1.07214 4.00121L4.53583 10.0006L4.53677 10.0011C4.18536 9.39306 4.00025 8.70322 4.00004 8.00095C3.99984 7.29868 4.18455 6.60873 4.53559 6.0005C4.88664 5.39226 5.39165 4.88718 5.99983 4.53605C6.60802 4.18491 7.29794 4.0001 8.00021 4.00021L8.00014 4.00027Z" fill="#E33B2E"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_498_4683">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<span>Chrome浏览器</span>
|
||||
</button>
|
||||
<button class="agent-setting-panel__browser-btn" @click="openBrowserGuide('edge')">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_498_4700)">
|
||||
<path d="M14.4375 11.9059C14.225 12.0184 14.0062 12.1184 13.7812 12.1996C13.0625 12.4684 12.3062 12.6059 11.5375 12.6059C8.5812 12.6059 6.0062 10.5746 6.0062 7.96211C6.01245 7.24961 6.4062 6.59336 7.0312 6.25586C4.3562 6.36836 3.6687 9.15586 3.6687 10.7871C3.6687 15.4059 7.92495 15.8746 8.8437 15.8746C9.33745 15.8746 10.0812 15.7309 10.5312 15.5871L10.6125 15.5621C12.3375 14.9684 13.8 13.8059 14.775 12.2621C14.85 12.1434 14.8125 11.9934 14.7 11.9184C14.6187 11.8684 14.5187 11.8621 14.4375 11.9059Z" fill="url(#paint0_linear_498_4700)"/>
|
||||
<path opacity="0.35" d="M14.4375 11.9059C14.225 12.0184 14.0062 12.1184 13.7812 12.1996C13.0625 12.4684 12.3062 12.6059 11.5375 12.6059C8.5812 12.6059 6.0062 10.5746 6.0062 7.96211C6.01245 7.24961 6.4062 6.59336 7.0312 6.25586C4.3562 6.36836 3.6687 9.15586 3.6687 10.7871C3.6687 15.4059 7.92495 15.8746 8.8437 15.8746C9.33745 15.8746 10.0812 15.7309 10.5312 15.5871L10.6125 15.5621C12.3375 14.9684 13.8 13.8059 14.775 12.2621C14.85 12.1434 14.8125 11.9934 14.7 11.9184C14.6187 11.8684 14.5187 11.8621 14.4375 11.9059Z" fill="url(#paint1_radial_498_4700)"/>
|
||||
<path d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint2_linear_498_4700)"/>
|
||||
<path opacity="0.41" d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint3_radial_498_4700)"/>
|
||||
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint4_radial_498_4700)"/>
|
||||
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint5_radial_498_4700)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_498_4700" x1="3.66895" y1="11.0634" x2="14.8116" y2="11.0634" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#0C59A4"/>
|
||||
<stop offset="1" stop-color="#114A8B"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint1_radial_498_4700" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9.82444 11.1519) scale(5.96065 5.662)">
|
||||
<stop offset="0.72" stop-opacity="0"/>
|
||||
<stop offset="0.95" stop-opacity="0.53"/>
|
||||
<stop offset="1"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint2_linear_498_4700" x1="9.54822" y1="6.23432" x2="2.58741" y2="13.8163" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#1B9DE2"/>
|
||||
<stop offset="0.16" stop-color="#1595DF"/>
|
||||
<stop offset="0.67" stop-color="#0680D7"/>
|
||||
<stop offset="1" stop-color="#0078D4"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint3_radial_498_4700" cx="0" cy="0" r="1" gradientTransform="matrix(1.34287 -8.86118 7.162 1.0743 4.41307 12.4383)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.76" stop-opacity="0"/>
|
||||
<stop offset="0.95" stop-opacity="0.5"/>
|
||||
<stop offset="1"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint4_radial_498_4700" cx="0" cy="0" r="1" gradientTransform="matrix(-0.506075 12.6493 -26.9472 -1.0119 1.61573 2.96205)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#35C1F1"/>
|
||||
<stop offset="0.11" stop-color="#34C1ED"/>
|
||||
<stop offset="0.23" stop-color="#2FC2DF"/>
|
||||
<stop offset="0.31" stop-color="#2BC3D2"/>
|
||||
<stop offset="0.67" stop-color="#36C752"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint5_radial_498_4700" cx="0" cy="0" r="1" gradientTransform="matrix(1.70345 5.83918 -4.74533 1.39926 15.0038 4.83786)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#66EB6E"/>
|
||||
<stop offset="1" stop-color="#66EB6E" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<clipPath id="clip0_498_4700">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<span>Edge浏览器</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 个人信息编辑弹窗 -->
|
||||
<div v-if="showEditDialog" class="agent-setting-panel__edit-overlay" @click.self="showEditDialog = false">
|
||||
<div class="agent-setting-panel__edit-dialog">
|
||||
<!-- 弹窗头部 -->
|
||||
<div class="agent-setting-panel__edit-dialog-header">
|
||||
<span class="agent-setting-panel__edit-dialog-title">个人信息</span>
|
||||
<svg class="agent-setting-panel__edit-dialog-close" @click="showEditDialog = false" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M6 6L18 18M18 6L6 18" stroke="#6A7282" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<!-- 表单内容 -->
|
||||
<div class="agent-setting-panel__edit-dialog-body">
|
||||
<!-- 第一行:姓名 + 电话 -->
|
||||
<div class="agent-setting-panel__edit-row">
|
||||
<div class="agent-setting-panel__edit-field">
|
||||
<label class="agent-setting-panel__edit-label">姓名</label>
|
||||
<input class="agent-setting-panel__edit-input" v-model="editForm.name" placeholder="请输入姓名" />
|
||||
</div>
|
||||
<div class="agent-setting-panel__edit-field">
|
||||
<label class="agent-setting-panel__edit-label">电话</label>
|
||||
<input class="agent-setting-panel__edit-input" v-model="editForm.phone" placeholder="请输入电话" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 第二行:微信 + 邮箱 -->
|
||||
<div class="agent-setting-panel__edit-row">
|
||||
<div class="agent-setting-panel__edit-field">
|
||||
<label class="agent-setting-panel__edit-label">微信</label>
|
||||
<input class="agent-setting-panel__edit-input" v-model="editForm.wechat" placeholder="请输入微信号" />
|
||||
</div>
|
||||
<div class="agent-setting-panel__edit-field">
|
||||
<label class="agent-setting-panel__edit-label">邮箱</label>
|
||||
<input class="agent-setting-panel__edit-input" v-model="editForm.email" placeholder="请输入邮箱" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 第三行:所在城市 -->
|
||||
<div class="agent-setting-panel__edit-field agent-setting-panel__edit-field--full">
|
||||
<label class="agent-setting-panel__edit-label">所在城市</label>
|
||||
<div class="agent-setting-panel__edit-city">
|
||||
<RegionSelector
|
||||
:regionCodes="editLocationCodes"
|
||||
:level="2"
|
||||
:maxSelect="1"
|
||||
:triggerStyle="cityTriggerStyle"
|
||||
@update:regionCodes="onEditLocationChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 保存按钮 -->
|
||||
<button class="agent-setting-panel__edit-dialog-save" :disabled="saving" @click="handleSaveEdit">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 求职目标设置弹窗 -->
|
||||
<JobGoalDialog v-model="showJobGoalDialog" />
|
||||
|
||||
<!-- 浏览器插件安装教程抽屉 -->
|
||||
<Teleport to="body">
|
||||
<Transition name="agent-browser-guide-drawer">
|
||||
<div v-if="showBrowserGuideDrawer" class="agent-browser-guide-mask" @click.self="closeBrowserGuideDrawer">
|
||||
<div class="agent-browser-guide-drawer">
|
||||
<!-- 顶部标题栏 -->
|
||||
<div class="agent-browser-guide-drawer__header">
|
||||
<div class="agent-browser-guide-drawer__header-left">
|
||||
<div class="agent-browser-guide-drawer__close" @click="closeBrowserGuideDrawer">
|
||||
<svg viewBox="0 0 24 24" fill="none" class="agent-browser-guide-drawer__close-icon">
|
||||
<path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="agent-browser-guide-drawer__title">安装浏览器插件教程</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 步骤内容 -->
|
||||
<div class="agent-browser-guide-drawer__body">
|
||||
<!-- 步骤1:下载插件包 -->
|
||||
<div class="agent-browser-guide-drawer__card">
|
||||
<div class="agent-browser-guide-drawer__step-row">
|
||||
<span class="agent-browser-guide-drawer__step-num">1</span>
|
||||
<div class="agent-browser-guide-drawer__step-info">
|
||||
<h4 class="agent-browser-guide-drawer__step-title">下载插件包</h4>
|
||||
<p class="agent-browser-guide-drawer__step-desc">下载 Offer派自动投递助手安装包,下载完成后由步骤 2 进入浏览器扩展页面</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="agent-browser-guide-drawer__download-box w263">
|
||||
<span class="agent-browser-guide-drawer__download-name">Offer派自动投递助手.crx</span>
|
||||
<button class="agent-browser-guide-drawer__download-btn" @click="downloadExtension">
|
||||
<svg viewBox="0 0 16 16" fill="none" width="14" height="14"><path d="M8 2v8M8 10L5 7M8 10l3-3M3 13h10" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span>下载</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 步骤2:打开扩展管理页面 -->
|
||||
<div class="agent-browser-guide-drawer__card">
|
||||
<div class="agent-browser-guide-drawer__step-row">
|
||||
<span class="agent-browser-guide-drawer__step-num">2</span>
|
||||
<div class="agent-browser-guide-drawer__step-info">
|
||||
<h4 class="agent-browser-guide-drawer__step-title">打开扩展管理页面</h4>
|
||||
<p class="agent-browser-guide-drawer__step-desc">在浏览器地址栏输入对应地址并回车,打开扩展管理页面</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 浏览器地址链接 -->
|
||||
<div class="agent-browser-guide-drawer__browser-links">
|
||||
<div class="agent-browser-guide-drawer__browser-link" @click="copyToClipboard('chrome://extensions')">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_498_5140)">
|
||||
<path d="M8.00027 12.4507C10.4587 12.4507 12.4516 10.4577 12.4516 7.99929C12.4516 5.54085 10.4587 3.54785 8.00027 3.54785C5.54183 3.54785 3.54883 5.54085 3.54883 7.99929C3.54883 10.4577 5.54177 12.4507 8.0002 12.4507" fill="white"/>
|
||||
<path d="M2.24303 5.81204C1.91094 5.23683 1.52061 4.63314 1.07203 4.00098C0.369757 5.21706 2.38548e-05 6.59661 1.15428e-09 8.0009C-2.38525e-05 9.4052 0.369663 10.7848 1.07189 12.0009C1.77412 13.217 2.78414 14.2268 4.0004 14.9288C5.21666 15.6307 6.59629 16.0001 8.00059 15.9998C8.73688 14.9671 9.2368 14.2225 9.50034 13.766C10.0065 12.8893 10.6612 11.6341 11.4643 10.0004V9.99941C11.1134 10.6077 10.6086 11.113 10.0005 11.4643C9.39241 11.8156 8.70256 12.0006 8.0003 12.0007C7.29804 12.0008 6.60813 11.816 5.99995 11.4649C5.39178 11.1138 4.88677 10.6087 4.53571 10.0005C3.44496 7.96623 2.68073 6.57004 2.24303 5.81204Z" fill="#229342"/>
|
||||
<path d="M8.00046 16.0002C9.05106 16.0004 10.0914 15.7936 11.0621 15.3916C12.0327 14.9896 12.9147 14.4003 13.6575 13.6574C14.4004 12.9145 14.9896 12.0325 15.3915 11.0619C15.7935 10.0912 16.0002 9.05084 16 8.00024C15.9997 6.59593 15.6297 5.21644 14.9273 4.00043C13.4118 3.85105 12.2933 3.77637 11.5719 3.77637C10.7539 3.77637 9.56323 3.85105 7.9999 4.00043L7.99902 4.00105C8.7013 4.00071 9.39128 4.18529 9.99958 4.53623C10.6079 4.88717 11.113 5.39211 11.4643 6.00024C11.8155 6.60838 12.0004 7.29828 12.0004 8.00056C12.0004 8.70284 11.8155 9.39274 11.4642 10.0009L8.00046 16.0002Z" fill="#FBC116"/>
|
||||
<path d="M8.00013 11.1677C9.74913 11.1677 11.1669 9.74992 11.1669 8.00086C11.1669 6.2518 9.74913 4.83398 8.00006 4.83398C6.25113 4.83398 4.83325 6.25186 4.83325 8.00086C4.83325 9.74986 6.25113 11.1677 8.00013 11.1677Z" fill="#1A73E8"/>
|
||||
<path d="M8.00027 4.00027H14.9276C14.2256 2.78399 13.2158 1.77397 11.9997 1.07176C10.7835 0.369547 9.40396 -9.50021e-05 7.99965 1.83149e-08C6.59534 9.50388e-05 5.21581 0.369924 3.99978 1.0723C2.78374 1.77467 1.77406 2.78484 1.07227 4.00121L4.53595 10.0006L4.53689 10.0011C4.18549 9.39306 4.00037 8.70322 4.00017 8.00095C3.99996 7.29868 4.18467 6.60873 4.53571 6.0005C4.88676 5.39226 5.39177 4.88718 5.99995 4.53605C6.60814 4.18491 7.29806 4.0001 8.00033 4.00021L8.00027 4.00027Z" fill="#E33B2E"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_498_5140">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<span>Chrome浏览器:chrome://extensions</span>
|
||||
<span class="agent-browser-guide-drawer__copy-btn">
|
||||
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
||||
复制
|
||||
</span>
|
||||
</div>
|
||||
<div class="agent-browser-guide-drawer__browser-link" @click="copyToClipboard('edge://extensions')">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_498_5157)">
|
||||
<path d="M14.4375 11.9059C14.225 12.0184 14.0062 12.1184 13.7812 12.1996C13.0625 12.4684 12.3062 12.6059 11.5375 12.6059C8.5812 12.6059 6.0062 10.5746 6.0062 7.96211C6.01245 7.24961 6.4062 6.59336 7.0312 6.25586C4.3562 6.36836 3.6687 9.15586 3.6687 10.7871C3.6687 15.4059 7.92495 15.8746 8.8437 15.8746C9.33745 15.8746 10.0812 15.7309 10.5312 15.5871L10.6125 15.5621C12.3375 14.9684 13.8 13.8059 14.775 12.2621C14.85 12.1434 14.8125 11.9934 14.7 11.9184C14.6187 11.8684 14.5187 11.8621 14.4375 11.9059Z" fill="url(#paint0_linear_498_5157)"/>
|
||||
<path opacity="0.35" d="M14.4375 11.9059C14.225 12.0184 14.0062 12.1184 13.7812 12.1996C13.0625 12.4684 12.3062 12.6059 11.5375 12.6059C8.5812 12.6059 6.0062 10.5746 6.0062 7.96211C6.01245 7.24961 6.4062 6.59336 7.0312 6.25586C4.3562 6.36836 3.6687 9.15586 3.6687 10.7871C3.6687 15.4059 7.92495 15.8746 8.8437 15.8746C9.33745 15.8746 10.0812 15.7309 10.5312 15.5871L10.6125 15.5621C12.3375 14.9684 13.8 13.8059 14.775 12.2621C14.85 12.1434 14.8125 11.9934 14.7 11.9184C14.6187 11.8684 14.5187 11.8621 14.4375 11.9059Z" fill="url(#paint1_radial_498_5157)"/>
|
||||
<path d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint2_linear_498_5157)"/>
|
||||
<path opacity="0.41" d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint3_radial_498_5157)"/>
|
||||
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint4_radial_498_5157)"/>
|
||||
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint5_radial_498_5157)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_498_5157" x1="3.66895" y1="11.0634" x2="14.8116" y2="11.0634" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#0C59A4"/>
|
||||
<stop offset="1" stop-color="#114A8B"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint1_radial_498_5157" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9.82444 11.1519) scale(5.96065 5.662)">
|
||||
<stop offset="0.72" stop-opacity="0"/>
|
||||
<stop offset="0.95" stop-opacity="0.53"/>
|
||||
<stop offset="1"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint2_linear_498_5157" x1="9.54822" y1="6.23432" x2="2.58741" y2="13.8163" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#1B9DE2"/>
|
||||
<stop offset="0.16" stop-color="#1595DF"/>
|
||||
<stop offset="0.67" stop-color="#0680D7"/>
|
||||
<stop offset="1" stop-color="#0078D4"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint3_radial_498_5157" cx="0" cy="0" r="1" gradientTransform="matrix(1.34287 -8.86118 7.162 1.0743 4.41307 12.4383)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.76" stop-opacity="0"/>
|
||||
<stop offset="0.95" stop-opacity="0.5"/>
|
||||
<stop offset="1"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint4_radial_498_5157" cx="0" cy="0" r="1" gradientTransform="matrix(-0.506075 12.6493 -26.9472 -1.0119 1.61573 2.96205)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#35C1F1"/>
|
||||
<stop offset="0.11" stop-color="#34C1ED"/>
|
||||
<stop offset="0.23" stop-color="#2FC2DF"/>
|
||||
<stop offset="0.31" stop-color="#2BC3D2"/>
|
||||
<stop offset="0.67" stop-color="#36C752"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint5_radial_498_5157" cx="0" cy="0" r="1" gradientTransform="matrix(1.70345 5.83918 -4.74533 1.39926 15.0038 4.83786)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#66EB6E"/>
|
||||
<stop offset="1" stop-color="#66EB6E" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<clipPath id="clip0_498_5157">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<span>Edge浏览器:edge://extensions</span>
|
||||
<span class="agent-browser-guide-drawer__copy-btn">
|
||||
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
||||
复制
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 步骤2示意图 -->
|
||||
<img src="@/assets/images/agent-setting/2-1.png" alt="输入扩展地址" class="agent-browser-guide-drawer__step-img" />
|
||||
</div>
|
||||
|
||||
<!-- 步骤3:打开开发者模式 -->
|
||||
<div class="agent-browser-guide-drawer__card">
|
||||
<div class="agent-browser-guide-drawer__step-row">
|
||||
<span class="agent-browser-guide-drawer__step-num">3</span>
|
||||
<div class="agent-browser-guide-drawer__step-info">
|
||||
<h4 class="agent-browser-guide-drawer__step-title">打开开发者模式</h4>
|
||||
<p class="agent-browser-guide-drawer__step-desc">在扩展管理页面的右上角,找到「开发者模式」开关并打开</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 步骤3示意图 -->
|
||||
<img src="@/assets/images/agent-setting/3-1.png" alt="打开开发者模式" class="agent-browser-guide-drawer__step-img" />
|
||||
</div>
|
||||
|
||||
<!-- 步骤4:将CRX安装包拖入安装 -->
|
||||
<div class="agent-browser-guide-drawer__card">
|
||||
<div class="agent-browser-guide-drawer__step-row">
|
||||
<span class="agent-browser-guide-drawer__step-num">4</span>
|
||||
<div class="agent-browser-guide-drawer__step-info">
|
||||
<h4 class="agent-browser-guide-drawer__step-title">将 CRX 安装包拖入安装</h4>
|
||||
<p class="agent-browser-guide-drawer__step-desc">直接将下载好的CRX文件拖拽到扩展管理页面中,浏览器会自动识别并安装插件</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 步骤4示意图 -->
|
||||
<img src="@/assets/images/agent-setting/4-1.png" alt="拖入安装" class="agent-browser-guide-drawer__step-img" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { formatEmploymentType } from '@/stores/index'
|
||||
import ProfileEditDrawer from '@/components/ProfileEditDrawer.vue'
|
||||
import JobGoalDialog from '@/components/JobGoalDialog.vue'
|
||||
import RegionSelector from '@/components/tools/RegionSelector.vue'
|
||||
import { saveProfile, fetchProfile, fetchEducation } from '@/api/profile'
|
||||
import { resolveRegionName } from '@/utils/region'
|
||||
import { resolveIndustryName } from '@/utils/industry'
|
||||
@@ -125,13 +424,14 @@ const profile = ref({
|
||||
education: [] as Array<{ school: string; major: string; degree: number }>,
|
||||
})
|
||||
|
||||
/** 个人资料副标题(学校·学历) */
|
||||
const profileSubText = computed(() => {
|
||||
if (profile.value.education.length === 0) return ''
|
||||
const edu = profile.value.education[0]
|
||||
const degreeMap: Record<number, string> = { 1: '大专', 2: '本科', 3: '硕士', 4: '博士' }
|
||||
const parts = [edu.school, degreeMap[edu.degree]].filter(Boolean)
|
||||
return parts.join('·')
|
||||
/** 个人信息摘要文字(姓名 · 电话 · 城市) */
|
||||
const profileSummaryText = computed(() => {
|
||||
const parts: string[] = []
|
||||
if (profile.value.name) parts.push(profile.value.name)
|
||||
if (profile.value.phone) parts.push(profile.value.phone)
|
||||
const cityName = resolveRegionName(profile.value.regionCode)
|
||||
if (cityName) parts.push(cityName)
|
||||
return parts.length > 0 ? parts.join(' · ') : '未填写'
|
||||
})
|
||||
|
||||
/** 加载个人资料 */
|
||||
@@ -152,7 +452,7 @@ async function loadProfile() {
|
||||
} catch { /* 静默 */ }
|
||||
}
|
||||
|
||||
/** 加载教育经历(只取第一条显示) */
|
||||
/** 加载教育经历 */
|
||||
async function loadEducation() {
|
||||
try {
|
||||
const res = await fetchEducation()
|
||||
@@ -166,43 +466,73 @@ async function loadEducation() {
|
||||
} catch { /* 静默 */ }
|
||||
}
|
||||
|
||||
// ==================== 编辑抽屉 ====================
|
||||
// ==================== 编辑弹窗 ====================
|
||||
|
||||
/** 编辑抽屉显隐 */
|
||||
const showEditDrawer = ref(false)
|
||||
const editModule = ref('info')
|
||||
const editInitialData = ref<Record<string, any>>({})
|
||||
/** 编辑弹窗显隐 */
|
||||
const showEditDialog = ref(false)
|
||||
const saving = ref(false)
|
||||
|
||||
/** 打开编辑个人资料 */
|
||||
/** 编辑表单数据 */
|
||||
const editForm = ref({
|
||||
name: '',
|
||||
phone: '',
|
||||
wechat: '',
|
||||
email: '',
|
||||
location: '',
|
||||
})
|
||||
|
||||
/** 城市选择器当前编码 */
|
||||
const editLocationCodes = ref<string[]>([])
|
||||
|
||||
/** 城市选择器触发按钮样式 */
|
||||
const cityTriggerStyle: Record<string, string> = {
|
||||
width: '100%',
|
||||
'box-sizing': 'border-box',
|
||||
padding: '0.08rem 0.16rem',
|
||||
'font-size': '0.14rem',
|
||||
color: '#1A1A1A',
|
||||
background: '#F3F4F6',
|
||||
border: 'none',
|
||||
'border-radius': '0.08rem',
|
||||
'justify-content': 'space-between',
|
||||
}
|
||||
|
||||
/** 打开编辑弹窗 */
|
||||
function handleEditProfile() {
|
||||
editModule.value = 'info'
|
||||
editInitialData.value = {
|
||||
editForm.value = {
|
||||
name: profile.value.name,
|
||||
email: profile.value.email,
|
||||
phone: profile.value.phone,
|
||||
location: profile.value.regionCode,
|
||||
wechat: profile.value.wechat,
|
||||
email: profile.value.email,
|
||||
location: profile.value.regionCode,
|
||||
}
|
||||
showEditDrawer.value = true
|
||||
editLocationCodes.value = profile.value.regionCode ? [profile.value.regionCode] : []
|
||||
showEditDialog.value = true
|
||||
}
|
||||
|
||||
/** 城市选择回调 */
|
||||
function onEditLocationChange(codes: string[]) {
|
||||
editLocationCodes.value = codes
|
||||
editForm.value.location = codes[0] || ''
|
||||
}
|
||||
|
||||
/** 保存编辑 */
|
||||
async function handleSaveEdit(data: Record<string, any>) {
|
||||
async function handleSaveEdit() {
|
||||
saving.value = true
|
||||
try {
|
||||
await saveProfile({
|
||||
name: data.name,
|
||||
email: data.email,
|
||||
mobileNumber: data.phone,
|
||||
regionCode: data.location,
|
||||
wechatNumber: data.wechat,
|
||||
name: editForm.value.name,
|
||||
email: editForm.value.email,
|
||||
mobileNumber: editForm.value.phone,
|
||||
regionCode: editForm.value.location,
|
||||
wechatNumber: editForm.value.wechat,
|
||||
})
|
||||
profile.value.name = data.name
|
||||
profile.value.email = data.email
|
||||
profile.value.phone = data.phone
|
||||
profile.value.wechat = data.wechat
|
||||
profile.value.regionCode = data.location || ''
|
||||
profile.value.name = editForm.value.name
|
||||
profile.value.email = editForm.value.email
|
||||
profile.value.phone = editForm.value.phone
|
||||
profile.value.wechat = editForm.value.wechat
|
||||
profile.value.regionCode = editForm.value.location
|
||||
showEditDialog.value = false
|
||||
ElMessage.success('个人信息保存成功')
|
||||
} catch {
|
||||
ElMessage.error('保存失败,请重试')
|
||||
@@ -215,7 +545,7 @@ async function handleSaveEdit(data: Record<string, any>) {
|
||||
|
||||
const showJobGoalDialog = ref(false)
|
||||
|
||||
/** 求职意向标签(汇总岗位+行业+地区+招聘类型) */
|
||||
/** 求职意向标签(汇总) */
|
||||
const intentionTags = computed(() => {
|
||||
const tags: string[] = []
|
||||
const catIds = store.state.jobIntention?.categoryIds || []
|
||||
@@ -229,10 +559,43 @@ const intentionTags = computed(() => {
|
||||
return tags
|
||||
})
|
||||
|
||||
/** 求职偏好 — 地区文字 */
|
||||
const intentionRegionText = computed(() => {
|
||||
const regCodes = store.state.jobIntention?.regionCodes || []
|
||||
const names = regCodes.map((code: string) => resolveRegionName(code)).filter(Boolean)
|
||||
return names.length > 0 ? names.join('、') : ''
|
||||
})
|
||||
|
||||
/** 求职偏好 — 岗位文字 */
|
||||
const intentionCategoryText = computed(() => {
|
||||
const catIds = store.state.jobIntention?.categoryIds || []
|
||||
const names = catIds.map((id: number) => resolveJobCategoryName(id)).filter(Boolean)
|
||||
return names.length > 0 ? names.join('、') : ''
|
||||
})
|
||||
|
||||
/** 求职偏好 — 行业文字 */
|
||||
const intentionIndustryText = computed(() => {
|
||||
const indIds = store.state.jobIntention?.industryIds || []
|
||||
const names = indIds.map((id: number) => resolveIndustryName(id)).filter(Boolean)
|
||||
return names.length > 0 ? names.join('、') : ''
|
||||
})
|
||||
|
||||
/** 求职偏好 — 招聘类型文字 */
|
||||
const intentionEmpText = computed(() => {
|
||||
return formatEmploymentType(store.state.jobIntention?.recruitCategory) || ''
|
||||
})
|
||||
|
||||
// ==================== 投递简历 ====================
|
||||
|
||||
const resumeList = ref<ResumeListItem[]>([])
|
||||
const selectedResumeId = ref('')
|
||||
const showResumeDropdown = ref(false)
|
||||
|
||||
/** 当前选中简历名称 */
|
||||
const selectedResumeName = computed(() => {
|
||||
const found = resumeList.value.find(r => r.id === selectedResumeId.value)
|
||||
return found?.resumeName || ''
|
||||
})
|
||||
|
||||
/** 加载简历列表 */
|
||||
async function loadResumeList() {
|
||||
@@ -246,18 +609,31 @@ async function loadResumeList() {
|
||||
} catch { /* 静默 */ }
|
||||
}
|
||||
|
||||
/** 切换简历时设为默认 */
|
||||
async function handleResumeChange(newId: string) {
|
||||
if (!newId) return
|
||||
try {
|
||||
await setDefaultResume(newId)
|
||||
} catch { /* 静默 */ }
|
||||
/** 选择简历 */
|
||||
function handleSelectResume(r: ResumeListItem) {
|
||||
selectedResumeId.value = r.id || ''
|
||||
showResumeDropdown.value = false
|
||||
if (r.id) {
|
||||
setDefaultResume(r.id).catch(() => { /* 静默 */ })
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 投递偏好 ====================
|
||||
|
||||
const autoOptimizeSwitch = ref(true)
|
||||
const autoMatchAnalysisSwitch = ref(true)
|
||||
const autoOptimizeSwitch = ref(false)
|
||||
const autoMatchAnalysisSwitch = ref(false)
|
||||
|
||||
/** 切换简历优化开关 */
|
||||
function toggleOptimize() {
|
||||
autoOptimizeSwitch.value = !autoOptimizeSwitch.value
|
||||
handleSavePreference()
|
||||
}
|
||||
|
||||
/** 切换匹配分析开关 */
|
||||
function toggleMatch() {
|
||||
autoMatchAnalysisSwitch.value = !autoMatchAnalysisSwitch.value
|
||||
handleSavePreference()
|
||||
}
|
||||
|
||||
/** 加载配置 */
|
||||
async function loadAgentConfigData() {
|
||||
@@ -265,7 +641,8 @@ async function loadAgentConfigData() {
|
||||
const res = await fetchAgentConfig()
|
||||
if (res.code === '0' && res.data) {
|
||||
if (res.data.autoOptimizeResume !== undefined) autoOptimizeSwitch.value = res.data.autoOptimizeResume === 1
|
||||
if (res.data.autoMatchAnalysis !== undefined) autoMatchAnalysisSwitch.value = res.data.autoMatchAnalysis === 1
|
||||
// acceptDeptTransfer: "是"=开启,null/空字符串/"否"=关闭
|
||||
autoMatchAnalysisSwitch.value = res.data.acceptDeptTransfer === '是'
|
||||
}
|
||||
} catch { /* 静默 */ }
|
||||
}
|
||||
@@ -275,20 +652,41 @@ async function handleSavePreference() {
|
||||
try {
|
||||
await saveAgentConfig({
|
||||
autoOptimizeResume: autoOptimizeSwitch.value ? 1 : 0,
|
||||
autoMatchAnalysis: autoMatchAnalysisSwitch.value ? 1 : 0,
|
||||
acceptDeptTransfer: autoMatchAnalysisSwitch.value ? '是' : '否',
|
||||
})
|
||||
} catch { /* 静默 */ }
|
||||
}
|
||||
|
||||
// ==================== 浏览器插件 ====================
|
||||
|
||||
/** 打开浏览器安装指引(简单跳转) */
|
||||
function openBrowserGuide(browser: string) {
|
||||
if (browser === 'chrome') {
|
||||
ElMessage.info('请复制地址 chrome://extensions 到浏览器打开')
|
||||
} else {
|
||||
ElMessage.info('请复制地址 edge://extensions/ 到浏览器打开')
|
||||
}
|
||||
/** 浏览器插件安装教程抽屉是否显示 */
|
||||
const showBrowserGuideDrawer = ref(false)
|
||||
|
||||
/** 插件下载地址 */
|
||||
const extensionDownloadUrl = 'https://offerpie.oss-cn-guangzhou.aliyuncs.com/extension/chrome-mv3-prod.rar'
|
||||
|
||||
/** 打开浏览器安装指引抽屉 */
|
||||
function openBrowserGuide(_browser: string) {
|
||||
showBrowserGuideDrawer.value = true
|
||||
}
|
||||
|
||||
/** 关闭浏览器安装指引抽屉 */
|
||||
function closeBrowserGuideDrawer() {
|
||||
showBrowserGuideDrawer.value = false
|
||||
}
|
||||
|
||||
/** 下载插件 */
|
||||
function downloadExtension() {
|
||||
window.open(extensionDownloadUrl, '_blank')
|
||||
}
|
||||
|
||||
/** 复制文本到剪贴板 */
|
||||
function copyToClipboard(text: string) {
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
ElMessage.success('已复制到剪贴板')
|
||||
}).catch(() => {
|
||||
ElMessage.error('复制失败,请手动复制')
|
||||
})
|
||||
}
|
||||
|
||||
// ==================== 初始化 ====================
|
||||
|
||||
@@ -1,266 +1,379 @@
|
||||
<template>
|
||||
<!-- 求职助手准备向导 — 第1步到第4步 -->
|
||||
<div class="agent-page__wizard">
|
||||
<!-- 个人资料编辑抽屉 -->
|
||||
<ProfileEditDrawer
|
||||
v-model="showEditDrawer"
|
||||
:module="editModule"
|
||||
:initial-data="editInitialData"
|
||||
@save="handleSaveEdit"
|
||||
/>
|
||||
<div class="bg-f ptb16 prl24 mb16 fs18 fw600">投递准备</div>
|
||||
<div>
|
||||
<div class="agent-page__wizard bg-f prl32 ptb24 border-ra12 mrl24">
|
||||
|
||||
<!-- 顶部步骤导航条 -->
|
||||
<div class="agent-page__steps">
|
||||
<template v-for="(step, index) in steps" :key="index">
|
||||
<div
|
||||
class="agent-page__step"
|
||||
:class="{ 'agent-page__step--active': currentStep === index + 1 }"
|
||||
>
|
||||
<span class="agent-page__step-number">{{ index + 1 }}</span>
|
||||
<span class="agent-page__step-label">{{ step }}</span>
|
||||
</div>
|
||||
<span v-if="index < steps.length - 1" class="agent-page__step-arrow">
|
||||
<svg viewBox="0 0 16 16" fill="none">
|
||||
<path d="M6 4l4 4-4 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
<!-- 个人资料编辑抽屉 -->
|
||||
<ProfileEditDrawer
|
||||
v-model="showEditDrawer"
|
||||
:module="editModule"
|
||||
:initial-data="editInitialData"
|
||||
@save="handleSaveEdit"
|
||||
/>
|
||||
|
||||
<!-- 主体内容区域 -->
|
||||
<div class="agent-page__main">
|
||||
<!-- ========== 第1步:确认个人资料 ========== -->
|
||||
<template v-if="currentStep === 1">
|
||||
<div class="agent-page__right">
|
||||
<div class="agent-page__profile-wrapper">
|
||||
<ProfilePageContent :profile="profile" @edit="handleEdit" @save="handleInlineSave" @exp-update="handleExpUpdate" @exp-add="handleExpAdd" @exp-delete="handleExpDelete" />
|
||||
<!-- 顶部步骤导航条 -->
|
||||
<div class="agent-page__steps">
|
||||
<template v-for="(step, index) in steps" :key="index">
|
||||
<div
|
||||
class="agent-page__step"
|
||||
:class="{ 'agent-page__step--active': currentStep === index + 1 }"
|
||||
>
|
||||
<span class="agent-page__step-number">{{ index + 1 }}</span>
|
||||
<span class="agent-page__step-label">{{ step }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="agent-page__left">
|
||||
<div class="agent-page__intro-card">
|
||||
<div class="agent-page__intro-header por">
|
||||
<div v-if="false" class="agent-page__intro-icon poa l-22 t0">
|
||||
<svg viewBox="0 0 24 24" fill="none"><path d="M12 12c2.7 0 5-2.3 5-5s-2.3-5-5-5-5 2.3-5 5 2.3 5 5 5zm0 2c-3.3 0-10 1.7-10 5v2h20v-2c0-3.3-6.7-5-10-5z" fill="currentColor"/></svg>
|
||||
<span v-if="index < steps.length - 1" class="agent-page__step-line"></span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- 主体内容区域 -->
|
||||
<div class="agent-page__main">
|
||||
<!-- ========== 第1步:确认个人资料 ========== -->
|
||||
<template v-if="currentStep === 1">
|
||||
<div class="agent-page__right">
|
||||
<div class="agent-page__profile-wrapper">
|
||||
<ProfilePageContent :profile="profile" @edit="handleEdit" @save="handleInlineSave" @exp-update="handleExpUpdate" @exp-add="handleExpAdd" @exp-delete="handleExpDelete" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="agent-page__left">
|
||||
<div class="agent-page__intro-card agent-page__intro-card--gradient">
|
||||
<!-- Nova 头像 + 名称 -->
|
||||
<div class="agent-page__intro-avatar-row">
|
||||
<img src="@/assets/images/nova-logo-2.png" alt="Nova" class="agent-page__intro-avatar-img" />
|
||||
<span class="agent-page__intro-avatar-name">Nova</span>
|
||||
</div>
|
||||
<!-- 标题 -->
|
||||
<h2 class="agent-page__intro-title">请先确认你的个人资料是否无误</h2>
|
||||
</div>
|
||||
<p class="agent-page__intro-desc mb50 ">请仔细对你的资料评估(包括个人信息、教育背景、工作履历及技能),确保资料齐全,让我能顺利为你开启求职之旅。</p>
|
||||
<div class="">
|
||||
<div class="tac"><button class="agent-page__confirm-btn dib" @click="handleNext">确认并进入</button></div>
|
||||
<div v-if="false" class="tac color-9 mt30 cursor-po" @click="handleBack">返回上一步</div>
|
||||
<!-- 描述 -->
|
||||
<p class="agent-page__intro-desc">请仔细对你的资料评估(包括个人信息、教育背景、工作履历及技能),确保资料齐全</p>
|
||||
<!-- 按钮 -->
|
||||
<button class="agent-page__intro-gradient-btn" @click="handleNext">下一步</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<!-- ========== 第2步:确认目标 ========== -->
|
||||
<template v-if="currentStep === 2">
|
||||
<!-- 左侧:求职偏好 + 简历设置 -->
|
||||
<div class="agent-page__right">
|
||||
<div class="agent-page__profile-wrapper">
|
||||
<!-- 求职偏好区域 -->
|
||||
<div class="agent-page__pref-section">
|
||||
<h3 class="agent-page__pref-section-title">求职偏好</h3>
|
||||
<p class="agent-page__pref-section-desc">这些是你之前设定的求职偏好。如有需要,请随时修改。</p>
|
||||
<div class="agent-page__pref-filters">
|
||||
<!-- 城市选择 -->
|
||||
<RegionSelector
|
||||
:regionCodes="step2RegionCodes"
|
||||
:level="2"
|
||||
:maxSelect="3"
|
||||
:triggerStyle="prefFilterTriggerStyle"
|
||||
:displayStyle="prefFilterDisplayStyle"
|
||||
@update:regionCodes="onStep2RegionChange"
|
||||
/>
|
||||
<!-- 岗位选择 -->
|
||||
<JobCategorySelector
|
||||
:categoryIds="step2CategoryIds"
|
||||
:maxSelect="3"
|
||||
:level="3"
|
||||
:allowParentSelect="true"
|
||||
:triggerStyle="prefFilterTriggerStyle"
|
||||
:displayStyle="prefFilterDisplayStyle"
|
||||
@update:categoryIds="onStep2CategoryChange"
|
||||
/>
|
||||
<!-- 行业选择 -->
|
||||
<IndustrySelector
|
||||
:industryIds="step2IndustryIds"
|
||||
:maxSelect="3"
|
||||
:level="2"
|
||||
:allowParentSelect="true"
|
||||
:triggerStyle="prefFilterTriggerStyle"
|
||||
:displayStyle="prefFilterDisplayStyle"
|
||||
@update:industryIds="onStep2IndustryChange"
|
||||
/>
|
||||
<!-- 招聘分类下拉选择 -->
|
||||
<div class="agent-page__pref-type-dropdown" @click.stop="showJobTypeDropdown = !showJobTypeDropdown">
|
||||
<span>{{ intentionEmploymentLabel || '类型' }}</span>
|
||||
<svg class="agent-page__pref-type-arrow" viewBox="0 0 12 12" fill="none">
|
||||
<path d="M3 4.5L6 7.5L9 4.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<!-- 下拉菜单 -->
|
||||
<div v-if="showJobTypeDropdown" class="agent-page__pref-type-menu" @click.stop>
|
||||
<div
|
||||
v-for="option in jobTypeOptions"
|
||||
:key="option.value"
|
||||
class="agent-page__pref-type-menu-item"
|
||||
:class="{ 'agent-page__pref-type-menu-item--active': store.state.jobIntention.recruitCategory === option.value }"
|
||||
@click.stop="selectJobType(option)"
|
||||
>{{ option.label }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 简历设置区域 -->
|
||||
<div class="agent-page__resume-section">
|
||||
<h3 class="agent-page__pref-section-title">简历设置</h3>
|
||||
<div class="agent-page__resume-sub-label">设置默认简历</div>
|
||||
<div class="agent-page__resume-select-row">
|
||||
<span class="agent-page__resume-check-icon">
|
||||
<svg viewBox="0 0 16 16" fill="none"><rect x="2" y="2" width="12" height="12" rx="2" stroke="currentColor" stroke-width="1.2"/></svg>
|
||||
</span>
|
||||
<el-select v-model="selectedResumeId" placeholder="请选择简历" class="agent-page__resume-select">
|
||||
<el-option v-for="r in resumeList" :key="r.id" :label="r.resumeName" :value="r.id || ''" />
|
||||
</el-select>
|
||||
</div>
|
||||
<!-- 自动优化简历开关 -->
|
||||
<div class="agent-page__resume-switch-row">
|
||||
<span class="agent-page__resume-switch-text">在投递时帮我针对岗位自动优化简历。</span>
|
||||
<el-switch v-model="autoOptimizeSwitch" :active-color="'#4FC2C9'" />
|
||||
</div>
|
||||
<!-- 岗位匹配分析开关 -->
|
||||
<div class="agent-page__resume-switch-row">
|
||||
<span class="agent-page__resume-switch-text">在投递时帮我进行岗位匹配分析</span>
|
||||
<el-switch v-model="autoMatchAnalysisSwitch" :active-color="'#4FC2C9'" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧:确认卡片 -->
|
||||
<div class="agent-page__left">
|
||||
<div class="agent-page__intro-card">
|
||||
<div class="agent-page__intro-header por">
|
||||
<div class="agent-page__intro-icon poa l-22 t0">
|
||||
<svg viewBox="0 0 24 24" fill="none"><path d="M12 12c2.7 0 5-2.3 5-5s-2.3-5-5-5-5 2.3-5 5 2.3 5 5 5zm0 2c-3.3 0-10 1.7-10 5v2h20v-2c0-3.3-6.7-5-10-5z" fill="currentColor"/></svg>
|
||||
</div>
|
||||
<h2 class="agent-page__intro-title">接下来,我想确认一下我为你搜寻的职位方向是否准确。</h2>
|
||||
</div>
|
||||
<p class="agent-page__intro-desc mb50">请仔细对你的资料评估(包括个人信息、教育背景、工作履历及技能),确保资料齐全,让我能顺利为你开启求职之旅。</p>
|
||||
<div class="">
|
||||
<div class="tac"><button class="agent-page__confirm-btn dib" @click="handleNext">确认并进入</button></div>
|
||||
<div class="tac color-9 mt30 cursor-po" @click="handleBack">返回上一步</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- ========== 第3步:安装插件 ========== -->
|
||||
<template v-if="currentStep === 3">
|
||||
<!-- 左侧:安装教程内容 -->
|
||||
<div class="agent-page__right">
|
||||
<div class="agent-page__profile-wrapper">
|
||||
<div class="agent-page__install-guide">
|
||||
<h3 class="agent-page__install-guide-title">安装自动填写插件</h3>
|
||||
|
||||
<!-- 步骤1:下载插件包 -->
|
||||
<div class="agent-page__install-step">
|
||||
<p class="agent-page__install-step-text">1、下载下方的插件包</p>
|
||||
<div class="agent-page__install-download">
|
||||
<button class="agent-page__install-download-btn" @click="downloadExtension">
|
||||
<span>Offer派自动投递助手.crx</span>
|
||||
<svg viewBox="0 0 16 16" fill="none" width="14" height="14"><path d="M8 2v8M8 10L5 7M8 10l3-3M3 13h10" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 步骤2:复制地址进入扩展程序页面 -->
|
||||
<div class="agent-page__install-step">
|
||||
<p class="agent-page__install-step-text">2、复制右下方的蓝色地址,在浏览器地址栏粘贴并进入浏览器的扩展程序页面</p>
|
||||
<div class="agent-page__install-step-content">
|
||||
<div class="agent-page__install-step-img">
|
||||
<img src="@/assets/images/agent-setting/2-1.png" alt="地址栏示例" />
|
||||
</div>
|
||||
<div class="agent-page__install-browser-links">
|
||||
<div class="agent-page__install-browser-item">
|
||||
<img src="@/assets/images/agent-setting/2-2.png" style="width: 3rem;height: 0.3rem;" alt="Chrome" class="agent-page__install-browser-icon" />
|
||||
|
||||
<!-- ========== 第2步:确认目标 ========== -->
|
||||
<template v-if="currentStep === 2">
|
||||
<!-- 左侧:求职偏好 + 简历选择 -->
|
||||
<div class="agent-page__right">
|
||||
<div class="agent-page__step2-panel">
|
||||
<!-- 求职偏好区域 -->
|
||||
<div class="agent-page__step2-section">
|
||||
<h3 class="agent-page__step2-section-title">求职偏好</h3>
|
||||
<div class="agent-page__step2-filters">
|
||||
<!-- 城市选择 -->
|
||||
<RegionSelector
|
||||
:regionCodes="step2RegionCodes"
|
||||
:level="2"
|
||||
:maxSelect="3"
|
||||
:triggerStyle="prefFilterTriggerStyle"
|
||||
:displayStyle="prefFilterDisplayStyle"
|
||||
@update:regionCodes="onStep2RegionChange"
|
||||
/>
|
||||
<!-- 岗位选择 -->
|
||||
<JobCategorySelector
|
||||
:categoryIds="step2CategoryIds"
|
||||
:maxSelect="3"
|
||||
:level="3"
|
||||
:allowParentSelect="true"
|
||||
:triggerStyle="prefFilterTriggerStyle"
|
||||
:displayStyle="prefFilterDisplayStyle"
|
||||
@update:categoryIds="onStep2CategoryChange"
|
||||
/>
|
||||
<!-- 行业选择 -->
|
||||
<IndustrySelector
|
||||
:industryIds="step2IndustryIds"
|
||||
:maxSelect="3"
|
||||
:level="2"
|
||||
:allowParentSelect="true"
|
||||
:triggerStyle="prefFilterTriggerStyle"
|
||||
:displayStyle="prefFilterDisplayStyle"
|
||||
@update:industryIds="onStep2IndustryChange"
|
||||
/>
|
||||
<!-- 招聘分类下拉选择 -->
|
||||
<div class="agent-page__pref-type-dropdown" @click.stop="showJobTypeDropdown = !showJobTypeDropdown">
|
||||
<span>{{ intentionEmploymentLabel || '招聘类型' }}</span>
|
||||
<svg class="agent-page__pref-type-arrow" viewBox="0 0 12 12" fill="none">
|
||||
<path d="M3 4.5L6 7.5L9 4.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<!-- 下拉菜单 -->
|
||||
<div v-if="showJobTypeDropdown" class="agent-page__pref-type-menu" @click.stop>
|
||||
<div
|
||||
v-for="option in jobTypeOptions"
|
||||
:key="option.value"
|
||||
class="agent-page__pref-type-menu-item"
|
||||
:class="{ 'agent-page__pref-type-menu-item--active': store.state.jobIntention.recruitCategory === option.value }"
|
||||
@click.stop="selectJobType(option)"
|
||||
>{{ option.label }}</div>
|
||||
</div>
|
||||
<a class="agent-page__install-browser-url" href="javascript:void(0)" @click="copyToClipboard('chrome://extensions')">
|
||||
chrome://extensions
|
||||
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
||||
</a>
|
||||
<div class="agent-page__install-browser-item mt16">
|
||||
<img src="@/assets/images/agent-setting/2-3.png" style="width: 3rem;height: 0.3rem;" alt="Edge" class="agent-page__install-browser-icon" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 简历选择区域 -->
|
||||
<div class="agent-page__step2-section">
|
||||
<h3 class="agent-page__step2-section-title">简历选择</h3>
|
||||
<div class="agent-page__step2-filters">
|
||||
<!-- 自定义简历下拉 -->
|
||||
<div class="agent-page__step2-resume-dropdown" @click.stop="showResumeDropdown = !showResumeDropdown">
|
||||
<span class="agent-page__step2-resume-dropdown-text">{{ selectedResumeName || '请选择简历' }}</span>
|
||||
<svg class="agent-page__step2-resume-dropdown-arrow" viewBox="0 0 12 12" fill="none">
|
||||
<path d="M3 4.5L6 7.5L9 4.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<!-- 下拉菜单 -->
|
||||
<div v-if="showResumeDropdown" class="agent-page__step2-resume-menu" @click.stop>
|
||||
<div
|
||||
v-for="r in resumeList"
|
||||
:key="r.id"
|
||||
class="agent-page__step2-resume-menu-item"
|
||||
:class="{ 'agent-page__step2-resume-menu-item--active': selectedResumeId === r.id }"
|
||||
@click.stop="selectResume(r)"
|
||||
>{{ r.resumeName }}</div>
|
||||
</div>
|
||||
<a class="agent-page__install-browser-url" href="javascript:void(0)" @click="copyToClipboard('edge://extensions/')">
|
||||
edge://extensions/
|
||||
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 步骤3:打开开发人员模式 -->
|
||||
<div class="agent-page__install-step">
|
||||
<p class="agent-page__install-step-text">3、在浏览器拓展页面中打开「开发人员模式」</p>
|
||||
<div class="agent-page__install-step-img-row">
|
||||
<div class="agent-page__install-step-img-item">
|
||||
<img src="@/assets/images/agent-setting/3-1.png" alt="打开开发人员模式" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 步骤4:拖入插件包 -->
|
||||
<div class="agent-page__install-step">
|
||||
<p class="agent-page__install-step-text">4、将下载好的「离线插件包」使用鼠标拖入到浏览器的扩展程序页面</p>
|
||||
<div class="agent-page__install-step-img-row">
|
||||
<div class="agent-page__install-step-img-item">
|
||||
<img src="@/assets/images/agent-setting/4-1.png" alt="拖入插件包" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧:确认卡片 -->
|
||||
<div class="agent-page__left">
|
||||
<div class="agent-page__intro-card">
|
||||
<div class="agent-page__intro-header por">
|
||||
<div class="agent-page__intro-icon poa l-22 t0">
|
||||
<svg viewBox="0 0 24 24" fill="none"><path d="M12 12c2.7 0 5-2.3 5-5s-2.3-5-5-5-5 2.3-5 5 2.3 5 5 5zm0 2c-3.3 0-10 1.7-10 5v2h20v-2c0-3.3-6.7-5-10-5z" fill="currentColor"/></svg>
|
||||
<!-- 右侧:确认卡片 -->
|
||||
<div class="agent-page__left">
|
||||
<div class="agent-page__intro-card agent-page__intro-card--gradient">
|
||||
<!-- Nova 头像 + 名称 -->
|
||||
<div class="agent-page__intro-avatar-row">
|
||||
<img src="@/assets/images/nova-logo-2.png" alt="Nova" class="agent-page__intro-avatar-img" />
|
||||
<span class="agent-page__intro-avatar-name">Nova</span>
|
||||
</div>
|
||||
<h2 class="agent-page__intro-title">现在我们来开启自动投递吧</h2>
|
||||
</div>
|
||||
<p class="agent-page__intro-desc mb20">简单四步安装 Chrome 扩展程序<br/>实现自动填表,并一站式追踪所有申请进度。</p>
|
||||
<div class="agent-page__install-steps-list">
|
||||
<p>1. 下载offer派自动投递助手插件包</p>
|
||||
<p>2. 进入浏览器扩展程序界面</p>
|
||||
<p>3. 打开扩展程序开发人员模式</p>
|
||||
<p>4.拖入安装包,完成安装!</p>
|
||||
</div>
|
||||
<div class="mt30">
|
||||
<div class="tac"><button class="agent-page__confirm-btn dib" @click="handleNext">我已安装</button></div>
|
||||
<div class="tac color-9 mt30 cursor-po" @click="handleBack">返回上一步</div>
|
||||
<!-- 标题 -->
|
||||
<h2 class="agent-page__intro-title">请配置你的投递方案</h2>
|
||||
<!-- 描述 -->
|
||||
<p class="agent-page__intro-desc">我们会根据你的选择,为你推荐最合适的投递岗位</p>
|
||||
<!-- 按钮 -->
|
||||
<button class="agent-page__intro-gradient-btn" @click="handleNext">下一步</button>
|
||||
<button class="agent-page__intro-back-btn" @click="handleBack">上一步</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- ========== 第4步:完成配置 ========== -->
|
||||
<template v-if="currentStep === 4">
|
||||
<div class="agent-page__complete">
|
||||
<div class="agent-page__complete-icon"><svg viewBox="0 0 80 80" fill="none"><rect x="8" y="8" width="64" height="64" rx="8" fill="#E8E8E8"/><circle cx="40" cy="32" r="8" fill="#BFBFBF"/><path d="M20 60 L32 44 L44 52 L56 36 L64 44 L64 64 L20 64Z" fill="#BFBFBF"/></svg></div>
|
||||
<h2 class="agent-page__complete-title">恭喜你!你的求职助手已经准备好。</h2>
|
||||
<p class="agent-page__complete-desc">启用求职助手后你可以随时调整求职偏好及简历信息。</p>
|
||||
<button class="agent-page__complete-btn" @click="handleLaunchAgent">启用求职助手开始投递</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<!-- ========== 第3步:安装插件 ========== -->
|
||||
<template v-if="currentStep === 3">
|
||||
<!-- 左侧:安装教程内容 -->
|
||||
<div class="agent-page__right">
|
||||
<div class="agent-page__profile-wrapper bg-f">
|
||||
<div class="agent-page__install-guide">
|
||||
|
||||
<!-- 步骤1:下载插件包 -->
|
||||
<div class="agent-page__install-card">
|
||||
<div class="agent-page__install-card-row">
|
||||
<div class="agent-page__install-card-left">
|
||||
<div class="agent-page__install-card-header">
|
||||
<span class="agent-page__install-card-num">1</span>
|
||||
<div class="agent-page__install-card-info">
|
||||
<h4 class="agent-page__install-card-title">下载插件包</h4>
|
||||
<p class="agent-page__install-card-desc">下载 Offer派自动投递助手安装包,下载完成后由步骤 2 进入浏览器扩展页面</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="">
|
||||
<div class="agent-page__install-download-box">
|
||||
<span class="agent-page__install-download-name">Offer派自动投递助手.crx</span>
|
||||
<button class="agent-page__install-download-btn2" @click="downloadExtension">
|
||||
<svg viewBox="0 0 16 16" fill="none" width="14" height="14"><path d="M8 2v8M8 10L5 7M8 10l3-3M3 13h10" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
<span>下载</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 步骤2:打开扩展管理页面 -->
|
||||
<div class="agent-page__install-card">
|
||||
<div class="agent-page__install-card-row">
|
||||
<div class="agent-page__install-card-left">
|
||||
<div class="agent-page__install-card-header">
|
||||
<span class="agent-page__install-card-num">2</span>
|
||||
<div class="agent-page__install-card-info">
|
||||
<h4 class="agent-page__install-card-title">打开扩展管理页面</h4>
|
||||
<p class="agent-page__install-card-desc">在浏览器地址栏输入对应地址并回车,打开扩展管理页面</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 浏览器地址链接 -->
|
||||
<div class="agent-page__install-browser-row">
|
||||
<a class="agent-page__install-browser-link" href="javascript:void(0)" @click="copyToClipboard('chrome://extensions')">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_525_3895)">
|
||||
<path d="M8.00027 12.4507C10.4587 12.4507 12.4516 10.4577 12.4516 7.99929C12.4516 5.54085 10.4587 3.54785 8.00027 3.54785C5.54183 3.54785 3.54883 5.54085 3.54883 7.99929C3.54883 10.4577 5.54177 12.4507 8.0002 12.4507" fill="white"/>
|
||||
<path d="M2.24303 5.81204C1.91094 5.23683 1.52061 4.63314 1.07203 4.00098C0.369757 5.21706 2.38548e-05 6.59661 1.15428e-09 8.0009C-2.38525e-05 9.4052 0.369663 10.7848 1.07189 12.0009C1.77412 13.217 2.78414 14.2268 4.0004 14.9288C5.21666 15.6307 6.59629 16.0001 8.00059 15.9998C8.73688 14.9671 9.2368 14.2225 9.50034 13.766C10.0065 12.8893 10.6612 11.6341 11.4643 10.0004V9.99941C11.1134 10.6077 10.6086 11.113 10.0005 11.4643C9.39241 11.8156 8.70256 12.0006 8.0003 12.0007C7.29804 12.0008 6.60813 11.816 5.99995 11.4649C5.39178 11.1138 4.88677 10.6087 4.53571 10.0005C3.44496 7.96623 2.68073 6.57004 2.24303 5.81204Z" fill="#229342"/>
|
||||
<path d="M8.00046 16.0002C9.05106 16.0004 10.0914 15.7936 11.0621 15.3916C12.0327 14.9896 12.9147 14.4003 13.6575 13.6574C14.4004 12.9145 14.9896 12.0325 15.3915 11.0619C15.7935 10.0912 16.0002 9.05084 16 8.00024C15.9997 6.59593 15.6297 5.21644 14.9273 4.00043C13.4118 3.85105 12.2933 3.77637 11.5719 3.77637C10.7539 3.77637 9.56323 3.85105 7.9999 4.00043L7.99902 4.00105C8.7013 4.00071 9.39128 4.18529 9.99958 4.53623C10.6079 4.88717 11.113 5.39211 11.4643 6.00024C11.8155 6.60838 12.0004 7.29828 12.0004 8.00056C12.0004 8.70284 11.8155 9.39274 11.4642 10.0009L8.00046 16.0002Z" fill="#FBC116"/>
|
||||
<path d="M8.00037 11.1677C9.74937 11.1677 11.1672 9.74992 11.1672 8.00086C11.1672 6.2518 9.74937 4.83398 8.00031 4.83398C6.25137 4.83398 4.8335 6.25186 4.8335 8.00086C4.8335 9.74986 6.25137 11.1677 8.00037 11.1677Z" fill="#1A73E8"/>
|
||||
<path d="M8.00027 4.00027H14.9276C14.2256 2.78399 13.2158 1.77397 11.9997 1.07176C10.7835 0.369547 9.40396 -9.50021e-05 7.99965 1.83149e-08C6.59534 9.50388e-05 5.21581 0.369924 3.99978 1.0723C2.78374 1.77467 1.77406 2.78484 1.07227 4.00121L4.53595 10.0006L4.53689 10.0011C4.18549 9.39306 4.00037 8.70322 4.00017 8.00095C3.99996 7.29868 4.18467 6.60873 4.53571 6.0005C4.88676 5.39226 5.39177 4.88718 5.99995 4.53605C6.60814 4.18491 7.29806 4.0001 8.00033 4.00021L8.00027 4.00027Z" fill="#E33B2E"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_525_3895">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<span class="agent-page__install-browser-link-label">Chrome浏览器:chrome://extensions</span>
|
||||
<span class="agent-page__install-browser-link-copy">
|
||||
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
||||
复制
|
||||
</span>
|
||||
</a>
|
||||
<a class="agent-page__install-browser-link" href="javascript:void(0)" @click="copyToClipboard('edge://extensions')">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_525_3912)">
|
||||
<path d="M14.4377 11.9059C14.2252 12.0184 14.0064 12.1184 13.7814 12.1996C13.0627 12.4684 12.3064 12.6059 11.5377 12.6059C8.58145 12.6059 6.00645 10.5746 6.00645 7.96211C6.0127 7.24961 6.40645 6.59336 7.03145 6.25586C4.35645 6.36836 3.66895 9.15586 3.66895 10.7871C3.66895 15.4059 7.9252 15.8746 8.84395 15.8746C9.3377 15.8746 10.0814 15.7309 10.5314 15.5871L10.6127 15.5621C12.3377 14.9684 13.8002 13.8059 14.7752 12.2621C14.8502 12.1434 14.8127 11.9934 14.7002 11.9184C14.6189 11.8684 14.5189 11.8621 14.4377 11.9059Z" fill="url(#paint0_linear_525_3912)"/>
|
||||
<path opacity="0.35" d="M14.4377 11.9059C14.2252 12.0184 14.0064 12.1184 13.7814 12.1996C13.0627 12.4684 12.3064 12.6059 11.5377 12.6059C8.58145 12.6059 6.00645 10.5746 6.00645 7.96211C6.0127 7.24961 6.40645 6.59336 7.03145 6.25586C4.35645 6.36836 3.66895 9.15586 3.66895 10.7871C3.66895 15.4059 7.9252 15.8746 8.84395 15.8746C9.3377 15.8746 10.0814 15.7309 10.5314 15.5871L10.6127 15.5621C12.3377 14.9684 13.8002 13.8059 14.7752 12.2621C14.8502 12.1434 14.8127 11.9934 14.7002 11.9184C14.6189 11.8684 14.5189 11.8621 14.4377 11.9059Z" fill="url(#paint1_radial_525_3912)"/>
|
||||
<path d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint2_linear_525_3912)"/>
|
||||
<path opacity="0.41" d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint3_radial_525_3912)"/>
|
||||
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint4_radial_525_3912)"/>
|
||||
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint5_radial_525_3912)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_525_3912" x1="3.6692" y1="11.0634" x2="14.8119" y2="11.0634" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#0C59A4"/>
|
||||
<stop offset="1" stop-color="#114A8B"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint1_radial_525_3912" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9.82468 11.1519) scale(5.96065 5.662)">
|
||||
<stop offset="0.72" stop-opacity="0"/>
|
||||
<stop offset="0.95" stop-opacity="0.53"/>
|
||||
<stop offset="1"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint2_linear_525_3912" x1="9.54822" y1="6.23432" x2="2.58741" y2="13.8163" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#1B9DE2"/>
|
||||
<stop offset="0.16" stop-color="#1595DF"/>
|
||||
<stop offset="0.67" stop-color="#0680D7"/>
|
||||
<stop offset="1" stop-color="#0078D4"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint3_radial_525_3912" cx="0" cy="0" r="1" gradientTransform="matrix(1.34287 -8.86118 7.162 1.0743 4.41307 12.4383)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.76" stop-opacity="0"/>
|
||||
<stop offset="0.95" stop-opacity="0.5"/>
|
||||
<stop offset="1"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint4_radial_525_3912" cx="0" cy="0" r="1" gradientTransform="matrix(-0.506075 12.6493 -26.9472 -1.0119 1.61573 2.96205)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#35C1F1"/>
|
||||
<stop offset="0.11" stop-color="#34C1ED"/>
|
||||
<stop offset="0.23" stop-color="#2FC2DF"/>
|
||||
<stop offset="0.31" stop-color="#2BC3D2"/>
|
||||
<stop offset="0.67" stop-color="#36C752"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint5_radial_525_3912" cx="0" cy="0" r="1" gradientTransform="matrix(1.70345 5.83918 -4.74533 1.39926 15.0038 4.83786)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#66EB6E"/>
|
||||
<stop offset="1" stop-color="#66EB6E" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<clipPath id="clip0_525_3912">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<span class="agent-page__install-browser-link-label">Edge浏览器:edge://extensions</span>
|
||||
<span class="agent-page__install-browser-link-copy">
|
||||
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
||||
复制
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="agent-page__install-card-right">
|
||||
<img src="@/assets/images/agent-setting/2-1.png" alt="输入扩展地址" class="agent-page__install-card-img" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 步骤3:打开开发者模式 -->
|
||||
<div class="agent-page__install-card">
|
||||
<div class="agent-page__install-card-row">
|
||||
<div class="agent-page__install-card-left">
|
||||
<div class="agent-page__install-card-header">
|
||||
<span class="agent-page__install-card-num">3</span>
|
||||
<div class="agent-page__install-card-info">
|
||||
<h4 class="agent-page__install-card-title">打开开发者模式</h4>
|
||||
<p class="agent-page__install-card-desc">在扩展管理页面的右上角,找到「开发者模式」开关并打开</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="agent-page__install-card-right">
|
||||
<img src="@/assets/images/agent-setting/3-1.png" alt="打开开发者模式" class="agent-page__install-card-img" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 步骤4:将CRX安装包拖入安装 -->
|
||||
<div class="agent-page__install-card">
|
||||
<div class="agent-page__install-card-row">
|
||||
<div class="agent-page__install-card-left">
|
||||
<div class="agent-page__install-card-header">
|
||||
<span class="agent-page__install-card-num">4</span>
|
||||
<div class="agent-page__install-card-info">
|
||||
<h4 class="agent-page__install-card-title">将 CRX 安装包拖入安装</h4>
|
||||
<p class="agent-page__install-card-desc">直接将下载好的CRX文件拖拽到扩展管理页面中,浏览器会自动识别并安装插件</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="agent-page__install-card-right">
|
||||
<img src="@/assets/images/agent-setting/4-1.png" alt="拖入安装" class="agent-page__install-card-img" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧:确认卡片 -->
|
||||
<div class="agent-page__left">
|
||||
<div class="agent-page__intro-card agent-page__intro-card--gradient">
|
||||
<!-- Nova 头像 + 名称 -->
|
||||
<div class="agent-page__intro-avatar-row">
|
||||
<img src="@/assets/images/nova-logo-2.png" alt="Nova" class="agent-page__intro-avatar-img" />
|
||||
<span class="agent-page__intro-avatar-name">Nova</span>
|
||||
</div>
|
||||
<!-- 标题 -->
|
||||
<h2 class="agent-page__intro-title">安装浏览器自动投递插件</h2>
|
||||
<!-- 描述 -->
|
||||
<p class="agent-page__intro-desc">按照左侧步骤完成插件安装,即可开启自动投递功能</p>
|
||||
<!-- 按钮 -->
|
||||
<button class="agent-page__intro-gradient-btn" @click="handleNext">下一步</button>
|
||||
<button class="agent-page__intro-back-btn" @click="handleBack">上一步</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- ========== 第4步:完成配置 ========== -->
|
||||
<template v-if="currentStep === 4">
|
||||
<div class="agent-page__complete">
|
||||
<div class="agent-page__complete-icon"><svg viewBox="0 0 80 80" fill="none"><rect x="8" y="8" width="64" height="64" rx="8" fill="#E8E8E8"/><circle cx="40" cy="32" r="8" fill="#BFBFBF"/><path d="M20 60 L32 44 L44 52 L56 36 L64 44 L64 64 L20 64Z" fill="#BFBFBF"/></svg></div>
|
||||
<h2 class="agent-page__complete-title">恭喜!求职助手已经准备好</h2>
|
||||
<p class="agent-page__complete-desc">启用求职助手后,你可以随时调整求职偏好和简历信息</p>
|
||||
<button class="agent-page__complete-btn" @click="handleLaunchAgent">启用求职助手开始投递</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- 求职目标设置弹窗 -->
|
||||
<JobGoalDialog v-model="showJobGoalDialog" />
|
||||
</div>
|
||||
<!-- 功能说明 — 独立区块,仅第2步显示 -->
|
||||
<div v-if="currentStep === 2" class="agent-page__step2-faq mrl24 mt16">
|
||||
<h3 class="agent-page__step2-faq-title">功能说明</h3>
|
||||
<div class="agent-page__step2-faq-item">
|
||||
<div class="agent-page__step2-faq-item-title">为什么要选择求职偏好?</div>
|
||||
<div class="agent-page__step2-faq-item-desc">城市、岗位、行业和招聘类型会影响岗位推荐范围,系统会优先筛选更符合你目标的投递机会。</div>
|
||||
</div>
|
||||
<div class="agent-page__step2-faq-item">
|
||||
<div class="agent-page__step2-faq-item-title">为什么要选择简历?</div>
|
||||
<div class="agent-page__step2-faq-item-desc">AI会基于你选择的简历进行岗位匹配度分析,差距识别和岗位专属优化,帮助提升投递成功率。</div>
|
||||
</div>
|
||||
<div class="agent-page__step2-faq-item">
|
||||
<div class="agent-page__step2-faq-item-title">这些设置会影响后续哪些功能?</div>
|
||||
<div class="agent-page__step2-faq-item-desc">会影响推荐岗位、匹配度评分、简历优化方向、自动投递队列和投递进度记录。</div>
|
||||
</div>
|
||||
<div class="agent-page__step2-faq-item">
|
||||
<div class="agent-page__step2-faq-item-title">设置后还能修改吗?</div>
|
||||
<div class="agent-page__step2-faq-item-desc">可以随时调整,修改后,系统会根据新的偏好和简历重新推荐结果。</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 求职目标设置弹窗 -->
|
||||
<JobGoalDialog v-model="showJobGoalDialog" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -295,7 +408,7 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
// ==================== 步骤导航 ====================
|
||||
const steps = ['确认个人资料', '确认目标', '安装插件', '配置求职助手']
|
||||
const steps = ['确认个人资料', '配置投递方案', '安装浏览器插件', '开启投递助手']
|
||||
const currentStep = ref(1)
|
||||
|
||||
/** 进入下一步 */
|
||||
@@ -546,6 +659,20 @@ const intentionEmploymentLabel = computed(() => formatEmploymentType(store.state
|
||||
const jobTypeOptions = JOB_TYPE_OPTIONS
|
||||
/** 招聘分类下拉是否展开 */
|
||||
const showJobTypeDropdown = ref(false)
|
||||
/** 简历下拉是否展开 */
|
||||
const showResumeDropdown = ref(false)
|
||||
|
||||
/** 当前选中简历名称 */
|
||||
const selectedResumeName = computed(() => {
|
||||
const item = resumeList.value.find(r => r.id === selectedResumeId.value)
|
||||
return item ? item.resumeName : ''
|
||||
})
|
||||
|
||||
/** 选中简历 */
|
||||
function selectResume(r: { id?: string; resumeName?: string }) {
|
||||
selectedResumeId.value = r.id || ''
|
||||
showResumeDropdown.value = false
|
||||
}
|
||||
|
||||
/** 选中招聘分类 */
|
||||
function selectJobType(option: { label: string; value: number }) {
|
||||
@@ -563,19 +690,20 @@ const step2IndustryIds = computed<number[]>(() => store.state.jobIntention.indus
|
||||
|
||||
/** 第2步:筛选组件统一触发按钮样式 — 大圆角胶囊按钮 */
|
||||
const prefFilterTriggerStyle = {
|
||||
padding: '0.1rem 0.28rem',
|
||||
borderRadius: '0.24rem',
|
||||
padding: '0.12rem 0.16rem',
|
||||
borderRadius: '0.12rem',
|
||||
fontSize: '0.14rem',
|
||||
background: '#F5FAF9',
|
||||
border: '1px solid #e0e0e0',
|
||||
background: '#F3F4F6',
|
||||
border: 'none',
|
||||
minWidth: '0.9rem',
|
||||
justifyContent: 'center',
|
||||
height: '0.38rem',
|
||||
height: '0.43rem',
|
||||
boxSizing: 'border-box',
|
||||
}
|
||||
/** 第2步:筛选组件显示文字样式 */
|
||||
const prefFilterDisplayStyle = {
|
||||
maxWidth: 'none',
|
||||
color: '#6A7282',
|
||||
}
|
||||
|
||||
/** 第2步:地区选择变更 */
|
||||
|
||||
@@ -1,55 +1,98 @@
|
||||
<template>
|
||||
<!-- 待投递列表下拉弹窗 -->
|
||||
<div class="agent-main__task-dropdown" @click.stop>
|
||||
<!-- Tab 切换 -->
|
||||
<div class="agent-main__task-tabs">
|
||||
<span
|
||||
class="agent-main__task-tab"
|
||||
:class="{ 'agent-main__task-tab--active': activeTab === 1 }"
|
||||
@click="switchTab(1)"
|
||||
>进行中({{ pendingList.length }})</span>
|
||||
<span
|
||||
class="agent-main__task-tab"
|
||||
:class="{ 'agent-main__task-tab--active': activeTab === 2 }"
|
||||
@click="switchTab(2)"
|
||||
>已完成({{ completedList.length }})</span>
|
||||
</div>
|
||||
<!-- 列表内容 -->
|
||||
<div class="agent-main__task-list">
|
||||
<template v-if="activeTab === 1">
|
||||
<div v-if="pendingList.length === 0" class="agent-main__task-empty">暂无进行中的岗位</div>
|
||||
<div v-for="job in pendingList" :key="job.id" class="agent-main__task-item">
|
||||
<div class="agent-main__task-item-left">
|
||||
<span class="agent-main__task-item-name">{{ (job.companyShortName || job.companyName) + '—' + job.title }}</span>
|
||||
<span class="agent-main__task-item-tag">自动投递</span>
|
||||
<!-- 投递任务抽屉 — 从浏览器右侧弹出,包含待投递和已完成两个tab -->
|
||||
<Teleport to="body">
|
||||
<Transition name="agent-task-drawer">
|
||||
<div v-if="visible" class="agent-task-drawer-mask" @click.self="handleClose">
|
||||
<div class="agent-task-drawer">
|
||||
<!-- 顶部标题栏 -->
|
||||
<div class="agent-task-drawer__header mb10">
|
||||
<div class="agent-task-drawer__header-left">
|
||||
<!-- 关闭按钮 -->
|
||||
<div class="agent-task-drawer__close" @click="handleClose">
|
||||
<svg viewBox="0 0 24 24" fill="none" class="agent-task-drawer__close-icon">
|
||||
<path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="agent-task-drawer__title">投递任务</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="agent-main__task-item-right">
|
||||
<span class="agent-main__task-item-status">未开始</span>
|
||||
<span class="agent-main__task-item-remove" @click="removeJob(job)">×</span>
|
||||
|
||||
<!-- Tab 切换按钮 -->
|
||||
<div class="agent-task-drawer__tabs">
|
||||
<button
|
||||
class="agent-task-drawer__tab"
|
||||
:class="{ 'agent-task-drawer__tab--active': activeTab === 'pending' }"
|
||||
@click="switchTab('pending')"
|
||||
>待投递 {{ pendingList.length }}</button>
|
||||
<button
|
||||
class="agent-task-drawer__tab"
|
||||
:class="{ 'agent-task-drawer__tab--active': activeTab === 'completed' }"
|
||||
@click="switchTab('completed')"
|
||||
>已完成 {{ completedList.length }}</button>
|
||||
</div>
|
||||
|
||||
<!-- 列表内容 -->
|
||||
<div class="agent-task-drawer__body">
|
||||
<!-- 待投递列表 -->
|
||||
<template v-if="activeTab === 'pending'">
|
||||
<div v-if="pendingLoading" class="agent-task-drawer__empty">加载中...</div>
|
||||
<div v-else-if="pendingList.length === 0" class="agent-task-drawer__empty">暂无待投递岗位</div>
|
||||
<div
|
||||
v-for="job in pendingList"
|
||||
:key="job.id"
|
||||
class="agent-task-drawer__card"
|
||||
>
|
||||
<div class="agent-task-drawer__card-info">
|
||||
<div class="agent-task-drawer__card-title">{{ job.title }}</div>
|
||||
<div class="agent-task-drawer__card-company">
|
||||
<img v-if="job.companyLogoUrl" :src="job.companyLogoUrl" class="agent-task-drawer__card-logo" :alt="job.companyShortName" />
|
||||
<svg v-else class="agent-task-drawer__card-logo-placeholder" viewBox="0 0 24 24" fill="none">
|
||||
<rect x="3" y="7" width="18" height="14" rx="2" stroke="currentColor" stroke-width="1.5"/>
|
||||
<path d="M7 7V5a2 2 0 012-2h6a2 2 0 012 2v2" stroke="currentColor" stroke-width="1.5"/>
|
||||
</svg>
|
||||
<span>{{ job.companyShortName || job.companyName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="agent-task-drawer__remove-btn"
|
||||
:disabled="removingIds.includes(job.id)"
|
||||
@click="handleRemove(job)"
|
||||
>移出任务</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 已完成列表 -->
|
||||
<template v-else>
|
||||
<div v-if="completedLoading" class="agent-task-drawer__empty">加载中...</div>
|
||||
<div v-else-if="completedList.length === 0" class="agent-task-drawer__empty">暂无已完成岗位</div>
|
||||
<div
|
||||
v-for="job in completedList"
|
||||
:key="job.id"
|
||||
class="agent-task-drawer__card"
|
||||
>
|
||||
<div class="agent-task-drawer__card-info">
|
||||
<div class="agent-task-drawer__card-title">{{ job.title }}</div>
|
||||
<div class="agent-task-drawer__card-company">
|
||||
<img v-if="job.companyLogoUrl" :src="job.companyLogoUrl" class="agent-task-drawer__card-logo" :alt="job.companyShortName" />
|
||||
<svg v-else class="agent-task-drawer__card-logo-placeholder" viewBox="0 0 24 24" fill="none">
|
||||
<rect x="3" y="7" width="18" height="14" rx="2" stroke="currentColor" stroke-width="1.5"/>
|
||||
<path d="M7 7V5a2 2 0 012-2h6a2 2 0 012 2v2" stroke="currentColor" stroke-width="1.5"/>
|
||||
</svg>
|
||||
<span>{{ job.companyShortName || job.companyName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 已完成状态不显示移出按钮 -->
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div v-if="loading" class="agent-main__task-empty">加载中...</div>
|
||||
<div v-else-if="completedList.length === 0" class="agent-main__task-empty">暂无已完成的岗位</div>
|
||||
<div v-for="job in completedList" :key="job.id" class="agent-main__task-item">
|
||||
<div class="agent-main__task-item-left">
|
||||
<span class="agent-main__task-item-name">{{ (job.companyShortName || job.companyName) + '—' + job.title }}</span>
|
||||
<span class="agent-main__task-item-tag">自动投递</span>
|
||||
</div>
|
||||
<div class="agent-main__task-item-right">
|
||||
<span class="agent-main__task-item-status agent-main__task-item-status--done">已完成</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<!-- 查看全部 -->
|
||||
<div class="agent-main__task-view-all" @click="handleViewAll">查看全部</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, watch } from 'vue'
|
||||
import { fetchAgentTaskList } from '@/api/jobs'
|
||||
import { cancelApplyJob } from '@/api/agent'
|
||||
import type { JobListItem } from '@/api/jobs'
|
||||
@@ -57,81 +100,114 @@ import type { JobListItem } from '@/api/jobs'
|
||||
// ==================== Props ====================
|
||||
|
||||
const props = defineProps<{
|
||||
/** 进行中列表(由父组件传入,保持同步) */
|
||||
pendingList: JobListItem[]
|
||||
/** 是否显示抽屉 */
|
||||
visible: boolean
|
||||
}>()
|
||||
|
||||
// ==================== 事件 ====================
|
||||
|
||||
const emit = defineEmits<{
|
||||
/** 关闭抽屉 */
|
||||
(e: 'close'): void
|
||||
/** 更新visible */
|
||||
(e: 'update:visible', val: boolean): void
|
||||
/** 移除岗位后通知父组件刷新列表 */
|
||||
(e: 'removed', jobId: string): void
|
||||
/** 查看全部(进行中 tab) */
|
||||
(e: 'viewAll'): void
|
||||
/** 查看全部(已完成 tab — 申请进度) */
|
||||
(e: 'viewAllCompleted'): void
|
||||
}>()
|
||||
|
||||
// ==================== 状态 ====================
|
||||
|
||||
/** 当前激活的 Tab(1=进行中 2=已完成) */
|
||||
const activeTab = ref(1)
|
||||
/** 当前激活的 Tab */
|
||||
const activeTab = ref<'pending' | 'completed'>('pending')
|
||||
|
||||
/** 已完成列表数据 */
|
||||
/** 待投递列表 */
|
||||
const pendingList = ref<JobListItem[]>([])
|
||||
|
||||
/** 已完成列表 */
|
||||
const completedList = ref<JobListItem[]>([])
|
||||
|
||||
/** 加载状态 */
|
||||
const loading = ref(false)
|
||||
/** 待投递加载状态 */
|
||||
const pendingLoading = ref(false)
|
||||
|
||||
// ==================== 生命周期 ====================
|
||||
/** 已完成加载状态 */
|
||||
const completedLoading = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
// 打开时同时加载已完成列表
|
||||
loadCompletedList()
|
||||
/** 正在移除中的岗位 ID 列表 */
|
||||
const removingIds = ref<string[]>([])
|
||||
|
||||
// ==================== 监听 ====================
|
||||
|
||||
/** 打开时加载数据 */
|
||||
watch(() => props.visible, (val) => {
|
||||
if (val) {
|
||||
loadPendingList()
|
||||
loadCompletedList()
|
||||
}
|
||||
})
|
||||
|
||||
// ==================== 方法 ====================
|
||||
|
||||
/** 切换 Tab */
|
||||
function switchTab(tab: number) {
|
||||
function switchTab(tab: 'pending' | 'completed') {
|
||||
activeTab.value = tab
|
||||
if (tab === 2) {
|
||||
loadCompletedList()
|
||||
}
|
||||
|
||||
/** 加载待投递列表(pageSize=300) */
|
||||
async function loadPendingList() {
|
||||
pendingLoading.value = true
|
||||
try {
|
||||
const res = await fetchAgentTaskList({ pageNum: 1, pageSize: 300, tab: 1 })
|
||||
if (res.code === '0' && res.data) {
|
||||
pendingList.value = res.data.list || []
|
||||
}
|
||||
} catch {
|
||||
console.error('[AgentTaskListDropdown] 加载待投递列表失败')
|
||||
} finally {
|
||||
pendingLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 加载已完成任务列表(tab=2) */
|
||||
/** 加载已完成列表(pageSize=300) */
|
||||
async function loadCompletedList() {
|
||||
loading.value = true
|
||||
completedLoading.value = true
|
||||
try {
|
||||
const res = await fetchAgentTaskList({ pageNum: 1, pageSize: 30, tab: 2 })
|
||||
const res = await fetchAgentTaskList({ pageNum: 1, pageSize: 300, tab: 2 })
|
||||
if (res.code === '0' && res.data) {
|
||||
completedList.value = res.data.list || []
|
||||
}
|
||||
} catch {
|
||||
console.error('[AgentTaskListDropdown] 加载已完成列表失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
completedLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 移除岗位 — 调用 cancelApplyJob 接口并通知父组件 */
|
||||
async function removeJob(job: JobListItem) {
|
||||
/** 移出岗位 */
|
||||
async function handleRemove(job: JobListItem) {
|
||||
if (removingIds.value.includes(job.id)) return
|
||||
removingIds.value.push(job.id)
|
||||
try {
|
||||
await cancelApplyJob(job.id)
|
||||
const idx = pendingList.value.findIndex(j => j.id === job.id)
|
||||
if (idx !== -1) {
|
||||
pendingList.value.splice(idx, 1)
|
||||
}
|
||||
emit('removed', job.id)
|
||||
ElMessage.success('已移除')
|
||||
} catch {
|
||||
ElMessage.error('移除失败')
|
||||
} finally {
|
||||
removingIds.value = removingIds.value.filter(id => id !== job.id)
|
||||
}
|
||||
}
|
||||
|
||||
/** 查看全部 — 根据当前 tab 触发不同事件 */
|
||||
function handleViewAll() {
|
||||
if (activeTab.value === 1) {
|
||||
emit('viewAll')
|
||||
} else {
|
||||
emit('viewAllCompleted')
|
||||
}
|
||||
/** 关闭抽屉 */
|
||||
function handleClose() {
|
||||
emit('close')
|
||||
emit('update:visible', false)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use '../assets/styles/components/agent-task-list-dropdown';
|
||||
</style>
|
||||
|
||||
@@ -1,94 +1,82 @@
|
||||
<template>
|
||||
<!-- 求职目标设置弹窗 -->
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
width="480px"
|
||||
:show-close="false"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="true"
|
||||
:align-center="false"
|
||||
:style="{ marginLeft: 'auto', marginRight: '0.2rem' }"
|
||||
class="job-goal-dialog"
|
||||
@close="handleClose"
|
||||
>
|
||||
<!-- 头部区域 -->
|
||||
<div class="job-goal-dialog__header">
|
||||
<!-- 关闭按钮 -->
|
||||
<button class="job-goal-dialog__close-btn" @click="handleClose">
|
||||
<el-icon><Close /></el-icon>
|
||||
</button>
|
||||
<!-- 弹窗标题 -->
|
||||
<span class="job-goal-dialog__title">求职目标设置</span>
|
||||
</div>
|
||||
|
||||
<!-- 岗位选择模块 -->
|
||||
<div class="job-goal-dialog__section">
|
||||
<div class="job-goal-dialog__label">*岗位</div>
|
||||
<JobCategorySelector
|
||||
:categoryIds="selectedCategoryIds"
|
||||
:maxSelect="3"
|
||||
:level="3"
|
||||
:allowParentSelect="false"
|
||||
:triggerStyle="selectorTriggerStyle"
|
||||
:displayStyle="selectorDisplayStyle"
|
||||
@update:categoryIds="onCategoryChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 行业选择模块 -->
|
||||
<div class="job-goal-dialog__section">
|
||||
<div class="job-goal-dialog__label">*行业</div>
|
||||
<IndustrySelector
|
||||
:industryIds="selectedIndustryIds"
|
||||
:maxSelect="3"
|
||||
:level="2"
|
||||
:allowParentSelect="false"
|
||||
:triggerStyle="selectorTriggerStyle"
|
||||
:displayStyle="selectorDisplayStyle"
|
||||
@update:industryIds="onIndustryChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 城市选择模块 -->
|
||||
<div class="job-goal-dialog__section">
|
||||
<div class="job-goal-dialog__label">*城市</div>
|
||||
<RegionSelector
|
||||
:regionCodes="selectedRegionCodes"
|
||||
:level="2"
|
||||
:maxSelect="3"
|
||||
:triggerStyle="selectorTriggerStyle"
|
||||
:displayStyle="selectorDisplayStyle"
|
||||
@update:regionCodes="onRegionChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 招聘分类选择模块 -->
|
||||
<div class="job-goal-dialog__section ">
|
||||
<div class="job-goal-dialog__label">*招聘分类</div>
|
||||
<!-- 招聘分类按钮组 -->
|
||||
<div class="job-goal-dialog__type-group">
|
||||
<button
|
||||
v-for="t in jobTypes"
|
||||
:key="t"
|
||||
class="job-goal-dialog__type-btn"
|
||||
:class="{ 'job-goal-dialog__type-btn--active': selectedJobType === t }"
|
||||
@click="selectedJobType = t"
|
||||
>
|
||||
{{ t }}
|
||||
</button>
|
||||
<!-- 求职偏好设置弹窗 -->
|
||||
<div v-if="visible" class="job-goal-dialog__overlay" @click.self="handleClose">
|
||||
<div class="job-goal-dialog">
|
||||
<!-- 头部区域 -->
|
||||
<div class="job-goal-dialog__header">
|
||||
<span class="job-goal-dialog__title">求职偏好</span>
|
||||
<!-- 关闭按钮 -->
|
||||
<svg class="job-goal-dialog__close-btn" @click="handleClose" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M6 6L18 18M18 6L6 18" stroke="#6A7282" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 保存按钮区域 -->
|
||||
<div class="job-goal-dialog__footer mt10">
|
||||
<!-- 岗位选择模块 -->
|
||||
<div class="job-goal-dialog__section">
|
||||
<div class="job-goal-dialog__label">岗位</div>
|
||||
<JobCategorySelector
|
||||
:categoryIds="selectedCategoryIds"
|
||||
:maxSelect="3"
|
||||
:level="3"
|
||||
:allowParentSelect="false"
|
||||
:triggerStyle="selectorTriggerStyle"
|
||||
:displayStyle="selectorDisplayStyle"
|
||||
@update:categoryIds="onCategoryChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 行业选择模块 -->
|
||||
<div class="job-goal-dialog__section">
|
||||
<div class="job-goal-dialog__label">行业</div>
|
||||
<IndustrySelector
|
||||
:industryIds="selectedIndustryIds"
|
||||
:maxSelect="3"
|
||||
:level="2"
|
||||
:allowParentSelect="false"
|
||||
:triggerStyle="selectorTriggerStyle"
|
||||
:displayStyle="selectorDisplayStyle"
|
||||
@update:industryIds="onIndustryChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 城市选择模块 -->
|
||||
<div class="job-goal-dialog__section">
|
||||
<div class="job-goal-dialog__label">城市</div>
|
||||
<RegionSelector
|
||||
:regionCodes="selectedRegionCodes"
|
||||
:level="2"
|
||||
:maxSelect="3"
|
||||
:triggerStyle="selectorTriggerStyle"
|
||||
:displayStyle="selectorDisplayStyle"
|
||||
@update:regionCodes="onRegionChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 招聘类型选择模块 -->
|
||||
<div class="job-goal-dialog__section">
|
||||
<div class="job-goal-dialog__label">招聘类型</div>
|
||||
<!-- 招聘类型按钮组 -->
|
||||
<div class="job-goal-dialog__type-group">
|
||||
<button
|
||||
v-for="t in jobTypes"
|
||||
:key="t"
|
||||
class="job-goal-dialog__type-btn"
|
||||
:class="{ 'job-goal-dialog__type-btn--active': selectedJobType === t }"
|
||||
@click="selectedJobType = t"
|
||||
>
|
||||
{{ t }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 保存按钮 -->
|
||||
<button class="job-goal-dialog__save-btn" @click="handleSave">保存</button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { Close } from '@element-plus/icons-vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { JOB_TYPE_OPTIONS, formatEmploymentType } from '@/stores/index'
|
||||
import RegionSelector from './tools/RegionSelector.vue'
|
||||
@@ -116,9 +104,9 @@ watch(visible, (v) => { emit('update:modelValue', v) })
|
||||
const selectedCategoryIds = ref<number[]>([])
|
||||
const selectedIndustryIds = ref<number[]>([])
|
||||
const selectedRegionCodes = ref<string[]>([])
|
||||
const selectedJobType = ref('全职')
|
||||
const selectedJobType = ref('全部')
|
||||
|
||||
/** 招聘分类选项列表 — 从全局常量提取 label 生成 */
|
||||
/** 招聘类型选项列表 */
|
||||
const jobTypes = JOB_TYPE_OPTIONS.map(item => item.label)
|
||||
|
||||
/** 弹窗打开时从 store 同步数据到本地编辑副本 */
|
||||
@@ -128,25 +116,25 @@ watch(() => props.modelValue, (v) => {
|
||||
selectedCategoryIds.value = [...(intention.categoryIds || [])]
|
||||
selectedIndustryIds.value = [...(intention.industryIds || [])]
|
||||
selectedRegionCodes.value = [...(intention.regionCodes || [])]
|
||||
selectedJobType.value = formatEmploymentType(intention.recruitCategory)
|
||||
selectedJobType.value = formatEmploymentType(intention.recruitCategory) || '全部'
|
||||
}
|
||||
})
|
||||
|
||||
/** 选择器触发按钮的自定义样式,适配弹窗内布局(参考 ProfileEditDrawer 中 regionTriggerStyle) */
|
||||
/** 选择器触发按钮的自定义样式 */
|
||||
const selectorTriggerStyle: Record<string, string> = {
|
||||
width: '100%',
|
||||
'box-sizing': 'border-box',
|
||||
padding: '0.1rem 0.14rem',
|
||||
'font-size': '0.13rem',
|
||||
color: '#1a1a2e',
|
||||
background: '#f6f6f9',
|
||||
border: '1px solid transparent',
|
||||
'border-radius': '0.06rem',
|
||||
padding: '0.08rem 0.16rem',
|
||||
'font-size': '0.14rem',
|
||||
color: '#1A1A1A',
|
||||
background: '#F3F4F6',
|
||||
border: 'none',
|
||||
'border-radius': '0.08rem',
|
||||
'max-width': 'none',
|
||||
'justify-content': 'space-between',
|
||||
}
|
||||
|
||||
/** 选择器显示文字的自定义样式,覆盖默认 max-width: 1.6rem */
|
||||
/** 选择器显示文字的自定义样式 */
|
||||
const selectorDisplayStyle: Record<string, string> = {
|
||||
'max-width': 'none',
|
||||
}
|
||||
@@ -166,9 +154,7 @@ function onRegionChange(codes: string[]) {
|
||||
selectedRegionCodes.value = codes
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存表单数据:调用 store action 保存到后端并同步 store,然后关闭弹窗
|
||||
*/
|
||||
/** 保存表单数据 */
|
||||
async function handleSave() {
|
||||
try {
|
||||
await store.dispatch('saveJobIntention', {
|
||||
@@ -183,9 +169,7 @@ async function handleSave() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭弹窗
|
||||
*/
|
||||
/** 关闭弹窗 */
|
||||
function handleClose() {
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
<!-- 加载中 -->
|
||||
<div v-if="chatLoading" class="mentor-aside-panel__chat-loading">
|
||||
<div class="mentor-aside-panel__chat-spinner"></div>
|
||||
<span>正在生成对话预览...</span>
|
||||
<span>正在加载...</span>
|
||||
</div>
|
||||
|
||||
<!-- 对话消息列表 -->
|
||||
@@ -164,60 +164,26 @@
|
||||
|
||||
<!-- 底部按钮 + 提示文字 -->
|
||||
<div class="mentor-aside-panel__footer">
|
||||
<button class="mentor-aside-panel__cta-btn" @click="openQrDialog">立即咨询导师</button>
|
||||
<button class="mentor-aside-panel__cta-btn" @click="openQrDialog">继续咨询</button>
|
||||
<div class="mentor-aside-panel__footer-tip">对话内容根据导师服务类型与行业背景动态生成</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- ==================== 二维码弹窗(遮罩 + 居中卡片) ==================== -->
|
||||
<teleport to="body">
|
||||
<div v-if="showQrDialog" class="mentor-qr-overlay" @click.self="closeQrDialog">
|
||||
<div class="mentor-qr-card">
|
||||
<!-- 头部:标题 + 关闭按钮 -->
|
||||
<div class="mentor-qr-card__header">
|
||||
<div class="mentor-qr-card__title-wrap">
|
||||
<div class="mentor-qr-card__title">扫码进入小程序预约导师咨询</div>
|
||||
<div class="mentor-qr-card__desc">查看导师价格、过往评价,并完成预约</div>
|
||||
</div>
|
||||
<!-- 关闭按钮 -->
|
||||
<div class="mentor-qr-card__close" @click="closeQrDialog">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M18 6L6 18M6 6l12 12" stroke="#6A7282" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 二维码展示区域 -->
|
||||
<div class="mentor-qr-card__qr-area">
|
||||
<div v-if="qrLoading" class="mentor-qr-card__loading">
|
||||
<div class="mentor-qr-card__spinner"></div>
|
||||
</div>
|
||||
<img
|
||||
v-else-if="qrCodeBase64"
|
||||
:src="qrCodeBase64"
|
||||
alt="小程序二维码"
|
||||
class="mentor-qr-card__qr-img"
|
||||
/>
|
||||
<div v-else class="mentor-qr-card__placeholder">二维码加载失败</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部提示 -->
|
||||
<div class="mentor-qr-card__footer">
|
||||
<div class="mentor-qr-card__footer-text">小程序名称:见识星球 | 大学生求职神器</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
<!-- 二维码弹窗组件 -->
|
||||
<MentorQrCodeDialog
|
||||
v-model:visible="showQrDialog"
|
||||
:mentorId="mentorId"
|
||||
:source="mode === 'list' ? 'fixed' : 'api'"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { fetchMentorMockChat, fetchMentorQrCode } from '@/api/mentor'
|
||||
import { fetchMentorMockChat } from '@/api/mentor'
|
||||
import type { MentorMockMessage } from '@/api/mentor'
|
||||
// 模式一固定二维码图片
|
||||
import fixedQrCodeImg from '@/assets/images/mentor/jsxqQrCode-mentors-page.png'
|
||||
import MentorQrCodeDialog from '@/components/MentorQrCodeDialog.vue'
|
||||
|
||||
// ==================== Props ====================
|
||||
|
||||
@@ -270,51 +236,10 @@ onMounted(() => {
|
||||
/** 弹窗是否显示 */
|
||||
const showQrDialog = ref(false)
|
||||
|
||||
/** 二维码图片 base64 */
|
||||
const qrCodeBase64 = ref('')
|
||||
|
||||
/** 二维码加载状态 */
|
||||
const qrLoading = ref(false)
|
||||
|
||||
/**
|
||||
* 打开二维码弹窗
|
||||
* 模式一:展示本地固定二维码图片
|
||||
* 模式二:请求后端生成导师专属二维码
|
||||
*/
|
||||
async function openQrDialog() {
|
||||
function openQrDialog() {
|
||||
showQrDialog.value = true
|
||||
|
||||
if (props.mode === 'list') {
|
||||
// 模式一:直接使用本地固定图片
|
||||
qrLoading.value = false
|
||||
qrCodeBase64.value = fixedQrCodeImg
|
||||
return
|
||||
}
|
||||
|
||||
// 模式二:调接口获取 base64 二维码
|
||||
qrLoading.value = true
|
||||
qrCodeBase64.value = ''
|
||||
try {
|
||||
const res: any = await fetchMentorQrCode(props.mentorId)
|
||||
// 返回值为 base64 图片字符串
|
||||
const base64 = res?.data ?? res
|
||||
if (typeof base64 === 'string' && base64.length > 0) {
|
||||
// 如果后端返回的已经包含 data:image 前缀就直接用,否则拼上
|
||||
qrCodeBase64.value = base64.startsWith('data:image')
|
||||
? base64
|
||||
: `data:image/png;base64,${base64}`
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[二维码] 获取失败', e)
|
||||
} finally {
|
||||
qrLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭弹窗
|
||||
*/
|
||||
function closeQrDialog() {
|
||||
showQrDialog.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<!-- 导师小程序二维码弹窗 -->
|
||||
<teleport to="body">
|
||||
<div v-if="visible" class="mentor-qr-overlay" @click.self="close">
|
||||
<div class="mentor-qr-card">
|
||||
<!-- 头部:标题 + 关闭按钮 -->
|
||||
<div class="mentor-qr-card__header">
|
||||
<div class="mentor-qr-card__title-wrap">
|
||||
<div class="mentor-qr-card__title">扫码进入小程序预约导师咨询</div>
|
||||
<div class="mentor-qr-card__desc">查看导师价格、过往评价,并完成预约</div>
|
||||
</div>
|
||||
<!-- 关闭按钮 -->
|
||||
<div class="mentor-qr-card__close" @click="close">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M18 6L6 18M6 6l12 12" stroke="#6A7282" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 二维码展示区域 -->
|
||||
<div class="mentor-qr-card__qr-area">
|
||||
<div v-if="qrLoading" class="mentor-qr-card__loading">
|
||||
<div class="mentor-qr-card__spinner"></div>
|
||||
</div>
|
||||
<img
|
||||
v-else-if="qrImgSrc"
|
||||
:src="qrImgSrc"
|
||||
alt="小程序二维码"
|
||||
class="mentor-qr-card__qr-img"
|
||||
/>
|
||||
<div v-else class="mentor-qr-card__placeholder">二维码加载失败</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部提示 -->
|
||||
<div class="mentor-qr-card__footer">
|
||||
<div class="mentor-qr-card__footer-text">小程序名称:见识星球 | 大学生求职神器</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { fetchMentorQrCode } from '@/api/mentor'
|
||||
// 模式一使用的固定二维码图片
|
||||
import fixedQrCodeImg from '@/assets/images/mentor/jsxqQrCode-mentors-page.png'
|
||||
|
||||
// ==================== Props ====================
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
/** 是否显示弹窗 */
|
||||
visible: boolean
|
||||
/** 导师ID(模式为api时必传) */
|
||||
mentorId?: string
|
||||
/** 二维码来源模式:fixed=本地固定图 / api=接口获取 */
|
||||
source?: 'fixed' | 'api'
|
||||
}>(), {
|
||||
visible: false,
|
||||
mentorId: '',
|
||||
source: 'api',
|
||||
})
|
||||
|
||||
// ==================== Emits ====================
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', value: boolean): void
|
||||
}>()
|
||||
|
||||
// ==================== 状态 ====================
|
||||
|
||||
/** 二维码图片地址 */
|
||||
const qrImgSrc = ref('')
|
||||
|
||||
/** 加载状态 */
|
||||
const qrLoading = ref(false)
|
||||
|
||||
// ==================== 方法 ====================
|
||||
|
||||
/** 关闭弹窗 */
|
||||
function close() {
|
||||
emit('update:visible', false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载二维码
|
||||
* fixed 模式直接用本地图片,api 模式调接口
|
||||
*/
|
||||
async function loadQrCode() {
|
||||
if (props.source === 'fixed') {
|
||||
qrLoading.value = false
|
||||
qrImgSrc.value = fixedQrCodeImg
|
||||
return
|
||||
}
|
||||
|
||||
// api 模式:请求后端生成导师专属二维码
|
||||
qrLoading.value = true
|
||||
qrImgSrc.value = ''
|
||||
try {
|
||||
const res: any = await fetchMentorQrCode(props.mentorId)
|
||||
// 返回结构:{ code: "0", data: { code: "data:image/png;base64,..." } }
|
||||
const base64 = res?.data?.code ?? res?.code ?? ''
|
||||
if (typeof base64 === 'string' && base64.length > 0) {
|
||||
qrImgSrc.value = base64.startsWith('data:image')
|
||||
? base64
|
||||
: `data:image/png;base64,${base64}`
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[二维码] 获取失败', e)
|
||||
} finally {
|
||||
qrLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 监听弹窗打开时加载 ====================
|
||||
|
||||
watch(() => props.visible, (val) => {
|
||||
if (val) {
|
||||
loadQrCode()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -2,7 +2,7 @@
|
||||
<!-- 个人资料编辑组件 — 内联模式(直接嵌入页面),通过 modelValue 控制显示/隐藏 -->
|
||||
<div v-if="modelValue" class="profile-edit-inline">
|
||||
<!-- 表单内容区 — 根据模块名动态渲染不同字段 -->
|
||||
<div class="profile-edit-inline__body">
|
||||
<div class="profile-edit-inline__body pb0">
|
||||
<!-- ========== 基本信息模块 ========== -->
|
||||
<template v-if="module === 'info'">
|
||||
<!-- 基本信息字段横排布局 -->
|
||||
@@ -204,9 +204,20 @@
|
||||
<!-- 标题 + AI润色按钮 -->
|
||||
<div class="profile-edit-inline__summary-header">
|
||||
<label class="profile-edit-inline__label">编辑个人概述</label>
|
||||
<button class="profile-edit-inline__ai-polish-btn" @click="handleAiPolish" :disabled="aiPolishing">
|
||||
<span><span>✦</span> AI润色</span>
|
||||
</button>
|
||||
<!-- AI润色按钮 -->
|
||||
<div class="dib dflex-center w66 h24 lh24 border-ra4 color-f aliite-c bg-linear-1 cursor-po mb4" @click="handleAiPolish" :disabled="aiPolishing">
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_589_1500)">
|
||||
<path d="M4.55306 2.724C4.85206 1.849 6.06106 1.8225 6.41556 2.6445L6.44556 2.7245L6.84906 3.9045C6.94154 4.17512 7.09097 4.42276 7.28728 4.63071C7.48359 4.83867 7.72222 5.00211 7.98706 5.11L8.09556 5.1505L9.27556 5.5535C10.1506 5.8525 10.1771 7.0615 9.35556 7.416L9.27556 7.446L8.09556 7.8495C7.82485 7.94191 7.57712 8.09131 7.36907 8.28763C7.16103 8.48394 6.99751 8.7226 6.88956 8.9875L6.84906 9.0955L6.44606 10.276C6.14706 11.151 4.93806 11.1775 4.58406 10.356L4.55306 10.276L4.15006 9.096C4.05765 8.82529 3.90825 8.57755 3.71193 8.36951C3.51562 8.16146 3.27696 7.99795 3.01206 7.89L2.90406 7.8495L1.72406 7.4465C0.848564 7.1475 0.822064 5.9385 1.64406 5.5845L1.72406 5.5535L2.90406 5.1505C3.17468 5.05803 3.42232 4.9086 3.63028 4.71229C3.83823 4.51597 4.00167 4.27735 4.10956 4.0125L4.15006 3.9045L4.55306 2.724ZM5.49956 3.047L5.09656 4.227C4.95576 4.63965 4.7267 5.01665 4.42533 5.33175C4.12397 5.64684 3.75754 5.89246 3.35156 6.0515L3.22656 6.097L2.04656 6.5L3.22656 6.903C3.63922 7.0438 4.01622 7.27287 4.33131 7.57423C4.64641 7.8756 4.89203 8.24203 5.05106 8.648L5.09656 8.773L5.49956 9.953L5.90256 8.773C6.04337 8.36035 6.27243 7.98335 6.5738 7.66825C6.87516 7.35316 7.24159 7.10754 7.64756 6.9485L7.77256 6.9035L8.95256 6.5L7.77256 6.097C7.35991 5.9562 6.98291 5.72713 6.66782 5.42577C6.35272 5.1244 6.1071 4.75797 5.94806 4.352L5.90306 4.227L5.49956 3.047ZM9.49956 1C9.5931 1 9.68477 1.02624 9.76414 1.07574C9.84351 1.12523 9.90741 1.196 9.94856 1.28L9.97256 1.3385L10.1476 1.8515L10.6611 2.0265C10.7548 2.05835 10.837 2.11731 10.8972 2.19591C10.9574 2.27451 10.9929 2.36921 10.9992 2.46801C11.0055 2.56681 10.9824 2.66527 10.9327 2.75089C10.883 2.83652 10.809 2.90547 10.7201 2.949L10.6611 2.973L10.1481 3.148L9.97306 3.6615C9.94116 3.75521 9.88216 3.83735 9.80353 3.8975C9.7249 3.95764 9.63018 3.9931 9.53138 3.99936C9.43259 4.00563 9.33415 3.98242 9.24856 3.93269C9.16296 3.88296 9.09405 3.80893 9.05056 3.72L9.02656 3.6615L8.85156 3.1485L8.33806 2.9735C8.24432 2.94165 8.16215 2.88269 8.10195 2.80409C8.04175 2.72549 8.00624 2.63079 7.99993 2.53199C7.99361 2.43319 8.01676 2.33473 8.06645 2.24911C8.11615 2.16348 8.19014 2.09453 8.27906 2.051L8.33806 2.027L8.85106 1.852L9.02606 1.3385C9.05978 1.23971 9.12357 1.15395 9.20848 1.09325C9.2934 1.03254 9.39518 0.999937 9.49956 1Z" fill="currentColor"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_589_1500">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<span class="ml2 fs12 fw600">AI润色</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="profile-edit-inline__field">
|
||||
<textarea class="profile-edit-inline__textarea" placeholder="请输入个人概述" v-model="summaryText" rows="6"></textarea>
|
||||
|
||||
@@ -22,25 +22,25 @@
|
||||
<el-icon><EditPen /></el-icon><span>编辑</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="profile-page-content__info-name dflex-start aliite-e"><span class="fs28">{{ profile.name }}</span><span class="fs13 color-6 ml10 dflex-start aliite-c pb5"><svg viewBox="0 0 16 16" fill="none" class="resume-detail__contact-icon">
|
||||
<div class="profile-page-content__info-name dflex-start aliite-e"><span class="fs28">{{ profile.name }}</span><span v-if="profile.regionCode&&profile.regionCode!='null'" class="fs13 color-6 ml10 dflex-start aliite-c pb5"><svg viewBox="0 0 16 16" fill="none" class="resume-detail__contact-icon">
|
||||
<circle cx="8" cy="6.5" r="2.5" stroke="currentColor" stroke-width="1.2"/>
|
||||
<path d="M8 14s-5-4-5-7.5a5 5 0 0110 0C13 10 8 14 8 14z" stroke="currentColor" stroke-width="1.2"/>
|
||||
</svg> {{ resolveRegionName(profile.regionCode) }}</span></div>
|
||||
<div class="profile-page-content__info-contacts">
|
||||
<span class="profile-page-content__contact-item"><svg viewBox="0 0 16 16" fill="none" class="resume-detail__contact-icon">
|
||||
<span v-if="profile.phone&&profile.phone!='null'" class="profile-page-content__contact-item"><svg viewBox="0 0 16 16" fill="none" class="resume-detail__contact-icon">
|
||||
<path d="M4 2h2.5l1.5 3-1.5 1.5a8 8 0 003 3L11 8l3 1.5V12a2 2 0 01-2 2C6.5 14 2 9.5 2 4a2 2 0 012-2z" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/>
|
||||
</svg> {{ profile.phone }}</span>
|
||||
<span class="profile-page-content__contact-item"><svg viewBox="0 0 16 16" fill="none" class="resume-detail__contact-icon">
|
||||
<span v-if="profile.email&&profile.email!='null'" class="profile-page-content__contact-item"><svg viewBox="0 0 16 16" fill="none" class="resume-detail__contact-icon">
|
||||
<rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.2"/>
|
||||
<path d="M2 5.5l6 4 6-4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
|
||||
</svg>{{ profile.email }}</span>
|
||||
|
||||
|
||||
<span class="profile-page-content__info-contacts" v-if="profile.wechat">
|
||||
<span class="profile-page-content__info-contacts" v-if="profile.wechat&&profile.wechat!='null'">
|
||||
<span class="profile-page-content__contact-item"><el-icon class="fs14 color-9"><ChatLineRound /></el-icon> {{ profile.wechat }}</span>
|
||||
</span>
|
||||
<!-- 作品集链接显示在个人信息卡片内 -->
|
||||
<span v-if="profile.portfolioUrl" class="profile-page-content__info-contacts">
|
||||
<span v-if="profile.portfolioUrl&&profile.portfolioUrl!='null'" class="profile-page-content__info-contacts">
|
||||
<span class="profile-page-content__contact-item dib">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="resume-detail__contact-icon mr6" width="0.15rem" height="0.15rem" viewBox="0 0 16 16">
|
||||
<path d="M0 0h16v16H0z" fill="none" />
|
||||
@@ -62,6 +62,8 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl14 mt14"></div>
|
||||
|
||||
<!-- 教育经历 -->
|
||||
<div ref="educationRef" class="profile-page-content__card">
|
||||
<div class="profile-page-content__card-header profile-page-content__header-hover">
|
||||
@@ -97,6 +99,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl14"></div>
|
||||
|
||||
<!-- 工作经历 -->
|
||||
<div ref="workRef" class="profile-page-content__card">
|
||||
<div class="profile-page-content__card-header profile-page-content__header-hover">
|
||||
@@ -131,7 +135,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 实习经历 -->
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl14"></div>
|
||||
|
||||
<!-- 实习经历 -->
|
||||
<div ref="internshipRef" class="profile-page-content__card">
|
||||
<div class="profile-page-content__card-header profile-page-content__header-hover">
|
||||
<h3 class="profile-page-content__card-title">实习经历</h3>
|
||||
@@ -165,6 +171,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl14"></div>
|
||||
|
||||
<!-- 项目经历 -->
|
||||
<div ref="projectRef" class="profile-page-content__card">
|
||||
<div class="profile-page-content__card-header profile-page-content__header-hover">
|
||||
@@ -199,6 +207,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl14"></div>
|
||||
|
||||
<!-- 竞赛 -->
|
||||
<div ref="competitionRef" class="profile-page-content__card">
|
||||
<div class="profile-page-content__card-header profile-page-content__header-hover">
|
||||
@@ -232,6 +242,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl14"></div>
|
||||
|
||||
<!-- 技能 -->
|
||||
<div ref="skillsRef" class="profile-page-content__card" :class="{ 'profile-page-content__card-hover': editingModule !== 'skills' }">
|
||||
<template v-if="editingModule !== 'skills'">
|
||||
@@ -255,6 +267,8 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl14"></div>
|
||||
|
||||
<!-- 证书 -->
|
||||
<div ref="certificateRef" class="profile-page-content__card" :class="{ 'profile-page-content__card-hover': editingModule !== 'certificate' }">
|
||||
<template v-if="editingModule !== 'certificate'">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<!-- 单条经历内联编辑组件 -->
|
||||
<div class="profile-edit-inline">
|
||||
<div class="profile-edit-inline__body">
|
||||
<div class="profile-edit-inline__body pb0">
|
||||
<!-- 教育经历 -->
|
||||
<template v-if="moduleType === 'education'">
|
||||
<div class="profile-edit-inline__fields-row">
|
||||
@@ -76,35 +76,56 @@
|
||||
<!-- 经历描述 + AI润色 -->
|
||||
<div class="profile-edit-inline__summary-header">
|
||||
<label class="profile-edit-inline__label">经历描述</label>
|
||||
<button class="profile-edit-inline__ai-polish-btn" @click="handleAiPolish" :disabled="aiPolishing">
|
||||
<span>✦ AI润色</span>
|
||||
</button>
|
||||
<div class="dib dflex-center w66 h24 lh24 border-ra4 color-f aliite-c bg-linear-1 cursor-po mb4" @click="handleAiPolish" :disabled="aiPolishing">
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_589_1500)">
|
||||
<path d="M4.55306 2.724C4.85206 1.849 6.06106 1.8225 6.41556 2.6445L6.44556 2.7245L6.84906 3.9045C6.94154 4.17512 7.09097 4.42276 7.28728 4.63071C7.48359 4.83867 7.72222 5.00211 7.98706 5.11L8.09556 5.1505L9.27556 5.5535C10.1506 5.8525 10.1771 7.0615 9.35556 7.416L9.27556 7.446L8.09556 7.8495C7.82485 7.94191 7.57712 8.09131 7.36907 8.28763C7.16103 8.48394 6.99751 8.7226 6.88956 8.9875L6.84906 9.0955L6.44606 10.276C6.14706 11.151 4.93806 11.1775 4.58406 10.356L4.55306 10.276L4.15006 9.096C4.05765 8.82529 3.90825 8.57755 3.71193 8.36951C3.51562 8.16146 3.27696 7.99795 3.01206 7.89L2.90406 7.8495L1.72406 7.4465C0.848564 7.1475 0.822064 5.9385 1.64406 5.5845L1.72406 5.5535L2.90406 5.1505C3.17468 5.05803 3.42232 4.9086 3.63028 4.71229C3.83823 4.51597 4.00167 4.27735 4.10956 4.0125L4.15006 3.9045L4.55306 2.724ZM5.49956 3.047L5.09656 4.227C4.95576 4.63965 4.7267 5.01665 4.42533 5.33175C4.12397 5.64684 3.75754 5.89246 3.35156 6.0515L3.22656 6.097L2.04656 6.5L3.22656 6.903C3.63922 7.0438 4.01622 7.27287 4.33131 7.57423C4.64641 7.8756 4.89203 8.24203 5.05106 8.648L5.09656 8.773L5.49956 9.953L5.90256 8.773C6.04337 8.36035 6.27243 7.98335 6.5738 7.66825C6.87516 7.35316 7.24159 7.10754 7.64756 6.9485L7.77256 6.9035L8.95256 6.5L7.77256 6.097C7.35991 5.9562 6.98291 5.72713 6.66782 5.42577C6.35272 5.1244 6.1071 4.75797 5.94806 4.352L5.90306 4.227L5.49956 3.047ZM9.49956 1C9.5931 1 9.68477 1.02624 9.76414 1.07574C9.84351 1.12523 9.90741 1.196 9.94856 1.28L9.97256 1.3385L10.1476 1.8515L10.6611 2.0265C10.7548 2.05835 10.837 2.11731 10.8972 2.19591C10.9574 2.27451 10.9929 2.36921 10.9992 2.46801C11.0055 2.56681 10.9824 2.66527 10.9327 2.75089C10.883 2.83652 10.809 2.90547 10.7201 2.949L10.6611 2.973L10.1481 3.148L9.97306 3.6615C9.94116 3.75521 9.88216 3.83735 9.80353 3.8975C9.7249 3.95764 9.63018 3.9931 9.53138 3.99936C9.43259 4.00563 9.33415 3.98242 9.24856 3.93269C9.16296 3.88296 9.09405 3.80893 9.05056 3.72L9.02656 3.6615L8.85156 3.1485L8.33806 2.9735C8.24432 2.94165 8.16215 2.88269 8.10195 2.80409C8.04175 2.72549 8.00624 2.63079 7.99993 2.53199C7.99361 2.43319 8.01676 2.33473 8.06645 2.24911C8.11615 2.16348 8.19014 2.09453 8.27906 2.051L8.33806 2.027L8.85106 1.852L9.02606 1.3385C9.05978 1.23971 9.12357 1.15395 9.20848 1.09325C9.2934 1.03254 9.39518 0.999937 9.49956 1Z" fill="currentColor"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_589_1500">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<span class="ml2 fs12 fw600">AI润色</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="profile-edit-inline__field">
|
||||
<textarea class="profile-edit-inline__textarea" placeholder="请输入经历描述" v-model="descriptionText" rows="4"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
<div class="profile-edit-inline__footer">
|
||||
<button class="profile-edit-inline__save-btn" @click.stop="handleSave">保存</button>
|
||||
<button class="profile-edit-inline__cancel-btn" @click.stop="handleCancel">取消</button>
|
||||
</div>
|
||||
|
||||
<!-- AI润色结果(保存取消下方) -->
|
||||
<div v-if="aiPolishResult" class="profile-edit-inline__ai-result">
|
||||
<p class="profile-edit-inline__ai-result-label">✦ AI润色结果</p>
|
||||
|
||||
<div class="profile-edit-inline__ai-result-card">
|
||||
<p class="profile-edit-inline__ai-result-label">✦ AI润色结果</p>
|
||||
<p class="profile-edit-inline__ai-result-text">{{ aiPolishResult }}</p>
|
||||
<div class="profile-edit-inline__ai-result-actions">
|
||||
<button class="profile-edit-inline__ai-replace-btn" @click="handleReplaceWithAi">+ 替换为此内容</button>
|
||||
<button class="profile-edit-inline__ai-regenerate-btn" @click="handleAiPolish" :disabled="aiPolishing">↻ 重新生成</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="profile-edit-inline__ai-result-actions">
|
||||
<button class="profile-edit-inline__ai-replace-btn" @click="handleReplaceWithAi">+ 替换为此内容</button>
|
||||
<button class="profile-edit-inline__ai-regenerate-btn" @click="handleAiPolish" :disabled="aiPolishing">↻ 重新生成</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 底部操作按钮 -->
|
||||
<div class="profile-edit-inline__footer mt16">
|
||||
<button class="profile-edit-inline__save-btn" @click.stop="handleSave">保存</button>
|
||||
<button class="profile-edit-inline__cancel-btn" @click.stop="handleCancel">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 全屏加载遮罩 -->
|
||||
<FullscreenLoading :visible="fullLoading" :text="fullLoadingText" title="Nova 正在帮您努力处理~" />
|
||||
<!-- AI润色步骤进度遮罩 -->
|
||||
<StepProgressOverlay
|
||||
v-if="showPolishProgress"
|
||||
:title="polishProgressTitle"
|
||||
:subtitle="polishProgressSubtitle"
|
||||
:steps="polishProgressSteps"
|
||||
:durations="polishProgressDurations"
|
||||
:done="polishProgressDone"
|
||||
@finished="handlePolishProgressFinished"
|
||||
@close="handlePolishProgressClose"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -112,6 +133,7 @@ import { ref, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { polishDiagnosisIssue } from '@/api/resume'
|
||||
import FullscreenLoading from '@/components/FullscreenLoading.vue'
|
||||
import StepProgressOverlay from '@/components/StepProgressOverlay.vue'
|
||||
|
||||
/** 描述段落结构 */
|
||||
interface DescriptionParagraph {
|
||||
@@ -185,25 +207,62 @@ async function handleAiPolish() {
|
||||
return
|
||||
}
|
||||
aiPolishing.value = true
|
||||
fullLoadingText.value = 'AI正在润色中……'
|
||||
fullLoading.value = true
|
||||
// 显示步骤进度遮罩
|
||||
showPolishProgress.value = true
|
||||
polishProgressDone.value = false
|
||||
try {
|
||||
const content = text.split('\n').filter(s => s.trim())
|
||||
const res = await polishDiagnosisIssue(content)
|
||||
if (res.code === 0 && res.data?.content) {
|
||||
aiPolishResult.value = res.data.content.join('\n')
|
||||
ElMessage.success('AI润色完成')
|
||||
pendingPolishResult.value = res.data.content.join('\n')
|
||||
polishProgressDone.value = true
|
||||
} else {
|
||||
showPolishProgress.value = false
|
||||
aiPolishing.value = false
|
||||
ElMessage.error(res.msg || '润色失败')
|
||||
}
|
||||
} catch {
|
||||
ElMessage.error('请求失败')
|
||||
} finally {
|
||||
showPolishProgress.value = false
|
||||
aiPolishing.value = false
|
||||
fullLoading.value = false
|
||||
ElMessage.error('请求失败')
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== AI润色步骤进度遮罩 ====================
|
||||
|
||||
/** 润色步骤进度遮罩是否显示 */
|
||||
const showPolishProgress = ref(false)
|
||||
/** 润色接口是否已完成 */
|
||||
const polishProgressDone = ref(false)
|
||||
/** 大标题 */
|
||||
const polishProgressTitle = 'Nova正在润色中...'
|
||||
/** 副标题 */
|
||||
const polishProgressSubtitle = '正在根据岗位要求润色简历,突出你的核心优势'
|
||||
/** 4个步骤名称 */
|
||||
const polishProgressSteps = ['提取核心关键词...', '寻找符合的语义...', '排版文字格式...', '最终生成中...']
|
||||
/** 每步时长1400毫秒 */
|
||||
const polishProgressDurations = [1400, 1400, 1400, 1400]
|
||||
/** 缓存润色结果 */
|
||||
const pendingPolishResult = ref('')
|
||||
|
||||
/** 润色进度走完后填充结果 */
|
||||
function handlePolishProgressFinished() {
|
||||
showPolishProgress.value = false
|
||||
aiPolishing.value = false
|
||||
if (pendingPolishResult.value) {
|
||||
aiPolishResult.value = pendingPolishResult.value
|
||||
ElMessage.success('AI润色完成')
|
||||
}
|
||||
pendingPolishResult.value = ''
|
||||
}
|
||||
|
||||
/** 关闭润色进度遮罩 */
|
||||
function handlePolishProgressClose() {
|
||||
showPolishProgress.value = false
|
||||
aiPolishing.value = false
|
||||
pendingPolishResult.value = ''
|
||||
}
|
||||
|
||||
/** 替换为AI润色内容 */
|
||||
function handleReplaceWithAi() {
|
||||
if (aiPolishResult.value) {
|
||||
|
||||
@@ -44,7 +44,24 @@
|
||||
class="fix-all-drawer__record"
|
||||
>
|
||||
<!-- 经历标识(经历类模块显示标题,summary不显示) -->
|
||||
<p v-if="record.recordLabel" class="fix-all-drawer__record-label">{{ record.recordLabel }}</p>
|
||||
<div v-if="record.recordLabel" class="fix-all-drawer__record-label dflex-start">
|
||||
<span class="mr10">{{ record.recordLabel }}</span>
|
||||
<!-- AI润色按钮 -->
|
||||
<div class="dib dflex-center w66 h24 lh24 border-ra4 color-f aliite-c bg-linear-1 cursor-po" @click="handleAiPolishRecord(record)">
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_589_1500)">
|
||||
<path d="M4.55306 2.724C4.85206 1.849 6.06106 1.8225 6.41556 2.6445L6.44556 2.7245L6.84906 3.9045C6.94154 4.17512 7.09097 4.42276 7.28728 4.63071C7.48359 4.83867 7.72222 5.00211 7.98706 5.11L8.09556 5.1505L9.27556 5.5535C10.1506 5.8525 10.1771 7.0615 9.35556 7.416L9.27556 7.446L8.09556 7.8495C7.82485 7.94191 7.57712 8.09131 7.36907 8.28763C7.16103 8.48394 6.99751 8.7226 6.88956 8.9875L6.84906 9.0955L6.44606 10.276C6.14706 11.151 4.93806 11.1775 4.58406 10.356L4.55306 10.276L4.15006 9.096C4.05765 8.82529 3.90825 8.57755 3.71193 8.36951C3.51562 8.16146 3.27696 7.99795 3.01206 7.89L2.90406 7.8495L1.72406 7.4465C0.848564 7.1475 0.822064 5.9385 1.64406 5.5845L1.72406 5.5535L2.90406 5.1505C3.17468 5.05803 3.42232 4.9086 3.63028 4.71229C3.83823 4.51597 4.00167 4.27735 4.10956 4.0125L4.15006 3.9045L4.55306 2.724ZM5.49956 3.047L5.09656 4.227C4.95576 4.63965 4.7267 5.01665 4.42533 5.33175C4.12397 5.64684 3.75754 5.89246 3.35156 6.0515L3.22656 6.097L2.04656 6.5L3.22656 6.903C3.63922 7.0438 4.01622 7.27287 4.33131 7.57423C4.64641 7.8756 4.89203 8.24203 5.05106 8.648L5.09656 8.773L5.49956 9.953L5.90256 8.773C6.04337 8.36035 6.27243 7.98335 6.5738 7.66825C6.87516 7.35316 7.24159 7.10754 7.64756 6.9485L7.77256 6.9035L8.95256 6.5L7.77256 6.097C7.35991 5.9562 6.98291 5.72713 6.66782 5.42577C6.35272 5.1244 6.1071 4.75797 5.94806 4.352L5.90306 4.227L5.49956 3.047ZM9.49956 1C9.5931 1 9.68477 1.02624 9.76414 1.07574C9.84351 1.12523 9.90741 1.196 9.94856 1.28L9.97256 1.3385L10.1476 1.8515L10.6611 2.0265C10.7548 2.05835 10.837 2.11731 10.8972 2.19591C10.9574 2.27451 10.9929 2.36921 10.9992 2.46801C11.0055 2.56681 10.9824 2.66527 10.9327 2.75089C10.883 2.83652 10.809 2.90547 10.7201 2.949L10.6611 2.973L10.1481 3.148L9.97306 3.6615C9.94116 3.75521 9.88216 3.83735 9.80353 3.8975C9.7249 3.95764 9.63018 3.9931 9.53138 3.99936C9.43259 4.00563 9.33415 3.98242 9.24856 3.93269C9.16296 3.88296 9.09405 3.80893 9.05056 3.72L9.02656 3.6615L8.85156 3.1485L8.33806 2.9735C8.24432 2.94165 8.16215 2.88269 8.10195 2.80409C8.04175 2.72549 8.00624 2.63079 7.99993 2.53199C7.99361 2.43319 8.01676 2.33473 8.06645 2.24911C8.11615 2.16348 8.19014 2.09453 8.27906 2.051L8.33806 2.027L8.85106 1.852L9.02606 1.3385C9.05978 1.23971 9.12357 1.15395 9.20848 1.09325C9.2934 1.03254 9.39518 0.999937 9.49956 1Z" fill="currentColor"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_589_1500">
|
||||
<rect width="12" height="12" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<span class="ml2 fw600">AI润色</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 原文编辑区 -->
|
||||
<div class="fix-all-drawer__card">
|
||||
@@ -120,6 +137,17 @@
|
||||
</Teleport>
|
||||
<!-- 全屏加载遮罩 -->
|
||||
<FullscreenLoading :visible="fullLoading" :text="fullLoadingText" title="Nova 正在帮您努力处理~" />
|
||||
<!-- AI润色步骤进度遮罩 -->
|
||||
<StepProgressOverlay
|
||||
v-if="showPolishProgress"
|
||||
:title="polishProgressTitle"
|
||||
:subtitle="polishProgressSubtitle"
|
||||
:steps="polishProgressSteps"
|
||||
:durations="polishProgressDurations"
|
||||
:done="polishProgressDone"
|
||||
@finished="handlePolishProgressFinished"
|
||||
@close="handlePolishProgressClose"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -127,6 +155,7 @@ import { ref, watch, nextTick } from 'vue'
|
||||
import type { DiagnosisIssue, DescriptionParagraph } from '@/api/resume'
|
||||
import { polishDiagnosisIssue, resolveDiagnosisIssue } from '@/api/resume'
|
||||
import FullscreenLoading from '@/components/FullscreenLoading.vue'
|
||||
import StepProgressOverlay from '@/components/StepProgressOverlay.vue'
|
||||
|
||||
// ==================== Props ====================
|
||||
|
||||
@@ -385,6 +414,79 @@ async function handleRegenerate(record: RecordState) {
|
||||
}
|
||||
}
|
||||
|
||||
/** AI润色按钮 — 调用润色接口,将结果直接替换到 polishText */
|
||||
async function handleAiPolishRecord(record: RecordState) {
|
||||
// 收集当前原文编辑框内容作为输入
|
||||
let content: string[]
|
||||
if (record.moduleType === 'summary') {
|
||||
content = [record.editText.trim()]
|
||||
} else {
|
||||
content = record.editText.split('\n').filter(line => line.trim() !== '')
|
||||
}
|
||||
|
||||
if (!content.length) {
|
||||
ElMessage.warning('原文内容为空,无法润色')
|
||||
return
|
||||
}
|
||||
|
||||
// 显示步骤进度遮罩
|
||||
showPolishProgress.value = true
|
||||
polishProgressDone.value = false
|
||||
pendingPolishRecord.value = record
|
||||
|
||||
try {
|
||||
const res = await polishDiagnosisIssue(content)
|
||||
if (res.code === 0 && res.data?.content) {
|
||||
// 缓存结果,等进度走完后填充
|
||||
pendingPolishResult.value = res.data.content.join('\n')
|
||||
polishProgressDone.value = true
|
||||
} else {
|
||||
showPolishProgress.value = false
|
||||
ElMessage.error(res.msg || '润色失败,请稍后重试')
|
||||
}
|
||||
} catch {
|
||||
showPolishProgress.value = false
|
||||
ElMessage.error('请求失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== AI润色步骤进度遮罩 ====================
|
||||
|
||||
/** 润色步骤进度遮罩是否显示 */
|
||||
const showPolishProgress = ref(false)
|
||||
/** 润色接口是否已完成 */
|
||||
const polishProgressDone = ref(false)
|
||||
/** 大标题 */
|
||||
const polishProgressTitle = 'Nova正在润色中...'
|
||||
/** 副标题 */
|
||||
const polishProgressSubtitle = '正在根据岗位要求润色简历,突出你的核心优势'
|
||||
/** 4个步骤名称 */
|
||||
const polishProgressSteps = ['提取核心关键词...', '寻找符合的语义...', '排版文字格式...', '最终生成中...']
|
||||
/** 每步时长1400毫秒 */
|
||||
const polishProgressDurations = [1400, 1400, 1400, 1400]
|
||||
/** 缓存当前润色的记录 */
|
||||
const pendingPolishRecord = ref<RecordState | null>(null)
|
||||
/** 缓存润色结果 */
|
||||
const pendingPolishResult = ref('')
|
||||
|
||||
/** 润色进度走完后填充结果 */
|
||||
function handlePolishProgressFinished() {
|
||||
showPolishProgress.value = false
|
||||
if (pendingPolishRecord.value && pendingPolishResult.value) {
|
||||
pendingPolishRecord.value.polishText = pendingPolishResult.value
|
||||
ElMessage.success('AI润色完成')
|
||||
}
|
||||
pendingPolishRecord.value = null
|
||||
pendingPolishResult.value = ''
|
||||
}
|
||||
|
||||
/** 关闭润色进度遮罩 */
|
||||
function handlePolishProgressClose() {
|
||||
showPolishProgress.value = false
|
||||
pendingPolishRecord.value = null
|
||||
pendingPolishResult.value = ''
|
||||
}
|
||||
|
||||
/** 一键使用AI润色结果 — 所有模块强制使用 AI 润色结果更新 */
|
||||
function handleUseAllAi() {
|
||||
const items: FixAllSubmitItem[] = []
|
||||
|
||||
@@ -10,16 +10,24 @@
|
||||
<!-- 主导航 -->
|
||||
<nav class="side-nav__menu">
|
||||
<a
|
||||
v-for="item in mainMenus"
|
||||
v-for="(item, index) in mainMenus"
|
||||
:key="item.name"
|
||||
href="javascript:void(0)"
|
||||
class="side-nav__item"
|
||||
:class="{ 'side-nav__item--active': isActive(item.name) }"
|
||||
@click="handleNav(item)"
|
||||
@mouseenter="hoverIndex = index"
|
||||
@mouseleave="hoverIndex = -1"
|
||||
>
|
||||
<!-- SVG图标,通过v-html渲染以支持currentColor继承颜色 -->
|
||||
<span class="side-nav__item-icon" v-html="item.iconImg"></span>
|
||||
<!-- SVG图标:hover/active 状态显示选中图标,否则显示默认图标 -->
|
||||
<span
|
||||
class="side-nav__item-icon"
|
||||
v-html="(isActive(item.name) || hoverIndex === index) && getActiveIcon(index) ? getActiveIcon(index) : item.iconImg"
|
||||
></span>
|
||||
<span class="side-nav__item-label">{{ item.label }}</span>
|
||||
<!-- 索引0的时候显示"全网"小标签 -->
|
||||
<span v-if="index === 0" class="side-nav__tag-quanwang mt2 ml8">全网</span>
|
||||
|
||||
<span v-if="item.badge" class="side-nav__badge">{{ item.badge }}</span>
|
||||
</a>
|
||||
</nav>
|
||||
@@ -27,13 +35,8 @@
|
||||
|
||||
<!-- 底部菜单 -->
|
||||
<div class="side-nav__footer">
|
||||
<!-- <div class="side-nav__item" v-for="item in footerMenus" :key="item.label" @click="item.action?.()">
|
||||
<span class="side-nav__item-label">{{ item.label }}</span>
|
||||
<span v-if="item.badge" class="side-nav__badge">{{ item.badge }}</span>
|
||||
</div> -->
|
||||
|
||||
<!-- 邀请会员卡片 -->
|
||||
<div class="side-nav__referral-card">
|
||||
<div class="side-nav__referral-card cursor-po" @click="showShareDialog = true">
|
||||
<!-- 顶部标题区域 -->
|
||||
<div class="side-nav__referral-title">邀请好友送 7 天会员</div>
|
||||
<div class="side-nav__referral-subtitle">好友加入后自动到账</div>
|
||||
@@ -53,7 +56,7 @@
|
||||
<!-- 分隔线 -->
|
||||
<div class="side-nav__referral-divider"></div>
|
||||
<!-- 去邀请按钮 -->
|
||||
<div class="side-nav__referral-action" @click="showShareDialog = true">去邀请</div>
|
||||
<div class="side-nav__referral-action">去邀请</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -61,14 +64,14 @@
|
||||
<div class="side-nav__user-info-wrapper" v-if="store.state.isAuthenticated && store.state.userInfo">
|
||||
<!-- 账户弹窗 -->
|
||||
<div v-if="showAccountPopup" class="side-nav__account-popup">
|
||||
<!-- 顶部渐变区域:会员信息 -->
|
||||
<div class="side-nav__account-popup-header">
|
||||
<!-- 顶部渐变区域:会员信息,根据会员类型显示不同渐变背景 -->
|
||||
<div class="side-nav__account-popup-header" :class="accountHeaderBgClass">
|
||||
<div class="side-nav__account-popup-header-row">
|
||||
<div class="side-nav__account-popup-header-left">
|
||||
<div class="side-nav__account-popup-member-type" :class="accountMemberColorClass">{{ memberTagText }}</div>
|
||||
<div v-if="memberExpireText" class="side-nav__account-popup-expire">{{ memberExpireText }}</div>
|
||||
</div>
|
||||
<div class="side-nav__account-popup-detail" @click="handleAccountDetail">详情></div>
|
||||
<div class="side-nav__account-popup-detail" @click="handleAccountDetail">{{ accountDetailBtnText }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 设置按钮 -->
|
||||
@@ -77,6 +80,10 @@
|
||||
<div class="side-nav__account-popup-item" @click="handleAccountLogout">退出登录</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- 用户信息卡片(点击弹出/关闭账户弹窗) -->
|
||||
<div class="side-nav__user-info" :class="{ 'side-nav__user-info--active': showAccountPopup }" @click.stop="showAccountPopup = !showAccountPopup">
|
||||
<div class="side-nav__user-left">
|
||||
@@ -255,6 +262,34 @@ import navShareIcon from '@/assets/images/nav/nav-share-icon.png'
|
||||
// 导师页图标(暂用 profile 图标占位,有设计稿后替换为专属图标)
|
||||
import navMentorIcon from '@/assets/images/nav/nav-profile-icon.png'
|
||||
|
||||
/**
|
||||
* 选中/hover 状态下的图标 SVG 数组
|
||||
* 按索引与 mainMenus 中的菜单项一一对应
|
||||
* 索引0 对应第一个菜单项,索引1 对应第二个,以此类推
|
||||
*/
|
||||
const activeIconSvgs: string[] = [
|
||||
// 索引0 — 职位(Jobs)
|
||||
'<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_268_1536)"><path d="M7.66664 2.16669C6.78388 2.16674 5.91411 2.37928 5.13081 2.78634C4.34751 3.1934 3.6737 3.78302 3.16631 4.50539C2.65891 5.22775 2.33285 6.06164 2.21567 6.93658C2.09849 7.81152 2.19362 8.70182 2.49305 9.53224C2.79247 10.3627 3.28738 11.1088 3.93596 11.7077C4.58454 12.3065 5.36773 12.7404 6.21936 12.9728C7.07099 13.2051 7.96603 13.229 8.82886 13.0426C9.6917 12.8561 10.497 12.4647 11.1766 11.9014L12.962 13.6867C13.0568 13.775 13.1821 13.8231 13.3117 13.8208C13.4412 13.8185 13.5648 13.766 13.6564 13.6744C13.748 13.5828 13.8005 13.4592 13.8028 13.3297C13.805 13.2002 13.757 13.0748 13.6686 12.98L11.8853 11.196C12.5567 10.3935 12.9853 9.41618 13.1208 8.37866C13.2562 7.34115 13.0929 6.28652 12.65 5.33856C12.2071 4.3906 11.503 3.58865 10.6203 3.02682C9.73759 2.465 8.71296 2.16661 7.66664 2.16669Z" fill="#52CAD1"/></g><defs><clipPath id="clip0_268_1536"><rect width="16" height="16" fill="white"/></clipPath></defs></svg>',
|
||||
// 索引1 — 第二个菜单项(待替换)
|
||||
'<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_268_1540)"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.49998 1.66667C9.49998 1.62246 9.48242 1.58007 9.45116 1.54882C9.41991 1.51756 9.37752 1.5 9.33331 1.5H4.66665C4.18042 1.5 3.7141 1.69315 3.37028 2.03697C3.02647 2.38079 2.83331 2.8471 2.83331 3.33333V12.6667C2.83331 13.1529 3.02647 13.6192 3.37028 13.963C3.7141 14.3068 4.18042 14.5 4.66665 14.5H11.3333C11.8195 14.5 12.2859 14.3068 12.6297 13.963C12.9735 13.6192 13.1666 13.1529 13.1666 12.6667V6.098C13.1666 6.0538 13.1491 6.0114 13.1178 5.98015C13.0866 5.94889 13.0442 5.93133 13 5.93133H9.99998C9.86737 5.93133 9.74019 5.87865 9.64643 5.78489C9.55266 5.69112 9.49998 5.56394 9.49998 5.43133V1.66667ZM9.99998 8.16667C10.1326 8.16667 10.2598 8.21935 10.3535 8.31311C10.4473 8.40688 10.5 8.53406 10.5 8.66667C10.5 8.79927 10.4473 8.92645 10.3535 9.02022C10.2598 9.11399 10.1326 9.16667 9.99998 9.16667H5.99998C5.86737 9.16667 5.74019 9.11399 5.64643 9.02022C5.55266 8.92645 5.49998 8.79927 5.49998 8.66667C5.49998 8.53406 5.55266 8.40688 5.64643 8.31311C5.74019 8.21935 5.86737 8.16667 5.99998 8.16667H9.99998ZM9.99998 10.8333C10.1326 10.8333 10.2598 10.886 10.3535 10.9798C10.4473 11.0735 10.5 11.2007 10.5 11.3333C10.5 11.4659 10.4473 11.5931 10.3535 11.6869C10.2598 11.7807 10.1326 11.8333 9.99998 11.8333H5.99998C5.86737 11.8333 5.74019 11.7807 5.64643 11.6869C5.55266 11.5931 5.49998 11.4659 5.49998 11.3333C5.49998 11.2007 5.55266 11.0735 5.64643 10.9798C5.74019 10.886 5.86737 10.8333 5.99998 10.8333H9.99998Z" fill="#52CAD1"/><path d="M10.5 1.88266C10.5 1.75999 10.6287 1.68199 10.724 1.75866C10.8049 1.82399 10.8767 1.89999 10.9393 1.98666L12.948 4.78466C12.9933 4.84866 12.944 4.93132 12.8653 4.93132H10.6667C10.6225 4.93132 10.5801 4.91377 10.5488 4.88251C10.5176 4.85125 10.5 4.80886 10.5 4.76466V1.88266Z" fill="#52CAD1"/></g><defs><clipPath id="clip0_268_1540"><rect width="16" height="16" fill="white"/></clipPath></defs></svg>',
|
||||
// 索引2 — 第三个菜单项(待替换)
|
||||
'<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_268_1537)"><path d="M13.8086 5.41868L13.6446 5.79601C13.619 5.85745 13.5758 5.90994 13.5204 5.94686C13.465 5.98378 13.3999 6.00348 13.3333 6.00348C13.2667 6.00348 13.2017 5.98378 13.1462 5.94686C13.0908 5.90994 13.0476 5.85745 13.022 5.79601L12.858 5.41868C12.5696 4.75116 12.0416 4.21596 11.378 3.91868L10.872 3.69268C10.8106 3.66444 10.7586 3.61919 10.7221 3.56229C10.6857 3.5054 10.6663 3.43925 10.6663 3.37168C10.6663 3.3041 10.6857 3.23795 10.7221 3.18106C10.7586 3.12416 10.8106 3.07891 10.872 3.05068L11.35 2.83801C12.0302 2.53226 12.5674 1.97726 12.8506 1.28734L13.0193 0.880009C13.0441 0.816911 13.0873 0.762741 13.1433 0.724559C13.1993 0.686377 13.2655 0.665955 13.3333 0.665955C13.4011 0.665955 13.4673 0.686377 13.5233 0.724559C13.5793 0.762741 13.6225 0.816911 13.6473 0.880009L13.816 1.28668C14.099 1.97673 14.6358 2.53196 15.316 2.83801L15.7946 3.05134C15.8558 3.07966 15.9077 3.1249 15.944 3.18172C15.9803 3.23855 15.9996 3.30457 15.9996 3.37201C15.9996 3.43944 15.9803 3.50547 15.944 3.56229C15.9077 3.61911 15.8558 3.66436 15.7946 3.69268L15.288 3.91801C14.6245 4.21559 14.0967 4.75103 13.8086 5.41868ZM13.3333 7.33334C13.7858 7.3337 14.2351 7.25728 14.662 7.10734C14.6651 7.1829 14.6666 7.25823 14.6666 7.33334C14.6666 8.74783 14.1047 10.1044 13.1045 11.1046C12.1044 12.1048 10.7478 12.6667 9.33331 12.6667V15C5.99998 13.6667 1.33331 11.6667 1.33331 7.33334C1.33331 5.91885 1.89522 4.5623 2.89541 3.56211C3.8956 2.56191 5.25216 2.00001 6.66665 2.00001H9.33331C9.40887 2.00001 9.4842 2.00156 9.55931 2.00468C9.34686 2.60796 9.28217 3.25339 9.37068 3.88684C9.45918 4.52028 9.69829 5.12327 10.068 5.64522C10.4376 6.16717 10.9271 6.59286 11.4952 6.88659C12.0634 7.18032 12.6937 7.33352 13.3333 7.33334Z" fill="#52CAD1"/></g><defs><clipPath id="clip0_268_1537"><rect width="16" height="16" fill="white"/></clipPath></defs></svg>',
|
||||
// 索引3 — 第四个菜单项(待替换)
|
||||
'<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_268_1539)"><path d="M13.88 2.97668C13.253 2.36774 12.4141 2.02596 11.54 2.02334H4.50002C4.06562 2.01717 3.6343 2.09718 3.23102 2.25875C2.82773 2.42032 2.46048 2.66025 2.1505 2.96464C1.84053 3.26904 1.59398 3.63187 1.42511 4.03216C1.25624 4.43244 1.16841 4.86223 1.16669 5.29668V10.7033C1.1684 11.1341 1.25528 11.5602 1.42233 11.9572C1.58937 12.3542 1.83328 12.7143 2.14002 13.0167C2.76361 13.6317 3.60419 13.9765 4.48002 13.9767H11.52C12.3959 13.9765 13.2364 13.6317 13.86 13.0167C14.1689 12.7159 14.4142 12.3561 14.5813 11.9587C14.7485 11.5614 14.8342 11.1345 14.8334 10.7033V5.29668C14.8362 4.86607 14.7534 4.43919 14.5898 4.0409C14.4261 3.6426 14.1848 3.28084 13.88 2.97668ZM7.77335 11.1433C7.64075 11.1433 7.51357 11.0907 7.4198 10.9969C7.32603 10.9031 7.27335 10.776 7.27335 10.6433C7.27312 10.4413 7.23295 10.2412 7.15515 10.0548C7.07735 9.86827 6.96346 9.699 6.82002 9.55667C6.52064 9.27977 6.12783 9.12596 5.72002 9.12596C5.31221 9.12596 4.9194 9.27977 4.62002 9.55667C4.47599 9.69855 4.3617 9.86774 4.28386 10.0543C4.20602 10.2409 4.16618 10.4412 4.16669 10.6433C4.16669 10.776 4.11401 10.9031 4.02024 10.9969C3.92647 11.0907 3.7993 11.1433 3.66669 11.1433C3.53408 11.1433 3.4069 11.0907 3.31313 10.9969C3.21937 10.9031 3.16669 10.776 3.16669 10.6433C3.16616 10.3089 3.23187 9.97762 3.36002 9.66868C3.48817 9.35973 3.67623 9.07923 3.91335 8.84334C4.14167 8.60543 4.41317 8.41313 4.71335 8.27668C4.44349 8.11088 4.22081 7.87847 4.0667 7.60178C3.91259 7.32508 3.83223 7.01339 3.83335 6.69668C3.83335 6.2016 4.03002 5.72681 4.38009 5.37674C4.73016 5.02667 5.20495 4.83001 5.70002 4.83001C6.19509 4.83001 6.66989 5.02667 7.01995 5.37674C7.37002 5.72681 7.56669 6.2016 7.56669 6.69668C7.57063 7.01088 7.49433 7.3209 7.345 7.59738C7.19568 7.87387 6.97827 8.10767 6.71335 8.27668C7.01802 8.40334 7.29669 8.58668 7.53335 8.81668C8.00738 9.29639 8.2753 9.94228 8.28002 10.6167C8.2847 10.6853 8.27496 10.7542 8.25142 10.8189C8.22789 10.8836 8.19107 10.9426 8.14335 10.9922C8.09563 11.0418 8.03806 11.0809 7.97434 11.1069C7.91062 11.133 7.84215 11.1454 7.77335 11.1433ZM12.1267 10.5567H9.73335C9.60075 10.5567 9.47357 10.504 9.3798 10.4102C9.28603 10.3165 9.23335 10.1893 9.23335 10.0567C9.23335 9.92407 9.28603 9.79689 9.3798 9.70312C9.47357 9.60935 9.60075 9.55667 9.73335 9.55667H12.1267C12.2593 9.55667 12.3865 9.60935 12.4802 9.70312C12.574 9.79689 12.6267 9.92407 12.6267 10.0567C12.6267 10.1893 12.574 10.3165 12.4802 10.4102C12.3865 10.504 12.2593 10.5567 12.1267 10.5567ZM9.23335 7.99668C9.23335 7.86407 9.28603 7.73689 9.3798 7.64312C9.47357 7.54935 9.60075 7.49668 9.73335 7.49668H10.76C10.8926 7.49668 11.0198 7.54935 11.1136 7.64312C11.2073 7.73689 11.26 7.86407 11.26 7.99668C11.26 8.12928 11.2073 8.25646 11.1136 8.35023C11.0198 8.444 10.8926 8.49668 10.76 8.49668H9.73335C9.66745 8.49757 9.60202 8.48525 9.54096 8.46044C9.47989 8.43563 9.42441 8.39884 9.3778 8.35223C9.33119 8.30562 9.2944 8.25014 9.26959 8.18907C9.24478 8.12801 9.23246 8.06258 9.23335 7.99668ZM12.1267 6.44334H9.73335C9.60075 6.44334 9.47357 6.39066 9.3798 6.2969C9.28603 6.20313 9.23335 6.07595 9.23335 5.94334C9.23335 5.81073 9.28603 5.68356 9.3798 5.58979C9.47357 5.49602 9.60075 5.44334 9.73335 5.44334H12.1267C12.2593 5.44334 12.3865 5.49602 12.4802 5.58979C12.574 5.68356 12.6267 5.81073 12.6267 5.94334C12.6267 6.07595 12.574 6.20313 12.4802 6.2969C12.3865 6.39066 12.2593 6.44334 12.1267 6.44334Z" fill="#52CAD1"/><path d="M5.72 7.59002C5.83381 7.59002 5.94651 7.56761 6.05166 7.52405C6.15681 7.4805 6.25235 7.41666 6.33283 7.33618C6.4133 7.2557 6.47714 7.16016 6.52069 7.05501C6.56425 6.94987 6.58667 6.83717 6.58667 6.72336C6.58667 6.60954 6.56425 6.49685 6.52069 6.3917C6.47714 6.28655 6.4133 6.19101 6.33283 6.11053C6.25235 6.03005 6.15681 5.96621 6.05166 5.92266C5.94651 5.87911 5.83381 5.85669 5.72 5.85669C5.49014 5.85669 5.2697 5.948 5.10717 6.11053C4.94464 6.27306 4.85333 6.4935 4.85333 6.72336C4.85333 6.95321 4.94464 7.17365 5.10717 7.33618C5.2697 7.49871 5.49014 7.59002 5.72 7.59002Z" fill="#52CAD1"/></g><defs><clipPath id="clip0_268_1539"><rect width="16" height="16" fill="white"/></clipPath></defs></svg>',
|
||||
// 索引4 — 第五个菜单项(待替换)
|
||||
'<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_268_1538)"><path d="M6.07134 3.63198C6.47001 2.46531 8.08201 2.42998 8.55468 3.52598L8.59468 3.63265L9.13268 5.20598C9.25597 5.5668 9.45521 5.89699 9.71696 6.17426C9.97871 6.45154 10.2969 6.66945 10.65 6.81331L10.7947 6.86731L12.368 7.40465C13.5347 7.80331 13.57 9.41531 12.4747 9.88798L12.368 9.92798L10.7947 10.466C10.4337 10.5892 10.1034 10.7884 9.82602 11.0502C9.54863 11.3119 9.33061 11.6301 9.18668 11.9833L9.13268 12.1273L8.59534 13.7013C8.19668 14.868 6.58468 14.9033 6.11268 13.808L6.07134 13.7013L5.53401 12.128C5.4108 11.767 5.21159 11.4367 4.94984 11.1593C4.68808 10.8819 4.36987 10.6639 4.01668 10.52L3.87268 10.466L2.29934 9.92865C1.13201 9.52998 1.09668 7.91798 2.19268 7.44598L2.29934 7.40465L3.87268 6.86731C4.2335 6.74402 4.56368 6.54478 4.84096 6.28303C5.11823 6.02128 5.33615 5.70311 5.48001 5.34998L5.53401 5.20598L6.07134 3.63198ZM12.6667 1.33331C12.7914 1.33331 12.9136 1.3683 13.0194 1.43429C13.1253 1.50029 13.2105 1.59465 13.2653 1.70665L13.2973 1.78465L13.5307 2.46865L14.2153 2.70198C14.3403 2.74444 14.4499 2.82306 14.5302 2.92786C14.6104 3.03266 14.6578 3.15893 14.6662 3.29066C14.6746 3.4224 14.6437 3.55367 14.5775 3.66784C14.5112 3.78201 14.4126 3.87394 14.294 3.93198L14.2153 3.96398L13.5313 4.19731L13.298 4.88198C13.2555 5.00693 13.1768 5.11645 13.072 5.19664C12.9671 5.27684 12.8408 5.32411 12.7091 5.33246C12.5774 5.34081 12.4461 5.30988 12.332 5.24357C12.2179 5.17726 12.126 5.07856 12.068 4.95998L12.036 4.88198L11.8027 4.19798L11.118 3.96465C10.993 3.92218 10.8835 3.84357 10.8032 3.73877C10.7229 3.63397 10.6756 3.5077 10.6672 3.37597C10.6587 3.24423 10.6896 3.11296 10.7559 2.99879C10.8221 2.88462 10.9208 2.79269 11.0393 2.73465L11.118 2.70265L11.802 2.46931L12.0353 1.78465C12.0803 1.65293 12.1653 1.53859 12.2786 1.45765C12.3918 1.37671 12.5275 1.33323 12.6667 1.33331Z" fill="#52CAD1"/></g><defs><clipPath id="clip0_268_1538"><rect width="16" height="16" fill="white"/></clipPath></defs></svg>',
|
||||
// 索引5 — 第六个菜单项(待替换)
|
||||
'<svg width="14" height="13" viewBox="0 0 14 13" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.66667 10.6667L1.13333 12.2C0.922223 12.4111 0.680446 12.4584 0.408001 12.342C0.135557 12.2256 -0.000443359 12.0171 1.08578e-06 11.7167V1.33333C1.08578e-06 0.966667 0.130668 0.652889 0.392001 0.392C0.653334 0.131111 0.967112 0.000444444 1.33333 0H12C12.3667 0 12.6807 0.130667 12.942 0.392C13.2033 0.653333 13.3338 0.967111 13.3333 1.33333V9.33333C13.3333 9.7 13.2029 10.014 12.942 10.2753C12.6811 10.5367 12.3671 10.6671 12 10.6667H2.66667ZM6.66667 8.66667C6.85556 8.66667 7.014 8.60267 7.142 8.47467C7.27 8.34667 7.33378 8.18845 7.33333 8C7.33289 7.81156 7.26889 7.65333 7.14133 7.52533C7.01378 7.39733 6.85556 7.33333 6.66667 7.33333C6.47778 7.33333 6.31956 7.39733 6.192 7.52533C6.06445 7.65333 6.00045 7.81156 6 8C5.99956 8.18845 6.06356 8.34689 6.192 8.47533C6.32045 8.60378 6.47867 8.66756 6.66667 8.66667ZM7.142 5.808C7.26956 5.68044 7.33333 5.52222 7.33333 5.33333V2.66667C7.33333 2.47778 7.26933 2.31956 7.14133 2.192C7.01333 2.06444 6.85511 2.00044 6.66667 2C6.47822 1.99956 6.32 2.06356 6.192 2.192C6.064 2.32044 6 2.47867 6 2.66667V5.33333C6 5.52222 6.064 5.68067 6.192 5.80867C6.32 5.93667 6.47822 6.00044 6.66667 6C6.85511 5.99956 7.01356 5.93556 7.142 5.808Z" fill="#52CAD1"/></svg>',
|
||||
]
|
||||
|
||||
/**
|
||||
* 根据菜单索引获取选中状态图标
|
||||
* 当菜单处于 hover 或 active 状态时使用此图标替换默认图标
|
||||
*/
|
||||
function getActiveIcon(index: number): string {
|
||||
return activeIconSvgs[index] || ''
|
||||
}
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const store = useStore()
|
||||
@@ -352,6 +387,8 @@ const mainMenus = computed<MenuItem[]>(() => {
|
||||
const showShareDialog = ref(false)
|
||||
const showMessageDialog = ref(false)
|
||||
const showFeedbackDialog = ref(false)
|
||||
/** 当前hover的菜单索引,-1表示无hover */
|
||||
const hoverIndex = ref(-1)
|
||||
/** 会员权限拦截弹窗 */
|
||||
const showMemberAccessDialog = ref(false)
|
||||
/** 会员购买弹窗 */
|
||||
@@ -595,6 +632,15 @@ const memberTagText = computed(() => {
|
||||
return '免费用户'
|
||||
})
|
||||
|
||||
/**
|
||||
* 账户弹窗右上角按钮文字:免费用户显示"开通会员",付费用户显示"详情>"
|
||||
*/
|
||||
const accountDetailBtnText = computed(() => {
|
||||
const status = store.state.memberStatus
|
||||
if (!status || !status.isMember) return '开通会员'
|
||||
return '详情>'
|
||||
})
|
||||
|
||||
/**
|
||||
* 会员标签样式 class
|
||||
*/
|
||||
@@ -623,6 +669,18 @@ const accountMemberColorClass = computed(() => {
|
||||
return 'side-nav__account-popup-member-type--free'
|
||||
})
|
||||
|
||||
/**
|
||||
* 账户弹窗顶部渐变背景 class
|
||||
* 正式会员:#EDF9FA → #FFF;试用会员:#FEF5E7 → #FFF;免费用户:#F1F2F4 → #FFF
|
||||
*/
|
||||
const accountHeaderBgClass = computed(() => {
|
||||
const status = store.state.memberStatus
|
||||
if (!status || !status.isMember) return 'side-nav__account-popup-header--free'
|
||||
if (status.memberType === 1) return 'side-nav__account-popup-header--formal'
|
||||
if (status.memberType === 2) return 'side-nav__account-popup-header--trial'
|
||||
return 'side-nav__account-popup-header--free'
|
||||
})
|
||||
|
||||
/**
|
||||
* 会员到期时间显示文字 — 使用项目时间工具 timestampToLocalDateTime
|
||||
*/
|
||||
@@ -636,9 +694,18 @@ const memberExpireText = computed(() => {
|
||||
})
|
||||
|
||||
/** 账户弹窗 — 点击"详情>"跳转会员页 */
|
||||
/** 账户弹窗 — 点击"详情>":正式会员打开设置弹窗并切换到会员tab,试用/免费用户打开会员购买弹窗 */
|
||||
function handleAccountDetail() {
|
||||
showAccountPopup.value = false
|
||||
showMemberDialog.value = true
|
||||
const status = store.state.memberStatus
|
||||
if (status && status.isMember && status.memberType === 1) {
|
||||
// 正式会员:打开设置弹窗,切换到会员页
|
||||
store.state.settingsTab = 'member'
|
||||
showSettingsDialog.value = true
|
||||
} else {
|
||||
// 试用会员 / 免费用户:打开会员购买弹窗
|
||||
showMemberDialog.value = true
|
||||
}
|
||||
}
|
||||
|
||||
/** 账户弹窗 — 点击"设置"打开设置弹窗 */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<SideNav />
|
||||
<div class="job-detail__content">
|
||||
<!-- 页面标题 + Tab 切换 -->
|
||||
<JobPageHeader :activeTab="''" />
|
||||
<JobPageHeader :activeTab="cachedTab" />
|
||||
<!-- 主内容卡片 -->
|
||||
<div class="job-detail__main-card">
|
||||
<!-- 返回按钮 -->
|
||||
@@ -218,6 +218,9 @@ const fullLoadingText = ref('')
|
||||
/** 当前岗位 ID,从路由参数中获取 */
|
||||
const jobId = route.params.id as string
|
||||
|
||||
/** 从 store 缓存中读取 Jobs 页面上次切换的 Tab,保持切换记录 */
|
||||
const cachedTab = computed(() => store.state.jobListCache?.tab || 'recommend')
|
||||
|
||||
// ==================== 工具函数 ====================
|
||||
|
||||
/** 工作类型映射:使用全局统一的 formatEmploymentType */
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
<!-- 提示条主体 -->
|
||||
<div class="jobs-page__ai-tip">
|
||||
<!-- 尖角:用::before(边框色)和::after(白色)双伪元素实现,通过动态left定位 -->
|
||||
<span class="jobs-page__ai-tip-arrow" :style="{ left: aiTipArrowLeft + 'px' }"></span>
|
||||
<span v-if="false" class="jobs-page__ai-tip-arrow" :style="{ left: aiTipArrowLeft + 'px' }"></span>
|
||||
<div class="jobs-page__ai-tip-content">
|
||||
<img class="jobs-page__ai-tip-logo" src="@/assets/images/logo-offerpai-2.png" alt="Nova" />
|
||||
<span class="jobs-page__ai-tip-text">
|
||||
@@ -143,8 +143,8 @@
|
||||
</button>
|
||||
<!-- 收藏页关闭按钮 -->
|
||||
<button v-if="activeTab === 'collected'" class="jobs-page__job-remove" aria-label="取消收藏" @click.stop="removeFavoriteFromList(job, index)">
|
||||
<svg viewBox="0 0 16 16" fill="none" class="jobs-page__remove-svg">
|
||||
<path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<svg viewBox="0 0 16 16" fill="#E85635" class="jobs-page__favorite-svg">
|
||||
<path d="M8 13.7l-1.1-1C3.6 9.8 1.5 7.9 1.5 5.7 1.5 3.9 2.9 2.5 4.7 2.5c1 0 2 .5 2.6 1.2h1.4c.6-.7 1.6-1.2 2.6-1.2 1.8 0 3.2 1.4 3.2 3.2 0 2.2-2.1 4.1-5.4 6.9L8 13.7z" stroke="#E85635" stroke-width="1"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -183,9 +183,16 @@
|
||||
<!-- 公司logo + 公司名 -->
|
||||
<div class="jobs-page__company-row">
|
||||
<div class="jobs-page__company-logo">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||
<path d="M0 0h24v24H0z" fill="none" />
|
||||
<path fill="currentColor" d="M18 15h-2v2h2m0-6h-2v2h2m2 6h-8v-2h2v-2h-2v-2h2v-2h-2V9h8M10 7H8V5h2m0 6H8V9h2m0 6H8v-2h2m0 6H8v-2h2M6 7H4V5h2m0 6H4V9h2m0 6H4v-2h2m0 6H4v-2h2m6-10V3H2v18h20V7z" />
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="24" height="24" rx="4" fill="#EDF9FA"/>
|
||||
<g clip-path="url(#clip0_294_2925)">
|
||||
<path d="M5.99998 16.6667H6.66665V8.24001C6.66667 8.0301 6.73274 7.82552 6.8555 7.65526C6.97827 7.48499 7.15149 7.35767 7.35065 7.29134L12.684 5.51401C12.8343 5.46395 12.9943 5.45031 13.1509 5.47423C13.3076 5.49815 13.4562 5.55893 13.5848 5.65157C13.7133 5.74421 13.8179 5.86606 13.8901 6.00708C13.9623 6.1481 14 6.30425 14 6.46268V16.6667H14.6666V10.66C14.6667 10.6107 14.6776 10.562 14.6987 10.5175C14.7199 10.4729 14.7506 10.4336 14.7887 10.4024C14.8268 10.3711 14.8714 10.3487 14.9193 10.3368C14.9671 10.3249 15.017 10.3237 15.0653 10.3333L16.5293 10.6267C16.7559 10.672 16.9599 10.7944 17.1064 10.973C17.253 11.1517 17.3332 11.3756 17.3333 11.6067V16.6667H18C18.1768 16.6667 18.3464 16.7369 18.4714 16.8619C18.5964 16.987 18.6666 17.1565 18.6666 17.3333C18.6666 17.5102 18.5964 17.6797 18.4714 17.8047C18.3464 17.9298 18.1768 18 18 18H5.99998C5.82317 18 5.6536 17.9298 5.52858 17.8047C5.40355 17.6797 5.33331 17.5102 5.33331 17.3333C5.33331 17.1565 5.40355 16.987 5.52858 16.8619C5.6536 16.7369 5.82317 16.6667 5.99998 16.6667Z" fill="#52CAD1"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_294_2925">
|
||||
<rect width="16" height="16" fill="white" transform="translate(4 4)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
<span class="jobs-page__company-name">{{ job.companyShortName || job.companyName }}</span>
|
||||
@@ -425,7 +432,7 @@ const selectorDisplayStyle: Record<string, string> = {
|
||||
|
||||
/** 选择器触发按钮 hover 时的样式 */
|
||||
const selectorHoverStyle: Record<string, string> = {
|
||||
background: '#12C7BE',
|
||||
background: '#52CAD1',
|
||||
color: '#fff',
|
||||
}
|
||||
|
||||
|
||||
@@ -15,23 +15,36 @@
|
||||
<div class="mentor-page__subtitle dib">自有合作导师,真实在职身份,全部实名认证</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mentor-page__search-wrap">
|
||||
<svg class="mentor-page__search-icon" viewBox="0 0 16 16" fill="none">
|
||||
<circle cx="7" cy="7" r="5.5" stroke="currentColor" stroke-width="1.2"/>
|
||||
<path d="M11 11L14 14" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<input
|
||||
v-model="keyword"
|
||||
class="mentor-page__search-input"
|
||||
placeholder="搜索导师、公司、服务类型..."
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
<!-- 清空按钮:有输入内容时鼠标 hover 搜索框才显示 -->
|
||||
<span
|
||||
v-if="keyword.length > 0"
|
||||
class="mentor-page__search-clear"
|
||||
@click="handleClearKeyword"
|
||||
>✕</span>
|
||||
<div class="dflex-end aliite-c flex-warp">
|
||||
<!-- 推荐搜索标签 -->
|
||||
<div class="mentor-page__quick-tags">
|
||||
<span class="mentor-page__quick-label">推荐搜索:</span>
|
||||
<span
|
||||
v-for="tag in quickSearchTags"
|
||||
:key="tag"
|
||||
class="mentor-page__quick-tag"
|
||||
@click="handleQuickSearch(tag)"
|
||||
>{{ tag }}</span>
|
||||
</div>
|
||||
<!-- 搜索 -->
|
||||
<div class="mentor-page__search-wrap">
|
||||
<svg class="mentor-page__search-icon" viewBox="0 0 16 16" fill="none">
|
||||
<circle cx="7" cy="7" r="5.5" stroke="currentColor" stroke-width="1.2"/>
|
||||
<path d="M11 11L14 14" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<input
|
||||
v-model="keyword"
|
||||
class="mentor-page__search-input"
|
||||
placeholder="搜索导师、公司、服务类型..."
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
<!-- 清空按钮:有输入内容时鼠标 hover 搜索框才显示 -->
|
||||
<span
|
||||
v-if="keyword.length > 0"
|
||||
class="mentor-page__search-clear"
|
||||
@click="handleClearKeyword"
|
||||
>✕</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -52,6 +65,7 @@
|
||||
v-for="mentor in mentorList"
|
||||
:key="mentor.id"
|
||||
class="mentor-page__card"
|
||||
@click="goToDetail(mentor)"
|
||||
>
|
||||
<!-- 左侧:头像 + 基本信息 -->
|
||||
<div class="mentor-page__card-left">
|
||||
@@ -100,7 +114,7 @@
|
||||
<!-- 查看详情按钮 -->
|
||||
<button
|
||||
class="mentor-page__detail-btn"
|
||||
@click="goToDetail(mentor)"
|
||||
|
||||
><span>查看详情</span> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.51612 4.07575C7.38279 3.94242 7.31879 3.78686 7.32412 3.60908C7.32945 3.43131 7.39901 3.27575 7.53278 3.14241C7.66612 3.02019 7.82167 2.95619 7.99946 2.95041C8.17723 2.94464 8.33278 3.00864 8.46612 3.14241L12.8661 7.54241C12.9328 7.60908 12.9801 7.6813 13.0081 7.75908C13.0361 7.83686 13.0497 7.92019 13.0488 8.00908C13.0479 8.09797 13.0339 8.18131 13.0068 8.25908C12.9797 8.33686 12.9326 8.40908 12.8654 8.47575L8.46545 12.8757C8.34323 12.998 8.19034 13.0591 8.00679 13.0591C7.82323 13.0591 7.66501 12.998 7.53212 12.8757C7.39879 12.7424 7.33212 12.584 7.33212 12.4004C7.33212 12.2169 7.39879 12.0586 7.53212 11.9257L10.7828 8.67575H3.33279C3.1439 8.67575 2.98546 8.61175 2.85745 8.48375C2.72945 8.35575 2.66567 8.19753 2.66612 8.00908C2.66656 7.82064 2.73056 7.6622 2.85812 7.53375C2.98568 7.40531 3.1439 7.34153 3.33279 7.34242L10.7828 7.34242L7.51612 4.07575Z" fill="currentColor"/>
|
||||
</svg>
|
||||
@@ -243,6 +257,18 @@ const noMore = ref(false)
|
||||
/** 搜索关键词 */
|
||||
const keyword = ref('')
|
||||
|
||||
/** 推荐搜索标签列表 */
|
||||
const quickSearchTags = ['字节跳动', '百度', '广告投放', 'AI产品', '大模型']
|
||||
|
||||
/**
|
||||
* 点击推荐搜索标签 — 直接用标签文字搜索,不显示在输入框中
|
||||
*/
|
||||
function handleQuickSearch(tag: string) {
|
||||
keyword.value = tag
|
||||
store.commit('SET_MENTOR_LIST_CACHE', null)
|
||||
resetAndLoad()
|
||||
}
|
||||
|
||||
/** 列表容器 ref */
|
||||
const listRef = ref<HTMLElement | null>(null)
|
||||
|
||||
|
||||
@@ -101,42 +101,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== 二维码弹窗(遮罩 + 居中卡片) ==================== -->
|
||||
<teleport to="body">
|
||||
<div v-if="showQrDialog" class="mentor-qr-overlay" @click.self="closeQrDialog">
|
||||
<div class="mentor-qr-card">
|
||||
<!-- 头部:标题 + 关闭按钮 -->
|
||||
<div class="mentor-qr-card__header">
|
||||
<div class="mentor-qr-card__title-wrap">
|
||||
<div class="mentor-qr-card__title">扫码进入小程序预约导师咨询</div>
|
||||
<div class="mentor-qr-card__desc">查看导师价格、过往评价,并完成预约</div>
|
||||
</div>
|
||||
<div class="mentor-qr-card__close" @click="closeQrDialog">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M18 6L6 18M6 6l12 12" stroke="#6A7282" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 二维码展示区域 -->
|
||||
<div class="mentor-qr-card__qr-area">
|
||||
<div v-if="qrLoading" class="mentor-qr-card__loading">
|
||||
<div class="mentor-qr-card__spinner"></div>
|
||||
</div>
|
||||
<img
|
||||
v-else-if="qrCodeBase64"
|
||||
:src="qrCodeBase64"
|
||||
alt="小程序二维码"
|
||||
class="mentor-qr-card__qr-img"
|
||||
/>
|
||||
<div v-else class="mentor-qr-card__placeholder">二维码加载失败</div>
|
||||
</div>
|
||||
<!-- 底部提示 -->
|
||||
<div class="mentor-qr-card__footer">
|
||||
<div class="mentor-qr-card__footer-text">小程序名称:见识星球 | 大学生求职神器</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
<!-- 二维码弹窗组件 -->
|
||||
<MentorQrCodeDialog
|
||||
v-model:visible="showQrDialog"
|
||||
:mentorId="mentorId"
|
||||
source="api"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -145,9 +115,10 @@ import { ref, computed, onMounted } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import SideNav from '@/components/SideNav.vue'
|
||||
import MentorAsidePanel from '@/components/MentorAsidePanel.vue'
|
||||
import { fetchMentorFullInfo, fetchMentorTalks, fetchMentorQrCode } from '@/api/mentor'
|
||||
import { fetchMentorFullInfo, fetchMentorTalks } from '@/api/mentor'
|
||||
import type { MentorFullInfo, MentorTalk } from '@/api/mentor'
|
||||
import { toOssUrl } from '@/utils/image'
|
||||
import MentorQrCodeDialog from '@/components/MentorQrCodeDialog.vue'
|
||||
|
||||
// ==================== 路由相关 ====================
|
||||
|
||||
@@ -259,36 +230,10 @@ onMounted(() => {
|
||||
/** 弹窗是否显示 */
|
||||
const showQrDialog = ref(false)
|
||||
|
||||
/** 二维码图片 base64 */
|
||||
const qrCodeBase64 = ref('')
|
||||
|
||||
/** 二维码加载状态 */
|
||||
const qrLoading = ref(false)
|
||||
|
||||
/**
|
||||
* 打开二维码弹窗,调接口获取当前导师的小程序二维码
|
||||
* 打开二维码弹窗
|
||||
*/
|
||||
async function openQrDialog() {
|
||||
function openQrDialog() {
|
||||
showQrDialog.value = true
|
||||
qrLoading.value = true
|
||||
qrCodeBase64.value = ''
|
||||
try {
|
||||
const res: any = await fetchMentorQrCode(mentorId)
|
||||
const base64 = res?.data ?? res
|
||||
if (typeof base64 === 'string' && base64.length > 0) {
|
||||
qrCodeBase64.value = base64.startsWith('data:image')
|
||||
? base64
|
||||
: `data:image/png;base64,${base64}`
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[二维码] 获取失败', e)
|
||||
} finally {
|
||||
qrLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 关闭弹窗 */
|
||||
function closeQrDialog() {
|
||||
showQrDialog.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
|
||||
<!-- 页面标题 -->
|
||||
<div class="profile-page__header">
|
||||
<h2 class="profile-page__title">个人资料 <span class="profile-page__title-tip">ⓘ</span></h2>
|
||||
<p class="profile-page__subtitle">
|
||||
设定个人资料以匹配岗位需求,包括教育背景、实习经历等,大部分信息可以从简历中自动获取,也可以手动修改。
|
||||
</p>
|
||||
<h2 class="profile-page__title">个人资料</h2>
|
||||
</div>
|
||||
|
||||
<!-- 主体区域:左侧详情 + 右侧入口 -->
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<span v-if="item.isDefault" class="resume-page__default-tag">默认</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="resume-page__td">{{ item.targetJob }}</td>
|
||||
<td class="resume-page__td resume-page__td--ellipsis">{{ item.targetJob }}</td>
|
||||
<td class="resume-page__td">{{ item.updatedAt }}</td>
|
||||
<!-- 操作按钮列 -->
|
||||
<td class="resume-page__td resume-page__td--action">
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<div class="resume-detail__fixed-top">
|
||||
|
||||
<!-- 简历评分区域 -->
|
||||
<div class="resume-detail__score-bar" :class="scoreBarClass">
|
||||
<div class="resume-detail__score-bar border-F0F0F0-bottom-1 border-ra0" :class="scoreBarClass">
|
||||
<div class="resume-detail__score-left">
|
||||
<!-- 星星+底座组合 -->
|
||||
<div class="resume-detail__star-wrapper">
|
||||
@@ -177,7 +177,7 @@
|
||||
<div class="resume-detail__card-header color-6">
|
||||
<div class="dflex-start aliite-c">
|
||||
<h3 class="resume-detail__user-name">{{ resumeMain.name || '未填写姓名' }}</h3>
|
||||
<span v-if="resumeMain.city" class="ml10 dflex-start aliite-c fs13">
|
||||
<span v-if="resumeMain.city&&resumeMain.city!='null'" class="ml10 dflex-start aliite-c fs13">
|
||||
<svg viewBox="0 0 16 16" fill="none" class="resume-detail__contact-icon">
|
||||
<circle cx="8" cy="6.5" r="2.5" stroke="currentColor" stroke-width="1.2"/>
|
||||
<path d="M8 14s-5-4-5-7.5a5 5 0 0110 0C13 10 8 14 8 14z" stroke="currentColor" stroke-width="1.2"/>
|
||||
@@ -193,7 +193,7 @@
|
||||
</div>
|
||||
<div class="resume-detail__contact">
|
||||
<!-- 邮箱 -->
|
||||
<span v-if="resumeMain.email" class="resume-detail__contact-item">
|
||||
<span v-if="resumeMain.email&&resumeMain.email!='null'" class="resume-detail__contact-item">
|
||||
<svg viewBox="0 0 16 16" fill="none" class="resume-detail__contact-icon">
|
||||
<rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.2"/>
|
||||
<path d="M2 5.5l6 4 6-4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
|
||||
@@ -201,7 +201,7 @@
|
||||
<span>{{ resumeMain.email }}</span>
|
||||
</span>
|
||||
<!-- 手机号 -->
|
||||
<span v-if="resumeMain.mobileNumber" class="resume-detail__contact-item">
|
||||
<span v-if="resumeMain.mobileNumber&&resumeMain.mobileNumber!='null'" class="resume-detail__contact-item">
|
||||
<svg viewBox="0 0 16 16" fill="none" class="resume-detail__contact-icon">
|
||||
<path d="M4 2h2.5l1.5 3-1.5 1.5a8 8 0 003 3L11 8l3 1.5V12a2 2 0 01-2 2C6.5 14 2 9.5 2 4a2 2 0 012-2z" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
@@ -209,12 +209,12 @@
|
||||
</span>
|
||||
|
||||
<!-- 微信号 -->
|
||||
<span v-if="resumeMain.wechatNumber" class="resume-detail__contact-item">
|
||||
<span v-if="resumeMain.wechatNumber&&resumeMain.wechatNumber!='null'" class="resume-detail__contact-item">
|
||||
<el-icon class="fs14 color-9"><ChatLineRound /></el-icon>
|
||||
<span>{{ resumeMain.wechatNumber }}</span>
|
||||
</span>
|
||||
<!-- 作品集链接 -->
|
||||
<span v-if="resumeMain.portfolioUrl" class="resume-detail__contact-item dib">
|
||||
<span v-if="resumeMain.portfolioUrl&&resumeMain.portfolioUrl!='null'" class="resume-detail__contact-item dib">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class=" mr6" width="0.15rem" height="0.15rem" viewBox="0 0 16 16">
|
||||
<path d="M0 0h16v16H0z" fill="none" />
|
||||
<path fill="none" stroke="currentColor" d="M14.5 8A6.5 6.5 0 0 1 8 14.5M14.5 8A6.5 6.5 0 0 0 8 1.5M14.5 8c0 1.657-2.91 3-6.5 3S1.5 9.657 1.5 8m13 0c0-1.657-2.91-3-6.5-3S1.5 6.343 1.5 8M8 14.5A6.5 6.5 0 0 1 1.5 8M8 14.5c1.657 0 3-2.91 3-6.5S9.657 1.5 8 1.5m0 13c-1.657 0-3-2.91-3-6.5s1.343-6.5 3-6.5M1.5 8A6.5 6.5 0 0 1 8 1.5" />
|
||||
@@ -237,8 +237,10 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl32"></div>
|
||||
|
||||
<!-- 个人概述 -->
|
||||
<div ref="resumeSectionSummaryRef" class="resume-detail__card" :class="{ 'resume-detail__card-hover': editModule !== 'summary' || !showEditDrawer }">
|
||||
<div ref="resumeSectionSummaryRef" class="resume-detail__card mt14" :class="{ 'resume-detail__card-hover': editModule !== 'summary' || !showEditDrawer }">
|
||||
<!-- 展示模式 -->
|
||||
<template v-if="editModule !== 'summary' || !showEditDrawer">
|
||||
<div class="resume-detail__section-header pl0">
|
||||
@@ -270,6 +272,8 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl32"></div>
|
||||
|
||||
<!-- 教育背景经历 -->
|
||||
<div ref="resumeSectionEducationRef" class="resume-detail__card">
|
||||
<div class="resume-detail__section-header">
|
||||
@@ -328,6 +332,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl32"></div>
|
||||
|
||||
<!-- 工作经历 -->
|
||||
<div ref="resumeSectionWorkRef" class="resume-detail__card">
|
||||
<div class="resume-detail__section-header">
|
||||
@@ -367,6 +373,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl32"></div>
|
||||
|
||||
<!-- 实习经历 -->
|
||||
<div ref="resumeSectionInternshipRef" class="resume-detail__card">
|
||||
<div class="resume-detail__section-header">
|
||||
@@ -405,6 +413,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl32"></div>
|
||||
|
||||
<!-- 项目经历 -->
|
||||
<div ref="resumeSectionProjectRef" class="resume-detail__card">
|
||||
<div class="resume-detail__section-header">
|
||||
@@ -443,6 +453,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl32"></div>
|
||||
|
||||
<!-- 竞赛经历 -->
|
||||
<div ref="resumeSectionCompetitionRef" class="resume-detail__card">
|
||||
<div class="resume-detail__section-header">
|
||||
@@ -481,6 +493,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl32"></div>
|
||||
|
||||
<!-- 技能 -->
|
||||
<div ref="resumeSectionSkillsRef" class="resume-detail__card" :class="{ 'resume-detail__card-hover': editModule !== 'skills' || !showEditDrawer }">
|
||||
<template v-if="editModule !== 'skills' || !showEditDrawer">
|
||||
@@ -510,6 +524,8 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="h1 border-EDF9FA-bottom-2 mrl32"></div>
|
||||
|
||||
<!-- 证书 -->
|
||||
<div ref="resumeSectionCertificateRef" class="resume-detail__card" :class="{ 'resume-detail__card-hover': editModule !== 'certificate' || !showEditDrawer }">
|
||||
<template v-if="editModule !== 'certificate' || !showEditDrawer">
|
||||
@@ -713,7 +729,7 @@ const gradeLabel = computed(() => {
|
||||
/** 星星边框/线条颜色 */
|
||||
const starStrokeColor = computed(() => {
|
||||
if (!hasDiagnosis.value) return '#858585'
|
||||
if (diagnosisReport.value.grade === 'A') return '#12C7BE'
|
||||
if (diagnosisReport.value.grade === 'A') return '#52CAD1'
|
||||
return '#FF8D0B'
|
||||
})
|
||||
|
||||
|
||||