<?php ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); session_start(); include('db.php'); // 检查用户是否已登录 if (!isset($_SESSION['username'])) { header('Location: index.php'); exit; } // 获取设备信息 $equipment_id = isset($_GET['id']) ? intval($_GET['id']) : 0; $equipment_query = "SELECT * FROM equipment WHERE id = ?"; $stmt = $conn->prepare($equipment_query); $stmt->bind_param("i", $equipment_id); $stmt->execute(); $equipment_result = $stmt->get_result(); $equipment = $equipment_result->fetch_assoc(); if (!$equipment) { echo "设备不存在。"; exit; } // 获取设备特定的问题 $questions_query = "SELECT * FROM equipment_questions WHERE equipment_id = ?"; $stmt = $conn->prepare($questions_query); $stmt->bind_param("i", $equipment_id); $stmt->execute(); $questions_result = $stmt->get_result(); $questions = []; while ($row = $questions_result->fetch_assoc()) { $questions[] = $row; } ?> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>预约设备</title> <!-- 引入Bootstrap CSS 和 FullCalendar --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"> <script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.15/index.global.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"></script> <style> .time-slot { display: inline-block; width: 80px; height: 40px; text-align: center; line-height: 40px; margin: 1px; border: 1px solid #ddd; cursor: pointer; } .booked { background-color: #ff6666; color: white; cursor: not-allowed; } .available { background-color: #66ff66; color: black; } .selected { background-color: #0066ff; color: white; } #calendar { max-width: 600px; margin: 0 auto; } .divider { border-top: 2px solid #dee2e6; margin: 40px 0; } .calendar-title { text-align: center; font-size: 24px; font-weight: bold; margin-bottom: 20px; } .equipment-photo { display: block; width: auto; max-height: 300px; margin: 20px 0; } .equipment-description { margin-left: 20px; max-width: 300px; } .photo-description-container { display: flex; justify-content: center; align-items: center; } #booking-info { margin-top: 20px; } #timeSlots { margin-top: 20px; } </style> </head> <body> <!-- 导航栏 --> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <!-- 省略,内容与index.php相同 --> </nav> <div class="container mt-3"> <a href="index.php" class="btn btn-secondary">返回主页</a> <button onclick="history.back()" class="btn btn-secondary">返回上一级</button> </div> <div class="container mt-4"> <a href="equipment_list.php" class="btn btn-secondary">返回设备列表</a> <h2>预约 <?php echo htmlspecialchars($equipment['name'], ENT_QUOTES, 'UTF-8'); ?></h2> <!-- 添加链接到“我的预约”页面 --> <div class="mb-3"> <a href="my_bookings.php" class="btn btn-info">查看我的预约</a> </div> <form action="submit_booking.php" method="POST"> <input type="hidden" name="equipment_id" value="<?php echo $equipment['id']; ?>"> <input type="hidden" id="selectedStartTime" name="start_time"> <input type="hidden" id="selectedEndTime" name="end_time"> <input type="hidden" id="selectedDate" name="date"> <!-- 显示设备照片和描述 --> <div class="row mb-4"> <div class="col-md-6"> <?php if (!empty($equipment['photo'])) { ?> <img src="<?php echo htmlspecialchars($equipment['photo'], ENT_QUOTES, 'UTF-8'); ?>" alt="设备照片" class="img-fluid equipment-photo"> <?php } ?> </div> <div class="col-md-6"> <?php if (!empty($equipment['description'])) { ?> <p><?php echo htmlspecialchars($equipment['description'], ENT_QUOTES, 'UTF-8'); ?></p> <?php } ?> </div> </div> <!-- FullCalendar --> <div class="form-group row"> <div class="col-md-6"> <div class="divider"></div> <div class="calendar-title">请选择日期:</div> <div id="calendar"></div> </div> <div class="col-md-6"> <div class="divider"></div> <div id="booking-info"> <h4>当天预约情况</h4> </div> <div id="timeSlots" class="mt-4"></div> </div> </div> <div class="form-group"> <label for="title" style="font-size: 24px">实验目的:一句话概括本次预约的实验目的。例如:AliCPT微波复用读出电路刻蚀工艺研究</label> <textarea class="form-control" id="title" name="title" rows="1" required></textarea> </div> <!-- 设备特定的问题 --> <?php foreach ($questions as $question) { ?> <div class="form-group mt-3"> <label for="question_<?php echo $question['id']; ?>"> <?php echo htmlspecialchars($question['question'], ENT_QUOTES, 'UTF-8'); ?> </label> <input type="text" class="form-control" id="question_<?php echo $question['id']; ?>" name="answers[<?php echo $question['id']; ?>]" required> </div> <?php } ?> <!-- 提交预约 --> <button type="submit" class="btn btn-success mt-4" id="submitBookingForm">提交预约</button> </form> </div> <script> $(document).ready(function () { // 初始化 FullCalendar var calendar = new FullCalendar.Calendar(document.getElementById('calendar'), { initialView: 'dayGridMonth', locale: 'zh-cn', selectable: true, // 允许选择日期 headerToolbar: { left: 'prev,next today', center: 'title', right: 'dayGridMonth' }, aspectRatio: 1.5, // 调整日历的宽高比 windowResize: function(view) { // 动态调整日历大小 if (window.innerWidth < 600) { calendar.setOption('aspectRatio', 1); // 小屏幕设备 } else { calendar.setOption('aspectRatio', 1.5); // 普通设备 } }, dateClick: function (info) { // 用户选择了日期,自动触发检查预约情况 var selectedDate = info.dateStr; var equipmentId = <?php echo $equipment['id']; ?>; // 清空之前的时间段 $('#timeSlots').html(''); // 发送 AJAX 请求,获取当天的预约情况 $.ajax({ url: 'fetch_bookings.php', type: 'POST', data: { equipment_id: equipmentId, date: selectedDate }, success: function (data) { var bookings = JSON.parse(data); var startTime = new Date(selectedDate + 'T08:00:00'); var endTime = new Date(selectedDate + 'T21:00:00'); // 以 30 分钟间隔生成时间段 for (var time = startTime; time < endTime; time.setMinutes(time.getMinutes() + 30)) { var timeString = time.toTimeString().substring(0, 5); var isBooked = false; // 检查该时间段是否已被预约 for (var i = 0; i < bookings.length; i++) { var bookingStart = new Date(bookings[i].start_time); var bookingEnd = new Date(bookings[i].end_time); if (time >= bookingStart && time < bookingEnd) { isBooked = true; break; } } // 显示时间段 if (isBooked) { $('#timeSlots').append('<div class="time-slot booked">' + timeString + '</div>'); } else { $('#timeSlots').append('<div class="time-slot available" data-time="' + timeString + '">' + timeString + '</div>'); } } // 允许用户选择多个连续的时间段 var selectedSlots = []; $('.available').click(function () { var time = $(this).data('time'); var index = selectedSlots.indexOf(time); if (selectedSlots.length === 0) { // 第一次选择,添加时间段 selectedSlots.push(time); $(this).addClass('selected'); } else { // 获取第一个选择的时间段和当前点击的时间段的索引 var firstIndex = $('.available').index($('.available[data-time="' + selectedSlots[0] + '"]')); var currentIndex = $('.available').index($(this)); // 清除之前的选择 $('.available').removeClass('selected'); selectedSlots = []; // 选择第一个和当前点击的之间的所有时间段 if (currentIndex > firstIndex) { for (var i = firstIndex; i <= currentIndex; i++) { var slotTime = $('.available').eq(i).data('time'); selectedSlots.push(slotTime); $('.available').eq(i).addClass('selected'); } } } // 更新隐藏的表单值 if (selectedSlots.length > 0) { var firstSlot = selectedSlots[0]; var lastSlot = selectedSlots[selectedSlots.length - 1]; $('#selectedStartTime').val(selectedDate + ' ' + firstSlot + ':00'); $('#selectedEndTime').val(selectedDate + ' ' + lastSlot + ':00'); $('#selectedDate').val(selectedDate); $('#submitBookingForm').show(); } else { $('#submitBookingForm').hide(); // 如果没有选中任何时间段,隐藏提交按钮 } }); }, error: function () { $('#booking-info').html('<p class="text-danger">无法获取预约信息,请稍后重试。</p>'); } }); } }); calendar.render(); }); </script> </body> </html>