6
0
Fork 0
jiqu-library-miniprogram/src/pageB/select_product/cart.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>