Bootstrap 本身不提供日程表组件,因其仅为 UI 框架,缺乏时间轴渲染、拖拽预约、冲突检测等核心调度能力,需借助 FullCalendar v6 等专用库实现会议室预约功能。

Bootstrap 本身不提供日程表(calendar/scheduler)组件,bootstrap-datepicker 或 bootstrap-datetimepicker 都只支持单日期/时间选择,无法直接实现带资源(如会议室)、时段(如 9:00–17:00 分格)、拖拽预约、冲突检测等功能的后台日程表。
为什么不能只靠 Bootstrap CSS + JS 实现会议室预约日程表
Bootstrap 是 UI 框架,不是日程调度库。它的 Modal、Table、Card 等组件可以辅助搭建界面,但以下核心能力必须额外引入:
- 按天/周/月视图动态渲染带时间轴的网格(例如每 30 分钟一格,横向为会议室,纵向为时间)
- 处理跨时段拖拽创建/修改预约,并实时校验会议室占用冲突
- 与后端交互保存/删除/更新预约,需管理
roomId、startTime、endTime、userId等字段 - 响应式缩放(尤其在小屏查看多会议室时容易挤成一团)
推荐组合:Bootstrap 5 + FullCalendar v6(+ @fullcalendar/resource-timeline)
这是目前最轻量、文档清晰、且与 Bootstrap 5 兼容性好的方案。FullCalendar 原生支持「资源时间轴视图(Resource Timeline View)」,正好对应「多个会议室 × 时间段」的建模需求。
实操要点:
- 用
npm install @fullcalendar/core @fullcalendar/resource-timeline @fullcalendar/bootstrap5安装 - 初始化时指定
resourceAreaWidth: '200px'控制左侧会议室列表宽度,避免文字截断 - 资源数据格式必须是数组,每个对象含
id和title(例如{ id: 'rm-1', title: 'A栋301' }) - 事件(events)数据中必须带
resourceId字段,否则不会显示在对应会议室行上 - 启用
select回调后,需手动调用calendar.addEvent({...})并发请求到后端,FullCalendar 不自动保存
示例关键配置片段:
const calendar = new Calendar(calendarEl, {
initialView: 'resourceTimelineWeek',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'resourceTimelineDay,resourceTimelineWeek,resourceTimelineMonth'
},
resources: [
{ id: 'rm-1', title: 'A栋301' },
{ id: 'rm-2', title: 'B栋208' }
],
events: [
{
id: '1',
resourceId: 'rm-1',
title: '产品评审会',
start: '2024-06-10T14:00:00',
end: '2024-06-10T15:30:00'
}
],
selectable: true,
select: function(info) {
// 这里弹出 Bootstrap Modal 表单收集预约信息
// 注意:info.resourceId 可取到当前点击的会议室 ID
}
});
常见踩坑点:时间格式、时区、冲突校验全得自己写
FullCalendar 默认使用浏览器本地时区解析 ISO 字符串,但后端通常存 UTC 时间。若前后端未对齐,会出现预约「提前 8 小时」或「延后半天」的问题。
- 后端返回事件时,
start和end必须带时区偏移(如'2024-06-10T06:00:00Z'),或统一转成 UTC 后再传给前端 - 用户拖拽新建预约时,
info.startStr和info.endStr是本地时区字符串,需用moment.tz(..., 'UTC').format()或new Date().toUTCString()转换后再提交 - 会议室冲突检测不在 FullCalendar 范围内——你得在
select或eventDrop回调里,用当前resourceId+start/end范围查一次后端 API,返回已有事件才允许保存 - 如果用 Bootstrap 的
Modal收集表单,注意 Modal 内的datetime-local输入框值是本地时间,需转换,不能直接塞进 event 对象
真正难的不是画出表格,而是把「谁在什么时间占了哪间房」这个业务规则稳稳地落在时间轴上,且不被时区和并发写入搞崩。留心 resourceId 字段是否漏传、后端返回的 ISO 时间有没有 Z、冲突检查是否绕过缓存——这些地方一松懈,预约就乱套。











