Newer
Older
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?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 {
background-color: #f8f9fa;
padding: 10px;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.calendar-title {
text-align: center;
font-size: 24px;
font-weight: bold;
margin-bottom: 20px;
color: #343a40;
}
.divider {
border-top: 2px solid #dee2e6;
margin: 40px 0;
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
}
.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">
<!-- 添加链接到“我的预约”页面 -->
<div class="mb-3">
<a href="equipment_status.php" class="btn btn-secondary">返回设备详细列表</a>
<a href="equipment_list.php" class="btn btn-secondary">返回设备简表</a>
<a href="my_bookings.php" class="btn btn-info">查看我的预约</a>
</div>
<h2>预约 <?php echo htmlspecialchars($equipment['name'], ENT_QUOTES, 'UTF-8'); ?></h2>
<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 nl2br(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">
>> 先从左侧日历选择日期,再选择时间段<br />
>> 请在时间表上选择起始时间,结束时间必须在开始时间之后,否则会取消所选时间。<br />
>> 预约的时长=结束时间-起始时间,最短预约时间为半小时。<br />
>> 例如:如果起始时间为10:00,结束时间是11:00,虽然显示占据了3个格子,但实际预约的时长仅为1小时!
</div>
<div id="timeSlots" class="mt-4"></div>
</div>
</div>
<label for="title" style="font-size: 20px">实验目的(一句话概括本次预约的实验目的。例如: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']; ?>" style="font-size: 20px">
<?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" disabled>提交预约</button>
</form>
</div>
<script>
$(document).ready(function () {
let submitButton = document.getElementById("submitBookingForm");
submitButton.disabled = true;
// 初始化 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 today = new Date();
today.setHours(0, 0, 0, 0);
var selectedDate = new Date(info.dateStr);
if (selectedDate < today) {
alert('不能选择过去的日期,请选择今天或之后的日期。');
return;
}
// 用户选择了日期,自动触发检查预约情况
var equipmentId = <?php echo $equipment['id']; ?>;
// 清空之前的时间段
$('#timeSlots').html('');
// 发送 AJAX 请求,获取当天的预约情况
$.ajax({
url: 'fetch_bookings.php',
type: 'POST',
data: {
equipment_id: equipmentId,
},
success: function (data) {
var bookings = JSON.parse(data);
var startTime = new Date(info.dateStr + 'T08:00:00');
var endTime = new Date(info.dateStr + 'T21:00:00');
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
// 以 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);
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');
}
}
var firstSlot = selectedSlots[0];
var lastSlot = selectedSlots[selectedSlots.length - 1];
var start = new Date(info.dateStr + ' ' + firstSlot + ':00');
var end = new Date(info.dateStr + ' ' + lastSlot + ':00');
var duration = (end - start) / (1000 * 60 * 60); // 时长,以分钟为单位
if (duration > 5) {
alert('每次预约的时长不能超过5小时。');
submitButton.disabled = true;
$('#selectedStartTime').val(info.dateStr + ' ' + firstSlot + ':00');
$('#selectedEndTime').val(info.dateStr + ' ' + lastSlot + ':00');
$('#selectedDate').val(info.dateStr);