外观
在线预约系统设计文档
概述
在线预约系统是一个支持用户预约房间(如会议室、教室、实验室等)和设备(如实验设备、仪器等)的完整解决方案。系统包含资源管理、预约管理、冲突检测、审批流程、通知提醒等核心功能,适用于企业、学校、机构等多种场景。
核心功能
1. 资源管理
- 房间管理:用户可自定义房间名称(如会议室01、教室02、我的实验室等),设置房间描述、位置、容量等信息
- 设备管理:用户可创建和管理设备(如实验设备、仪器等),设置设备描述、分类等信息
- 资源创建:所有用户都可以创建房间和设备
- 自动审批设置:资源创建者可设置是否自动审批,创建者可随时修改自动审批设置
2. 预约功能
- 自定义时间段预约:最小颗粒度为半小时,起始时间只能是整点或半点
- 冲突检测:智能检测时间冲突,确保同一资源在同一时间段只能被一人预约
- 重复预约:支持每周同一时间重复预约
- 预约审批流程:由资源创建者审批,支持自动审批
- 取消预约:用户可以取消自己的预约
- 状态管理:创建者可修改已自动审批通过的预约状态
3. 通知提醒
- 邮箱提醒选择:用户预约时可在界面上选择是否通过邮箱提醒
- 邮箱绑定检查:如果选择邮箱提醒,系统会检查用户邮箱绑定状态(未绑定邮箱需提示激活账号)
- 预约成功通知:通过邮箱发送,仅当用户选择邮箱提醒时
- 审批通过/拒绝通知:通过邮箱发送,仅当用户选择邮箱提醒时
- 预约开始前提醒:通过邮箱发送,仅当用户选择邮箱提醒时(定时任务)
4. 历史记录
- 预约历史记录查询:支持分页、筛选
- 我的预约列表:查看自己创建的所有预约
- 资源预约记录:查看某个资源的所有预约记录
- 我的资源预约管理:资源创建者查看和管理自己创建的资源的所有预约
5. 落地页功能(apps-home/booking)
- SEO 优化:针对搜索引擎优化的落地页
- 产品介绍:功能特点、使用场景介绍
- 文案优化:吸引用户使用该产品
数据库设计
表结构
1. 房间表(booking_room)
用于存储房间基本信息。
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键,自增 |
| name | varchar(255) | 房间名称(如:会议室01、教室02) |
| description | varchar(500) | 房间描述 |
| location | varchar(255) | 位置信息 |
| capacity | int | 容量(人数) |
| status | enum | 状态:启用/禁用 |
| creator_id | int | 创建者ID,关联user表 |
| auto_approve | boolean | 是否自动审批(默认false) |
| image | varchar(500) | 房间图片 |
| created_at | timestamp | 创建时间 |
| updated_at | timestamp | 更新时间 |
索引:
- 外键索引:
creator_id关联user.id
2. 设备表(booking_equipment)
用于存储设备基本信息。
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键,自增 |
| name | varchar(255) | 设备名称 |
| description | varchar(500) | 设备描述 |
| category | varchar(100) | 设备分类 |
| status | enum | 状态:启用/禁用/维护中 |
| creator_id | int | 创建者ID,关联user表 |
| auto_approve | boolean | 是否自动审批(默认false) |
| image | varchar(500) | 设备图片 |
| created_at | timestamp | 创建时间 |
| updated_at | timestamp | 更新时间 |
索引:
- 外键索引:
creator_id关联user.id
3. 预约表(booking)
用于存储预约信息。
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键,自增 |
| resource_type | enum | 资源类型:房间/设备 |
| resource_id | int | 资源ID(房间ID或设备ID) |
| user_id | int | 预约用户ID,关联user表 |
| start_time | datetime | 开始时间(必须是整点或半点) |
| end_time | datetime | 结束时间(最小颗粒度半小时) |
| status | enum | 状态:待审批/已通过/已拒绝/已取消/已完成 |
| reason | varchar(500) | 预约原因/用途 |
| reject_reason | varchar(500) | 拒绝原因 |
| approver_id | int | 审批人ID(资源创建者),关联user表 |
| approved_at | datetime | 审批时间 |
| cancelled_at | datetime | 取消时间 |
| is_recurring | boolean | 是否重复预约 |
| recurring_pattern | varchar(50) | 重复模式(如:weekly, monthly) |
| recurring_end_date | datetime | 重复结束日期 |
| parent_booking_id | int | 父预约ID(用于重复预约),关联booking表 |
| is_auto_approved | boolean | 是否自动审批通过 |
| email_reminder | boolean | 是否接收邮箱提醒(用户预约时选择) |
| created_at | timestamp | 创建时间 |
| updated_at | timestamp | 更新时间 |
索引:
- 外键索引:
user_id关联user.id - 外键索引:
approver_id关联user.id - 外键索引:
parent_booking_id关联booking.id - 复合索引:
(resource_type, resource_id, status)用于快速查询资源的有效预约
4. 预约通知表(booking_notification)
用于存储预约通知信息。
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键,自增 |
| booking_id | int | 预约ID,关联booking表 |
| user_id | int | 接收用户ID,关联user表 |
| type | enum | 通知类型:创建/审批通过/审批拒绝/提醒/取消 |
| title | varchar(255) | 通知标题 |
| content | varchar(1000) | 通知内容 |
| is_read | boolean | 是否已读 |
| read_at | datetime | 阅读时间 |
| created_at | timestamp | 创建时间 |
| updated_at | timestamp | 更新时间 |
索引:
- 外键索引:
booking_id关联booking.id - 外键索引:
user_id关联user.id - 复合索引:
(user_id, is_read)用于快速查询用户未读通知
后端实现
服务层(src/services/)
1. bookingRoom.mts - 房间管理服务
提供房间的 CRUD 操作和自动审批设置管理。
主要函数:
createRoom- 创建房间updateRoom- 更新房间(包括修改自动审批设置)deleteRoom- 删除房间getRoomList- 获取房间列表(支持分页、筛选)getRoomDetail- 获取房间详情updateAutoApprove- 更新自动审批设置
关键逻辑:
- 所有用户都可以创建房间
- 只有房间创建者可以修改和删除自己的房间
- 自动审批设置可以随时修改
2. bookingEquipment.mts - 设备管理服务
提供设备的 CRUD 操作和自动审批设置管理。
主要函数:
createEquipment- 创建设备updateEquipment- 更新设备(包括修改自动审批设置)deleteEquipment- 删除设备getEquipmentList- 获取设备列表(支持分页、筛选)getEquipmentDetail- 获取设备详情updateAutoApprove- 更新自动审批设置
关键逻辑:
- 所有用户都可以创建设备
- 只有设备创建者可以修改和删除自己的设备
- 自动审批设置可以随时修改
3. booking.mts - 预约管理服务
提供预约的核心业务逻辑,包括时间验证、冲突检测、重复预约等。
主要函数:
createBooking- 创建预约(包含冲突检测和时间验证)createRecurringBooking- 创建重复预约checkConflict- 检查时间冲突validateTimeSlot- 验证时间段(确保起始时间为整点或半点,最小颗粒度半小时)updateBooking- 更新预约cancelBooking- 取消预约getBookingList- 获取预约列表(支持分页、筛选)getBookingDetail- 获取预约详情getMyBookings- 获取我的预约getResourceBookings- 获取资源预约记录getMyResourceBookings- 获取我创建的资源的所有预约(用于创建者管理)
关键逻辑:
时间验证:
- 起始时间必须是整点(如 09:00)或半点(如 09:30)
- 最小预约时长为半小时
- 时间段必须是半小时的整数倍
冲突检测:
- 查询同一资源(resource_type + resource_id)的所有有效预约
- 筛选状态为 'approved' 或 'pending' 的预约
- 检查新预约的时间段是否与已有预约重叠
- 如果重叠,返回冲突错误
自动审批:
- 检查资源的 auto_approve 设置
- 如果 auto_approve 为 true 且无时间冲突:
- 自动将状态设置为 'approved'
- 设置 is_auto_approved 为 true
- 设置 approver_id 为资源创建者ID
- 发送审批通过通知给预约用户
- 发送预约创建通知给资源创建者
- 如果 auto_approve 为 false 或存在冲突:
- 状态设置为 'pending'
- 发送预约创建通知给资源创建者(需要审批)
重复预约:
- 支持每周、每月重复预约
- 根据重复模式生成多个预约记录
- 所有重复预约共享同一个 parent_booking_id
- 每个重复预约都需要单独进行冲突检测和审批
4. bookingAudit.mts - 预约审批服务
提供预约审批和状态管理功能。
主要函数:
approveBooking- 审批通过(由资源创建者调用)rejectBooking- 审批拒绝(由资源创建者调用)updateBookingStatus- 更新预约状态(创建者可修改自动审批通过的预约状态)getPendingBookings- 获取待审批列表(按资源创建者筛选)getMyResourcePendingBookings- 获取我创建的资源的所有待审批预约
关键逻辑:
- 只有资源创建者可以审批该资源的预约
- 审批通过后,发送通知给预约用户
- 审批拒绝时,需要填写拒绝原因
- 资源创建者可以修改已自动审批通过的预约状态
5. bookingNotification.mts - 预约通知服务
提供通知创建和发送功能。
主要函数:
createNotification- 创建通知checkUserEmail- 检查用户邮箱绑定状态(检查 email 和 email_verified)sendBookingCreatedNotification- 发送预约创建通知(通过邮箱发送给资源创建者)sendBookingApprovedNotification- 发送审批通过通知(通过邮箱发送给预约用户)sendBookingRejectedNotification- 发送审批拒绝通知(通过邮箱发送给预约用户)sendBookingReminderNotification- 发送预约提醒通知(通过邮箱发送)getNotifications- 获取通知列表markAsRead- 标记为已读
关键逻辑:
- 所有通知均通过邮箱发送,使用项目现有的邮件发送服务(EmailUtils)
- 发送通知前必须检查用户邮箱绑定状态(检查
user.email和user.email_verified) - 如果用户未绑定邮箱或邮箱未验证,返回错误提示用户需要激活账号
- 提示信息:激活账号后手机号和邮箱都会绑定
- 仅当预约记录的 email_reminder = true 时才发送邮件通知
控制器层(src/controllers/)
1. bookingRoom.mts - 房间管理控制器
提供房间管理的 HTTP 接口。
主要接口:
cCreateRoom- 创建房间cUpdateRoom- 更新房间cUpdateRoomAutoApprove- 更新房间自动审批设置cDeleteRoom- 删除房间cGetRoomList- 获取房间列表cGetRoomDetail- 获取房间详情
请求验证:
- 使用 Zod 定义请求参数 Schema(命名以
s开头,如sCreateRoom) - 所有控制器函数包含 try-catch 和
next(err)错误处理 - 使用
res.success和res.successPage统一响应格式
2. bookingEquipment.mts - 设备管理控制器
提供设备管理的 HTTP 接口。
主要接口:
cCreateEquipment- 创建设备cUpdateEquipment- 更新设备cUpdateEquipmentAutoApprove- 更新设备自动审批设置cDeleteEquipment- 删除设备cGetEquipmentList- 获取设备列表cGetEquipmentDetail- 获取设备详情
请求验证:
- 使用 Zod 定义请求参数 Schema
- 所有控制器函数包含 try-catch 和
next(err)错误处理 - 使用
res.success和res.successPage统一响应格式
3. booking.mts - 预约管理控制器
提供预约管理的 HTTP 接口。
主要接口:
cCreateBooking- 创建预约cUpdateBooking- 更新预约cCancelBooking- 取消预约cGetBookingList- 获取预约列表cGetBookingDetail- 获取预约详情cGetMyBookings- 获取我的预约cGetResourceBookings- 获取资源预约记录cGetMyResourceBookings- 获取我创建的资源的所有预约
请求验证:
- 使用 Zod 定义请求参数 Schema
- 时间参数验证:确保起始时间为整点或半点
- 所有控制器函数包含 try-catch 和
next(err)错误处理 - 使用
res.success和res.successPage统一响应格式
4. bookingAudit.mts - 预约审批控制器
提供预约审批的 HTTP 接口。
主要接口:
cApproveBooking- 审批通过cRejectBooking- 审批拒绝cUpdateBookingStatus- 更新预约状态(创建者可修改自动审批通过的预约状态)cGetPendingBookings- 获取待审批列表cGetMyResourcePendingBookings- 获取我创建的资源的所有待审批预约
请求验证:
- 使用 Zod 定义请求参数 Schema
- 审批拒绝时必须填写拒绝原因
- 所有控制器函数包含 try-catch 和
next(err)错误处理 - 使用
res.success统一响应格式
5. bookingNotification.mts - 预约通知控制器
提供通知管理的 HTTP 接口。
主要接口:
cGetNotifications- 获取通知列表cMarkAsRead- 标记为已读
请求验证:
- 使用 Zod 定义请求参数 Schema
- 所有控制器函数包含 try-catch 和
next(err)错误处理 - 使用
res.success和res.successPage统一响应格式
路由层(src/routes/)
1. bookingRoom.mts - 房间管理路由
定义房间管理的 API 路由。
路由列表:
POST /api/booking/room- 创建房间PUT /api/booking/room- 更新房间PUT /api/booking/room/auto-approve- 更新自动审批设置DELETE /api/booking/room- 删除房间GET /api/booking/room/list- 获取房间列表GET /api/booking/room/detail- 获取房间详情
中间件:
authMiddleware- 需要登录bodyValidateMiddleware- 请求体验证
2. bookingEquipment.mts - 设备管理路由
定义设备管理的 API 路由。
路由列表:
POST /api/booking/equipment- 创建设备PUT /api/booking/equipment- 更新设备PUT /api/booking/equipment/auto-approve- 更新自动审批设置DELETE /api/booking/equipment- 删除设备GET /api/booking/equipment/list- 获取设备列表GET /api/booking/equipment/detail- 获取设备详情
中间件:
authMiddleware- 需要登录bodyValidateMiddleware- 请求体验证
3. booking.mts - 预约管理路由
定义预约管理的 API 路由。
路由列表:
POST /api/booking/booking- 创建预约PUT /api/booking/booking- 更新预约DELETE /api/booking/booking- 取消预约GET /api/booking/booking/list- 获取预约列表GET /api/booking/booking/detail- 获取预约详情GET /api/booking/booking/my- 获取我的预约GET /api/booking/booking/resource- 获取资源预约记录GET /api/booking/booking/my-resource- 获取我创建的资源的所有预约
中间件:
authMiddleware- 需要登录bodyValidateMiddleware- 请求体验证
4. bookingAudit.mts - 预约审批路由
定义预约审批的 API 路由。
路由列表:
POST /api/booking/audit/approve- 审批通过POST /api/booking/audit/reject- 审批拒绝PUT /api/booking/audit/status- 更新预约状态GET /api/booking/audit/pending- 获取待审批列表GET /api/booking/audit/my-resource-pending- 获取我创建的资源的所有待审批预约
中间件:
authMiddleware- 需要登录bodyValidateMiddleware- 请求体验证
5. bookingNotification.mts - 预约通知路由
定义通知管理的 API 路由。
路由列表:
GET /api/booking/notification/list- 获取通知列表PUT /api/booking/notification/read- 标记为已读
中间件:
authMiddleware- 需要登录bodyValidateMiddleware- 请求体验证
前端实现
主要功能应用(apps/booking/)
基于 Vue 3 + TypeScript + Element Plus 构建的主要功能应用。
应用结构
apps/booking/index.html- 入口 HTMLapps/booking/src/main.ts- 入口文件apps/booking/src/App.vue- 根组件apps/booking/src/router/index.ts- 路由配置apps/booking/vite.config.mts- Vite 配置apps/booking/tsconfig.json- TypeScript 配置
API 接口(apps/booking/src/api/)
api.ts- API 基础配置bookingRoom.ts- 房间管理 APIbookingEquipment.ts- 设备管理 APIbooking.ts- 预约管理 APIbookingAudit.ts- 预约审批 APIbookingNotification.ts- 预约通知 API
公共组件(apps/booking/src/components/)
BookingStatusTag.vue- 预约状态标签组件ResourceCard.vue- 资源卡片组件(房间/设备)AutoApproveSwitch.vue- 自动审批开关组件EmailReminderSwitch.vue- 邮箱提醒开关组件TimeRangePicker.vue- 时间段选择器(限制起始时间为整点或半点,最小颗粒度半小时)RecurringBookingForm.vue- 重复预约表单组件BookingCalendar.vue- 预约日历组件(显示资源可用时间段)
页面组件(apps/booking/src/views/)
房间相关页面:
RoomListView.vue- 房间列表页RoomDetailView.vue- 房间详情页RoomCreateView.vue- 创建房间页RoomManageView.vue- 房间管理页(创建者管理自己的房间)
设备相关页面:
EquipmentListView.vue- 设备列表页EquipmentDetailView.vue- 设备详情页EquipmentCreateView.vue- 创建设备页EquipmentManageView.vue- 设备管理页(创建者管理自己的设备)
预约相关页面:
BookingListView.vue- 预约列表页BookingCreateView.vue- 创建预约页(包含时间选择、重复预约设置)BookingDetailView.vue- 预约详情页MyBookingsView.vue- 我的预约页MyResourceBookingsView.vue- 我的资源预约管理页(创建者查看和管理自己资源的预约)BookingAuditView.vue- 预约审批页(资源创建者审批)
通知相关页面:
NotificationView.vue- 通知中心页
落地页应用(apps-home/booking/)
基于 Nuxt 4 构建的 SEO 优化落地页。
应用结构
apps-home/booking/app/pages/index.vue- 首页apps-home/booking/nuxt.config.ts- Nuxt 配置apps-home/booking/tsconfig.json- TypeScript 配置apps-home/booking/build/deploy.mts- 部署脚本
页面内容
- SEO 优化的首页:产品介绍、功能特点、使用场景等
- 产品优势展示:灵活预约、重复预约、自动审批、冲突检测、邮箱提醒、资源管理
- 使用场景:会议室预约、教室预约、设备预约、其他资源预约
- 联系入口:提供联系方式
核心业务逻辑
1. 时间验证规则
验证逻辑:
- 起始时间必须是整点(如 09:00)或半点(如 09:30)
- 最小预约时长为半小时
- 结束时间必须是整点或半点
- 时间段必须是半小时的整数倍
- 开始时间不能晚于结束时间
实现位置:src/services/booking.mts 中的 validateTimeSlot 函数
2. 冲突检测算法
检测逻辑:
- 查询同一资源(resource_type + resource_id)的所有有效预约
- 筛选状态为 'approved' 或 'pending' 的预约
- 检查新预约的时间段是否与已有预约重叠
- 如果重叠,返回冲突错误
时间重叠判断:
- 新预约的开始时间 < 已有预约的结束时间
- 新预约的结束时间 > 已有预约的开始时间
实现位置:src/services/booking.mts 中的 checkConflict 函数
3. 自动审批流程
自动审批逻辑:
- 用户创建预约时,检查资源的 auto_approve 设置
- 如果 auto_approve 为 true 且无时间冲突:
- 自动将状态设置为 'approved'
- 设置 is_auto_approved 为 true
- 设置 approver_id 为资源创建者ID
- 发送审批通过通知给预约用户(如果 email_reminder = true)
- 发送预约创建通知给资源创建者
- 如果 auto_approve 为 false 或存在冲突:
- 状态设置为 'pending'
- 发送预约创建通知给资源创建者(需要审批)
实现位置:src/services/booking.mts 中的 createBooking 函数
4. 审批流程
审批流程:
- 用户创建预约 -> 状态为 'pending'(如果未自动审批)
- 资源创建者审批 -> 状态变为 'approved' 或 'rejected'
- 审批通过后,发送通知给预约用户(如果 email_reminder = true)
- 审批拒绝时,需要填写拒绝原因
- 资源创建者可以修改已自动审批通过的预约状态
实现位置:src/services/bookingAudit.mts 中的 approveBooking、rejectBooking、updateBookingStatus 函数
5. 重复预约处理
重复预约逻辑:
- 用户选择重复模式(weekly/monthly)和结束日期
- 根据重复模式生成多个预约记录
- 所有重复预约共享同一个 parent_booking_id
- 取消时可以选择取消单个或全部
- 每个重复预约都需要单独进行冲突检测和审批
实现位置:src/services/booking.mts 中的 createRecurringBooking 函数
6. 通知提醒机制
通知类型(所有通知均通过邮箱发送):
- 预约创建通知 - 创建预约时发送给资源创建者
- 审批通过通知 - 审批通过时发送给预约用户(如果 email_reminder = true)
- 审批拒绝通知 - 审批拒绝时发送给预约用户(如果 email_reminder = true)
- 预约提醒通知 - 预约开始前 1 小时发送提醒(定时任务,如果 email_reminder = true)
- 预约取消通知 - 取消预约时发送给相关人员(如果 email_reminder = true)
邮箱提醒选择逻辑:
- 用户预约时可在界面上选择是否通过邮箱提醒(email_reminder 字段)
- 如果用户选择邮箱提醒(email_reminder = true):
- 创建预约时检查用户是否已绑定邮箱(user.email 和 email_verified)
- 如果用户未绑定邮箱或邮箱未验证,返回错误提示用户需要激活账号
- 提示用户:激活账号后手机号和邮箱都会绑定
- 如果用户已绑定并验证邮箱,则保存 email_reminder = true
- 发送通知时:
- 仅当预约记录的 email_reminder = true 时才发送邮件通知
- 使用项目现有的邮件发送服务(EmailUtils)
实现位置:src/services/bookingNotification.mts 中的相关函数
定时任务
预约提醒任务(schedules/jobBookingReminder.mts)
功能:
- 查询即将开始的预约(1小时内开始),发送提醒通知
- 自动将已过期的预约状态更新为 'completed'
执行频率:每 10 分钟执行一次
实现逻辑:
- 查询状态为 'approved' 且 1 小时内开始的预约
- 仅处理 email_reminder = true 的预约
- 检查是否已经发送过提醒(通过检查通知表)
- 发送提醒通知给预约用户
- 查询已过期的预约(end_time < 当前时间),批量更新状态为 'completed'
注册位置:schedules/index.mts