From bd9330675efcd2b794dc0428e53dcfaeeb2a40ed Mon Sep 17 00:00:00 2001 From: yovinchen Date: Thu, 3 Jul 2025 00:25:30 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=9F=E6=88=90=E8=AE=A2=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ProductService.java | 17 +- src/main/webapp/WEB-INF/views/cart.jsp | 59 +++- src/main/webapp/WEB-INF/views/products.jsp | 326 +++++++++--------- 3 files changed, 234 insertions(+), 168 deletions(-) diff --git a/src/main/java/com/org/flashsalesystem/service/ProductService.java b/src/main/java/com/org/flashsalesystem/service/ProductService.java index 8af1ed0..a772e95 100644 --- a/src/main/java/com/org/flashsalesystem/service/ProductService.java +++ b/src/main/java/com/org/flashsalesystem/service/ProductService.java @@ -261,7 +261,22 @@ public class ProductService { productRepository.increaseStock(productId, quantity); } else if ("decrease".equals(operation)) { // 减少库存 - Long currentStock = (Long) redisService.get(stockKey); + Object stockObj = redisService.get(stockKey); + Long currentStock = null; + if (stockObj != null) { + if (stockObj instanceof Integer) { + currentStock = ((Integer) stockObj).longValue(); + } else if (stockObj instanceof Long) { + currentStock = (Long) stockObj; + } else if (stockObj instanceof String) { + try { + currentStock = Long.parseLong((String) stockObj); + } catch (NumberFormatException e) { + log.error("库存数据格式错误: 商品ID={}, 数据={}", productId, stockObj); + return false; + } + } + } if (currentStock == null || currentStock < quantity) { log.warn("库存不足: 商品ID={}, 当前库存={}, 需要扣减={}", productId, currentStock, quantity); return false; diff --git a/src/main/webapp/WEB-INF/views/cart.jsp b/src/main/webapp/WEB-INF/views/cart.jsp index f6623e8..3d0cb02 100644 --- a/src/main/webapp/WEB-INF/views/cart.jsp +++ b/src/main/webapp/WEB-INF/views/cart.jsp @@ -419,13 +419,60 @@ productIds.push(parseInt($(this).val())); }); - // 跳转到结算页面 - const form = $('
'); - productIds.forEach(function (productId) { - form.append(''); + // 显示确认对话框 + if (!confirm('确定要结算选中的 ' + selectedItems.length + ' 个商品吗?\n\n结算后将生成订单,请及时支付。')) { + return; + } + + // 禁用结算按钮防止重复点击 + const checkoutBtn = $('#checkoutBtn'); + const originalText = checkoutBtn.html(); + checkoutBtn.prop('disabled', true).html(' 结算中...'); + + // 通过AJAX调用购物车结算接口 + $.ajax({ + url: '${pageContext.request.contextPath}/api/cart/checkout', + type: 'POST', + contentType: 'application/json', + data: JSON.stringify({ + productIds: productIds + }), + success: function (response) { + if (response.success) { + showMessage('✅ 订单生成成功!订单号:' + response.data.orderNo, 'success'); + + // 清空购物车显示 + loadCart(); + + // 3秒后跳转到订单详情页面 + setTimeout(() => { + window.location.href = '${pageContext.request.contextPath}/order/' + response.data.id; + }, 2000); + } else { + showMessage('❌ 下单失败:' + response.message, 'error'); + + // 恢复按钮状态 + checkoutBtn.prop('disabled', false).html(originalText); + } + }, + error: function (xhr, status, error) { + let errorMessage = '网络异常,请重试'; + + if (xhr.status === 401) { + errorMessage = '登录已过期,请重新登录'; + setTimeout(() => { + window.location.href = '${pageContext.request.contextPath}/login?returnUrl=' + encodeURIComponent(window.location.pathname); + }, 1500); + } else if (xhr.status === 400 && xhr.responseJSON) { + errorMessage = xhr.responseJSON.message || '请求参数错误'; + } + + showMessage('❌ 结算失败:' + errorMessage, 'error'); + + // 恢复按钮状态 + checkoutBtn.prop('disabled', false).html(originalText); + } }); - $('body').append(form); - form.submit(); } // 加载推荐商品 diff --git a/src/main/webapp/WEB-INF/views/products.jsp b/src/main/webapp/WEB-INF/views/products.jsp index 6133448..120cc14 100644 --- a/src/main/webapp/WEB-INF/views/products.jsp +++ b/src/main/webapp/WEB-INF/views/products.jsp @@ -29,12 +29,6 @@ font-size: 1.2rem; } - .original-price { - color: #999; - text-decoration: line-through; - font-size: 0.9rem; - } - .stock-badge { position: absolute; top: 10px; @@ -58,6 +52,20 @@ text-align: center; padding: 40px; } + + .btn:hover { + transform: translateY(-1px); + } + + /* 卡片悬停效果 */ + .card:hover .card-img-top { + transform: scale(1.05); + transition: transform 0.3s ease; + } + + .card-img-top { + transition: transform 0.3s ease; + }
@@ -96,7 +104,6 @@ -
@@ -172,6 +179,11 @@ searchProducts(); } }); + + // 更新购物车数量(如果用户已登录) + + updateCartCount(); + }); // 加载商品列表 @@ -195,7 +207,7 @@ params.append('sortDirection', sortValue[1]); } - $.get('/api/product/list?' + params.toString()) + $.get('${pageContext.request.contextPath}/api/product/list?' + params.toString()) .done(function (response) { if (response.success) { displayProducts(response.data.content); @@ -235,54 +247,46 @@ }); } - // 创建商品卡片 + // 创建商品卡片(参考热门商品样式) function createProductCard(product) { - const stockBadge = product.stock > 0 ? - `库存 ${product.stock}` : - `无库存`; + const imageUrl = product.imageUrl || '${pageContext.request.contextPath}/images/default-product.svg'; + const productName = product.name; + const productDescription = product.description || '暂无描述'; + const price = product.price ? product.price.toFixed(2) : '0.00'; + const stock = product.stock || 0; - const originalPrice = product.originalPrice && product.originalPrice > product.price ? - `¥${product.originalPrice}` : ''; + var cardHtml = '
' + + '
' + + '
' + + '' + productName + '' + + '' + + (stock > 0 ? '库存 ' + stock : '无库存') + + '' + + '
' + + '
' + + '
' + productName + '
' + + '

