mrr.sj.front/pages/add/add.vue

330 lines
7.4 KiB
Vue
Raw Normal View History

2026-03-24 11:45:13 +08:00
<template>
<view class="add-page">
<!-- 其他内容 -->
<!-- 时间选择弹框 -->
<view class="popup-mask" v-if="showTimePicker" @click="closeTimePicker"></view>
<view class="time-picker" :class="{ show: showTimePicker }">
<view class="picker-header">
<text class="cancel" @click="closeTimePicker">取消</text>
<text class="title">选择时间</text>
<text class="confirm" @click="confirmTime">确定</text>
</view>
<view class="time-range">
<view class="time-block" :class="{ active: timeType === 'start' }" @click="switchTimeType('start')">
<text class="time-value">{{formatTime(startTime)}}</text>
<text class="time-label">开始时间</text>
</view>
<text class="time-separator"></text>
<view class="time-block" :class="{ active: timeType === 'end' }" @click="switchTimeType('end')">
<text class="time-value">{{formatTime(endTime)}}</text>
<text class="time-label">结束时间</text>
</view>
</view>
<view class="picker-content">
<picker-view
:value="pickerValue"
@change="handleTimeChange"
class="picker-view"
: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>
</view>
</view>
</template>
<script>
export default {
data() {
return {
showTimePicker: true,
pickerValue: [19, 34, 0, 20, 34],
hours: Array.from({length: 24}, (_, i) => i < 10 ? `0${i}` : `${i}`),
minutes: Array.from({length: 60}, (_, i) => i < 10 ? `0${i}` : `${i}`),
timeType: 'start',
indicatorStyle: 'height: 80rpx;'
}
},
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: {
// 打开时间选择器
openTimePicker() {
this.showTimePicker = true
setTimeout(() => {
const mask = document.querySelector('.popup-mask')
if (mask) mask.classList.add('show')
}, 0)
},
// 关闭时间选择器
closeTimePicker() {
const mask = document.querySelector('.popup-mask')
if (mask) mask.classList.remove('show')
setTimeout(() => {
this.showTimePicker = false
}, 300)
},
// 切换时间类型(开始/结束)
switchTimeType(type) {
this.timeType = type
},
// 处理时间变化
handleTimeChange(e) {
const values = e.detail.value
console.log(values)
// 检查开始时间是否大于结束时间
const startMinutes = parseInt(this.hours[values[0]]) * 60 + parseInt(this.minutes[values[1]])
const endMinutes = parseInt(this.hours[values[3]]) * 60 + parseInt(this.minutes[values[4]])
if (startMinutes >= endMinutes) {
// 如果开始时间大于等于结束时间,将结束时间设置为开始时间后一小时
const newEndHour = (parseInt(this.hours[values[0]]) + 1) % 24
values[3] = newEndHour
values[4] = values[1]
}
this.pickerValue = values
},
// 格式化时间显示
formatTime(time) {
return `${time.hour}:${time.minute}`
},
// 确认选择
confirmTime() {
const result = {
start: this.formatTime(this.startTime),
end: this.formatTime(this.endTime)
}
console.log('Selected time range:', result)
this.closeTimePicker()
}
}
}
</script>
<style>
/* 遮罩层 */
.popup-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 998;
opacity: 0;
transition: opacity 0.3s ease;
}
.popup-mask.show {
opacity: 1;
}
/* 时间选择器 */
.time-picker {
position: fixed;
left: 0;
right: 0;
bottom: -100%;
background-color: #fff;
z-index: 999;
border-radius: 24rpx 24rpx 0 0;
/* #ifdef H5 */
transition: bottom 0.3s ease;
/* #endif */
/* #ifdef APP-PLUS || MP-WEIXIN */
transform: translateY(100%);
transition: transform 0.3s ease;
/* #endif */
}
/* #ifdef H5 */
.time-picker.show {
bottom: 0;
}
/* #endif */
/* #ifdef APP-PLUS || MP-WEIXIN */
.time-picker.show {
transform: translateY(0);
}
/* #endif */
/* 选择器头部 */
.picker-header {
display: flex;
justify-content: space-between;
align-items: center;
height: 110rpx;
padding: 0 32rpx;
border-bottom: 1rpx solid #F5F5F5;
}
.cancel {
font-size: 32rpx;
color: #666666;
}
.title {
font-size: 36rpx;
color: #333333;
font-weight: 500;
}
.confirm {
font-size: 32rpx;
color: #4080FF;
font-weight: 500;
}
/* 时间范围选择 */
.time-range {
display: flex;
align-items: center;
justify-content: center;
padding: 32rpx;
background: #F8F9FC;
}
.time-block {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
background: #FFFFFF;
border-radius: 12rpx;
padding: 24rpx 0;
transition: all 0.3s ease;
}
.time-block.active {
background: #ECF2FF;
}
.time-label {
font-size: 26rpx;
color: #999999;
margin-top: 8rpx;
}
.time-value {
font-size: 40rpx;
color: #333333;
font-weight: 500;
}
.time-block.active .time-value {
color: #4080FF;
}
.time-separator {
font-size: 28rpx;
color: #999999;
margin: 0 24rpx;
}
/* 选择器内容区 */
.picker-content {
height: 480rpx;
position: relative;
padding: 0 32rpx;
background-color: #FFFFFF;
}
.picker-view {
width: 100%;
height: 100%;
}
.picker-item {
height: 80rpx;
line-height: 80rpx;
text-align: center;
font-size: 36rpx;
color: #333333;
font-weight: 400;
}
.picker-indicator .time-label {
font-size: 24rpx;
color: #999999;
background-color: #F5F7FA;
padding: 8rpx 32rpx;
border-radius: 8rpx;
}
/* 修改选择器中间指示器的样式 */
.uni-picker-view-indicator {
height: 80rpx !important;
}
.uni-picker-view-mask {
background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4)),
linear-gradient(0deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4)) !important;
}
/* 平台特定样式 */
/* #ifdef H5 */
.picker-view {
height: 480rpx !important;
}
/* #endif */
/* #ifdef APP-PLUS */
.picker-view {
height: 480rpx !important;
}
/* #endif */
/* #ifdef MP-WEIXIN */
.picker-view {
height: 480rpx !important;
}
.picker-item {
display: flex;
justify-content: center;
align-items: center;
}
/* #endif */
</style>