1012 lines
28 KiB
Vue
1012 lines
28 KiB
Vue
<template>
|
||
<view class="pages-store">
|
||
<fixed :zIndex="99">
|
||
<view class="shop-store-info b-1px-b" v-if="storeInfo.id">
|
||
<uni-nav-bar :fixed="false" :shadow="false" :statusBar="true" color="#fff" backgroundColor="none"
|
||
leftIcon="icon-left" title="店铺">
|
||
</uni-nav-bar>
|
||
<image mode="aspectFill" lazy-load class="common-bg abs"
|
||
:style="{height: `${configInfo.navBarHeight + 104}px`}" src="https://lbqny.migugu.com/admin/farm/bg-cash.png">
|
||
</image>
|
||
<view class="common-top-img"></view>
|
||
<view class="store-info rel fill-base">
|
||
<view class="info-box abs">
|
||
<view @tap.stop="$util.goUrl({url:`/shop/pages/choose-store`})"
|
||
class="farm-item rel fill-base ml-md mr-md pd-lg box-shadow radius-24">
|
||
<view class="more-btn abs flex-center">
|
||
<view class="flex-y-baseline" :style="{color:primaryColor}">
|
||
<view>切换店铺</view>
|
||
<i class="iconfont icon-qiehuan"></i>
|
||
</view>
|
||
</view>
|
||
<view class="flex-warp">
|
||
<image mode="aspectFill" lazy-load class="cover box-shadow radius-24"
|
||
:src="storeInfo.cover">
|
||
</image>
|
||
<view class="flex-1 ml-lg">
|
||
<view class="max-title f-title c-title mt-sm mb-sm ellipsis">
|
||
{{storeInfo.title}}
|
||
</view>
|
||
<view class="store-desc f-caption c-caption ellipsis-2">
|
||
<text decode="emsp" style="word-break:break-all;">{{storeInfo.desc}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="pd-md">
|
||
<search @input="toSearch" type="input" textAlign="left" placeholder="搜索商品名称" :padding="0"
|
||
:radius="35">
|
||
</search>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</fixed>
|
||
<scroll-view scroll-y="true" :scroll-into-view="changeCate" :scroll-with-animation="true" class="cate-list fix"
|
||
:style="{top:`${shopHeight}px`}" v-if="cateList.length > 0">
|
||
<block v-for="(item,index) in cateList" :key="index">
|
||
<view @tap.stop="tabChange($event,index)" data-key="changeCate" data-type="cate" :data-id="item.id"
|
||
:id="['changeCate' + index]" class="cate-item flex-center f-desc text-center"
|
||
:class="[{'cur': cateInd == index},{'c-desc':cateInd!=index}]"
|
||
:style="{color:cateInd==index?primaryColor:''}">
|
||
{{item.title}}
|
||
</view>
|
||
</block>
|
||
<view class="space-pay pt-md pb-md" v-if="shopCarList.car_count > 0">
|
||
<view class="pay-item"></view>
|
||
</view>
|
||
</scroll-view>
|
||
<view :style="{height:`${shopHeight}px`}" v-if="storeInfo.id"></view>
|
||
<view class="goods-list rel" :style="{minHeight:`${shopHeight}px`}" v-if="cateList.length > 0">
|
||
<view @tap.stop="getGoodsSpec(index)" class="item-child flex-center ml-md mr-lg pt-lg pb-lg"
|
||
:class="[{'b-1px-t':index!=0}]" v-for="(item,index) in list.data" :key="index">
|
||
<view @tap.stop="goDetail(index)" class="rel">
|
||
<image mode="aspectFill" lazy-load class="goods-img radius-16" :src="item.cover"></image>
|
||
<view class="sell-out-info flex-center abs radius-16" v-if="item.all_stock < 1">
|
||
<image mode="aspectFill" lazy-load class="sell-out-img"
|
||
:src="`/static/image/shop/sell_out.png`"></image>
|
||
</view>
|
||
</view>
|
||
<view class="flex-1 ml-md">
|
||
<view class="goods-max f-title c-title text-bold ellipsis">{{item.goods_name}}</view>
|
||
<view class="goods-max f-caption c-caption ellipsis" style="height: 36rpx;">库存:{{item.all_stock}}
|
||
</view>
|
||
<view class="flex-between mt-sm">
|
||
<view class="f-caption c-caption">
|
||
<view class="flex-y-baseline c-warning">¥<view class="f-title text-bold">
|
||
{{item.show_price}}
|
||
</view>
|
||
<view class="f-caption c-caption text-delete ml-sm">¥{{item.show_init_price}}</view>
|
||
</view>
|
||
</view>
|
||
<view class="add-remove-item" v-if="item.all_stock>0">
|
||
<i class="iconfont icon-add-circle" :style="{color:primaryColor}"></i>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<block v-if="cateList.length > 0">
|
||
<load-more :noMore="list.current_page>=list.last_page&&list.data.length>0" :loading="loading"
|
||
v-if="loading">
|
||
</load-more>
|
||
<abnor v-if="!loading&&list.data.length<=0&&list.current_page==1"></abnor>
|
||
</block>
|
||
</view>
|
||
<block v-if="shopCarList.car_count > 0">
|
||
<view class="space-pay pt-md pb-md">
|
||
<view class="pay-item"></view>
|
||
</view>
|
||
<view class="store-pay-info pt-md pb-md fill-base fix">
|
||
<view @tap.stop="$refs.show_car_item.open()" class="flex-between pay-info ml-lg mr-lg fill-base">
|
||
<view class="car-img-info rel pr-md">
|
||
<image mode="aspectFill" lazy-load class="car-img abs" :src="`/static/image/shop/cart.png`">
|
||
</image>
|
||
<view class="car-num flex-center fill-warning c-base f-icontext abs"
|
||
:style="{width: shopCarList.car_count<10 ? '30rpx' : '50rpx'}">{{shopCarList.car_count}}
|
||
</view>
|
||
</view>
|
||
<view class="flex-y-baseline flex-1 ml-sm f-paragraph c-title" style="line-height: 35rpx;">
|
||
合计:
|
||
<view class="f-title c-warning text-bold">
|
||
¥{{shopCarList.car_price}}
|
||
</view>
|
||
</view>
|
||
<view @tap.stop="goOrder" class="store-pay-btn flex-center f-title c-base"
|
||
:style="{background:primaryColor,opacity: shopCarList.car_price*1 < storeInfo.min_price*1-0.01 ? 0.5 : 1}">
|
||
去结算</view>
|
||
</view>
|
||
<view class="space-safe"></view>
|
||
</view>
|
||
</block>
|
||
|
||
|
||
<abnor v-if="!loading&&list.data.length<=0&&list.current_page==1&&cateList.length == 0">
|
||
</abnor>
|
||
|
||
<!-- 选择规格 -->
|
||
<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.id || currentSpecs.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" style="height: 130rpx;">
|
||
<view class="f-desc c-title">购买数量</view>
|
||
<view class="add-remove-item flex-center" v-if="carIsHave.isHave">
|
||
<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 || 0}}</view>
|
||
<i @tap.stop="changeNum(1)" class="iconfont icon-add-circle" :style="{color:primaryColor}"></i>
|
||
</view>
|
||
<view @tap="toAddCar" class="add-car-btn flex-y-center c-base pl-lg pr-lg radius-16"
|
||
:style="{background:primaryColor}" v-else><i class="iconfont icon-tianjia mr-sm"></i> 加入购物车
|
||
</view>
|
||
</view>
|
||
<view class="space-safe"></view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
<!-- 购物车 -->
|
||
<uni-popup ref="show_car_item" type="bottom">
|
||
<view class="popup-show-car fill-base">
|
||
<view class="flex-between b-1px-b pd-lg">
|
||
<view></view>
|
||
<view @tap.stop="toDelCar" class="flex-y-baseline f-paragraph c-caption"><i
|
||
class="iconfont icon-del mr-sm"></i>清空购物车</view>
|
||
</view>
|
||
<scroll-view scroll-y @touchmove.stop.prevent class="car-info">
|
||
<view class="item-child mb-md ml-sm mr-sm pt-lg pl-lg pr-lg fill-base radius-24"
|
||
:class="[{'mt-md':index==0}]" v-for="(item,index) in shopCarList.list" :key="index">
|
||
<view class="flex-y-center mb-lg">
|
||
<i class="iconfont icon-dianpu mr-sm"></i>
|
||
<view class="f-title c-title text-bold ellipsis">{{item.farmer_info.title}}</view>
|
||
<!-- <i class="iconfont icon-right"></i> -->
|
||
</view>
|
||
<view @tap.stop="toUpdateStatus(index,aindex)" class="flex-warp pb-lg b-1px-b"
|
||
:class="[{'pt-lg':aindex!=0}]" v-for="(aitem,aindex) in item.goods_list" :key="aindex">
|
||
<i class="iconfont flex-y-center mr-md"
|
||
:class="[{'icon-xuanze':!aitem.status},{'icon-xuanze-fill':aitem.status}]"
|
||
:style="{color:aitem.status?primaryColor:''}"></i>
|
||
<image mode="aspectFill" lazy-load class="goods-img radius-16" :src="aitem.cover">
|
||
</image>
|
||
<view class="flex-1 ml-md">
|
||
<view class="goods-title f-title c-title text-bold ellipsis">
|
||
{{aitem.goods_name}}
|
||
</view>
|
||
<view class="flex-between mt-sm">
|
||
<view class="goods-spe pl-sm pr-sm f-caption c-paragraph ellipsis radius-4">
|
||
{{aitem.spe_name}}
|
||
</view>
|
||
<view class="flex-1"></view>
|
||
</view>
|
||
<view class="f-desc c-warning mt-sm" v-if="aitem.integral_id">
|
||
{{aitem.i_price*1>0?`${aitem.integral}积分+${aitem.i_price}元`:`${aitem.integral}积分`}}
|
||
</view>
|
||
<view class="flex-between" :class="[{'mt-md':!aitem.integral_id}]">
|
||
<view class="flex-y-baseline f-caption c-warning">
|
||
<view class="f-caption c-caption mr-sm" v-if="aitem.integral_id">商城价</view>
|
||
¥<view class="f-title text-bold"> {{aitem.price}} </view>
|
||
</view>
|
||
<view class="flex-warp">
|
||
<view class="add-remove-item flex-center">
|
||
<i @tap.stop="toUpdateCar(aitem.farmer_id,aitem.id,aitem.spe_id,-1)"
|
||
class="iconfont icon-remove-circle c-caption"></i>
|
||
<view class="number flex-center f-desc pl-sm pr-sm">{{aitem.goods_num}}
|
||
</view>
|
||
<i @tap.stop="toUpdateCar(aitem.farmer_id,aitem.goods_id,aitem.spe_id,1)"
|
||
class="iconfont icon-add-circle" :style="{color:primaryColor}"></i>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
<view @tap.stop="goOrder" class="store-pay-info pt-md pb-md fill-base">
|
||
<view class="flex-between pay-info ml-lg mr-lg fill-base">
|
||
<view class="car-img-info rel pr-md">
|
||
<image mode="aspectFill" lazy-load class="car-img abs" :src="`/static/image/shop/cart.png`">
|
||
</image>
|
||
<view class="car-num flex-center fill-warning c-base f-icontext abs"
|
||
:style="{width: shopCarList.car_count<10 ? '30rpx' : '50rpx'}">{{shopCarList.car_count}}
|
||
</view>
|
||
</view>
|
||
<view class="flex-y-baseline flex-1 ml-sm f-paragraph c-title" style="line-height: 35rpx;">
|
||
合计:
|
||
<view class="f-title c-warning text-bold">
|
||
¥{{shopCarList.car_price}}
|
||
</view>
|
||
</view>
|
||
<view class="store-pay-btn flex-center f-title c-base"
|
||
:style="{background:primaryColor,opacity: shopCarList.car_price*1 < storeInfo.min_price*1-0.01 ? 0.5 : 1}">
|
||
去结算</view>
|
||
</view>
|
||
<view class="space-safe"></view>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
mapState,
|
||
mapActions,
|
||
mapMutations
|
||
} from "vuex"
|
||
export default {
|
||
components: {},
|
||
data() {
|
||
return {
|
||
options: {},
|
||
storeInfo: {},
|
||
cateList: [],
|
||
cateInd: 0,
|
||
cateId: 0,
|
||
changeCate: 'changeCate0',
|
||
shopHeight: 0,
|
||
param: {
|
||
page: 1,
|
||
cate_id: 0
|
||
},
|
||
list: {
|
||
data: []
|
||
},
|
||
loading: true,
|
||
current: 0,
|
||
goodsInd: 0,
|
||
detail: {},
|
||
speImg: '',
|
||
shopItemInfo: {}, //存放要和选中的值进行匹配的数据
|
||
selectArr: [], //存放被选中的值
|
||
subIndex: [], //是否选中 因为不确定是多规格还是但规格,所以这里定义数组来判断
|
||
currentSpecs: {}, //存放最后选中的商品
|
||
currentNum: 1, //选中数量
|
||
totalPrice: 0,
|
||
carIsHave: {
|
||
id: 0,
|
||
isHave: false,
|
||
},
|
||
lockTap: false
|
||
}
|
||
},
|
||
computed: mapState({
|
||
primaryColor: state => state.config.configInfo.primaryColor,
|
||
subColor: state => state.config.configInfo.subColor,
|
||
configInfo: state => state.config.configInfo,
|
||
userInfo: state => state.user.userInfo,
|
||
shopCarList: state => state.order.shopCarList,
|
||
}),
|
||
async onLoad(options) {
|
||
this.$util.showLoading()
|
||
this.options = options
|
||
await this.initIndex()
|
||
},
|
||
onPullDownRefresh() {
|
||
// #ifndef APP-PLUS
|
||
uni.showNavigationBarLoading()
|
||
// #endif
|
||
this.initRefresh()
|
||
uni.stopPullDownRefresh()
|
||
},
|
||
onReachBottom() {
|
||
if (this.list.current_page >= this.list.last_page || this.loading) return
|
||
this.param.page = this.param.page + 1
|
||
this.loading = true
|
||
this.getList()
|
||
},
|
||
methods: {
|
||
...mapActions(['getConfigInfo', 'updateCommonOptions', 'getShopCarList']),
|
||
...mapMutations(['updateUserItem']),
|
||
async initIndex() {
|
||
this.$refs.show_spe_item.close()
|
||
this.$refs.show_car_item.close()
|
||
await Promise.all([this.getCateList(), this.getShopCarList()])
|
||
setTimeout(() => {
|
||
this.toSetResHeight()
|
||
}, 200)
|
||
},
|
||
initRefresh() {
|
||
this.param.page = 1
|
||
this.initIndex()
|
||
},
|
||
async getCateList() {
|
||
let {
|
||
id: store_id
|
||
} = this.options
|
||
let {
|
||
cate_id,
|
||
store_info
|
||
} = await this.$api.shop.goodsIndex({
|
||
store_id
|
||
})
|
||
this.storeInfo = store_info
|
||
this.cateList = cate_id
|
||
if (cate_id.length == 0) {
|
||
this.$util.hideAll()
|
||
this.loading = false
|
||
return
|
||
}
|
||
let {
|
||
cateId,
|
||
} = this
|
||
let cateInd = cate_id.findIndex(item => {
|
||
return item.id == cateId
|
||
})
|
||
cateInd = cateInd == -1 ? 0 : cateInd
|
||
this.cateInd = cateInd
|
||
this.cateId = cate_id[cateInd].id
|
||
this.getList()
|
||
},
|
||
toSearch(val) {
|
||
this.loading = true
|
||
this.param.page = 1
|
||
this.param.goods_name = val
|
||
this.getList()
|
||
},
|
||
async getList() {
|
||
let {
|
||
list: oldList,
|
||
cateId: cate_id,
|
||
} = this
|
||
let {
|
||
id: store_id
|
||
} = this.options
|
||
let param = Object.assign({}, this.param, {
|
||
store_id,
|
||
cate_id,
|
||
})
|
||
let newList = await this.$api.shop.goodsList(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()
|
||
},
|
||
async toSetResHeight() {
|
||
const query = uni.createSelectorQuery();
|
||
query.select('.shop-store-info').boundingClientRect(data => {
|
||
this.shopHeight = data.height
|
||
}).exec();
|
||
},
|
||
tabChange(e, index) {
|
||
let {
|
||
id,
|
||
type,
|
||
key
|
||
} = this.$util.getDataSet(e)
|
||
this[`${type}Ind`] = index
|
||
this[key] = `${key}${index}`
|
||
this[`${type}Id`] = id
|
||
if (type == 'cate') {
|
||
uni.pageScrollTo({
|
||
scrollTop: 0
|
||
})
|
||
this.cateId = id
|
||
}
|
||
this.param.page = 1
|
||
this.getList()
|
||
},
|
||
async getCarInfo(isCar = 2) {
|
||
await this.getShopCarList()
|
||
setTimeout(() => {
|
||
if (isCar == 1 && this.shopCarList.list.length < 1) {
|
||
this.$refs.show_car_item.close()
|
||
}
|
||
this.checkCarIsHave()
|
||
}, 500)
|
||
},
|
||
// 商品详情
|
||
async getGoodsSpec(index) {
|
||
this.current = 0
|
||
this.goodsInd = index
|
||
let {
|
||
id
|
||
} = this.list.data[index]
|
||
let data = await this.$api.shop.goodsInfo({
|
||
id
|
||
});
|
||
data.spe_price.map(item => {
|
||
item.is_show = true
|
||
})
|
||
data.spe_text.map(item => {
|
||
if (item.cate.length < 1) return
|
||
this.selectArr.push('');
|
||
this.subIndex.push(-1);
|
||
});
|
||
this.detail = data
|
||
this.speImg = ''
|
||
this.shopItemInfo = {}
|
||
this.selectArr = []
|
||
this.subIndex = []
|
||
this.currentSpecs = {}
|
||
this.checkItem(); //计算sku里面规格形成路径
|
||
this.checkInpath(-1); //传-1是为了不跳过循环
|
||
|
||
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()
|
||
await this.checkCarIsHave()
|
||
this.$refs.show_spe_item.open()
|
||
},
|
||
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()
|
||
},
|
||
//循环所有属性判断哪些属性可选(当前选中的兄弟节点和已选中属性不需要循环 )
|
||
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
|
||
await this.checkCarIsHave()
|
||
},
|
||
async checkCarIsHave() {
|
||
let isHave = false
|
||
let {
|
||
id = 0,
|
||
goods_id = 0,
|
||
cart_id = 0
|
||
} = this.currentSpecs
|
||
let {
|
||
id: store_id
|
||
} = this.options
|
||
let {
|
||
currentNum = 0
|
||
} = this
|
||
this.shopCarList.list.map(item => {
|
||
if (item.farmer_id == store_id) {
|
||
item.goods_list.map(aitem => {
|
||
if (aitem.goods_id == goods_id && aitem.spe_id == id) {
|
||
isHave = true
|
||
currentNum = aitem.goods_num
|
||
cart_id = aitem.id
|
||
}
|
||
})
|
||
}
|
||
})
|
||
let carIsHave = {
|
||
id: cart_id,
|
||
isHave,
|
||
}
|
||
console.log(carIsHave, "========carIsHave")
|
||
this.$set(this, 'carIsHave', carIsHave)
|
||
this.$set(this, 'currentNum', currentNum)
|
||
},
|
||
// 加/减数量
|
||
async changeNum(mol) {
|
||
let {
|
||
id: spe_id,
|
||
stock
|
||
} = this.currentSpecs;
|
||
if (!spe_id) {
|
||
this.$util.showToast({
|
||
title: '请选择规格'
|
||
})
|
||
return
|
||
}
|
||
let {
|
||
id: goods_id,
|
||
store
|
||
} = this.detail
|
||
let store_id = store[0]
|
||
let id = mol > 0 ? goods_id : this.carIsHave.id
|
||
await this.toUpdateCar(store_id, id, spe_id, mol, 2)
|
||
},
|
||
// 添加购物车
|
||
async toAddCar() {
|
||
let {
|
||
id: goods_id,
|
||
store
|
||
} = this.detail
|
||
let store_id = store[0]
|
||
let {
|
||
id: spe_id
|
||
} = this.currentSpecs
|
||
await this.toUpdateCar(store_id, goods_id, spe_id, 1, 2)
|
||
},
|
||
// 修改购物车数量
|
||
// id 增加数量时传商品goods_id
|
||
async toUpdateCar(store_id, id, spe_id, goods_num, isCar = 1) {
|
||
let methodModel = goods_num > 0 ? 'addCar' : 'delCar'
|
||
let param = goods_num > 0 ? {
|
||
store_id,
|
||
goods_id: id,
|
||
spe_id,
|
||
goods_num,
|
||
} : {
|
||
id,
|
||
goods_num: 1
|
||
}
|
||
if (this.lockTap) return;
|
||
this.lockTap = true;
|
||
try {
|
||
await this.$api.shop[methodModel](param)
|
||
this.lockTap = false
|
||
await this.getCarInfo(isCar)
|
||
} catch (e) {
|
||
this.lockTap = false
|
||
}
|
||
},
|
||
// 修改购物车数据选择状态
|
||
async toUpdateStatus(index, aindex) {
|
||
let {
|
||
id,
|
||
status
|
||
} = this.shopCarList.list[index].goods_list[aindex]
|
||
let param = {
|
||
id: [id],
|
||
status: status == 1 ? 0 : 1
|
||
}
|
||
if (this.lockTap) return;
|
||
this.lockTap = true;
|
||
try {
|
||
await this.$api.shop.carUpdate(param)
|
||
this.lockTap = false
|
||
await this.getShopCarList()
|
||
} catch (e) {
|
||
this.lockTap = false
|
||
}
|
||
},
|
||
// 清空购物车
|
||
async toDelCar() {
|
||
await this.$api.shop.delSomeCar()
|
||
this.$util.showToast({
|
||
title: `清空成功`
|
||
})
|
||
this.$refs.show_car_item.close()
|
||
await this.getCarInfo()
|
||
},
|
||
// 商品详情
|
||
goDetail(index) {
|
||
let {
|
||
id
|
||
} = this.list.data[index]
|
||
let url = `/shop/pages/detail?id=${id}`
|
||
this.$util.goUrl({
|
||
url
|
||
})
|
||
},
|
||
// 去结算
|
||
goOrder() {
|
||
let {
|
||
car_count
|
||
} = this.shopCarList
|
||
if (car_count < 1) {
|
||
this.$util.showToast({
|
||
title: `请选择商品`
|
||
})
|
||
return
|
||
}
|
||
this.$refs.show_car_item.close()
|
||
this.$util.goUrl({
|
||
url: `/shop/pages/order`
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
|
||
<style lang="scss">
|
||
page {
|
||
background: #ffffff
|
||
}
|
||
|
||
.pages-store {
|
||
width: 100%;
|
||
height: 100vh;
|
||
|
||
.shop-store-info {
|
||
width: 100%;
|
||
top: 0;
|
||
left: 0;
|
||
z-index: 1;
|
||
|
||
.store-img {
|
||
height: 160rpx;
|
||
}
|
||
|
||
.store-info {
|
||
height: 186rpx;
|
||
|
||
.info-box {
|
||
top: -144rpx;
|
||
width: 100%;
|
||
|
||
.farm-item {
|
||
height: 220rpx;
|
||
|
||
.cover {
|
||
width: 160rpx;
|
||
height: 160rpx;
|
||
}
|
||
|
||
.icon-dingwei,
|
||
.icon-right {
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.max-title {
|
||
max-width: 460rpx;
|
||
}
|
||
|
||
.more-btn {
|
||
top: 0;
|
||
right: 0;
|
||
width: 122rpx;
|
||
height: 46rpx;
|
||
font-size: 20rpx;
|
||
background: rgba(112, 152, 64, 0.1);
|
||
border-radius: 0 25rpx 0 15rpx;
|
||
|
||
.iconfont {
|
||
font-size: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.cate-list {
|
||
width: 164rpx;
|
||
z-index: 1;
|
||
overflow-y: auto;
|
||
bottom: 0;
|
||
background: #F5F5F5;
|
||
|
||
.cate-item {
|
||
line-height: 1.3;
|
||
padding: 30rpx 10rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.cur {
|
||
background: #fff
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
.goods-list {
|
||
width: 586rpx;
|
||
margin-left: 164rpx;
|
||
z-index: 2;
|
||
overflow: hidden;
|
||
|
||
.goods-cate-scroll {
|
||
white-space: nowrap;
|
||
width: 586rpx;
|
||
height: 80rpx;
|
||
left: 164rpx;
|
||
right: 0rpx;
|
||
z-index: 3;
|
||
|
||
.item-child {
|
||
padding: 0 30rpx;
|
||
height: 80rpx;
|
||
line-height: 80rpx;
|
||
display: inline-block;
|
||
}
|
||
|
||
.purchase-item {
|
||
width: 40rpx;
|
||
height: 4rpx;
|
||
bottom: 0;
|
||
left: 50%;
|
||
margin-left: -20rpx;
|
||
}
|
||
}
|
||
|
||
.item-child {
|
||
.goods-img {
|
||
width: 130rpx;
|
||
height: 130rpx;
|
||
border: 1px solid rgba(238, 238, 238, 0.79);
|
||
}
|
||
|
||
.goods-max {
|
||
max-width: 332rpx;
|
||
}
|
||
|
||
.sell-out-info {
|
||
top: 1rpx;
|
||
left: 1rpx;
|
||
width: 130rpx;
|
||
height: 130rpx;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
|
||
.sell-out-img {
|
||
width: 84rpx;
|
||
height: 23rpx;
|
||
margin: 0 auto;
|
||
}
|
||
}
|
||
|
||
.express-self-btn {
|
||
width: 110rpx;
|
||
height: 36rpx;
|
||
font-size: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
.add-car-btn {
|
||
height: 70rpx;
|
||
font-size: 30rpx;
|
||
}
|
||
|
||
|
||
.space-pay {
|
||
.pay-item {
|
||
height: 94rpx;
|
||
margin-bottom: calc(5px + env(safe-area-inset-bottom) / 2);
|
||
}
|
||
}
|
||
|
||
.store-pay-info {
|
||
bottom: 0rpx;
|
||
z-index: 8;
|
||
|
||
.pay-info {
|
||
width: 686rpx;
|
||
height: 94rpx;
|
||
border-radius: 47rpx;
|
||
background: #fff;
|
||
box-shadow: 0px 4px 26px -10px rgba(0, 0, 0, 0.23);
|
||
|
||
.car-img-info {
|
||
width: 108rpx;
|
||
height: 94rpx;
|
||
|
||
.car-img {
|
||
width: 108rpx;
|
||
height: 108rpx;
|
||
left: 0;
|
||
bottom: 0;
|
||
}
|
||
|
||
.car-num {
|
||
width: 30rpx;
|
||
height: 30rpx;
|
||
line-height: 30rpx;
|
||
border-radius: 15rpx;
|
||
right: 10rpx;
|
||
top: -18rpx;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
.store-pay-btn {
|
||
width: 210rpx;
|
||
height: 94rpx;
|
||
border-radius: 0 47rpx 47rpx 0;
|
||
}
|
||
}
|
||
|
||
|
||
.popup-choose-spe {
|
||
width: 100%;
|
||
|
||
.icon-close {
|
||
font-size: 50rpx;
|
||
top: 32rpx;
|
||
right: 32rpx;
|
||
}
|
||
|
||
.cover {
|
||
width: 130rpx;
|
||
height: 130rpx;
|
||
}
|
||
|
||
.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;
|
||
|
||
.spe-img {
|
||
width: 42rpx;
|
||
height: 42rpx;
|
||
}
|
||
}
|
||
|
||
.spe-item.cur {
|
||
background: #EFEFFF;
|
||
border: 1rpx solid #393A81;
|
||
}
|
||
}
|
||
|
||
.confirm-btn {
|
||
width: 500rpx;
|
||
height: 88rpx;
|
||
}
|
||
}
|
||
|
||
.popup-show-car {
|
||
border-radius: 15rpx 15rpx 0 0;
|
||
z-index: 8;
|
||
|
||
.car-info {
|
||
max-height: 65vh;
|
||
background: #EEEEEE;
|
||
|
||
.item-child {
|
||
|
||
.icon-xuanze,
|
||
.icon-xuanze-fill {
|
||
height: 172rpx;
|
||
}
|
||
|
||
.goods-img {
|
||
width: 172rpx;
|
||
height: 172rpx;
|
||
}
|
||
|
||
.goods-title {
|
||
max-width: 420rpx;
|
||
}
|
||
|
||
.goods-spe {
|
||
height: 44rpx;
|
||
line-height: 44rpx;
|
||
background: #F7F7F7;
|
||
max-width: 420rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.space-car {
|
||
height: 30rpx;
|
||
height: calc(30rpx + env(safe-area-inset-bottom) / 2);
|
||
padding-bottom: calc(5px + env(safe-area-inset-bottom) / 2);
|
||
}
|
||
}
|
||
}
|
||
</style>
|