如何在FullCalendar中关联资源与事件并同步更新至数据库
解决FullCalendar资源与事件绑定并同步到数据库的问题
看起来你已经完成了基础的资源添加和事件拖拽功能,核心问题出在资源ID的映射识别以及前后端数据交互的细节处理上。下面一步步帮你解决:
1. 修复资源数据的字段映射(关键!)
FullCalendar的资源组件默认期望资源数据的唯一标识字段是id,显示名称字段是title,但你的数据库表用的是resourceid和resourceTitle。这会导致FullCalendar无法正确识别资源ID,拖拽事件时自然拿不到正确的resourceid。
修改all_resources.php,将数据库字段映射为FullCalendar需要的格式:
<?php require 'connection.php'; $conn = DB::databaseConnection(); $alldata = array(); // 重命名字段,匹配FullCalendar的资源要求 $sql = "SELECT resourceid AS id, resourceTitle AS title FROM resources ORDER BY resourceid"; $result = $conn->prepare($sql); $result->execute(); // 删掉原代码中多余的bindParam(SQL里没有占位符) while($row = $result->fetch(PDO::FETCH_ASSOC)) { array_push($alldata, $row); } echo json_encode($alldata); ?>
2. 完善eventReceive的事件数据处理
拖拽外部事件到资源列时,需要确保resourceId正确获取,同时完善时间字段和错误处理:
eventReceive: function(info) { // 先判断事件是否被拖拽到具体资源列 if (!info.event.resourceId) { alert('请将事件拖拽到具体的房间列中!'); info.event.remove(); return; } var eventData = { resourceid: info.event.resourceId, title: info.event.title, start: moment(info.event.start).format("YYYY-MM-DD HH:mm"), // 处理end字段为空的情况,默认给1小时时长 end: info.event.end ? moment(info.event.end).format("YYYY-MM-DD HH:mm") : moment(info.event.start).add(1, 'hour').format("YYYY-MM-DD HH:mm"), }; console.log(eventData); fetch('add_event.php', { method: 'POST', headers: { 'Accept': 'application/json' }, body: encodeFormData(eventData) }) .then(response => response.json()) // 解析后端的JSON响应 .then(data => { if (data.success) { console.log('事件添加成功:', data); // 可选:刷新日历事件列表 // calendar.refetchEvents(); } else { alert('添加失败: ' + data.message); info.event.remove(); } }) .catch(error => { console.error('添加事件失败:', error); info.event.remove(); }); }
3. 修复后端接口的响应格式
你的后端接口目前没有返回标准的JSON响应,前端无法判断操作是否成功。修改两个添加接口:
修改add_resources.php
<?php require 'connection.php'; header('Content-Type: application/json'); // 设置响应为JSON格式 $title = $_POST['title'] ?? ''; if(empty($title)) { echo json_encode(['success' => false, 'message' => '房间名称不能为空']); exit; } $conn = DB::databaseConnection(); try { $conn->beginTransaction(); $sqlInsert = "INSERT INTO Resources (resourceTitle) VALUES (:title)"; $stmt = $conn->prepare($sqlInsert); $stmt->bindParam(':title', $title); $stmt->execute(); // 获取刚插入的资源ID(可选,后续可能用到) $newResourceId = $conn->lastInsertId(); $conn->commit(); echo json_encode(['success' => true, 'resourceId' => $newResourceId, 'message' => '房间添加成功']); } catch(PDOException $e) { $conn->rollback(); echo json_encode(['success' => false, 'message' => '添加失败: ' . $e->getMessage()]); } ?>
修改add_event.php
<?php require 'connection.php'; header('Content-Type: application/json'); $resourceid = $_POST['resourceid'] ?? ''; $title = $_POST['title'] ?? ''; $start = $_POST['start'] ?? ''; $end = $_POST['end'] ?? ''; // 校验必填字段 if(empty($resourceid) || empty($title) || empty($start)) { echo json_encode(['success' => false, 'message' => '必填字段不能为空']); exit; } $conn = DB::databaseConnection(); try { $conn->beginTransaction(); // 如果是SQL Server,end字段需要用反引号/方括号,MySQL用反引号即可 $sqlInsert = "INSERT INTO Events (resourceid, title, start, `end`) VALUES (:resourceid, :title, :start, :end)"; $stmt = $conn->prepare($sqlInsert); $stmt->bindParam(':resourceid', $resourceid); $stmt->bindParam(':title', $title); $stmt->bindParam(':start', $start); $stmt->bindParam(':end', $end); $stmt->execute(); $newEventId = $conn->lastInsertId(); $conn->commit(); echo json_encode(['success' => true, 'eventId' => $newEventId, 'message' => '事件添加成功']); } catch(PDOException $e) { $conn->rollback(); echo json_encode(['success' => false, 'message' => '添加失败: ' . $e->getMessage()]); } ?>
4. 可选:添加事件拖拽更新的处理
如果需要支持已存在的事件拖拽到其他资源列时更新数据库,添加eventDrop回调:
eventDrop: function(info) { var eventData = { id: info.event.id, resourceid: info.event.resourceId, start: moment(info.event.start).format("YYYY-MM-DD HH:mm"), end: info.event.end ? moment(info.event.end).format("YYYY-MM-DD HH:mm") : moment(info.event.start).add(1, 'hour').format("YYYY-MM-DD HH:mm"), }; fetch('update_event.php', { method: 'POST', headers: { 'Accept': 'application/json' }, body: encodeFormData(eventData) }) .then(response => response.json()) .then(data => { if (!data.success) { alert('更新失败: ' + data.message); info.revert(); // 恢复事件位置 } }) .catch(error => { console.error('更新事件失败:', error); info.revert(); }); }
对应的update_event.php逻辑是根据id更新resourceid、start、end字段,写法参考add_event.php即可。
完成以上修改后,拖拽事件到资源列时就能正确将resourceid同步到Events表中了。
内容的提问来源于stack exchange,提问作者AAM
相关产品推荐
相关产品推荐

