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

React周历拖拽问题:无法将拖拽框放置到指定时段

问题描述
  • 拖拽框操作时,框会被放置到目标日期的首个空时段,而非拖拽到的指定时段。例如将26日t1的框拖到27日t2,实际会放到27日t1;拖到29日t6时,因t1、t2已满,会放到29日t3。
  • 刷新网站后,所有移动过的拖拽框都会恢复原状。
  • 拖拽框显示订单号(如190、182)及郊区名称,当前仅存在存储所有数据的orderData表,无日历相关表。

一、修复"拖拽到指定时段失效"问题

核心问题是代码未维护订单与时段的绑定关系,渲染时仅靠数组索引匹配时段,导致新订单被放到数组末尾对应首个空时段。以下是具体修改方案:

1. 给订单添加timeSlot字段

用来存储订单绑定的时段(如t1/t2...t10),实现精准匹配。

2. 修改订单筛选与渲染逻辑

替换原generateCalendar中的ordersForDay逻辑,按日期+时段匹配订单:

// 替换原ordersForDay筛选代码
const ordersForDay = [...Array(10)].map((_, slotIndex) => {
  const targetSlot = `t${slotIndex + 1}`;
  return orderData.order.find(order => {
    const orderDate = new Date(order.RequiredDateAndTime).getDate();
    return orderDate === parseInt(dayOfMonth) && order.timeSlot === targetSlot;
  });
});

3. 调整handleDrop函数,精准绑定时段

const handleDrop = (e, timeSlotIndex, dayOfMonth, year, month) => {
  e.preventDefault();
  e.stopPropagation();

  const targetSlot = `t${timeSlotIndex + 1}`;
  const targetDate = new Date(year, month - 1, dayOfMonth); // 注意JS中月份从0开始

  // 移除原位置的订单
  let newOrderData = orderData.order.filter(item => item !== changeData);

  // 移除目标时段已有订单(可选:可改为提示用户时段已占用)
  const targetOrder = orderData.order.find(order => {
    const orderDate = new Date(order.RequiredDateAndTime).getDate();
    return orderDate === parseInt(dayOfMonth) && order.timeSlot === targetSlot;
  });
  if (targetOrder) {
    newOrderData = newOrderData.filter(item => item !== targetOrder);
  }

  // 更新拖拽订单的日期和时段
  const updatedOrder = {
    ...changeData,
    OrderDate: targetDate.toISOString(),
    RequiredDateAndTime: targetDate.toISOString(),
    timeSlot: targetSlot
  };

  // 更新orderData状态(原代码错误更新了calendarData,需改为orderData)
  newOrderData.push(updatedOrder);
  setOrderData({ ...orderData, order: newOrderData });
};

4. 初始化订单的timeSlot字段

给现有无时段的订单补全初始值:

useEffect(() => {
  const updatedOrders = orderData.order.map((order, index) => ({
    ...order,
    timeSlot: order.timeSlot || `t${(index % 10) + 1}`
  }));
  setOrderData({ ...orderData, order: updatedOrders });
}, []);

二、修复"刷新后拖拽状态丢失"问题

当前修改仅存在于前端内存状态,未持久化到数据库,刷新后会重置。解决方案:

  1. 后端新增订单更新接口:拖拽完成后,调用接口将更新后的订单(含timeSlot和新日期)保存到orderData表。
  2. 前端挂载时拉取最新数据:页面加载时从后端获取最新订单状态,替代初始静态数据。

示例接口调用(添加到handleDrop末尾):

// 调用后端API保存更新
fetch('/api/update-order', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(updatedOrder)
})
.catch(err => console.error('保存失败:', err));

三、是否需要给orderData表添加时段字段?

需要,原因如下:

  • 现有表无字段存储订单与时段的绑定关系,这是拖拽失效和状态丢失的核心根源。
  • 添加time_slot字段(如VARCHAR类型,存储t1/t2等值),可持久化时段分配逻辑,同时让后端能识别订单的时段信息。
  • 无需新增日历表,直接在orderData表添加字段即可,既满足需求又降低数据库复杂度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:48:12