职位列表去投递定时提醒去AI助手弹窗
This commit is contained in:
@@ -633,6 +633,31 @@
|
|||||||
z-index: 10;
|
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 {
|
&__job-match--high &__match-score {
|
||||||
color: $accent-hover;
|
color: $accent-hover;
|
||||||
@@ -642,6 +667,74 @@
|
|||||||
color: $accent;
|
color: $accent;
|
||||||
font-weight: 500;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 不感兴趣反馈弹窗 ====================
|
// ==================== 不感兴趣反馈弹窗 ====================
|
||||||
|
|||||||
@@ -379,7 +379,8 @@ const handleEditTarget = () => {
|
|||||||
watch(() => props.modelValue, (val) => {
|
watch(() => props.modelValue, (val) => {
|
||||||
if (val && store.state.isAuthenticated) {
|
if (val && store.state.isAuthenticated) {
|
||||||
store.dispatch('loadCommonData')
|
store.dispatch('loadCommonData')
|
||||||
store.dispatch('loadJobIntention')
|
// 暂时注释掉loadJobIntention,现在设置弹窗里去掉了求职意向的设置功能,设置求职意向会导致Jobs.vue里岗位列表刷新
|
||||||
|
// store.dispatch('loadJobIntention')
|
||||||
loadMemberStatus()
|
loadMemberStatus()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
+2
-2
@@ -96,8 +96,8 @@ const TIME_EVENT_CACHE_KEY = 'local_time_event_cache'
|
|||||||
* │ 事件名称ID │ 事件描述说明 │
|
* │ 事件名称ID │ 事件描述说明 │
|
||||||
* ├──────────────────────────────────────────────────────────────┤
|
* ├──────────────────────────────────────────────────────────────┤
|
||||||
* │ member_status_query │ 会员状态查询时间记录 │
|
* │ member_status_query │ 会员状态查询时间记录 │
|
||||||
* │ │ │
|
* │ ai_agent_remind_first │ 第一次AI助手跳转提醒时间记录 │
|
||||||
* │ │ │
|
* │ ai_agent_remind_second │ 第二次AI助手跳转提醒时间记录 │
|
||||||
* │ │ │
|
* │ │ │
|
||||||
* └──────────────────────────────────────────────────────────────┘
|
* └──────────────────────────────────────────────────────────────┘
|
||||||
*/
|
*/
|
||||||
|
|||||||
+1
-1
@@ -1120,7 +1120,7 @@ async function handleConfirmResumeStep(msg: AgentChatMessage) {
|
|||||||
msg.extra = JSON.stringify(extraData)
|
msg.extra = JSON.stringify(extraData)
|
||||||
|
|
||||||
//测试一下通过userId和jobId拿到storageKey,再用storageKey拿到简历文件并下载到浏览器测试一下(测试成功,先注释)
|
//测试一下通过userId和jobId拿到storageKey,再用storageKey拿到简历文件并下载到浏览器测试一下(测试成功,先注释)
|
||||||
const testRecord = getCachedResumeRecord(userId, jobId)
|
// const testRecord = getCachedResumeRecord(userId, jobId)
|
||||||
// if (testRecord) {
|
// if (testRecord) {
|
||||||
// const testFile = await getCachedResumeFile(testRecord.storageKey, '测试缓存简历')
|
// const testFile = await getCachedResumeFile(testRecord.storageKey, '测试缓存简历')
|
||||||
// if (testFile) {
|
// if (testFile) {
|
||||||
|
|||||||
+116
-7
@@ -112,7 +112,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 职位列表 -->
|
<!-- 职位列表 -->
|
||||||
<div ref="jobListRef" v-loading="loading" class="jobs-page__list pr5" :style="restoring ? { visibility: 'hidden' } : {}" @scroll="onListScroll">
|
<div ref="jobListRef" class="jobs-page__list pr5" :style="restoring ? { visibility: 'hidden' } : {}" @scroll="onListScroll">
|
||||||
<div
|
<div
|
||||||
v-for="(job, index) in jobList"
|
v-for="(job, index) in jobList"
|
||||||
:key="index"
|
:key="index"
|
||||||
@@ -196,7 +196,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
问助手
|
问助手
|
||||||
</button>
|
</button>
|
||||||
<button @click="handleReport(job.sourceUrl)" class="jobs-page__job-apply-btn" :class="{ 'jobs-page__job-apply-btn--active': job.applied }">
|
<button @click.stop="handleReport(job.sourceUrl)" class="jobs-page__job-apply-btn" :class="{ 'jobs-page__job-apply-btn--active': job.applied }">
|
||||||
去投递
|
去投递
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -208,7 +208,7 @@
|
|||||||
class="jobs-page__job-popup-item"
|
class="jobs-page__job-popup-item"
|
||||||
v-for="action in popupActions"
|
v-for="action in popupActions"
|
||||||
:key="action"
|
:key="action"
|
||||||
@click="handlePopupAction(action, job)"
|
@click.stop="handlePopupAction(action, job)"
|
||||||
>{{ action }}</div>
|
>{{ action }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -244,10 +244,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 首次加载中提示 -->
|
||||||
|
<div v-if="loading" class="jobs-page__loading-box">
|
||||||
|
<div class="jobs-page__loading-spinner"></div>
|
||||||
|
<span>加载中...</span>
|
||||||
|
</div>
|
||||||
<!-- 暂无数据提示 -->
|
<!-- 暂无数据提示 -->
|
||||||
<div v-if="!loading && jobList.length === 0" class="jobs-page__empty">暂无数据</div>
|
<div v-if="!loading && jobList.length === 0" class="jobs-page__empty">暂无数据</div>
|
||||||
<!-- 加载更多提示 -->
|
<!-- 加载更多提示 -->
|
||||||
<div v-if="loadingMore" class="jobs-page__loading-more">加载中...</div>
|
<div v-if="loadingMore" class="jobs-page__loading-box">
|
||||||
|
<div class="jobs-page__loading-spinner"></div>
|
||||||
|
<span>加载中...</span>
|
||||||
|
</div>
|
||||||
<div v-else-if="noMore && jobList.length > 0" class="jobs-page__loading-more">没有更多符合的职位了</div>
|
<div v-else-if="noMore && jobList.length > 0" class="jobs-page__loading-more">没有更多符合的职位了</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -259,6 +267,16 @@
|
|||||||
<!-- 职位问题反馈弹窗 -->
|
<!-- 职位问题反馈弹窗 -->
|
||||||
<JobFeedbackDialog ref="feedbackDialogRef" v-model="showFeedbackDialog" :job-id="feedbackJobId" />
|
<JobFeedbackDialog ref="feedbackDialogRef" v-model="showFeedbackDialog" :job-id="feedbackJobId" />
|
||||||
|
|
||||||
|
<!-- AI助手投递提醒弹窗 -->
|
||||||
|
<div v-if="showAgentRemindDialog" class="jobs-page__agent-remind-overlay" @click.self="closeAgentRemind">
|
||||||
|
<div class="jobs-page__agent-remind-dialog">
|
||||||
|
<p class="jobs-page__agent-remind-text">去AI助手投递岗位效果更好哦!</p>
|
||||||
|
<div class="jobs-page__agent-remind-actions">
|
||||||
|
<button class="jobs-page__agent-remind-btn jobs-page__agent-remind-btn--secondary" @click="directApply">直接投</button>
|
||||||
|
<button class="jobs-page__agent-remind-btn jobs-page__agent-remind-btn--primary" @click="goToAgent">去AI助手</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -279,6 +297,7 @@ import RegionSelector from '@/components/tools/RegionSelector.vue'
|
|||||||
|
|
||||||
import { fetchJobList, fetchFavoriteList, toggleJobFavorite, removeJobFavorite, fetchFavoriteCount, fetchApplyList, fetchApplyCount, removeJobFromList } from '@/api/jobs'
|
import { fetchJobList, fetchFavoriteList, toggleJobFavorite, removeJobFavorite, fetchFavoriteCount, fetchApplyList, fetchApplyCount, removeJobFromList } from '@/api/jobs'
|
||||||
import type { JobListItem, JobListParams, FavoriteListParams, ApplyListParams, ApplyCountData } from '@/api/jobs'
|
import type { JobListItem, JobListParams, FavoriteListParams, ApplyListParams, ApplyCountData } from '@/api/jobs'
|
||||||
|
import { getTimeEvent, setTimeEvent, timestampToLocalDateTime } from '@/utils/time'
|
||||||
|
|
||||||
|
|
||||||
// 2. 注意:这里的字符串不需要再手动转义双引号了
|
// 2. 注意:这里的字符串不需要再手动转义双引号了
|
||||||
@@ -517,11 +536,101 @@ function closeDropdownOnClickOutside(e: MouseEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 跳转到原链接 */
|
/** 跳转到原链接 — 带 AI 助手提醒弹窗频率控制 */
|
||||||
function handleReport( url:string ) {
|
/**
|
||||||
if (url) {
|
* 提醒弹窗频率逻辑说明:
|
||||||
|
* 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')
|
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 () => {
|
onMounted(async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user