根据开始时间和结束时间生成指定间隔的时间段列表

效果图

openAllDay为false

openAllDay为true

打印结果

实现代码

time.ts

ts文件

interface GetTimePeriodOptions {
    date: string
    time: { startTime: string, endTime: string } | 'allDay'
    /** 分钟 */
    period: number
}

function format(date: Date, withHour?: boolean) {
    const year = date.getFullYear();
    const month = (date.getMonth() + 1) > 9 ? date.getMonth() + 1 : ("0" + (date.getMonth() + 1));
    const day = date.getDate() > 9 ? date.getDate() : "0" + date.getDate();
    if (withHour != null && !withHour) {
        return `${year}-${month}-${day}`
    }
    const hours = date.getHours() > 9 ? date.getHours() : "0" + date.getHours();
    const minutes = date.getMinutes() > 9 ? date.getMinutes() : "0" + date.getMinutes();
    const seconds = date.getSeconds() > 9 ? date.getSeconds() : "0" + date.getSeconds();
    return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
}

interface TimePeriod {
    startTime: string,
    endTime: string
}

export const getTimePeriod = (options: GetTimePeriodOptions): TimePeriod[] => {
    const date = new Date(options.date + " 00:00:00");
    let startTimestamp: number
    let endTimestamp: number
    if (options.time == 'allDay') {
        startTimestamp = date.setHours(0, 0, 0, 0);
        endTimestamp = startTimestamp + 24 * 60 * 60 * 1000;
    } else {
        // 是否跨天
        const overDay = options.time.endTime <= options.time.startTime;
        const startDate = format(date, false)
        const endDate = overDay ? format(new Date(date.getTime() + 24 * 60 * 60 * 1000), false) : startDate;
        startTimestamp = new Date(startDate + ' ' + options.time.startTime).getTime()
        endTimestamp = new Date(endDate + ' ' + options.time.endTime).getTime()
    }
    const periods: TimePeriod[] = []
    let currentStartTimestamp = startTimestamp
    do {
        const start = new Date(currentStartTimestamp);
        currentStartTimestamp = currentStartTimestamp + options.period * 60 * 1000;
        if (currentStartTimestamp <= endTimestamp) {
            const end = new Date(currentStartTimestamp);
            periods.push({
                startTime: format(start),
                endTime: format(end),
            } as TimePeriod)
        }
    } while (currentStartTimestamp <= endTimestamp)
    return periods;
}

vue 文件

<!-- 预约弹窗 -->
<template>
	<vxe-modal title="会员预约" v-model="showPop" width="640" @hide="reset">
		<vxe-form :data="formData" :rules="formRules" titleAlign="right" titleWidth="80" @submit="saveBooking">
			<!-- 预约时间 -->
			<vxe-form-item title="预约时间" field="appointmentStartTime" span="12">
				<template #default>
					<vxe-pulldown ref="bookingRef" destroy-on-close transfer class="w">
						<template #default>
							<vxe-input v-model="formData.appointmentStartTime" type="integer" min="1" clearable
								placeholder="请选择预约时间" :controls="false" @focus="$refs.bookingRef.showPanel()" />
						</template>
						<template #dropdown>
							<view class="w550 h300">
								<view class=""
									style="display:flex;white-space: nowrap; padding: 0;margin: 0;overflow-y: scroll">
									<view class="margin5 padding10 center-x-p30 br4 hand"
										:class="`${v.date == selectDate ? 'bg-green' : 'bg-eee'}`"
										v-for="(v,i) in dateList" :key="i" @click="selectDateFn(v)">
										<view class="">{{ v.date }}</view>
										<view class="">{{ v.week }}</view>
									</view>
								</view>
								<s-line></s-line>
								<view class="flex-wrap"
									style="max-height: 200px;padding: 0 20px;margin: 0;overflow-y: scroll"
									v-if="timeList.length>0">
									<view class="margin5 padding10 h40 center br4 hand"
										:class="`${current ==i ? 'bg-green ' : 'bg-eee dashed'}`"
										v-for="(v,i) in timeList" :key="i" @click="selectTimeFn(v,i)">
										<text> {{ v.startTime.slice(11,16) }} ~ {{ v.endTime.slice(11,16) }}</text>
									</view>
								</view>
							</view>
						</template>
					</vxe-pulldown>
				</template>
			</vxe-form-item>
			<!-- 底部确认取消 -->
			<vxe-form-item span="24">
				<view class="w right">
					<vxe-button type="reset" class="w80" @click="showPop = false" content="取消" />
					<vxe-button type="submit" status="primary" class="w80" content="确定" />
				</view>
			</vxe-form-item>
		</vxe-form>
	</vxe-modal>
</template>

