// 全局变量 let currentProduct = null; let currentOrder = null; let appliedCoupon = null; // 当前应用的优惠码 // DOM 元素 const productPrice = document.getElementById('product-price'); const quantityInput = document.getElementById('quantity'); const totalPriceElement = document.getElementById('total-price'); const orderForm = document.getElementById('orderForm'); const orderModal = document.getElementById('orderModal'); const paymentStatus = document.getElementById('paymentStatus'); // 初始化 document.addEventListener('DOMContentLoaded', function() { loadProductData(); setupEventListeners(); }); // 加载产品数据 async function loadProductData() { try { const response = await fetch('/api/products'); const products = await response.json(); // 使用第一个产品作为展示产品 const productId = Object.keys(products)[0]; currentProduct = { id: productId, ...products[productId] }; // 更新界面 document.getElementById('product-name').textContent = currentProduct.name; document.getElementById('product-price').textContent = currentProduct.price.toFixed(2); document.getElementById('unit-price').textContent = currentProduct.price.toFixed(2); updateTotalPrice(); } catch (error) { console.error('加载产品数据失败:', error); alert('加载产品信息失败,请刷新页面重试'); } } // 设置事件监听器 function setupEventListeners() { // 数量控制 document.getElementById('decrease-qty').addEventListener('click', () => { const current = parseInt(quantityInput.value) || 1; if (current > 1) { quantityInput.value = current - 1; updateTotalPrice(); } }); document.getElementById('increase-qty').addEventListener('click', () => { const current = parseInt(quantityInput.value) || 1; if (current < 999) { quantityInput.value = current + 1; updateTotalPrice(); } }); // 数量输入变化 quantityInput.addEventListener('input', updateTotalPrice); quantityInput.addEventListener('change', validateQuantity); // 手机号验证 document.getElementById('customer_phone').addEventListener('blur', validatePhone); document.getElementById('customer_phone').addEventListener('input', function(e) { // 只允许输入数字 e.target.value = e.target.value.replace(/[^0-9]/g, ''); // 限制长度为11位 if (e.target.value.length > 11) { e.target.value = e.target.value.slice(0, 11); } }); // 表单提交 - 显示配送信息模态框 orderForm.addEventListener('submit', function(e) { e.preventDefault(); showShippingInfoModal(); }); // 模态框控制 document.getElementById('closeModal').addEventListener('click', closeOrderModal); document.getElementById('pay-now-btn').addEventListener('click', handlePayNow); // 配送信息模态框控制 document.getElementById('closeShippingModal').addEventListener('click', closeShippingInfoModal); document.getElementById('shippingForm').addEventListener('submit', handleShippingOrderSubmit); // 手机号验证 - 模态框中的 document.getElementById('modal_customer_phone').addEventListener('blur', function() { validatePhoneField(this); }); document.getElementById('modal_customer_phone').addEventListener('input', function(e) { // 只允许输入数字 e.target.value = e.target.value.replace(/[^0-9]/g, ''); // 限制长度为11位 if (e.target.value.length > 11) { e.target.value = e.target.value.slice(0, 11); } }); // 优惠码输入监听 document.getElementById('coupon-code').addEventListener('input', function(e) { // 自动转换为大写 e.target.value = e.target.value.toUpperCase(); // 清除已应用的优惠码状态 if (appliedCoupon) { clearAppliedCoupon(); } }); // 优惠码回车键应用 document.getElementById('coupon-code').addEventListener('keypress', function(e) { if (e.key === 'Enter') { e.preventDefault(); applyCoupon(); } }); // 支付状态检查 document.getElementById('check-status-btn').addEventListener('click', checkPaymentStatus); // 点击模态框外部关闭 orderModal.addEventListener('click', (e) => { if (e.target === orderModal) { closeOrderModal(); } }); } // 更新总价 function updateTotalPrice() { if (!currentProduct) return; const quantity = parseInt(quantityInput.value) || 1; const unitPrice = currentProduct.price; const originalTotal = unitPrice * quantity; // 计算数量折扣 let quantityDiscount = 0; let quantityDiscountText = ''; let afterQuantityDiscount = originalTotal; if (quantity >= 5) { quantityDiscount = originalTotal * 0.1; // 9折,优惠10% quantityDiscountText = '5个及以上 9折优惠'; afterQuantityDiscount = originalTotal * 0.9; } else if (quantity >= 2) { quantityDiscount = originalTotal * 0.05; // 9.5折,优惠5% quantityDiscountText = '2个 9.5折优惠'; afterQuantityDiscount = originalTotal * 0.95; } // 计算优惠码折扣 let couponDiscount = 0; let finalTotal = afterQuantityDiscount; if (appliedCoupon) { if (appliedCoupon.discount_type === 'percentage') { couponDiscount = afterQuantityDiscount * (appliedCoupon.discount_value / 100); } else if (appliedCoupon.discount_type === 'fixed') { couponDiscount = Math.min(appliedCoupon.discount_value, afterQuantityDiscount); } finalTotal = afterQuantityDiscount - couponDiscount; } // 更新显示 const discountLine = document.getElementById('discount-line'); const subtotalLine = document.getElementById('subtotal-line'); const couponDiscountLine = document.getElementById('coupon-discount-line'); const discountTextElement = document.getElementById('discount-text'); const subtotalPriceElement = document.getElementById('subtotal-price'); const couponDiscountTextElement = document.getElementById('coupon-discount-text'); // 数量折扣显示 if (quantityDiscount > 0) { discountTextElement.textContent = `-$${quantityDiscount.toFixed(2)} USDT (${quantityDiscountText})`; subtotalPriceElement.textContent = `$${originalTotal.toFixed(2)} USDT`; discountLine.classList.remove('no-discount'); } else { discountTextElement.textContent = `$0.00 USDT (无优惠)`; subtotalPriceElement.textContent = `$${originalTotal.toFixed(2)} USDT`; discountLine.classList.add('no-discount'); } // 优惠码折扣显示 if (appliedCoupon && couponDiscount > 0) { couponDiscountTextElement.textContent = `-$${couponDiscount.toFixed(2)} USDT (${appliedCoupon.name})`; couponDiscountLine.style.display = 'flex'; } else { couponDiscountLine.style.display = 'none'; } discountLine.style.display = 'flex'; subtotalLine.style.display = 'flex'; totalPriceElement.textContent = `$${finalTotal.toFixed(2)} USDT`; } // 显示配送信息模态框 function showShippingInfoModal() { if (!currentProduct) return; const quantity = parseInt(quantityInput.value) || 1; const unitPrice = currentProduct.price; const originalTotal = unitPrice * quantity; // 计算数量折扣 let quantityDiscount = 0; let quantityDiscountText = ''; let afterQuantityDiscount = originalTotal; if (quantity >= 5) { quantityDiscount = originalTotal * 0.1; quantityDiscountText = '9折优惠 (-10%)'; afterQuantityDiscount = originalTotal * 0.9; } else if (quantity >= 2) { quantityDiscount = originalTotal * 0.05; quantityDiscountText = '9.5折优惠 (-5%)'; afterQuantityDiscount = originalTotal * 0.95; } // 计算优惠码折扣 let couponDiscount = 0; let finalTotal = afterQuantityDiscount; if (appliedCoupon) { if (appliedCoupon.discount_type === 'percentage') { couponDiscount = afterQuantityDiscount * (appliedCoupon.discount_value / 100); } else if (appliedCoupon.discount_type === 'fixed') { couponDiscount = Math.min(appliedCoupon.discount_value, afterQuantityDiscount); } finalTotal = afterQuantityDiscount - couponDiscount; } // 更新订单汇总信息 document.getElementById('summary-product-name').textContent = currentProduct.name; document.getElementById('summary-quantity').textContent = quantity; document.getElementById('summary-unit-price').textContent = `$${unitPrice.toFixed(2)} USDT`; document.getElementById('summary-total-price').textContent = `$${finalTotal.toFixed(2)} USDT`; // 更新折扣信息 const discountRow = document.querySelector('.discount-row'); const discountTextElement = document.getElementById('summary-discount-text'); if (quantityDiscount > 0 || couponDiscount > 0) { let totalDiscountAmount = quantityDiscount + couponDiscount; let discountDescription = ''; if (quantityDiscount > 0 && couponDiscount > 0) { // 同时有数量折扣和优惠码折扣 discountDescription = `数量${quantityDiscountText} + 优惠码"${appliedCoupon.name}"`; } else if (quantityDiscount > 0) { // 只有数量折扣 discountDescription = quantityDiscountText; } else if (couponDiscount > 0) { // 只有优惠码折扣 const couponDiscountText = appliedCoupon.discount_type === 'percentage' ? `${appliedCoupon.discount_value}%折扣` : `$${appliedCoupon.discount_value}减免`; discountDescription = `优惠码"${appliedCoupon.name}" (${couponDiscountText})`; } discountTextElement.textContent = `-$${totalDiscountAmount.toFixed(2)} USDT (${discountDescription})`; discountRow.classList.remove('no-discount'); } else { discountTextElement.textContent = `$0.00 USDT (无优惠)`; discountRow.classList.add('no-discount'); } document.getElementById('shippingInfoModal').style.display = 'flex'; } // 关闭配送信息模态框 function closeShippingInfoModal() { document.getElementById('shippingInfoModal').style.display = 'none'; } // 验证手机号字段(通用函数) function validatePhoneField(phoneInput) { const phone = phoneInput.value.trim(); if (phone && !validatePhoneNumber(phone)) { phoneInput.style.borderColor = '#ff4757'; showFieldError(phoneInput, '请输入正确的11位手机号码'); } else { phoneInput.style.borderColor = '#444'; hideFieldError(phoneInput); } } // 应用优惠码 async function applyCoupon() { const couponCode = document.getElementById('coupon-code').value.trim(); const applyBtn = document.getElementById('apply-coupon-btn'); const messageEl = document.getElementById('coupon-message'); if (!couponCode) { showCouponMessage('请输入优惠码', 'error'); return; } // 禁用按钮 applyBtn.disabled = true; applyBtn.textContent = '验证中...'; try { const response = await fetch('/api/coupons/validate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code: couponCode }) }); const result = await response.json(); if (response.ok && result.valid) { // 优惠码有效,应用优惠 appliedCoupon = result.coupon; updateTotalPrice(); // 更新UI状态 document.getElementById('coupon-code').readOnly = true; applyBtn.textContent = '移除'; applyBtn.onclick = clearAppliedCoupon; const discountText = result.coupon.discount_type === 'percentage' ? `${result.coupon.discount_value}%折扣` : `$${result.coupon.discount_value}减免`; showCouponMessage(`✓ 优惠码"${result.coupon.name}"已应用 (${discountText})`, 'success'); } else { showCouponMessage(result.message || '优惠码无效', 'error'); } } catch (error) { console.error('Apply coupon error:', error); showCouponMessage('验证优惠码失败,请稍后重试', 'error'); } finally { if (!appliedCoupon) { applyBtn.disabled = false; applyBtn.textContent = '使用'; } } } // 清除已应用的优惠码 function clearAppliedCoupon() { appliedCoupon = null; updateTotalPrice(); // 重置UI状态 document.getElementById('coupon-code').readOnly = false; document.getElementById('coupon-code').value = ''; const applyBtn = document.getElementById('apply-coupon-btn'); applyBtn.disabled = false; applyBtn.textContent = '使用'; applyBtn.onclick = applyCoupon; showCouponMessage('优惠码已移除', 'info'); setTimeout(() => { document.getElementById('coupon-message').style.display = 'none'; }, 2000); } // 显示优惠码消息 function showCouponMessage(message, type = 'info') { const messageEl = document.getElementById('coupon-message'); messageEl.textContent = message; messageEl.className = `coupon-message ${type}`; messageEl.style.display = 'block'; } // 验证数量 function validateQuantity() { const value = parseInt(quantityInput.value); if (isNaN(value) || value < 1) { quantityInput.value = 1; } else if (value > 999) { quantityInput.value = 999; } updateTotalPrice(); } // 处理订单提交 async function handleOrderSubmit(e) { e.preventDefault(); if (!currentProduct) { alert('产品信息加载中,请稍后重试'); return; } // 获取表单数据 const formData = new FormData(orderForm); const quantity = parseInt(formData.get('quantity')); // 计算最终价格(包含折扣) const unitPrice = currentProduct.price; const originalTotal = unitPrice * quantity; // 数量折扣计算 let afterQuantityDiscount = originalTotal; if (quantity >= 5) { afterQuantityDiscount = originalTotal * 0.9; // 9折 } else if (quantity >= 2) { afterQuantityDiscount = originalTotal * 0.95; // 9.5折 } // 优惠码折扣计算 let finalTotal = afterQuantityDiscount; if (appliedCoupon) { if (appliedCoupon.discount_type === 'percentage') { finalTotal = afterQuantityDiscount * (1 - appliedCoupon.discount_value / 100); } else if (appliedCoupon.discount_type === 'fixed') { finalTotal = Math.max(0, afterQuantityDiscount - appliedCoupon.discount_value); } } const orderData = { product_id: currentProduct.id, quantity: quantity, unit_price: unitPrice, total_amount: finalTotal, // 使用折扣后的价格 customer_name: formData.get('customer_name').trim(), customer_email: formData.get('customer_email').trim(), customer_phone: formData.get('customer_phone').trim(), shipping_address: formData.get('shipping_address').trim(), coupon_code: appliedCoupon ? appliedCoupon.code : null }; // 验证必填字段 if (!orderData.customer_name || !orderData.customer_phone || !orderData.customer_email || !orderData.shipping_address) { alert('请填写所有必填信息'); return; } // 验证手机号格式 if (!validatePhoneNumber(orderData.customer_phone)) { alert('请输入正确的11位手机号码'); return; } // 验证邮箱格式 if (!validateEmail(orderData.customer_email)) { alert('请输入正确的邮箱地址'); return; } // 禁用提交按钮 const submitBtn = document.getElementById('submit-order'); const btnText = submitBtn.querySelector('.btn-text'); const btnLoading = submitBtn.querySelector('.btn-loading'); submitBtn.disabled = true; btnText.style.display = 'none'; btnLoading.style.display = 'inline'; try { // 创建订单 const response = await fetch('/api/orders', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(orderData) }); const result = await response.json(); if (result.success) { currentOrder = { ...orderData, order_id: result.order_id, total_amount: result.total_amount }; showOrderModal(); } else { throw new Error(result.error || '订单创建失败'); } } catch (error) { console.error('创建订单失败:', error); alert('创建订单失败: ' + error.message); } finally { // 恢复提交按钮 submitBtn.disabled = false; btnText.style.display = 'inline'; btnLoading.style.display = 'none'; } } // 显示订单确认模态框 function showOrderModal() { if (!currentOrder) return; // 填充订单信息 document.getElementById('modal-order-id').textContent = currentOrder.order_id; document.getElementById('modal-product-name').textContent = currentProduct.name; document.getElementById('modal-quantity').textContent = currentOrder.quantity; document.getElementById('modal-total-price').textContent = `$${currentOrder.total_amount.toFixed(2)} USDT`; document.getElementById('modal-address').textContent = currentOrder.shipping_address; orderModal.style.display = 'flex'; } // 关闭订单模态框 function closeOrderModal() { orderModal.style.display = 'none'; } // 处理支付 async function handlePayNow() { if (!currentOrder) return; try { // 创建支付 const response = await fetch('/api/payment/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ order_id: currentOrder.order_id }) }); const result = await response.json(); if (result.success) { // 检查是否为手动支付模式 if (result.manual_mode) { // 关闭模态框,跳转到手动支付页面 closeOrderModal(); window.location.href = result.payment_url; } else { // 关闭模态框,直接跳转到UPay支付页面 closeOrderModal(); // 显示跳转提示 const jumpTip = document.createElement('div'); jumpTip.innerHTML = `

