Browse Source

feat: 商品详情页面;

pull/1/head
fox 2 months ago
parent
commit
a4f00134fb
7 changed files with 260 additions and 203 deletions
  1. +3
    -3
      components/product/productCard.vue
  2. +6
    -4
      pages.json
  3. +9
    -0
      pages/index/category.vue
  4. +1
    -1
      pages/index/index.vue
  5. +241
    -195
      pages_order/product/productDetail.vue
  6. BIN
      pages_order/static/productDetail/icon-share.png
  7. BIN
      pages_order/static/productDetail/temp-product.png

+ 3
- 3
components/product/productCard.vue View File

@ -29,7 +29,7 @@
<text>{{ `已售出 ${data.sales}` }}</text>
</view>
</view>
<button plain class="btn" @click="goToPlaceOrder">立即下单</button>
<button plain class="btn" @click="goToPlaceOrder(data.id)">立即下单</button>
</view>
</view>
</template>
@ -64,8 +64,8 @@
}
},
methods: {
goToPlaceOrder() {
// todo
goToPlaceOrder(id) {
this.$utils.navigateTo(`/pages_order/product/productDetail?id=${id}`)
}
},
}


+ 6
- 4
pages.json View File

@ -48,7 +48,12 @@
},
"subPackages": [{
"root": "pages_order",
"pages": [{
"pages": [
{
"path": "product/productDetail"
},
{
"path": "mine/partner"
},
{
@ -66,9 +71,6 @@
{
"path": "mine/address"
},
{
"path": "product/productDetail"
},
{
"path": "auth/wxLogin"
},


+ 9
- 0
pages/index/category.vue View File

@ -100,6 +100,11 @@
return {
mixinsListApi: 'queryItemList',
current : 0,
queryParams: {
pageNo: 1,
pageSize: 10,
title: null,
},
}
},
computed: {
@ -109,9 +114,13 @@
search,
cid
}) {
if (search) {
this.queryParams.title = search
}
// todo: check
return
// this.$store.commit('getCategoryList')
if(this.category.length > 0 && cid){
this.category.forEach((n, i) => {


+ 1
- 1
pages/index/index.vue View File

@ -15,7 +15,7 @@
<!-- 轮播图 -->
<view class="swipe">
<uv-swiper :list="bannerList" indicator height="340rpx" keyName="image"></uv-swiper>
<uv-swiper :list="bannerList" indicator indicatorMode="dot" height="340rpx" keyName="image"></uv-swiper>
</view>


+ 241
- 195
pages_order/product/productDetail.vue View File

@ -1,110 +1,71 @@
<template>
<view class="page">
<!-- 导航栏 -->
<!-- <navbar title="商品详情" leftClick @leftClick="$utils.navigateBack" /> -->
<navbar title="商品详情" leftClick @leftClick="$utils.navigateBack" />
<view class="swipe">
<uv-swiper :list="productDetail.image
&& productDetail.image.split(',')" indicator height="680rpx"></uv-swiper>
</view>
<uv-swiper :list="bannerList" indicator indicatorMode="dot" height="475rpx"></uv-swiper>
<!-- 商品标题 -->
<view class="info">
<view class="title">
{{ productDetail.title }}
</view>
<view class="price">
<view class="money">
<text>{{ productDetail.price }}</text>
<text class="unit">/元每件</text>
</view>
<view class="oldPrice">
<text>{{ productDetail.oldPrice }}</text>
<text class="unit">/</text>
</view>
</view>
<view class="price">
<view class="money">
<text>{{ productDetail.goldPrice }}</text>
<text class="unit">/元每件</text>
<view class="overview">
<view class="flex sale">
<view class="flex price" :class="[role]">
<view>
<text class="price-unit"></text>
<text>{{ productDetail.price }}</text>
</view>
<view class="flex tag" v-if="role === 'member-personal'">
<image class="icon" src="@/static/image/home/icon-member-personal.png"></image>
<text>个人会员价</text>
</view>
<view class="flex tag" v-else-if="role === 'member-business'">
<image class="icon" src="@/static/image/home/icon-member-business.png"></image>
<text>企业会员价</text>
</view>
</view>
<view class="price-imgs">
<image :src="configList.vip_money_one" mode="aspectFill"
class="price-img"></image>
<view>
<text>{{ `已售出:${productDetail.sales}` }}</text>
</view>
</view>
<view class="price">
<view class="money">
<text>{{ productDetail.silverPrice }}</text>
<text class="unit">/元每件</text>
</view>
<view class="price-imgs">
<image :src="configList.vip_money_two" mode="aspectFill" class="price-img">
</image>
</view>
<view class="title">
<text>{{ productDetail.title }}</text>
</view>
<view class="price">
<view class="money">
<text>{{ productDetail.diamondPrice }}</text>
<text class="unit">/元每件</text>
</view>
<view class="price-imgs">
<image :src="configList.vip_money_three" mode="aspectFill" class="price-img">
</image>
<view class="flex desc">
<view v-for="tag in productDetail.tags" :key="tag"
class="flex tag"
>
<view class="dot"></view>
<text>{{ tag }}</text>
</view>
</view>
</view>
<!-- 服务 -->
<view class="server">
<view class="setver-main">
<view class="title">服务</view>
<view class="descript">
免费上门退·7天无理由退货·快递发货
</view>
</view>
<view class="server-arraw">
<uv-icon name="arrow-right"></uv-icon>
<!-- 商品详情 -->
<view class="detail">
<view class="flex header">
<view class="underline"></view>
<view class="title">商品详情</view>
</view>
<!-- todo: check -->
<uv-parse :content="productDetail.details"></uv-parse>
</view>
<!-- 参数 -->
<view v-if="productDetail.sku" class="params">
<view class="params-main">
<view class="title">参数</view>
<view class="descript">
{{ productDetail.sku }}
<!-- 分享和购买按钮 -->
<view class="flex bar">
<button plain class="flex flex-column btn btn-share" open-type="share">
<image class="btn-share-icon" src="../static/productDetail/icon-share.png"></image>
<text>分享</text>
</button>
<view class="flex count">
<text>合计</text>
<view class="price">
<text class="price-unit">¥</text>
<!-- todo: check -->
<text>{{ productDetail.price }}</text>
</view>
</view>
<view class="server-arraw">
<uv-icon name="arrow-right"></uv-icon>
</view>
</view>
<!-- 商品详情 -->
<view class="item-line">
<view class="before"></view>
<view class="label">商品详情</view>
<button plain class="btn btn-pay" @click="submit">立即支付</button>
</view>
<uv-parse :content="productDetail.details"></uv-parse>
<!-- 分享和购买按钮 -->
<submit
@service="service"
@toSend="toSend"
@submit="submit"
@addCart="addCart"
:detail="productDetail" />
<!-- 联系客服 -->
<customerServicePopup ref="customerServicePopup" />
</view>
</template>
@ -126,6 +87,18 @@
details: '',
},
id: 0,
role: 'member-business', // member-personal | member-business
}
},
computed: {
bannerList() {
const { image } = this.productDetail
if (!image) {
return []
}
return Array.isArray(image) ? image : image.split(',')
}
},
onLoad(args) {
@ -134,25 +107,21 @@
onShow() {
this.getRiceProductDetail()
},
methods: {
//
share() {
onShareAppMessage(res) {
const {
title,
} = this.productDetail
},
//
addCart(){
this.$api('addCart', {
shopId : this.id,
num : 1,
}, res => {
if(res.code == 200){
uni.showToast({
title: '加入购物车成功',
icon: 'none'
})
}
})
},
// todo: check
let o = {
title: title,
imageUrl: bannerList[0],
query: `id=${this.productDetail.id}`,
}
return o
},
methods: {
//
submit() {
this.$store.commit('setPayOrderProduct', [
@ -172,6 +141,20 @@
},
//
getRiceProductDetail() {
// todo: delete test data
const TEMP_BANNER_IMG_URL = 'http://gips3.baidu.com/it/u=70459541,3412285454&fm=3028&app=3028&f=JPEG&fmt=auto?w=960&h=1280'
this.productDetail = {
image: new Array(4).fill(1).map(() => TEMP_BANNER_IMG_URL),
price: 99,
sales: 235,
title: '60分钟肩颈推拿按摩',
tags: ['专业技师', '舒适环境', '深度放松'],
details: '<p>这里是商品详情..............<br/>这里是商品详情..............</p>'
}
return
this.$api('getRiceProductDetail', {
id: this.id
}, res => {
@ -181,118 +164,181 @@
}
})
},
//
service() {
this.$refs.customerServicePopup.open()
},
}
}
</script>
<style scoped lang="scss">
$bar-height: 120rpx;
.page {
padding-bottom: 120rpx;
.swipe {}
//
.info {
padding: 20rpx;
background-color: #fff;
display: flex;
flex-direction: column;
gap: 14rpx;
.title {
font-size: 36rpx;
font-weight: 900;
}
padding-bottom: $bar-height;
background-color: #F3F3F3;
/deep/ .nav-bar__view {
background-image: linear-gradient(#84A73F, #D8FF8F);
}
// &
.server,
.params {
background: white;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
padding: 30rpx 20rpx;
box-sizing: border-box;
.overview {
padding: 16rpx 31rpx 18rpx 24rpx;
background-color: $uni-fg-color;
.setver-main,
.params-main {
display: flex;
flex-wrap: wrap;
width: 90%;
font-size: 32rpx;
.sale {
justify-content: space-between;
color: #949494;
font-size: 20rpx;
.title {
color: #7C7C7C;
margin-right: 20rpx;
.price {
color: #FF2A2A;
font-size: 45rpx;
&-unit {
font-size: 30rpx;
margin-right: 3rpx;
}
.tag {
font-size: 18rpx;
font-weight: 700;
padding: 9rpx 12rpx 9rpx 19rpx;
margin-left: 15rpx;
.icon {
width: 27rpx;
height: 19rpx;
margin-right: 3rpx;
}
}
&.member-personal {
color: $uni-color-light;
.tag {
background-color: rgba($color: #D8FF8F, $alpha: 0.72);
}
}
&.member-business {
color: #FFB465;
.tag {
background-color: rgba($color: #FFFBC4, $alpha: 0.72);
}
}
}
}
.server-arraw {
display: flex;
justify-content: flex-end;
text-align: right;
.title {
color: #3A3A3A;
font-size: 28rpx;
font-weight: 700;
margin-top: 15rpx;
}
}
//
.price {
display: flex;
align-items: center;
color: #f40;
font-size: 30rpx;
align-items: flex-end;
.money {
font-size: 30rpx;
.unit {
font-size: 24rpx;
.desc {
justify-content: space-between;
margin-top: 20rpx;
.tag {
color: #949494;
font-size: 22rpx;
.dot {
width: 8rpx;
height: 8rpx;
border-radius: 50%;
background-color: #949494;
margin-right: 16rpx;
}
}
}
.price-imgs {
display: flex;
flex-wrap: wrap;
.price-img {
width: 80rpx;
height: 30rpx;
margin-left: 10rpx;
}
.detail {
padding: 18rpx 28rpx;
background-color: $uni-fg-color;
.header {
position: relative;
margin-bottom: 25rpx;
.underline {
margin-top: 26rpx;
margin-left: 30rpx;
width: 146rpx;
height: 8rpx;
border-radius: 4rpx;
background-image: linear-gradient(to right, #84A73F, #D8FF8F);
}
.title {
color: #000000;
font-size: 28rpx;
font-weight: 700;
position: absolute;
top: 0;
}
}
}
.oldPrice{
color: #999;
font-size: 24rpx;
text-decoration: line-through;
}
.bar {
position: fixed;
bottom: 0;
left: 0;
width: 100vw;
height: $bar-height;
//
.item-line {
display: flex;
background: white;
padding: 20rpx 27rpx 20rpx 58rpx;
box-sizing: border-box;
font-size: 34rpx;
padding: 20rpx;
}
.item-line .before {
content: "";
width: 8rpx;
height: 30rpx;
background: $uni-color;
border-radius: 4rpx;
margin-right: 10rpx;
margin-top: 15rpx;
}
.count {
flex: 1;
color: #000000;
font-size: 28rpx;
margin-left: 29rpx;
padding-left: 40rpx;
border-left: 1rpx solid #B3997E;
justify-content: flex-start;
.item-line .label {
display: flex;
align-items: center;
width: 152rpx;
height: 60rpx;
.price {
color: #FF2A2A;
font-size: 30rpx;
&-unit {
font-size: 18rpx;
}
}
}
.btn {
border: none;
line-height: 1;
background-color: transparent;
padding: 0;
width: auto;
height: auto;
margin: 0;
&-share {
color: #000000;
font-size: 22rpx;
&-icon {
width: 48rpx;
height: 50rpx;
margin-bottom: 11rpx;
}
}
&-pay {
padding: 24rpx 137rpx;
color: $uni-text-color-inverse;
font-size: 28rpx;
border-radius: 44rpx;
background-image: linear-gradient(to right, #84A73F, #D8FF8F);
}
}
}
}
</style>

BIN
pages_order/static/productDetail/icon-share.png View File

Before After
Width: 48  |  Height: 50  |  Size: 1.4 KiB

BIN
pages_order/static/productDetail/temp-product.png View File

Before After
Width: 750  |  Height: 475  |  Size: 422 KiB

Loading…
Cancel
Save