Files
xiuhuwangqiu/components/reserve-time.vue
2025-12-30 18:17:28 +08:00

246 lines
9.2 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>
<view style="position: relative;">
<view class="uni-padding-wrap">
<view class="" style="font-size: 36rpx; line-height: 50rpx; color: #121212; text-align: center;width: 100%;margin-top: 52rpx;">选择时间</view>
<image src="@/static/icon/close2.png" style="width: 60rpx;height: 60rpx; position: absolute; top: 30rpx; right: 30rpx;" @click="closePopup"/>
</view>
<picker-view v-if="visible" :indicator-style="indicatorStyle" :value="value" @change="bindChange" class="picker-view">
<picker-view-column>
<view class="item" v-for="(item,index) in dateList" :key="index">{{item.label}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in hourList" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in minuteList" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
<view class="line"></view>
<view class="btn">
<view class="btn1" @click="reset">重置</view>
<view class="btn2" @click="confirm">确定</view>
</view>
</view>
</template>
<script>
export default {
data: function () {
const date = new Date();
const weekMap = ['日', '一', '二', '三', '四', '五', '六'];
// 生成今天起未来7天若当天已过22:00则不加入当天
const dateList = [];
for (let i = 0; i < 3; i++) {
const d = new Date(date.getFullYear(), date.getMonth(), date.getDate() + i);
// 判断当天是否已过22:00
if (i === 0) {
const now = new Date();
if (now.getFullYear() === d.getFullYear() && now.getMonth() === d.getMonth() && now.getDate() === d.getDate()) {
if (now.getHours() > 21 || (now.getHours() === 21 && now.getMinutes() >= 60)) {
continue; // 跳过当天
}
}
}
const mm = (d.getMonth() + 1).toString().padStart(2, '0');
const dd = d.getDate().toString().padStart(2, '0');
const week = weekMap[d.getDay()];
dateList.push({
label: `${mm}${dd}日周${week}`,
date: d
});
}
// 默认选中今天、当前小时、当前分钟
return {
title: 'picker-view',
dateList,
hourList: [],
minuteList: [],
value: [0, 0, 0],
visible: true,
indicatorStyle: `height: 50px;`
}
},
mounted() {
this.updateHourAndMinuteList(0, 0);
},
methods: {
bindChange: function (e) {
const val = e.detail.value;
// 选中项索引分别为dateList、hourList、minuteList
this.value = val;
// 联动更新小时和分钟
this.updateHourAndMinuteList(val[0], val[1]);
},
// 联动生成小时和分钟列表
updateHourAndMinuteList(dateIdx, hourIdx) {
const now = new Date();
const selectedDate = this.dateList[dateIdx]?.date;
let hourList = [];
let minuteList = [];
// 判断是否为今天
const isToday = selectedDate &&
selectedDate.getFullYear() === now.getFullYear() &&
selectedDate.getMonth() === now.getMonth() &&
selectedDate.getDate() === now.getDate();
if (isToday) {
// 如果当前时间已超过 22:00则不显示任何可选时间
if (now.getHours() > 21 || (now.getHours() === 21 && now.getMinutes() >= 60)) {
hourList = [];
minuteList = [];
} else {
for (let i = 6; i <= 21; i++) {
if (i > now.getHours()) {
hourList.push(i < 10 ? `0${i}` : `${i}`);
} else if (i === now.getHours()) {
// 当前小时,分钟要过滤
let hasValidMinute = false;
for (let m = 0; m < 60; m += 10) {
if (m >= now.getMinutes()) {
hasValidMinute = true;
break;
}
}
if (hasValidMinute) {
hourList.push(i < 10 ? `0${i}` : `${i}`);
}
}
}
}
} else {
for (let i = 6; i <= 21; i++) {
hourList.push(i < 10 ? `0${i}` : `${i}`);
}
}
// 选中的小时
let selectedHour = hourList[hourIdx] ? parseInt(hourList[hourIdx]) : parseInt(hourList[0]);
if (isToday && hourList.length > 0 && selectedHour === now.getHours()) {
for (let m = 0; m < 60; m += 10) {
if (m >= now.getMinutes()) {
minuteList.push(m < 10 ? `0${m}` : `${m}`);
}
}
} else if (hourList.length > 0) {
for (let m = 0; m < 60; m += 10) {
minuteList.push(m < 10 ? `0${m}` : `${m}`);
}
} else {
minuteList = [];
}
// 修正value
let value = [...this.value];
// hourIdx/minuteIdx 越界修正
if (value[1] >= hourList.length) value[1] = 0;
if (value[2] >= minuteList.length) value[2] = 0;
this.hourList = hourList;
this.minuteList = minuteList;
this.value = [dateIdx, value[1], value[2]];
},
// 重置
reset: function () {
// 重置为今天、可选的第一个小时和分钟
this.updateHourAndMinuteList(0, 0);
},
// 确认
confirm() {
// 获取选中索引
const [dateIdx, hourIdx, minuteIdx] = this.value;
const dateObj = this.dateList[dateIdx];
console.log("🚀 ~ dateObj:", this.value)
const hour = this.hourList[hourIdx];
const minute = this.minuteList[minuteIdx];
// 组装时间戳
let ts = 0;
let endts = 0;
if (dateObj && hour !== undefined && minute !== undefined) {
// 构造 yyyy-mm-dd hh:mm:00 字符串
const d = dateObj.date;
const yyyy = d.getFullYear();
const mm = (d.getMonth() + 1).toString().padStart(2, '0');
const dd = d.getDate().toString().padStart(2, '0');
const hh = hour.toString().padStart(2, '0');
const mi = minute.toString().padStart(2, '0');
const dateStr = `${yyyy}-${mm}-${dd} ${hh}:${mi}:00`;
const endStr = `${yyyy}-${mm}-${dd} 22:00:00`;
console.log("🚀 ~ endStr:", endStr)
ts = Math.floor(new Date(dateStr.replace(/-/g, '/')).getTime() / 1000);
endts = Math.floor(new Date(endStr.replace(/-/g, '/')).getTime() / 1000);
}
// 传递给父组件
this.$emit('confirm', {
date: dateObj.date,
dateLabel: dateObj.label,
hour,
minute,
value: `${dateObj.label} ${hour}:${minute}`,
timestamp: ts,
endtimestamp: endts
});
this.$emit('close');
},
closePopup() {
this.$emit('close');
}
}
}
</script>
<style>
.uni-padding-wrap {
display: flex;
}
.picker-view {
width: 750rpx;
height: 600rpx;
margin-top: 20rpx;
}
.item {
line-height: 100rpx;
text-align: center;
font-size: 32rpx;
}
.line {
margin-top: 62rpx;
height: 2rpx;
background: #E5E5E5;
}
.btn {
margin-top: 44rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 32rpx;
}
.btn1, .btn2 {
width: 335rpx;
height: 90rpx;
text-align: center;
line-height: 90rpx;
font-size: 32rpx;
border-radius: 8rpx;
margin-bottom: 60rpx;
}
.btn1 {
background: #F6F7F8;
color: #303133;
}
.btn2 {
background: #365A9A;
color: #fff;
}
</style>