Files
ks-app-employment-service/packageA/pages/exhibitors/exhibitors.vue
2025-07-14 15:38:39 +08:00

542 lines
16 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>
<AppLayout title="" :use-scroll-view="false">
<template #headerleft>
<view class="btnback">
<image src="@/static/icon/back.png" @click="navBack"></image>
</view>
</template>
<view class="content">
<view class="content-top">
<view class="companyinfo-left">
<image src="@/static/icon/companyIcon.png" mode=""></image>
</view>
<view class="companyinfo-right">
<view class="row1 line_2">{{ fairInfo?.name }}</view>
<view class="row2">
<text>{{ fairInfo.location }}</text>
<convert-distance
:alat="fairInfo.latitude"
:along="fairInfo.longitude"
:blat="latitudeVal"
:blong="longitudeVal"
></convert-distance>
</view>
</view>
</view>
<view class="locations">
<image class="location-img" src="/static/icon/mapLine.png"></image>
<view class="location-info">
<view class="info">
<text class="info-title">{{ fairInfo.address }}</text>
<text class="info-text">位置</text>
</view>
</view>
</view>
<view class="conetent-info" :class="{ expanded: isExpanded }">
<view class="info-title">内容描述</view>
<view class="info-desirption">{{ fairInfo.description }}</view>
<!-- <view class="info-title title2">公司地址</view>
<view class="locationCompany"></view> -->
<view class="company-times">
<view class="info-title">内容描述</view>
<view class="card-times">
<view class="time-left">
<view class="left-date">{{ parseDateTime(fairInfo.startTime).time }}</view>
<view class="left-dateDay">{{ parseDateTime(fairInfo.startTime).date }}</view>
</view>
<view class="line"></view>
<view class="time-center">
<view class="center-date">
{{ getTimeStatus(fairInfo.startTime, fairInfo.endTime).statusText }}
</view>
<view class="center-dateDay">
{{ getHoursBetween(fairInfo.startTime, fairInfo.endTime) }}小时
</view>
</view>
<view class="line"></view>
<view class="time-right">
<view class="left-date">{{ parseDateTime(fairInfo.endTime).time }}</view>
<view class="left-dateDay">{{ parseDateTime(fairInfo.endTime).date }}</view>
</view>
</view>
</view>
</view>
<view class="expand" @click="expand">
<text>{{ isExpanded ? '收起' : '展开' }}</text>
<image
class="expand-img"
:class="{ 'expand-img-active': !isExpanded }"
src="@/static/icon/downs.png"
></image>
</view>
<scroll-view scroll-y class="Detailscroll-view">
<view class="views">
<view class="Detail-title">
<text class="title">参会单位{{ companyList.length }}</text>
</view>
<renderCompanys
v-if="companyList.length"
:list="companyList"
:longitude="longitudeVal"
:latitude="latitudeVal"
></renderCompanys>
<empty v-else pdTop="200"></empty>
</view>
</scroll-view>
</view>
<template #footer>
<view class="footer" v-if="hasnext">
<view
class="btn-wq button-click"
:class="{ 'btn-desbel': fairInfo.isCollection }"
@click="applyExhibitors"
>
{{ fairInfo.isCollection ? '已预约招聘会' : '预约招聘会' }}
</view>
</view>
</template>
</AppLayout>
</template>
<script setup>
import point from '@/static/icon/point.png';
import { reactive, inject, watch, ref, onMounted, computed } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import dictLabel from '@/components/dict-Label/dict-Label.vue';
import useLocationStore from '@/stores/useLocationStore';
const { $api, navTo, vacanciesTo, navBack } = inject('globalFunction');
import { storeToRefs } from 'pinia';
const { longitudeVal, latitudeVal } = storeToRefs(useLocationStore());
const isExpanded = ref(false);
const fairInfo = ref({});
const companyList = ref([]);
const hasnext = ref(true);
onLoad((options) => {
getCompanyInfo(options.jobFairId);
});
function getCompanyInfo(id) {
$api.createRequest(`/app/fair/${id}`).then((resData) => {
fairInfo.value = resData.data;
companyList.value = resData.data.companyList;
hasAppointment();
});
}
const hasAppointment = () => {
const isTimePassed = (timeStr) => {
const targetTime = new Date(timeStr.replace(/-/g, '/')).getTime(); // 兼容格式
const now = Date.now();
return now < targetTime;
};
hasnext.value = isTimePassed(fairInfo.value.startTime);
};
function openMap(lat, lng, name = '位置') {
const isConfirmed = window.confirm('是否打开地图查看位置?');
if (!isConfirmed) return;
// 使用高德地图或百度地图的 H5 链接打开
const url = `https://uri.amap.com/marker?position=${lng},${lat}&name=${encodeURIComponent(name)}`;
window.location.href = url;
}
function expand() {
isExpanded.value = !isExpanded.value;
}
// 取消/收藏岗位
function applyExhibitors() {
const fairId = fairInfo.value.jobFairId;
if (fairInfo.value.isCollection) {
// $api.createRequest(`/app/fair/collection/${fairId}`, {}, 'DELETE').then((resData) => {
// getCompanyInfo(fairId);
// $api.msg('取消预约成功');
// });
$api.msg('已预约成功');
} else {
$api.createRequest(`/app/fair/collection/${fairId}`, {}, 'POST').then((resData) => {
getCompanyInfo(fairId);
$api.msg('预约成功');
});
}
}
function parseDateTime(datetimeStr) {
if (!datetimeStr) return { time: '', date: '' };
const dateObj = new Date(datetimeStr);
if (isNaN(dateObj.getTime())) 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 = new Date(startTimeStr);
const endTime = new Date(endTimeStr);
// 判断状态0 开始中1 过期2 待开始
let status = 0;
let statusText = '开始中';
if (now < startTime) {
status = 2; // 待开始
statusText = '待开始';
} else if (now > endTime) {
status = 1; // 已过期
statusText = '已过期';
} else {
status = 0; // 进行中
statusText = '进行中';
}
return {
status, // 0: 进行中1: 已过期2: 待开始
statusText,
};
}
function getHoursBetween(startTimeStr, endTimeStr) {
const start = new Date(startTimeStr);
const end = new Date(endTimeStr);
const diffMs = end - start;
const diffHours = diffMs / (1000 * 60 * 60);
return +diffHours.toFixed(2); // 保留 2 位小数
}
</script>
<style lang="stylus" scoped>
.btnback{
width: 64rpx;
height: 64rpx;
}
.btn {
display: flex;
justify-content: space-between;
align-items: center;
width: 52rpx;
height: 52rpx;
}
image {
height: 100%;
width: 100%;
}
.content{
height: 100%
display: flex;
flex-direction: column
.content-top{
padding: 28rpx
padding-top: 50rpx
display: flex
flex-direction: row
flex-wrap: nowrap
.companyinfo-left{
width: 96rpx;
height: 96rpx;
margin-right: 24rpx
}
.companyinfo-right{
flex: 1
.row1{
font-weight: 500;
font-size: 32rpx;
color: #333333;
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
}
.row2{
font-weight: 400;
font-size: 28rpx;
color: #6C7282;
line-height: 45rpx;
display: flex
justify-content: space-between
}
}
}
.locations{
padding: 0 28rpx
height: 86rpx;
position: relative
margin-bottom: 36rpx
.location-img{
border-radius: 8rpx 8rpx 8rpx 8rpx;
border: 2rpx solid #EFEFEF;
}
.location-info{
position: absolute
top: 0
left: 0
width: 100%
height: 100%
.info{
padding: 0 60rpx
height: 100%
display: flex
align-items: center
justify-content: space-between
white-space: nowrap
padding-top: rpx
.info-title{
font-weight: 600;
font-size: 28rpx;
color: #333333;
}
.info-text{
font-weight: 400;
font-size: 28rpx;
color: #9B9B9B;
position: relative;
padding-right: 20rpx
}
.info-text::before{
position: absolute;
right: 0;
top: 50%;
content: '';
width: 4rpx;
height: 16rpx;
border-radius: 2rpx
background: #9B9B9B;
transform: translate(0, -75%) rotate(-45deg)
}
.info-text::after {
position: absolute;
right: 0;
top: 50%;
content: '';
width: 4rpx;
height: 16rpx;
border-radius: 2rpx
background: #9B9B9B;
transform: translate(0, -25%) rotate(45deg)
}
}
}
}
.conetent-info{
padding: 0 28rpx
overflow: hidden;
max-height: 0rpx;
transition: max-height 0.3s ease;
.info-title{
font-weight: 600;
font-size: 28rpx;
color: #000000;
}
.info-desirption{
margin-top: 12rpx
font-weight: 400;
font-size: 28rpx;
color: #495265;
text-align: justified;
}
.title2{
margin-top: 48rpx
}
}
.company-times{
padding-top: 40rpx
.info-title{
font-weight: 600;
font-size: 28rpx;
color: #000000;
}
}
.expanded {
max-height: 1000rpx; // 足够显示完整内容
}
.expand{
display: flex
flex-wrap: nowrap
white-space: nowrap
justify-content: center
margin-bottom: 46rpx
font-weight: 400;
font-size: 28rpx;
color: #256BFA;
.expand-img{
width: 40rpx;
height: 40rpx;
}
.expand-img-active{
transform: rotate(180deg)
}
}
}
.Detailscroll-view{
flex: 1;
overflow: hidden;
background: #F4F4F4;
.views{
padding: 28rpx
.Detail-title{
font-weight: 600;
font-size: 32rpx;
color: #000000;
position: relative;
display: flex
justify-content: space-between
.title{
position: relative;
z-index: 2;
}
}
.Detail-title::before{
position: absolute
content: '';
left: -14rpx
bottom: 0
height: 16rpx;
width: 108rpx;
background: linear-gradient(to right, #CBDEFF, #FFFFFF);
border-radius: 8rpx;
z-index: 1;
}
.cards{
padding: 32rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 8rpx 0rpx rgba(0,0,0,0.04);
border-radius: 20rpx 20rpx 20rpx 20rpx;
margin-top: 22rpx;
.card-company{
display: flex
justify-content: space-between
align-items: flex-start
.company{
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
.salary{
font-weight: 500;
font-size: 28rpx;
color: #4C6EFB;
white-space: nowrap
line-height: 48rpx
}
}
.card-companyName{
font-weight: 400;
font-size: 28rpx;
color: #6C7282;
}
.card-tags{
display: flex
flex-wrap: wrap
.tag{
width: fit-content;
height: 30rpx;
background: #F4F4F4;
border-radius: 4rpx;
padding: 6rpx 20rpx;
line-height: 30rpx;
font-weight: 400;
font-size: 24rpx;
color: #6C7282;
text-align: center;
margin-top: 14rpx;
white-space: nowrap
margin-right: 20rpx
}
}
.card-bottom{
margin-top: 32rpx
display: flex
justify-content: space-between
font-size: 28rpx;
color: #6C7282;
}
}
}
}
.card-times{
display: flex;
justify-content: space-between
align-items: center
padding: 24rpx 30rpx 10rpx 30rpx
.time-left,
.time-right{
text-align: center
.left-date{
font-weight: 500;
font-size: 48rpx;
color: #333333;
}
.left-dateDay{
font-weight: 400;
font-size: 24rpx;
color: #333333;
margin-top: 12rpx
}
}
.line{
width: 40rpx;
height: 0rpx;
border: 2rpx solid #D4D4D4;
margin-top: 64rpx
}
.time-center{
text-align: center;
display: flex
flex-direction: column
justify-content: center
align-items: center
.center-date{
font-weight: 400;
font-size: 28rpx;
color: #FF881A;
padding-top: 10rpx
}
.center-dateDay{
font-weight: 400;
font-size: 24rpx;
color: #333333;
margin-top: 6rpx
line-height: 48rpx;
width: 104rpx;
height: 48rpx;
background: #F9F9F9;
border-radius: 8rpx 8rpx 8rpx 8rpx;
}
}
}
.footer{
background: #FFFFFF;
box-shadow: 0rpx -4rpx 24rpx 0rpx rgba(11,44,112,0.12);
border-radius: 0rpx 0rpx 0rpx 0rpx;
padding: 40rpx 28rpx 20rpx 28rpx
.btn-wq{
height: 90rpx;
background: #256BFA;
border-radius: 12rpx 12rpx 12rpx 12rpx;
font-weight: 500;
font-size: 32rpx;
color: #FFFFFF;
text-align: center;
line-height: 90rpx
}
.btn-desbel{
background: #6697FB;
box-shadow: 0rpx -4rpx 24rpx 0rpx rgba(11,44,112,0.12);
}
}
</style>