重构页面模块,新增求职辅助工具、招聘信息浏览与交互、个人信息管理和智能岗位推荐功能,优化用户体验和界面布局。
This commit is contained in:
@@ -1,24 +1,428 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<h2>数据分析页</h2>
|
||||
<p>后续可以在这里放图表、统计数据等可视化内容。</p>
|
||||
<h2>智能岗位推荐模块</h2>
|
||||
<p class="intro">
|
||||
基于毕业生的专业背景、技能画像与求职偏好,实时生成匹配度更高的岗位推荐列表。
|
||||
</p>
|
||||
|
||||
<section class="card">
|
||||
<div class="card-header">
|
||||
<h3>1. 精准推荐列表</h3>
|
||||
<div class="filters">
|
||||
<label>
|
||||
过滤专业:
|
||||
<select v-model="filter.major">
|
||||
<option value="">全部</option>
|
||||
<option value="计算机">计算机相关</option>
|
||||
<option value="机械">机械相关</option>
|
||||
<option value="电子">电子信息</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
最低匹配度:
|
||||
<input
|
||||
v-model.number="filter.minScore"
|
||||
type="number"
|
||||
min="0"
|
||||
max="100"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="job-list">
|
||||
<div
|
||||
v-for="job in filteredJobs"
|
||||
:key="job.id"
|
||||
class="job-item"
|
||||
:class="{ active: selectedJob && selectedJob.id === job.id }"
|
||||
@click="selectJob(job)"
|
||||
>
|
||||
<div class="job-main">
|
||||
<div class="job-title-row">
|
||||
<span class="job-title">{{ job.title }}</span>
|
||||
<span class="job-company">{{ job.company }}</span>
|
||||
</div>
|
||||
<div class="job-tags">
|
||||
<span class="tag">{{ job.majorTag }}</span>
|
||||
<span class="tag" v-for="skill in job.skills" :key="skill">
|
||||
{{ skill }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="job-side">
|
||||
<div class="match-score">
|
||||
匹配度
|
||||
<span class="score-value">{{ job.matchScore }}%</span>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="small-btn"
|
||||
@click.stop="toggleCompare(job)"
|
||||
>
|
||||
{{ isInCompare(job.id) ? '取消对比' : '加入对比' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="!filteredJobs.length" class="empty-text">
|
||||
当前条件下没有推荐岗位,可以调低匹配度或清空筛选。
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="two-columns">
|
||||
<!-- 推荐理由解析 -->
|
||||
<section class="card">
|
||||
<h3>2. 推荐理由解析</h3>
|
||||
<div v-if="selectedJob" class="reason-panel">
|
||||
<h4>{{ selectedJob.title }} · {{ selectedJob.company }}</h4>
|
||||
<ul>
|
||||
<li>专业契合度:{{ selectedJob.reasons.major }}</li>
|
||||
<li>技能匹配度:{{ selectedJob.reasons.skills }}</li>
|
||||
<li>求职偏好匹配:{{ selectedJob.reasons.preference }}</li>
|
||||
</ul>
|
||||
<p class="tip">
|
||||
建议:可根据推荐理由优化个人信息填写,例如补充缺失技能或调整求职偏好。
|
||||
</p>
|
||||
</div>
|
||||
<p v-else class="empty-text">点击左侧推荐列表中的岗位查看推荐理由。</p>
|
||||
</section>
|
||||
|
||||
<!-- 岗位对比功能 -->
|
||||
<section class="card">
|
||||
<h3>3. 岗位对比功能</h3>
|
||||
<div v-if="compareList.length" class="compare-table-wrapper">
|
||||
<table class="compare-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>岗位</th>
|
||||
<th>公司</th>
|
||||
<th>匹配度</th>
|
||||
<th>城市</th>
|
||||
<th>薪资</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="job in compareList" :key="job.id">
|
||||
<td>{{ job.title }}</td>
|
||||
<td>{{ job.company }}</td>
|
||||
<td>{{ job.matchScore }}%</td>
|
||||
<td>{{ job.city }}</td>
|
||||
<td>{{ job.salary }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="tip">
|
||||
你可以通过匹配度、城市和薪资综合对比,选择更适合当前阶段发展的岗位。
|
||||
</p>
|
||||
</div>
|
||||
<p v-else class="empty-text">
|
||||
在上方推荐列表中点击“加入对比”,即可在此处查看横向对比结果。
|
||||
</p>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
|
||||
type Reason = {
|
||||
major: string
|
||||
skills: string
|
||||
preference: string
|
||||
}
|
||||
|
||||
type Job = {
|
||||
id: number
|
||||
title: string
|
||||
company: string
|
||||
majorTag: string
|
||||
skills: string[]
|
||||
matchScore: number
|
||||
city: string
|
||||
salary: string
|
||||
reasons: Reason
|
||||
}
|
||||
|
||||
const jobs = ref<Job[]>([
|
||||
{
|
||||
id: 1,
|
||||
title: '后端开发工程师',
|
||||
company: '某互联网科技公司',
|
||||
majorTag: '计算机',
|
||||
skills: ['Java', 'SpringBoot', 'MySQL'],
|
||||
matchScore: 92,
|
||||
city: '北京',
|
||||
salary: '18-25K',
|
||||
reasons: {
|
||||
major: '与你的“计算机科学与技术”专业高度匹配',
|
||||
skills: 'Java / 数据库 等技能与岗位需求高度重合',
|
||||
preference: '工作城市、行业方向均与求职偏好一致'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '测试开发工程师',
|
||||
company: '智能硬件企业',
|
||||
majorTag: '电子',
|
||||
skills: ['Python', '自动化测试', '嵌入式'],
|
||||
matchScore: 85,
|
||||
city: '深圳',
|
||||
salary: '15-20K',
|
||||
reasons: {
|
||||
major: '与“电子信息工程”专业方向契合',
|
||||
skills: '具备脚本开发与自动化测试经验',
|
||||
preference: '符合你设置的南方沿海城市与制造业方向'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '机械设计工程师',
|
||||
company: '装备制造龙头企业',
|
||||
majorTag: '机械',
|
||||
skills: ['SolidWorks', '机械设计', '有限元分析'],
|
||||
matchScore: 78,
|
||||
city: '上海',
|
||||
salary: '12-18K',
|
||||
reasons: {
|
||||
major: '你的机械相关课程背景与岗位需求较为匹配',
|
||||
skills: '具备 3D 建模与结构分析能力',
|
||||
preference: '行业方向匹配“高端制造业”'
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
const selectedJob = ref<Job | null>(null)
|
||||
const compareIds = ref<number[]>([])
|
||||
|
||||
const filter = reactive({
|
||||
major: '',
|
||||
minScore: 70
|
||||
})
|
||||
|
||||
const filteredJobs = computed(() =>
|
||||
jobs.value.filter((job) => {
|
||||
const passMajor = filter.major ? job.majorTag.includes(filter.major) : true
|
||||
const passScore = job.matchScore >= (filter.minScore || 0)
|
||||
return passMajor && passScore
|
||||
})
|
||||
)
|
||||
|
||||
const compareList = computed(() =>
|
||||
jobs.value.filter((job) => compareIds.value.includes(job.id))
|
||||
)
|
||||
|
||||
function selectJob(job: Job) {
|
||||
selectedJob.value = job
|
||||
}
|
||||
|
||||
function isInCompare(id: number) {
|
||||
return compareIds.value.includes(id)
|
||||
}
|
||||
|
||||
function toggleCompare(job: Job) {
|
||||
if (isInCompare(job.id)) {
|
||||
compareIds.value = compareIds.value.filter((v) => v !== job.id)
|
||||
} else if (compareIds.value.length < 3) {
|
||||
compareIds.value.push(job.id)
|
||||
} else {
|
||||
alert('最多同时对比 3 个岗位(示例限制)')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page h2 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
font-size: 18px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.page p {
|
||||
margin: 0;
|
||||
.intro {
|
||||
margin: 0 0 16px;
|
||||
color: #4b5563;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #f9fafb;
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.filters label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
select,
|
||||
input[type='number'] {
|
||||
border-radius: 8px;
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 4px 6px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.job-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.job-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 12px;
|
||||
border-radius: 10px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.job-item.active {
|
||||
border-color: #2563eb;
|
||||
box-shadow: 0 0 0 1px rgba(37, 99, 235, 0.3);
|
||||
}
|
||||
|
||||
.job-main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.job-title-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.job-title {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.job-company {
|
||||
font-size: 13px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.job-tags {
|
||||
margin-top: 4px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font-size: 11px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 999px;
|
||||
background: #e0f2fe;
|
||||
color: #0369a1;
|
||||
}
|
||||
|
||||
.job-side {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 6px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.match-score {
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.score-value {
|
||||
margin-left: 4px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
.small-btn {
|
||||
border-radius: 999px;
|
||||
border: none;
|
||||
background: #2563eb;
|
||||
color: #ffffff;
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.small-btn:hover {
|
||||
background: #1d4ed8;
|
||||
}
|
||||
|
||||
.two-columns {
|
||||
margin-top: 16px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.reason-panel h4 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.reason-panel ul {
|
||||
padding-left: 18px;
|
||||
margin: 0 0 8px;
|
||||
font-size: 13px;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
margin-top: 6px;
|
||||
font-size: 13px;
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.compare-table-wrapper {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.compare-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.compare-table th,
|
||||
.compare-table td {
|
||||
padding: 6px 8px;
|
||||
border: 1px solid #e5e7eb;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.compare-table th {
|
||||
background: #eff6ff;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,24 +1,422 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<h2>欢迎来到首页</h2>
|
||||
<p>这里可以展示项目的总体介绍、关键指标和快捷入口。</p>
|
||||
<h2>个人信息管理模块</h2>
|
||||
<p class="intro">
|
||||
面向理工科毕业生的核心个人画像入口,为后续岗位推荐和匹配提供基础数据支持。
|
||||
</p>
|
||||
|
||||
<div class="grid">
|
||||
<!-- 基础信息录入 -->
|
||||
<section class="card">
|
||||
<h3>1. 基础信息录入</h3>
|
||||
<form class="form" @submit.prevent="saveBasicInfo">
|
||||
<div class="form-row">
|
||||
<label>专业</label>
|
||||
<input v-model="basic.major" placeholder="例如:计算机科学与技术" />
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>学历</label>
|
||||
<select v-model="basic.education">
|
||||
<option value="">请选择</option>
|
||||
<option value="本科">本科</option>
|
||||
<option value="硕士">硕士</option>
|
||||
<option value="博士">博士</option>
|
||||
<option value="专科">专科</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>毕业院校</label>
|
||||
<input v-model="basic.university" placeholder="请输入学校名称" />
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>技能证书</label>
|
||||
<input
|
||||
v-model="basic.certificates"
|
||||
placeholder="如:CET-6、计算机二级、软考等"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>项目经历</label>
|
||||
<textarea
|
||||
v-model="basic.projects"
|
||||
rows="3"
|
||||
placeholder="简单描述你做过的项目或科研经历"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit">保存基础信息</button>
|
||||
<span class="hint">仅本地演示,后续可接入后端存储。</span>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<!-- 求职偏好设置 -->
|
||||
<section class="card">
|
||||
<h3>2. 求职偏好设置</h3>
|
||||
<form class="form" @submit.prevent="saveJobPreference">
|
||||
<div class="form-row">
|
||||
<label>期望岗位类型</label>
|
||||
<input
|
||||
v-model="preference.positionType"
|
||||
placeholder="如:后端开发工程师、测试工程师"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>期望工作地点</label>
|
||||
<input
|
||||
v-model="preference.location"
|
||||
placeholder="如:北京 / 上海 / 杭州,可填写多个"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-row salary-row">
|
||||
<label>期望薪资范围(K/月)</label>
|
||||
<div class="salary-inputs">
|
||||
<input
|
||||
v-model.number="preference.salaryMin"
|
||||
type="number"
|
||||
min="0"
|
||||
placeholder="最低"
|
||||
/>
|
||||
<span class="separator">-</span>
|
||||
<input
|
||||
v-model.number="preference.salaryMax"
|
||||
type="number"
|
||||
min="0"
|
||||
placeholder="最高"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>行业方向</label>
|
||||
<input
|
||||
v-model="preference.industry"
|
||||
placeholder="如:互联网、新能源、制造业等"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit">保存求职偏好</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<!-- 简历管理 -->
|
||||
<section class="card resume-card">
|
||||
<h3>3. 简历管理</h3>
|
||||
<div class="upload-area">
|
||||
<label class="upload-label">
|
||||
上传简历文件(PDF / Word)
|
||||
<input type="file" class="file-input" @change="handleUpload" />
|
||||
</label>
|
||||
<p class="hint">当前仅做界面演示,文件不会真正上传。</p>
|
||||
</div>
|
||||
|
||||
<div class="resume-list" v-if="resumes.length">
|
||||
<div class="resume-item" v-for="item in resumes" :key="item.id">
|
||||
<div>
|
||||
<div class="resume-title">
|
||||
{{ item.name }}
|
||||
<span v-if="item.isDefault" class="tag-default">默认</span>
|
||||
</div>
|
||||
<div class="resume-desc">{{ item.description }}</div>
|
||||
</div>
|
||||
<div class="resume-actions">
|
||||
<button type="button" @click="setDefault(item.id)">
|
||||
设为默认
|
||||
</button>
|
||||
<button type="button" @click="editResume(item.id)">在线编辑</button>
|
||||
<button type="button" class="primary" @click="quickApply(item.id)">
|
||||
一键投递
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p v-else class="empty-text">暂时还没有简历,请先上传或创建一份。</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
const basic = reactive({
|
||||
major: '',
|
||||
education: '',
|
||||
university: '',
|
||||
certificates: '',
|
||||
projects: ''
|
||||
})
|
||||
|
||||
const preference = reactive({
|
||||
positionType: '',
|
||||
location: '',
|
||||
salaryMin: undefined as number | undefined,
|
||||
salaryMax: undefined as number | undefined,
|
||||
industry: ''
|
||||
})
|
||||
|
||||
type ResumeItem = {
|
||||
id: number
|
||||
name: string
|
||||
description: string
|
||||
isDefault: boolean
|
||||
}
|
||||
|
||||
const resumes = ref<ResumeItem[]>([
|
||||
{
|
||||
id: 1,
|
||||
name: '通用技术岗简历-v1',
|
||||
description: '适用于后端 / 测试 / 运维等通用技术岗位',
|
||||
isDefault: true
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '算法岗位简历-v1',
|
||||
description: '突出数学与算法竞赛经历,适合算法与数据岗位',
|
||||
isDefault: false
|
||||
}
|
||||
])
|
||||
|
||||
function saveBasicInfo() {
|
||||
console.log('保存基础信息', { ...basic })
|
||||
alert('基础信息已保存(示例)')
|
||||
}
|
||||
|
||||
function saveJobPreference() {
|
||||
console.log('保存求职偏好', { ...preference })
|
||||
alert('求职偏好已保存(示例)')
|
||||
}
|
||||
|
||||
function handleUpload(event: Event) {
|
||||
const target = event.target as HTMLInputElement
|
||||
const file = target.files?.[0]
|
||||
if (!file) return
|
||||
|
||||
const id = Date.now()
|
||||
resumes.value.push({
|
||||
id,
|
||||
name: file.name,
|
||||
description: '从本地上传的简历文件,仅作示例展示。',
|
||||
isDefault: false
|
||||
})
|
||||
target.value = ''
|
||||
}
|
||||
|
||||
function setDefault(id: number) {
|
||||
resumes.value = resumes.value.map((item) => ({
|
||||
...item,
|
||||
isDefault: item.id === id
|
||||
}))
|
||||
}
|
||||
|
||||
function editResume(id: number) {
|
||||
const item = resumes.value.find((r) => r.id === id)
|
||||
if (item) {
|
||||
alert(`打开在线编辑器(示例):${item.name}`)
|
||||
}
|
||||
}
|
||||
|
||||
function quickApply(id: number) {
|
||||
const item = resumes.value.find((r) => r.id === id)
|
||||
if (item) {
|
||||
alert(`使用【${item.name}】进行一键投递(示例)`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page h2 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
font-size: 18px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.page p {
|
||||
margin: 0;
|
||||
.intro {
|
||||
margin: 0 0 16px;
|
||||
color: #4b5563;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #f9fafb;
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
margin: 0 0 12px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.form-row label {
|
||||
font-size: 13px;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
border-radius: 8px;
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 6px 8px;
|
||||
font-size: 13px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
select:focus,
|
||||
textarea:focus {
|
||||
border-color: #2563eb;
|
||||
box-shadow: 0 0 0 1px rgba(37, 99, 235, 0.3);
|
||||
}
|
||||
|
||||
.salary-row label {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.salary-inputs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.salary-inputs input {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.separator {
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-top: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 999px;
|
||||
border: none;
|
||||
background: #2563eb;
|
||||
color: #ffffff;
|
||||
padding: 6px 14px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #1d4ed8;
|
||||
}
|
||||
|
||||
.hint {
|
||||
font-size: 12px;
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.resume-card {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.upload-area {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.upload-label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 999px;
|
||||
border: 1px dashed #9ca3af;
|
||||
font-size: 13px;
|
||||
color: #4b5563;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.file-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.resume-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.resume-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 12px;
|
||||
border-radius: 10px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.resume-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.tag-default {
|
||||
padding: 2px 6px;
|
||||
border-radius: 999px;
|
||||
background: #0ea5e9;
|
||||
color: #f9fafb;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.resume-desc {
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.resume-actions {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.resume-actions button {
|
||||
padding-inline: 10px;
|
||||
}
|
||||
|
||||
.resume-actions .primary {
|
||||
background: #f97316;
|
||||
}
|
||||
|
||||
.resume-actions .primary:hover {
|
||||
background: #ea580c;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 13px;
|
||||
color: #9ca3af;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,24 +1,423 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<h2>报告中心</h2>
|
||||
<p>在这里管理、查看和导出各类报告。</p>
|
||||
<h2>招聘信息浏览与交互模块</h2>
|
||||
<p class="intro">
|
||||
为理工科毕业生提供多维度的岗位检索能力,以及与企业进行高效互动的入口。
|
||||
</p>
|
||||
|
||||
<!-- 多维度搜索 -->
|
||||
<section class="card">
|
||||
<h3>1. 多维度搜索</h3>
|
||||
<form class="filter-bar" @submit.prevent>
|
||||
<input v-model="filter.keyword" placeholder="输入岗位关键词,例如:Java、测试" />
|
||||
<select v-model="filter.major">
|
||||
<option value="">专业方向</option>
|
||||
<option value="计算机">计算机相关</option>
|
||||
<option value="机械">机械相关</option>
|
||||
<option value="电子">电子信息</option>
|
||||
</select>
|
||||
<select v-model="filter.companyType">
|
||||
<option value="">企业类型</option>
|
||||
<option value="国企">国企</option>
|
||||
<option value="外企">外企</option>
|
||||
<option value="民企">民企</option>
|
||||
</select>
|
||||
<select v-model="filter.hot">
|
||||
<option value="">岗位热度</option>
|
||||
<option value="高">高</option>
|
||||
<option value="中">中</option>
|
||||
<option value="低">低</option>
|
||||
</select>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="layout">
|
||||
<!-- 岗位列表 -->
|
||||
<section class="card job-list-card">
|
||||
<h3>2. 岗位列表</h3>
|
||||
<div class="job-list">
|
||||
<div
|
||||
v-for="job in filteredJobs"
|
||||
:key="job.id"
|
||||
class="job-item"
|
||||
:class="{ active: selectedJob && selectedJob.id === job.id }"
|
||||
@click="selectJob(job)"
|
||||
>
|
||||
<div>
|
||||
<div class="job-title-row">
|
||||
<span class="job-title">{{ job.title }}</span>
|
||||
<span class="job-company">{{ job.company }}</span>
|
||||
</div>
|
||||
<div class="job-meta">
|
||||
<span>{{ job.city }}</span>
|
||||
<span>{{ job.salary }}</span>
|
||||
<span>{{ job.companyType }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="job-actions">
|
||||
<button
|
||||
type="button"
|
||||
@click.stop="toggleFavorite(job.id)"
|
||||
:class="{ secondary: isFavorite(job.id) }"
|
||||
>
|
||||
{{ isFavorite(job.id) ? '已收藏' : '收藏' }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="primary"
|
||||
@click.stop="apply(job.id)"
|
||||
>
|
||||
{{ isApplied(job.id) ? '已投递' : '投递简历' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="!filteredJobs.length" class="empty-text">
|
||||
暂无符合当前筛选条件的岗位,可以尝试调整搜索条件。
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 岗位详情页 -->
|
||||
<section class="card detail-card">
|
||||
<h3>3. 岗位详情</h3>
|
||||
<div v-if="selectedJob" class="detail">
|
||||
<h4>{{ selectedJob.title }} · {{ selectedJob.company }}</h4>
|
||||
<p class="detail-sub">
|
||||
{{ selectedJob.city }} · {{ selectedJob.salary }} ·
|
||||
{{ selectedJob.companyType }}
|
||||
</p>
|
||||
|
||||
<h5>岗位职责</h5>
|
||||
<ul>
|
||||
<li v-for="(duty, index) in selectedJob.duties" :key="index">
|
||||
{{ duty }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5>任职要求</h5>
|
||||
<ul>
|
||||
<li v-for="(req, index) in selectedJob.requirements" :key="index">
|
||||
{{ req }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5>企业介绍与薪资福利</h5>
|
||||
<p class="detail-desc">{{ selectedJob.companyIntro }}</p>
|
||||
</div>
|
||||
<p v-else class="empty-text">
|
||||
在左侧列表中选择一个岗位,查看详细信息与岗位要求。
|
||||
</p>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
|
||||
type JobItem = {
|
||||
id: number
|
||||
title: string
|
||||
company: string
|
||||
city: string
|
||||
salary: string
|
||||
companyType: string
|
||||
majorTag: string
|
||||
hot: '高' | '中' | '低'
|
||||
duties: string[]
|
||||
requirements: string[]
|
||||
companyIntro: string
|
||||
}
|
||||
|
||||
const jobs = ref<JobItem[]>([
|
||||
{
|
||||
id: 1,
|
||||
title: 'Java 后端开发工程师',
|
||||
company: '云计算科技有限公司',
|
||||
city: '北京',
|
||||
salary: '18-25K',
|
||||
companyType: '民企',
|
||||
majorTag: '计算机',
|
||||
hot: '高',
|
||||
duties: [
|
||||
'参与后端服务的设计与开发,保证系统稳定性与性能。',
|
||||
'参与需求评审,与前端及产品协作完成业务功能。',
|
||||
'编写相关技术文档与单元测试。'
|
||||
],
|
||||
requirements: [
|
||||
'计算机或相关理工科专业,本科及以上学历。',
|
||||
'熟悉 Java 语言及 SpringBoot 框架。',
|
||||
'掌握 MySQL、Redis 等常用中间件,具备良好的编码习惯。'
|
||||
],
|
||||
companyIntro: '专注云计算与大数据解决方案,为各行业提供技术服务。'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '自动化测试工程师',
|
||||
company: '智能硬件科技集团',
|
||||
city: '深圳',
|
||||
salary: '15-20K',
|
||||
companyType: '民企',
|
||||
majorTag: '电子',
|
||||
hot: '中',
|
||||
duties: [
|
||||
'参与产品测试方案设计及测试用例编写。',
|
||||
'搭建和维护自动化测试框架。',
|
||||
'跟踪和推动缺陷修复,保障产品质量。'
|
||||
],
|
||||
requirements: [
|
||||
'电子信息、计算机等相关理工科专业。',
|
||||
'熟悉 Python、Shell 等脚本语言。',
|
||||
'了解常见自动化测试工具和方法。'
|
||||
],
|
||||
companyIntro: '国内领先的智能硬件设计与生产企业,产品覆盖多领域。'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '机械设计工程师',
|
||||
company: '高端装备制造股份有限公司',
|
||||
city: '上海',
|
||||
salary: '12-18K',
|
||||
companyType: '国企',
|
||||
majorTag: '机械',
|
||||
hot: '高',
|
||||
duties: [
|
||||
'负责机械部件及整机结构的方案设计与优化。',
|
||||
'输出二维工程图与三维模型,并跟进生产制造。',
|
||||
'参与样机装配与测试验证。'
|
||||
],
|
||||
requirements: [
|
||||
'机械设计相关专业,本科及以上学历。',
|
||||
'熟练使用 SolidWorks、CATIA 等三维设计软件。',
|
||||
'具备良好的沟通协调能力和团队协作精神。'
|
||||
],
|
||||
companyIntro: '国有大型装备制造企业,深耕高端装备领域多年。'
|
||||
}
|
||||
])
|
||||
|
||||
const filter = reactive({
|
||||
keyword: '',
|
||||
major: '',
|
||||
companyType: '',
|
||||
hot: ''
|
||||
})
|
||||
|
||||
const selectedJob = ref<JobItem | null>(null)
|
||||
const favoriteIds = ref<number[]>([])
|
||||
const appliedIds = ref<number[]>([])
|
||||
|
||||
const filteredJobs = computed(() =>
|
||||
jobs.value.filter((job) => {
|
||||
const byKeyword = filter.keyword
|
||||
? job.title.includes(filter.keyword) ||
|
||||
job.company.includes(filter.keyword)
|
||||
: true
|
||||
const byMajor = filter.major ? job.majorTag === filter.major : true
|
||||
const byCompanyType = filter.companyType
|
||||
? job.companyType === filter.companyType
|
||||
: true
|
||||
const byHot = filter.hot ? job.hot === filter.hot : true
|
||||
|
||||
return byKeyword && byMajor && byCompanyType && byHot
|
||||
})
|
||||
)
|
||||
|
||||
function selectJob(job: JobItem) {
|
||||
selectedJob.value = job
|
||||
}
|
||||
|
||||
function isFavorite(id: number) {
|
||||
return favoriteIds.value.includes(id)
|
||||
}
|
||||
|
||||
function toggleFavorite(id: number) {
|
||||
if (isFavorite(id)) {
|
||||
favoriteIds.value = favoriteIds.value.filter((v) => v !== id)
|
||||
} else {
|
||||
favoriteIds.value.push(id)
|
||||
}
|
||||
}
|
||||
|
||||
function isApplied(id: number) {
|
||||
return appliedIds.value.includes(id)
|
||||
}
|
||||
|
||||
function apply(id: number) {
|
||||
if (!isApplied(id)) {
|
||||
appliedIds.value.push(id)
|
||||
alert('简历已投递(示例),可在个人中心查看投递状态。')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page h2 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
font-size: 18px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.page p {
|
||||
margin: 0;
|
||||
.intro {
|
||||
margin: 0 0 16px;
|
||||
color: #4b5563;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #f9fafb;
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.filter-bar input,
|
||||
.filter-bar select {
|
||||
border-radius: 999px;
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 6px 10px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.layout {
|
||||
margin-top: 16px;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.4fr) minmax(0, 1.2fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.job-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.job-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 12px;
|
||||
border-radius: 10px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.job-item.active {
|
||||
border-color: #2563eb;
|
||||
box-shadow: 0 0 0 1px rgba(37, 99, 235, 0.3);
|
||||
}
|
||||
|
||||
.job-title-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.job-title {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.job-company {
|
||||
font-size: 13px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.job-meta {
|
||||
margin-top: 4px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.job-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 999px;
|
||||
border: none;
|
||||
padding: 5px 12px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
background: #2563eb;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #1d4ed8;
|
||||
}
|
||||
|
||||
.primary {
|
||||
background: #f97316;
|
||||
}
|
||||
|
||||
.primary:hover {
|
||||
background: #ea580c;
|
||||
}
|
||||
|
||||
.secondary {
|
||||
background: #e5e7eb;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
min-height: 260px;
|
||||
}
|
||||
|
||||
.detail h4 {
|
||||
margin: 0 0 4px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.detail-sub {
|
||||
margin: 0 0 10px;
|
||||
font-size: 13px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.detail h5 {
|
||||
margin: 10px 0 6px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.detail ul {
|
||||
padding-left: 18px;
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.detail-desc {
|
||||
font-size: 13px;
|
||||
color: #4b5563;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
margin-top: 6px;
|
||||
font-size: 13px;
|
||||
color: #9ca3af;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,24 +1,398 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<h2>系统设置</h2>
|
||||
<p>这里可以配置系统参数、主题、用户等。</p>
|
||||
<h2>求职辅助工具模块</h2>
|
||||
<p class="intro">
|
||||
通过测评、经验库与行业资讯,为理工科毕业生提供更全面的求职决策支持。
|
||||
</p>
|
||||
|
||||
<section class="card">
|
||||
<h3>1. 能力测评工具</h3>
|
||||
<div class="assessment-grid">
|
||||
<div
|
||||
class="assessment-card"
|
||||
:class="{ active: activeAssessment === 'skill' }"
|
||||
@click="setAssessment('skill')"
|
||||
>
|
||||
<h4>专业技能测评</h4>
|
||||
<p>评估编程、工程设计、数据分析等理工科核心技能掌握情况。</p>
|
||||
<button type="button">开始测评</button>
|
||||
</div>
|
||||
<div
|
||||
class="assessment-card"
|
||||
:class="{ active: activeAssessment === 'personality' }"
|
||||
@click="setAssessment('personality')"
|
||||
>
|
||||
<h4>职业性格测评</h4>
|
||||
<p>了解更适合你的岗位类型与团队环境,辅助职业定位。</p>
|
||||
<button type="button">开始测评</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="activeAssessment" class="assessment-panel">
|
||||
<h4>测评问题示例({{ activeAssessmentLabel }})</h4>
|
||||
<p class="question">
|
||||
Q1:你更倾向于哪种工作内容?
|
||||
</p>
|
||||
<ul class="options">
|
||||
<li><label><input type="radio" name="q1" /> A. 深度编码与技术攻关</label></li>
|
||||
<li>
|
||||
<label><input type="radio" name="q1" /> B. 与人沟通、需求分析与协调</label>
|
||||
</li>
|
||||
<li>
|
||||
<label><input type="radio" name="q1" /> C. 数据分析、建模与实验验证</label>
|
||||
</li>
|
||||
</ul>
|
||||
<button type="button" class="submit-btn">提交测评(示例)</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h3>2. 面试经验库</h3>
|
||||
<div class="experience-filter">
|
||||
<input v-model="experienceKeyword" placeholder="按岗位搜索面试经验,例如:测试 / 算法" />
|
||||
</div>
|
||||
<div class="experience-list">
|
||||
<div
|
||||
v-for="item in filteredExperiences"
|
||||
:key="item.id"
|
||||
class="experience-item"
|
||||
>
|
||||
<div>
|
||||
<div class="exp-title">
|
||||
{{ item.position }} · {{ item.company }}
|
||||
</div>
|
||||
<div class="exp-tags">
|
||||
<span class="tag" v-for="tag in item.tags" :key="tag">
|
||||
{{ tag }}
|
||||
</span>
|
||||
</div>
|
||||
<p class="exp-brief">{{ item.brief }}</p>
|
||||
</div>
|
||||
<button type="button" class="secondary-btn">查看详情</button>
|
||||
</div>
|
||||
<p v-if="!filteredExperiences.length" class="empty-text">
|
||||
暂无相关面试经验,可以尝试更换关键词。
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h3>3. 就业资讯</h3>
|
||||
<div class="news-list">
|
||||
<div v-for="news in newsList" :key="news.id" class="news-item">
|
||||
<div class="news-main">
|
||||
<div class="news-title">{{ news.title }}</div>
|
||||
<div class="news-meta">
|
||||
<span>{{ news.tag }}</span>
|
||||
<span>{{ news.date }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="link-btn">查看详情</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
type AssessmentType = 'skill' | 'personality' | null
|
||||
|
||||
type ExperienceItem = {
|
||||
id: number
|
||||
position: string
|
||||
company: string
|
||||
tags: string[]
|
||||
brief: string
|
||||
}
|
||||
|
||||
type NewsItem = {
|
||||
id: number
|
||||
title: string
|
||||
tag: string
|
||||
date: string
|
||||
}
|
||||
|
||||
const activeAssessment = ref<AssessmentType>(null)
|
||||
|
||||
const experienceKeyword = ref('')
|
||||
|
||||
const experiences = ref<ExperienceItem[]>([
|
||||
{
|
||||
id: 1,
|
||||
position: '后端开发工程师',
|
||||
company: '互联网大厂一面 + 二面',
|
||||
tags: ['Java', '计网', '操作系统'],
|
||||
brief: '主要考察基础算法、项目细节以及高并发相关问题。'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
position: '测试开发工程师',
|
||||
company: '智能设备公司现场面试',
|
||||
tags: ['测试用例', 'Python', '自动化测试'],
|
||||
brief: '以场景题为主,需要设计完整的测试方案和脚本思路。'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
position: '算法工程师实习',
|
||||
company: 'AI 创业公司线上面试',
|
||||
tags: ['机器学习', '数学基础', '项目经历'],
|
||||
brief: '注重项目中模型选择理由以及效果对比。'
|
||||
}
|
||||
])
|
||||
|
||||
const newsList = ref<NewsItem[]>([
|
||||
{
|
||||
id: 1,
|
||||
title: '2026 届理工科毕业生就业形势分析报告',
|
||||
tag: '行业报告',
|
||||
date: '2026-01-15'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '国家发布关于促进高校毕业生就业的新政策',
|
||||
tag: '政策解读',
|
||||
date: '2025-12-30'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '多家头部科技企业启动春季校园招聘',
|
||||
tag: '招聘动态',
|
||||
date: '2026-02-01'
|
||||
}
|
||||
])
|
||||
|
||||
const activeAssessmentLabel = computed(() => {
|
||||
if (activeAssessment.value === 'skill') return '专业技能测评'
|
||||
if (activeAssessment.value === 'personality') return '职业性格测评'
|
||||
return ''
|
||||
})
|
||||
|
||||
const filteredExperiences = computed(() => {
|
||||
if (!experienceKeyword.value.trim()) return experiences.value
|
||||
return experiences.value.filter(
|
||||
(item) =>
|
||||
item.position.includes(experienceKeyword.value) ||
|
||||
item.company.includes(experienceKeyword.value) ||
|
||||
item.tags.some((t) => t.includes(experienceKeyword.value))
|
||||
)
|
||||
})
|
||||
|
||||
function setAssessment(type: AssessmentType) {
|
||||
activeAssessment.value = type
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page h2 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 8px;
|
||||
font-size: 18px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.page p {
|
||||
margin: 0;
|
||||
.intro {
|
||||
margin: 0 0 16px;
|
||||
color: #4b5563;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #f9fafb;
|
||||
border-radius: 12px;
|
||||
padding: 14px 16px;
|
||||
border: 1px solid #e5e7eb;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.assessment-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 12px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.assessment-card {
|
||||
padding: 10px 12px;
|
||||
border-radius: 10px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.assessment-card.active {
|
||||
border-color: #2563eb;
|
||||
box-shadow: 0 0 0 1px rgba(37, 99, 235, 0.3);
|
||||
}
|
||||
|
||||
.assessment-card h4 {
|
||||
margin: 0 0 6px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.assessment-card p {
|
||||
margin: 0 0 8px;
|
||||
font-size: 13px;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.assessment-card button {
|
||||
border-radius: 999px;
|
||||
border: none;
|
||||
padding: 5px 12px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
background: #2563eb;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.assessment-panel {
|
||||
margin-top: 12px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 10px;
|
||||
background: #eff6ff;
|
||||
}
|
||||
|
||||
.assessment-panel h4 {
|
||||
margin: 0 0 6px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.question {
|
||||
margin: 0 0 6px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.options {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0 0 8px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.options li + li {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
border-radius: 999px;
|
||||
border: none;
|
||||
padding: 5px 12px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
background: #f97316;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.experience-filter {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.experience-filter input {
|
||||
width: 100%;
|
||||
border-radius: 999px;
|
||||
border: 1px solid #d1d5db;
|
||||
padding: 6px 10px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.experience-list {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.experience-item {
|
||||
padding: 10px 12px;
|
||||
border-radius: 10px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.exp-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.exp-tags {
|
||||
margin-top: 4px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font-size: 11px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 999px;
|
||||
background: #e0f2fe;
|
||||
color: #0369a1;
|
||||
}
|
||||
|
||||
.exp-brief {
|
||||
margin: 4px 0 0;
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.secondary-btn {
|
||||
border-radius: 999px;
|
||||
border: none;
|
||||
padding: 5px 12px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
background: #e5e7eb;
|
||||
color: #374151;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.news-list {
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.news-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 10px;
|
||||
border-radius: 10px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.news-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.news-meta {
|
||||
margin-top: 2px;
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.link-btn {
|
||||
border-radius: 999px;
|
||||
border: none;
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
background: #2563eb;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 13px;
|
||||
color: #9ca3af;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user