Files
2023-11-15 19:59:37 +08:00

416 lines
9.8 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>
<Header
system-bar-area-bg="#fff"
header-area-bg="#fff"
bg-change-by-scroll
>
购物车
</Header>
<!-- have data -->
<view v-if="!showEmpty">
<!-- manage row -->
<view class="cart-manage">
<view @click="manage=!manage">
{{ manageStr }}
</view>
</view>
<!-- cart body box-->
<uv-checkbox-group
v-model="shoppingSelect"
shape="circle"
activeColor="#ee6d46"
@change="handleSingleSelect"
>
<card class="shopping-checkbox">
<!-- 购物车信息 -->
<view
v-for="(item) in cartList"
:key="item.id"
class="shopping-item"
>
<uv-checkbox
:name="item.id"
/>
<view class="good">
<Goods
row
imgWidth="200rpx"
info-padding="0 0 0 40rpx"
:goods="item.productInfo"
>
<template #options>
<view class="goods-options">
<!-- sku select -->
<view class="sku-row flex">
<view
class="sku-info flex flex-jc__sb flex-ai__center"
@click.stop="handleOpenSkuSelect(item,goodsAttrSelectRef)"
>
<view class="info">
{{ item.productInfo && item.productInfo.attrInfo && item.productInfo.attrInfo.sku }}
</view>
<uv-icon
class="icon"
name="arrow-down"
color="#ccc"
size="12"
/>
</view>
</view>
<!-- bottom -->
<view class="price-row flex flex-ai__center flex-jc__sb">
<!-- price -->
<view class="price-box flex flex-ai__end">
{{ item.truePrice }}
<view class="old-price">
{{ item.productInfo.otPrice }}
</view>
</view>
<!-- cart number -->
<view
class="cart-num flex flex-ai__center flex-jc__sb"
@click.stop=""
>
<view
class="button"
@click="handleCartNumberChange(item,'minus')"
>
<uv-icon
name="minus"
color="#333"
size="12"
></uv-icon>
</view>
<view class="input">
<input
type="number"
inputmode="numeric"
v-model="item.cartNum"
@blur="(e)=>handleCartNumberInputChange(e,item)"
>
</view>
<view
class="button"
@click="handleCartNumberChange(item,'plus')"
>
<uv-icon
name="plus"
color="#333"
size="12"
></uv-icon>
</view>
</view>
</view>
</view>
</template>
</Goods>
</view>
</view>
<!-- 选中了的结算统计信息 -->
<view :class="{'select-product-settle-info':true,show:shoppingSelect.length>0}">
<view
class="row flex flex-ai__center flex-jc__sb"
v-for="(item,index) in settleFields"
:key="index"
>
<view class="label">
{{ item.label }}
</view>
<view v-if="statisticsInfo">
{{ item.prefix }} {{ statisticsInfo[item.field].toFixed(2) }}
</view>
</view>
</view>
</card>
</uv-checkbox-group>
<!-- bottom action row -->
<view class="screen action-bar ">
<view class="action-info">
<view class="action-checkbox">
<uv-checkbox-group
shape="circle"
activeColor="#ee6d46"
>
<uv-checkbox
name="all"
:checked="shoppingSelectAll"
@change="handleSelectAll"
>
全选
</uv-checkbox>
</uv-checkbox-group>
</view>
</view>
<view class="action-btns">
<view
class="action-total"
v-show="!manage"
>
总计{{ statisticsInfo ? statisticsInfo.totalPrice.toFixed(2) : "0.00" }}
</view>
<view
class="button"
v-if="!manage"
@click="submitOrder"
>结算
</view>
<view
v-else
class="button"
@click="openDelModal(modalRef)"
>
删除
</view>
</view>
</view>
</view>
<!-- null data -->
<CartEmpty v-else />
<!-- 商品推荐 -->
<Recommend />
<view class="action-height"></view>
<view class="h5-tabbar-height"></view>
<!-- sku select -->
<GoodAttrSelect
style="z-index: 999"
:id="openSkuProductId"
ref="goodsAttrSelectRef"
@close="handleCloseSkuSelect"
@submit="(e)=>handleSubmitSkuSelect(e, goodsAttrSelectRef,cartList,handleCartNumberInputChange,doGetCartList)
"
/>
<!-- delete modal -->
<Modal
ref="modalRef"
content="确认要删除这些购物车数据吗?"
@confirm="doDelete"
/>
</template>
<script setup>
import { ref } from 'vue'
import Goods from "@/components/goodsComponents/Goods.vue";
import GoodAttrSelect from "@/components/good-attr-select/good-attr-select.vue";
import Modal from "@/components/Modal/index.vue"
import { settleFields } from "@/pages/shoppingCart/index.data";
import { useCartData, useCartNumber, useCartOption, useSku } from "@/pages/shoppingCart/index.utils";
import CartEmpty from "@/pages/shoppingCart/components/CartEmpty.vue";
import Header from "@/components/Header/index.vue"
import { onHide, onPageScroll, onReachBottom } from "@dcloudio/uni-app";
import Recommend from "@/components/Recommend/index.vue";
import { useScroll } from "@/hooks/useScroll";
const modalRef = ref() // 删除弹窗
const goodsAttrSelectRef = ref() // 更改sku
const {
showEmpty,
cartList,
doGetCartList
} = useCartData();
const {
manage,
manageStr,
shoppingSelect,
shoppingSelectAll,
handleSingleSelect,
handleSelectAll,
statisticsInfo,
computeSelectInfoByShoppingSelect,
openDelModal,
doDelete,
submitOrder,
} = useCartOption({cartList, doGetCartList})
const {
openSkuProductId,
handleOpenSkuSelect,
handleCloseSkuSelect,
handleSubmitSkuSelect
} = useSku()
const {
handleCartNumberInputChange,
handleCartNumberChange
} = useCartNumber({afterChange: computeSelectInfoByShoppingSelect})
onHide(() => {
modalRef.value?.close()
goodsAttrSelectRef.value?.close()
})
useScroll()
</script>
<style lang="scss">
.cart-manage {
padding: 20rpx 34rpx;
font-size: 28rpx;
color: #333333;
background-color: #fff;
display: flex;
justify-content: flex-end;
border-bottom: 1rpx solid #f9f9f9;
}
// 商品SKU 数量等操作条
.goods-options {
width: 100%;
.sku-row {
margin-bottom: 30rpx;
.sku-info {
@include usePadding(10, 4);
border: 1rpx solid #ccc;
border-radius: 5rpx;
font-size: 24rpx;
transition: all .3s;
max-width: 100%;
.info {
width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
&:active {
scale: 1.1;
}
.icon {
margin-left: 15rpx;
}
}
}
.price-row {
width: 100%;
.price-box {
font-size: 30rpx;
.old-price {
font-size: 20rpx;
color: $tips-color;
text-decoration: line-through;
margin-left: 10rpx;
}
}
.cart-num {
font-size: 24rpx;
.input {
width: 120rpx;
input {
width: 100%;
text-align: center;
color: #333;
}
}
.button {
font-size: 32rpx;
width: 34rpx;
aspect-ratio: 1/1;
border-radius: 5rpx;
border: 2rpx solid #cccccc;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
transition: all .3s;
&:active {
scale: 1.2;
}
}
}
}
}
// 统计信息
.select-product-settle-info {
@include usePadding(40, 0);
font-size: 28rpx;
transition: height .3s;
height: 0;
overflow: hidden;
.row {
margin: 20rpx 0;
}
&.show {
@include usePadding(40, 10);
border-top: 1rpx solid #E6E6E6;
height: 230rpx;
}
}
.action-bar {
z-index: 89;
height: 100rpx;
.action-btns {
height: 100%;
padding: 0 0;
.action-total {
padding-right: 30rpx;
font-size: 34rpx;
}
.button {
margin: 0 0;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 0 50rpx;
background: $primary-color;
color: $white-color;
}
}
}
// #ifndef H5
.action-height {
width: 100%;
height: 100rpx;
background: #fff;
}
// #endif
.shopping-checkbox {
width: 100%;
.shopping-item {
display: flex;
align-items: center;
padding: 0 20rpx;
box-sizing: border-box;
margin-bottom: 50rpx;
.good {
width: 93%;
position: relative;
}
}
}
</style>