This commit is contained in:
王子琦
2026-01-13 13:55:40 +08:00
parent 6affd0c77e
commit f58e05d962
72 changed files with 3251 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
<template>
<div class="page">
<el-card>
<el-button type="text" @click="$router.push('/')">返回首页</el-button>
</el-card>
<el-card class="content">
<el-row :gutter="20">
<el-col :span="10">
<img :src="product.coverUrl || placeholder" class="cover" />
</el-col>
<el-col :span="14">
<h2>{{ product.name }}</h2>
<p>{{ product.description }}</p>
<div class="price">{{ product.price }}</div>
<el-input-number v-model="quantity" :min="1" :max="product.stock || 99" />
<div class="section">
<el-select v-model="addressId" placeholder="选择收货地址">
<el-option
v-for="addr in addresses"
:key="addr.id"
:label="formatAddress(addr)"
:value="addr.id"
/>
</el-select>
<el-button type="primary" @click="submitOrder">立即购买</el-button>
</div>
</el-col>
</el-row>
</el-card>
</div>
</template>
<script>
import { getProduct } from '../api/product';
import { listAddresses } from '../api/address';
import { createOrder } from '../api/order';
export default {
data() {
return {
product: {},
quantity: 1,
addresses: [],
addressId: null,
placeholder: 'https://via.placeholder.com/400x300?text=Flower'
};
},
created() {
this.loadDetail();
this.loadAddresses();
},
methods: {
loadDetail() {
getProduct(this.$route.params.id).then((res) => {
this.product = res.data.data || {};
});
},
loadAddresses() {
listAddresses().then((res) => {
this.addresses = res.data.data || [];
const def = this.addresses.find((item) => item.isDefault);
if (def) {
this.addressId = def.id;
}
});
},
formatAddress(addr) {
return `${addr.recipientName} ${addr.phone} ${addr.province || ''}${addr.city || ''}${addr.district || ''}${addr.detail || ''}`;
},
submitOrder() {
if (!this.addressId) {
this.$message.warning('请选择收货地址');
return;
}
createOrder({
addressId: this.addressId,
items: [{ productId: this.product.id, quantity: this.quantity }]
}).then((res) => {
this.$message.success('下单成功');
const order = res.data.data.order;
this.$router.push(`/orders?highlight=${order.id}`);
});
}
}
};
</script>
<style scoped>
.page {
padding: 20px;
}
.content {
margin-top: 16px;
}
.cover {
width: 100%;
border-radius: 8px;
object-fit: cover;
}
.price {
color: #f56c6c;
font-size: 20px;
margin: 12px 0;
}
.section {
margin-top: 20px;
display: flex;
align-items: center;
}
.section .el-select {
margin-right: 12px;
width: 300px;
}
</style>