预约系统优化:避免预插时段及JS实现已约时段隐藏方案
预约系统优化方案及JS实现
一、数据库设计优化
原方案需要给每个日期预插大量时段数据,冗余且维护成本高,我们改成只存储时段规则和已预约记录,彻底取消预插操作:
调整后的表结构
table_date_rules:存储日期/星期的时段规则rule_id(主键)date_type:类型标识,可选具体日期(如2024-05-20)或星期缩写(如TUE)start_time:时段起始时间(如09:00)end_time:时段结束时间(如17:00)interval_min:时段间隔分钟数(固定填15,也可灵活配置)
table_booked_slots:仅存储已预约的时段booked_id(主键)booked_date:预约日期(如2024-05-20)booked_time:预约时段(如09:15)user_info:预约用户信息(按需添加)
核心逻辑
- 用户选好日期后,后端先检查该日期是否有专属规则(
date_type为具体日期),无则按星期匹配对应规则 - 根据规则生成该日期的所有理论可用时段,对比
table_booked_slots筛选出已预约时段,仅返回已预约时段列表+时段规则给前端
二、前端JS实现(基于@Grumpy思路)
核心思路:前端根据后端返回的规则生成所有时段,再隐藏/移除已预约的时段,无需依赖后端返回全部可用时段。
后端接口需返回的数据
接口需返回两个关键数据:
{ "timeRule": { "startTime": "09:00", "endTime": "17:00", "intervalMin": 15 }, "bookedTimes": ["09:15", "10:30"] // 已预约的时段数组 }
完整JS代码实现
success: function (response) { const timeSelect = $('select[name="time"]'); // 清空原有选项并添加默认提示 timeSelect.empty().append('<option value="Choose time">Choose Time</option>'); // 解构后端返回的数据 const { timeRule, bookedTimes } = response; const { startTime, endTime, intervalMin } = timeRule; // 工具函数:将HH:mm格式转为总分钟数,方便计算 const convertToMinutes = (timeStr) => { const [hours, mins] = timeStr.split(':').map(Number); return hours * 60 + mins; }; const startTotalMin = convertToMinutes(startTime); const endTotalMin = convertToMinutes(endTime); const bookedSet = new Set(bookedTimes); // 用Set优化查找效率 // 循环生成所有时段 for (let currentMin = startTotalMin; currentMin <= endTotalMin; currentMin += intervalMin) { // 将总分钟数转回HH:mm格式 const hours = Math.floor(currentMin / 60).toString().padStart(2, '0'); const mins = (currentMin % 60).toString().padStart(2, '0'); const timeStr = `${hours}:${mins}`; // 仅添加未被预约的时段作为可选选项 if (!bookedSet.has(timeStr)) { timeSelect.append(`<option value="${timeStr}">${timeStr}</option>`); } } }
可选优化:保留已预约时段并置灰
如果需要展示已预约时段但禁止选择,可修改生成逻辑,给已预约选项添加禁用属性:
// 替换循环内的代码 const option = $(`<option value="${timeStr}">${timeStr}</option>`); if (bookedSet.has(timeStr)) { option.prop('disabled', true).css('color', '#ccc'); } timeSelect.append(option);
额外优化建议
- 前端可缓存常用星期规则(如周二的规则),避免重复请求后端
- 用户预约成功后,前端直接移除对应时段选项,无需重新请求接口刷新列表
内容的提问来源于stack exchange,提问作者Adam D.
相关产品推荐
相关产品推荐

