Files

419 lines
10 KiB
Vue
Raw Normal View History

2023-10-11 11:27:47 +08:00
<template>
2023-11-14 17:21:03 +08:00
<Header
2023-11-17 20:55:32 +08:00
:scroll-top="scrollTop"
2023-11-14 17:21:03 +08:00
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>
2023-10-11 11:27:47 +08:00
</view>
2023-11-14 17:21:03 +08:00
<!-- cart body box-->
2023-10-11 11:27:47 +08:00
<uv-checkbox-group
2023-11-14 17:21:03 +08:00
v-model="shoppingSelect"
shape="circle"
activeColor="#ee6d46"
@change="handleSingleSelect"
2023-10-11 11:27:47 +08:00
>
2023-11-14 17:21:03 +08:00
<card class="shopping-checkbox">
<!-- 购物车信息 -->
<view
v-for="(item) in cartList"
2023-11-15 19:59:37 +08:00
:key="item.id"
2023-11-14 17:21:03 +08:00
class="shopping-item"
>
<uv-checkbox
2023-10-11 11:27:47 +08:00
:name="item.id"
2023-11-14 17:21:03 +08:00
/>
<view class="good">
<Goods
row
imgWidth="200rpx"
info-padding="0 0 0 40rpx"
:goods="item.productInfo"
2023-10-11 11:27:47 +08:00
>
2023-11-14 17:21:03 +08:00
<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"
2023-11-17 20:55:32 +08:00
:class="item.cartNum <= 1 && 'disabled'"
2023-11-14 17:21:03 +08:00
@click="handleCartNumberChange(item,'minus')"
>
<uv-icon
name="minus"
color="#333"
2023-11-17 20:55:32 +08:00
size="24rpx"
2023-11-14 17:21:03 +08:00
></uv-icon>
</view>
<view class="input">
<input
type="number"
inputmode="numeric"
v-model="item.cartNum"
@blur="(e)=>handleCartNumberInputChange(e,item)"
@input="(e)=>cartNumberInput(e,item)"
2023-11-14 17:21:03 +08:00
>
</view>
<view
class="button"
2023-11-17 20:55:32 +08:00
:class="item.cartNum >= item.trueStock && 'disabled'"
2023-11-14 17:21:03 +08:00
@click="handleCartNumberChange(item,'plus')"
>
<uv-icon
name="plus"
color="#333"
2023-11-17 20:55:32 +08:00
size="24rpx"
2023-11-14 17:21:03 +08:00
></uv-icon>
</view>
</view>
</view>
</view>
2023-10-11 11:27:47 +08:00
</template>
2023-11-14 17:21:03 +08:00
</Goods>
2023-10-11 11:27:47 +08:00
</view>
2023-11-14 17:21:03 +08:00
</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>
2023-10-11 11:27:47 +08:00
</uv-checkbox-group>
2023-11-14 17:21:03 +08:00
<!-- bottom action row -->
<view class="screen action-bar ">
2023-10-11 11:27:47 +08:00
<view class="action-info">
<view class="action-checkbox">
2023-11-14 17:21:03 +08:00
<uv-checkbox-group
shape="circle"
activeColor="#ee6d46"
>
2023-10-11 11:27:47 +08:00
<uv-checkbox
2023-11-14 17:21:03 +08:00
name="all"
:checked="shoppingSelectAll"
@change="handleSelectAll"
2023-10-11 11:27:47 +08:00
>
全选
</uv-checkbox>
</uv-checkbox-group>
</view>
</view>
<view class="action-btns">
2023-11-14 17:21:03 +08:00
<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>
2023-10-11 11:27:47 +08:00
</view>
</view>
2023-11-15 19:59:37 +08:00
2023-11-14 17:21:03 +08:00
</view>
<!-- null data -->
<CartEmpty v-else />
2023-11-15 19:59:37 +08:00
<!-- 商品推荐 -->
<Recommend />
2023-11-15 19:59:37 +08:00
<view class="action-height"></view>
<view class="h5-tabbar-height"></view>
2023-11-14 17:21:03 +08:00
<!-- sku select -->
<GoodAttrSelect
2023-11-15 19:59:37 +08:00
style="z-index: 999"
2023-11-14 17:21:03 +08:00
:id="openSkuProductId"
ref="goodsAttrSelectRef"
:goods-detail="openProductItem"
:sku-id="openSkuSkuId"
@select="(e)=>handleSubmitSkuSelect(e, goodsAttrSelectRef,cartList,handleCartNumberInputChange,doGetCartList)
2023-11-14 17:21:03 +08:00
"
/>
<!-- delete modal -->
<Modal
ref="modalRef"
content="确认要删除这些购物车数据吗?"
@confirm="doDelete"
/>
2023-11-17 20:55:32 +08:00
<ReturnTop :scroll-top="scrollTop" />
2023-10-11 11:27:47 +08:00
</template>
<script setup>
2023-11-14 17:21:03 +08:00
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 "@/root/shoppingCart/index.data";
import { useCartData, useCartNumber, useCartOption, useSku } from "@/root/shoppingCart/index.utils";
import CartEmpty from "@/root/shoppingCart/components/CartEmpty.vue";
2023-11-14 17:21:03 +08:00
import Header from "@/components/Header/index.vue"
import { onHide } from "@dcloudio/uni-app";
2023-11-15 19:59:37 +08:00
import Recommend from "@/components/Recommend/index.vue";
import { useScroll } from "@/hooks/useScroll";
2023-11-17 20:55:32 +08:00
import ReturnTop from "@/components/ReturnTop/index.vue"
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
const modalRef = ref() // 删除弹窗
const goodsAttrSelectRef = ref() // 更改sku
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
const {
showEmpty,
cartList,
doGetCartList
} = useCartData();
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
const {
manage,
manageStr,
shoppingSelect,
shoppingSelectAll,
handleSingleSelect,
handleSelectAll,
statisticsInfo,
computeSelectInfoByShoppingSelect,
openDelModal,
doDelete,
submitOrder,
} = useCartOption({cartList, doGetCartList})
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
const {
openSkuSkuId,
openProductItem,
2023-11-14 17:21:03 +08:00
openSkuProductId,
handleOpenSkuSelect,
handleCloseSkuSelect,
handleSubmitSkuSelect
} = useSku()
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
const {
handleCartNumberInputChange,
handleCartNumberChange,
cartNumberInput
2023-11-14 17:21:03 +08:00
} = useCartNumber({afterChange: computeSelectInfoByShoppingSelect})
onHide(() => {
modalRef.value?.close()
goodsAttrSelectRef.value?.close()
2023-10-11 11:27:47 +08:00
})
2023-11-17 20:55:32 +08:00
const {scrollTop} = useScroll()
2023-11-14 17:21:03 +08:00
</script>
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
<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;
2023-10-11 11:27:47 +08:00
}
2023-11-14 17:21:03 +08:00
// 商品SKU 数量等操作条
.goods-options {
width: 100%;
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
.sku-row {
margin-bottom: 30rpx;
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
.sku-info {
@include usePadding(10, 4);
border: 1rpx solid #ccc;
border-radius: 5rpx;
font-size: 24rpx;
transition: all .3s;
max-width: 100%;
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
.info {
width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
&:active {
scale: 1.1;
}
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
.icon {
margin-left: 15rpx;
}
2023-10-11 11:27:47 +08:00
}
2023-11-14 17:21:03 +08:00
}
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
.price-row {
width: 100%;
.price-box {
font-size: 30rpx;
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
.old-price {
font-size: 20rpx;
color: $tips-color;
text-decoration: line-through;
margin-left: 10rpx;
2023-10-11 11:27:47 +08:00
}
}
2023-11-14 17:21:03 +08:00
.cart-num {
font-size: 24rpx;
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
.input {
2023-11-17 20:55:32 +08:00
width: 70rpx;
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
input {
width: 100%;
text-align: center;
color: #333;
}
}
.button {
font-size: 32rpx;
2023-11-17 20:55:32 +08:00
width: 40rpx;
height: 40rpx;
2023-11-14 17:21:03 +08:00
aspect-ratio: 1/1;
border-radius: 5rpx;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
transition: all .3s;
2023-11-17 20:55:32 +08:00
border: 1px solid #999999;
2023-10-11 11:27:47 +08:00
2023-11-14 17:21:03 +08:00
&:active {
scale: 1.2;
}
&.disabled {
2023-11-17 20:55:32 +08:00
border-color: #dddddd;
:deep(.uv-icon__icon) {
2023-11-17 20:55:32 +08:00
color: #dddddd !important;
}
2023-11-17 20:55:32 +08:00
&:active {
scale: 1;
}
}
2023-11-14 17:21:03 +08:00
}
}
2023-10-11 11:27:47 +08:00
}
2023-11-14 17:21:03 +08:00
}
.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;
}
}
2023-10-11 11:27:47 +08:00
}
</style>