更改了购物车逻辑,增加了地址管理
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user