superlishunqin 170db69eb4 version_1
2025-07-14 05:06:05 +08:00

366 lines
11 KiB
JavaScript
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.

// 订单结算页面脚本
let selectedAddressId = 0;
let subtotal = 0;
// 初始化页面
document.addEventListener('DOMContentLoaded', function() {
// 从页面获取初始数据
const defaultAddress = document.querySelector('input[name="address_id"]:checked');
if (defaultAddress) {
selectedAddressId = parseInt(defaultAddress.value);
}
// 获取商品总价
const subtotalElement = document.getElementById('subtotal');
if (subtotalElement) {
subtotal = parseFloat(subtotalElement.textContent.replace('¥', ''));
}
// 初始化地址卡片动画
initAddressAnimations();
});
// 初始化地址卡片动画
function initAddressAnimations() {
const addressCards = document.querySelectorAll('.address-card');
addressCards.forEach((card, index) => {
card.style.animationDelay = `${index * 0.1}s`;
});
}
// 选择地址(优化版本)
function selectAddress(addressId) {
selectedAddressId = addressId;
// 添加加载状态
const clickedCard = document.querySelector(`[data-address-id="${addressId}"]`);
if (clickedCard) {
clickedCard.classList.add('loading');
}
// 延迟执行UI更新给用户视觉反馈
setTimeout(() => {
// 更新UI
document.querySelectorAll('.address-card').forEach(card => {
card.classList.remove('selected', 'loading');
});
const selectedCard = document.querySelector(`[data-address-id="${addressId}"]`);
if (selectedCard) {
selectedCard.classList.add('selected');
// 添加选中动画效果
selectedCard.style.animation = 'none';
selectedCard.offsetHeight; // 触发重排
selectedCard.style.animation = 'slideIn 0.4s ease';
}
// 更新单选按钮
const radioButton = document.querySelector(`input[value="${addressId}"]`);
if (radioButton) {
radioButton.checked = true;
// 触发单选按钮动画
const radioMark = radioButton.nextElementSibling;
if (radioMark) {
radioMark.style.transform = 'scale(1.1)';
setTimeout(() => {
radioMark.style.transform = 'scale(1)';
}, 200);
}
}
// 显示成功提示
showSelectionFeedback('地址选择成功');
}, 150);
}
// 显示选择反馈
function showSelectionFeedback(message) {
// 创建临时提示元素
const feedback = document.createElement('div');
feedback.className = 'position-fixed top-0 start-50 translate-middle-x mt-3';
feedback.style.zIndex = '9999';
feedback.innerHTML = `
<div class="alert alert-success alert-dismissible fade show" role="alert">
<i class="bi bi-check-circle me-2"></i>
${message}
</div>
`;
document.body.appendChild(feedback);
// 3秒后自动移除
setTimeout(() => {
if (feedback.parentNode) {
feedback.remove();
}
}, 3000);
}
// 更新运费(优化版本)
function updateShippingFee() {
const shippingMethodElement = document.querySelector('input[name="shipping_method"]:checked');
if (!shippingMethodElement) return;
const shippingMethod = shippingMethodElement.value;
let fee = 0;
let description = '';
switch(shippingMethod) {
case 'express':
fee = 10;
description = '次日达服务';
break;
case 'same_day':
fee = 20;
description = '当日达服务';
break;
default:
fee = 0;
description = '标准配送';
}
// 添加动画效果更新价格
const shippingFeeElement = document.getElementById('shippingFee');
const totalAmountElement = document.getElementById('totalAmount');
if (shippingFeeElement && totalAmountElement) {
// 淡出效果
shippingFeeElement.style.opacity = '0.5';
totalAmountElement.style.opacity = '0.5';
setTimeout(() => {
shippingFeeElement.textContent = `¥${fee.toFixed(2)}`;
totalAmountElement.textContent = `¥${(subtotal + fee).toFixed(2)}`;
// 淡入效果
shippingFeeElement.style.opacity = '1';
totalAmountElement.style.opacity = '1';
// 显示配送方式反馈
if (fee > 0) {
showSelectionFeedback(`已选择${description} (+¥${fee})`);
} else {
showSelectionFeedback(`已选择${description} (免费)`);
}
}, 200);
}
}
// 提交订单(优化版本)
function submitOrder() {
// 验证地址选择
if (!selectedAddressId) {
showAlert('请选择收货地址', 'warning');
highlightAddressSection();
return;
}
// 获取表单数据
const shippingMethodElement = document.querySelector('input[name="shipping_method"]:checked');
const paymentMethodElement = document.querySelector('input[name="payment_method"]:checked');
const remarkElement = document.getElementById('orderRemark');
if (!shippingMethodElement) {
showAlert('请选择配送方式', 'warning');
highlightSection('shipping');
return;
}
if (!paymentMethodElement) {
showAlert('请选择支付方式', 'warning');
highlightSection('payment');
return;
}
const shippingMethod = shippingMethodElement.value;
const paymentMethod = paymentMethodElement.value;
const remark = remarkElement ? remarkElement.value : '';
// 获取选中的购物车商品ID
const urlParams = new URLSearchParams(window.location.search);
const selectedItems = urlParams.getAll('items');
if (selectedItems.length === 0) {
showAlert('没有选中的商品', 'error');
return;
}
const orderData = {
selected_items: selectedItems,
address_id: selectedAddressId,
shipping_method: shippingMethod,
payment_method: paymentMethod,
remark: remark
};
// 显示加载状态
const submitBtn = document.querySelector('.btn-danger');
if (!submitBtn) {
showAlert('提交按钮未找到', 'error');
return;
}
const originalText = submitBtn.innerHTML;
submitBtn.innerHTML = '<i class="bi bi-hourglass-split"></i> 提交中...';
submitBtn.disabled = true;
submitBtn.classList.add('loading');
// 添加页面加载遮罩
showLoadingOverlay();
// 提交订单
fetch('/order/create', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(orderData)
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
hideLoadingOverlay();
if (data.success) {
showAlert('订单创建成功!正在跳转到支付页面...', 'success');
// 添加成功动画
submitBtn.innerHTML = '<i class="bi bi-check-circle"></i> 订单创建成功';
submitBtn.classList.add('btn-success');
submitBtn.classList.remove('btn-danger');
setTimeout(() => {
window.location.href = `/order/pay/${data.payment_sn}`;
}, 1500);
} else {
showAlert(data.message || '订单创建失败', 'error');
restoreSubmitButton(submitBtn, originalText);
}
})
.catch(error => {
console.error('提交订单错误:', error);
hideLoadingOverlay();
showAlert('提交订单失败,请重试', 'error');
restoreSubmitButton(submitBtn, originalText);
});
}
// 恢复提交按钮状态
function restoreSubmitButton(submitBtn, originalText) {
submitBtn.innerHTML = originalText;
submitBtn.disabled = false;
submitBtn.classList.remove('loading', 'btn-success');
submitBtn.classList.add('btn-danger');
}
// 高亮地址选择区域
function highlightAddressSection() {
const addressSection = document.querySelector('#addressList');
if (addressSection) {
addressSection.style.border = '2px solid #dc3545';
addressSection.style.borderRadius = '8px';
addressSection.scrollIntoView({ behavior: 'smooth', block: 'center' });
setTimeout(() => {
addressSection.style.border = '';
}, 3000);
}
}
// 高亮指定区域
function highlightSection(sectionType) {
let selector = '';
switch(sectionType) {
case 'shipping':
selector = 'input[name="shipping_method"]';
break;
case 'payment':
selector = 'input[name="payment_method"]';
break;
}
if (selector) {
const element = document.querySelector(selector);
if (element) {
const section = element.closest('.card');
if (section) {
section.style.border = '2px solid #dc3545';
section.scrollIntoView({ behavior: 'smooth', block: 'center' });
setTimeout(() => {
section.style.border = '';
}, 3000);
}
}
}
}
// 显示加载遮罩
function showLoadingOverlay() {
const overlay = document.createElement('div');
overlay.id = 'loadingOverlay';
overlay.className = 'position-fixed top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center';
overlay.style.backgroundColor = 'rgba(0,0,0,0.5)';
overlay.style.zIndex = '9999';
overlay.innerHTML = `
<div class="text-center text-white">
<div class="spinner-border mb-3" role="status">
<span class="visually-hidden">加载中...</span>
</div>
<h5>正在创建订单...</h5>
<p>请稍候,不要关闭页面</p>
</div>
`;
document.body.appendChild(overlay);
}
// 隐藏加载遮罩
function hideLoadingOverlay() {
const overlay = document.getElementById('loadingOverlay');
if (overlay) {
overlay.remove();
}
}
// 增强的提示函数
function showAlert(message, type = 'info') {
const alertClass = {
'success': 'alert-success',
'error': 'alert-danger',
'warning': 'alert-warning',
'info': 'alert-info'
}[type] || 'alert-info';
const icon = {
'success': 'bi-check-circle',
'error': 'bi-exclamation-triangle',
'warning': 'bi-exclamation-triangle',
'info': 'bi-info-circle'
}[type] || 'bi-info-circle';
const alertDiv = document.createElement('div');
alertDiv.className = `alert ${alertClass} alert-dismissible fade show position-fixed top-0 start-50 translate-middle-x mt-3`;
alertDiv.style.zIndex = '10000';
alertDiv.innerHTML = `
<i class="bi ${icon} me-2"></i>
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
document.body.appendChild(alertDiv);
// 5秒后自动移除
setTimeout(() => {
if (alertDiv.parentNode) {
alertDiv.remove();
}
}, 5000);
}