From dde72be9dee48bc66ad7543afab3f3f468e483c1 Mon Sep 17 00:00:00 2001 From: xuxin <15279969124@163.com> Date: Mon, 1 Jun 2026 15:46:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=81=8C=E4=BD=8D=E5=88=97=E8=A1=A8=E5=8E=BB?= =?UTF-8?q?=E6=8A=95=E9=80=92=E5=AE=9A=E6=97=B6=E6=8F=90=E9=86=92=E5=8E=BB?= =?UTF-8?q?AI=E5=8A=A9=E6=89=8B=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/styles/pages/jobs.scss | 93 ++++++++++++++++++++++ src/components/SettingsDialog.vue | 3 +- src/utils/time.ts | 4 +- src/views/Agent.vue | 2 +- src/views/Jobs.vue | 123 ++++++++++++++++++++++++++++-- 5 files changed, 214 insertions(+), 11 deletions(-) diff --git a/src/assets/styles/pages/jobs.scss b/src/assets/styles/pages/jobs.scss index 254003e..b941f11 100644 --- a/src/assets/styles/pages/jobs.scss +++ b/src/assets/styles/pages/jobs.scss @@ -633,6 +633,31 @@ z-index: 10; } + // 列表底部加载盒子 + &__loading-box { + display: flex; + align-items: center; + justify-content: center; + gap: 0.08rem; + padding: 0.24rem 0; + font-size: 0.13rem; + color: $text-light; + } + + // 加载旋转动画 + &__loading-spinner { + width: 0.18rem; + height: 0.18rem; + border: 2px solid rgba(0, 0, 0, 0.1); + border-top-color: $accent; + border-radius: 50%; + animation: jobs-spin 0.6s linear infinite; + } + + @keyframes jobs-spin { + to { transform: rotate(360deg); } + } + // 高匹配度特殊样式 &__job-match--high &__match-score { color: $accent-hover; @@ -642,6 +667,74 @@ color: $accent; font-weight: 500; } + + // ==================== AI助手投递提醒弹窗 ==================== + + // 遮罩层 + &__agent-remind-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: $overlay-bg; + display: flex; + align-items: center; + justify-content: center; + z-index: 2000; + } + + // 弹窗主体 + &__agent-remind-dialog { + background: $bg-white; + border-radius: 0.12rem; + padding: 0.32rem 0.36rem 0.24rem; + min-width: 3.2rem; + text-align: center; + } + + // 提示文字 + &__agent-remind-text { + font-size: 0.15rem; + color: $text-dark; + font-weight: 500; + margin-bottom: 0.28rem; + line-height: 1.5; + } + + // 按钮区域 + &__agent-remind-actions { + display: flex; + gap: 0.16rem; + } + + // 按钮通用 + &__agent-remind-btn { + flex: 1; + padding: 0.1rem 0; + border-radius: 0.08rem; + font-size: 0.14rem; + font-weight: 500; + cursor: pointer; + border: none; + transition: opacity 0.2s; + + &:hover { + opacity: 0.85; + } + + // 灰色按钮 — 直接投 + &--secondary { + background: $bg-main; + color: $text-middle; + } + + // 主题色按钮 — 去AI助手 + &--primary { + background: $btn-dark; + color: $bg-white; + } + } } // ==================== 不感兴趣反馈弹窗 ==================== diff --git a/src/components/SettingsDialog.vue b/src/components/SettingsDialog.vue index 1b0081e..a06d6b8 100644 --- a/src/components/SettingsDialog.vue +++ b/src/components/SettingsDialog.vue @@ -379,7 +379,8 @@ const handleEditTarget = () => { watch(() => props.modelValue, (val) => { if (val && store.state.isAuthenticated) { store.dispatch('loadCommonData') - store.dispatch('loadJobIntention') + // 暂时注释掉loadJobIntention,现在设置弹窗里去掉了求职意向的设置功能,设置求职意向会导致Jobs.vue里岗位列表刷新 + // store.dispatch('loadJobIntention') loadMemberStatus() } }) diff --git a/src/utils/time.ts b/src/utils/time.ts index 24d828e..9c0058e 100644 --- a/src/utils/time.ts +++ b/src/utils/time.ts @@ -96,8 +96,8 @@ const TIME_EVENT_CACHE_KEY = 'local_time_event_cache' * │ 事件名称ID │ 事件描述说明 │ * ├──────────────────────────────────────────────────────────────┤ * │ member_status_query │ 会员状态查询时间记录 │ - * │ │ │ - * │ │ │ + * │ ai_agent_remind_first │ 第一次AI助手跳转提醒时间记录 │ + * │ ai_agent_remind_second │ 第二次AI助手跳转提醒时间记录 │ * │ │ │ * └──────────────────────────────────────────────────────────────┘ */ diff --git a/src/views/Agent.vue b/src/views/Agent.vue index 21e3ca2..e587c5d 100644 --- a/src/views/Agent.vue +++ b/src/views/Agent.vue @@ -1120,7 +1120,7 @@ async function handleConfirmResumeStep(msg: AgentChatMessage) { msg.extra = JSON.stringify(extraData) //测试一下通过userId和jobId拿到storageKey,再用storageKey拿到简历文件并下载到浏览器测试一下(测试成功,先注释) - const testRecord = getCachedResumeRecord(userId, jobId) + // const testRecord = getCachedResumeRecord(userId, jobId) // if (testRecord) { // const testFile = await getCachedResumeFile(testRecord.storageKey, '测试缓存简历') // if (testFile) { diff --git a/src/views/Jobs.vue b/src/views/Jobs.vue index f771958..f1b90b4 100644 --- a/src/views/Jobs.vue +++ b/src/views/Jobs.vue @@ -112,7 +112,7 @@ -
+
问助手 -
@@ -208,7 +208,7 @@ class="jobs-page__job-popup-item" v-for="action in popupActions" :key="action" - @click="handlePopupAction(action, job)" + @click.stop="handlePopupAction(action, job)" >{{ action }}
@@ -244,10 +244,18 @@ + +
+
+ 加载中... +
暂无数据
-
加载中...
+
+
+ 加载中... +
没有更多符合的职位了
@@ -259,6 +267,16 @@ + +
+
+

