diff --git a/public/css/style.css b/public/css/style.css index 7b10bab..b593970 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -70,15 +70,26 @@ main { background: linear-gradient(135deg, #28a745, #20c997); color: white; border: none; - border-radius: 50px; - padding: 12px 25px; - font-size: 14px; - font-weight: bold; + border-radius: 50%; + width: 60px; + height: 60px; cursor: pointer; transition: all 0.3s ease; - text-transform: uppercase; - letter-spacing: 1px; box-shadow: 0 4px 15px rgba(40, 167, 69, 0.3); + display: flex; + align-items: center; + justify-content: center; +} + +.contact-floating-btn svg { + width: 28px; + height: 28px; + color: white; + transition: transform 0.3s ease; +} + +.contact-floating-btn:hover svg { + transform: scale(1.1); } .contact-floating-btn:hover { @@ -321,9 +332,21 @@ main { .coupon-section { margin-top: 20px; padding: 20px; - background: linear-gradient(145deg, #0f1419, #1a2332); + background: linear-gradient(145deg, #1a1a1a, #2a2a2a); border-radius: 12px; - border: 1px solid #2c3e50; + border: 1px solid #444; + position: relative; + overflow: hidden; +} + +.coupon-section::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, #ffd700, #ffed4a, #ffd700); } .coupon-input-group { @@ -342,24 +365,28 @@ main { font-size: 14px; transition: all 0.3s ease; text-transform: uppercase; + font-family: 'Consolas', 'Monaco', 'Courier New', monospace; + letter-spacing: 1px; } .coupon-input-group input:focus { outline: none; - border-color: #007bff; - box-shadow: 0 0 15px rgba(0, 123, 255, 0.2); + border-color: #ffd700; + box-shadow: 0 0 15px rgba(255, 215, 0, 0.2); background: #1a1a1a; } .coupon-input-group input::placeholder { color: #666; text-transform: none; + font-family: 'Arial', 'Microsoft YaHei', sans-serif; + letter-spacing: normal; } .coupon-input-group button { padding: 12px 20px; - background: linear-gradient(135deg, #007bff, #0056b3); - color: #fff; + background: linear-gradient(135deg, #ffd700, #ffed4a); + color: #000; border: none; border-radius: 8px; font-size: 14px; @@ -368,12 +395,29 @@ main { transition: all 0.3s ease; text-transform: uppercase; letter-spacing: 1px; + position: relative; + overflow: hidden; +} + +.coupon-input-group button::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); + transition: left 0.5s; +} + +.coupon-input-group button:hover::before { + left: 100%; } .coupon-input-group button:hover { - background: linear-gradient(135deg, #0056b3, #004085); + background: linear-gradient(135deg, #ffed4a, #fff700); transform: translateY(-2px); - box-shadow: 0 8px 20px rgba(0, 123, 255, 0.3); + box-shadow: 0 8px 20px rgba(255, 215, 0, 0.4); } .coupon-input-group button:disabled { @@ -382,29 +426,34 @@ main { transform: none; } +.coupon-input-group button:disabled::before { + display: none; +} + .coupon-message { - padding: 8px 12px; - border-radius: 6px; + padding: 10px 15px; + border-radius: 8px; font-size: 13px; font-weight: 500; + border: 1px solid; } .coupon-message.success { - background: rgba(40, 167, 69, 0.1); + background: linear-gradient(145deg, #0a1a0a, #1a3a1a); color: #28a745; - border: 1px solid #28a745; + border-color: #28a745; } .coupon-message.error { - background: rgba(220, 53, 69, 0.1); + background: linear-gradient(145deg, #1a0a0a, #3a1a1a); color: #dc3545; - border: 1px solid #dc3545; + border-color: #dc3545; } .coupon-message.info { - background: rgba(0, 123, 255, 0.1); - color: #007bff; - border: 1px solid #007bff; + background: linear-gradient(145deg, #0a0a1a, #1a1a3a); + color: #ffd700; + border-color: #ffd700; } /* 优惠提示样式 */ @@ -919,8 +968,13 @@ main { .contact-floating-btn { bottom: 20px; right: 20px; - padding: 10px 20px; - font-size: 12px; + width: 50px; + height: 50px; + } + + .contact-floating-btn svg { + width: 24px; + height: 24px; } .footer-content { @@ -1163,6 +1217,7 @@ main { padding: 0; flex: 1; overflow-y: auto; + padding-top: 20px; } /* 滚动条样式优化 */ @@ -1196,68 +1251,37 @@ main { background: linear-gradient(145deg, #0a0a0a, #1a1a1a); margin: 0 30px 25px; border-radius: 15px; - padding: 25px; + padding: 20px; border: 1px solid #333; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3); } .summary-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 20px; - padding-bottom: 15px; + margin-bottom: 15px; + padding-bottom: 12px; border-bottom: 1px solid #333; } .product-info { - display: flex; - align-items: center; - flex: 1; -} - -.product-thumb { - width: 50px; - height: 50px; - object-fit: cover; - border-radius: 8px; - margin-right: 12px; - border: 1px solid #444; + display: block; } .product-details h4 { color: #ffffff; - margin: 0 0 4px 0; + margin: 0 0 6px 0; font-size: 1.1em; font-weight: 600; } -.product-details p { - color: #b0b0b0; - margin: 0; - font-size: 0.85em; -} - -.quantity-display { - text-align: center; - padding: 8px 16px; - background: linear-gradient(145deg, #1a1a1a, #2d2d2d); - border-radius: 8px; - border: 1px solid #444; -} - -.quantity-label { - display: block; - color: #b0b0b0; - font-size: 0.8em; - margin-bottom: 2px; -} - -.quantity-value { - display: block; +.product-meta { color: #ffd700; - font-weight: bold; - font-size: 1.1em; + font-size: 0.9em; + font-weight: 500; +} + +.product-meta strong { + color: #ffd700; + font-weight: 700; } /* 价格明细 */ @@ -1387,22 +1411,20 @@ main { .order-summary-card { margin: 0 20px 20px; - padding: 20px; + padding: 15px; } .summary-header { - flex-direction: column; - gap: 15px; - align-items: stretch; + margin-bottom: 12px; + padding-bottom: 10px; } - .product-info { - justify-content: center; + .product-details h4 { + font-size: 1em; } - .quantity-display { - align-self: center; - min-width: 80px; + .product-meta { + font-size: 0.85em; } .shipping-form-section { @@ -1424,17 +1446,4 @@ main { font-size: 16px; /* 防止iOS缩放 */ padding: 14px; } - - .product-thumb { - width: 45px; - height: 45px; - } - - .product-details h4 { - font-size: 1em; - } - - .product-details p { - font-size: 0.8em; - } } \ No newline at end of file diff --git a/public/index.html b/public/index.html index b5371c6..12f1489 100644 --- a/public/index.html +++ b/public/index.html @@ -16,7 +16,14 @@ - +
@@ -248,15 +255,11 @@
- 产品图片

高级产品

+ 数量: 1
-
- 数量 - 1 -
diff --git a/public/js/admin.js b/public/js/admin.js index 6b1dc4a..0d48293 100644 --- a/public/js/admin.js +++ b/public/js/admin.js @@ -607,6 +607,10 @@ async function createCoupon() { } try { + console.log('Creating coupon with data:', { + code, name, discount_type: discountType, discount_value: discountValue, is_reusable: isReusable, max_uses: maxUses + }); + const response = await fetch('/api/admin/coupons', { method: 'POST', headers: { @@ -622,7 +626,20 @@ async function createCoupon() { }) }); - const result = await response.json(); + console.log('Response status:', response.status); + console.log('Response headers:', response.headers); + + const responseText = await response.text(); + console.log('Response text:', responseText); + + let result; + try { + result = JSON.parse(responseText); + } catch (parseError) { + console.error('Failed to parse JSON:', parseError); + console.error('Response was:', responseText.substring(0, 200)); + throw new Error('服务器返回了无效的响应格式'); + } if (response.ok) { alert('优惠码创建成功!'); diff --git a/public/js/main.js b/public/js/main.js index a4a2d8c..3efc725 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -205,19 +205,33 @@ function showShippingInfoModal() { const quantity = parseInt(quantityInput.value) || 1; const unitPrice = currentProduct.price; const originalTotal = unitPrice * quantity; - let finalTotal = originalTotal; - let discountText = ''; - let hasDiscount = false; - // 计算折扣 + // 计算数量折扣 + let quantityDiscount = 0; + let quantityDiscountText = ''; + let afterQuantityDiscount = originalTotal; + if (quantity >= 5) { - finalTotal = originalTotal * 0.9; - discountText = '9折优惠 (-10%)'; - hasDiscount = true; + quantityDiscount = originalTotal * 0.1; + quantityDiscountText = '9折优惠 (-10%)'; + afterQuantityDiscount = originalTotal * 0.9; } else if (quantity >= 2) { - finalTotal = originalTotal * 0.95; - discountText = '9.5折优惠 (-5%)'; - hasDiscount = true; + 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; } // 更新订单汇总信息 @@ -230,9 +244,25 @@ function showShippingInfoModal() { const discountRow = document.querySelector('.discount-row'); const discountTextElement = document.getElementById('summary-discount-text'); - if (hasDiscount) { - const discountAmount = originalTotal - finalTotal; - discountTextElement.textContent = `-$${discountAmount.toFixed(2)} USDT (${discountText})`; + 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 (无优惠)`; @@ -368,12 +398,23 @@ async function handleOrderSubmit(e) { // 计算最终价格(包含折扣) const unitPrice = currentProduct.price; const originalTotal = unitPrice * quantity; - let finalTotal = originalTotal; + // 数量折扣计算 + let afterQuantityDiscount = originalTotal; if (quantity >= 5) { - finalTotal = originalTotal * 0.9; // 9折 + afterQuantityDiscount = originalTotal * 0.9; // 9折 } else if (quantity >= 2) { - finalTotal = originalTotal * 0.95; // 9.5折 + 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 = { @@ -713,12 +754,23 @@ async function handleShippingOrderSubmit(e) { // 计算最终价格(包含折扣) const unitPrice = currentProduct.price; const originalTotal = unitPrice * quantity; - let finalTotal = originalTotal; + // 数量折扣计算 + let afterQuantityDiscount = originalTotal; if (quantity >= 5) { - finalTotal = originalTotal * 0.9; // 9折 + afterQuantityDiscount = originalTotal * 0.9; // 9折 } else if (quantity >= 2) { - finalTotal = originalTotal * 0.95; // 9.5折 + 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 = { diff --git a/server.js b/server.js index 22d5870..76cd01c 100644 --- a/server.js +++ b/server.js @@ -42,6 +42,31 @@ db.serialize(() => { updated_at DATETIME DEFAULT CURRENT_TIMESTAMP )`); + // 检查并添加缺失的列 + db.all("PRAGMA table_info(orders)", [], (err, columns) => { + if (err) { + console.error('Error checking table structure:', err); + return; + } + + const columnNames = columns.map(col => col.name); + + // 添加缺失的优惠码相关列 + if (!columnNames.includes('coupon_code')) { + db.run("ALTER TABLE orders ADD COLUMN coupon_code TEXT", (err) => { + if (err) console.error('Error adding coupon_code column:', err); + else console.log('Added coupon_code column to orders table'); + }); + } + + if (!columnNames.includes('coupon_discount')) { + db.run("ALTER TABLE orders ADD COLUMN coupon_discount REAL DEFAULT 0", (err) => { + if (err) console.error('Error adding coupon_discount column:', err); + else console.log('Added coupon_discount column to orders table'); + }); + } + }); + // 创建优惠码表 db.run(`CREATE TABLE IF NOT EXISTS coupons ( id INTEGER PRIMARY KEY AUTOINCREMENT,