mrr.sj.front/components/time-picker/time-picker.vue

210 lines
5.5 KiB
Vue
Raw Permalink 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>
<uni-popup
ref="popup"
type="bottom"
border-radius="20rpx"
style="z-index: 20000"
>
<!-- 时间选择滚轮 -->
<view class="region-body">
<image class="region-body__close" @click="close" src="/static/images/shop/close.png"></image>
<view class="region-body__header"> 请选择时间段 </view>
<picker-view
:value="pickerValue"
@change="handleTimeChange"
class="picker-scroll"
:indicator-style="indicatorStyle"
>
<picker-view-column>
<view class="picker-item" v-for="(hour, index) in hours" :key="index">
{{ hour }}时
</view>
</picker-view-column>
<picker-view-column>
<view
class="picker-item"
v-for="(minute, index) in minutes"
:key="index"
>
{{ minute }}分
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item"> - </view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(hour, index) in hours" :key="index">
{{ hour }}
</view>
</picker-view-column>
<picker-view-column>
<view
class="picker-item"
v-for="(minute, index) in minutes"
:key="index"
>
{{ minute }}分
</view>
</picker-view-column>
</picker-view>
<view class="region-body__btn" @tap="confirmTime"
>确认
{{
`(${this.formatTime(this.startTime)}-${this.formatTime(
this.endTime
)})`
}}</view
>
</view>
</uni-popup>
</template>
<script>
export default {
data() {
return {
default_times: "",
business_time: "",
indicatorStyle: "height: 68rpx;",
pickerValue: [8, 0, 0, 18, 0],
// 小时数组直接用数字字符串确保parseInt转换无歧义
hours: Array.from({ length: 24 }, (_, i) => `${i}`),
// 分钟数组使用数字字符串,避免格式问题
minutes: ["0", "10", "20", "30", "40", "50", "59"],
};
},
computed: {
startTime() {
return {
hour: this.hours[this.pickerValue[0]],
minute: this.minutes[this.pickerValue[1]],
};
},
endTime() {
return {
hour: this.hours[this.pickerValue[3]],
minute: this.minutes[this.pickerValue[4]],
};
},
},
methods: {
// 处理时间变化,确保开始时间小于结束时间
handleTimeChange(e) {
const values = e.detail.value;
// 转换为数值计算(避免字符串比较问题)
const startHour = parseInt(this.hours[values[0]], 10);
const startMinute = parseInt(this.minutes[values[1]], 10);
const endHour = parseInt(this.hours[values[3]], 10);
const endMinute = parseInt(this.minutes[values[4]], 10);
// 计算总分钟数进行比较
const startTotalMinutes = startHour * 60 + startMinute;
const endTotalMinutes = endHour * 60 + endMinute;
if (startTotalMinutes >= endTotalMinutes) {
// 自动调整结束时间为开始时间后1小时处理跨天情况
let newEndHour = startHour + 1;
if (newEndHour >= 24) newEndHour = 0; // 超过24点则重置为0点
// 找到新结束小时在数组中的索引
const newEndHourIndex = this.hours.findIndex(h => parseInt(h, 10) === newEndHour);
// 保持分钟与开始时间一致
values[3] = newEndHourIndex;
values[4] = values[1];
}
this.pickerValue = values;
},
openTimePopup() {
this.$refs.popup.open();
},
// 格式化时间显示(保持":""分隔iOS兼容
formatTime(time) {
// 确保分钟为两位数显示(可选,根据需求调整)
const minute = time.minute.padStart(2, '0');
return `${time.hour}:${minute}`;
},
close(){
this.$refs.popup.close();
},
// 确认选择,发射标准化的时间字符串
confirmTime() {
const startTimeStr = this.formatTime(this.startTime);
const endTimeStr = this.formatTime(this.endTime);
this.$emit("confirmTime", `${startTimeStr}-${endTimeStr}`);
this.$refs.popup.close();
},
},
};
</script>
<style scoped lang="less">
/* 样式部分不变 */
.region-body {
flex: 1;
overflow: hidden;
background: #fff;
border-radius: 20rpx 20rpx 0 0;
&__close{
width: 22rpx;
height: 22rpx;
position: absolute;
top: 44rpx;
right: 30rpx;
}
&__header {
padding: 40rpx 0;
font-weight: 500;
font-size: 32rpx;
color: #333333;
line-height: 45rpx;
text-align: left;
font-style: normal;
display: flex;
justify-content: center;
}
&__btn {
display: flex;
align-items: center;
justify-content: center;
width: 690rpx;
height: 80rpx;
background: #FF4767;
border-radius: 38rpx;
font-weight: 400;
font-size: 30rpx;
color: #ffffff;
line-height: 39rpx;
text-align: right;
font-style: normal;
margin: 0 30rpx;
}
}
.region-scroll {
height: 100%;
}
.picker-scroll {
height: 400rpx;
}
.picker-item {
height: 68rpx;
line-height: 68rpx;
text-align: center;
}
.region-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 0;
border-bottom: 1rpx solid #eeeeee;
}
.region-item.checkbox-item {
padding: 20rpx 0;
width: 100%;
justify-content: flex-start !important;
align-items: center !important;
}
</style>