红颜弃轩冕,白首卧松云。
1 前言
在最近的业务开发中,遇到了一个棘手的问题,需要设计一个服务预约系统。业务场景是这样的,用户在平台上选择日期和时间,来预约对应的家政人员进行服务。接下来,会结合产品需求和开发设计以及实现过程来分享预约系统的实现过程。
2 业务要求
- 1 用户可以在平台预约家政人员进行服务,服务时间为
09:00-21:00
,可以在服务时间段选择对应的服务项,每个服务项目的服务时长是固定的,用户可以预约平台选择服务项目,并选择对应的家政人员进行服务。 - 2 同一个家政人员在同一时间内只能为一个客户服务,并且服务之间需要间隔30分钟,家政人员需要赶赴服务的地址。
- 3 预约系统只显示当前时间之后可以预约的时间,并且至少要提前30分钟进行预约。不可服务的时间需要置灰显示。
以下列举的服务项目仅是为了说明服务项目的时长有所不同,时长不尽准确。
服务项 | 时长/分钟 |
---|---|
保洁服务 | 60 |
厨房打扫 | 40 |
卫生间打扫 | 30 |
窗户擦洗 | 50 |
3 系统设计
首先我们需要创建一张预约表,为了保证预约不能冲突,还要设计一张预约明细表,使用唯一索引键来约束每个家政人员的服务时间。不能出现项目预约时间冲突的情况。具体的表设计如下图所示:

此外,预约系统还需要有店铺,服务项目,以及服务人员的信息,其关联关系如下图所示:

4 预约数据保存
由于每项服务的时间都是固定的,在接收到用户的预约请求时,需要将预约的家政人员信息,店铺信息,项目信息,以及时间段保存到预约表中,同时将家政人员以及分割的时间点存入预约表明细中进行保存。在保存数据时,使用事务操作,利用预约表明细的唯一约束来控制预约时间不冲突。
如下图所示,即数据保存前的校验以及数据的赋值。首先需要校验其项目信息,店铺信息是否存在,此外还要校验项目的服务时长和请求的起止时间是否一致。在保存预约明细时,需要按照起止时间将时间切割成10分钟的节点,进行保存。

如下图所示,使用编程式事务保存预约单和预约明细单,此外需要判断是否是新增预约还是更新预约,更新预约时间的情况下,需要先删除对应的预约单然后进行保存。

用户创建预约后,需要根据预约单创建订单,如果未能在 3分钟内完成创建订单并支付,需要使用定时任务释放预约,以供有需要的用户进行选择。
5 可视化预约信息展示
预约的展示相对于数据的保存复杂的多,需要将可预约的时间点显示出来,以可视化的方式供用户进行选择。用户预约的途径可以在服务人员里面根据服务项目进行选择,也可以在店铺里面选择项目,然后选择不同的服务人员进行预约。
5.1 服务预约
这里的难度在于,如何将已预约的信息展示出来,并且需要约束可预约的时间要在店铺的营业时间段内。

如上图所示,即实现的代码,在实际情况中,还需要考虑服务人员的假期情况,从可预约的时间段内进行扣除。
5.2 店铺预约
对于店铺预约,其难点在于用户选择服务的开始时间后,需要根据其预约时间将店铺可以选择的服务人员所涉及的项目进行展示,如果该时段可以预约则显示空闲,不能预约则显示可以预约的开始时间,否则就要展示已约满。

6 效果展示
如下图所示,即是预约功能实现的效果,在店铺预约时需要选择服务的开始时间,在家政服务预约可以选择7天内的服务时间段。预约里面的每个细节都需要注意,防止预约超越营业时间,以及不能存在预约冲突的情况。

7 总结
本文主要介绍了如何设计一个预约系统,实现了预约的不冲突,提高了预约接口的性能。此外从两个维度介绍了如何实现预约的可视化查询,其中涉及到了部分算法问题。本文中所涉及的代码已经上传至 github
, 欢迎交流学习。项目地址 sandbox-stock。