hookehuyr

新增预约日期选择页

/*
* @Date: 2023-06-13 13:26:46
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-01-15 13:09:12
* @LastEditTime: 2024-01-15 13:36:19
* @FilePath: /xysBooking/src/route.js
* @Description: 文件描述
*/
......@@ -21,6 +21,13 @@ export default [
},
},
{
path: '/booking',
component: () => import('@/views/booking.vue'),
meta: {
title: '预约',
},
},
{
path: '/auth',
component: () => import('@/views/auth.vue'),
meta: {
......
<!--
* @Date: 2024-01-15 13:35:51
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-01-15 16:22:20
* @FilePath: /xysBooking/src/views/booking.vue
* @Description: 预约页面
* @Version: 1.0.0
-->
<template>
<div class="booking-page">
<div class="calendar">
<div class="choose-date">
<div class="title">
<div class="text">选择参访日期</div>
<div class="day">01月</div>
</div>
<div class="days-of-week">
<div v-for="day in daysOfWeek" :key="day" class="item">{{ day }}</div>
</div>
<div v-for="(week, index) in weeks" :key="index" class="weeks">
<div v-for="date in week" :key="date"
@click="chooseDay(date)"
:class="['item', checked_day === findDatesInfo(date).date ? 'checked' : '', !findDatesInfo(date).num ? 'disabled' : '']"
>
<p class="day-text">{{ findDatesInfo(date).text }}</p>
<p v-if="findDatesInfo(date).num" class="day-price">¥{{ findDatesInfo(date).price }}</p>
<p v-else class="day-no-booking">已约满</p>
</div>
</div>
</div>
<div class="choose-time">
<div class="title">
<div class="text">选择参访时间段</div>
</div>
<div class="time-list">
<div @click="chooseTime(item, index)" v-for="(item, index) in timePeriod" :key="index" class="time">
<div class="left">
<van-icon v-if="checked_time !== index" name="https://cdn.ipadbiz.cn/xys/booking/%E5%8D%95%E9%80%8901@2x.png" />&nbsp;
<van-icon v-else name="https://cdn.ipadbiz.cn/xys/booking/%E5%8D%95%E9%80%8902@2x.png" />&nbsp;
{{ item.left }}
</div>
<div class="right">余量:{{ item.right }}</div>
</div>
</div>
</div>
</div>
<div style="height: 5rem;"></div>
<div class="next">
<div class="button" style="background-color: #A67939;">下一步</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);
const dates = ref([
"2024-01-01",
"2024-01-02",
"2024-01-03",
"2024-01-04",
"2024-01-05",
"2024-01-06",
"2024-01-07",
"2024-01-08",
"2024-01-09",
]);
const dates_list = ref([{
date: "2024-01-01",
price: 5,
num: 0,
}, {
date: "2024-01-02",
price: 5,
num: 0,
}, {
date: "2024-01-03",
price: 5,
num: 1,
}, {
date: "2024-01-04",
price: 5,
num: 1,
}, {
date: "2024-01-05",
price: 5,
num: 1,
}, {
date: "2024-01-06",
price: 5,
num: 1,
}, {
date: "2024-01-07",
price: 5,
num: 1,
}, {
date: "2024-01-08",
price: 5,
num: 1,
}, {
date: "2024-01-09",
price: 5,
num: 1,
}]);
const findDatesInfo = (date) => {
const result = dates_list.value.find((item) => item.date === date);
const currentDate = new Date(date);
return {
text: currentDate.getDate().toString().padStart(2, '0'),
date: result.date,
price: result.price,
num: result.num,
};
};
const daysOfWeek = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
const weeks = computed(() => {
const result = [];
let currentWeek = [];
let currentDate = new Date(dates.value[0]);
// 确定第一个日期是星期几
const firstDayOfWeek = currentDate.getDay() === 0 ? 7 : currentDate.getDay();
// 添加空白的日期,直到第一个日期的星期一
for (let i = 1; i < firstDayOfWeek; i++) {
currentWeek.push('');
}
// 添加日期
for (const date of dates.value) {
currentDate = new Date(date);
const dayOfWeek = currentDate.getDay() === 0 ? 7 : currentDate.getDay();
// 如果当前星期一,开始新的一行
if (dayOfWeek === 1 && currentWeek.length > 0) {
result.push(currentWeek);
currentWeek = [];
}
// currentWeek.push(currentDate.getDate()); // 仅将日期部分作为字符串添加到当前星期数组
currentWeek.push(date); // 仅将日期部分作为字符串添加到当前星期数组
}
// 添加最后一行
if (currentWeek.length > 0) {
result.push(currentWeek);
}
return result;
});
const checked_day = ref('');
const checked_time = ref(-1);
const timePeriod = ref([{
left: '05:00-08:00',
right: 1098,
}, {
left: '05:00-08:00',
right: 1098,
}, {
left: '05:00-08:00',
right: 1098,
},{
left: '05:00-08:00',
right: 1098,
}, {
left: '05:00-08:00',
right: 1098,
}, {
left: '05:00-08:00',
right: 1098,
}, {
left: '05:00-08:00',
right: 1098,
},]);
const chooseTime = (item, index) => {
checked_time.value = index;
console.log(item, index);
};
const chooseDay = (date) => {
checked_day.value = date;
console.log(date);
};
</script>
<style lang="less" scoped>
.booking-page {
position: relative;
.calendar {
padding: 1rem 0.5rem;
.choose-date {
border-radius: 5px;
background-color: #FFFFFF;
.title {
padding: 0.5rem 0.75rem;
display: flex;
justify-content: space-between;
align-items: center;
.text {
&::before {
content: '';
border: 2px solid #A67939;
margin-right: 0.5rem;
}
}
.day {
background-color: #FFFBF3;
border-radius: 7px;
border: 1px solid #A67939;
padding: 0.2rem 0.5rem;
color: #A67939;
}
}
.days-of-week {
background-color: #EAEAEA;
display: flex;
padding: 0.75em 1%;
font-size: 0.85rem;
.item {
width: 14.5%;
text-align: center;
}
}
.weeks {
display: flex;
padding: 0.5em 1%;
.item {
width: 11%;
text-align: center;
margin: 0 0.3rem;
padding: 0.5rem 0;
.day-text {
color: #1E1E1E;
font-weight: bold;
font-size: 1.05rem;
}
.day-price {
color: #A67939;
font-size: 0.85rem;
}
&.checked {
border: 1px solid #A67939;
border-radius: 5px;
background-color: #FFFBF3;
}
&.disabled {
.day-text {
color: #C7C7C7;
}
.day-price {
color: #C7C7C7;
}
.day-no-booking {
color: #C7C7C7;
font-size: 0.75rem;
}
}
}
}
}
.choose-time {
margin-top: 1rem;
.title {
padding: 0.5rem 0.75rem;
display: flex;
justify-content: space-between;
align-items: center;
.text {
&::before {
content: '';
border: 2px solid #A67939;
margin-right: 0.5rem;
}
}
}
.time-list {
.time {
display: flex;
align-items: center;
justify-content: space-between;
background-color: #FFF;
border-radius: 5px;
padding: 0.85rem;
margin: 1rem 0;
.left {
display: flex;
align-items: center;
color: #1E1E1E;
}
.right {
color: #A67939;
}
}
}
}
}
.next {
position: fixed;
bottom: 0;
height: 5rem;
width: 100vw;
display: flex;
left: 0;
background-color: #FFF;
align-items: center;
justify-content: center;
box-shadow: 0rem -0.33rem 0.25rem 0rem rgba(0,0,0,0.12);
.button {
color: #FFF;
padding: 0.85rem 8rem;
border-radius: 8px;
}
}
}
</style>