feat: 新增预约系统功能及优化

- 添加获取每日预约时长的API接口
- 实现0元订单自动标记为已付款功能
- 优化预约信息复制功能,增加服务时长和备注
- 新增预约信息模板系统
- 在待处理预约页面添加时长提示功能
- 优化移动端触摸反馈和倒计时显示
This commit is contained in:
2025-12-06 05:05:15 +08:00
parent a672e1d7bc
commit b963c2b513
7 changed files with 558 additions and 26 deletions
+98 -3
View File
@@ -42,14 +42,17 @@ if (isset($_POST['action']) && $_POST['action'] == 'convert_to_booking' && isset
$end_time = date('Y-m-d H:i:s', strtotime($start_time) + $duration * 60);
// 将数据插入到正式预约表
// 对于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, status,
member_type, source
member_type, source, payment_status
) VALUES (
?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?,
?, ?
?, ?, ?
)");
$stmt->execute([
@@ -66,7 +69,8 @@ if (isset($_POST['action']) && $_POST['action'] == 'convert_to_booking' && isset
$submission['remarks'],
'已确认', // 默认设置为已确认
'普通客户', // 默认普通客户,可根据需要调整
'其他' // 默认来源,可根据需要调整
'其他', // 默认来源,可根据需要调整
$payment_status // 根据总价自动设置付款状态
]);
$booking_id = $pdo->lastInsertId();
@@ -430,6 +434,32 @@ try {
background: #c3e6cb;
}
/* 预约时长提示样式 */
.duration-alert {
margin: 15px 0;
padding: 15px;
border-radius: 4px;
font-weight: bold;
}
.duration-alert .alert {
padding: 12px;
border-radius: 4px;
margin-bottom: 0;
}
.duration-alert .alert-warning {
background-color: #fff3cd;
border-color: #ffeaa7;
color: #856404;
}
.duration-alert .alert-info {
background-color: #d1ecf1;
border-color: #bee5eb;
color: #0c5460;
}
/* 套餐信息样式 */
.package-info {
background: #f8f9fa;
@@ -723,6 +753,11 @@ try {
</div>
</div>
<!-- 预约时长提示区域 -->
<div class="duration-alert" id="durationAlert_<?php echo $submission['id']; ?>">
<!-- 提示信息将通过JavaScript动态生成 -->
</div>
<div class="form-row">
<div class="form-group">
<label for="customDuration_<?php echo $submission['id']; ?>">服务时长(分钟)</label>
@@ -852,6 +887,9 @@ try {
// 生成时间段
generateTimeSlots(submissionId, date);
// 显示时长提示
showDurationAlert(submissionId);
}
// 生成时间段
@@ -934,6 +972,9 @@ try {
if (slotElement) {
slotElement.classList.add('selected');
}
// 显示时长提示
showDurationAlert(submissionId);
}
// 更新套餐信息
@@ -1137,6 +1178,9 @@ try {
if (!buttonFound) {
console.warn('⚠️ No matching duration button found for:', minutes, 'minutes');
}
// 显示时长提示
showDurationAlert(submissionId);
}
// 应用自定义时长
@@ -1159,6 +1203,57 @@ try {
customDurationInput.value = roundedDuration;
selectDuration(submissionId, roundedDuration);
}
// 显示时长提示
showDurationAlert(submissionId);
}
// 计算当天总预约时长(异步函数)
async function calculateDailyTotalDuration(submissionId) {
const selectedDate = document.getElementById('selected_date_' + submissionId).value;
const currentDuration = parseInt(document.getElementById('customDuration_' + submissionId).value);
try {
// 通过AJAX请求获取当天已有的预约时长
const response = await fetch(`get_daily_booking_duration.php?date=${selectedDate}`);
const data = await response.json();
if (data.error) {
console.error('获取当天预约时长失败:', data.error);
return currentDuration; // 如果获取失败,只返回当前预约时长
}
const existingDuration = data.total_duration || 0;
return existingDuration + currentDuration;
} catch (error) {
console.error('获取当天预约时长出错:', error);
return currentDuration; // 如果出错,只返回当前预约时长
}
}
// 显示时长提示
async function showDurationAlert(submissionId) {
const alertContainer = document.getElementById('durationAlert_' + submissionId);
// 清空现有提示
alertContainer.innerHTML = '<div class="alert alert-info">加载中...</div>';
try {
const totalDuration = await calculateDailyTotalDuration(submissionId);
// 清空现有提示
alertContainer.innerHTML = '';
// 根据总时长显示不同的提示
if (totalDuration >= 720) { // 大于等于12小时
alertContainer.innerHTML = '<div class="alert alert-warning">⚠️ 当天总预约时长已达到12小时,你要当超人啊,别约了!</div>';
} else if (totalDuration >= 360) { // 大于等于6小时
alertContainer.innerHTML = '<div class="alert alert-info">💡 当天总预约时长已达到6小时,注意休息!</div>';
}
} catch (error) {
console.error('计算总预约时长出错:', error);
alertContainer.innerHTML = '';
}
}
</script>
</body>