You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP实现会议室预订系统HTML表格:多预订单元格数据插入难题

解决会议室预订系统多预订单元格填充问题

嘿,我懂你现在的困境——处理会议室预订表格时,同一天多个预订的情况总是容易搞砸单元格的内容展示,对吧?我之前做类似系统的时候也踩过这个坑,给你分享个靠谱的解决思路:

核心问题分析

你之前用if语句直接对比单个预订的开始时间和时间数组的slot,大概率会遇到两个问题:

  1. 同一个时间段有多个预订时,只会渲染第一个匹配的,后面的直接被忽略;
  2. 跨时间段的预订(比如09:00-10:30),只会在09:00的单元格显示,后续时间段的单元格没法关联到这个预订。

解决方案步骤

1. 先把预订数据按时间段映射

首先把当天的所有预订,分配到它们覆盖的每一个时间slot里,用一个对象来存储每个slot对应的所有预订。

// 假设从数据库拿到的预订数据
const bookings = [
  { roomId: 1, startTime: '2024-05-20 09:00', endTime: '2024-05-20 10:30', title: '团队周会', booker: '张三' },
  { roomId: 1, startTime: '2024-05-20 10:00', endTime: '2024-05-20 11:00', title: '客户沟通', booker: '李四' },
  { roomId: 2, startTime: '2024-05-20 09:30', endTime: '2024-05-20 12:00', title: '项目评审', booker: '王五' }
];

// 当天日期(可根据实际情况动态获取)
const today = '2024-05-20';
// 你的时间槽数组(示例为半小时间隔)
const timeSlots = ['09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '12:00'];

// 初始化时间槽-预订映射
const slotBookingsMap = {};
timeSlots.forEach(slot => slotBookingsMap[slot] = []);

// 筛选当天的预订并分配到对应时间槽
const todayBookings = bookings.filter(booking => booking.startTime.startsWith(today));
todayBookings.forEach(booking => {
  const startSlot = booking.startTime.split(' ')[1];
  const endSlot = booking.endTime.split(' ')[1];
  const startIdx = timeSlots.indexOf(startSlot);
  const endIdx = timeSlots.indexOf(endSlot);
  
  // 把预订添加到它覆盖的每一个时间槽
  for (let i = startIdx; i < endIdx; i++) {
    slotBookingsMap[timeSlots[i]].push(booking);
  }
});

2. 动态渲染表格单元格

遍历时间槽数组,每个单元格根据映射里的预订列表来渲染内容——多个预订就用列表展示,没有就显示“空闲”。

<table border="1" cellpadding="8" cellspacing="0">
  <thead>
    <tr>
      <th>时间段</th>
      <th>会议室1</th>
      <th>会议室2</th>
    </tr>
  </thead>
  <tbody id="bookingTableBody">
    <!-- 动态内容会在这里生成 -->
  </tbody>
</table>

<script>
const tbody = document.getElementById('bookingTableBody');

timeSlots.forEach(slot => {
  const row = document.createElement('tr');
  
  // 渲染时间段单元格
  const timeCell = document.createElement('td');
  timeCell.textContent = slot;
  row.appendChild(timeCell);
  
  // 渲染会议室1单元格
  const room1Cell = document.createElement('td');
  const room1Bookings = slotBookingsMap[slot].filter(b => b.roomId === 1);
  if (room1Bookings.length > 0) {
    const bookingList = document.createElement('ul');
    bookingList.style.margin = '0';
    room1Bookings.forEach(booking => {
      const listItem = document.createElement('li');
      listItem.textContent = `${booking.title} (${booking.startTime.split(' ')[1]}-${booking.endTime.split(' ')[1]})`;
      // 加tooltip显示预订人
      listItem.title = `预订人:${booking.booker}`;
      bookingList.appendChild(listItem);
    });
    room1Cell.appendChild(bookingList);
  } else {
    room1Cell.textContent = '空闲';
    room1Cell.style.color = '#888';
  }
  row.appendChild(room1Cell);
  
  // 渲染会议室2单元格(逻辑和会议室1一致)
  const room2Cell = document.createElement('td');
  const room2Bookings = slotBookingsMap[slot].filter(b => b.roomId === 2);
  if (room2Bookings.length > 0) {
    const bookingList = document.createElement('ul');
    bookingList.style.margin = '0';
    room2Bookings.forEach(booking => {
      const listItem = document.createElement('li');
      listItem.textContent = `${booking.title} (${booking.startTime.split(' ')[1]}-${booking.endTime.split(' ')[1]})`;
      listItem.title = `预订人:${booking.booker}`;
      bookingList.appendChild(listItem);
    });
    room2Cell.appendChild(bookingList);
  } else {
    room2Cell.textContent = '空闲';
    room2Cell.style.color = '#888';
  }
  row.appendChild(room2Cell);
  
  tbody.appendChild(row);
});
</script>

额外优化建议

  • 如果预订时间段不是刚好匹配你的时间槽(比如结束时间是10:15),可以把时间转换成分钟数来计算覆盖的slot,避免遗漏;
  • 单元格内容太多时,可以用CSS折叠或者模态框展示详细信息;
  • 给重叠的预订添加不同的背景色,方便视觉区分。

内容的提问来源于stack exchange,提问作者Dominic F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:44:35