20260929
This commit is contained in:
@@ -0,0 +1,289 @@
|
||||
<template>
|
||||
<view class="product-page">
|
||||
<view class="page-hero">
|
||||
<AppNavbar class="page-navbar" title="商品详情"/>
|
||||
</view>
|
||||
<view class="product-detail" v-if="product.goodsId">
|
||||
<view class="gallery card">
|
||||
<swiper class="swiper" circular autoplay indicator-dots indicator-color="#d8e6ff"
|
||||
indicator-active-color="#2563eb" v-if="product.files">
|
||||
<swiper-item v-for="(img, idx) in JSON.parse(product.files)" :key="idx">
|
||||
<image class="cover" :src="img.url" mode="aspectFill"></image>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<!-- <view class="badge rating">评分 {{ product.rating }} / 5</view>-->
|
||||
</view>
|
||||
|
||||
<view class="card block">
|
||||
<view class="price-row">
|
||||
<view class="price">¥{{ product.salePrice }}</view>
|
||||
<view class="origin">¥{{ product.originPrice }}</view>
|
||||
<view class="coupon" @tap="openCoupon">领券</view>
|
||||
</view>
|
||||
<view class="name">{{ product.goodsName }}</view>
|
||||
<!-- <view class="sell-point">{{ // product.sellPoint }}</view>-->
|
||||
<!-- <view class="meta">规格:{{ product.specs }} · 厂家:{{ product.vendor }}</view>-->
|
||||
</view>
|
||||
|
||||
<!-- <view class="card block">-->
|
||||
<!-- <view class="section-title">商品规格</view>-->
|
||||
<!-- <view class="specs">-->
|
||||
<!-- <view class="chip" v-for="spec in product.specOptions" :key="spec" :class="{'active': spec === selectedSpec}"-->
|
||||
<!-- @tap="selectedSpec = spec">{{ spec }}-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
|
||||
<view class="card block">
|
||||
<view class="section-title">图文详情</view>
|
||||
<u-parse :content="product.content"/>
|
||||
</view>
|
||||
|
||||
<!-- <view class="card block">-->
|
||||
<!-- <view class="section-title">热卖推荐</view>-->
|
||||
<!-- <view class="recommend" v-for="item in recommends" :key="item.id" @tap="openRecommend(item)">-->
|
||||
<!-- <view class="rec-name">{{ item.name }}</view>-->
|
||||
<!-- <view class="rec-meta">{{ item.specs }} · ¥{{ item.price }}</view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
|
||||
<view class="action-bar">
|
||||
<u-icon name="share" label="分享" label-pos="bottom" size="40rpx"/>
|
||||
<view class="action-group">
|
||||
<view class="primary-btn" @tap="addCart">加入购物车</view>
|
||||
<view class="primary-btn buy" @tap="buyNow">立即购买</view>
|
||||
</view>
|
||||
</view>
|
||||
<Login ref="Login" @done="getUserData"/>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {goodsInfoReq} from "@/api/goods";
|
||||
import Login from "@/components/Login.vue";
|
||||
import {userInfoReq} from "@/api/user";
|
||||
import {getUserInfo} from "@/util/user";
|
||||
import {addCartReq} from "@/api/cart";
|
||||
import AppNavbar from "@/components/AppNavbar.vue";
|
||||
|
||||
export default {
|
||||
components: {Login, AppNavbar},
|
||||
data() {
|
||||
return {
|
||||
product: {},
|
||||
selectedSpec: '10袋/盒',
|
||||
recommends: [],
|
||||
isLoggedIn: false,
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options.id) {
|
||||
this.id = options.id
|
||||
this.getInfo()
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
if (getUserInfo().token) {
|
||||
this.isLoggedIn = true
|
||||
this.getUserData()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getUserData() {
|
||||
const {data} = await userInfoReq()
|
||||
this.isLoggedIn = true
|
||||
},
|
||||
async getInfo() {
|
||||
const {data} = await goodsInfoReq(this.id)
|
||||
this.product = data
|
||||
},
|
||||
openCoupon() {
|
||||
uni.navigateTo({
|
||||
url: '/packageUser/coupon/index'
|
||||
})
|
||||
},
|
||||
async addCart() {
|
||||
if (!this.isLoggedIn) return this.$refs.Login.open()
|
||||
await addCartReq({
|
||||
goodsId: this.product.goodsId,
|
||||
num: 1
|
||||
})
|
||||
uni.showToast({
|
||||
title: '已加入购物车',
|
||||
icon: 'success'
|
||||
})
|
||||
},
|
||||
buyNow() {
|
||||
const goodsDataList = [{
|
||||
goodsId: this.product.goodsId,
|
||||
num: 1
|
||||
}]
|
||||
uni.navigateTo({
|
||||
url: `/pages/order/checkout?goodsDataList=${JSON.stringify(goodsDataList)}`
|
||||
})
|
||||
},
|
||||
openRecommend(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/detail?name=${encodeURIComponent(item.name)}&price=${item.price}&origin=${item.price}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.product-page {
|
||||
min-height: 100vh;
|
||||
padding: 0 20rpx 100rpx;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.page-hero {
|
||||
padding: 30rpx 6rpx 18rpx;
|
||||
background: url('https://yaodongxiao.oss-cn-guangzhou.aliyuncs.com/20260126/462bfa04cf0eff8698884c38b9d17519.png') no-repeat
|
||||
top center / 100% auto;
|
||||
}
|
||||
|
||||
.page-navbar {
|
||||
padding: 0 6rpx;
|
||||
}
|
||||
|
||||
.product-detail {
|
||||
padding: 0 6rpx 100rpx;
|
||||
}
|
||||
|
||||
.gallery {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.swiper {
|
||||
height: 320rpx;
|
||||
}
|
||||
|
||||
.cover {
|
||||
width: 100%;
|
||||
height: 320rpx;
|
||||
}
|
||||
|
||||
.rating {
|
||||
position: absolute;
|
||||
top: 12rpx;
|
||||
right: 12rpx;
|
||||
}
|
||||
|
||||
.block {
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
|
||||
.price-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: #ff3b30;
|
||||
font-size: 36rpx;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.origin {
|
||||
color: #a1aabc;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.coupon {
|
||||
color: #ff8354;
|
||||
background: #fff1e9;
|
||||
border-radius: 999rpx;
|
||||
padding: 6rpx 12rpx;
|
||||
border: 1rpx dashed #ffb08a;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 34rpx;
|
||||
font-weight: 800;
|
||||
color: var(--text-main);
|
||||
margin: 8rpx 0;
|
||||
}
|
||||
|
||||
.sell-point {
|
||||
color: #ff3b30;
|
||||
font-size: 26rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.meta {
|
||||
color: var(--text-sub);
|
||||
}
|
||||
|
||||
.specs {
|
||||
display: flex;
|
||||
gap: 10rpx;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.chip.active {
|
||||
background: linear-gradient(135deg, var(--brand-primary), var(--brand-primary-soft));
|
||||
color: #fff;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.detail-text {
|
||||
color: var(--text-main);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.recommend {
|
||||
padding: 12rpx 0;
|
||||
border-bottom: 1rpx solid #edf1f7;
|
||||
}
|
||||
|
||||
.recommend:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.rec-name {
|
||||
font-weight: 700;
|
||||
color: var(--text-main);
|
||||
}
|
||||
|
||||
.rec-meta {
|
||||
color: var(--text-sub);
|
||||
font-size: 24rpx;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.action-bar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
padding: 12rpx 24rpx;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 -6rpx 16rpx rgba(31, 111, 232, 0.08);
|
||||
}
|
||||
|
||||
.collect {
|
||||
color: var(--brand-primary);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.action-group {
|
||||
margin-left: 20rpx;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.buy {
|
||||
margin-left: 20rpx;
|
||||
background: linear-gradient(135deg, #ff8354, #ff9f72);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user