You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
shop-app/pages/goods/detail/index.vue

257 lines
6.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!--
* @Author: ch
* @Date: 2022-03-23 17:27:21
* @LastEditors: ch
* @LastEditTime: 2022-04-27 21:16:21
* @Description: file content
-->
<template>
<view>
<view class="back" @click="$Router.back()">
<image class="back--icon" src="@/static/goods/back.png"/>
</view>
<SlideImage :images="goods.pictureList"></SlideImage>
<SeckillPrice :data.sync="productActivityVO" :activityStatus="activityStatus"
v-if="productActivityVO.isActivity" @change="getGoodsDetail"
:title="goods.name"></SeckillPrice>
<view class="goods-info" v-if="!productActivityVO.isActivity">
<view class="pirce">
<text>¥</text>
<text class="pirce--max">{{goods.startingPrice}}</text>
<text>起</text>
</view>
<view class="goods-info--title">{{goods.name}}</view>
</view>
<view class="select">
<Service></Service>
<u-cell label="选择" :value="curSku.name || '请选择规格'" :border="false" isLink @click="onShowSkuPopup(1)"></u-cell>
<SkuPopup v-model="curSku" :visible.sync="showSkuPopup" :mode="skuMode"
:goodsInfo="goods" :skuInfo="skuInfoData" :activityStatus="activityStatus">
</SkuPopup>
</view>
<view class="goods-desc">
<mp-html :content="goods.content"/>
</view>
<view class="footer">
<view class="footer--left">
<view class="icon service">客服</view>
<view class="icon cart" @click="$Router.push('/cart')"></view>
</view>
<view class="footer--btns">
<UiButton class="btn" :disable="stock == 0 || activityStatus == 'startActivity'" @click="onShowSkuPopup(2)"></UiButton>
<UiButton class="btn btn--buy" :disable="stock == 0" @click="onShowSkuPopup(3)"> </UiButton>
</view>
</view>
</view>
</template>
<script>
import {ApiGetGoodsDetail, ApiGetGoodsSkus} from '@/common/api/goods';
import SlideImage from './components/SlideImage.vue';
import Service from './components/Service.vue';
import SkuPopup from './components/SkuPopup.vue';
import mpHtml from 'mp-html/dist/uni-app/components/mp-html/mp-html';
import UiButton from '../../../components/UiButton.vue';
import SeckillPrice from './components/SeckillPrice.vue';
export default {
components: { SlideImage, mpHtml, Service, SkuPopup, UiButton, SeckillPrice},
data(){
return {
goods : {
pictureList : []
},
skuInfoData : [],
curSku : {},
showSkuPopup : false,
// sku弹窗模式 1:都显示 2:只显示购物车 3:只显示立即购买
skuMode : 1,
selectedSkuInfo : {
sku : '',
num : 1
},
productActivityVO : {}
}
},
computed:{
activityStatus(){
// noActivity 没有活动 noStartActivity有活动未开始 startActivity活动已开始
let status = 'noActivity';
if(this.productActivityVO.isActivity){
status = 'noStartActivity';
}
if(this.productActivityVO.isStartActivity){
status = 'startActivity';
}
return status;
},
stock(){
let stock = 0;
this.skuInfoData.forEach(i => {
stock += i.stock
})
return stock
}
},
onLoad(){
this.getGoodsDetail();
},
methods:{
async getGoodsDetail(){
const {query} = this.$Route;
const {error, result} = await ApiGetGoodsDetail({id : query.id});
if(error){
uni.$u.toast(error.message);
return false;
}
this.goods = {...result,
images : result.pictureList || [],
};
// 秒杀活动数据,单独拎出来传给秒杀价格组件
this.productActivityVO = {
...result.productActivityVO,
// 原价,取商品起售价
originalPrice:result.startingPrice
};
this.getGoodsSkus();
},
async getGoodsSkus(){
const {query} = this.$Route;
const {error, result} = await ApiGetGoodsSkus({productId : query.id});
if(error) {
uni.$u.toast(error.message);
return false;
}
this.skuInfoData = result;
},
/**
* 显示/隐藏SKU弹窗
* @param {skuMode} 模式 1:都显示 2:只显示购物车 3:只显示立即购买
*/
onShowSkuPopup(skuMode = 1) {
this.skuMode = skuMode
this.showSkuPopup = true
},
}
}
</script>
<style lang="scss" scoped>
page{
background: $color-grey1;
padding-bottom: 206rpx;
}
.back{
position: absolute;
width: 50rpx;
height: 50rpx;
left: 40rpx;
/* #ifdef H5 */
top: 40rpx;
/* #endif */
/* #ifndef H5 */
top: 128rpx;
/* #endif */
background: rgba($color: #000000, $alpha: .1);
z-index: 999;
border-radius: 50%;
&--icon{
width: 14rpx;
height: 28rpx;
margin: 10rpx 0 0 15rpx;
}
}
.goods-info{
margin: 20rpx 30rpx 0;
background: $color-grey0;
border-radius: 16rpx;
padding: 30rpx;
&--title{
font-size: $font-size-lg;
line-height: 48rpx;
}
}
.pirce{
text{
color: $color-yellow3;
font-size: $font-size-base;
&.pirce--max{
font-size: 52rpx;
margin: 0 10rpx 24rpx 0;
}
}
}
.select{
margin: 20rpx 30rpx;
background: $color-grey0;
border-radius: 16rpx;
}
.goods-desc{
margin: 20rpx 30rpx;
background: $color-grey0;
border-radius: 16rpx;
padding: 20rpx;
}
.footer{
height: 206rpx;
padding: 0 30rpx 68rpx 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
bottom: 0;
left: 0;
right: 0;
border-top-left-radius: 24rpx;
border-top-right-radius: 24rpx;
background: $color-grey0;
box-shadow: 0 8rpx 80rpx 1px rgba(0, 0, 0, 0.1);
&--left{
display: flex;
}
&--btns{
background: #FFF3EE;
border-radius: 40rpx;
height: 80rpx;
overflow: hidden;
}
.icon{
font-size: 22rpx;
padding-top: 60rpx;
background: url('@/static/goods/service_icon.png') no-repeat center top;
background-size: 48rpx;
color: $color-grey6;
&.cart{
margin-left: 40rpx;
background-image: url('@/static/goods/cart_icon.png');
}
}
.btn{
width: 250rpx;
height: 80rpx;
line-height: 80rpx;
display: inline-block;
background: none;
border: none;
font-size: $font-size-base;
color: $color-yellow3;
border-bottom-left-radius: 0;
border-top-left-radius: 0;
padding: 0;
&::after{
display: none;
}
&--buy{
background: url('@/static/goods/buy.png');
background-size: 250rpx;
color: $color-grey0;
}
}
}
</style>