时间冲突检测必须在后端save()中查库完成,覆盖起始/结束时间重叠,用(start_time < existing_end AND end_time > existing_start)一次性捕获所有重叠情形。

时间冲突检测必须在保存前完成,不能只靠前端校验
用户提交预约时,save() 方法里必须查数据库已有记录,否则并发场景下两个几乎同时的请求会绕过前端限制。后端校验逻辑要覆盖「起始时间重叠」和「结束时间重叠」两种情况,常见错误是只判断 start_time >= existing_start 而漏掉 start_time 这类交叉。
推荐用半开区间比较(即 [start, end)),SQL 查询可写成:
SELECT COUNT(*) FROM lab_booking WHERE instrument_id = %s AND start_time < %s AND end_time > %s;
其中第二个参数是新预约的 end_time,第三个是新预约的 start_time。这样能一次性捕获所有重叠情形,包括完全包含、部分交叉、端点相接(若需排除端点相接,把 和 <code>> 改为 和 <code>>=)。
Sublime Text 本身不处理业务逻辑,别在 .sublime-project 里写校验规则
Sublime Text 是编辑器,不是运行环境。所谓“Sublime开发”实际是指用它编写 Python/PHP/Node.js 等后端代码,或配合本地服务器调试。有人误以为能在 .sublime-project 文件里配置时间校验,结果白忙活——那只是项目元数据,不参与执行。
真正要改的是后端接口代码,比如 Flask 中的路由函数:
- 检查请求里的
start_time和end_time是否为合法 ISO 格式(如"2024-05-20T14:00") - 转成带时区的
datetime对象(避免本地时间偏差) - 确认
end_time > start_time,且跨度不超过系统允许最大值(如 4 小时)
使用记录需区分“预约成功”和“实际使用”,两者字段和触发时机不同
很多实现把 booking 表和 usage_log 表混用,导致无法回溯“谁约了但没来”。正确做法是:预约生成 booking 记录(含 status 字段,值为 "pending" 或 "confirmed");实际开机/扫码/刷卡后,再插入独立的 usage_log 记录,并关联到对应 booking_id。
关键细节:
-
usage_log应含actual_start和actual_end,可能与预约时间不同 - 仪器端上报时间要用 NTP 同步过的系统时间,不能信客户端传来的
now() - 若支持手动补录,需加操作员字段和审核状态,避免日志被随意篡改
MySQL 时间类型选 DATETIME 还是 TIMESTAMP?优先 DATETIME
实验室排程对时区敏感度低,更看重时间值稳定不变。TIMESTAMP 会随 MySQL 服务器时区设置自动转换,一旦运维调了时区,历史预约全乱;而 DATETIME 存的就是字面值,读出来就是写进去的样子。
注意两点:
- Python 的
datetime对象存入DATETIME前,务必去掉tzinfo(用dt.replace(tzinfo=None)),否则 SQLAlchemy 可能报ValueError: MySQL DATETIME does not support timezone-aware datetimes - 如果真需要时区支持(比如跨校区协同),改用
TIMESTAMP+ 统一存 UTC,并在应用层做显示转换
时间冲突逻辑跑得再准,数据库类型选错,数据就不可信。这点容易被跳过,但改库结构的成本远高于改一行校验代码。

















