895 lines
26 KiB
Vue
895 lines
26 KiB
Vue
<template>
|
||
<view class="shop-detail" v-if="detail.id">
|
||
<banner :list="detail.imgs" :margin="0" :autoplay="true" :borderRadius="0" :height="750"
|
||
:indicatorActiveColor="primaryColor" indicatorType="number"></banner>
|
||
|
||
<view class="seckill-info rel mb-md"
|
||
v-if="(currentSpecs.id && currentSpecs.kill_atv && currentSpecs.kill_atv.id) || (detail.kill_list && detail.kill_list.id)">
|
||
<image mode="aspectFill" class="seckill-img abs" src="/static/image/shop/seckill.png">
|
||
</image>
|
||
<view class="seckill-btn abs flex-center f-desc text-bold radius" :style="{color:primaryColor}"
|
||
v-if="currentSpecs.kill_atv.id ? currentSpecs.kill_atv.atv_status==1:detail.kill_list.atv_status==1">
|
||
即将开抢</view>
|
||
<view class="seckill-count abs" v-if="detail.kill_list.atv_status==2">
|
||
<min-countdown :type="3" :targetTime="detail.kill_list.end_time * 1000" :color="primaryColor"
|
||
textColor="#fff" className="sm" @callback="countEnd">
|
||
</min-countdown>
|
||
</view>
|
||
<view class="seckill-content flex-between f-icontext c-base abs">
|
||
<view>
|
||
<view class="flex-y-center">秒杀价<view class="flex-y-baseline ml-sm">¥<view class="f-lg-title">
|
||
{{currentSpecs.kill_atv.id ? currentSpecs.kill_atv.price : detail.kill_list.price}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view>即将恢复
|
||
¥{{currentSpecs.kill_atv.id ? currentSpecs.kill_atv.init_price : detail.kill_list.init_price}}
|
||
</view>
|
||
</view>
|
||
<view class="flex-center flex-column">
|
||
<view class="f-caption">
|
||
{{currentSpecs.kill_atv.id ? currentSpecs.kill_atv.stock : detail.kill_list.stock}}
|
||
</view>
|
||
<view>仅剩(件)</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
|
||
<view class="pd-lg fill-base">
|
||
<view class="flex-center">
|
||
<view class="rel flex-1">
|
||
<view class="reduce-info abs flex-center pr-sm f-caption c-base" :style="{background:primaryColor}"
|
||
v-if="(currentSpecs.id && currentSpecs.kill_atv && currentSpecs.kill_atv.id) || (detail.kill_list && detail.kill_list.id)">
|
||
<view class="reduce-tag abs flex-center pr-sm f-icontext" :style="{color:primaryColor}">限时直降
|
||
</view>
|
||
¥{{currentSpecs.kill_atv.id ? currentSpecs.kill_atv.reduce_price : detail.kill_list.reduce_price}}
|
||
</view>
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<view class="max-600">
|
||
<!-- #endif -->
|
||
<!-- #ifndef MP-WEIXIN -->
|
||
<view>
|
||
<!-- #endif -->
|
||
<view class="f-sm-title c-title"
|
||
:style="{textIndent:(currentSpecs.id && currentSpecs.kill_atv&¤tSpecs.kill_atv.id) || (detail.kill_list && detail.kill_list.id) ? `${seckillWidth}px` : ''}">
|
||
{{detail.goods_name}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<button open-type="share" class="clear-btn flex-center flex-column">
|
||
<i class="iconfont icon-share c-title"></i>
|
||
<view class="f-caption c-title">分享</view>
|
||
</button>
|
||
<!-- #endif -->
|
||
</view>
|
||
<view class="flex-between f-caption c-caption mt-sm">
|
||
<view class="flex-y-baseline f-lg-title c-warning">
|
||
<block v-if="currentSpecs.id">
|
||
<view class="flex-y-baseline mt-sm" v-if="currentSpecs.integral_atv.id">
|
||
<view class="f-title c-warning">
|
||
{{currentSpecs.integral_atv.price*1>0?`${currentSpecs.integral_atv.integral}积分+${currentSpecs.integral_atv.price}元`:`${currentSpecs.integral_atv.integral}积分`}}
|
||
</view>
|
||
<view class="f-caption c-caption text-delete ml-sm">商城价 ¥{{currentSpecs.price}}
|
||
</view>
|
||
</view>
|
||
<block v-else>
|
||
¥{{currentSpecs.price}}
|
||
<view class="f-desc c-caption text-delete ml-sm">¥{{currentSpecs.original_price}}
|
||
</view>
|
||
</block>
|
||
</block>
|
||
<block v-else>¥{{detail.show_price}}
|
||
<view class="f-desc c-caption text-delete ml-sm">¥{{detail.show_init_price}}
|
||
</view>
|
||
</block>
|
||
</view>
|
||
<view>已销售:{{detail.sale_num}} </view>
|
||
</view>
|
||
</view>
|
||
|
||
<block v-if="list.all_count>0">
|
||
<view class="mt-md pt-sm pl-lg pr-lg fill-base f-paragraph c-title">
|
||
<view class="common-nav-title flex-center c-title">
|
||
<view class="common-line" :style="{background:primaryColor}"></view>
|
||
<view class="flex-1 flex-between">
|
||
<view class="f-title text-bold">评价({{list.all_count}})</view>
|
||
<view @tap.stop="$util.goUrl({url:`/mine/pages/evaluate/more?id=${options.id}&type=3`})"
|
||
class="flex-y-center f-paragraph c-caption">
|
||
<view>查看全部</view>
|
||
<i class="iconfont icon-right" style="font-size: 28rpx;"></i>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<block v-for="(item,index) in list.data" :key="index">
|
||
<view class="flex-warp fill-base pd-lg" :class="[{'b-1px-t':index!=0}]" v-if="index<2">
|
||
<image mode="aspectFill" lazy-load class="avatar sm radius" :src="item.user_info.avatarUrl">
|
||
</image>
|
||
<view class="flex-1 ml-lg">
|
||
<view class="flex-between">
|
||
<view class="f-paragraph c-title max-350 ellipsis">{{item.user_info.nickName}}</view>
|
||
<view class="f-icontext c-caption">{{item.create_time}}</view>
|
||
</view>
|
||
<view class="flex-warp">
|
||
<i class="iconfont icon-star-fill icon-font-color mr-sm"
|
||
:style="{backgroundImage: aindex < item.star ? '-webkit-linear-gradient(90deg, #FDCD47, #FFC000)' : '-webkit-linear-gradient(90deg, #eee, #eee)'}"
|
||
v-for="(aitem,aindex) in 5" :key="aindex"></i>
|
||
</view>
|
||
<view class="f-caption c-desc mt-md">
|
||
<text decode="emsp" style="word-break:break-all;">{{item.text || '该用户没有填写评价哦'}}</text>
|
||
</view>
|
||
<view class="flex-warp mt-md" v-if="item.imgs && item.imgs.length > 0">
|
||
<block v-for="(aitem,aindex) in item.imgs" :key="aindex">
|
||
<view class="eva-img sm radius-10 rel" v-if="aindex < 3">
|
||
<image @tap.stop="toPreviewImage(index,aindex)" mode="aspectFill"
|
||
class="eva-img sm radius-10" :src="aitem">
|
||
</image>
|
||
<view class="more f-caption c-base abs"
|
||
v-if="aindex == 2 && item.imgs.length > 3">
|
||
+{{item.imgs.length - 3}}</view>
|
||
</view>
|
||
</block>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
</block>
|
||
|
||
<view @tap="$util.goUrl({url:`/shop/pages/store?id=${detail.store_info.id}`})"
|
||
class="store-info flex-center mt-md pd-lg fill-base f-paragraph c-title">
|
||
<image mode="aspectFill" class="cover" :src="detail.store_info.cover"></image>
|
||
<view class="flex-1 flex-between ml-md">
|
||
<view>
|
||
<view class="flex-y-center mb-sm">
|
||
<view class="f-sm-title text-bold ellipsis"
|
||
:class="[{'max-300':detail.store_info.is_admin},{'max-400':!detail.store_info.is_admin}]">
|
||
{{detail.store_info.title}}
|
||
</view>
|
||
<view class="store-tag flex-center ml-sm f-icontext" v-if="detail.store_info.is_admin">平台直营
|
||
</view>
|
||
</view>
|
||
<view class="star-fill-info rel">
|
||
<view class="flex-warp star rel">
|
||
<view class="item-star flex-center" v-for="(aitem,aindex) in 5" :key="aindex">
|
||
<i class="iconfont icon-star-bold-fill"></i>
|
||
</view>
|
||
</view>
|
||
<view class="star-fill abs" :style="{width: detail.store_info.star_percent}">
|
||
<view class="flex-warp">
|
||
<view class="item-star flex-center" v-for="(aitem,aindex) in 5" :key="aindex">
|
||
<i class="iconfont icon-star-bold-fill icon-font-color"
|
||
:style="{backgroundImage: '-webkit-linear-gradient(90deg, #FDCD47, #FFC000)'}"></i>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="go-btn flex-center f-paragraph"
|
||
:style="{color:primaryColor,border:`1px solid ${primaryColor}`}">进店逛逛
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="mt-md pt-sm pl-lg pr-lg pb-lg fill-base f-paragraph c-title" v-if="detail.text">
|
||
<view class="common-nav-title flex-center c-title">
|
||
<view class="common-line" :style="{background:primaryColor}"></view>
|
||
<view class="f-title text-bold flex-1">商品详情</view>
|
||
</view>
|
||
<view class="pt-sm" v-if="detail.text">
|
||
<parser :html="detail.text" @linkpress="linkpress" show-with-animation lazy-load>加载中...</parser>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="space-max-footer"></view>
|
||
<view class="footer-btn fill-base fix">
|
||
<view class="footer-item flex-between pr-lg">
|
||
<view class="flex-warp f-caption c-title">
|
||
<view @tap.stop="$util.goUrl({url:`/pages/home`,openType:`switchTab`})"
|
||
class="flex-center flex-column pl-lg pr-lg">
|
||
<i class="iconfont icon-home"></i>
|
||
<view>首页</view>
|
||
</view>
|
||
<view @tap.stop="$util.goUrl({url:`/shop/pages/car`})"
|
||
class="flex-center flex-column pl-md rel">
|
||
<view v-if="shopCarList.car_count" class="car-count flex-center c-base f-icontext abs"
|
||
:style="{width: shopCarList.car_count<10 ? '30rpx' : '50rpx'}">
|
||
{{shopCarList.car_count < 100 ? shopCarList.car_count : '99+'}}
|
||
</view>
|
||
<i class="iconfont icon-gouwuche"></i>
|
||
<view>购物车</view>
|
||
</view>
|
||
</view>
|
||
<view class="flex-warp">
|
||
<block v-if="detail.kill_list && detail.kill_list.id"></block>
|
||
<view @tap.stop="toAddOrder(1)" class="order-btn flex-center f-title c-base text-bold radius"
|
||
:style="{color:primaryColor,border:`1rpx solid ${primaryColor}`}" v-else>
|
||
加入购物车
|
||
</view>
|
||
<view
|
||
@tap.stop="toAddOrder(detail.kill_list && detail.kill_list.id && detail.kill_list.atv_status == 2 ? 3 : currentSpecs.id && currentSpecs.integral_atv&¤tSpecs.integral_atv.id ? 4 :2)"
|
||
class="order-btn flex-center ml-md f-title c-base text-bold radius"
|
||
:style="{background:primaryColor,border:`1rpx solid ${primaryColor}`}">
|
||
<block v-if="detail.kill_list&&detail.kill_list.id&& detail.kill_list.atv_status == 2">立即抢购
|
||
</block>
|
||
<block
|
||
v-else-if="currentSpecs.id && currentSpecs.integral_atv&¤tSpecs.integral_atv.id">
|
||
积分兑换</block>
|
||
<block v-else>立即购买</block>
|
||
|
||
<!-- {{detail.kill_list&&detail.kill_list.id&& detail.kill_list.atv_status == 2?'立即抢购':currentSpecs.id && currentSpecs.integral_atv&¤tSpecs.integral_atv.id?'积分兑换':'立即购买'}} -->
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="space-safe"></view>
|
||
</view>
|
||
|
||
<uni-popup ref="show_spe_item" type="bottom">
|
||
<view @touchmove.stop.prevent class="popup-choose-spe f-paragraph c-desc fill-base radius-top-34">
|
||
<i @tap.stop="$refs.show_spe_item.close()" class="iconfont icon-close c-title abs"></i>
|
||
<view class="space-lg"></view>
|
||
<view class="flex-center pd-lg">
|
||
<image mode="aspectFill" class="avatar radius-16" :src="speImg || detail.cover"></image>
|
||
<view class="flex-1 ml-lg f-desc c-warning">
|
||
<view :class="[{'flex-y-baseline':currentSpecs.integral_atv.price*1==0}]"
|
||
v-if="currentSpecs.id && (currentSpecs.kill_atv&¤tSpecs.kill_atv.id || currentSpecs.integral_atv&¤tSpecs.integral_atv.id)">
|
||
<view class="flex-y-center c-warning" v-if="currentSpecs.kill_atv.id">
|
||
秒杀价<view class="flex-y-baseline ml-sm">¥<view class="f-lg-title">
|
||
{{currentSpecs.kill_atv.price}}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="f-title c-warning" v-else>
|
||
{{currentSpecs.integral_atv.price*1>0?`${currentSpecs.integral_atv.integral}积分+${currentSpecs.integral_atv.price}元`:`${currentSpecs.integral_atv.integral}积分`}}
|
||
</view>
|
||
<view class="f-caption c-caption"
|
||
:class="[{'ml-sm text-delete':currentSpecs.integral_atv.price*1==0}]">
|
||
商城价 ¥{{currentSpecs.price}}
|
||
</view>
|
||
</view>
|
||
<view class="flex-y-baseline" v-else>
|
||
¥<view class="f-lg-title">{{currentSpecs.id ?currentSpecs.price:detail.show_price}}
|
||
</view>
|
||
<view class="c-caption text-delete ml-sm">
|
||
¥{{currentSpecs.id ?currentSpecs.original_price:detail.show_init_price}} </view>
|
||
</view>
|
||
<view class="f-caption c-title mt-sm">库存:{{currentSpecs.id ? currentSpecs.stock : 0}}</view>
|
||
</view>
|
||
</view>
|
||
<scroll-view scroll-y class="spe-list">
|
||
<view class="pd-lg" :class="[{'b-1px-t':index!=0}]" v-for="(item,index) in detail.spe_text"
|
||
:key="index">
|
||
<view class="f-desc c-title text-bold">{{item.title}}</view>
|
||
<view class="flex-warp">
|
||
<view @tap.stop="skuClick(aitem, index, aindex)"
|
||
class="spe-item flex-center f-icontext c-title mt-md mb-sm mr-lg"
|
||
:style="{borderColor:!aitem.is_show ? '#999' : subIndex[index] == aindex?primaryColor:'',background:!aitem.is_show ? '#999' : subIndex[index] == aindex?'#EFEFFF':'',color:!aitem.is_show ? '#fff' :subIndex[index] == aindex?primaryColor:''}"
|
||
v-for="(aitem,aindex) in item.cate" :key="aindex">
|
||
<image mode="aspectFill" class="spe-img mr-sm radius-4" :src="aitem.image"
|
||
v-if="aitem.is_img === 1 && aitem.image"></image>
|
||
<view style="max-width: 510rpx;">{{aitem.title}}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
<view class="flex-between pd-lg b-1px-t">
|
||
<view class="f-desc c-title">购买数量</view>
|
||
<view class="add-remove-item flex-center">
|
||
<block v-if="currentNum">
|
||
<i @tap.stop="changeNum(-1)" class="iconfont icon-remove-circle c-caption"></i>
|
||
<view class="number flex-center f-desc pl-sm pr-sm">{{currentNum}}</view>
|
||
</block>
|
||
<i @tap.stop="changeNum(1)" class="iconfont icon-add-circle"
|
||
:style="{color:primaryColor}"></i>
|
||
</view>
|
||
</view>
|
||
<view class="flex-center pd-lg">
|
||
<view @tap="toAddCar" class="confirm-btn flex-center f-sm-title c-base radius"
|
||
:style="{background:primaryColor}">
|
||
确定
|
||
</view>
|
||
</view>
|
||
<view class="space-safe"></view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
mapState,
|
||
mapActions
|
||
} from "vuex"
|
||
import parser from "@/components/jyf-Parser/index"
|
||
export default {
|
||
components: {
|
||
parser
|
||
},
|
||
data() {
|
||
return {
|
||
options: {},
|
||
detail: {},
|
||
speImg: '',
|
||
videoContexts: {},
|
||
shopItemInfo: {}, //存放要和选中的值进行匹配的数据
|
||
selectArr: [], //存放被选中的值
|
||
subIndex: [], //是否选中 因为不确定是多规格还是但规格,所以这里定义数组来判断
|
||
currentSpecs: {}, //存放最后选中的商品
|
||
currentNum: 1, //选中数量
|
||
totalPrice: 0,
|
||
seckillWidth: 119,
|
||
param: {
|
||
page: 1,
|
||
limit: 10
|
||
},
|
||
list: {
|
||
data: []
|
||
},
|
||
add_order_type: 1
|
||
}
|
||
},
|
||
computed: mapState({
|
||
primaryColor: state => state.config.configInfo.primaryColor,
|
||
subColor: state => state.config.configInfo.subColor,
|
||
userInfo: state => state.user.userInfo,
|
||
shopCarList: state => state.order.shopCarList
|
||
}),
|
||
onLoad(options) {
|
||
this.$util.showLoading()
|
||
this.options = options
|
||
this.initIndex()
|
||
},
|
||
onPullDownRefresh() {
|
||
// #ifndef APP-PLUS
|
||
uni.showNavigationBarLoading()
|
||
// #endif
|
||
this.initRefresh()
|
||
uni.stopPullDownRefresh()
|
||
},
|
||
onShareAppMessage(e) {
|
||
let {
|
||
id: pid
|
||
} = this.userInfo
|
||
let {
|
||
id,
|
||
goods_name: title,
|
||
cover: imageUrl
|
||
} = this.detail
|
||
let path = `/shop/pages/detail?pid=${pid}&id=${id}`
|
||
this.$util.log(path)
|
||
return {
|
||
title,
|
||
imageUrl,
|
||
path,
|
||
}
|
||
},
|
||
methods: {
|
||
...mapActions(['getConfigInfo', 'getShopCarList']),
|
||
async initIndex() {
|
||
await Promise.all([this.getDetail(), this.getList()])
|
||
},
|
||
initRefresh() {
|
||
this.initIndex()
|
||
},
|
||
countEnd() {
|
||
this.$util.log("倒计时完了")
|
||
setTimeout(() => {
|
||
this.initRefresh()
|
||
}, 1000)
|
||
},
|
||
linkpress(res) {
|
||
console.log("linkpress", res);
|
||
// #ifdef APP-PLUS
|
||
this.$util.goUrl({
|
||
url: res.href,
|
||
openType: 'web'
|
||
})
|
||
// #endif
|
||
},
|
||
async getDetail() {
|
||
let {
|
||
id
|
||
} = this.options
|
||
let data = await this.$api.shop.goodsInfo({
|
||
id
|
||
});
|
||
data.spe_price.map(item => {
|
||
item.is_show = true
|
||
if (item.kill_atv && item.kill_atv.id) {
|
||
let {
|
||
price,
|
||
init_price
|
||
} = item.kill_atv
|
||
item.kill_atv.reduce_price = init_price * 1 - price * 1
|
||
}
|
||
})
|
||
data.spe_text.map(item => {
|
||
if (item.cate.length < 1) return
|
||
this.selectArr.push('');
|
||
this.subIndex.push(-1);
|
||
});
|
||
if (data.kill_list && data.kill_list.id) {
|
||
let {
|
||
price,
|
||
init_price
|
||
} = data.kill_list
|
||
data.kill_list.reduce_price = init_price * 1 - price * 1
|
||
}
|
||
data.store_info.star_percent = (data.store_info.star * 1 / 5 * 100).toFixed(2) + '%'
|
||
this.detail = data
|
||
this.speImg = ''
|
||
this.shopItemInfo = {}
|
||
this.selectArr = []
|
||
this.subIndex = []
|
||
this.currentSpecs = {}
|
||
this.checkItem(); //计算sku里面规格形成路径
|
||
this.checkInpath(-1); //传-1是为了不跳过循环
|
||
setTimeout(() => {
|
||
this.toSetResHeight()
|
||
}, 100)
|
||
if (this.shopItemInfo.length < 1) return
|
||
let curr_spe = this.shopItemInfo[Object.keys(this.shopItemInfo)[0]]
|
||
if (!curr_spe) {
|
||
this.$util.hideAll()
|
||
return
|
||
}
|
||
this.currentSpecs = curr_spe
|
||
this.selectArr = curr_spe.spe_array_text
|
||
this.detail.spe_text.forEach((bitem, bindex) => {
|
||
if (bitem.cate.length < 1) return
|
||
bitem.cate.forEach((citem, cindex) => {
|
||
curr_spe.spe_array_text.forEach((ditem, dindex) => {
|
||
if (ditem == citem.id) {
|
||
if (citem.is_img == 1) {
|
||
this.speImg = citem.image
|
||
}
|
||
this.subIndex[dindex] = cindex
|
||
this.checkInpath(bindex)
|
||
}
|
||
})
|
||
})
|
||
})
|
||
this.$util.hideAll()
|
||
},
|
||
async toSetResHeight() {
|
||
let {
|
||
kill_list = {}
|
||
} = this.detail
|
||
let {
|
||
currentSpecs = {}
|
||
} = this
|
||
if ((currentSpecs && currentSpecs.id && currentSpecs.kill_atv && currentSpecs.kill_atv.id) || (
|
||
kill_list && kill_list.id)) {
|
||
this.seckillWidth = 119
|
||
const query = uni.createSelectorQuery();
|
||
query.select('.reduce-info').boundingClientRect(data => {
|
||
console.log(data, "=====data")
|
||
this.seckillWidth = data.width + 5
|
||
}).exec();
|
||
} else {
|
||
this.seckillWidth = 0
|
||
}
|
||
},
|
||
async getList() {
|
||
let {
|
||
list: oldList,
|
||
} = this
|
||
let {
|
||
id: goods_id,
|
||
} = this.options
|
||
let param = Object.assign({}, this.param, {
|
||
goods_id,
|
||
type: 3,
|
||
is_goods: 0
|
||
});
|
||
let newList = await this.$api.mine.goodsEvaluateList(param);
|
||
if (this.param.page == 1) {
|
||
this.list = newList
|
||
} else {
|
||
newList.data = oldList.data.concat(newList.data)
|
||
this.list = newList
|
||
}
|
||
this.loading = false
|
||
this.$util.hideAll()
|
||
},
|
||
playCurrent(current) {
|
||
let {
|
||
current: preCurrent
|
||
} = this
|
||
this.current = current
|
||
for (let key in this.videoContexts) {
|
||
if (key != current) {
|
||
this.videoContexts[key].pause()
|
||
this.text[key].is_play = false
|
||
} else if (current == preCurrent) {
|
||
let {
|
||
is_play
|
||
} = this.text[key]
|
||
if (is_play) {
|
||
this.videoContexts[key].pause()
|
||
} else {
|
||
this.videoContexts[key].play()
|
||
}
|
||
this.text[key].is_play = is_play ? false : true
|
||
} else {
|
||
this.videoContexts[key].play()
|
||
this.text[key].is_play = true
|
||
}
|
||
}
|
||
},
|
||
onPlay(e) {},
|
||
onPause(e) {},
|
||
onEnded(e) {
|
||
let {
|
||
index
|
||
} = this.$util.getDataSet(e)
|
||
this.detail.text[index].is_play = false
|
||
},
|
||
onError(e) {},
|
||
onTimeUpdate(e) {},
|
||
onWaiting(e) {},
|
||
onProgress(e) {},
|
||
onLoadedMetaData(e) {},
|
||
toPreviewImage(index, aindex) {
|
||
let {
|
||
imgs: urls
|
||
} = this.list.data[index]
|
||
this.$util.previewImage({
|
||
current: urls[aindex],
|
||
urls
|
||
})
|
||
},
|
||
skuClick(citem, index, cindex) {
|
||
if (!citem.is_show) return
|
||
let isCheck = this.selectArr[index] != citem.id
|
||
this.$set(this.selectArr, index, isCheck ? citem.id : '')
|
||
this.$set(this.subIndex, index, isCheck ? cindex : '-1')
|
||
if (citem.is_img == 1) {
|
||
this.speImg = isCheck ? citem.image : ''
|
||
}
|
||
this.checkInpath(index);
|
||
this.countBuy()
|
||
setTimeout(() => {
|
||
this.toSetResHeight()
|
||
}, 10)
|
||
},
|
||
//循环所有属性判断哪些属性可选(当前选中的兄弟节点和已选中属性不需要循环 )
|
||
checkInpath(clickIndex) {
|
||
for (let i = 0, len = this.detail.spe_text.length; i < len; i++) {
|
||
if (i == clickIndex) {
|
||
continue;
|
||
}
|
||
let len2 = this.detail.spe_text[i].cate.length;
|
||
for (let j = 0; j < len2; j++) {
|
||
if (this.subIndex[i] != -1 && j == this.subIndex[i]) {
|
||
continue;
|
||
}
|
||
let choosed_copy = [...this.selectArr];
|
||
this.$set(choosed_copy, i, this.detail.spe_text[i].cate[j].id);
|
||
let choosed_copy2 = choosed_copy.filter(item => item !== '' && typeof item !== 'undefined');
|
||
if (this.shopItemInfo.hasOwnProperty(choosed_copy2)) {
|
||
this.$set(this.detail.spe_text[i].cate[j], 'is_show', true);
|
||
} else {
|
||
this.$set(this.detail.spe_text[i].cate[j], 'is_show', false);
|
||
}
|
||
}
|
||
}
|
||
},
|
||
//计算可选路径
|
||
checkItem() {
|
||
let arrList = []
|
||
this.detail.spe_price.forEach(item => {
|
||
if (!item.is_show) return
|
||
if (item.stock < 1) return
|
||
arrList.push(item)
|
||
})
|
||
let result = arrList.reduce(
|
||
(arrs, items) => {
|
||
return arrs.concat(
|
||
items.spe_array_text.reduce(
|
||
(arr, item) => {
|
||
return arr.concat(
|
||
arr.map(item2 => {
|
||
//利用对象属性的唯一性实现二维数组去重
|
||
if (!this.shopItemInfo.hasOwnProperty([...item2, item])) {
|
||
this.shopItemInfo[[...item2, item]] = items;
|
||
}
|
||
return [...item2, item];
|
||
})
|
||
);
|
||
},
|
||
[
|
||
[]
|
||
]
|
||
)
|
||
);
|
||
},
|
||
[
|
||
[]
|
||
]
|
||
);
|
||
},
|
||
async countBuy() {
|
||
//如果全部选完
|
||
let isCheckAllSpec = this.selectArr.every(item => item != '')
|
||
this.currentSpecs = isCheckAllSpec ? this.shopItemInfo[this.selectArr] : {}
|
||
this.currentNum = 0
|
||
if (this.currentSpecs.stock >= 1) {
|
||
this.currentNum = 1
|
||
}
|
||
let {
|
||
id = 0, price
|
||
} = this.currentSpecs
|
||
this.totalPrice = id ? (price * this.currentNum).toFixed(2) : 0
|
||
},
|
||
toAddOrder(type) {
|
||
this.add_order_type = type
|
||
this.$refs.show_spe_item.open()
|
||
},
|
||
// 加减数量
|
||
async changeNum(mol) {
|
||
let spe_price_id = this.currentSpecs.id;
|
||
if (!spe_price_id) {
|
||
this.$util.showToast({
|
||
title: '请选择规格'
|
||
})
|
||
return
|
||
}
|
||
let num = (this.currentNum + mol) * 1;
|
||
if (num < 1) {
|
||
this.$util.showToast({
|
||
title: `此商品最少购买1件`
|
||
})
|
||
return;
|
||
}
|
||
let stock = this.currentSpecs.stock * 1
|
||
if (num > stock) {
|
||
this.$util.showToast({
|
||
title: "数量不能大于库存"
|
||
})
|
||
return;
|
||
}
|
||
|
||
this.currentNum = num;
|
||
let {
|
||
id = 0, price
|
||
} = this.currentSpecs
|
||
let total_wholesale_price = this.cur_wholesale.id ? this.cur_wholesale.total_price * 1 : 0
|
||
this.totalPrice = id ? (price * this.currentNum).toFixed(2) : 0
|
||
},
|
||
//加入购物车
|
||
async toAddCar() {
|
||
let {
|
||
add_order_type
|
||
} = this
|
||
let is_show = JSON.parse(JSON.stringify(add_order_type))
|
||
is_show = is_show === 1 ? 1 : 2
|
||
let {
|
||
id: goods_id,
|
||
store,
|
||
} = this.detail;
|
||
let store_id = store[0]
|
||
let {
|
||
id: spe_id,
|
||
integral_atv = {}
|
||
} = this.currentSpecs;
|
||
if (!spe_id) {
|
||
this.$util.showToast({
|
||
title: '请选择规格'
|
||
})
|
||
return
|
||
}
|
||
let {
|
||
currentNum: goods_num,
|
||
} = this
|
||
let {
|
||
stock
|
||
} = this.currentSpecs
|
||
if (goods_num < 1) {
|
||
this.$util.showToast({
|
||
title: `此商品最少购买1件`
|
||
})
|
||
return;
|
||
}
|
||
if (goods_num > stock * 1) {
|
||
this.$util.showToast({
|
||
title: `数量不能大于库存`
|
||
})
|
||
return;
|
||
}
|
||
this.$util.showLoading();
|
||
let param = {
|
||
store_id,
|
||
goods_id,
|
||
spe_id,
|
||
goods_num,
|
||
is_show
|
||
}
|
||
await this.$api.shop.addCar(param)
|
||
this.$util.hideAll()
|
||
if (is_show == 1) {
|
||
this.$util.showToast({
|
||
title: "加入成功"
|
||
})
|
||
await this.getShopCarList()
|
||
} else {
|
||
this.$refs.show_spe_item.close()
|
||
let url = `/shop/pages/order?is_show=2`
|
||
if (integral_atv.id && add_order_type === 4) {
|
||
url = `${url}&no_i=0`
|
||
}
|
||
this.$util.goUrl({
|
||
url
|
||
})
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
|
||
<style lang="scss">
|
||
.shop-detail {
|
||
.seckill-info {
|
||
width: 100%;
|
||
height: 143rpx;
|
||
|
||
.seckill-img {
|
||
left: 0;
|
||
bottom: 0;
|
||
width: 100%;
|
||
height: 156rpx;
|
||
}
|
||
|
||
.seckill-btn {
|
||
left: 58rpx;
|
||
bottom: 22rpx;
|
||
width: 152rpx;
|
||
height: 56rpx;
|
||
background: #FFFB00;
|
||
}
|
||
|
||
.seckill-count {
|
||
left: 38rpx;
|
||
bottom: 30rpx;
|
||
}
|
||
|
||
.seckill-content {
|
||
left: 298rpx;
|
||
top: 0;
|
||
width: 420rpx;
|
||
height: 140rpx;
|
||
padding: 20rpx;
|
||
}
|
||
}
|
||
|
||
.f-lg-title {
|
||
line-height: 1;
|
||
}
|
||
|
||
.icon-share {
|
||
font-size: 42rpx;
|
||
}
|
||
|
||
.count-list {
|
||
.count-item {
|
||
width: 249rpx;
|
||
|
||
.ellipsis {
|
||
max-width: 220rpx;
|
||
}
|
||
}
|
||
|
||
.line {
|
||
width: 1rpx;
|
||
height: 58rpx;
|
||
background: #CCCCCC;
|
||
opacity: 0.4;
|
||
}
|
||
|
||
}
|
||
|
||
.store-info {
|
||
.cover {
|
||
width: 98rpx;
|
||
height: 98rpx;
|
||
border-radius: 12rpx
|
||
}
|
||
|
||
.store-tag {
|
||
width: 96rpx;
|
||
height: 29rpx;
|
||
color: #39b54a;
|
||
background: rgba(0, 146, 84, 0.1);
|
||
border-radius: 2rpx;
|
||
}
|
||
|
||
.go-btn {
|
||
width: 139rpx;
|
||
height: 54rpx;
|
||
border-radius: 4rpx;
|
||
transform: rotateZ(360deg);
|
||
}
|
||
}
|
||
|
||
.goods-img {
|
||
width: 100%;
|
||
}
|
||
|
||
.goods-video {
|
||
width: 100%;
|
||
height: 450rpx;
|
||
}
|
||
|
||
.footer-btn {
|
||
bottom: 0;
|
||
|
||
.footer-item {
|
||
height: 114rpx;
|
||
|
||
.iconfont {
|
||
font-size: 36rpx;
|
||
}
|
||
|
||
.car-count {
|
||
width: 30rpx;
|
||
height: 30rpx;
|
||
line-height: 30rpx;
|
||
border-radius: 15rpx;
|
||
background: #f12c20;
|
||
top: -10rpx;
|
||
right: -10rpx;
|
||
}
|
||
}
|
||
|
||
.order-btn {
|
||
width: 220rpx;
|
||
height: 78rpx;
|
||
transform: rotateZ(360deg);
|
||
}
|
||
}
|
||
|
||
|
||
.popup-choose-spe {
|
||
width: 100%;
|
||
|
||
.icon-close {
|
||
font-size: 50rpx;
|
||
top: 32rpx;
|
||
right: 32rpx;
|
||
}
|
||
|
||
.spe-list {
|
||
max-height: 55vh;
|
||
overflow: auto;
|
||
|
||
.spe-item {
|
||
min-width: 98rpx;
|
||
min-height: 38rpx;
|
||
padding: 10rpx 15rpx;
|
||
background: #F6F6F6;
|
||
border-radius: 12rpx;
|
||
border: 1rpx solid #F6F6F6;
|
||
transform: rotateZ(360deg);
|
||
|
||
.spe-img {
|
||
width: 42rpx;
|
||
height: 42rpx;
|
||
}
|
||
}
|
||
|
||
.spe-item.cur {
|
||
background: #EFEFFF;
|
||
border: 1rpx solid #393A81;
|
||
}
|
||
}
|
||
|
||
.confirm-btn {
|
||
width: 500rpx;
|
||
height: 88rpx;
|
||
}
|
||
}
|
||
}
|
||
</style>
|