glhcp/uniapp/pages/shop_cart/shop_cart.vue

413 lines
16 KiB
Vue
Raw Blame History

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.

<template>
<view class="shop-cart">
<view class="main " :style="{'padding-bottom': (cartType == 1 ? '100rpx' : 0)}">
<view class="cart-list m-b-20" v-show="cartType==1">
<view class="cart-item bg-white" v-for="(items, index) in cartLists" :key="index">
<view class="flex select">
<u-checkbox :disabled="shopInvalid(items)" @change="changeSelect($event, 1, index)"
shape="circle" :value="items.is_selected == 1">
</u-checkbox>
<shop-title :shop="items.shop"></shop-title>
<view class="xs muted flex-none" v-if="items.shop.is_pay == 0">该店铺未开启支付功能</view>
</view>
<view>
<u-swipe-action :show="openCartId == item.cart_id" btn-width="150" v-for="item in items.cart"
:key="item.cart_id" :index="item.cart_id" @click="deleteOneCart($event, item.cart_id)"
:options="options" @open="openSwipe">
<view class="flex p-20">
<u-checkbox :disabled="cartInvalid(item)"
@change="changeSelect($event, 2, item.cart_id)" shape="circle"
:value="item.selected == 1">
</u-checkbox>
<router-link class="flex-1"
:to="{path: '/pages/goods_details/goods_details', query: {id: item.goods_id}}">
<view class="flex">
<view class="goods-img m-r-20">
<u-image width="180rpx" height="180rpx" border-radius="10rpx"
:src="item.image" />
<view v-if="item.goods_status == 0 || item.goods_del == 1" class="invalid sm white text-center">已失效
</view>
</view>
<view class="info flex-1">
<view class="line-2 nr">{{item.goods_name}}</view>
<view class="muted line-1 xs m-t-10">
{{item.spec_value_str}}
</view>
<view class="flex row-between m-t-20">
<view class="price flex primary">
<price-format :price="item.price" :first-size="32" :second-size="32"
:subscript-size="24" :weight="500">
</price-format>
</view>
<view class="cartNum" @tap.stop="">
<u-number-box :disabled="cartInvalid(item)" :value="item.goods_num"
:min="1" :max="item.stock"
@change="countChange($event, item.cart_id)" />
</view>
</view>
</view>
</view>
</router-link>
</view>
</u-swipe-action>
</view>
</view>
</view>
<view class="cart-null flex-col col-center row-center bg-white m-b-20" style="padding: 80rpx 0 50rpx"
v-show="cartType == 2">
<image class="img-null" src="/static/images/cart_null.png"></image>
<view class="muted m-b-20">购物车暂无任何商品~</view>
<router-link to="/pages/index/index" navType="pushTab">
<view class="primary br60 btn flex row-center">去逛逛</view>
</router-link>
</view>
<view v-if="!isLogin" class="login flex-col col-center row-center">
<image class="img-null" src="/static/images/cart_null.png"></image>
<view class="muted mt20">登录后才能查看购物车哦</view>
<router-link to="/pages/login/login">
<view class="white br60 flex row-center btn">
<image class="mr10" src="/static/images/icon_wechat.png"></image>
<text>去登录</text>
</view>
</router-link>
</view>
<goods-column v-if="showMoreGoods" ref="mescrollItem"></goods-column>
</view>
<view class="footer flex bg-white" v-show="cartType == 1">
<u-checkbox :disabled="allInvalid()" @change="changeSelect($event,3)" shape="circle" :value="isSelectedAll">
</u-checkbox>
<view class="primary" @tap="deleteSelectCart"></view>
<view class="all-price flex lg m-r-20 row-right">
<view>合计</view>
<view class="primary">{{totalPrice || 0}}</view>
</view>
<view class="right-btn br60 white" :style="' ' + (nullSelect ? 'background: #d7d7d7' : '')"
@tap="goToConfirm"></view>
</view>
<u-modal v-model="showDelTips" :show-cancel-button="true" comfirm-text="狠心删除"
:confirm-color="colorConfig.primary" :show-title="false" @confirm="deleteCart">
<view class="flex-col col-center tips-dialog" style="padding-top: 40rpx">
<image class="icon-lg" src="/static/images/icon_warning.png" />
<view style="margin:30rpx 0;">确认删除选中商品吗?</view>
</view>
</u-modal>
</view>
</template>
<script>
import {
getCartList,
changeCartSelect,
changeGoodsCount,
deleteGoods
} from '@/api/store';
import {
getUser
} from '@/api/user';
import {
mapGetters,
mapActions
} from 'vuex'
import Cache from '@/utils/cache'
import MescrollCompMixin from "@/components/mescroll-uni/mixins/mescroll-comp";
export default {
mixins: [MescrollCompMixin],
data() {
return {
//购物车状态 1为有 2为空 0则什么都不显示
cartType: 0,
showMoreGoods: false,
cartLists: [],
showDelTips: false,
totalPrice: '',
options: [{
text: '删除',
style: {
backgroundColor: '#FF2C3C'
}
}],
openCartId: 0
};
},
computed: {
...mapGetters(['cartNum', 'inviteCode']),
// 一个都没有选中
nullSelect() {
const {
cartLists
} = this
let nullS = true
cartLists.forEach((item) => {
item.cart.forEach(goods => {
if (goods.selected) nullS = false
})
})
return nullS
},
// 判断全选状态
isSelectedAll() {
const {
cartLists
} = this
if (!cartLists.length) return false
if (this.allInvalid()) return false
let index = cartLists.findIndex(item => item.is_selected == 0);
return index == -1 ? true : false
},
},
onLoad() {
},
onShow() {
this.getCartListFun();
},
methods: {
...mapActions(['getCartNum']),
// 删除购物车
deleteCart() {
this.showDelTips = false
deleteGoods({
cart_id: this.cartId
}).then(res => {
if (res.code == 1) {
this.getCartListFun();
}
});
},
openSwipe(index) {
this.openCartId = index
},
cartInvalid(item) {
return item.goods_status == 0 || item.goods_del == 1 || item.is_pay == 0 || item.has_item == 0 ? true : false
},
shopInvalid(item) {
return item.cart.every(citem => this.cartInvalid(citem))
},
allInvalid() {
return this.cartLists.every(item => this.shopInvalid(item))
},
// 删除选中购物车
deleteSelectCart() {
this.cartId = this.getSelectCart()
this.showDelTips = !this.showDelTips;
},
// 删除单个购物车
deleteOneCart(e, cartId) {
if (cartId) {
this.cartId = cartId;
}
this.showDelTips = !this.showDelTips;
},
async getCartListFun() {
const {
data: {
lists,
total_amount
},
code
} = await getCartList()
if (code == 1) {
let cartType = 0;
if (lists.length == 0) {
cartType = 2;
} else {
cartType = 1;
}
this.showMoreGoods = true
this.cartLists = lists;
this.cartType = cartType;
this.totalPrice = total_amount;
this.getCartNum()
} else {
this.cartType = 0
}
},
// 更改选中状态 type为1选中店铺/2选中商品/3全选
changeSelect({
value
}, type, number) {
let cartId = []
const {
cartLists
} = this
switch (type) {
case 1:
cartId = cartLists[number].cart.map(item => item.cart_id)
break;
case 2:
cartId.push(number)
break;
case 3:
cartId = cartLists.reduce((pre, item) => {
return pre.concat(item.cart.map(i => i.cart_id))
}, cartId)
break;
}
this.changeCartSelectFun(cartId, value);
},
changeCartSelectFun(cartId, selected) {
changeCartSelect({
cart_id: cartId,
selected: selected ? 1 : 0
}).then(res => {
if (res.code == 1) {
this.getCartListFun();
}
});
},
// 数量改变
countChange({
value
}, cartId) {
console.log(value)
let cartid = cartId;
changeGoodsCount({
cart_id: cartid,
goods_num: value
}).then(res => {
this.getCartListFun();
})
},
getSelectCart() {
const {
cartLists
} = this
return cartLists.reduce((pre, item) => {
return pre.concat(item.cart.filter(i => i.selected && !this.cartInvalid(i)).map(i => i
.cart_id))
}, [])
},
goToConfirm() {
let {
cartLists
} = this;
let goods = [];
let carts = this.getSelectCart()
if (carts.length == 0) return this.$toast({
title: '您还没有选择商品哦'
});
// 处理出商品数组数据
cartLists.forEach(item => {
if (item.cart.length != 0) {
item.cart.forEach((el, i) => {
// 选中的商品才能进入
if(el.selected == 1) {
goods.push({
item_id: el.item_id,
num: el.goods_num,
goods_id: el.goods_id,
shop_id: item.shop.shop_id
})
}
})
}
})
const params = {
carts: carts,
goods: goods,
type: 'cart'
};
this.$Router.push({
path: '/pages/confirm_order/confirm_order',
query: {
data: params
}
})
},
},
};
</script>
<style lang="scss">
.shop-cart {
.main {
padding-bottom: 100rpx;
}
.cart-list {
.cart-item {
margin: 20rpx 20rpx 0;
border-radius: 10rpx;
.goods-img {
position: relative;
border-radius: 10rpx;
overflow: hidden;
.invalid {
position: absolute;
width: 100%;
bottom: 0;
background-color: rgba(0, 0, 0, 0.4);
}
}
.info {
max-width: 400rpx;
}
}
.select {
height: 80rpx;
padding: 0 20rpx;
border-bottom: $-solid-border;
}
}
.cart-null {
.btn {
border: 1px solid $-color-primary;
width: 184rpx;
margin-left: auto;
margin-right: auto;
padding: 8rpx 24rpx;
}
}
.footer {
position: fixed;
padding: 0 24rpx;
width: 100%;
height: 100rpx;
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.1);
bottom: var(--window-bottom);
box-sizing: border-box;
z-index: 20;
.all-price {
text-align: right;
flex: 1;
}
.right-btn {
padding: 13rpx 45rpx;
background: linear-gradient(90deg, rgba(249, 95, 47, 1) 0%, rgba(255, 44, 60, 1) 100%);
}
}
.login {
height: calc(100vh - var(--window-bottom));
background: #fff;
text-align: center;
.btn {
background-color: #09BB07;
width: 280rpx;
line-height: 70rpx;
margin: 40rpx auto 0;
image {
width: 50rpx;
height: 50rpx;
}
}
}
}
</style>