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

268 lines
6.3 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-29 19:56:18
* @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 v-if="stock > 0" 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.detail"/>
</view>
<view class="footer--not-stock" v-if="stock === 0">商品无库存啦~看看其他的吧</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 {
// 总库存为了默认不提示无库存默认值为1
stock : 1,
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;
}
},
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;
// 设置总库存
this.stock = 0;
this.skuInfoData.forEach(i => {
this.stock += i.stock
})
},
/**
* 显示/隐藏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);
&--not-stock{
width: 100%;
height: 80rpx;
line-height: 80rpx;
background: rgba($color: #2E354E, $alpha: .5);
color: $color-grey0;
text-align: center;
position: fixed;
bottom: 206rpx;
}
&--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>