<template>
<view class="content">
<swiper
vertical
circular
:style="{ height : height + 'px'}"
:current='swiperActiveIndex'
@change='swiperChange'
>
<swiper-item
:style="{ height : height + 'px'}"
v-for='item in swiperList'
:key='item.id'
@click.stop='details(item.id)'
>
<view class='goods' @click.stop='show=true'>
<view class='goods-cart'>
<image src='../../static/images/shop.png'></image>
</view>
<view class='goods-title'>
<view>{{ item.title }}</view>
</view>
</view>
<image :src='item.skus[0].resources[0].resPath' :style="{ height : height + 'px'}"></image>
</swiper-item>
</swiper>
<u-popup :show="show" @close="show=false" @open="show=true">
<view>
<image :src='goods.img'></image>
<view>
<view>{{ changePrice(goods.price) }}</view>
<view>{{ goods.title }}</view>
<view>
<button open-type="share" class='share'>分享</button>
<view
@click.stop='$u.debounce(fav, 1000)'
:class='goods.isFav==1?"fav-active":""'
>收藏 {{ goods.isFav }}</view>
<button @click.stop='goPayment'>立即购买</button>
</view>
</view>
</view>
</u-popup>
<u-popup :show="isShow" @close="isShow=false" @open="isShow=true">
<view class='goods-main'>
<view class='goods-img'>
<image :src="goodsCurrent.resources[0].resPath" mode=""></image>
<view> {{ goodsCurrent.currentPrice }} </view>
</view>
<view v-for='item in spec' :key='item.id' class='goods-sku'>
<view>{{ item.name}} ({{ item.children.length }})</view>
<view class='sku-item'>
<view
v-for='(k,index) in item.children'
:key='index'
@click.stop='skuBtn(item,k.name)'
:class='k.active?"skus-active":""'
>
{{ k.name }}
</view>
</view>
</view>
<view v-if='goodsCurrent.stock == 0'>
商品已售罄....
</view>
<view v-else class='goods-number'>
<view>购买数量</view>
<u-number-box :min="1" :max="goodsCurrent.stock" v-model="number"></u-number-box>
</view>
<view class='goods-order'>
<button
:disabled="goodsCurrent.stock == 0"
@click='confirmOrder'
>立即购买</button>
</view>
</view>
</u-popup>
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
import { goodsPage , getGoods } from '@/utils/api/goods.js'
import changeGoods from '@/mixins/changeGoods.js'
import { collectAdd , collectDelete } from '@/utils/api/fav.js'
export default {
mixins:[changeGoods],
data() {
return {
height:'',
swiperActiveIndex:0,
goodsList:[],
swiperList:[],
pages:{
current:1,
size:10
},
currentIndex:0,
show:false,
isShow:false,
goods:{
id:0,
img:'',
title:'',
price:0,
isFav:0,
},
spec:[],
skus:[],
goodsCurrent:[],
number:1,
}
},
onLoad() {
this.dataInit();
this.height = uni.getSystemInfoSync().windowHeight;
},
methods: {
async dataInit(){
let { current , size } = this.pages;
let res = await goodsPage({ current , size });
this.goodsList = Object.freeze( [...this.goodsList , ...this.convert(res.data.records)] );
this.getShowList();
},
convert( record ){
record.forEach(item=>{
(item.skus).forEach( skusItem=>{
skusItem.resources = JSON.parse( skusItem.resources );
})
})
return record;
},
getShowList(){
let currentValue = this.goodsList[this.currentIndex];
let nextValue = this.goodsList[ this.getDataIndex( this.currentIndex + 1 ) ];
let prevValue = this.goodsList[ this.getDataIndex( this.currentIndex - 1 ) ]
this.swiperList = new Array(3);
this.swiperList[ this.swiperActiveIndex ] = currentValue;
this.swiperList[ this.getSwiperIndex( this.swiperActiveIndex + 1 ) ] = nextValue;
this.swiperList[ this.getSwiperIndex( this.swiperActiveIndex - 1 ) ] = prevValue;
let goods = this.swiperList[this.swiperActiveIndex];
this.goods = {
id:goods.id,
img:goods.skus[0].resources[0].resPath,
title:goods.title,
price:goods.skus[0].currentPrice,
isFav:goods.isCollected
}
},
getDataIndex( index ){
if( index < 0 ){
return this.goodsList.length - 1;
}else if( index >= this.goodsList.length ){
return 0;
}else{
return index;
}
},
getSwiperIndex( index ){
if( index < 0 ){
return this.swiperList.length - 1;
}else if( index >= this.swiperList.length ){
return 0;
}else{
return index;
}
},
swiperChange( e ){
let current = e.detail.current;
if( [1,1-this.swiperList.length].includes(current-this.swiperActiveIndex) ){
this.currentIndex = this.getDataIndex( this.currentIndex + 1 );
}else{
this.currentIndex = this.getDataIndex( this.currentIndex - 1 );
if( this.currentIndex == this.goodsList.length-1 ){
this.pages.current++;
this.dataInit();
}
}
this.swiperActiveIndex = current;
this.getShowList();
},
async goPayment(){
this.show = false;
let { id } = this.goods;
let res = await getGoods(id);
let data = res.data;
let specialSpecArray = data.specialSpecArray;
let specialSpec = JSON.parse( data.specialSpec );
let spec = [];
let skus = data.skus;
for( let i=0;i<skus.length;i++){
skus[i].resources = JSON.parse( skus[i].resources );
skus[i].specialSku = JSON.parse( skus[i].specialSku );
for( let k in skus[i].specialSku ){
skus[i][k] = skus[i].specialSku[k];
}
}
this.skus = skus;
this.goodsCurrent = skus[0];
specialSpecArray.forEach(v=>{
let children = [];
for( let i=0;i<specialSpec[v.id].length;i++){
children.push({
name:specialSpec[v.id][i],
active:specialSpec[v.id][i] == this.goodsCurrent[v.id] ? true : false
})
}
spec.push({
id:v.id,
name:v.name,
children
})
})
this.spec = spec;
this.isShow = true;
},
skuBtn( item , name ){
let currentObj = {};
for( let i=0;i<this.spec.length; i++){
if( this.spec[i]['id'] == item.id ){
this.spec[i].children.forEach(v=>{
v.active = false;
if( v.name == name ){
v.active = true;
}
})
}
this.spec[i].children.forEach(v=>{
if( v.active ){
currentObj[this.spec[i].id] = v.name;
}
})
}
for( let i=0;i<this.skus.length;i++){
let number = 0;
for(let k in currentObj){
if( this.skus[i][k] == currentObj[k] ){
number++;
}
}
if( number == Object.keys(currentObj).length ){
this.goodsCurrent = this.skus[i];
}
}
},
details( id ){
uni.navigateTo({
url:`/pages/goods-detail?id=${id}`
})
},
confirmOrder(){
if( !this.$store.state.userInfo.status ){
return uni.navigateTo({
url:'/login/login'
})
}
let { id , currentPrice , stock , spuId } = this.goodsCurrent;
let { img , title } = this.goods;
let confirm = {
id,
currentPrice,
stock,
img,
title,
spuId,
number:this.number
}
uni.navigateTo({
url:`/order/confirmOrder?goods=${ JSON.stringify(confirm) }`
})
},
async fav(){
let { id } = this.goods;
if( this.goods.isFav == 0 ){
console.log('添加收藏');
let res = await collectAdd(id);
if( res.code !='200' ) return;
this.$refs.uToast.show({
type:"success",
message:"收藏成功"
})
this.goods.isFav = 1;
return ;
}
if( this.goods.isFav == 1 ){
console.log( '删除收藏' )
let res = await collectDelete(id);
if( res.code !='200' ) return;
this.$refs.uToast.show({
type:"success",
message:"取消收藏"
})
this.goods.isFav = 0;
return ;
}
}
}
}
</script>
<style>
.content image{
width:100%;
}
.goods{
display: flex;
position: absolute;
bottom:64rpx;
left:50%;
z-index: 666;
transform: translateX(-50%);
}
.goods-cart{
display: flex;
align-items: center;
justify-content: center;
width: 94rpx;
height: 94rpx;
background: rgba(0,0,0,.7);
border-radius: 50%;
}
.goods-cart image{
width: 43rpx;
height: 35rpx;
}
.goods-title{
display: flex;
align-items: center;
justify-content: center;
width: 562rpx;
margin-left: 9rpx;
background: rgba(0,0,0,.7);
border-radius: 36px;
color:#fff;
}
.goods-title view{
padding: 0 20rpx;
font-size:24rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.goods-main{
padding:17rpx;
}
.goods-img{
display: flex;
align-items: center;
}
.goods-img image{
width: 115rpx;
height: 116rpx;
background: #FFFFFF;
border-radius: 7rpx;
border: 1px solid #707070;
}
.goods-img view{
margin-left:19rpx;
}
.goods-sku{
margin:16rpx 0;
}
.sku-item{
display: flex;
}
.sku-item > view{
padding:10rpx 20rpx;
background: #F7F7F7;
border-radius: 7px;
color:#000;
}
.sku-item view + view{
margin-left:30rpx;
}
.goods-number{
display: flex;
justify-content: space-between;
margin-top: 100rpx;
}
.goods-order{
display: flex;
align-items: center;
justify-content: center;
margin-top: 300rpx;
}
.goods-order button{
width: 490rpx;
height: 85rpx;
background: linear-gradient(128deg, #525252 0%, #000000 100%);
border-radius: 43rpx;
color:#fff;
}
.skus-active{
border:1px solid blue;
}
.share{
border: none!important;
border-radius: 0!important;
background-color: #f8f8f8;
color: #000;
display: inline-block;
margin-left: auto;
margin-right: auto;
padding:0rpx;
}
.fav-active{
color:red;
}
</style>