<script>
	import api from '@/_core/utils/dataBase/api.ts'; //引入接口
	import weChatMsg from '@/pages/weChatMsg'; //微信消息推送
	import {
		getTimePeriod
	} from "../time"; // 员工列表弹窗
	export default {
		emits: ['addSuccess'],
		props: {},
		data() {
			return {
				current: -1, //预约时间默认选当前项
				showPop: false, // 显示弹窗
				formData: {
					remark: null
				}, //门店信息
				// 修改品牌弹窗数据校验
				formRules: {
					appointmentStartTime: [{
						required: true,
						message: '预约开始时间不能为空'
					}],
				},

				memberInfo: {}, //会员详情数据
				beginTime: null,
				endTime: null,
				isOpenAllDay: false, //是否24小时营业
				dateList: [],
				timeList: [],
				selectDate: '',
				appointmentTime: '',
				selectTime: '',
				keyboardShow: false,
				memberId: null,
				selectTimeObj: {}
			};
		},
		methods: {
			reset() {
				this.memberInfo = {};
				this.staffInfo = {};
				this.current = -1
			},
			selectTimeFn(data, index) {
				this.current = index
				this.selectTimeObj = data
				this.formData.appointmentStartTime = this.selectTimeObj.startTime.slice(5, 16) + '~' + this.selectTimeObj
					.endTime.slice(11, 16)
				this.$refs.bookingRef.hidePanel()
			},
			selectDateFn(data) {
				if (this.selectTimeObj.startTime) {
					this.formData.appointmentStartTime = this.selectTimeObj.startTime.slice(5, 16) + '~' + this
						.selectTimeObj.endTime.slice(11, 16)
				}
				this.current = -1
				this.selectDate = data.date;
				this.getTimeList();
			},
			// 给外部用的的方法 $refs.xxx.show()  getPlaceOrder
			async show(data) {
				this.loadings('加载中', async () => {
					this.formData = {}
					this.appointmentTime = ''
					this.selectTime = ''
					this.showPop = true
					this.timeList = []
					this.selectDate = this.getDate().slice(5)
					console.log(this.selectDate, 'this.selectDate'); // 07-17 this.selectDate
					await this.getDateList()
				})
			},
			async getDateList() {
				this.dateList = this.initData(5); // 日期栏初始化
				console.log(this.dateList, 'this.dateList');
				await this.getTimeList()
			},
			async getTimeList() {
				const openTime = this.cacheInfo.shopInfo.openTime
				const closeTime = this.cacheInfo.shopInfo.closeTime
				const openAllDay = this.cacheInfo.shopInfo.openAllDay || false
				console.log(openTime, closeTime, openAllDay);
				console.log(this.getDate().slice(0, 5) + this.selectDate,
					'this.getDate().slice(0, 5) + this.selectDate');
				this.timeList = getTimePeriod({
					time: openAllDay ? "allDay" : {
						startTime: openTime,
						endTime: closeTime
					},
					period: 30, // 间隔分钟
					date: this.getDate().slice(0, 5) + this.selectDate
				}).filter(v => +new Date(v.startTime).getTime() >= new Date().getTime())
			},
			saveBooking() {
				if (!this.formData.appointmentStartTime) return this.toast('请选择预约时间', 'error')
				console.log(this.selectTimeObj.startTime, 'this.selectTimeObj.startTime');
				console.log(this.selectTimeObj.endTime, 'this.selectTimeObj.endTime');
			},
		}
	};
</script>

<style lang="scss" scoped></style>

补充 initData方法

//获取最近7天的日期和礼拜天数
	initData(days= 7) {
		const time = []
		const date = new Date()

		const now = date.getTime() //获取当前日期的时间戳
		let timeStr = 3600 * 24 * 1000 //一天的时间戳
		let obj = {
			0: "今天",
			1: "明天",
			2: "后天"
		}
		for (let i = 0; i < days; i++) {
			const timeObj = {}
			timeObj.date = this.timeStamp(now + timeStr * i).dates //保存日期
			timeObj.dates = this.timeStamp(now + timeStr * i).date //保存日期
			timeObj.timeStamp = this.timeStamp(now + timeStr * i).simple //保存日期
			timeObj.week = obj[i] ?? this.timeStamp(now + timeStr * i).day
			time.push(timeObj)
		}
		return time
	},

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是实现该需求的JavaScript代码: ```js const fetchStartTime = '8:00'; const fetchEndTime = '18:00'; const fetchInterval = 60; // 间隔60分钟 const now = new Date(); const currentHour = now.getHours(); const currentMinute = now.getMinutes(); const currentTime = `${currentHour}:${currentMinute}`; const timeSlots = []; let fetchTime = fetchStartTime; while (fetchTime < fetchEndTime) { const startTime = fetchTime; const endTime = addMinutes(fetchTime, fetchInterval); const timeSlot = `${startTime}~${endTime}`; const isDisabled = timeSlot < currentTime; timeSlots.push({ timeSlot, isDisabled }); fetchTime = endTime; } console.log(timeSlots); function addMinutes(time, minutes) { const [hour, min] = time.split(':'); const date = new Date(); date.setHours(hour); date.setMinutes(min); date.setMinutes(date.getMinutes() + minutes); const newHour = date.getHours().toString().padStart(2, '0'); const newMinute = date.getMinutes().toString().padStart(2, '0'); return `${newHour}:${newMinute}`; } ``` 具体实现思路如下: 1. 定义起始时间结束时间间隔时间。 2. 获取当前时间,并将其转换为类似“8:30”的格式。 3. 通过循环,按照每个间隔时间生成一个时间段,并判断该时间段是否早于当前时间。 4. 将每个时间段和是否禁用的状态组成对象,添加到 `timeSlots` 数组中。 5. 最终输出 `timeSlots` 数组。 为了将时间段中的小时和分钟格式化为两位数,我们还定义了一个 `addMinutes` 函数,用于在给定时间上加上指定的分钟数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值