Files
ks-app-employment-service/packageRc/pages/index/indexYtj.vue
shirlwang 9393e9a624 feat(index): add custom navigation and new job list components
- Updated the index page to include a custom navigation style for H5.
- Introduced a new component `IndexYtj` for enhanced job listing features.
- Added a new job list page `jobListYtj` with improved layout and functionality.
- Integrated a WeChat authorization login component for better user experience.
- Included several new static assets for UI enhancements.
2026-04-30 17:44:54 +08:00

815 lines
20 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.

<!--
* @Date: 2025-10-16 15:15:47
* @LastEditors: shirlwang
* @LastEditTime: 2026-01-27 09:30:18
-->
<template>
<!-- @scroll="handleScroll" @scrolltolower="scrollBottom" -->
<scroll-view :scroll-y="true" class="container" :class="{'h5-pc-container': isH5}" :show-scrollbar="false">
<!-- 自定义导航栏 -->
<view class="custom-nav" :style="{paddingTop: statusBarHeight + 'px'}">
<view class="nav-content">
<view class="nav-back" @click="back"><text class="iconfont"><</text></view>
<view class="nav-title">高校毕业生智慧就业</view>
<view class="nav-placeholder"></view>
</view>
</view>
<view class="main-content">
<!-- #ifdef MP-WEIXIN -->
<view class="kinggang">
<view @click="navTo('/packageA/pages/myResume/myResume')">
<image src="../../../packageRc/static/kinggang1.png"/>
<view>信息维护</view>
</view>
<view @click="navTo('/packageA/pages/Intendedposition/Intendedposition')">
<image src="../../../packageRc/static/kinggang5.png"/>
<view>投递记录</view>
</view>
<view @click="tiao()">
<image src="../../../packageRc/static/kinggang2.png"/>
<view>需求上报</view>
</view>
<view>
<image @click="goAiAu" src="../../../packageRc/static/kinggang3.png"/>
<view>虚拟面试</view>
</view>
<view @click="goCa">
<image src="../../../packageRc/static/kinggang4.png"/>
<view>素质测评</view>
</view>
</view>
<!-- #endif -->
<!-- 岗位类型切换 -->
<view class="tabs">
<view class="tab" :class="{active: pageState.type == ''}" @click="changeJobType('')">岗位列表</view>
<view class="tab" :class="{active: pageState.type == 2}" @click="changeJobType(2)">实习实训</view>
<view class="tab" :class="{active: pageState.type == 3}" @click="changeJobType(3)">社区实践</view>
</view>
<!-- 子选项卡 -->
<view class="titles">
<view class="title-item" :class="{active: activeTitle == 1}" @click="activeTitle = 1,getJobRecommed()">
<view>推荐<text class="accent">岗位</text></view>
</view>
<view class="title-item" :class="{active: activeTitle == 2}" @click="activeTitle = 2,getJobList()">
<view>热门<text class="accent">岗位</text></view>
</view>
</view>
<!-- 岗位列表改为网格布局 -->
<view class="job-grid">
<view v-for="(item, index) in jobList" :key="index" @click="nextDetail(item)" class="job-card-box">
<view class="job-top">
<view class="job-name">{{ item.jobTitle }}</view>
<view class="job-salary">{{item.minSalary}}-{{item.maxSalary}}/</view>
</view>
<view class="job-tags">
<view v-if="item.jobLocationAreaCode" class="tag"><dict-Label dictType="jobLocationAreaCode" :value="item.jobLocationAreaCode"></dict-Label></view>
<view class="tag"><dict-Label dictType="education" :value="item.education"></dict-Label></view>
<view class="tag"><dict-Label dictType="experience" :value="item.experience"></dict-Label></view>
</view>
<view class="job-desc">
{{ vacanciesTo(item.vacancies) }} | {{item.jobCategory}} | {{ item.jobCategory }}
</view>
<view class="company-link">
<image class="comp-icon" src="../../../packageRc/static/dmsc/gs.png" />
<view class="comp-name">{{ item.companyName }}</view>
</view>
<view class="delivery-btn" @click.stop="nextDetail(item)">简历投递</view>
</view>
</view>
<view class="view-more-btn" @click="viewMore">查看更多内容</view>
<!-- 政策专区改为常驻显示 -->
<view class="titles section-title" style="justify-content: space-between; margin-top: 36rpx;">
<view class="title-item active"><view>政策<text class="accent">专区</text></view></view>
<view class="more-link" @click="toPolicyList">{{'查看更多 >'}}</view>
</view>
<view v-for="(item, index) in policyList" :key="index" class="policy-list-card" @click="toPolicyDetail(item)">
<view class="card-left">
<image class="clock-icon" src="../../../packageRc/static/dmsc/sj.png" />
<view class="date-md">{{ formatMD(item.publishTime || item.createTime) }}</view>
<view class="date-year">{{ formatYear(item.publishTime || item.createTime) }}</view>
</view>
<view class="card-right">
<view class="card-title">{{ item.zcmc }}</view>
<view class="card-infos">
<view v-if="item.zcLevel" class="info-tag">{{ item.zcLevel }}</view>
<view v-if="item.sourceUnit" class="info-tag">{{ item.sourceUnit }}</view>
</view>
</view>
</view>
</view>
</scroll-view>
</template>
<script setup>
import { reactive, inject, watch, ref, onMounted, watchEffect, nextTick } from 'vue';
const { $api, navTo, vacanciesTo, formatTotal, config } = inject('globalFunction');
const isH5 = ref(false);
const uniIconSize = ref(18);
// #ifdef H5
isH5.value = true;
uniIconSize.value = 20;
// #endif
// 状态栏高度(用于自定义导航栏)
const statusBarHeight = ref(0);
try {
const sysInfo = uni.getSystemInfoSync();
statusBarHeight.value = sysInfo.statusBarHeight || 0;
} catch(e) {}
import { getPolicyList } from '@/packageRc/apiRc/policy';
let policyList = ref([])
function getPolicy() {
getPolicyList({pageNum: 1, pageSize: 4,zclx:'1'}).then(res => {
if (res.code == 200) {
policyList.value = res.rows
} else {
throw new Error();
}
})
}
let tabType = ref(1)
function changeType(type) {
tabType.value = type
}
function toPolicyList() {
navTo(`/packageRc/pages/policy/policyList?zclx=1`)
}
function toPolicyDetail(item) {
navTo(`/packageRc/pages/policy/policyDetail?id=${item.id}`)
}
let activeTab = ref(1)
let activeTitle = ref(1)
function back() {
// uni.navigateBack({
// delta: 1
// })
window.location.href='https://www.xjksly.cn/mechine-single-vue/'
// uni.reLaunch({
// url: '/pages/index/index'
// })
}
onMounted(()=>{
getJobRecommed()
getPolicy();
})
function goCa(){
if (checkLogin()) {
const userInfo = uni.getStorageSync('userInfo')
navTo(`/packageCa/search/search?userId=${userInfo.userId}&name=${userInfo.name}`);
}
}
// 跳转AI智能面试
function goAiAu(){
if (checkLogin()) {
const userInfo = uni.getStorageSync('userInfo')
navTo(`/packageCa/search/AIAudition?userId=${userInfo.userId}&name=${userInfo.name}`);
}
}
function viewMore() {
navTo(`/packageRc/pages/jobList/jobList`);
}
function tiao(){
console.log('尝试导航到待办详情页面');
// 尝试直接使用uni.navigateTo使用正确的格式
uni.navigateTo({
url: `/packageRc/pages/needs/personNeeds`,
success: function() {
console.log('导航成功');
},
fail: function(err) {
console.error('导航失败:', err);
}
});
}
import useUserStore from '@/stores/useUserStore';
const conditionSearch = ref({});
const pageState = reactive({
page: 0,
total: 0,
maxPage: 2,
pageSize: 4,
search: {
order: 0,
},
type:'',
});
let jobList = ref([])
// 获取推荐岗位
function getJobRecommed(){
let params = {
pageSize: pageState.pageSize,
sessionId: useUserStore().seesionId,
...pageState.search,
...conditionSearch.value,
isPublish: 1,
type:pageState.type
};
$api.createRequest('/app/job/recommend', params).then((resData) => {
if (resData.code == 200 && resData.data.length) {
jobList.value = resData.data
} else {
throw new Error();
}
}).catch(() => {
// 造一些测试数据
const mock = { jobTitle: '计算机网络运维员', companyName: '新疆天山人才智汇发展有限责任公司', minSalary: '面议', maxSalary: '面议' };
jobList.value = [mock, mock, mock, mock];
});
}
// 获取岗位列表
function getJobList(){
let params = {
current: pageState.page,
pageSize: pageState.pageSize,
...pageState.search,
// ...conditionSearch.value,
type:pageState.type
};
$api.createRequest('/app/job/list', params).then((resData) => {
jobList.value = resData.rows
pageState.total = 0;
});
}
// 更改实习实训等
function changeJobType(val){
pageState.type = val
if(activeTitle.value == 1){
getJobRecommed()
}else{
getJobList()
}
}
// 登录检查函数
import { storeToRefs } from 'pinia';
const { userInfo, hasLogin, token } = storeToRefs(useUserStore());
const checkLogin = () => {
const tokenValue = uni.getStorageSync('token') || '';
if (!tokenValue || !hasLogin.value) {
// 未登录,打开授权弹窗
wxAuthLoginRef.value?.open();
return false;
}
return true;
};
// 跳转到详情页面
function nextDetail(job) {
navTo(`/packageA/pages/post/post?jobId=${encodeURIComponent(job.jobId)}&encryptJobId=${job.encryptJobId}`);
// 登录检查
// if (checkLogin()) {
// }
}
function formatMD(dateStr) {
if (!dateStr) return '--';
const parts = dateStr.split('-').length > 1 ? dateStr.split('-') : dateStr.split(' ');
// 处理 YYYY-MM-DD 或 YYYY-MM-DD HH:mm:ss
let d = parts[0].includes('-') ? parts[0].split('-') : parts;
if (d.length >= 3) {
return `${d[1]}-${d[2].substring(0,2)}`;
}
return dateStr;
}
function formatYear(dateStr) {
if (!dateStr) return '';
const parts = dateStr.split('-');
if (parts.length >= 1) {
return parts[0].substring(0, 4);
}
return '';
}
</script>
<style lang="less" scoped>
/* 隐藏滚动条 */
::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
view{box-sizing: border-box;display: block;}
.container{
background-color: #FFFFFF;
min-height: 1920px;
min-width: 1080px;
box-sizing: border-box;
}
/* 自定义导航栏 */
.custom-nav {
background: #107AFD;
width: 100%;
.nav-content {
height: 120rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24rpx;
.nav-back {
width: 72rpx;
height: 120rpx;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-weight: 300;
.iconfont{
font-size: 40px!important;
}
}
.nav-title {
color: #fff;
font-size: 43rpx;
font-weight: bold;
}
.nav-placeholder {
width: 72rpx;
}
}
}
.main-content {
position: relative;
z-index: 2;
/* 页面全局边距加倍 */
padding: 38rpx 29rpx;
}
.kinggang{
display: flex;
justify-content: space-around;
align-items: center;
padding: 14rpx 10rpx 29rpx 10rpx;
font-size: 31rpx;
background: #FFFFFF;
border-radius: 12rpx;
margin-bottom: 19rpx;
>view{
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
}
image{
width: 96rpx;
height: 96rpx;
margin-bottom: 12rpx;
}
}
.tabs{
/* 调大上方选项卡的边距 */
margin: 38rpx auto 38rpx;
border-radius: 72rpx;
display: flex;
background: #F4F6F9;
color: #878787;
text-align: center;
width: 80%;
overflow: hidden;
padding: 5rpx;
box-sizing: border-box;
.tab{
flex: 1;
line-height: 72rpx;
position: relative;
font-size: 43rpx;
font-weight: 500;
transition: all 0.25s;
border-radius: 72rpx;
&.active{
color: #fff;
background: #107AFD;
box-shadow: none;
}
}
}
.titles{
display: flex;
/* 调大标题下边距 */
margin-bottom: 43rpx;
align-items: flex-end;
.title-item{
font-size: 72rpx;
font-weight: bold;
color: #282828;
margin-right: 34rpx;
position: relative;
>view{
position: relative;
z-index: 2;
padding: 0 5rpx;
.accent {
color: #EC7737;
margin-left: 2rpx;
}
}
&.active::after{
content: '';
position: absolute;
z-index: 1;
bottom: -5rpx;
left: 10%;
width: 80%;
height: 12rpx;
border-radius: 50px;
background: linear-gradient(90deg, rgba(82, 149, 255, 0.4) 0%, rgba(24, 116, 255, 0) 100%);
}
}
}
.job-list{
width: 100%;
margin: 0 auto;
color: #333333;
border-radius: 7rpx;
background: #FFFFFF;
padding: 19rpx;
margin-bottom: 14rpx;
position: relative;
/* 去掉阴影,保持扁平统一 */
.sign{
position: absolute;
font-size: 17rpx;
right: 0;
top: 0;
padding: 5rpx 12rpx;
border: 1rpx solid #EC4827;
background: rgba(227, 79, 49, 0.09);
border-top-right-radius: 14rpx;
border-bottom-left-radius: 14rpx;
color: #EC4827;
}
.top-line{
display: flex;
justify-content: space-between;
font-size: 14rpx;
color: #A2A2A2;
margin-bottom: 10rpx;
.salary{
font-size: 19rpx;
color: #4C6EFB;
font-weight: bold;
}
}
.title{
font-size: 19rpx;
font-weight: bold;
color: #282828;
margin-bottom: 10rpx;
display: flex;
image{
width: 28rpx;
height: 28rpx;
margin-right: 7rpx;
}
}
.infos{
display: flex;
flex-wrap: wrap;
font-size: 14rpx;
margin-bottom: 10rpx;
line-height: 25rpx;
view{
padding: 0 10rpx;
margin-right: 6rpx;
background: #F2F2F2;
}
}
.bottom-line{
display: flex;
justify-content: space-between;
font-size: 14rpx;
color: #A2A2A2;
margin-top: 7rpx;
}
}
.view-more-btn{
padding: 6rpx 34rpx;
background: #FFFFFF;
color: #4C6EFB;
border: 1rpx solid #4C6EFB;
text-align: center;
border-radius: 24rpx;
width: fit-content;
margin: 0 auto;
margin-bottom: 12rpx;
}
.job-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
/* 列表前边距调大 */
margin-top: 29rpx;
.job-card-box {
/* 缩小宽度比例以增加瀑布流列间距 */
width: calc(50% - 14rpx);
background: #FFFFFF;
background-image: url(../../../packageRc/static/dmsc/kpbj.png);
background-size: 100% 100%;
/* 加大卡片下边距 */
margin-bottom: 29rpx;
border: 1px solid #D1E5FF;
border-radius: 10rpx;
/* 加大卡片内边距 */
padding: 29rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
.job-top {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 14rpx;
.job-salary {
color: #EC7737;
font-weight: bold;
font-size: 38rpx;
flex-shrink: 0;
}
.job-name {
font-size: 43rpx;
font-weight: bold;
color: #333;
flex: 1;
margin-top: 0;
margin-right: 7rpx;
/* 只保留单行溢出,以适应不同宽度 */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.job-tags {
display: flex;
flex-wrap: wrap;
margin-bottom: 19rpx;
.tag {
background: #7DA6FF;
color: #FFFFFF;
font-size: 29rpx;
padding: 5rpx 12rpx;
border-radius: 7rpx;
margin-right: 10rpx;
margin-bottom: 10rpx;
}
}
.job-desc {
font-size: 29rpx;
color: #4C6EFB;
margin-bottom: 26rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.company-link {
display: flex;
align-items: center;
margin-top: auto;
margin-bottom: 29rpx;
.comp-icon {
width: 34rpx;
height: 34rpx;
margin-right: 10rpx;
flex-shrink: 0;
}
.comp-name {
font-size: 29rpx;
color: #666;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.delivery-btn {
width: 75%;
margin: 0 auto;
height: 58rpx;
line-height: 58rpx;
background: #2591FF; /* 与设计图一致的亮蓝色 */
color: #FFFFFF;
text-align: center;
font-size: 31rpx;
font-weight: 500;
border-radius: 7rpx;
/* 移除阴影以贴合扁平化设计稿 */
}
}
}
.policy-list-card {
width: 100%;
margin: 0 auto;
color: #333333;
/* 政策卡片大边距与内边距 */
margin-bottom: 29rpx;
box-sizing: border-box;
display: flex;
background: linear-gradient(180deg, #F0F8FF 0%, #FFFFFF 100%);
padding: 38rpx 29rpx;
border-radius: 10rpx;
border: 1px solid #D1E5FF;
box-shadow: 0px 2rpx 7rpx 0px rgba(16, 122, 253, 0.05);
.card-left {
/* 加宽左侧保护不再折行 */
width: 132rpx;
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-right: 1px solid #E5EEFA;
/* 增大左右空隙 */
margin-right: 29rpx;
.clock-icon {
width: 31rpx;
height: 31rpx;
margin-bottom: 7rpx;
}
.date-md {
font-size: 36rpx;
font-weight: bold;
color: #107afd;
line-height: 1;
margin-bottom: 7rpx;
}
.date-year {
font-size: 24rpx;
color: #107afd;
line-height: 1;
}
}
.card-right {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
.card-title {
font-size: 38rpx;
font-weight: bold;
color: #333;
margin-bottom: 14rpx;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.card-infos {
display: flex;
flex-wrap: wrap;
.info-tag {
font-size: 29rpx;
color: #999;
margin-right: 14rpx;
}
}
}
}
/* #ifdef H5 */
.h5-pc-container {
& > view {
width: 100% !important;
margin: 0 auto !important;
padding-left: 32px !important;
padding-right: 32px !important;
padding-top: 0 !important; /* 彻底移除顶部补白 */
box-sizing: border-box !important;
}
.showtab {
margin-top: 0 !important; /* 移除卡片顶部间距 */
margin-bottom: 72rpx;
height: 204rpx;
.tabItem {
height: 204rpx !important;
image:first-child {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.activeImg {
width: 96rpx !important;
height: 12rpx !important;
bottom: -24rpx !important;
}
}
.tabs {
margin-bottom: 48rpx;
background-color: #eee;
border-radius: 60px;
padding: 10px;
.tab {
width: 33.3% !important;
line-height: 108rpx !important;
font-size: 36px !important;
border-radius: 60rpx;
}
}
.titles {
margin-top: 24rpx;
margin-bottom: 60px;
.title-item {
font-size: 40px;
font-weight: 600;
margin-right: 100px !important;
>view {
padding: 0 10rpx !important;
}
&::after {
height: 12rpx !important;
bottom: -16px !important;
width: 20% !important;
left: 40% !important;
background: orange;
border-radius: 0;
}
}
.more-link {
font-size: 20px !important;
color: #A2A2A2;
}
}
.job-list {
padding: 29rpx 24rpx !important;
margin-bottom: 19rpx !important;
border-radius: 14rpx !important;
border: 1px solid #f0f0f0;
box-shadow: 0px 1rpx 6rpx rgba(0, 0, 0, 0.02);
.sign {
font-size: 20px !important;
padding: 5rpx 12rpx !important;
}
}
.title {
font-size: 24px !important;
font-weight: 600;
margin-bottom: 14rpx !important;
}
.infos view {
font-size: 20px !important;
line-height: 1.5 !important;
padding: 6rpx 14rpx !important;
margin-bottom: 7rpx;
background: #f5f5f5 !important;
border-radius: 7rpx !important;
}
.salary {
font-size: 24px !important;
font-weight: 600;
}
.time {
font-size: 20px !important; /* 发布日期字号放大 */
}
.bottom-line {
font-size: 20px !important;
margin-top: 12rpx !important;
}
.view-more-btn {
font-size: 24px !important; /* 查看更多字号放大 */
padding: 12rpx 48rpx !important;
border-radius: 36rpx !important;
}
}
/* #endif */
</style>