Files
offerpai_web/src/components/AgentChatJobList.vue
T
2026-06-24 19:03:41 +08:00

148 lines
5.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<!-- 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>
</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>
</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>
</div>
<!-- 空状态 -->
<div class="color-9" v-if="displayJobs.length === 0">
暂无相关职位推荐
</div>
<!-- 底部按钮区域 -->
<div v-if="displayJobs.length > 0" class="agent-chat-job-list__footer">
<!-- 换一批按钮 -->
<button class="agent-chat-job-list__refresh-btn" :disabled="refreshing" @click="handleRefresh">
{{ refreshing ? '加载中...' : '换一批' }}
</button>
<!-- 全部添加按钮 -->
<button class="agent-chat-job-list__add-all-btn" @click="handleAddAll">全部添加</button>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import type { AgentRecommendJob } from '@/api/agent'
/** 组件 Props */
const props = defineProps<{
/** 推荐说明文字 */
summary: string
/** 当前展示的岗位列表数据(父组件已随机抽取10个) */
jobs: AgentRecommendJob[]
/** 正在请求中的岗位 ID 列表 */
loadingJobIds?: number[]
/** 是否正在换一批加载中 */
refreshing?: boolean
}>()
/** 事件 */
const emit = defineEmits<{
/** 点击查看全部岗位(打开右侧面板) */
(e: 'viewAll'): void
/** 点击岗位查看详情 */
(e: 'clickJob', job: AgentRecommendJob): void
/** 添加单个岗位到待投递 */
(e: 'add', job: AgentRecommendJob): void
/** 全部添加 */
(e: 'addAll'): void
/** 换一批 */
(e: 'refresh'): void
/** 不再推荐 */
(e: 'dismiss', job: AgentRecommendJob): void
}>()
/** 只显示前3个岗位 */
const displayJobs = computed(() => props.jobs.slice(0, 3))
/** 点击岗位 — 通知父组件打开岗位预览 */
function handleClickJob(job: AgentRecommendJob) {
emit('clickJob', job)
}
/** 添加岗位到待投递 */
function handleAdd(job: AgentRecommendJob) {
emit('add', job)
}
/** 全部添加 */
function handleAddAll() {
emit('addAll')
}
/** 换一批 */
function handleRefresh() {
emit('refresh')
}
/** 不再推荐 */
function handleDismiss(job: AgentRecommendJob) {
emit('dismiss', job)
}
</script>
<style scoped lang="scss">
@use '../assets/styles/components/agent-chat-job-list';
</style>