Files
xdd-uniapp-new/pages/shop/ShoppingCart/index.vue
T
2023-12-25 17:16:56 +08:00

702 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="shoppingCart">
<hx-navbar
title="购物车"
:fixed="true"
:back="false"
:left-slot="true"
:right-slot="true"
color="#333333"
statusBarFontColor="#ffffff"
:background-color="[255,255,255]"
>
<block slot="left">
<view style="padding-left: 30rpx;" class="top-delete-btn acea-row row-middle" @click="delgoods">
<image class="delete-icon" :src="webUrl+'/20210806133058078099.png'" mode=""></image>
</view>
</block>
</hx-navbar>
<view v-if="false" class="nav acea-row row-between-wrapper" style="border-top: 1px solid #f5f5f5">
<view>
<text class="num" style="color: #666666;">{{ count }}件商品</text>
</view>
<view class="top-delete-btn acea-row row-middle" @click="delgoods">
<image class="delete-icon" :src="webUrl+'/20210806133058078099.png'" mode=""></image>
</view>
</view>
<view style="border-top: 1px solid #f5f5f5" v-if="$store.getters.token||userInfo.uid">
<view v-if="validList.length > 0 || cartList.invalid.length > 0">
<view class="list">
<view
class="item acea-row row-between-wrapper"
v-for="(item, cartListValidIndex) in validList"
:key="cartListValidIndex"
>
<view class="select-btn">
<view class="checkbox-wrapper">
<checkbox-group @change="switchSelect(cartListValidIndex)">
<label class="well-check">
<checkbox :checked="item.checked" color="#fff"
style="border-radius: 50%;transform:scale(0.7)"></checkbox>
</label>
</checkbox-group>
</view>
</view>
<view class="picTxt acea-row row-between">
<view class="pictrue" @click="goGoodsCon(item)">
<image :src="item.productInfo.attrInfo.image" v-if="item.productInfo.attrInfo.image"/>
<image :src="item.productInfo.image" v-else/>
</view>
<view class="text acea-row row-column-between">
<view class="line1">{{ item.productInfo.storeName }}</view>
<view class="acea-row row-middle row-left">
<!-- height: 38rpx; -->
<view
class="infor"
style="background-color: #FFF3F2;border-radius: 19rpx;padding: 4rpx 20rpx;"
v-if="item.productInfo.attrInfo"
>规格{{ item.productInfo.attrInfo.sku }}
</view>
</view>
<view class="money" style="color: #FF564A !important;">{{ force2Decimal(item.truePrice) }}</view>
</view>
<view class="carnum acea-row row-middle row-between">
<view
class="reduce"
:class="validList[cartListValidIndex].cartNum <= 1 ? 'on' : ''"
@click.prevent="reduce(cartListValidIndex)"
></view>
<view class="num">{{ item.cartNum }}</view>
<view
class="plus"
v-if="validList[cartListValidIndex].attrInfo"
:class="validList[cartListValidIndex].cartNum >= validList[cartListValidIndex].attrInfo.stock ? 'on' : ''"
@click.prevent="plus(cartListValidIndex)"
></view>
<view
class="plus"
v-else
:class="validList[cartListValidIndex].cartNum >= validList[cartListValidIndex].stock ? 'on' : ''"
@click.prevent="plus(cartListValidIndex)"
></view>
</view>
</view>
</view>
</view>
<!-- 失效商品开始 -->
<view class="invalidGoods" v-if="cartList.invalid.length > 0">
<view class="goodsNav acea-row row-between-wrapper">
<view @click="goodsOpen">
<text
class="iconfont"
:class="goodsHidden === true ? 'icon-xiangyou' : 'icon-xiangxia'"
></text>
失效商品
</view>
<view class="del" @click="delInvalidGoods">
<text class="iconfont icon-shanchu1"></text>
清空
</view>
</view>
<view class="goodsList" :hidden="goodsHidden">
<view
v-for="(item, cartListinvalidIndex) in cartList.invalid"
:key="cartListinvalidIndex"
>
<view
@click="goGoodsCon(item)"
class="item acea-row row-between-wrapper"
v-if="item.productInfo"
>
<view class="invalid acea-row row-center-wrapper">失效</view>
<view class="pictrue">
<image :src="item.productInfo.attrInfo.image" v-if="item.productInfo.attrInfo"/>
<image :src="item.productInfo.image" v-else/>
</view>
<view class="text acea-row row-column-between">
<view class="line1">{{ item.productInfo.storeName }}</view>
<view
class="infor line1"
v-if="item.productInfo.attrInfo"
>属性{{ item.productInfo.attrInfo.sku }}
</view>
<view class="acea-row row-between-wrapper">
<view class="end">该商品已下架</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 失效商品结束 -->
</view>
<!--购物车暂无商品-->
<view class="noCart" v-if="cartList.valid.length === 0 && cartList.invalid.length === 0">
<view class="pictrue">
<image :src="webUrl+'/20210203153734554332.png'"/>
</view>
<Recommend></Recommend>
</view>
<view style="height:210rpx"></view>
<view class="footer" v-if="cartList.valid.length > 0">
<view class="footer-content acea-row row-between-wrapper">
<view class="acea-row row-middle row-between" style="flex: 1;flex-wrap: nowrap;">
<view class="select-btn">
<view class="checkbox-wrapper">
<!-- <label class="well-check">
<input
type="checkbox"
name
value
:checked="isAllSelect && cartCount > 0"
@click="allChecked"
/>
<i class="icon"></i>
<text class="checkAll">全选 ({{ cartCount }})</text>
</label>-->
<checkbox-group @change="allChecked">
<label class="well-check">
<checkbox style="transform:scale(0.7)" value="allSelect" :checked="isAllSelect && cartCount > 0"
color="#fff"></checkbox>
<text class="checkAll" style="color: #666666;">全选 ({{ cartCount }})</text>
</label>
</checkbox-group>
</view>
</view>
<view class="acea-row row-middle" style="margin-left: 20rpx">
<text style="color: #000000;font-size: 28rpx;font-weight: bold;">合计:</text>
<text style="color: #FF564A;font-size: 24rpx;"></text>
<text class="" style="font-size: 32rpx;color: #FF564A;">{{ force2Decimal(countmoney) }}</text>
</view>
</view>
<!-- <view class="money acea-row row-middle" v-if="footerswitch === false"> -->
<view class="money acea-row row-center row-middle" style="background: #FF564A;
height: 100%;
width: 198rpx;
text-align: center;
margin-right: -30rpx;flex-shrink: 0;margin-left: 10rpx;">
<!-- <view class="vline"></view> -->
<view class="placeOrder" @click="placeOrder">结算</view>
</view>
<!-- <view class="button acea-row row-middle" style="position: relative;" v-else>
<view class="vline"></view>
<view class="bnt cart-color" @click="collectAll">收藏</view>
<view class="bnt" @click="delgoods">删除</view>
</view> -->
</view>
</view>
</view>
</view>
</template>
<script>
import Recommend from "@/components/Recommend";
import {mapGetters} from "vuex";
import {changeCartNum, getCartCount, getCartList, postCartDel} from "@/api/store";
import {postCollectAll} from "@/api/user";
import {add, mul} from "@/utils/bc";
import cookie from "@/utils/store/cookie";
const CHECKED_IDS = "cart_checked";
var that;
export default {
name: "ShoppingCart",
components: {
Recommend
},
props: {},
data: function () {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
cartList: {
invalid: [],
valid: []
},
bgImgHeight: '20px',
validList: [],
isAllSelect: false,
cartCount: 0,
countmoney: 0,
goodsHidden: true,
footerswitch: false,
count: 0,
checkedIds: [],
loaded: false
};
},
computed: mapGetters(["userInfo", "token"]),
// watch: {
// $yroute(n) {
// if (n.name === "ShoppingCart") {
// this.carnum();
// this.countMoney();
// this.getCartList();
// this.gainCount();
// this.goodsHidden = true;
// this.footerswitch = false;
// }
// },
// cartList(list) {
// this.validList = list.valid;
// }
// },
watch: {
userInfo(user) {
if (user.uid) {
this.carnum();
this.countMoney();
this.getCartList();
this.gainCount();
}
},
token(token) {
if (this.userInfo.uid) {
this.carnum();
this.countMoney();
this.getCartList();
this.gainCount();
}
},
cartList(list) {
this.validList = list.valid;
}
},
onShow: function () {
this.carnum();
this.countMoney();
this.getCartList();
this.gainCount();
},
onLoad: function () {
that = this;
uni.getSystemInfo({
success: (e) => {
// this.compareVersion(e.SDKVersion, '2.5.0')
let statusBar = 0;
let customBar = 0;
// #ifdef MP
statusBar = e.statusBarHeight
customBar = e.statusBarHeight + 45
if (e.platform === 'android') {
//this.$store.commit('SET_SYSTEM_IOSANDROID', false)
customBar = e.statusBarHeight + 50
}
// #endif
// #ifdef MP-WEIXIN
statusBar = e.statusBarHeight
// @ts-ignore
//uni.getMenuButtonBoundingClientRect();
const custom = uni.getMenuButtonBoundingClientRect()
customBar = custom.bottom + custom.top - e.statusBarHeight
// #endif
// #ifdef MP-ALIPAY
statusBar = e.statusBarHeight
customBar = e.statusBarHeight + e.titleBarHeight
// #endif
// #ifdef APP-PLUS
console.log('app-plus', e)
statusBar = e.statusBarHeight
customBar = e.statusBarHeight + 45
// #endif
// #ifdef H5
statusBar = 0
customBar = e.statusBarHeight + 45
// #endif
// 这里你可以自己决定存放方式,建议放在store中,因为store是实时变化的
// this.$store.commit('SET_STATUS_BAR', statusBar)
// this.$store.commit('SET_CUSTOM_BAR', customBar)
// this.$store.commit('SET_SYSTEM_INFO', e)
// //两列商品宽度
// that.hotGoodsColumnWidth = (e.screenWidth - uni.upx2px(90))/2+'px';
//状态栏图片高度
that.bgImgHeight = statusBar + 'px';
}
});
},
methods: {
force2Decimal(v) {
return this.$force2Decimal(v);
},
goGoodsCon(item) {
this.$yrouter.push({
path: "/pages/shop/GoodsCon/index",
query: {
id: item.productId
}
});
},
getCartList: function () {
let that = this;
getCartList().then(res => {
that.cartList = res.data;
let checkedIds = cookie.get(CHECKED_IDS) || [];
if (!Array.isArray(checkedIds)) checkedIds = [];
this.cartList.valid.forEach(cart => {
if (checkedIds.indexOf(cart.id) !== -1) cart.checked = true;
});
if (checkedIds.length) {
that.checkedIds = checkedIds;
that.isAllSelect = checkedIds.length === this.cartList.valid.length;
that.carnum();
that.countMoney();
}
this.loaded = true;
});
},
//删除商品;
delgoods: function () {
let that = this,
id = [],
valid = [],
list = that.cartList.valid;
list.forEach(function (val) {
if (val.checked === true) {
id.push(val.id);
}
});
if (id.length === 0) {
uni.showToast({
title: "请选择产品",
icon: "none",
duration: 2000
});
return;
}
uni.showModal({
title: '确认删除已选商品?',
content: '',
showCancel: true,
cancelText: '取消',
confirmText: '确认',
success: res => {
uni.showLoading();
postCartDel(id).then(function () {
list.forEach(function (val, i) {
if (val.checked === false || val.checked === undefined)
valid.push(list[i]);
});
that.$set(that.cartList, "valid", valid);
that.carnum();
that.countMoney();
that.gainCount();
that.getCartList();
}).finally(() => {
uni.hideLoading();
});
},
fail: () => {
},
complete: () => {
}
});
},
// //获取数量
gainCount: function () {
let that = this;
getCartCount().then(res => {
that.count = res.data.count;
});
},
//清除失效产品;
delInvalidGoods: function () {
let that = this,
id = [],
list = that.cartList.invalid;
list.forEach(function (val) {
id.push(val.id);
});
postCartDel(id).then(function () {
list.splice(0, list.length);
that.gainCount();
that.getCartList();
});
},
//批量收藏;
collectAll: function () {
let that = this,
data = {
id: [],
category: ""
},
list = that.cartList.valid;
list.forEach(function (val) {
if (val.checked === true) {
data.id.push(val.product_id);
data.category = val.type;
}
});
if (data.id.length === 0) {
uni.showToast({
title: "请选择产品",
icon: "none",
duration: 2000
});
return;
}
postCollectAll(data).then(function () {
uni.showToast({
title: "收藏成功!",
icon: "none",
duration: 2000
});
});
},
//立即下单;
placeOrder: function () {
let that = this,
list = that.cartList.valid,
id = [];
list.forEach(function (val) {
if (val.checked === true) {
id.push(val.id);
}
});
if (id.length === 0) {
uni.showToast({
title: "请选择产品",
icon: "none",
duration: 2000
});
return;
}
this.$yrouter.push({
path: "/pages/order/OrderSubmission/index",
query: {
id: id.join(",")
}
});
},
manage: function () {
let that = this;
that.footerswitch = !that.footerswitch;
},
goodsOpen: function () {
let that = this;
that.goodsHidden = !that.goodsHidden;
},
//加
plus: function (index) {
let that = this;
let list = that.cartList.valid[index];
if (list.cartNum + 1 > list.trueStock) {
uni.showToast({
title: '该商品库存不足,无法继续增加',
icon: 'none'
})
return
}
list.cartNum++;
if (list.attrInfo) {
if (list.cartNum >= list.attrInfo.stock) {
that.$set(list, "cart_num", list.attrInfo.stock);
}
} else {
if (list.cartNum >= list.stock) {
that.$set(list, "cart_num", list.stock);
}
}
that.carnum();
that.countMoney();
that.syncCartNum(list);
},
//减
reduce: function (index) {
let that = this;
let list = that.cartList.valid[index];
if (list.cartNum <= 1) {
uni.showToast({
title: "不能再少了!",
icon: "none",
duration: 2000
});
return;
}
list.cartNum--;
if (list.cartNum < 1) {
that.$set(list, "cart_num", 1);
}
that.carnum();
that.countMoney();
that.syncCartNum(list);
},
syncCartNum(cart) {
if (!cart.sync) {
changeCartNum(cart.id, Math.max(cart.cartNum, 1) || 1)
.then(res => {
this.getCartList();
this.gainCount();
})
.catch(error => {
this.gainCount();
uni.showToast({
title: error.response.data.msg,
icon: "none",
duration: 2000
});
});
}
},
//单选
switchSelect: function (index) {
let that = this,
cart = that.cartList.valid[index],
i = this.checkedIds.indexOf(cart.id);
cart.checked = !cart.checked;
if (i !== -1) this.checkedIds.splice(i, 1);
if (cart.checked) {
this.checkedIds.push(cart.id);
}
let len = that.cartList.valid.length;
let selectnum = [];
for (let i = 0; i < len; i++) {
if (that.cartList.valid[i].checked === true) {
selectnum.push(true);
}
}
that.isAllSelect = selectnum.length === len;
that.$set(that, "cartList", that.cartList);
that.$set(that, "isAllSelect", that.isAllSelect);
cookie.set(CHECKED_IDS, that.checkedIds);
that.carnum();
that.gainCount();
that.countMoney();
},
//全选
allChecked: function (e) {
console.log(e);
let that = this;
let selectAllStatus = e.mp.detail.value[0] == "allSelect" ? true : false;
console.log(selectAllStatus);
// let selectAllStatus = that.isAllSelect;
let checkedIds = [];
// for (let i = 0; i < array.length; i++) {
// array[i].checked = selectAllStatus;
// checked.push()
// }
that.cartList.valid.forEach(cart => {
cart.checked = selectAllStatus;
if (selectAllStatus) {
checkedIds.push(cart.id);
}
});
let cartList = {
...that.cartList
};
that.cartList = [];
that.cartList = cartList;
console.log(this.cartList);
this.$set(this, "cartList", this.cartList);
this.$set(this, "isAllSelect", selectAllStatus);
this.checkedIds = checkedIds;
cookie.set(CHECKED_IDS, checkedIds);
that.carnum();
that.countMoney();
this.$forceUpdate();
},
//数量
carnum: function () {
let that = this;
var carnum = 0;
var array = that.cartList.valid;
for (let i = 0; i < array.length; i++) {
if (array[i].checked === true) {
carnum += parseInt(array[i].cartNum);
}
}
that.$set(that, "cartCount", carnum);
},
//总共价钱;
countMoney: function () {
let that = this;
let carmoney = 0;
let array = that.cartList.valid;
for (let i = 0; i < array.length; i++) {
if (array[i].checked === true) {
carmoney = add(carmoney, mul(array[i].cartNum, array[i].truePrice));
}
}
that.countmoney = carmoney;
}
}
};
</script>
<style scoped lang="less">
.plus {
background-image: url("~@/static/images/num_plus_icon.png");
background-repeat: no-repeat;
background-size: 100% 100%;
border: none !important;
width: 38rpx !important;
height: 38rpx !important;
}
.reduce {
background-image: url("~@/static/images/num_minus_icon.png");
background-repeat: no-repeat;
background-size: 100% 100%;
border: none !important;
width: 38rpx !important;
height: 38rpx !important;
}
.shoppingCart .list .item .picTxt .text .money {
color: #feb655 !important;
}
.vline {
width: 0px;
height: 36rpx;
border-left: 1px solid rgba(255, 255, 255, 0.6);
margin: 26rpx 30rpx 26rpx 0;
}
.top-delete-btn {
padding: 10rpx;
//background:rgba(255,187,225,0.4);
//border-radius:12rpx;
}
.delete-icon {
width: 36rpx;
height: 36rpx;
}
.shoppingCart .footer-content {
background: #fff !important;
border-radius: 0 !important;
margin: 0 !important;
}
.shoppingCart .footer {
height: auto !important;
}
</style>