0) {
$stmt = $pdo->prepare("SELECT * FROM vip_customers WHERE id = ? AND is_active = 1");
$stmt->execute([$vip_id]);
$vip_customer = $stmt->fetch();
if (!$vip_customer) {
throw new Exception('选择的VIP客户无效');
}
// 使用VIP客户信息
$customer_name = $vip_customer['customer_name'];
$phone = $vip_customer['phone'];
$car_model = $vip_customer['car_model'] ?: $car_model; // 允许覆盖
$car_number = $vip_customer['car_number'] ?: $car_number; // 允许覆盖
$member_type = 'VIP会员';
} else {
// 新客户录入
$customer_name = trim($_POST['customer_name']);
$phone = trim($_POST['phone']);
}
$car_model = trim($_POST['car_model']);
$car_number = trim($_POST['car_number']);
$package_id = (int)$_POST['package_id'];
$custom_services = trim($_POST['custom_services'] ?? '');
$appointment_date = $_POST['appointment_date'];
$appointment_time = $_POST['appointment_time'];
$duration = (int)$_POST['duration'];
$notes = trim($_POST['notes'] ?? '');
$member_type = $_POST['member_type'];
$source = $_POST['source'];
// 验证必填字段
if (empty($customer_name) || empty($phone) || empty($car_model) ||
empty($car_number) || empty($appointment_date) || empty($appointment_time)) {
throw new Exception('请填写所有必填字段');
}
// 验证VIP客户或新客户的必填字段
if ($customer_type === 'vip') {
if (empty($vip_id)) {
throw new Exception('请选择一个VIP客户');
}
} else {
if (empty($customer_name) || empty($phone)) {
throw new Exception('请填写客户姓名和联系电话');
}
}
// 验证套餐
if ($package_id) {
$stmt = $pdo->prepare("SELECT * FROM packages WHERE id = ? AND is_active = 1");
$stmt->execute([$package_id]);
$package = $stmt->fetch();
if (!$package) {
throw new Exception('选择的套餐无效');
}
$total_price = $package['price'];
} else {
throw new Exception('请选择一个套餐');
}
// 计算预约时间范围
$start_time = $appointment_date . ' ' . $appointment_time . ':00';
$end_time = date('Y-m-d H:i:s', strtotime($start_time . " +{$duration} minutes"));
// 检查时间冲突
$stmt = $pdo->prepare("SELECT COUNT(*) FROM bookings
WHERE status != '已取消'
AND (
(start_time <= ? AND end_time > ?)
OR (start_time < ? AND end_time >= ?)
OR (start_time >= ? AND end_time <= ?)
)");
$stmt->execute([$start_time, $start_time, $end_time, $end_time, $start_time, $end_time]);
if ($stmt->fetchColumn() > 0) {
throw new Exception('该时间段已被预约,请选择其他时间');
}
// 插入预约记录
// 对于0元订单,自动标记为已付款
$payment_status = ($total_price <= 0) ? '已付款' : '未付款';
$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, member_type, source, payment_status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$customer_name, $phone, $car_model, $car_number, $package_id, $custom_services,
$start_time, $end_time, $duration, $total_price, $notes, $member_type, $source, $payment_status]);
$success_message = "预约提交成功!";
} catch (Exception $e) {
$message = $e->getMessage();
}
}
// 获取套餐列表
$stmt = $pdo->query("SELECT * FROM packages WHERE is_active = 1 ORDER BY price");
$packages = $stmt->fetchAll();
// 获取一周内的预约数据用于日历显示
$start_date = date('Y-m-d');
$end_date = date('Y-m-d', strtotime('+7 days'));
$stmt = $pdo->prepare("SELECT DATE(start_time) as date,
COUNT(*) as booking_count,
GROUP_CONCAT(
CONCAT(
TIME_FORMAT(start_time, '%H:%i'), '-',
TIME_FORMAT(end_time, '%H:%i'),
'(', status, ')'
) ORDER BY start_time SEPARATOR '
'
) as bookings
FROM bookings
WHERE DATE(start_time) BETWEEN ? AND ?
AND status NOT IN ('已完成', '已取消')
GROUP BY DATE(start_time)
ORDER BY date");
$stmt->execute([$start_date, $end_date]);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 将结果转换为键值对格式(日期 => 预约数量)
$booking_schedule = [];
$booking_details = []; // 存储详细的预约信息
foreach ($results as $row) {
$booking_schedule[$row['date']] = $row['booking_count'];
$booking_details[$row['date']] = $row['bookings'];
}
// 获取具体的时间段预约信息供JavaScript使用
$stmt2 = $pdo->prepare("SELECT DATE(start_time) as date,
TIME_FORMAT(start_time, '%H:%i') as start_time,
TIME_FORMAT(end_time, '%H:%i') as end_time,
status,
customer_name,
car_model,
car_number
FROM bookings
WHERE DATE(start_time) BETWEEN ? AND ?
AND status NOT IN ('已完成', '已取消')
ORDER BY date, start_time");
$stmt2->execute([$start_date, $end_date]);
$all_bookings = $stmt2->fetchAll(PDO::FETCH_ASSOC);
// 按日期组织预约数据,处理跨天预约情况
$bookings_by_date = [];
foreach ($all_bookings as $booking) {
$start_date = $booking['date'];
$start_time = $booking['start_time'];
$end_time = $booking['end_time'];
// 将预约添加到开始日期
$bookings_by_date[$start_date][] = $booking;
// 检查是否是跨天预约(结束时间早于开始时间)
if (strtotime($end_time) < strtotime($start_time)) {
// 计算第二天的日期
$next_date = date('Y-m-d', strtotime($start_date . ' +1 day'));
// 创建第二天的预约记录副本
$next_day_booking = $booking;
$next_day_booking['is_cross_day'] = true; // 标记为跨天预约
// 将预约添加到第二天
$bookings_by_date[$next_date][] = $next_day_booking;
}
}
// 获取套餐信息用于JavaScript
$packages_json = json_encode(array_map(function($package) {
$package['services'] = array_filter(array_map('trim', explode(',', $package['services'])));
return $package;
}, $packages));
?>