This repository has been archived on 2026-06-20. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
carwash_order/pending_bookings.php
T

1114 lines
48 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
date_default_timezone_set('Asia/Shanghai');
// pending_bookings.php - 待预约页面,处理WPS表单数据
session_start();
require_once 'db_connect.php';
// 处理表单提交
$success_message = '';
$error_message = '';
// 如果有预约转换请求
if (isset($_POST['action']) && $_POST['action'] == 'convert_to_booking' && isset($_POST['submission_id'])) {
$submission_id = $_POST['submission_id'];
$selected_date = $_POST['selected_date'];
$selected_time = $_POST['selected_time'];
$selected_package = $_POST['selected_package'];
$custom_notes = $_POST['custom_notes'];
$total_price = $_POST['total_price'];
$duration = $_POST['duration'];
try {
// 获取WPS表单提交数据
$stmt = $pdo->prepare("SELECT * FROM wps_form_submissions WHERE id = ?");
$stmt->execute([$submission_id]);
$submission = $stmt->fetch();
if (!$submission) {
throw new Exception("表单提交数据不存在");
}
// 获取套餐信息
$stmt = $pdo->prepare("SELECT * FROM packages WHERE id = ?");
$stmt->execute([$selected_package]);
$package = $stmt->fetch();
if (!$package) {
throw new Exception("选择的套餐不存在");
}
// 计算开始和结束时间
$start_time = $selected_date . ' ' . $selected_time;
$end_time = date('Y-m-d H:i:s', strtotime($start_time) + $duration * 60);
// 将数据插入到正式预约表
$stmt = $pdo->prepare("INSERT INTO bookings (
customer_name, phone, car_model, car_number, package_id, custom_services,
start_time, end_time, duration, total_price, notes, status,
member_type, source
) VALUES (
?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?,
?, ?
)");
$stmt->execute([
$submission['name'],
$submission['mobile'],
$submission['car_type'],
$submission['license_plate'],
$selected_package,
$custom_notes,
$start_time,
$end_time,
$duration,
$total_price,
$submission['remarks'],
'已确认', // 默认设置为已确认
'普通客户', // 默认普通客户,可根据需要调整
'其他' // 默认来源,可根据需要调整
]);
$booking_id = $pdo->lastInsertId();
// 更新WPS表单提交状态为已处理
$stmt = $pdo->prepare("UPDATE wps_form_submissions SET status = 'processed' WHERE id = ?");
$stmt->execute([$submission_id]);
// 生成预约成功信息
$booking_success_msg = "预约成功!\n\n客户:{$submission['name']}\n手机号:{$submission['mobile']}\n车牌号:{$submission['license_plate']}\n车型:{$submission['car_type']}\n\n预约时间:{$start_time}\n服务项目:{$package['package_name']}\n服务时长:{$duration}分钟\n总价:{$total_price}\n\n感谢您的预约!";
$success_message = "预约转换成功!预约ID{$booking_id}";
// 存储预约成功信息到会话,以便在页面上显示
$_SESSION['booking_success_msg'] = $booking_success_msg;
} catch (Exception $e) {
$error_message = '预约转换失败:' . $e->getMessage();
}
}
// 获取待处理的WPS表单提交
try {
$stmt = $pdo->prepare("SELECT * FROM wps_form_submissions WHERE status = 'pending' ORDER BY create_time DESC");
$stmt->execute();
$pending_submissions = $stmt->fetchAll();
} catch (Exception $e) {
$error_message = '获取待处理表单失败:' . $e->getMessage();
$pending_submissions = [];
}
// 获取所有套餐
try {
$stmt = $pdo->prepare("SELECT * FROM packages WHERE is_active = true");
$stmt->execute();
$packages = $stmt->fetchAll();
} catch (Exception $e) {
$error_message = '获取套餐信息失败:' . $e->getMessage();
$packages = [];
}
// 获取当前日期及未来7天的日期
$current_date = date('Y-m-d');
$available_dates = [];
for ($i = 0; $i < 7; $i++) {
$available_dates[] = date('Y-m-d', strtotime($current_date . " +$i days"));
}
// 获取所有预约数据,用于显示空闲时间段
$booking_schedule = [];
$bookings_by_date = [];
try {
// 获取所有未来的预约
$stmt = $pdo->prepare("SELECT * FROM bookings WHERE end_time > NOW() ORDER BY start_time ASC");
$stmt->execute();
$all_bookings = $stmt->fetchAll();
// 处理预约数据
foreach ($all_bookings as $booking) {
$start_date = date('Y-m-d', strtotime($booking['start_time']));
$end_date = date('Y-m-d', strtotime($booking['end_time']));
$start_time = date('H:i', strtotime($booking['start_time']));
$end_time = date('H:i', strtotime($booking['end_time']));
// 处理跨天预约
$is_cross_day = $start_date != $end_date;
// 添加到预约日程
if (!isset($booking_schedule[$start_date])) {
$booking_schedule[$start_date] = [];
}
if (!isset($bookings_by_date[$start_date])) {
$bookings_by_date[$start_date] = [];
}
// 主预约记录
$bookings_by_date[$start_date][] = [
'booking_id' => $booking['id'],
'customer_name' => $booking['customer_name'],
'car_model' => $booking['car_model'],
'car_number' => $booking['car_number'],
'status' => $booking['status'],
'start_time' => $start_time,
'end_time' => $end_time,
'is_cross_day' => $is_cross_day
];
// 如果是跨天预约,添加第二天的记录
if ($is_cross_day) {
if (!isset($bookings_by_date[$end_date])) {
$bookings_by_date[$end_date] = [];
}
$bookings_by_date[$end_date][] = [
'booking_id' => $booking['id'],
'customer_name' => $booking['customer_name'],
'car_model' => $booking['car_model'],
'car_number' => $booking['car_number'],
'status' => $booking['status'],
'start_time' => $start_time,
'end_time' => $end_time,
'is_cross_day' => $is_cross_day
];
}
}
} catch (Exception $e) {
$error_message = '获取预约数据失败:' . $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>待预约处理 - 洗车预约系统</title>
<link rel="stylesheet" href="style.css">
<style>
/* 待预约页面特定样式 */
.pending-bookings-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.pending-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
margin-bottom: 20px;
overflow: hidden;
}
.pending-header {
background: #f5f5f5;
padding: 15px 20px;
border-bottom: 1px solid #ddd;
display: flex;
justify-content: space-between;
align-items: center;
}
.pending-details {
padding: 20px;
}
.detail-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
margin-bottom: 20px;
}
.detail-item {
margin-bottom: 10px;
}
.detail-label {
font-weight: bold;
color: #666;
}
.convert-form {
background: #f9f9f9;
padding: 20px;
border-top: 1px solid #ddd;
}
.form-row {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-bottom: 15px;
}
.form-group {
flex: 1;
min-width: 200px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.form-group input, .form-group select, .form-group textarea {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.btn {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: bold;
}
.btn-primary {
background: #007bff;
color: white;
}
.btn-primary:hover {
background: #0056b3;
}
.booking-success {
background: #d4edda;
border: 1px solid #c3e6cb;
color: #155724;
padding: 15px;
border-radius: 4px;
margin: 20px 0;
}
.copy-message {
background: #fff;
border: 1px solid #ddd;
padding: 10px;
border-radius: 4px;
margin-top: 10px;
font-family: monospace;
white-space: pre-wrap;
}
.copy-btn {
background: #28a745;
color: white;
padding: 5px 10px;
border: none;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
}
.status-badge {
padding: 5px 10px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
}
.status-pending {
background: #ffc107;
color: #212529;
}
/* 日历和时间选择样式 */
.calendar-container {
margin-bottom: 20px;
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.calendar-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 10px;
}
.calendar-day {
padding: 15px;
background: #f5f5f5;
border-radius: 4px;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
}
.calendar-day:hover {
background: #e9ecef;
}
.calendar-day.selected {
background: #007bff;
color: white;
}
.time-slots-container {
margin-bottom: 20px;
}
.time-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
gap: 10px;
}
.time-slot {
padding: 10px;
border-radius: 4px;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
}
.time-slot.available {
background: #d4edda;
color: #155724;
}
.time-slot.booked {
background: #f8d7da;
color: #721c24;
cursor: not-allowed;
}
.time-slot.past {
background: #e9ecef;
color: #6c757d;
cursor: not-allowed;
}
.time-slot.selected {
background: #007bff;
color: white;
}
.time-slot:hover.available {
background: #c3e6cb;
}
/* 套餐信息样式 */
.package-info {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
display: none;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
}
.package-info:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}
.package-details {
margin-bottom: 15px;
}
.package-details h4 {
margin: 0 0 12px 0;
color: #2c3e50;
font-size: 18px;
font-weight: 600;
}
.package-meta {
display: flex;
gap: 16px;
margin: 15px 0;
flex-wrap: wrap;
align-items: center;
}
.package-meta span {
background: #e3f2fd;
color: #1976d2;
padding: 6px 12px;
border-radius: 20px;
font-size: 14px;
font-weight: 500;
}
#packageServices_<?php echo $submission['id']; ?> {
margin-top: 15px;
padding: 15px;
background: #ffffff;
border: 1px solid #e0e0e0;
border-radius: 6px;
}
#packageServices_<?php echo $submission['id']; ?> strong {
color: #2c3e50;
font-size: 16px;
display: block;
margin-bottom: 10px;
}
#packageServices_<?php echo $submission['id']; ?> br {
display: none;
}
#packageServices_<?php echo $submission['id']; ?>::before {
content: '';
}
#packageServices_<?php echo $submission['id']; ?>::after {
content: '';
}
.service-list {
margin: 10px 0 0 20px;
padding: 0;
}
.service-list li {
margin-bottom: 6px;
color: #424242;
line-height: 1.6;
font-size: 15px;
}
.service-list li::marker {
color: #1976d2;
font-weight: bold;
}
.booking-detail-item {
background: #fff;
border: 1px solid #e9ecef;
border-radius: 4px;
padding: 10px;
margin-bottom: 10px;
}
.booking-time {
font-weight: bold;
margin-bottom: 5px;
}
.status-已确认 {
color: #28a745;
}
.status-待服务 {
color: #ffc107;
}
.status-已完成 {
color: #6c757d;
}
</style>
</head>
<body>
<div class="pending-bookings-container">
<header class="header">
<h1>🚗 洗车预约系统 - 待预约处理</h1>
<nav class="nav">
<a href="index.php" class="nav-link">预约洗车</a>
<a href="bookings.php" class="nav-link">预约管理</a>
<a href="pending_bookings.php" class="nav-link active">待预约处理</a>
<a href="packages.php" class="nav-link">套餐管理</a>
<a href="vip.php" class="nav-link">VIP管理</a>
<a href="announcement.php" class="nav-link">今日待办</a>
</nav>
</header>
<?php if (isset($success_message)): ?>
<div class="success-message"><?php echo $success_message; ?></div>
<?php endif; ?>
<?php if (isset($error_message)): ?>
<div class="error-message">
<?php echo $error_message; ?>
</div>
<?php endif; ?>
<!-- 预约成功信息显示 -->
<?php if (isset($_SESSION['booking_success_msg'])): ?>
<div class="booking-success">
<h3>预约成功信息已生成</h3>
<div class="copy-message" id="successMessage">
<?php echo htmlspecialchars($_SESSION['booking_success_msg']); ?>
</div>
<button class="copy-btn" onclick="copyMessage()">复制信息</button>
</div>
<?php unset($_SESSION['booking_success_msg']); ?>
<?php endif; ?>
<div class="card">
<h2>待处理预约 (共 <?php echo count($pending_submissions); ?> 条)</h2>
<?php if (empty($pending_submissions)): ?>
<div class="empty-message">暂无待处理的预约请求</div>
<?php else: ?>
<?php foreach ($pending_submissions as $submission): ?>
<div class="pending-card">
<div class="pending-header">
<h3><?php echo htmlspecialchars($submission['name']); ?> 的预约请求</h3>
<span class="status-badge status-pending">待处理</span>
</div>
<div class="pending-details">
<div class="detail-grid">
<div class="detail-item">
<span class="detail-label">联系方式:</span>
<span class="detail-value"><?php echo htmlspecialchars($submission['mobile']); ?></span>
</div>
<div class="detail-item">
<span class="detail-label">车牌号:</span>
<span class="detail-value"><?php echo htmlspecialchars($submission['license_plate']); ?></span>
</div>
<div class="detail-item">
<span class="detail-label">车型:</span>
<span class="detail-value"><?php echo htmlspecialchars($submission['car_type']); ?></span>
</div>
<div class="detail-item">
<span class="detail-label">是否有车衣:</span>
<span class="detail-value"><?php echo htmlspecialchars($submission['has_car_coat']); ?></span>
</div>
<div class="detail-item">
<span class="detail-label">洗车习惯:</span>
<span class="detail-value"><?php echo htmlspecialchars($submission['car_wash_habit']); ?></span>
</div>
<div class="detail-item">
<span class="detail-label">撸车经验:</span>
<span class="detail-value"><?php echo htmlspecialchars($submission['car_wash_experience']); ?></span>
</div>
<div class="detail-item">
<span class="detail-label">洗车频率:</span>
<span class="detail-value"><?php echo htmlspecialchars($submission['wash_frequency']); ?></span>
</div>
<div class="detail-item">
<span class="detail-label">年龄段:</span>
<span class="detail-value"><?php echo htmlspecialchars($submission['age_group']); ?></span>
</div>
<div class="detail-item">
<span class="detail-label">自动编号:</span>
<span class="detail-value"><?php echo htmlspecialchars($submission['auto_number']); ?></span>
</div>
<div class="detail-item">
<span class="detail-label">提交时间:</span>
<span class="detail-value"><?php echo htmlspecialchars($submission['create_time']); ?></span>
</div>
</div>
<?php if (!empty($submission['remarks'])): ?>
<div class="detail-item">
<span class="detail-label">备注:</span>
<span class="detail-value"><?php echo htmlspecialchars($submission['remarks']); ?></span>
</div>
<?php endif; ?>
</div>
<div class="convert-form">
<h4>转换为正式预约</h4>
<form method="POST" action="pending_bookings.php">
<input type="hidden" name="action" value="convert_to_booking">
<input type="hidden" name="submission_id" value="<?php echo $submission['id']; ?>">
<div class="form-group">
<label for="selected_package_<?php echo $submission['id']; ?>">选择套餐:</label>
<select id="selected_package_<?php echo $submission['id']; ?>" name="selected_package" required onchange="updatePackageInfo(<?php echo $submission['id']; ?>)">
<option value="">请选择套餐</option>
<?php foreach ($packages as $package): ?>
<option value="<?php echo $package['id']; ?>"
data-duration="<?php echo $package['base_duration']; ?>"
data-price="<?php echo $package['price']; ?>"
data-services='<?php echo htmlspecialchars($package['services']); ?>'>
<?php echo htmlspecialchars($package['package_name']); ?> - ¥<?php echo number_format($package['price'], 2); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="package-info" id="packageInfo_<?php echo $submission['id']; ?>">
<div class="package-details">
<h4 id="packageName_<?php echo $submission['id']; ?>"></h4>
<div class="package-meta">
<span id="packageDuration_<?php echo $submission['id']; ?>"></span>
<span id="packagePrice_<?php echo $submission['id']; ?>"></span>
</div>
<div class="form-group" style="margin-top: 15px;">
<label for="total_price_<?php echo $submission['id']; ?>">最终价格 (¥)</label>
<input type="number" id="total_price_<?php echo $submission['id']; ?>" name="total_price" min="0" step="0.01" value="0" placeholder="输入最终价格" required>
<input type="hidden" id="package_price_<?php echo $submission['id']; ?>" value="0">
</div>
<div id="packageServices_<?php echo $submission['id']; ?>"></div>
</div>
</div>
<div class="calendar-container">
<div class="calendar-header">
<h5>选择预约日期</h5>
</div>
<div class="calendar-grid" id="calendarGrid_<?php echo $submission['id']; ?>">
<?php foreach ($available_dates as $date): ?>
<div class="calendar-day"
data-date="<?php echo $date; ?>"
onclick="selectDate(<?php echo $submission['id']; ?>, '<?php echo $date; ?>')">
<div><?php echo date('m月d日', strtotime($date)); ?></div>
<div><?php echo date('D', strtotime($date)); ?></div>
</div>
<?php endforeach; ?>
</div>
</div>
<div class="form-group">
<input type="hidden" id="selected_date_<?php echo $submission['id']; ?>" name="selected_date" value="<?php echo date('Y-m-d'); ?>">
<input type="hidden" id="selected_time_<?php echo $submission['id']; ?>" name="selected_time" value="" required>
</div>
<div class="time-slots-container">
<h5>选择预约时间</h5>
<div class="time-grid" id="timeGrid_<?php echo $submission['id']; ?>">
<!-- 时间格子将通过JavaScript生成 -->
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="duration_<?php echo $submission['id']; ?>">服务时长(分钟)</label>
<div class="quick-duration">
<button type="button" class="duration-btn" data-duration="60" onclick="selectDuration(<?php echo $submission['id']; ?>, 60)">1小时</button>
<button type="button" class="duration-btn" data-duration="90" onclick="selectDuration(<?php echo $submission['id']; ?>, 90)">1.5小时</button>
<button type="button" class="duration-btn" data-duration="120" onclick="selectDuration(<?php echo $submission['id']; ?>, 120)">2小时</button>
<button type="button" class="duration-btn" data-duration="240" onclick="selectDuration(<?php echo $submission['id']; ?>, 240)">4小时</button>
<button type="button" class="duration-btn" data-duration="360" onclick="selectDuration(<?php echo $submission['id']; ?>, 360)">6小时</button>
<button type="button" class="duration-btn" data-duration="480" onclick="selectDuration(<?php echo $submission['id']; ?>, 480)">8小时</button>
<button type="button" class="duration-btn" data-duration="600" onclick="selectDuration(<?php echo $submission['id']; ?>, 600)">10小时</button>
<button type="button" class="duration-btn" data-duration="720" onclick="selectDuration(<?php echo $submission['id']; ?>, 720)">12小时</button>
<input type="number" id="customDuration_<?php echo $submission['id']; ?>" min="30" step="30" value="60" style="width: 80px; margin-left: 10px;">
<button type="button" class="btn btn-sm" onclick="applyCustomDuration(<?php echo $submission['id']; ?>)">确定</button>
</div>
<input type="number" id="duration_<?php echo $submission['id']; ?>" name="duration" min="30" step="30" value="60" required style="margin-top: 10px;">
</div>
</div>
<div class="form-group">
<label for="custom_notes_<?php echo $submission['id']; ?>">自定义服务需求:</label>
<textarea id="custom_notes_<?php echo $submission['id']; ?>" name="custom_notes" rows="3"
placeholder="如有特殊需求,请在此说明..."></textarea>
</div>
<button type="submit" class="btn btn-primary">确认预约</button>
</form>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
<script>
// 复制预约成功信息到剪贴板
function copyMessage() {
const message = document.getElementById('successMessage');
const textArea = document.createElement('textarea');
textArea.value = message.textContent;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
// 显示复制成功提示
alert('预约信息已复制到剪贴板!');
}
// 工作时间设置
const workingHours = {
start: 0, // 00:00
end: 24, // 24:00
slotDuration: 30 // 30分钟一个时段
};
// 预约数据 - 为每个提交创建独立的预约数据对象
const allBookingsByDate = <?php echo json_encode($bookings_by_date); ?>;
// 页面加载时初始化所有预约的日期、时间和套餐信息
document.addEventListener('DOMContentLoaded', function() {
<?php foreach ($pending_submissions as $submission): ?>
// 初始化日期
selectDate(<?php echo $submission['id']; ?>, '<?php echo date('Y-m-d'); ?>');
// 初始化默认套餐信息(如果有默认选择的话)
const packageSelect = document.getElementById('selected_package_<?php echo $submission['id']; ?>');
if (packageSelect.value) {
updatePackageInfo(<?php echo $submission['id']; ?>);
} else if (packageSelect.options.length > 1) {
// 默认选择第一个套餐
packageSelect.selectedIndex = 1;
updatePackageInfo(<?php echo $submission['id']; ?>);
}
<?php endforeach; ?>
});
// 选择日期
function selectDate(submissionId, date) {
const calendarGrid = document.getElementById('calendarGrid_' + submissionId);
const timeGrid = document.getElementById('timeGrid_' + submissionId);
const selectedDateInput = document.getElementById('selected_date_' + submissionId);
// 更新日期输入
selectedDateInput.value = date;
// 更新日历选中状态
calendarGrid.querySelectorAll('.calendar-day').forEach(day => {
day.classList.remove('selected');
});
// 找到当前日历中的日期元素
const calendarDays = calendarGrid.querySelectorAll('.calendar-day');
calendarDays.forEach(day => {
if (day.dataset.date === date) {
day.classList.add('selected');
}
});
// 生成时间段
generateTimeSlots(submissionId, date);
}
// 生成时间段
function generateTimeSlots(submissionId, date) {
const timeGrid = document.getElementById('timeGrid_' + submissionId);
const selectedTimeInput = document.getElementById('selected_time_' + submissionId);
timeGrid.innerHTML = '';
// 获取当天已有预约
const dayBookings = allBookingsByDate[date] || [];
// 生成时间段
for (let hour = workingHours.start; hour < workingHours.end; hour++) {
for (let minute = 0; minute < 60; minute += workingHours.slotDuration) {
const timeString = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;
const slotTime = new Date(`${date} ${timeString}:00`);
const now = new Date();
const isPast = slotTime <= now;
const isBooked = checkTimeSlotBooked(date, timeString);
const slotDiv = document.createElement('div');
slotDiv.className = `time-slot ${isPast ? 'past' : ''} ${isBooked ? 'booked' : 'available'}`;
slotDiv.textContent = timeString;
slotDiv.dataset.time = timeString;
// 只有可用的时间段才添加点击事件
if (!isPast && !isBooked) {
slotDiv.onclick = () => selectTimeSlot(submissionId, timeString);
} else {
// 禁用不可点击的时间段
slotDiv.style.cursor = 'not-allowed';
}
timeGrid.appendChild(slotDiv);
}
}
selectedTimeInput.value = '';
}
// 检查时间段是否已被预约
function checkTimeSlotBooked(date, time) {
const bookings = allBookingsByDate[date] || [];
for (let booking of bookings) {
const bookingStart = booking.start_time;
const bookingEnd = booking.end_time;
// 处理跨天预约的情况
if (booking.is_cross_day) {
// 如果是跨天预约的第二天记录,所有时间都应该是已被预约的(从00:00到结束时间)
if (time < bookingEnd) {
return true; // 该时间段已被预约
}
} else {
// 正常预约检查
if (time >= bookingStart && time < bookingEnd) {
return true; // 该时间段已被预约
}
}
}
return false; // 该时间段可用
}
// 选择时间
function selectTimeSlot(submissionId, time) {
const selectedTimeInput = document.getElementById('selected_time_' + submissionId);
// 更新时间输入
selectedTimeInput.value = time;
// 更新时间段选中状态
const timeGrid = document.getElementById('timeGrid_' + submissionId);
timeGrid.querySelectorAll('.time-slot').forEach(slot => {
slot.classList.remove('selected');
});
const slotElement = timeGrid.querySelector(`[data-time="${time}"]`);
if (slotElement) {
slotElement.classList.add('selected');
}
}
// 更新套餐信息
function updatePackageInfo(submissionId) {
console.log('=== updatePackageInfo called with submissionId:', submissionId, '===');
// 直接获取表单元素,确保在正确的表单上下文中操作
const packageSelect = document.getElementById('selected_package_' + submissionId);
if (!packageSelect) {
console.error('❌ Package select not found for submissionId:', submissionId);
return;
}
// 获取当前表单
const form = packageSelect.closest('form');
if (!form) {
console.error('❌ Form not found for submissionId:', submissionId);
return;
}
const selectedOption = packageSelect.options[packageSelect.selectedIndex];
const packageInfoDiv = document.getElementById('packageInfo_' + submissionId);
console.log('Selected option:', selectedOption, 'value:', selectedOption ? selectedOption.value : 'null');
if (selectedOption && selectedOption.value) {
// 使用getAttribute方法获取data属性,确保兼容所有浏览器
const duration = parseInt(selectedOption.getAttribute('data-duration'));
const price = parseFloat(selectedOption.getAttribute('data-price'));
const servicesJSON = selectedOption.getAttribute('data-services');
let services = [];
// 尝试解析servicesJSON,如果解析失败则将其视为逗号分隔字符串
if (servicesJSON) {
try {
// 尝试作为JSON解析
services = JSON.parse(servicesJSON);
console.log('✅ Parsed services as JSON:', services);
} catch (e) {
// 如果JSON解析失败,尝试作为逗号分隔字符串处理
console.log('⚠️ JSON parse failed, treating as comma-separated string:', servicesJSON);
services = servicesJSON.split(',').map(service => service.trim()).filter(service => service.length > 0);
console.log('✅ Converted to array:', services);
}
}
console.log('Package data:', {duration, price, services: services.length});
// 更新套餐信息显示
const packageNameElement = document.getElementById('packageName_' + submissionId);
const packageDurationElement = document.getElementById('packageDuration_' + submissionId);
const packagePriceElement = document.getElementById('packagePrice_' + submissionId);
if (packageNameElement) packageNameElement.textContent = selectedOption.textContent;
if (packageDurationElement) packageDurationElement.textContent = `基础时长: ${duration}分钟`;
if (packagePriceElement) packagePriceElement.textContent = `套餐价格: ¥${price.toFixed(2)}`;
// 更新服务项目显示
const servicesContainer = document.getElementById('packageServices_' + submissionId);
if (servicesContainer) {
if (services && services.length > 0) {
servicesContainer.innerHTML = '<strong>包含服务:</strong><ul class="service-list">' +
services.map(service => `<li>${service}</li>`).join('') + '</ul>';
} else {
servicesContainer.innerHTML = '';
}
}
// 使用两种方式获取时长输入框,确保万无一失
const durationInputById = document.getElementById('duration_' + submissionId);
const durationInputByName = form.querySelector('input[name="duration"]');
console.log('Duration inputs found - by ID:', durationInputById ? 'Yes' : 'No', 'by Name:', durationInputByName ? 'Yes' : 'No');
// 优先使用ID获取的元素,如果不存在则使用name获取的元素
const durationInput = durationInputById || durationInputByName;
if (durationInput) {
// 强制设置时长值
durationInput.value = duration;
// 触发change事件,确保所有依赖此输入的功能都能更新
durationInput.dispatchEvent(new Event('change'));
console.log('✅ Successfully updated duration input to:', duration);
} else {
console.error('❌ Cannot find duration input for submissionId:', submissionId);
}
// 同时更新自定义时长输入框
const customDurationInput = document.getElementById('customDuration_' + submissionId);
if (customDurationInput) {
customDurationInput.value = duration;
console.log('✅ Successfully updated custom duration input to:', duration);
} else {
console.error('❌ Cannot find custom duration input for submissionId:', submissionId);
}
// 更新价格输入框
const totalPriceInput = document.getElementById('total_price_' + submissionId);
if (totalPriceInput) {
totalPriceInput.value = price.toFixed(2);
console.log('✅ Updated total price to:', price.toFixed(2));
}
// 更新快捷选择按钮状态
console.log('Calling selectDuration with:', submissionId, duration);
selectDuration(submissionId, duration);
// 显示套餐信息
if (packageInfoDiv) {
packageInfoDiv.style.display = 'block';
}
} else {
if (packageInfoDiv) {
packageInfoDiv.style.display = 'none';
}
console.log('❌ No package selected');
}
}
// 快捷选择服务时长
function selectDuration(submissionId, minutes) {
console.log('=== selectDuration called with submissionId:', submissionId, 'minutes:', minutes, '===');
// 先检查minutes是否有效
if (isNaN(minutes) || minutes <= 0) {
console.error('❌ Invalid minutes value:', minutes);
return;
}
// 使用两种方式获取表单,确保找到正确的表单
let form = null;
// 方式1:通过套餐选择元素获取表单
const packageSelect = document.getElementById('selected_package_' + submissionId);
if (packageSelect) {
form = packageSelect.closest('form');
console.log('Form found via packageSelect:', form ? 'Yes' : 'No');
}
// 方式2:如果方式1失败,通过时长输入框获取表单
if (!form) {
const durationInputById = document.getElementById('duration_' + submissionId);
if (durationInputById) {
form = durationInputById.closest('form');
console.log('Form found via durationInputById:', form ? 'Yes' : 'No');
}
}
// 方式3:如果还是失败,尝试通过packageInfo找到表单
if (!form) {
const packageInfo = document.getElementById('packageInfo_' + submissionId);
if (packageInfo) {
form = packageInfo.closest('form');
console.log('Form found via packageInfo:', form ? 'Yes' : 'No');
}
}
// 方式4:如果还是失败,尝试通过自定义时长输入框找到表单
if (!form) {
const customDurationInput = document.getElementById('customDuration_' + submissionId);
if (customDurationInput) {
form = customDurationInput.closest('form');
console.log('Form found via customDurationInput:', form ? 'Yes' : 'No');
}
}
if (!form) {
console.error('❌ Form not found for submissionId:', submissionId);
return;
}
// 使用两种方式获取时长输入框,确保万无一失
const durationInputById = document.getElementById('duration_' + submissionId);
const durationInputByName = form.querySelector('input[name="duration"]');
const durationInput = durationInputById || durationInputByName;
if (durationInput) {
// 强制设置时长值
durationInput.value = minutes;
// 触发change事件,确保所有依赖此输入的功能都能更新
durationInput.dispatchEvent(new Event('change'));
console.log('✅ Duration input updated to:', minutes);
} else {
console.error('❌ Duration input not found for submissionId:', submissionId);
}
// 更新自定义时长输入框
const customDurationInput = document.getElementById('customDuration_' + submissionId);
if (customDurationInput) {
customDurationInput.value = minutes;
console.log('✅ Custom duration input updated to:', minutes);
} else {
console.error('❌ Custom duration input not found for submissionId:', submissionId);
}
// 获取当前表单的时长按钮
const durationButtons = form.querySelectorAll('.duration-btn');
console.log('Found duration buttons:', durationButtons.length);
if (durationButtons.length === 0) {
console.warn('⚠️ No duration buttons found in form');
return;
}
// 更新按钮选中状态
let buttonFound = false;
durationButtons.forEach(btn => {
// 使用getAttribute获取data属性,确保兼容所有浏览器
const btnDuration = parseInt(btn.getAttribute('data-duration'));
console.log('Checking button:', btn.textContent, 'data-duration:', btnDuration);
if (btnDuration === minutes) {
btn.classList.add('selected');
console.log('✅ Added selected class to button with duration:', btnDuration);
buttonFound = true;
} else {
btn.classList.remove('selected');
}
});
if (!buttonFound) {
console.warn('⚠️ No matching duration button found for:', minutes, 'minutes');
}
}
// 应用自定义时长
function applyCustomDuration(submissionId) {
const customDurationInput = document.getElementById('customDuration_' + submissionId);
const customDuration = parseInt(customDurationInput.value);
const maxDuration = 720; // 最大时长为12小时(720分钟)
if (customDuration < 30) {
alert('最小服务时长为30分钟');
customDurationInput.value = 30;
selectDuration(submissionId, 30);
} else if (customDuration > maxDuration) {
alert('最大服务时长为12小时(720分钟)');
customDurationInput.value = maxDuration;
selectDuration(submissionId, maxDuration);
} else {
// 确保时长是30的倍数
const roundedDuration = Math.round(customDuration / 30) * 30;
customDurationInput.value = roundedDuration;
selectDuration(submissionId, roundedDuration);
}
}
</script>
</body>
</html>