小程序中时间段选择以及多个相邻时间段的合并

view部分内容  

<view v-for="(item,index) in openingSlot" :key="index" class="mt20">
				<view class="muted row-between">
					<text>时间{{index+1}}</text>
					<view class="row" v-if="openingSlot.length > 1" @click="delOpening(index)">
						<u-icon name="trash" color="#8a8a8a" />
						<text>删除</text>
					</view>
				</view>
				<view class="block mt10">
					<view class="row-between row-info bdb-line">
						<view class="bold">开店时间</view>
						<view class="muted row" @click="changeTime(index,'state_time',item.state_time)">
							<text v-if="item.state_time">{{item.state_time}}</text>
							<text v-else>未设置</text>
							<u-icon name="arrow-right" color="#8a8a8a" />
						</view>
					</view>
					<view class="row-between row-info">
						<view class="bold">关店时间</view>
						<view class="muted row" @click="changeTime(index,'end_time',item.end_time)">
							<text v-if="item.end_time">
								<text v-if="parseTime(item.state_time) > parseTime(item.end_time)">次日</text>
								{{item.end_time}}</text>
							<text v-else>未设置</text>
							<u-icon name="arrow-right" color="#8a8a8a" />
						</view>
					</view>
				</view>
			</view>
			<view class="row-center mt20 green" @click="onAddOpeningSlot">
				<u-icon name="plus" size="18" color="#5ac725"></u-icon>
				<view class="ml10 md">添加营业时间</view>
			</view>
<u-datetime-picker :show="show" v-model="timeValue" mode="time" @confirm="confirmPicker"
			@cancel="show = false"></u-datetime-picker>

JS部分内容

<script>
	export default {
		data() {
			return {
				openingStyle: 1,
				openingSlot: [{
					state_time: '',
					end_time: ''
				}],
				changeIndex: 0,
				changeType: '',
				show: false,
				timeValue: '',
			}
		},
		onLoad() {
		},
		methods: {
			

			/*
			 * @Author: 
			 * @Date: 
			 * @Description: 获取当前时分=>
			 */
			nowTime() {
				let now = new Date();
				// 获取当前小时(0-23)  
				let hours = now.getHours();
				// 获取当前分钟(0-59)  
				let minutes = now.getMinutes();
				// 如果需要补零到两位数  
				hours = hours.toString().padStart(2, '0');
				minutes = minutes.toString().padStart(2, '0');
				return hours + ':' + minutes
			},
			/**
			 * @description: 添加营业时间
			 * @date:
			 */
			onAddOpeningSlot() {
				this.openingSlot.push({
					state_time: '',
					end_time: ''
				})
			},
			/*
			 * @Author: 
			 * @Date:
			 * @Description: 删除时间段=>
			 */
			delOpening(index) {
				this.openingSlot.splice(index, 1)
			},
			/*
			 * @Author: 
			 * @Date:
			 * @Description: 选择时间=>index:判断点击的是那一条信息 type:判断点击的是开始还是结束 time:时间
			 */
			changeTime(index, type, time) {
				if (time != '') {
					this.timeValue = time
				} else {
					this.timeValue = this.nowTime()
				}
				this.changeIndex = index
				this.changeType = type
				this.show = true
			},
			/*
			 * @Author: 
			 * @Date: 
			 * @Description: 确认选择时间=>e:返回的值
			 */
			confirmPicker(e) {
				// console.log(e.value, 'e')
				this.openingSlot[this.changeIndex][this.changeType] = e.value
				if (this.changeType == 'end_time' && this.openingSlot.length > 1) {
					this.openingSlot = this.mergeTimeRanges(this.openingSlot)
				}
				this.show = false
			},

			/*
			 * @Author: 
			 * @Date: 
			 * @Description: 时间变化
			 */
			parseTime(time) {
				const [hours, minutes] = time.split(':').map(Number);
				return hours * 60 + minutes;
			},
			/*
			 * @Author: 
			 * @Date: 
			 * @Description: 时间变化
			 */
			formatTime(minutes) {
				const hours = Math.floor(minutes / 60) % 24;
				const mins = minutes % 60;
				return `${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}`;
			},
			/*
			 * @Author: 
			 * @Date: 
			 * @Description: 时间变化
			 */
			normalizeTimeRange(start, end) {
				let startMinutes = this.parseTime(start);
				let endMinutes = this.parseTime(end);

				// Handle the case where start time is greater than end time (e.g., overnight range)
				if (startMinutes > endMinutes) {
					endMinutes += 24 * 60; // Add 24 hours to end time
				}

				return {
					startMinutes,
					endMinutes
				};
			},
			/*
			 * @Author: 
			 * @Date: 
			 * @Description: 时间变化
			 */
			mergeTimeRanges(timeRanges) {
				// Normalize all time ranges
				const normalizedRanges = timeRanges.map(({
					state_time,
					end_time
				}) => {
					const {
						startMinutes,
						endMinutes
					} = this.normalizeTimeRange(state_time, end_time);
					return {
						startMinutes,
						endMinutes
					};
				});

				// Sort ranges by start time
				normalizedRanges.sort((a, b) => a.startMinutes - b.startMinutes);

				const mergedRanges = [];
				let currentRange = normalizedRanges[0];

				for (let i = 1; i < normalizedRanges.length; i++) {
					const range = normalizedRanges[i];

					if (range.startMinutes <= currentRange.endMinutes) {
						// Overlapping ranges, merge them
						currentRange.endMinutes = Math.max(currentRange.endMinutes, range.endMinutes);
						// uni.
					} else {
						// Non-overlapping range, push current range to result and update current range
						mergedRanges.push(currentRange);
						currentRange = range;
					}
				}

				// Push the last range
				mergedRanges.push(currentRange);

				// Convert back to HH:MM format
				let formattedRanges = mergedRanges.map(({
					startMinutes,
					endMinutes
				}) => ({
					state_time: this.formatTime(startMinutes),
					end_time: this.formatTime(endMinutes % (24 * 60)),
				}));

				// Handle cases where end time has passed midnight
				formattedRanges.forEach(range => {
					if (this.parseTime(range.state_time) > this.parseTime(range.end_time)) {
						range.end_time = this.formatTime(this.parseTime(formattedRanges[0].end_time) + 24 * 60);
						// console.log('mergeTimeRanges', formattedRanges[0], range.end_time)
						formattedRanges.splice(0, 1)
					}
					if (this.parseTime(range.state_time) == this.parseTime(range.end_time)) {
						formattedRanges = [{
							state_time: '00:00',
							end_time: '23:59'
						}]
					}
				});

				return formattedRanges;
			},
		}
	}
</script>

具体效果如下图所示

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值