264 lines
8.1 KiB
Vue
264 lines
8.1 KiB
Vue
<template>
|
|
<view>
|
|
<cu-navbar class="cu-navbar" :background="{ background: '#f5f5f5' }" :border-bottom="false" :isBack="false" :title="`购物车(${cartList.length})`">
|
|
<view slot="left" class="flex items-center pl-base text-xl font-medium text-txBase font-extrabold">
|
|
<!-- 左边返回箭头 -->
|
|
<view class="w-20rpx flex items-center mr-10rpx" @tap="back" v-if="isBack">
|
|
<image class="w-20rpx" src="/static/images/user/left_arrow.png" mode="widthFix"></image>
|
|
</view>
|
|
<!-- <view>购物车<text class="text-md">({{ cartList.length }})</text></view> -->
|
|
</view>
|
|
<!-- <view slot="right" class="mx-base relative" @tap="$u.route('/pageA/news/index')">
|
|
<u-icon name="chat" size="48"></u-icon>
|
|
<u-badge :is-dot="true" size="16" :offset="[0, 2]" type="warning"></u-badge>
|
|
</view> -->
|
|
<block v-if="isLogin">
|
|
<view class="pl-base text-xl font-medium text-txBase" @tap="changeEdit">
|
|
{{ navBarLeftText }}
|
|
</view>
|
|
</block>
|
|
</cu-navbar>
|
|
<!-- 已登录 -->
|
|
<block v-if="cartList.length > 0">
|
|
<view class="bg-white rounded-xs card mx-base">
|
|
<block v-for="(item, index) in cartList" :key="item.id">
|
|
<cart-goods-item
|
|
:data="item"
|
|
:goods="item.sku"
|
|
:selected="isSelect(item)"
|
|
@select="onSelect"
|
|
@tap="onGoodsClick"
|
|
@num-change="onNumChange"
|
|
:isEdit="isEdit"
|
|
></cart-goods-item>
|
|
<u-line color="#E5E5E5" v-if="index != cartList.length - 1" />
|
|
</block>
|
|
</view>
|
|
<view class="fixed inset-x-0 bg-white px-18rpx py-20rpx bottom-card z-99">
|
|
<view class="flex w-full items-end">
|
|
<view class="flex items-end">
|
|
<view class="flex items-center" @tap="selectAll = !selectAll">
|
|
<image v-if="selectAll" class="w-32rpx h-32rpx flex-none mr-17rpx" src="/static/images/cart/check-round-fill.png" mode="scaleToFill" />
|
|
<image v-else class="w-32rpx h-32rpx flex-none mr-17rpx" src="/static/images/cart/check-round.png" mode="scaleToFill" />
|
|
<text class="text-lg">全选</text>
|
|
</view>
|
|
<view class="ml-30rpx">
|
|
<text>共 {{ cartList.length }} 件</text>
|
|
</view>
|
|
</view>
|
|
<block v-if="isEdit">
|
|
<view class="flex-1"></view>
|
|
<view>
|
|
<view :disabled="selectedCart.length == 0" class="btn btn-primary rounded-full text-lg px-30rpx py-10rpx" @tap="delShow = true">
|
|
移除
|
|
</view>
|
|
</view>
|
|
</block>
|
|
<block v-else>
|
|
<view class="flex-1 text-right text-xl mr-20rpx">
|
|
<text>合计:</text>
|
|
<text class="text-txSvip">¥{{ calculate.amount }}</text>
|
|
</view>
|
|
<view>
|
|
<view @tap="onSubmit" class="btn btn-primary rounded-full text-lg px-30rpx py-10rpx"> 确认下单 </view>
|
|
</view>
|
|
</block>
|
|
</view>
|
|
</view>
|
|
<view class="box-shdow inset-x-0 h-2rpx fixed bottom-card z-99"></view>
|
|
|
|
<view class="h-148rpx"></view>
|
|
</block>
|
|
<!-- 未登录 -->
|
|
<block v-else>
|
|
<view class="flex items-center justify-center flex-col bg-white py-100rpx">
|
|
<image src="/static/images/cart/empty-cart.png" class="w-300rpx h-254rpx" mode="scaleToFill" />
|
|
<view class="text-txGray text-md">购物车是空的</view>
|
|
<view class="w-full px-150rpx flex items-center mt-50rpx text-txBase text-md mx-100rpx justify-between">
|
|
<view @tap="jumpIndex" class="w-180rpx h-55rpx border border-txBase leading-55rpx text-center rounded-full"> 去逛逛</view>
|
|
<view @tap="$u.routeAuth('/pageA/collection/index')" class="w-180rpx h-55rpx border border-txBase leading-55rpx text-center rounded-full"
|
|
>看看关注</view
|
|
>
|
|
</view>
|
|
</view>
|
|
</block>
|
|
|
|
<!-- 删除提示 -->
|
|
<cu-modal
|
|
v-model="delShow"
|
|
:content="`确定要删除${selectedCart.length}种商品吗?`"
|
|
show-cancel-button
|
|
async-close
|
|
@confirm="delConfirm"
|
|
></cu-modal>
|
|
</view>
|
|
</template>
|
|
<script>
|
|
import CartGoodsItem from '@/pages/shop_cart/components/cart-goods-item.vue';
|
|
import { mapActions, mapGetters } from 'vuex';
|
|
import { add, mcl } from '@/utils';
|
|
import CartMixin from '@/pages/shop_cart/mixin';
|
|
export default {
|
|
mixins: [CartMixin],
|
|
components: {
|
|
CartGoodsItem,
|
|
},
|
|
props: {
|
|
isBack: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
delShow: false,
|
|
isEdit: false,
|
|
calculate: {
|
|
amount: 0,
|
|
},
|
|
};
|
|
},
|
|
onShow() {
|
|
this.getCartList();
|
|
},
|
|
computed: {
|
|
...mapGetters(['cartList', 'selectedCart']),
|
|
navBarLeftText() {
|
|
return this.isEdit ? '完成' : '管理';
|
|
},
|
|
selectAll: {
|
|
set(val) {
|
|
this.setSelectedCart(val ? this.cartList.map((e) => e.id) : []);
|
|
},
|
|
get() {
|
|
return this.cartList.length == this.selectedCart.length && this.cartList.length > 0;
|
|
},
|
|
},
|
|
selectedCorrect() {
|
|
return this.selectedCart?.filter((id) => this.cartList.findIndex((e) => e.id == id && e.sku.is_online) >= 0) ?? [];
|
|
},
|
|
|
|
height() {
|
|
const { windowHeight, statusBarHeight } = this.$u.sys();
|
|
return windowHeight - statusBarHeight - 44 + 'px';
|
|
},
|
|
},
|
|
methods: {
|
|
...mapActions({
|
|
getCartList: 'goods/getCartList',
|
|
setSelectedCart: 'goods/setSelectedCart',
|
|
}),
|
|
//结算
|
|
onSubmit() {
|
|
if (this.selectedCorrect.length == 0) return this.$u.toast('请选择需要结算的商品');
|
|
const params = {
|
|
cards: this.selectedCorrect,
|
|
type: 'cart',
|
|
};
|
|
this.$u.route('/pages/confirm_order/confirm_order?data=' + encodeURIComponent(JSON.stringify(params)));
|
|
},
|
|
//数量改变
|
|
async onNumChange(value, id) {
|
|
await this.$api.put(
|
|
`/v1/shopping-cart-items/${id}`,
|
|
{
|
|
quantity: value,
|
|
},
|
|
{
|
|
custom: {
|
|
loading: true,
|
|
},
|
|
},
|
|
);
|
|
this.getCartList();
|
|
},
|
|
//移除购物车
|
|
async delConfirm() {
|
|
if (this.selectedCart.length == 0) return this.$u.toast('您还未选择商品哦');
|
|
|
|
await this.$api.delete(
|
|
'/v1/shopping-cart-items',
|
|
{ ids: this.selectedCart },
|
|
{
|
|
custom: {
|
|
loading: true,
|
|
},
|
|
},
|
|
);
|
|
this.delShow = false;
|
|
this.getCartList();
|
|
},
|
|
//编辑
|
|
changeEdit() {
|
|
this.isEdit = !this.isEdit;
|
|
},
|
|
//复选框
|
|
onSelect(id, selected) {
|
|
if (selected) {
|
|
this.setSelectedCart([...this.selectedCart, id]);
|
|
} else {
|
|
this.setSelectedCart(this.selectedCart.filter((e) => id != e));
|
|
}
|
|
},
|
|
//商品点击
|
|
onGoodsClick(e) {
|
|
if (this.isEdit) return false;
|
|
this.$u.route('/pages/product_details/index', {
|
|
skuId: e.id,
|
|
});
|
|
},
|
|
//计算价格
|
|
getCalculateAmount() {
|
|
const { is_vip } = this.$store.getters?.user ?? false;
|
|
const amount = this.cartList.reduce((pr, cu) => {
|
|
if (this.selectedCart.findIndex((e) => e == cu.id) >= 0) pr = add(mcl(is_vip ? cu.sku.vip_price : cu.sku.sell_price, cu.quantity), pr);
|
|
return pr;
|
|
}, 0);
|
|
this.calculate.amount = amount;
|
|
},
|
|
//是否勾选
|
|
isSelect({ id }) {
|
|
return this.selectedCart.some((item) => item == id);
|
|
},
|
|
back() {
|
|
uni.navigateBack({
|
|
delta: 1,
|
|
});
|
|
},
|
|
jumpIndex() {
|
|
uni.switchTab({
|
|
url: '/pages/index/index',
|
|
});
|
|
},
|
|
},
|
|
watch: {
|
|
selectedCart: {
|
|
immediate: true,
|
|
handler(e) {
|
|
this.getCalculateAmount();
|
|
// console.log(e);
|
|
},
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
.card {
|
|
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.08);
|
|
}
|
|
|
|
.bottom-card {
|
|
box-shadow: 0px -4rpx 8rpx rgba(0, 0, 0, 0.25);
|
|
bottom: var(--window-bottom);
|
|
}
|
|
|
|
.bottom-h {
|
|
padding: var(--window-bottom);
|
|
}
|
|
|
|
.box-shdow {
|
|
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25);
|
|
background: #ffffff;
|
|
}
|
|
</style>
|