正在跳转到支付页面...

请在新页面完成USDT支付

`; document.body.appendChild(jumpTip); // 3秒后跳转到UPay支付页面 setTimeout(() => { window.location.href = result.payment_url; }, 3000); } } else { throw new Error(result.error || '创建支付失败'); } } catch (error) { console.error('创建支付失败:', error); alert('创建支付失败: ' + error.message); } } // 显示支付状态页面 function showPaymentStatus() { if (!currentOrder) return; document.getElementById('status-order-id').textContent = currentOrder.order_id; document.getElementById('status-amount').textContent = currentOrder.total_amount.toFixed(2); paymentStatus.style.display = 'flex'; // 开始监听支付状态 startPaymentStatusCheck(); } // 开始支付状态检查 function startPaymentStatusCheck() { // 每10秒检查一次支付状态 const checkInterval = setInterval(async () => { const status = await checkPaymentStatus(); if (status === 'finished' || status === 'failed') { clearInterval(checkInterval); } }, 10000); } // 检查支付状态 async function checkPaymentStatus() { if (!currentOrder) return; try { const response = await fetch(`/api/orders/${currentOrder.order_id}`); const order = await response.json(); const statusIcon = document.getElementById('status-icon'); const statusTitle = document.getElementById('status-title'); const statusMessage = document.getElementById('status-message'); switch (order.payment_status) { case 'finished': statusIcon.innerHTML = '
'; statusTitle.textContent = '支付成功!'; statusMessage.textContent = '您的订单已确认,我们将尽快处理并发货。'; break; case 'failed': case 'expired': statusIcon.innerHTML = '
'; statusTitle.textContent = '支付失败'; statusMessage.textContent = '支付未完成或已过期,请重新下单。'; break; case 'confirming': statusTitle.textContent = '支付确认中...'; statusMessage.textContent = '我们已收到您的支付,正在等待区块链确认。'; break; default: statusTitle.textContent = '等待支付...'; statusMessage.textContent = '请完成USDT支付,我们正在等待您的交易。'; } return order.payment_status; } catch (error) { console.error('检查支付状态失败:', error); return null; } } // 工具函数:验证邮箱 function validateEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } // 工具函数:验证手机号码 function validatePhoneNumber(phone) { const phoneRegex = /^1[3-9]\d{9}$/; return phoneRegex.test(phone); } // 手机号失焦验证 function validatePhone() { const phoneInput = document.getElementById('customer_phone'); const phone = phoneInput.value.trim(); if (phone && !validatePhoneNumber(phone)) { phoneInput.style.borderColor = '#ff4757'; showFieldError(phoneInput, '请输入正确的11位手机号码'); } else { phoneInput.style.borderColor = '#444'; hideFieldError(phoneInput); } } // 显示字段错误 function showFieldError(input, message) { hideFieldError(input); // 先清除已有错误 const errorDiv = document.createElement('div'); errorDiv.className = 'field-error'; errorDiv.textContent = message; errorDiv.style.cssText = 'color: #ff4757; font-size: 12px; margin-top: 5px; padding-left: 5px;'; input.parentNode.appendChild(errorDiv); } // 隐藏字段错误 function hideFieldError(input) { const existingError = input.parentNode.querySelector('.field-error'); if (existingError) { existingError.remove(); } } // 工具函数:验证电话号码(保留兼容性) function validatePhone(phone) { return validatePhoneNumber(phone); } // 管理员登录相关函数 function showAdminLogin() { document.getElementById('adminLoginModal').style.display = 'flex'; document.getElementById('adminPassword').focus(); } function closeAdminLogin() { document.getElementById('adminLoginModal').style.display = 'none'; document.getElementById('adminPassword').value = ''; document.getElementById('loginError').style.display = 'none'; } // 联系我们相关函数 function showContactModal() { document.getElementById('contactModal').style.display = 'flex'; } function closeContactModal() { document.getElementById('contactModal').style.display = 'none'; } function verifyAdminPassword() { const password = document.getElementById('adminPassword').value; const errorDiv = document.getElementById('loginError'); if (password === '223388') { // 密码正确,跳转到管理页面 window.location.href = '/admin.html'; } else { // 密码错误 errorDiv.textContent = '密码错误,请重新输入'; errorDiv.style.display = 'block'; document.getElementById('adminPassword').value = ''; document.getElementById('adminPassword').focus(); } } // 键盘事件监听 document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { closeAdminLogin(); closeContactModal(); } }); // 管理员登录密码框回车事件 document.addEventListener('DOMContentLoaded', function() { const adminPasswordInput = document.getElementById('adminPassword'); if (adminPasswordInput) { adminPasswordInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') { verifyAdminPassword(); } }); } }); // 处理配送信息提交并直接下单 async function handleShippingOrderSubmit(e) { e.preventDefault(); if (!currentProduct) { alert('产品信息加载中,请稍后重试'); return; } // 获取表单数据 const formData = new FormData(e.target); const quantity = parseInt(quantityInput.value); // 计算最终价格(包含折扣) const unitPrice = currentProduct.price; const originalTotal = unitPrice * quantity; // 数量折扣计算 let afterQuantityDiscount = originalTotal; if (quantity >= 5) { afterQuantityDiscount = originalTotal * 0.9; // 9折 } else if (quantity >= 2) { afterQuantityDiscount = originalTotal * 0.95; // 9.5折 } // 优惠码折扣计算 let finalTotal = afterQuantityDiscount; if (appliedCoupon) { if (appliedCoupon.discount_type === 'percentage') { finalTotal = afterQuantityDiscount * (1 - appliedCoupon.discount_value / 100); } else if (appliedCoupon.discount_type === 'fixed') { finalTotal = Math.max(0, afterQuantityDiscount - appliedCoupon.discount_value); } } const orderData = { product_id: currentProduct.id, quantity: quantity, unit_price: unitPrice, total_amount: finalTotal, // 使用折扣后的价格 customer_name: formData.get('customer_name').trim(), customer_email: formData.get('customer_email').trim(), customer_phone: formData.get('customer_phone').trim(), shipping_address: formData.get('shipping_address').trim(), coupon_code: appliedCoupon ? appliedCoupon.code : null }; // 验证必填字段 if (!orderData.customer_name || !orderData.customer_phone || !orderData.customer_email || !orderData.shipping_address) { alert('请填写所有必填信息'); return; } // 验证手机号格式 if (!validatePhoneNumber(orderData.customer_phone)) { alert('请输入正确的11位手机号码'); return; } // 验证邮箱格式 if (!validateEmail(orderData.customer_email)) { alert('请输入正确的邮箱地址'); return; } // 禁用提交按钮 const submitBtn = document.getElementById('submit-shipping-order'); const btnText = submitBtn.querySelector('.btn-text'); const btnLoading = submitBtn.querySelector('.btn-loading'); submitBtn.disabled = true; btnText.style.display = 'none'; btnLoading.style.display = 'inline'; try { // 创建订单 const orderResponse = await fetch('/api/orders', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(orderData) }); const orderResult = await orderResponse.json(); if (orderResult.success) { // 创建支付 const paymentResponse = await fetch('/api/payment/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ order_id: orderResult.order_id }) }); const paymentResult = await paymentResponse.json(); if (paymentResult.success) { // 关闭配送信息模态框 closeShippingInfoModal(); if (paymentResult.manual_mode) { // 手动支付模式 window.location.href = paymentResult.payment_url; } else { // 显示跳转提示并直接跳转到UPay支付页面 const jumpTip = document.createElement('div'); jumpTip.innerHTML = `

正在跳转到支付页面...

请在新页面完成USDT支付

`; document.body.appendChild(jumpTip); // 3秒后跳转到UPay支付页面 setTimeout(() => { window.location.href = paymentResult.payment_url; }, 3000); } } else { throw new Error(paymentResult.error || '创建支付失败'); } } else { throw new Error(orderResult.error || '订单创建失败'); } } catch (error) { console.error('下单失败:', error); alert('下单失败: ' + error.message); } finally { // 恢复提交按钮 submitBtn.disabled = false; btnText.style.display = 'inline'; btnLoading.style.display = 'none'; } } // 验证手机号字段(通用函数) function validatePhoneField(phoneInput) { const phone = phoneInput.value.trim(); if (phone && !validatePhoneNumber(phone)) { phoneInput.style.borderColor = '#ff4757'; showFieldError(phoneInput, '请输入正确的11位手机号码'); } else { phoneInput.style.borderColor = '#444'; hideFieldError(phoneInput); } }