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

FullCalendar资源时间线拖拽事件按优先级预览重排实现咨询

解决方案:FullCalendar资源时间线视图拖拽事件继承优先级预览

针对你在React+TypeScript技术栈下,使用FullCalendar资源时间线视图时遇到的拖拽事件继承优先级预览问题,以下是两种可行的实现方案:

方案一:基于事件监听+临时状态的轻量实现

核心思路是通过监听拖拽悬停事件获取目标事件的优先级,结合eventDragMutationMassagers修改拖拽事件的优先级,利用FullCalendar自带的eventOrder配置实现实时重排预览。

具体实现代码

import { useState } from 'react';
import FullCalendar from '@fullcalendar/react';
import resourceTimelinePlugin from '@fullcalendar/resource-timeline';
import type { EventDragOverArg, EventMutation } from '@fullcalendar/core';

const ScheduleCalendar = () => {
  // 维护当前悬停事件的优先级状态
  const [hoveredTargetPriority, setHoveredTargetPriority] = useState<number | null>(null);

  // 监听拖拽悬停,检测是否命中其他事件
  const handleEventDragOver = (info: EventDragOverArg) => {
    const hoveredEventEl = document.elementFromPoint(info.jsEvent.clientX, info.jsEvent.clientY);
    const targetEventEl = hoveredEventEl?.closest('.fc-event');
    
    if (targetEventEl) {
      const targetEventId = targetEventEl.getAttribute('data-event-id');
      const targetEvent = info.view.calendar.getEventById(targetEventId!);
      setHoveredTargetPriority(targetEvent?.extendedProps.priority || null);
    } else {
      setHoveredTargetPriority(null);
    }
  };

  // 自定义拖拽事件的属性修改逻辑
  const eventDragMutationMassagers = [
    (mutation: EventMutation, context: any) => {
      if (hoveredTargetPriority !== null) {
        // 修改拖拽事件的优先级字段
        mutation.eventMutations[0].extendedProps.priority = hoveredTargetPriority;
      }
      return mutation;
    }
  ];

  return (
    <FullCalendar
      plugins={[resourceTimelinePlugin]}
      initialView="resourceTimelineDay"
      // 配置按优先级排序,值越大事件越置顶
      eventOrder="priority"
      allDayDefault={true}
      resources={[/* 你的员工资源数据 */]}
      events={[/* 你的事件数据,需包含extendedProps.priority字段 */]}
      eventDragOver={handleEventDragOver}
      eventDragMutationMassagers={eventDragMutationMassagers}
      // 拖拽结束后重置状态
      eventDragStop={() => setHoveredTargetPriority(null)}
    />
  );
};

export default ScheduleCalendar;

方案二:利用内部API强制触发Hit检测

如果需要更贴近FullCalendar原生拖拽逻辑,可以通过调用内部交互实例的方法,强制触发Hit生成,让eventDragMutationMassagers在悬停事件时生效。注意:该方案依赖内部未公开API,需锁定FullCalendar版本避免兼容性问题。

核心代码片段

import { useEffect, useRef } from 'react';
import FullCalendar from '@fullcalendar/react';
import resourceTimelinePlugin from '@fullcalendar/resource-timeline';

const ScheduleCalendar = () => {
  const calendarRef = useRef<any>(null);

  useEffect(() => {
    const calendarEl = document.querySelector('.fc');
    if (!calendarEl || !calendarRef.current) return;

    const handleDragOver = (e: DragEvent) => {
      const targetEventEl = (e.target as HTMLElement).closest('.fc-event');
      if (!targetEventEl) return;

      const targetEventId = targetEventEl.getAttribute('data-event-id');
      const targetEvent = calendarRef.current.getEventById(targetEventId!);
      if (!targetEvent) return;

      // 手动构造Hit对象,模拟进入目标事件的资源和日期
      const customHit = {
        resourceId: targetEvent.extendedProps.resourceId,
        date: targetEvent.start,
        event: targetEvent
      };

      // 获取当前拖拽交互实例,强制更新Hit
      const dragInteraction = calendarRef.current.interactions.find(
        (inter: any) => inter.type === 'eventDrag'
      );
      if (dragInteraction?.updateHit) {
        dragInteraction.updateHit(customHit);
      }
    };

    calendarEl.addEventListener('dragover', handleDragOver);
    return () => calendarEl.removeEventListener('dragover', handleDragOver);
  }, []);

  // 在eventDragMutationMassagers中通过hit关联的事件获取优先级
  const eventDragMutationMassagers = [
    (mutation: any, context: any) => {
      const hitEvent = context.dragHit?.event;
      if (hitEvent) {
        mutation.eventMutations[0].extendedProps.priority = hitEvent.extendedProps.priority;
      }
      return mutation;
    }
  ];

  return (
    <FullCalendar
      ref={calendarRef}
      plugins={[resourceTimelinePlugin]}
      initialView="resourceTimelineDay"
      eventOrder="priority"
      allDayDefault={true}
      resources={[/* 你的员工资源数据 */]}
      events={[/* 你的事件数据 */]}
      eventDragMutationMassagers={eventDragMutationMassagers}
    />
  );
};

export default ScheduleCalendar;

关键注意事项

  1. 确保事件数据中包含extendedProps.priority字段,且eventOrder配置为"priority",这样修改优先级后视图会自动触发重排。
  2. 方案一不依赖内部API,兼容性更强;方案二需注意FullCalendar版本更新可能导致内部方法变更,建议锁定版本(如v6.x)。
  3. 拖拽结束后需重置临时状态,避免影响后续拖拽操作。

内容的提问来源于stack exchange,提问作者Matthew McDonald

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 23:22:41