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 }); }, []);
二、修复"刷新后拖拽状态丢失"问题
当前修改仅存在于前端内存状态,未持久化到数据库,刷新后会重置。解决方案:
- 后端新增订单更新接口:拖拽完成后,调用接口将更新后的订单(含
timeSlot和新日期)保存到orderData表。 - 前端挂载时拉取最新数据:页面加载时从后端获取最新订单状态,替代初始静态数据。
示例接口调用(添加到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
相关产品推荐
相关产品推荐