去AI助手投递岗位效果更好哦!

+
+ + +
+
+
@@ -279,6 +297,7 @@ import RegionSelector from '@/components/tools/RegionSelector.vue' import { fetchJobList, fetchFavoriteList, toggleJobFavorite, removeJobFavorite, fetchFavoriteCount, fetchApplyList, fetchApplyCount, removeJobFromList } from '@/api/jobs' import type { JobListItem, JobListParams, FavoriteListParams, ApplyListParams, ApplyCountData } from '@/api/jobs' +import { getTimeEvent, setTimeEvent, timestampToLocalDateTime } from '@/utils/time' // 2. 注意:这里的字符串不需要再手动转义双引号了 @@ -517,11 +536,101 @@ function closeDropdownOnClickOutside(e: MouseEvent) { } } -/** 跳转到原链接 */ -function handleReport( url:string ) { - if (url) { +/** 跳转到原链接 — 带 AI 助手提醒弹窗频率控制 */ +/** + * 提醒弹窗频率逻辑说明: + * 1. 未登录用户:直接跳转外部链接,不弹窗 + * 2. 已登录用户首次点击(无 ai_agent_remind_first 缓存):弹窗提醒,记录第一次提醒时间 + * 3. 有第一次记录但无第二次记录: + * - 距第一次记录 ≤ 1小时:直接跳转,不弹窗 + * - 距第一次记录 > 1小时:弹窗提醒,记录第二次提醒时间 + * 4. 有第二次记录: + * - 距第二次记录 ≤ 7天:直接跳转,不弹窗 + * - 距第二次记录 > 7天:弹窗提醒,更新第二次记录时间为当前时间 + */ +function handleReport(url: string) { + // 暂存当前要跳转的链接 + pendingApplyUrl.value = url + + // 未登录直接跳转 + if (!isAuthenticated.value) { window.open(url, '_blank') + return } + + const userId = store.state.userInfo?.id + if (!userId) { + window.open(url, '_blank') + return + } + + const now = Date.now() + const firstTime = getTimeEvent('ai_agent_remind_first', userId) + const secondTime = getTimeEvent('ai_agent_remind_second', userId) + + if (!firstTime) { + // 情况1:从未弹过 → 弹窗,记录第一次时间 + setTimeEvent('ai_agent_remind_first', userId, timestampToLocalDateTime(now)) + showAgentRemindDialog.value = true + return + } + + if (!secondTime) { + // 情况2:有第一次记录,无第二次记录 → 检查是否超过1小时 + const firstTimestamp = new Date(firstTime).getTime() + const diffHours = (now - firstTimestamp) / (1000 * 60 * 60) + if (diffHours <= 1) { + // 1小时内不弹窗,直接跳转 + window.open(url, '_blank') + } else { + // 超过1小时 → 弹窗,记录第二次时间 + setTimeEvent('ai_agent_remind_second', userId, timestampToLocalDateTime(now)) + showAgentRemindDialog.value = true + } + return + } + + // 情况3:有第二次记录 → 检查是否超过7天 + const secondTimestamp = new Date(secondTime).getTime() + const diffDays = (now - secondTimestamp) / (1000 * 60 * 60 * 24) + if (diffDays <= 7) { + // 7天内不弹窗,直接跳转 + window.open(url, '_blank') + } else { + // 超过7天 → 弹窗,更新第二次记录时间 + setTimeEvent('ai_agent_remind_second', userId, timestampToLocalDateTime(now)) + showAgentRemindDialog.value = true + } +} + +// ==================== AI助手提醒弹窗状态 ==================== + +/** AI助手提醒弹窗是否显示 */ +const showAgentRemindDialog = ref(false) + +/** 暂存待跳转的外部链接 */ +const pendingApplyUrl = ref('') + +/** 关闭AI助手提醒弹窗 */ +function closeAgentRemind() { + showAgentRemindDialog.value = false + pendingApplyUrl.value = '' +} + +/** 点击"直接投"按钮 — 关闭弹窗并跳转外部链接 */ +function directApply() { + showAgentRemindDialog.value = false + if (pendingApplyUrl.value) { + window.open(pendingApplyUrl.value, '_blank') + } + pendingApplyUrl.value = '' +} + +/** 点击"去AI助手"按钮 — 关闭弹窗并跳转到 Agent 页面 */ +function goToAgent() { + showAgentRemindDialog.value = false + pendingApplyUrl.value = '' + router.push('/agent') } onMounted(async () => {