' + + productDescription + + '

' + + '
' + + '¥' + price + '' + + '库存: ' + stock + '' + + '
' + + '
' + + (stock > 0 ? + '' : + '' + ) + + '' + + '
' + + '
' + + '
' + + '
'; - const addToCartBtn = product.stock > 0 ? - `` : - ``; - - return ` -
-
-
- ${product.name} - ${stockBadge} -
-
-
- ${product.name.length > 30 ? product.name.substring(0, 30) + '...' : product.name} -
-

- ${product.description ? - (product.description.length > 50 ? product.description.substring(0, 50) + '...' : product.description) : - '暂无描述'} -

-
- ¥${product.price} - ${originalPrice} -
-
- ${addToCartBtn} - -
-
-
-
- `; + return cardHtml; } // 更新分页 @@ -296,36 +300,36 @@ // 上一页 const prevDisabled = currentPage === 0 ? 'disabled' : ''; pagination.append(` -
  • - - - -
  • - `); +
  • + + + +
  • + `); // 页码 let startPage = Math.max(0, currentPage - 2); let endPage = Math.min(totalPages - 1, currentPage + 2); if (startPage > 0) { - pagination.append(`
  • 1
  • `); + pagination.append('
  • 1
  • '); if (startPage > 1) { - pagination.append(`
  • ...
  • `); + pagination.append('
  • ...
  • '); } } for (let i = startPage; i <= endPage; i++) { const active = i === currentPage ? 'active' : ''; pagination.append(` -
  • - ${i + 1} -
  • - `); +
  • + ${i + 1} +
  • + `); } if (endPage < totalPages - 1) { if (endPage < totalPages - 2) { - pagination.append(`
  • ...
  • `); + pagination.append('
  • ...
  • '); } pagination.append(`
  • ${totalPages}
  • `); } @@ -333,19 +337,19 @@ // 下一页 const nextDisabled = currentPage === totalPages - 1 ? 'disabled' : ''; pagination.append(` -
  • - - - -
  • - `); +
  • + + + +
  • + `); } // 查看商品详情 function viewProductDetail(productId) { currentProductId = productId; - $.get(`/api/product/${productId}`) + $.get('${pageContext.request.contextPath}/api/product/' + productId) .done(function (response) { if (response.success) { displayProductDetail(response.data); @@ -362,91 +366,80 @@ // 显示商品详情 function displayProductDetail(product) { const modalBody = $('#productModalBody'); - modalBody.html(` -
    -
    - ${product.name} -
    -
    -

    ${product.name}

    -

    ${product.description || '暂无详细描述'}

    -
    - ¥${product.price} - ${product.originalPrice && product.originalPrice > product.price ? - '¥' + product.originalPrice + '' : ''} -
    -
    - - - - 库存 ${product.stock} - - - 暂时缺货 - - - -
    -
    - 商品类别: ${product.category || '未分类'} -
    -
    - 商品状态: - - - - 上架中 - - - 已下架 - - - -
    -
    -
    - `); + const imageUrl = product.imageUrl || '${pageContext.request.contextPath}/images/default-product.svg'; + const stock = product.stock || 0; + const price = product.price ? product.price.toFixed(2) : '0.00'; + + var modalHtml = '
    ' + + '
    ' + + '' + product.name + '' + + '
    ' + + '
    ' + + '

    ' + product.name + '

    ' + + '

    ' + (product.description || '暂无详细描述') + '

    ' + + '
    ' + + '¥' + price + '' + + '
    ' + + '
    ' + + '' + + (stock > 0 ? '库存 ' + stock : '暂时缺货') + + '' + + '
    ' + + '
    ' + + '商品状态: ' + + '' + + (product.status === 1 ? '上架中' : '已下架') + + '' + + '
    ' + + '
    ' + + '
    '; + + modalBody.html(modalHtml); // 更新加入购物车按钮状态 const addToCartBtn = $('#addToCartBtn'); - if (product.stock > 0 && product.status === 1) { + if (stock > 0 && product.status === 1) { addToCartBtn.prop('disabled', false).html(' 加入购物车'); } else { addToCartBtn.prop('disabled', true).html(' 暂时无法购买'); } } - // 添加到购物车 + // 添加到购物车(参考首页实现) function addToCart(productId) { - if (!isUserLoggedIn()) { - showLoginPrompt(); - return; - } - - const data = { - productId: productId, - quantity: 1 - }; - + + $.ajax({ - url: '/api/cart/add', - method: 'POST', + url: '${pageContext.request.contextPath}/api/cart/add', + type: 'POST', contentType: 'application/json', - data: JSON.stringify(data) - }) - .done(function (response) { + data: JSON.stringify({ + productId: productId, + quantity: 1 + }), + success: function (response) { if (response.success) { - showSuccess('商品已添加到购物车'); + showMessage('商品已添加到购物车', 'success'); updateCartCount(); + // 如果是从模态框添加的,关闭模态框 $('#productModal').modal('hide'); } else { - showError('添加失败:' + response.message); + showMessage(response.message, 'error'); } - }) - .fail(function () { - showError('网络错误,请稍后重试'); - }); + }, + error: function () { + showMessage('添加失败,请重试', 'error'); + } + }); + + + showMessage('请先登录', 'warning'); + setTimeout(() => { + window.location.href = '${pageContext.request.contextPath}/login?returnUrl=' + encodeURIComponent(window.location.pathname); + }, 1500); + + } // 显示加载状态 @@ -461,40 +454,51 @@ } } - // 检查用户是否登录 - function isUserLoggedIn() { - // 这里需要根据实际的登录状态检查逻辑来实现 - return sessionStorage.getItem('userToken') || - document.cookie.includes('JSESSIONID'); + // 显示消息(参考首页实现) + function showMessage(message, type = 'info') { + // 创建消息元素 + const alertDiv = document.createElement('div'); + alertDiv.className = `alert alert-${type == 'error' ? 'danger' : type} alert-dismissible fade show position-fixed`; + alertDiv.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;'; + + alertDiv.innerHTML = ` + ${message} + + `; + + document.body.appendChild(alertDiv); + + // 3秒后自动消失 + setTimeout(() => { + if (alertDiv.parentNode) { + alertDiv.remove(); + } + }, 3000); } - // 显示登录提示 - function showLoginPrompt() { - if (confirm('请先登录后再进行购物,是否前往登录页面?')) { - window.location.href = '/login?returnUrl=' + encodeURIComponent(window.location.pathname); - } - } - - // 更新购物车数量 + // 更新购物车数量(参考首页实现) function updateCartCount() { - if (!isUserLoggedIn()) return; - - $.get('/api/cart/count') + $.get('${pageContext.request.contextPath}/api/cart/count') .done(function (response) { - if (response.success && response.data.count > 0) { - $('.cart-count').text(response.data.count).show(); + if (response.success) { + const cartBadge = document.querySelector('.cart-count'); + if (cartBadge) { + const count = response.data.count || 0; + cartBadge.textContent = count; + cartBadge.style.display = count > 0 ? 'inline' : 'none'; + } } }); } // 错误提示 function showError(message) { - alert('错误:' + message); + showMessage(message, 'error'); } // 成功提示 function showSuccess(message) { - alert('成功:' + message); + showMessage(message, 'success'); }