简介
本文件面向DouPHP预约系统的开发者与数据库管理员,围绕预约主表 dou_book 提供完整的数据模型参考。内容涵盖字段设计、状态流转、生命周期时间戳、查询优化建议与索引策略,帮助快速理解并高效维护预约业务数据。
项目结构
- 数据定义:预约主表及关联表的建表语句集中在模块备份SQL中。
- 模型层:后台与前台分别提供 Book 模型,封装常用查询与作用域。
- 国际化:状态文案通过语言包统一维护,便于前端展示与多语言扩展。
graph TB
A["预约主表<br/>dou_book"] --> B["预约项目表<br/>dou_book_item"]
A --> C["预约联系人表<br/>dou_book_contact"]
A --> D["预约操作日志表<br/>dou_book_log"]
A --> E["预约通知记录表<br/>dou_book_notify"]
A --> F["预约规则表<br/>dou_book_rule / dou_book_rule_slot"]
A --> G["预约时段配置表<br/>dou_book_schedule"]
核心组件
- 预约主表 dou_book:承载一次预约的核心信息,包括单号、用户、项目、联系人、时间、人数、价格、支付、状态与各类时间戳等。
- 预约项目表 dou_book_item:定义可预约的项目及其默认时长、容量、价格等。
- 预约操作日志表 dou_book_log:记录状态变更、操作人、IP、备注等审计信息。
- 预约通知记录表 dou_book_notify:记录短信、邮件、微信、App等通知的发送情况。
- 预约规则与排班:通过规则表与排班表控制可约日期、时段、容量与价格调整。
架构总览
预约主表作为业务核心,与项目、规则、排班、日志、通知等表形成稳定耦合;后台与前台模型提供统一的查询与写入入口,并通过作用域与预加载简化复杂查询。
classDiagram
class 预约主表_dou_book {
+id
+book_sn
+user_id
+item_id
+contact_id
+name
+phone
+id_card
+book_date
+start_time
+end_time
+people_count
+custom
+remark
+price
+pay_status
+paid_at
+order_sn
+status
+cancelled_at
+cancel_reason
+released_at
+confirmed_at
+confirm_work_id
+confirm_admin_id
+checked_in_at
+checkin_work_id
+checkin_admin_id
+checkin_status
+ip
+created_at
+updated_at
}
class 预约项目表_dou_book_item {
+id
+class_id
+name
+duration
+capacity
+price
+original_price
+advance_days
+min_advance_hours
+max_advance_hours
+cancel_deadline_hours
+item_day_limit
+item_period_days
+item_period_limit
+brief
+content
+sort
+status
+created_at
+updated_at
}
class 预约操作日志表_dou_book_log {
+id
+book_id
+operator_type
+operator_id
+action
+before_status
+after_status
+remark
+ip
+created_at
}
class 预约通知记录表_dou_book_notify {
+id
+book_id
+user_id
+notify_type
+notify_event
+receiver
+content
+send_status
+sent_at
+response
+created_at
}
预约主表_dou_book --> 预约项目表_dou_book_item : "item_id"
预约主表_dou_book --> 预约操作日志表_dou_book_log : "book_id"
预约主表_dou_book --> 预约通知记录表_dou_book_notify : "book_id"
详细组件分析
字段设计与语义
- 标识与关联
- id:自增主键
- book_sn:预约单号(唯一)
- user_id:下单用户ID
- item_id:预约项目ID
- contact_id:联系人ID(关联联系人表)
- 联系人信息
- name:预约人姓名
- phone:预约人电话
- id_card:身份证号
- 时间与人数
- book_date:预约日期
- start_time/end_time:开始与结束时间
- people_count:预约人数
- 价格与支付
- price:预约价格
- pay_status:支付状态(0未支付,1已支付)
- paid_at:支付完成时间
- order_sn:关联订单号
- 状态与流程
- status:预约状态(0待确认,1已确认,2已完成,3已取消,4已过期,5已拒绝)
- 流程时间戳
- cancelled_at:取消时间
- cancel_reason:取消原因
- released_at:释放时间(如释放占位或名额)
- confirmed_at:确认时间
- confirm_work_id/confirm_admin_id:确认操作人(工作端/管理员)
- checked_in_at:签到时间
- checkin_work_id/checkin_admin_id:签到操作人(工作端/管理员)
- checkin_status:签到状态(0未签到,1已签到)
- 其他
- custom:自定义选项
- remark:备注
- ip:预约IP
- created_at/updated_at:创建与更新时间
状态流转与业务逻辑
- 状态枚举与含义
- 0 待确认:新创建的预约等待审核或自动确认
- 1 已确认:已通过审核或满足自动确认条件
- 2 已完成:服务完成或标记完成
- 3 已取消:由用户或系统取消
- 4 已过期:超过约定时间未签到或未处理而自动过期
- 5 已拒绝:被管理员或规则拒绝
- 典型流转路径
- 新建 → 待确认 → 已确认 → 已完成
- 新建 → 待确认 → 已拒绝
- 新建 → 待确认 → 已取消
- 已确认 → 已过期(超时未签到)
- 已确认 → 已取消(在允许时间内)
- 相关时间戳更新时机
- confirmed_at:状态从“待确认”变为“已确认”时写入
- cancelled_at/cancel_reason:状态变为“已取消”时写入
- released_at:释放占位或名额时写入
- checked_in_at:签到成功时写入,同时更新签到状态
- paid_at:支付成功后写入
- updated_at:任意字段更新时刷新
预约生命周期时间戳说明
- 创建与更新
- created_at:预约创建时间
- updated_at:最近一次修改时间
- 确认阶段
- confirmed_at:确认时间
- confirm_work_id/confirm_admin_id:确认操作者
- 取消阶段
- cancelled_at:取消时间
- cancel_reason:取消原因
- 释放阶段
- released_at:释放时间(如释放时段占用)
- 签到阶段
- checked_in_at:签到时间
- checkin_work_id/checkin_admin_id:签到操作者
- checkin_status:签到状态
- 支付阶段
- paid_at:支付完成时间
查询优化建议
- 常用过滤维度
- 按用户:user_id
- 按项目:item_id
- 按日期范围:book_date
- 按时间段:start_time/end_time
- 按状态:status
- 按创建时间:created_at
- 按释放时间:released_at
- 推荐索引策略
- 唯一索引:book_sn(单号唯一)
- 普通索引:user_id、item_id、contact_id、status、created_at、released_at
- 复合索引:(book_date, start_time) 用于按日与时段的高效筛选
- 查询实践建议
- 列表页优先使用 scopeFilterByUserId/scopeFilterByItemId/scopeFilterByStatus/scopeFilterByDateStart/scopeFilterByDateEnd 组合条件
- 详情查询使用 findAdminBookingById 或 findAndUserId,避免全表扫描
- 需要项目信息的列表,使用 withItem 预加载减少N+1查询
- 对时间范围查询尽量使用闭区间,配合 (book_date, start_time) 复合索引提升性能
模型与接口要点
- 后台模型
- 表名:book
- 主键:id
- 类型转换:status 使用数据语言映射,created_at 格式化输出
- 作用域:按用户、项目、状态、日期范围筛选;工作端待处理筛选;关键字解析为 user_id 后落 where
- 删除级联:删除预约时同步清理日志与通知
- 前台模型
- 表名:book
- 关联:item 预加载
- 方法:按用户筛选、创建返回新ID、默认排序
状态机流程图
flowchart TD
Start(["新建预约"]) --> Pending["待确认"]
Pending --> Confirmed{"是否通过审核?"}
Confirmed --> |是| ConfirmedState["已确认"]
Confirmed --> |否| Rejected["已拒绝"]
Pending --> Cancelled["已取消"]
ConfirmedState --> Completed["已完成"]
ConfirmedState --> Expired["已过期"]
ConfirmedState --> Cancelled
Cancelled --> End(["结束"])
Rejected --> End
Completed --> End
Expired --> End
依赖关系分析
- 外键语义
- user_id:关联用户表(不在本节SQL中,但模型中有对应关联)
- item_id:关联预约项目表
- contact_id:关联联系人表
- book_id:日志与通知表通过该字段关联主表
- 耦合与内聚
- 主表与项目、规则、排班存在强业务耦合,但通过ID解耦,保持表间高内聚
- 日志与通知独立成表,保证主表轻量与可追溯性
graph LR
U["用户(user)"] --> B["预约主表(book)"]
I["预约项目(item)"] --> B
C["联系人(contact)"] --> B
B --> L["日志(log)"]
B --> N["通知(notify)"]
性能考虑
- 索引设计
- 唯一索引:book_sn
- 高频查询索引:user_id、item_id、contact_id、status、created_at、released_at
- 复合索引:(book_date, start_time) 支持按日与时段的范围查询
- 查询优化
- 使用作用域组合条件,避免无索引的全表扫描
- 列表页采用分页与必要字段选择,减少数据传输
- 详情与列表预加载关联项,降低N+1问题
- 写入优化
- 批量更新状态时注意事务与锁粒度
- 日志与通知异步写入,降低主流程延迟
故障排查指南
- 常见异常场景
- 重复单号:检查 book_sn 唯一约束冲突
- 状态不一致:核对状态流转是否符合规则,检查日志表记录
- 支付状态不同步:核对 paid_at 与 order_sn 的一致性
- 签到失败:检查 checkin_status 与 checked_in_at 的更新时机
- 定位手段
- 通过 book_id 查询日志表,查看状态变更轨迹
- 通过 user_id/item_id/status 等索引字段快速定位记录
- 结合 created_at/released_at 判断是否存在超时或释放异常
结论
dou_book 作为预约系统的核心表,字段设计覆盖预约全生命周期所需的关键信息,状态与时间戳清晰表达业务流程。配合合理的索引与查询作用域,可在高并发场景下保持稳定性能。建议在实际使用中严格遵循状态流转规则,完善日志与通知机制,确保数据一致性与可追溯性。
附录
- 相关表概览
- 预约项目表:定义项目基础信息与限制
- 预约规则表与规则时段:控制可约日期、时段、容量与价格调整
- 预约排班表:按周与时间段配置容量与加价
- 预约日志表:审计状态变更与操作痕迹
- 预约通知表:记录多渠道通知发送结果