必须后端校验才能避免重复预订和时间冲突,前端仅负责渲染结构化数据、用class控制状态样式、添加唯一请求标识并配合redis幂等处理,时段冲突判断必须由后端完成。

直接用纯 HTML + 少量内联 CSS 和 JS 就能做出可用的共享办公预订页面,但想避免用户重复预订、时间冲突或点错位置,光靠前端拦不住——submit 必须走后端校验,否则所有“已预订”状态都是假的。
会议室/工位列表怎么渲染才不卡、还能实时标出占用?
静态页面里别用循环生成几十个 <div class="seat"> 再挨个查状态;先让后端返回一个结构化数据,比如:
<pre class="brush:php;toolbar:false;">{
"rooms": [
{
"id": "rm-a101",
"name": "创意间A",
"capacity": 6,
"bookings": [{"start": "10:00", "end": "12:00", "user": "张三"}]
}
],
"desks": [
{"id": "desk-03", "status": "available", "floor": 2}
]
}</pre>
<p>前端用 <code>fetch() 拿到后,用 map() 渲染,每个项加 data-id 和 data-status,方便后续点击时传参。别手动拼 HTML 字符串,用 document.createElement() 或模板字符串更稳。
- 状态样式统一用 class 控制:
class="desk booked"/class="desk available" - 如果工位数超 50,加
loading占位和节流滚动加载,不然 Safari 会卡顿 - 别把全天时间轴(如 9:00–18:00 每 30 分钟一格)全画出来——只渲染当前视口+前后两屏,用 IntersectionObserver 触发补全
点击预订按钮后,为什么 onclick 拦不住重复提交?
用户手快连点两次,submit 请求发出去两个,后端没做幂等处理的话,就真订了两回。解决不在前端“禁用按钮”这种表面功夫,而要:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 提交前生成唯一请求标识:
const reqId = Date.now() + '-' + Math.random().toString(36).substr(2, 9),传给后端 - 后端收到后先查
req_id是否已存在(Redis 存 10 分钟),存在则直接返回重复 - 前端按钮置灰的同时,加
disabled+data-sending="true"双保险,防止 onclick 绑定多个事件 - 失败后记得恢复按钮状态,别忘了
catch()里重置disabled
localStorage 能不能存预订草稿?存什么、存多久?
可以存,但只能存用户本地未提交的操作,比如选中的工位 ID、期望时间段、备注文字。绝对不要存“已确认预订”的状态——那会和真实数据库对不上。
- 键名用带业务前缀的:
localStorage.setItem('coffice_draft_desk_03', JSON.stringify({...})) - 每次进入页面检查
localStorage里有没有过期草稿(超过 30 分钟自动清掉) - 一旦成功提交,立刻
removeItem()对应草稿;失败则保留,但提示“上次未完成的预订已恢复” - 别存整个
bookings数组——容易和真实数据混淆,只存用户主动输入/选择的部分
真正麻烦的是时段冲突逻辑:两个预订只要 start/end 有任意重叠就算冲突,这个计算必须在后端做,前端只负责把用户选的时间段传过去,别自己写判断函数——时区、夏令时、跨天预订都会让它漏判。










