生成订单
This commit is contained in:
@@ -261,7 +261,22 @@ public class ProductService {
|
|||||||
productRepository.increaseStock(productId, quantity);
|
productRepository.increaseStock(productId, quantity);
|
||||||
} else if ("decrease".equals(operation)) {
|
} 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) {
|
if (currentStock == null || currentStock < quantity) {
|
||||||
log.warn("库存不足: 商品ID={}, 当前库存={}, 需要扣减={}", productId, currentStock, quantity);
|
log.warn("库存不足: 商品ID={}, 当前库存={}, 需要扣减={}", productId, currentStock, quantity);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -419,13 +419,60 @@
|
|||||||
productIds.push(parseInt($(this).val()));
|
productIds.push(parseInt($(this).val()));
|
||||||
});
|
});
|
||||||
|
|
||||||
// 跳转到结算页面
|
// 显示确认对话框
|
||||||
const form = $('<form method="post" action="${pageContext.request.contextPath}/checkout">');
|
if (!confirm('确定要结算选中的 ' + selectedItems.length + ' 个商品吗?\n\n结算后将生成订单,请及时支付。')) {
|
||||||
productIds.forEach(function (productId) {
|
return;
|
||||||
form.append('<input type="hidden" name="productIds" value="' + productId + '">');
|
}
|
||||||
|
|
||||||
|
// 禁用结算按钮防止重复点击
|
||||||
|
const checkoutBtn = $('#checkoutBtn');
|
||||||
|
const originalText = checkoutBtn.html();
|
||||||
|
checkoutBtn.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> 结算中...');
|
||||||
|
|
||||||
|
// 通过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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载推荐商品
|
// 加载推荐商品
|
||||||
|
|||||||
@@ -29,12 +29,6 @@
|
|||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.original-price {
|
|
||||||
color: #999;
|
|
||||||
text-decoration: line-through;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stock-badge {
|
.stock-badge {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
@@ -58,6 +52,20 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 40px;
|
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;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="container my-4">
|
<div class="container my-4">
|
||||||
@@ -96,7 +104,6 @@
|
|||||||
<option value="id,desc">最新上架</option>
|
<option value="id,desc">最新上架</option>
|
||||||
<option value="price,asc">价格从低到高</option>
|
<option value="price,asc">价格从低到高</option>
|
||||||
<option value="price,desc">价格从高到低</option>
|
<option value="price,desc">价格从高到低</option>
|
||||||
<option value="sales,desc">销量最高</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
@@ -172,6 +179,11 @@
|
|||||||
searchProducts();
|
searchProducts();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 更新购物车数量(如果用户已登录)
|
||||||
|
<c:if test="${not empty sessionScope.user}">
|
||||||
|
updateCartCount();
|
||||||
|
</c:if>
|
||||||
});
|
});
|
||||||
|
|
||||||
// 加载商品列表
|
// 加载商品列表
|
||||||
@@ -195,7 +207,7 @@
|
|||||||
params.append('sortDirection', sortValue[1]);
|
params.append('sortDirection', sortValue[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$.get('/api/product/list?' + params.toString())
|
$.get('${pageContext.request.contextPath}/api/product/list?' + params.toString())
|
||||||
.done(function (response) {
|
.done(function (response) {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
displayProducts(response.data.content);
|
displayProducts(response.data.content);
|
||||||
@@ -235,54 +247,46 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建商品卡片
|
// 创建商品卡片(参考热门商品样式)
|
||||||
function createProductCard(product) {
|
function createProductCard(product) {
|
||||||
const stockBadge = product.stock > 0 ?
|
const imageUrl = product.imageUrl || '${pageContext.request.contextPath}/images/default-product.svg';
|
||||||
`<span class="stock-badge bg-success">库存 ${product.stock}</span>` :
|
const productName = product.name;
|
||||||
`<span class="stock-badge bg-danger">无库存</span>`;
|
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 ?
|
var cardHtml = '<div class="col-lg-3 col-md-4 col-sm-6 mb-4">' +
|
||||||
`<span class="original-price">¥${product.originalPrice}</span>` : '';
|
'<div class="card product-card h-100">' +
|
||||||
|
'<div class="position-relative">' +
|
||||||
|
'<img src="' + imageUrl + '" class="card-img-top product-image" alt="' + productName + '" ' +
|
||||||
|
'onerror="this.src=\'${pageContext.request.contextPath}/images/default-product.svg\'; this.onerror=null;">' +
|
||||||
|
'<span class="stock-badge ' + (stock > 0 ? 'bg-success' : 'bg-danger') + '">' +
|
||||||
|
(stock > 0 ? '库存 ' + stock : '无库存') +
|
||||||
|
'</span>' +
|
||||||
|
'</div>' +
|
||||||
|
'<div class="card-body d-flex flex-column">' +
|
||||||
|
'<h6 class="card-title text-truncate" title="' + productName + '">' + productName + '</h6>' +
|
||||||
|
'<p class="card-text text-muted small flex-grow-1 text-truncate" title="' + productDescription + '">' +
|
||||||
|
productDescription +
|
||||||
|
'</p>' +
|
||||||
|
'<div class="d-flex justify-content-between align-items-center mb-2">' +
|
||||||
|
'<span class="text-primary fw-bold">¥' + price + '</span>' +
|
||||||
|
'<small class="text-muted">库存: ' + stock + '</small>' +
|
||||||
|
'</div>' +
|
||||||
|
'<div class="d-flex gap-2">' +
|
||||||
|
(stock > 0 ?
|
||||||
|
'<button class="btn btn-primary btn-sm flex-grow-1" onclick="addToCart(' + product.id + ')"><i class="fas fa-cart-plus"></i> 加入购物车</button>' :
|
||||||
|
'<button class="btn btn-secondary btn-sm flex-grow-1" disabled><i class="fas fa-ban"></i> 暂时缺货</button>'
|
||||||
|
) +
|
||||||
|
'<button class="btn btn-outline-secondary btn-sm" onclick="viewProductDetail(' + product.id + ')" title="查看详情">' +
|
||||||
|
'<i class="fas fa-eye"></i>' +
|
||||||
|
'</button>' +
|
||||||
|
'</div>' +
|
||||||
|
'</div>' +
|
||||||
|
'</div>' +
|
||||||
|
'</div>';
|
||||||
|
|
||||||
const addToCartBtn = product.stock > 0 ?
|
return cardHtml;
|
||||||
`<button class="btn btn-primary btn-sm" onclick="addToCart(${product.id})">
|
|
||||||
<i class="fas fa-cart-plus"></i> 加入购物车
|
|
||||||
</button>` :
|
|
||||||
`<button class="btn btn-secondary btn-sm" disabled>
|
|
||||||
<i class="fas fa-ban"></i> 暂时缺货
|
|
||||||
</button>`;
|
|
||||||
|
|
||||||
return `
|
|
||||||
<div class="col-lg-3 col-md-4 col-sm-6 mb-4">
|
|
||||||
<div class="card product-card h-100">
|
|
||||||
<div class="position-relative">
|
|
||||||
<img src="${product.imageUrl || '/static/images/default-product.svg'}"
|
|
||||||
class="card-img-top product-image" alt="${product.name}">
|
|
||||||
${stockBadge}
|
|
||||||
</div>
|
|
||||||
<div class="card-body d-flex flex-column">
|
|
||||||
<h6 class="card-title" title="${product.name}">
|
|
||||||
${product.name.length > 30 ? product.name.substring(0, 30) + '...' : product.name}
|
|
||||||
</h6>
|
|
||||||
<p class="card-text text-muted small flex-grow-1">
|
|
||||||
${product.description ?
|
|
||||||
(product.description.length > 50 ? product.description.substring(0, 50) + '...' : product.description) :
|
|
||||||
'暂无描述'}
|
|
||||||
</p>
|
|
||||||
<div class="price-section mb-2">
|
|
||||||
<span class="price">¥${product.price}</span>
|
|
||||||
${originalPrice}
|
|
||||||
</div>
|
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
|
||||||
${addToCartBtn}
|
|
||||||
<button class="btn btn-outline-secondary btn-sm" onclick="viewProductDetail(${product.id})">
|
|
||||||
<i class="fas fa-eye"></i> 详情
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新分页
|
// 更新分页
|
||||||
@@ -296,36 +300,36 @@
|
|||||||
// 上一页
|
// 上一页
|
||||||
const prevDisabled = currentPage === 0 ? 'disabled' : '';
|
const prevDisabled = currentPage === 0 ? 'disabled' : '';
|
||||||
pagination.append(`
|
pagination.append(`
|
||||||
<li class="page-item ${prevDisabled}">
|
<li class="page-item ${prevDisabled}">
|
||||||
<a class="page-link" onclick="loadProducts(${currentPage - 1})" href="javascript:void(0)">
|
<a class="page-link" onclick="loadProducts(${currentPage - 1})" href="javascript:void(0)">
|
||||||
<i class="fas fa-chevron-left"></i>
|
<i class="fas fa-chevron-left"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
// 页码
|
// 页码
|
||||||
let startPage = Math.max(0, currentPage - 2);
|
let startPage = Math.max(0, currentPage - 2);
|
||||||
let endPage = Math.min(totalPages - 1, currentPage + 2);
|
let endPage = Math.min(totalPages - 1, currentPage + 2);
|
||||||
|
|
||||||
if (startPage > 0) {
|
if (startPage > 0) {
|
||||||
pagination.append(`<li class="page-item"><a class="page-link" onclick="loadProducts(0)" href="javascript:void(0)">1</a></li>`);
|
pagination.append('<li class="page-item"><a class="page-link" onclick="loadProducts(0)" href="javascript:void(0)">1</a></li>');
|
||||||
if (startPage > 1) {
|
if (startPage > 1) {
|
||||||
pagination.append(`<li class="page-item disabled"><span class="page-link">...</span></li>`);
|
pagination.append('<li class="page-item disabled"><span class="page-link">...</span></li>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = startPage; i <= endPage; i++) {
|
for (let i = startPage; i <= endPage; i++) {
|
||||||
const active = i === currentPage ? 'active' : '';
|
const active = i === currentPage ? 'active' : '';
|
||||||
pagination.append(`
|
pagination.append(`
|
||||||
<li class="page-item ${active}">
|
<li class="page-item ${active}">
|
||||||
<a class="page-link" onclick="loadProducts(${i})" href="javascript:void(0)">${i + 1}</a>
|
<a class="page-link" onclick="loadProducts(${i})" href="javascript:void(0)">${i + 1}</a>
|
||||||
</li>
|
</li>
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endPage < totalPages - 1) {
|
if (endPage < totalPages - 1) {
|
||||||
if (endPage < totalPages - 2) {
|
if (endPage < totalPages - 2) {
|
||||||
pagination.append(`<li class="page-item disabled"><span class="page-link">...</span></li>`);
|
pagination.append('<li class="page-item disabled"><span class="page-link">...</span></li>');
|
||||||
}
|
}
|
||||||
pagination.append(`<li class="page-item"><a class="page-link" onclick="loadProducts(${totalPages - 1})" href="javascript:void(0)">${totalPages}</a></li>`);
|
pagination.append(`<li class="page-item"><a class="page-link" onclick="loadProducts(${totalPages - 1})" href="javascript:void(0)">${totalPages}</a></li>`);
|
||||||
}
|
}
|
||||||
@@ -333,19 +337,19 @@
|
|||||||
// 下一页
|
// 下一页
|
||||||
const nextDisabled = currentPage === totalPages - 1 ? 'disabled' : '';
|
const nextDisabled = currentPage === totalPages - 1 ? 'disabled' : '';
|
||||||
pagination.append(`
|
pagination.append(`
|
||||||
<li class="page-item ${nextDisabled}">
|
<li class="page-item ${nextDisabled}">
|
||||||
<a class="page-link" onclick="loadProducts(${currentPage + 1})" href="javascript:void(0)">
|
<a class="page-link" onclick="loadProducts(${currentPage + 1})" href="javascript:void(0)">
|
||||||
<i class="fas fa-chevron-right"></i>
|
<i class="fas fa-chevron-right"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查看商品详情
|
// 查看商品详情
|
||||||
function viewProductDetail(productId) {
|
function viewProductDetail(productId) {
|
||||||
currentProductId = productId;
|
currentProductId = productId;
|
||||||
|
|
||||||
$.get(`/api/product/${productId}`)
|
$.get('${pageContext.request.contextPath}/api/product/' + productId)
|
||||||
.done(function (response) {
|
.done(function (response) {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
displayProductDetail(response.data);
|
displayProductDetail(response.data);
|
||||||
@@ -362,91 +366,80 @@
|
|||||||
// 显示商品详情
|
// 显示商品详情
|
||||||
function displayProductDetail(product) {
|
function displayProductDetail(product) {
|
||||||
const modalBody = $('#productModalBody');
|
const modalBody = $('#productModalBody');
|
||||||
modalBody.html(`
|
const imageUrl = product.imageUrl || '${pageContext.request.contextPath}/images/default-product.svg';
|
||||||
<div class="row">
|
const stock = product.stock || 0;
|
||||||
<div class="col-md-6">
|
const price = product.price ? product.price.toFixed(2) : '0.00';
|
||||||
<img src="${product.imageUrl || '/static/images/default-product.svg'}"
|
|
||||||
class="img-fluid rounded" alt="${product.name}">
|
var modalHtml = '<div class="row">' +
|
||||||
</div>
|
'<div class="col-md-6">' +
|
||||||
<div class="col-md-6">
|
'<img src="' + imageUrl + '" class="img-fluid rounded" alt="' + product.name + '" ' +
|
||||||
<h4>${product.name}</h4>
|
'onerror="this.src=\'${pageContext.request.contextPath}/images/default-product.svg\'; this.onerror=null;">' +
|
||||||
<p class="text-muted">${product.description || '暂无详细描述'}</p>
|
'</div>' +
|
||||||
<div class="mb-3">
|
'<div class="col-md-6">' +
|
||||||
<span class="price h4">¥${product.price}</span>
|
'<h4>' + product.name + '</h4>' +
|
||||||
${product.originalPrice && product.originalPrice > product.price ?
|
'<p class="text-muted">' + (product.description || '暂无详细描述') + '</p>' +
|
||||||
'<span class="original-price ms-2">¥' + product.originalPrice + '</span>' : ''}
|
'<div class="mb-3">' +
|
||||||
</div>
|
'<span class="text-primary fw-bold h4">¥' + price + '</span>' +
|
||||||
<div class="mb-3">
|
'</div>' +
|
||||||
<span class="badge ${product.stock > 0 ? 'bg-success' : 'bg-danger'}">
|
'<div class="mb-3">' +
|
||||||
<c:choose>
|
'<span class="badge ' + (stock > 0 ? 'bg-success' : 'bg-danger') + '">' +
|
||||||
<c:when test="${product.stock > 0}">
|
(stock > 0 ? '库存 ' + stock : '暂时缺货') +
|
||||||
库存 ${product.stock}
|
'</span>' +
|
||||||
</c:when>
|
'</div>' +
|
||||||
<c:otherwise>
|
'<div class="mb-3">' +
|
||||||
暂时缺货
|
'<strong>商品状态:</strong> ' +
|
||||||
</c:otherwise>
|
'<span class="badge ' + (product.status === 1 ? 'bg-success' : 'bg-secondary') + '">' +
|
||||||
</c:choose>
|
(product.status === 1 ? '上架中' : '已下架') +
|
||||||
</span>
|
'</span>' +
|
||||||
</div>
|
'</div>' +
|
||||||
<div class="mb-3">
|
'</div>' +
|
||||||
<strong>商品类别:</strong> ${product.category || '未分类'}
|
'</div>';
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
modalBody.html(modalHtml);
|
||||||
<strong>商品状态:</strong>
|
|
||||||
<span class="badge">
|
|
||||||
<c:choose>
|
|
||||||
<c:when test="${product.status == 1}">
|
|
||||||
<span class="bg-success">上架中</span>
|
|
||||||
</c:when>
|
|
||||||
<c:otherwise>
|
|
||||||
<span class="bg-secondary">已下架</span>
|
|
||||||
</c:otherwise>
|
|
||||||
</c:choose>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
|
|
||||||
// 更新加入购物车按钮状态
|
// 更新加入购物车按钮状态
|
||||||
const addToCartBtn = $('#addToCartBtn');
|
const addToCartBtn = $('#addToCartBtn');
|
||||||
if (product.stock > 0 && product.status === 1) {
|
if (stock > 0 && product.status === 1) {
|
||||||
addToCartBtn.prop('disabled', false).html('<i class="fas fa-cart-plus"></i> 加入购物车');
|
addToCartBtn.prop('disabled', false).html('<i class="fas fa-cart-plus"></i> 加入购物车');
|
||||||
} else {
|
} else {
|
||||||
addToCartBtn.prop('disabled', true).html('<i class="fas fa-ban"></i> 暂时无法购买');
|
addToCartBtn.prop('disabled', true).html('<i class="fas fa-ban"></i> 暂时无法购买');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加到购物车
|
// 添加到购物车(参考首页实现)
|
||||||
function addToCart(productId) {
|
function addToCart(productId) {
|
||||||
if (!isUserLoggedIn()) {
|
<c:choose>
|
||||||
showLoginPrompt();
|
<c:when test="${not empty sessionScope.user}">
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
productId: productId,
|
|
||||||
quantity: 1
|
|
||||||
};
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '/api/cart/add',
|
url: '${pageContext.request.contextPath}/api/cart/add',
|
||||||
method: 'POST',
|
type: 'POST',
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
data: JSON.stringify(data)
|
data: JSON.stringify({
|
||||||
})
|
productId: productId,
|
||||||
.done(function (response) {
|
quantity: 1
|
||||||
|
}),
|
||||||
|
success: function (response) {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
showSuccess('商品已添加到购物车');
|
showMessage('商品已添加到购物车', 'success');
|
||||||
updateCartCount();
|
updateCartCount();
|
||||||
|
// 如果是从模态框添加的,关闭模态框
|
||||||
$('#productModal').modal('hide');
|
$('#productModal').modal('hide');
|
||||||
} else {
|
} else {
|
||||||
showError('添加失败:' + response.message);
|
showMessage(response.message, 'error');
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
.fail(function () {
|
error: function () {
|
||||||
showError('网络错误,请稍后重试');
|
showMessage('添加失败,请重试', 'error');
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
</c:when>
|
||||||
|
<c:otherwise>
|
||||||
|
showMessage('请先登录', 'warning');
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = '${pageContext.request.contextPath}/login?returnUrl=' + encodeURIComponent(window.location.pathname);
|
||||||
|
}, 1500);
|
||||||
|
</c:otherwise>
|
||||||
|
</c:choose>
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示加载状态
|
// 显示加载状态
|
||||||
@@ -461,40 +454,51 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查用户是否登录
|
// 显示消息(参考首页实现)
|
||||||
function isUserLoggedIn() {
|
function showMessage(message, type = 'info') {
|
||||||
// 这里需要根据实际的登录状态检查逻辑来实现
|
// 创建消息元素
|
||||||
return sessionStorage.getItem('userToken') ||
|
const alertDiv = document.createElement('div');
|
||||||
document.cookie.includes('JSESSIONID');
|
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}
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||||
|
`;
|
||||||
|
|
||||||
|
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() {
|
function updateCartCount() {
|
||||||
if (!isUserLoggedIn()) return;
|
$.get('${pageContext.request.contextPath}/api/cart/count')
|
||||||
|
|
||||||
$.get('/api/cart/count')
|
|
||||||
.done(function (response) {
|
.done(function (response) {
|
||||||
if (response.success && response.data.count > 0) {
|
if (response.success) {
|
||||||
$('.cart-count').text(response.data.count).show();
|
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) {
|
function showError(message) {
|
||||||
alert('错误:' + message);
|
showMessage(message, 'error');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 成功提示
|
// 成功提示
|
||||||
function showSuccess(message) {
|
function showSuccess(message) {
|
||||||
alert('成功:' + message);
|
showMessage(message, 'success');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user