// Cart Page JavaScript - 使用真实API console.log('=== cart.js 已加载 ==='); $(document).ready(function() { console.log('=== cart.js $(document).ready ==='); initCartPage(); }); function initCartPage() { console.log('=== initCartPage 开始 ==='); loadCartItems(); loadRecommendations(); bindCartEvents(); console.log('=== initCartPage 完成 ==='); // 监听语言切换 $(document).on('languageChanged', function() { loadCartItems(); loadRecommendations(); }); } // 加载购物车商品 - 从API获取 function loadCartItems() { // 调用后端API获取购物车数据 API.get('/cart') .then(data => { console.log('购物车数据:', data); const cartItems = data.items || []; if (cartItems.length === 0) { $('#cartContent').hide(); $('#cartEmpty').show(); updateCartCount(0); return; } $('#cartEmpty').hide(); $('#cartContent').show(); renderCartItems(cartItems); updateCartCount(data.total_quantity || cartItems.reduce((sum, item) => sum + item.quantity, 0)); }) .catch(error => { console.error('加载购物车失败:', error); Toast.error(error.message || '加载购物车失败'); $('#cartContent').hide(); $('#cartEmpty').show(); }); } // 渲染购物车商品列表 function renderCartItems(cartItems) { const lang = i18n.currentLang; // 生成购物车表格HTML let cartHtml = ` `; // 添加商品行 cartItems.forEach(item => { const product = item.product || {}; const sku = item.sku || {}; const itemName = product.name || '未知商品'; const itemImage = product.main_image || product.image || 'https://picsum.photos/200/200?random=default'; // 价格转换:分 → 元 const itemPrice = PriceUtils.fenToYuan(sku.price || product.price || 0); const itemTotal = PriceUtils.fenToYuan((sku.price || product.price || 0) * item.quantity); // 规格信息 let specsHtml = ''; if (sku.spec_values && Object.keys(sku.spec_values).length > 0) { specsHtml = '
'; for (const [key, value] of Object.entries(sku.spec_values)) { specsHtml += `${key}: ${value}`; } specsHtml += '
'; } cartHtml += ` `; }); // 计算已选商品的小计和总计 const selectedItems = cartItems.filter(item => item.selected); const subtotal = calculateSubtotal(selectedItems); const total = subtotal; // 暂不计算折扣 cartHtml += `
${i18n.t('product')} ${i18n.t('price')} ${i18n.t('quantity')} ${i18n.t('total')}
${itemName}
${specsHtml}
¥${itemPrice.toFixed(2)}
¥${itemTotal.toFixed(2)}

${i18n.t('cart_totals')}

