hookehuyr

新增预约日期选择页

1 /* 1 /*
2 * @Date: 2023-06-13 13:26:46 2 * @Date: 2023-06-13 13:26:46
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2024-01-15 13:09:12 4 + * @LastEditTime: 2024-01-15 13:36:19
5 * @FilePath: /xysBooking/src/route.js 5 * @FilePath: /xysBooking/src/route.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -21,6 +21,13 @@ export default [ ...@@ -21,6 +21,13 @@ export default [
21 }, 21 },
22 }, 22 },
23 { 23 {
24 + path: '/booking',
25 + component: () => import('@/views/booking.vue'),
26 + meta: {
27 + title: '预约',
28 + },
29 + },
30 + {
24 path: '/auth', 31 path: '/auth',
25 component: () => import('@/views/auth.vue'), 32 component: () => import('@/views/auth.vue'),
26 meta: { 33 meta: {
......
1 +<!--
2 + * @Date: 2024-01-15 13:35:51
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-01-15 16:22:20
5 + * @FilePath: /xysBooking/src/views/booking.vue
6 + * @Description: 预约页面
7 + * @Version: 1.0.0
8 +-->
9 +<template>
10 + <div class="booking-page">
11 + <div class="calendar">
12 + <div class="choose-date">
13 + <div class="title">
14 + <div class="text">选择参访日期</div>
15 + <div class="day">01月</div>
16 + </div>
17 + <div class="days-of-week">
18 + <div v-for="day in daysOfWeek" :key="day" class="item">{{ day }}</div>
19 + </div>
20 + <div v-for="(week, index) in weeks" :key="index" class="weeks">
21 + <div v-for="date in week" :key="date"
22 + @click="chooseDay(date)"
23 + :class="['item', checked_day === findDatesInfo(date).date ? 'checked' : '', !findDatesInfo(date).num ? 'disabled' : '']"
24 + >
25 + <p class="day-text">{{ findDatesInfo(date).text }}</p>
26 + <p v-if="findDatesInfo(date).num" class="day-price">¥{{ findDatesInfo(date).price }}</p>
27 + <p v-else class="day-no-booking">已约满</p>
28 + </div>
29 + </div>
30 + </div>
31 + <div class="choose-time">
32 + <div class="title">
33 + <div class="text">选择参访时间段</div>
34 + </div>
35 + <div class="time-list">
36 + <div @click="chooseTime(item, index)" v-for="(item, index) in timePeriod" :key="index" class="time">
37 + <div class="left">
38 + <van-icon v-if="checked_time !== index" name="https://cdn.ipadbiz.cn/xys/booking/%E5%8D%95%E9%80%8901@2x.png" />&nbsp;
39 + <van-icon v-else name="https://cdn.ipadbiz.cn/xys/booking/%E5%8D%95%E9%80%8902@2x.png" />&nbsp;
40 + {{ item.left }}
41 + </div>
42 + <div class="right">余量:{{ item.right }}</div>
43 + </div>
44 + </div>
45 + </div>
46 + </div>
47 + <div style="height: 5rem;"></div>
48 + <div class="next">
49 + <div class="button" style="background-color: #A67939;">下一步</div>
50 + </div>
51 + </div>
52 +</template>
53 +
54 +<script setup>
55 +import { ref } from 'vue'
56 +import { useRoute, useRouter } from 'vue-router'
57 +
58 +import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
59 +//import { } from '@/utils/generateModules.js'
60 +//import { } from '@/utils/generateIcons.js'
61 +//import { } from '@/composables'
62 +const $route = useRoute();
63 +const $router = useRouter();
64 +useTitle($route.meta.title);
65 +
66 +const dates = ref([
67 + "2024-01-01",
68 + "2024-01-02",
69 + "2024-01-03",
70 + "2024-01-04",
71 + "2024-01-05",
72 + "2024-01-06",
73 + "2024-01-07",
74 + "2024-01-08",
75 + "2024-01-09",
76 +]);
77 +
78 +const dates_list = ref([{
79 + date: "2024-01-01",
80 + price: 5,
81 + num: 0,
82 +}, {
83 + date: "2024-01-02",
84 + price: 5,
85 + num: 0,
86 +}, {
87 + date: "2024-01-03",
88 + price: 5,
89 + num: 1,
90 +}, {
91 + date: "2024-01-04",
92 + price: 5,
93 + num: 1,
94 +}, {
95 + date: "2024-01-05",
96 + price: 5,
97 + num: 1,
98 +}, {
99 + date: "2024-01-06",
100 + price: 5,
101 + num: 1,
102 +}, {
103 + date: "2024-01-07",
104 + price: 5,
105 + num: 1,
106 +}, {
107 + date: "2024-01-08",
108 + price: 5,
109 + num: 1,
110 +}, {
111 + date: "2024-01-09",
112 + price: 5,
113 + num: 1,
114 +}]);
115 +
116 +const findDatesInfo = (date) => {
117 + const result = dates_list.value.find((item) => item.date === date);
118 + const currentDate = new Date(date);
119 + return {
120 + text: currentDate.getDate().toString().padStart(2, '0'),
121 + date: result.date,
122 + price: result.price,
123 + num: result.num,
124 + };
125 +};
126 +
127 +const daysOfWeek = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
128 +
129 +const weeks = computed(() => {
130 + const result = [];
131 + let currentWeek = [];
132 + let currentDate = new Date(dates.value[0]);
133 +
134 + // 确定第一个日期是星期几
135 + const firstDayOfWeek = currentDate.getDay() === 0 ? 7 : currentDate.getDay();
136 +
137 + // 添加空白的日期,直到第一个日期的星期一
138 + for (let i = 1; i < firstDayOfWeek; i++) {
139 + currentWeek.push('');
140 + }
141 +
142 + // 添加日期
143 + for (const date of dates.value) {
144 + currentDate = new Date(date);
145 + const dayOfWeek = currentDate.getDay() === 0 ? 7 : currentDate.getDay();
146 +
147 + // 如果当前星期一,开始新的一行
148 + if (dayOfWeek === 1 && currentWeek.length > 0) {
149 + result.push(currentWeek);
150 + currentWeek = [];
151 + }
152 +
153 + // currentWeek.push(currentDate.getDate()); // 仅将日期部分作为字符串添加到当前星期数组
154 + currentWeek.push(date); // 仅将日期部分作为字符串添加到当前星期数组
155 + }
156 +
157 + // 添加最后一行
158 + if (currentWeek.length > 0) {
159 + result.push(currentWeek);
160 + }
161 +
162 + return result;
163 +});
164 +
165 +const checked_day = ref('');
166 +
167 +const checked_time = ref(-1);
168 +const timePeriod = ref([{
169 + left: '05:00-08:00',
170 + right: 1098,
171 +}, {
172 + left: '05:00-08:00',
173 + right: 1098,
174 +}, {
175 + left: '05:00-08:00',
176 + right: 1098,
177 +},{
178 + left: '05:00-08:00',
179 + right: 1098,
180 +}, {
181 + left: '05:00-08:00',
182 + right: 1098,
183 +}, {
184 + left: '05:00-08:00',
185 + right: 1098,
186 +}, {
187 + left: '05:00-08:00',
188 + right: 1098,
189 +},]);
190 +
191 +const chooseTime = (item, index) => {
192 + checked_time.value = index;
193 + console.log(item, index);
194 +};
195 +
196 +const chooseDay = (date) => {
197 + checked_day.value = date;
198 + console.log(date);
199 +};
200 +</script>
201 +
202 +<style lang="less" scoped>
203 +.booking-page {
204 + position: relative;
205 + .calendar {
206 + padding: 1rem 0.5rem;
207 + .choose-date {
208 + border-radius: 5px;
209 + background-color: #FFFFFF;
210 + .title {
211 + padding: 0.5rem 0.75rem;
212 + display: flex;
213 + justify-content: space-between;
214 + align-items: center;
215 + .text {
216 + &::before {
217 + content: '';
218 + border: 2px solid #A67939;
219 + margin-right: 0.5rem;
220 + }
221 + }
222 + .day {
223 + background-color: #FFFBF3;
224 + border-radius: 7px;
225 + border: 1px solid #A67939;
226 + padding: 0.2rem 0.5rem;
227 + color: #A67939;
228 + }
229 + }
230 + .days-of-week {
231 + background-color: #EAEAEA;
232 + display: flex;
233 + padding: 0.75em 1%;
234 + font-size: 0.85rem;
235 + .item {
236 + width: 14.5%;
237 + text-align: center;
238 + }
239 + }
240 + .weeks {
241 + display: flex;
242 + padding: 0.5em 1%;
243 + .item {
244 + width: 11%;
245 + text-align: center;
246 + margin: 0 0.3rem;
247 + padding: 0.5rem 0;
248 + .day-text {
249 + color: #1E1E1E;
250 + font-weight: bold;
251 + font-size: 1.05rem;
252 + }
253 + .day-price {
254 + color: #A67939;
255 + font-size: 0.85rem;
256 + }
257 + &.checked {
258 + border: 1px solid #A67939;
259 + border-radius: 5px;
260 + background-color: #FFFBF3;
261 + }
262 + &.disabled {
263 + .day-text {
264 + color: #C7C7C7;
265 + }
266 + .day-price {
267 + color: #C7C7C7;
268 + }
269 + .day-no-booking {
270 + color: #C7C7C7;
271 + font-size: 0.75rem;
272 + }
273 + }
274 + }
275 + }
276 + }
277 + .choose-time {
278 + margin-top: 1rem;
279 + .title {
280 + padding: 0.5rem 0.75rem;
281 + display: flex;
282 + justify-content: space-between;
283 + align-items: center;
284 + .text {
285 + &::before {
286 + content: '';
287 + border: 2px solid #A67939;
288 + margin-right: 0.5rem;
289 + }
290 + }
291 + }
292 + .time-list {
293 + .time {
294 + display: flex;
295 + align-items: center;
296 + justify-content: space-between;
297 + background-color: #FFF;
298 + border-radius: 5px;
299 + padding: 0.85rem;
300 + margin: 1rem 0;
301 + .left {
302 + display: flex;
303 + align-items: center;
304 + color: #1E1E1E;
305 + }
306 + .right {
307 + color: #A67939;
308 + }
309 + }
310 + }
311 + }
312 + }
313 + .next {
314 + position: fixed;
315 + bottom: 0;
316 + height: 5rem;
317 + width: 100vw;
318 + display: flex;
319 + left: 0;
320 + background-color: #FFF;
321 + align-items: center;
322 + justify-content: center;
323 + box-shadow: 0rem -0.33rem 0.25rem 0rem rgba(0,0,0,0.12);
324 + .button {
325 + color: #FFF;
326 + padding: 0.85rem 8rem;
327 + border-radius: 8px;
328 + }
329 + }
330 +}
331 +</style>