更改了购物车逻辑,增加了地址管理
This commit is contained in:
@@ -23,20 +23,43 @@
|
||||
<div class="address-section">
|
||||
<div class="address-header">
|
||||
<el-icon><Location /></el-icon>
|
||||
<span class="address-label">收货 地址</span>
|
||||
<el-icon class="edit-icon"><Edit /></el-icon>
|
||||
<span class="address-label">收货地址</span>
|
||||
<el-button
|
||||
type="text"
|
||||
@click="goToAddressManage"
|
||||
class="manage-address-btn"
|
||||
>
|
||||
管理地址
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="address-content">
|
||||
<div v-if="!showAddressEdit" class="address-text" @click="showAddressEdit = true">{{ shippingAddress }}</div>
|
||||
<el-input
|
||||
v-else
|
||||
v-model="shippingAddress"
|
||||
@blur="showAddressEdit = false"
|
||||
@keyup.enter="showAddressEdit = false"
|
||||
placeholder="请输入收货地址"
|
||||
class="address-input"
|
||||
autofocus
|
||||
/>
|
||||
<el-select
|
||||
v-model="selectedAddressId"
|
||||
placeholder="请选择收货地址"
|
||||
class="address-select"
|
||||
@change="handleAddressChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="address in addresses"
|
||||
:key="address.id"
|
||||
:label="`${address.recipientName} ${address.recipientPhone} ${address.province}${address.city}${address.district}${address.detailAddress}`"
|
||||
:value="address.id"
|
||||
>
|
||||
<div class="address-option">
|
||||
<div class="address-info">
|
||||
<span class="recipient-info">{{ address.recipientName }} {{ address.recipientPhone }}</span>
|
||||
<el-tag v-if="address.isDefault" type="danger" size="small" class="default-tag">默认</el-tag>
|
||||
</div>
|
||||
<div class="address-detail">{{ address.province }}{{ address.city }}{{ address.district }}{{ address.detailAddress }}</div>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<div v-if="addresses.length === 0" class="no-address">
|
||||
<span class="no-address-text">暂无收货地址</span>
|
||||
<el-button type="text" @click="goToAddressManage" class="add-address-btn">
|
||||
立即添加
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -115,7 +138,6 @@
|
||||
class="note-input"
|
||||
autofocus
|
||||
/>
|
||||
<el-icon v-if="!showNoteEdit" class="arrow-icon"><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -127,7 +149,7 @@
|
||||
<el-button
|
||||
size="large"
|
||||
class="cart-button"
|
||||
@click="addToCart"
|
||||
@click="handleAddToCart"
|
||||
:disabled="!canPurchase"
|
||||
>
|
||||
加入购物车
|
||||
@@ -170,9 +192,10 @@ const categories = ref([])
|
||||
const sizes = ref([])
|
||||
const selectedCategory = ref(null)
|
||||
const selectedSize = ref(null)
|
||||
const shippingAddress = ref('请输入收货地址')
|
||||
const addresses = ref([])
|
||||
const selectedAddressId = ref('')
|
||||
const selectedAddress = ref(null)
|
||||
const orderNote = ref('')
|
||||
const showAddressEdit = ref(false)
|
||||
const showNoteEdit = ref(false)
|
||||
|
||||
// 计算属性
|
||||
@@ -272,15 +295,21 @@ const addToCart = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 立即购买功能
|
||||
const handlePurchase = async () => {
|
||||
if (!canPurchase.value) {
|
||||
ElMessage.error('请选择完整的商品信息')
|
||||
return
|
||||
}
|
||||
|
||||
if (!selectedAddress.value) {
|
||||
ElMessage.error('请选择收货地址')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 先将商品添加到购物车
|
||||
const cartItem = {
|
||||
// 创建单独的购买订单
|
||||
const orderData = {
|
||||
productId: product.value.id,
|
||||
quantity: quantity.value,
|
||||
categoryId: selectedCategory.value.id,
|
||||
@@ -289,11 +318,11 @@ const handlePurchase = async () => {
|
||||
name: product.value.name,
|
||||
image: product.value.image,
|
||||
stock: product.value.stock,
|
||||
shippingAddress: shippingAddress.value,
|
||||
addressId: selectedAddress.value.id,
|
||||
orderNote: orderNote.value
|
||||
}
|
||||
|
||||
const response = await api.post('/cart/add', cartItem)
|
||||
const response = await api.post('/cart/buy-now', orderData)
|
||||
|
||||
if (response.data.success) {
|
||||
const cartId = response.data.data.cartId
|
||||
@@ -306,13 +335,73 @@ const handlePurchase = async () => {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
throw new Error(response.data.message || '添加到购物车失败')
|
||||
throw new Error(response.data.message || '创建订单失败')
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error(error.message || '操作失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
// 添加到购物车功能(新增)
|
||||
const handleAddToCart = async () => {
|
||||
if (!canPurchase.value) {
|
||||
ElMessage.error('请选择完整的商品信息')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
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.image,
|
||||
stock: product.value.stock
|
||||
}
|
||||
|
||||
const response = await api.post('/cart/add', cartItem)
|
||||
|
||||
if (response.data.success) {
|
||||
ElMessage.success('商品已加入购物车!')
|
||||
// 可以选择返回上一页或跳转到购物车页面
|
||||
router.go(-1)
|
||||
} else {
|
||||
throw new Error(response.data.message || '添加到购物车失败')
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error(error.message || '添加到购物车失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户地址列表
|
||||
const getAddressList = async () => {
|
||||
try {
|
||||
const response = await api.get('/address/list')
|
||||
addresses.value = response.data.data.addresses || []
|
||||
// 如果有默认地址,自动选中
|
||||
const defaultAddress = addresses.value.find(addr => addr.isDefault)
|
||||
if (defaultAddress) {
|
||||
selectedAddressId.value = defaultAddress.id
|
||||
selectedAddress.value = defaultAddress
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取地址列表失败:', error)
|
||||
ElMessage.error('获取地址列表失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 处理地址选择变化
|
||||
const handleAddressChange = (addressId) => {
|
||||
selectedAddress.value = addresses.value.find(addr => addr.id === addressId)
|
||||
}
|
||||
|
||||
// 跳转到地址管理页面
|
||||
const goToAddressManage = () => {
|
||||
router.push('/address')
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
// 从URL参数获取初始数量
|
||||
@@ -324,6 +413,7 @@ onMounted(() => {
|
||||
getProductInfo()
|
||||
getCategories()
|
||||
getSizes()
|
||||
getAddressList()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -382,10 +472,7 @@ onMounted(() => {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.address-text {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
||||
.product-section {
|
||||
background: white;
|
||||
@@ -557,12 +644,67 @@ onMounted(() => {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.arrow-icon {
|
||||
color: #ccc;
|
||||
.address-select {
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.address-input {
|
||||
margin-top: 8px;
|
||||
.manage-address-btn {
|
||||
color: #409eff;
|
||||
font-size: 14px;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.manage-address-btn:hover {
|
||||
color: #66b1ff;
|
||||
}
|
||||
|
||||
.address-option {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.address-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.recipient-info {
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.default-tag {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.address-detail {
|
||||
color: #606266;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.no-address {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.no-address-text {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.add-address-btn {
|
||||
color: #409eff;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.add-address-btn:hover {
|
||||
color: #66b1ff;
|
||||
}
|
||||
|
||||
.note-input {
|
||||
@@ -575,10 +717,7 @@ onMounted(() => {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.address-text {
|
||||
cursor: pointer;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
|
||||
.note-content {
|
||||
cursor: pointer;
|
||||
|
||||
Reference in New Issue
Block a user