${i18n.t('subtotal')} ¥${PriceUtils.fenToYuan(subtotal).toFixed(2)}
${i18n.t('shipping')} ${i18n.t('free')}
${i18n.t('total')} ¥${PriceUtils.fenToYuan(total).toFixed(2)}
${i18n.t('free_shipping_notice')}
`; $('#cartContent').html(cartHtml); } // 判断是否全选 function isAllSelected(cartItems) { return cartItems.length > 0 && cartItems.every(item => item.selected); } // 计算小计(已选商品) function calculateSubtotal(selectedItems) { return selectedItems.reduce((sum, item) => { const price = (item.sku && item.sku.price) || (item.product && item.product.price) || 0; return sum + (price * item.quantity); }, 0); } // 加载推荐商品 function loadRecommendations() { // 调用商品列表API获取推荐商品 API.get('/products/list', { page: 1, size: 4 }) .then(data => { const products = data.products || data.list || []; renderRecommendations(products.slice(0, 4)); }) .catch(error => { console.error('加载推荐商品失败:', error); // 失败时不显示推荐区域 $('.recommendations-section').hide(); }); } // 渲染推荐商品 function renderRecommendations(products) { const lang = i18n.currentLang; let recommendationsHtml = ''; products.forEach(product => { const productName = product.name || '商品名称'; const category = product.category_name || '商品分类'; const currentPrice = PriceUtils.fenToYuan(product.price || 0); const originalPrice = product.original_price ? PriceUtils.fenToYuan(product.original_price) : null; const mainImage = product.main_image || product.image || 'https://picsum.photos/400/400?random=default'; recommendationsHtml += `
${productName} ${product.stock > 0 ? '' : '售罄'}
${category}
${productName}
¥${currentPrice.toFixed(2)} ${originalPrice ? `¥${originalPrice.toFixed(2)}` : ''}
`; }); $('#recommendationsGrid').html(recommendationsHtml); } // 绑定购物车事件 function bindCartEvents() { console.log('=== 绑定购物车事件 ==='); // 全选/取消全选 $(document).off('change', '#selectAll').on('change', '#selectAll', function() { const selected = $(this).is(':checked'); selectAllItems(selected); }); // 单个商品选择 $(document).off('change', '.item-checkbox').on('change', '.item-checkbox', function() { const cartId = $(this).data('cart-id'); const selected = $(this).is(':checked'); selectCartItem(cartId, selected); }); // 数量增加 $(document).off('click', '.qty-btn.plus').on('click', '.qty-btn.plus', function() { console.log('点击了+按钮'); const productId = $(this).data('product-id'); const skuId = $(this).data('sku-id'); const $input = $(this).siblings('.qty-input'); const currentQty = parseInt($input.val()); console.log('+ 按钮参数:', { productId, skuId, currentQty }); updateQuantity(productId, skuId, currentQty + 1); }); // 数量减少 $(document).off('click', '.qty-btn.minus').on('click', '.qty-btn.minus', function() { console.log('点击了-按钮'); const productId = $(this).data('product-id'); const skuId = $(this).data('sku-id'); const $input = $(this).siblings('.qty-input'); const currentQty = parseInt($input.val()); console.log('- 按钮参数:', { productId, skuId, currentQty }); if (currentQty > 1) { updateQuantity(productId, skuId, currentQty - 1); } }); // 数量输入框变化 $(document).off('change', '.qty-input').on('change', '.qty-input', function() { console.log('输入框数量变化'); const productId = $(this).data('product-id'); const skuId = $(this).data('sku-id'); let newQuantity = parseInt($(this).val()); console.log('输入框参数:', { productId, skuId, newQuantity }); if (isNaN(newQuantity) || newQuantity < 1) { newQuantity = 1; } else if (newQuantity > 99) { newQuantity = 99; } $(this).val(newQuantity); updateQuantity(productId, skuId, newQuantity); }); // 移除商品 $(document).off('click', '.cart-product-remove').on('click', '.cart-product-remove', function() { const productId = $(this).data('product-id'); const skuId = $(this).data('sku-id'); removeItem(productId, skuId); }); // 结算按钮 $(document).off('click', '#checkoutBtn').on('click', '#checkoutBtn', function() { if (!$(this).prop('disabled')) { window.location.href = 'checkout.html'; } }); // 添加推荐商品 $(document).off('click', '.recommendation-add-btn').on('click', '.recommendation-add-btn', function() { const productId = $(this).data('product-id'); if (!$(this).prop('disabled')) { addRecommendedProduct(productId); } }); } // 全选/取消全选 function selectAllItems(selected) { API.put('/cart/select-all', { selected: selected }) .then(() => { loadCartItems(); }) .catch(error => { Toast.error(error.message || '操作失败'); // 恢复选中状态 $('#selectAll').prop('checked', !selected); }); } // 选择/取消选择单个商品 function selectCartItem(cartId, selected) { API.put(`/cart/${cartId}/select`, { selected: selected }) .then(() => { loadCartItems(); }) .catch(error => { Toast.error(error.message || '操作失败'); // 恢复选中状态 $(`.item-checkbox[data-cart-id="${cartId}"]`).prop('checked', !selected); }); } // 更新商品数量 function updateQuantity(productId, skuId, quantity) { console.log('updateQuantity 参数:', { productId, skuId, quantity }); if (!productId) { console.error('productId 不能为空'); Toast.error('商品ID不能为空'); return; } const data = { quantity: quantity }; if (skuId && skuId != 0) { data.sku_id = parseInt(skuId); } const url = `/cart/${productId}`; console.log('更新购物车请求URL:', url, '数据:', data); API.put(url, data) .then(() => { Toast.success('修改成功'); loadCartItems(); }) .catch(error => { console.error('更新购物车失败:', error); Toast.error(error.message || '修改数量失败'); loadCartItems(); // 刷新以恢复原数量 }); } // 移除商品 function removeItem(productId, skuId) { Toast.confirm({ title: '确认删除', message: '确定要从购物车中删除该商品吗?', confirmText: '确定', cancelText: '取消' }).then(confirmed => { if (confirmed) { let url = `/cart/${productId}`; if (skuId && skuId != 0) { url += `?sku_id=${skuId}`; } API.delete(url) .then(() => { Toast.success('已删除'); loadCartItems(); }) .catch(error => { Toast.error(error.message || '删除失败'); }); } }); } // 添加推荐商品到购物车 function addRecommendedProduct(productId) { API.post('/cart', { product_id: parseInt(productId), quantity: 1 }) .then(() => { Toast.success(i18n.t('product_added_to_cart') || '已添加到购物车'); loadCartItems(); }) .catch(error => { Toast.error(error.message || '添加失败'); }); } // 更新购物车数量显示 function updateCartCount(count) { $('#cartCount').text(count); $('.cart-count').text(count); }