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:29:17 +08:00
|
|
|
|
|
2025-11-05 17:21:01 +08:00
|
|
|
|
function goDetail(jobFairId){
|
|
|
|
|
|
if(state.current != 3){
|
|
|
|
|
|
navTo('/packageA/pages/exhibitors/exhibitors?jobFairId=' + jobFairId)
|
|
|
|
|
|
}else{
|
2025-11-06 17:14:14 +08:00
|
|
|
|
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>
|