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

FullCalendar时间线模式下如何实现相邻资源事件合并?

FullCalendar时间线模式多资源事件合并实现方案

1. 调整事件数据结构

给事件添加resourceIds数组,明确关联的所有资源ID:

events: [
  {
    title: "多人聚餐",
    start: "2024-05-20T12:00:00",
    end: "2024-05-20T18:00:00",
    resourceIds: ["100", "101"] // 关联相邻桌台100、101
  },
  {
    title: "团队会议",
    start: "2024-05-20T10:00:00",
    end: "2024-05-20T14:00:00",
    resourceIds: ["100", "103"] // 关联不相邻桌台100、103
  }
]

2. 自定义事件渲染(核心实现)

利用eventContent和eventDidMount回调,判断资源连续性并渲染对应样式:

document.addEventListener('DOMContentLoaded', function() {
  const calendarEl = document.getElementById('calendar');
  // 提前存储资源列表,用于判断连续性
  const resources = [
    { id: "100", title: "桌台100" },
    { id: "101", title: "桌台101" },
    { id: "102", title: "桌台102" },
    { id: "103", title: "桌台103" }
  ];

  const calendar = new FullCalendar.Calendar(calendarEl, {
    schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
    initialView: 'resourceTimelineDay',
    resources: resources,
    events: [/* 你的事件数据 */],
    eventContent: function(info) {
      const eventResources = info.event.getResources();
      const currentResource = info.resource;

      // 仅在关联的第一个资源上渲染,其余资源跳过
      if (eventResources[0].id !== currentResource.id) {
        return { html: '' };
      }

      // 判断资源是否连续
      let isContiguous = true;
      for (let i = 1; i < eventResources.length; i++) {
        const prevIndex = resources.findIndex(r => r.id === eventResources[i-1].id);
        const currIndex = resources.findIndex(r => r.id === eventResources[i].id);
        if (currIndex !== prevIndex + 1) {
          isContiguous = false;
          break;
        }
      }

      if (isContiguous) {
        return {
          html: `<div class="fc-event-merged">${info.event.title}</div>`
        };
      } else {
        // 资源不相邻,正常渲染单个事件
        return { html: `<div>${info.event.title}</div>` };
      }
    },
    eventDidMount: function(info) {
      const eventResources = info.event.getResources();
      if (eventResources.length > 1 && eventResources[0].id === info.resource.id) {
        const rowHeight = calendar.view.resourceGrid.getRowHeight();
        // 让合并事件覆盖对应数量的资源行
        info.el.style.height = `${rowHeight * eventResources.length}px`;
        info.el.style.top = '0';
        info.el.style.zIndex = 10;
      }
    }
  });

  calendar.render();
});

3. 补充样式优化

添加CSS确保合并事件的视觉效果:

.fc-event-merged {
  background-color: #378006;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 600;
}

关键逻辑说明

  • 资源连续时:仅在第一个关联资源位置渲染一个覆盖所有对应资源行的合并区块,其余关联资源位置不渲染事件。
  • 资源不连续时:每个关联资源独立显示该事件,保持原有逻辑。

内容的提问来源于stack exchange,提问作者Gandalf Corvotempesta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 15:33:10