更改了购物车逻辑,增加了地址管理

This commit is contained in:
2025-08-27 10:16:48 +08:00
parent 2ae7f21b68
commit ff5b70345e
7 changed files with 1626 additions and 90 deletions

View File

@@ -125,15 +125,29 @@
<!-- 商品描述 -->
<div class="product-description">
<h3>商品描述</h3>
<p>{{ product.description }}</p>
<h3 class="section-title">
商品描述
</h3>
<div v-if="showDescription" class="section-content">
<p>{{ product.description }}</p>
</div>
<div v-else class="section-placeholder">
<span class="placeholder-text" @click="toggleDescription">详情</span>
</div>
</div>
<!-- 商品详情 -->
<div class="product-details">
<h3>商品详情</h3>
<div class="detail-content">
<p>{{ product.description || '暂无详细描述' }}</p>
<h3 class="section-title">
商品详情
</h3>
<div v-if="showDetails" class="section-content">
<div class="detail-content">
<p>{{ product.description || '暂无详细描述' }}</p>
</div>
</div>
<div v-else class="section-placeholder">
<span class="placeholder-text" @click="toggleDetails">详情</span>
</div>
</div>
@@ -261,9 +275,14 @@
<div v-else class="cart-items">
<div class="cart-header">
<span> {{ cartTotalItems }} 件商品</span>
<el-button type="text" @click="clearCart" class="clear-btn">
清空购物车
</el-button>
<div class="cart-actions">
<el-button type="text" @click="goToCartPage" class="manage-btn">
管理
</el-button>
<el-button type="text" @click="clearCart" class="clear-btn">
清空购物车
</el-button>
</div>
</div>
<div class="cart-list">
@@ -378,6 +397,10 @@ const cartLoading = ref(false)
const userPoints = ref(0)
const cartItems = ref([])
const cartCount = ref(0)
const showDescription = ref(false)
const showDetails = ref(false)
const selectedCategory = ref(null)
const selectedSize = ref(null)
// 计算属性
const totalPoints = computed(() => {
@@ -432,7 +455,7 @@ const getProductDetail = async () => {
}
}
const addToCart = () => {
const addToCart = async () => {
if (!product.value) {
ElMessage.error('商品信息加载中,请稍后再试')
return
@@ -443,14 +466,51 @@ const addToCart = () => {
return
}
// 跳转到BuyDetails页面进行确认订单
router.push({
path: '/buydetail',
query: {
productId: product.value.id,
quantity: quantity.value
try {
// 检查是否已选择必要的商品属性
if (!selectedCategory.value || !selectedSize.value) {
// 如果没有选择属性跳转到BuyDetails页面进行详细配置
router.push({
path: '/buydetail',
query: {
productId: product.value.id,
quantity: quantity.value
}
})
return
}
})
// 构建购物车商品数据
const cartItem = {
productId: product.value.id,
quantity: quantity.value,
categoryId: selectedCategory.value.id,
sizeId: selectedSize.value.id,
points: product.value.points,
name: product.value.name,
image: product.value.images?.[0] || product.value.image,
stock: product.value.stock
}
// 添加到购物车
const response = await api.post('/cart/add', cartItem)
if (response.data.success) {
ElMessage.success('商品已加入购物车!')
// 更新本地购物车数据
await loadCartFromBackend()
// 重置选择状态
quantity.value = 1
selectedCategory.value = null
selectedSize.value = null
} else {
throw new Error(response.data.message || '添加到购物车失败')
}
} catch (error) {
ElMessage.error(error.message || '添加到购物车失败,请重试')
}
}
// 购物车商品管理方法
@@ -540,6 +600,12 @@ const loadCartFromBackend = async () => {
}
}
// 跳转到购物车管理页面
const goToCartPage = () => {
showCart.value = false
router.push('/cart')
}
// 购物车结算功能
const checkoutCart = async () => {
if (cartItems.value.length === 0) {
@@ -547,43 +613,40 @@ const checkoutCart = async () => {
return
}
if (cartTotalPoints.value > userPoints.value) {
ElMessage.error('积分不足,无法结算')
return
}
try {
await ElMessageBox.confirm(
`确定要花费 ${cartTotalPoints.value} 积分购买这些商品吗?`,
'确认结算',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
const orderData = {
// 创建购物车结算请求
const cartData = {
items: cartItems.value.map(item => ({
productId: item.id,
productId: item.id || item.productId,
quantity: item.quantity,
points: item.points
})),
totalPoints: cartTotalPoints.value
points: item.points,
name: item.name,
image: item.image,
categoryId: item.categoryId,
sizeId: item.sizeId
}))
}
await api.post('/orders', orderData)
const response = await api.post('/cart/checkout', cartData)
// 清空购物车
cartItems.value = []
showCart.value = false
ElMessage.success('结算成功!')
router.push('/orders')
if (response.data.success) {
const cartId = response.data.data.cartId
// 跳转到支付页面
router.push({
path: '/pay',
query: {
cartId: cartId
}
})
// 关闭购物车弹窗
showCart.value = false
} else {
throw new Error(response.data.message || '创建订单失败')
}
} catch (error) {
if (error !== 'cancel') {
ElMessage.error('结算失败,请重试')
}
ElMessage.error(error.message || '结算失败,请重试')
}
}
@@ -652,6 +715,14 @@ const getUserPoints = async () => {
}
}
const toggleDescription = () => {
showDescription.value = !showDescription.value
}
const toggleDetails = () => {
showDetails.value = !showDetails.value
}
// 生命周期
onMounted(() => {
//getProductDetail()
@@ -881,19 +952,52 @@ watch(
margin-bottom: 20px;
}
.product-description h3,
.product-details h3 {
.section-title {
margin: 0 0 12px 0;
font-size: 16px;
color: #333;
padding: 8px 0;
border-bottom: 1px solid #eee;
}
.product-description p {
.section-content {
padding: 12px 0;
animation: slideDown 0.3s ease;
}
.section-content p {
margin: 0;
line-height: 1.6;
color: #666;
}
.section-placeholder {
padding: 12px 0;
}
.placeholder-text {
color: #999;
font-size: 14px;
font-style: italic;
cursor: pointer;
transition: color 0.3s ease;
}
.placeholder-text:hover {
color: #409eff;
}
@keyframes slideDown {
from {
opacity: 0;
max-height: 0;
}
to {
opacity: 1;
max-height: 200px;
}
}
.detail-item {
display: flex;
padding: 8px 0;
@@ -1172,6 +1276,21 @@ watch(
color: #666;
}
.cart-actions {
display: flex;
align-items: center;
gap: 10px;
}
.manage-btn {
color: #409eff;
font-size: 14px;
}
.manage-btn:hover {
color: #66b1ff;
}
.clear-btn {
color: #ff4757;
font-size: 12px;