Files
ks-app-employment-service/pages/careerfair/careerfair.vue

804 lines
19 KiB
Vue
Raw Normal View History

2024-11-08 11:55:23 +08:00
<template>
2025-11-05 17:21:01 +08:00
<view class="app-custom-root">
<view class="app-container">
<!-- 顶部头部区域 -->
<view class="container-header">
<view class="header-top">
<view class="header-btnLf button-click" @click="seemsg(1)" :class="{ active: state.current === 1 }">
线上招聘会
</view>
<view class="header-btnLf button-click" @click="seemsg(2)" :class="{ active: state.current === 2 }">
线下招聘会
</view>
<view class="header-btnLf button-click" @click="seemsg(3)" :class="{ active: state.current === 3 }">
我参与的
</view>
<view class="header-btnLf button-click" @click="navTo('/packageB/login')">
登录
</view>
</view>
<view class="header-input btn-feel">
<uni-icons class="iconsearch" color="#666666" type="search" size="18"
@click="getFair('refresh')"></uni-icons>
<input class="input" placeholder="招聘会" placeholder-class="inputplace"
v-model="pageState.jobFairTitle" />
</view>
</view>
<!-- 主体内容区域 -->
<view class="container-main">
<scroll-view scroll-y class="main-scroll" @scrolltolower="handleScrollToLower">
<view class="cards" v-if="fairList.length">
<view class="card press-button" v-for="(item, index) in fairList" :key="index"
@click="goDetail(item.jobFairId)">
<view class="card-title">
{{ item.jobFairTitle }}
<view class="center-date"
:style="{ color: getTimeStatus(item.jobFairStartTime, item.jobFairEndTime).color,borderColor: getTimeStatus(item.jobFairStartTime, item.jobFairEndTime).color }">
{{ getTimeStatus(item.jobFairStartTime, item.jobFairEndTime).statusText }}
</view>
</view>
<view class="card-row">
<text class="">{{ item.jobFairAddress }}</text>
</view>
<view class="card-times">
<view class="time-left">
<view class="left-date">
{{parseDateTime(item.jobFairStartTime).time}}
</view>
<view class="left-dateDay">
{{parseDateTime(item.jobFairStartTime).date}}
</view>
</view>
<view class="line"></view>
<view class="time-center">
<view class="center-dateDay">
{{getHoursBetween(item.jobFairStartTime,item.jobFairEndTime)}}小时
</view>
</view>
<view class="line"></view>
<view class="time-right">
<view class="left-date">
{{parseDateTime(item.jobFairEndTime).time}}
</view>
<view class="left-dateDay">
{{parseDateTime(item.jobFairEndTime).date}}
</view>
</view>
</view>
<view class="recommend-card-line"></view>
<view class="card-footer">内容简介{{ item.jobFairIntroduction || "暂无" }}</view>
</view>
</view>
<empty v-else pdTop="200"></empty>
</scroll-view>
</view>
<!-- 自定义tabbar -->
<CustomTabBar :currentPage="1" />
<!-- 微信授权登录弹窗 -->
<WxAuthLogin ref="wxAuthLoginRef" @success="handleLoginSuccess"></WxAuthLogin>
</view>
</view>
2024-11-08 11:55:23 +08:00
</template>
2024-11-18 16:33:37 +08:00
<script setup>
2025-11-05 17:21:01 +08:00
import {
reactive,
inject,
watch,
ref,
onMounted,
onUnmounted
} from "vue";
import {
onLoad,
onShow
} from "@dcloudio/uni-app";
import useLocationStore from "@/stores/useLocationStore";
import {
storeToRefs
} from "pinia";
import {
tabbarManager
} from "@/utils/tabbarManager";
import WxAuthLogin from "@/components/WxAuthLogin/WxAuthLogin.vue";
import config from "@/config.js";
const {
longitudeVal,
latitudeVal
} = storeToRefs(useLocationStore());
const wxAuthLoginRef = ref(null);
const {
$api,
navTo,
cloneDeep
} = inject("globalFunction");
const isLogin = ref(false);
const weekList = ref([]);
const fairList = ref([]);
const currentDay = ref({});
const userInfo = ref({});
const state = reactive({
current: 1,
all: [{}],
});
const pageState = reactive({
pageNum: 0,
total: 0,
maxPage: 2,
pageSize: 10,
jobFairTitle: "",
});
const baseUrl = config.imgBaseUrl;
onLoad(() => {
// const today = new Date();
// const year = today.getFullYear();
// const month = String(today.getMonth() + 1).padStart(2, '0');
// const day = String(today.getDate()).padStart(2, '0');
// const currentDate = `${year}-${month}-${day}`;
// const result = getNextDates({
// startDate: currentDate,
// });
// weekList.value = result;
getHeart();
});
onShow(() => {
// 更新自定义tabbar选中状态
tabbarManager.updateSelected(1);
});
onMounted(() => {
// 监听退出登录事件,显示微信登录弹窗
uni.$on("showLoginModal", () => {
wxAuthLoginRef.value?.open();
});
});
onUnmounted(() => {
uni.$off("showLoginModal");
});
// 登录成功回调
const handleLoginSuccess = () => {
console.log("登录成功");
// 可以在这里添加登录成功后的处理逻辑
};
2025-11-05 17:21:01 +08:00
function goDetail(jobFairId){
if(state.current != 3){
navTo('/packageA/pages/exhibitors/exhibitors?jobFairId=' + jobFairId)
}else{
console.log(userInfo.value, 'userInfo');
if(userInfo.value){
if(userInfo.value.userType=='ent'){
navTo('/packageB/jobFair/detailCom?jobFairId=' + jobFairId)
}else{
navTo('/packageB/jobFair/detailPerson?jobFairId=' + jobFairId)
}
}
2025-11-05 17:21:01 +08:00
}
}
function toSelectDate() {
navTo("/packageA/pages/selectDate/selectDate", {
query: {
date: currentDay.value.fullDate,
},
onBack: (res) => {
const result = getNextDates({
startDate: res.date,
});
const formattedDate = res.date.slice(5); // MM-DD
const dateFull = {
date: res.date.slice(5),
day: "周" + res.week,
fullDate: res.date,
};
currentDay.value = dateFull;
weekList.value = result;
getFair("refresh");
},
});
}
// 查看消息类型
function changeSwiperMsgType(e) {
const currented = e.detail.current;
state.current = currented;
}
function seemsg(index) {
state.current = index;
if (index != 3) {
getFair("refresh");
} else {
if (!isLogin.value) {
getHeart();
return;
}
// 确保获取到用户信息后再请求“我参与的”列表
if (!userInfo.value?.info?.userId) {
getUser().then(() => {
getMyFair("refresh");
});
} else {
getMyFair("refresh");
}
}
}
const handleScrollToLower = () => {
if (pageState.pageNum >= pageState.maxPage) {
return;
} else {
if (state.current != 3) {
getFair();
} else {
this.$nextTick(() => {
getMyFair();
});
}
}
};
function getHeart() {
const raw = uni.getStorageSync("Padmin-Token");
const token = typeof raw === "string" ? raw.trim() : "";
const headers = token ? {
Authorization: raw.startsWith("Bearer ") ? raw : `Bearer ${token}`
} : {};
$api.myRequest("/dashboard/auth/heart", {}, "POST", 10100, headers).then((resData) => {
if (resData.code == 200) {
isLogin.value = true;
getUser();
} else {
isLogin.value = false;
$api.msg('请先登录')
getFair("refresh");
}
});
}
function getUser() {
const raw = uni.getStorageSync("Padmin-Token");
const token = typeof raw === "string" ? raw.trim() : "";
const headers = token ? {
Authorization: raw.startsWith("Bearer ") ? raw : `Bearer ${token}`
} : {};
return $api.myRequest("/system/user/login/user/info", {}, "GET", 10100, headers).then((resData) => {
// 正确映射响应为用户信息(优先使用 data 字段)
const data = resData?.data ?? resData;
userInfo.value = data || {};
getFair("refresh");
return userInfo.value;
});
}
function getMyFair(type = "add") {
if (type === "refresh") {
pageState.pageNum = 1;
pageState.maxPage = 1;
}
if (type === "add" && pageState.pageNum < pageState.maxPage) {
pageState.pageNum += 1;
}
let params = {
pageNum: pageState.pageNum,
pageSize: pageState.pageSize,
jobFairTitle: pageState.jobFairTitle,
};
if (isLogin.value) {
console.log(userInfo, 'userInfo');
if (userInfo.value.userType == "ent") {
params.enterpriseId = userInfo.value.info.userId;
$api.myRequest("/jobfair/public/jobfair/enterprise/my-sign-up-job-fair", params).then((resData) => {
if (type === "add") {
const reslist = resData.data.list;
fairList.value = fairList.value.concat(reslist);
} else {
fairList.value = resData.data.list;
}
pageState.total = resData.data.total;
pageState.maxPage = resData.data.pages;
});
} else {
params.personId = userInfo.value.info.userId;
$api.myRequest("/jobfair/public/jobfair/person/my-sign-up-job-fair", params).then((resData) => {
if (type === "add") {
const reslist = resData.data.list;
fairList.value = fairList.value.concat(reslist);
} else {
fairList.value = resData.data.list;
}
pageState.total = resData.data.total;
pageState.maxPage = resData.data.pages;
});
}
console.log(params, 'params');
} else {
$api.msg('请先登录');
}
}
function getFair(type = "add") {
if (type === "refresh") {
pageState.pageNum = 1;
pageState.maxPage = 1;
}
if (type === "add" && pageState.pageNum < pageState.maxPage) {
pageState.pageNum += 1;
}
let params = {
pageNum: pageState.pageNum,
pageSize: pageState.pageSize,
jobFairTitle: pageState.jobFairTitle,
jobFairType: state.current,
};
if (isLogin.value) {
if (userInfo.value.userType == "ent") {
params.enterpriseId = userInfo.value.info.userId;
} else {
params.personId = userInfo.value.info.userId;
}
}
$api.myRequest("/jobfair/public/jobfair/page", params).then((resData) => {
if (type === "add") {
const reslist = resData.data.list;
fairList.value = fairList.value.concat(reslist);
} else {
fairList.value = resData.data.list;
}
pageState.total = resData.data.total;
pageState.maxPage = resData.data.pages;
});
}
function toIOSDate(input) {
if (!input) return null;
if (input instanceof Date) return isNaN(input.getTime()) ? null : input;
if (typeof input === "number") {
const d = new Date(input);
return isNaN(d.getTime()) ? null : d;
}
if (typeof input !== "string") return null;
let s = input.trim();
// "YYYY-MM-DD HH:mm[:ss]" -> "YYYY-MM-DDTHH:mm[:ss]"
if (/^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}(:\d{2})?$/.test(s)) {
s = s.replace(" ", "T");
// 仅到分钟则补秒
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(s)) {
s = s + ":00";
}
}
// 其余已是 iOS 可解析格式:"YYYY/MM/DD[ HH:mm:ss]"、"YYYY-MM-DD"、ISO 8601 等
const d = new Date(s);
return isNaN(d.getTime()) ? null : d;
}
function parseDateTime(datetimeStr) {
if (!datetimeStr)
return {
time: "",
date: "",
};
const dateObj = toIOSDate(datetimeStr);
if (!dateObj)
return {
time: "",
date: "",
}; // 无效时间
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(2, "0");
const day = String(dateObj.getDate()).padStart(2, "0");
const hours = String(dateObj.getHours()).padStart(2, "0");
const minutes = String(dateObj.getMinutes()).padStart(2, "0");
return {
time: `${hours}:${minutes}`,
date: `${year}${month}${day}`,
};
}
function getTimeStatus(startTimeStr, endTimeStr) {
const now = new Date();
const startTime = toIOSDate(startTimeStr);
const endTime = toIOSDate(endTimeStr);
if (!startTime || !endTime) {
return {
status: 1,
statusText: "时间异常",
color: "#999999"
};
}
// 判断状态0 开始中1 过期2 未开始
let status = 0;
let statusText = "开始中";
let color = "#13C57C"; // 进行中 - 绿色
if (now < startTime) {
status = 2; // 未开始
statusText = "未开始";
color = "#015EEA"; // 未开始 - 蓝色
} else if (now > endTime) {
status = 1; // 已过期
statusText = "已过期";
color = "#999999"; // 已过期 - 灰色
} else {
status = 0; // 进行中
statusText = "进行中";
color = "#13C57C"; // 进行中 - 绿色
}
return {
status, // 0: 进行中1: 已过期2: 未开始
statusText,
color
};
}
function getHoursBetween(startTimeStr, endTimeStr) {
const start = toIOSDate(startTimeStr);
const end = toIOSDate(endTimeStr);
if (!start || !end) return 0;
const diffMs = end - start;
const diffHours = diffMs / (1000 * 60 * 60);
return +diffHours.toFixed(2); // 保留 2 位小数
}
const selectDate = (item) => {
if (currentDay.value?.fullDate === item.fullDate) {
currentDay.value = {};
getFair("refresh");
return;
}
currentDay.value = item;
getFair("refresh");
};
function getNextDates({
startDate = "",
count = 6
}) {
const baseDate = startDate ? toIOSDate(startDate) || new Date() : new Date(); // 指定起点或今天
const dates = [];
const dayNames = ["日", "一", "二", "三", "四", "五", "六"];
for (let i = 0; i < count; i++) {
const date = new Date(baseDate);
date.setDate(baseDate.getDate() + i);
const fullDate = date.toISOString().slice(0, 10); // YYYY-MM-DD
const formattedDate = fullDate.slice(5); // MM-DD
const dayOfWeek = dayNames[date.getDay()];
dates.push({
date: formattedDate,
fullDate,
day: "周" + dayOfWeek,
});
}
// 可选设置默认选中项
// currentDay.value = dates[0];
return dates;
}
2024-11-08 11:55:23 +08:00
</script>
2025-11-03 15:08:39 +08:00
<style scoped lang="stylus">
2025-11-05 17:21:01 +08:00
.app-custom-root {
position: fixed;
z-index: 10;
width: 100vw;
height: calc(100% - var(--window-bottom));
overflow: hidden;
}
.app-container {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
.app-container .container-header {
background: url("@/static/icon/background2.png") 0 0 no-repeat;
background-size: 100% 400rpx;
}
.app-container .container-header .header-top {
display: flex;
line-height: calc(88rpx - 14rpx);
padding: 16rpx 44rpx 14rpx 44rpx;
}
.app-container .container-header .header-top .header-btnLf {
display: flex;
white-space: nowrap;
justify-content: flex-start;
align-items: center;
width: calc(60rpx * 3);
font-weight: 500;
font-size: 40rpx;
color: #696969;
margin-right: 44rpx;
position: relative;
}
.app-container .container-header .header-top .header-btnLf .btns-wd {
position: absolute;
top: 2rpx;
right: 2rpx;
width: 16rpx;
height: 16rpx;
background: #f73636;
border-radius: 50%;
border: 4rpx solid #eeeeff;
}
.app-container .container-header .header-top .active {
font-weight: 600;
font-size: 40rpx;
color: #000000;
}
.app-container .container-header .header-input {
padding: 0 24rpx;
width: calc(100% - 48rpx);
position: relative;
}
.app-container .container-header .header-input .iconsearch {
position: absolute;
left: 50rpx;
top: 50%;
transform: translate(0, -50%);
}
.app-container .container-header .header-input .input {
padding: 0 30rpx 0 80rpx;
height: 80rpx;
background: #ffffff;
border-radius: 75rpx;
font-size: 28rpx;
}
.app-container .container-header .header-input .inputplace {
font-weight: 400;
font-size: 28rpx;
color: #b5b5b5;
}
.app-container .container-header .header-date {
padding: 28rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.app-container .container-header .header-date .data-week {
flex: 1;
display: flex;
justify-content: space-between;
flex-wrap: nowrap;
overflow: hidden;
}
.app-container .container-header .header-date .data-week .weel-days {
font-family: "PingFangSC-Medium", "PingFang SC", "Helvetica Neue", Helvetica,
Arial, "Microsoft YaHei", sans-serif;
display: flex;
justify-content: center;
flex-direction: column;
text-align: center;
font-weight: 400;
font-size: 24rpx;
color: #333333;
width: 96rpx;
height: 88rpx;
}
.app-container .container-header .header-date .data-week .weel-days .day {
font-weight: 500;
}
.app-container .container-header .header-date .data-week .active {
background: rgba(37, 107, 250, 0.1);
border-radius: 12rpx;
color: #256bfa;
}
.app-container .container-header .header-date .data-all {
width: 66rpx;
height: 66rpx;
margin-left: 18rpx;
}
.app-container .container-header .header-date .data-all .allimg {
width: 100%;
height: 100%;
}
.container-main {
flex: 1;
overflow: hidden;
background-color: #f4f4f4;
}
.main-scroll {
width: 100%;
height: calc(100% - 150rpx);
}
.cards {
padding: 28rpx;
}
.cards .card {
margin-top: 28rpx;
padding: 32rpx;
background: linear-gradient(to bottom, #e3efff 0%, #fbfdff 100%);
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0, 0, 0, 0.04);
border-radius: 20rpx;
}
.cards .card-title {
font-family: "PingFangSC-Medium", "PingFang SC", "Helvetica Neue", Helvetica,
Arial, "Microsoft YaHei", sans-serif;
font-weight: 600;
font-size: 34rpx;
color: #005eb6;
text-align: center;
position relative;
display: flex;
align-items: center;
justify-content: center;
&::after {
content: "";
width: 120rpx;
height: 4rpx;
background: linear-gradient(to right, #015EEA 0%, #00C0FA 100%);
position: absolute;
left: 50%;
bottom: -14rpx;
transform: translate(-50%, -50%);
}
.center-date {
font-weight: 400;
font-size: 24rpx;
// position: absolute;
// right: 0;
// top: 0;
border: 1rpx solid;
padding: 5rpx 10rpx;
margin-left: 10rpx;
}
}
.cards .card-row {
display: flex;
justify-content: center;
font-size: 26rpx;
color: #3e8ff3;
margin-top: 23rpx;
}
.cards .card-times {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 24rpx;
}
.cards .card-times .time-left,
.cards .card-times .time-right {
text-align: center;
}
.cards .card-times .left-date {
font-weight: 600;
font-size: 48rpx;
font-family: "PingFangSC-Medium", "PingFang SC", "Helvetica Neue", Helvetica,
Arial, "Microsoft YaHei", sans-serif;
background: linear-gradient(180deg, #015EEA 0%, #00C0FA 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.cards .card-times .left-dateDay {
font-weight: 400;
font-size: 24rpx;
color: #333333;
margin-top: 12rpx;
}
.cards .card-times .line {
width: 40rpx;
height: 2rpx;
background: #7BB6FF;
margin-top: 7rpx;
}
.cards .card-times .time-center {
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.cards .card-times .time-center .center-dateDay {
font-weight: 400;
font-size: 24rpx;
color: #fff;
margin-top: 6rpx;
line-height: 48rpx;
width: max-content;
height: 48rpx;
background: #71B1FF;
border-radius: 8rpx;
padding: 0 30rpx;
}
.cards .recommend-card-line {
width: 100%;
height: 0;
border-radius: 0;
border-bottom: 2rpx dashed rgba(0, 0, 0, 0.14);
margin-top: 32rpx;
position: relative;
}
.cards .recommend-card-line::before {
content: "";
position: absolute;
left: 0;
top: 0;
transform: translate(-50%, -50%);
width: 28rpx;
height: 28rpx;
background: #f4f4f4;
border-radius: 50%;
}
.cards .recommend-card-line::after {
content: "";
position: absolute;
right: 0;
top: 0;
transform: translate(50%, -50%);
width: 28rpx;
height: 28rpx;
background: #f4f4f4;
border-radius: 50%;
}
.cards .card-footer {
margin-top: 32rpx;
min-height: 50rpx;
font-weight: 400;
font-size: 28rpx;
color: #6c7282;
text-align: center;
}
.cards .card:first-child {
margin-top: 0;
}
2024-11-08 11:55:23 +08:00
</style>