代码提交

This commit is contained in:
黄少君
2023-11-14 17:21:03 +08:00
parent d0b337c596
commit dcab74274f
567 changed files with 22414 additions and 7375 deletions

View File

@ -1,234 +1,251 @@
<template>
<layout>
<uv-navbar
:fixed="false"
title="购物车"
left-arrow
@leftClick="$onClickLeft"
/>
<view class="shopping-manage">
<div
class="shopping-manage-item"
@tap="changeMange"
>
{{ isManage ? '取消' : '管理' }}
</div>
<Header
system-bar-area-bg="#fff"
header-area-bg="#fff"
:scroll-top="scrollTop"
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"
@change="handleShoppingSelect"
v-model="shoppingSelect"
shape="circle"
activeColor="#ee6d46"
@change="handleSingleSelect"
>
<space
direction="vertical"
fill
>
<card class="shopping-checkbox">
<view
v-for="(item, index) in shoppingData"
class="shopping-checkbox-cell"
>
<uv-checkbox
<card class="shopping-checkbox">
<!-- 购物车信息 -->
<view
v-for="(item) in cartList"
class="shopping-item"
>
<uv-checkbox
:name="item.id"
activeColor="#ee0a24"
/>
<goods
link
list
interval
showAction
model
:price="item.productInfo.price"
:data="item.productInfo"
/>
<view class="good">
<Goods
row
imgWidth="200rpx"
info-padding="0 0 0 40rpx"
:goods="item.productInfo"
>
<template #action>
<uv-number-box
v-model="item.cartNum"
step="1"
@change="handleChangeNum($event, item)"
/>
<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>
</Goods>
</view>
</card>
</space>
</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>
<view class="action-bar screen">
<!-- bottom action row -->
<view class="screen action-bar ">
<view class="action-info">
<view class="action-checkbox">
<uv-checkbox-group>
<uv-checkbox-group
shape="circle"
activeColor="#ee6d46"
>
<uv-checkbox
name="all"
:checked="shoppingSelectAll"
activeColor="#ee0a24"
@change="handleShoppingSelectAll"
name="all"
:checked="shoppingSelectAll"
@change="handleSelectAll"
>
全选
</uv-checkbox>
</uv-checkbox-group>
</view>
<view class="action-total">
总计{{ totalPrice }}
</view>
</view>
<view class="action-btns">
<uv-button
v-if="!isManage"
type="primary"
text="结算"
@click="handleSubmitOrder(1)"
></uv-button>
<uv-button
v-if="isManage"
type="primary"
text="删除"
@click="handleDelete(1)"
></uv-button>
<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>
</layout>
<view class="action-height"></view>
<view class="h5-tabbar-height"></view>
</view>
<!-- null data -->
<CartEmpty v-else />
<!-- sku select -->
<GoodAttrSelect
: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 } from "@dcloudio/uni-app";
import { ref, watch } from 'vue'
import { getCartList, getCartNum, getCartDel } from '@/api/cart'
import { navigateTo } from '@/utils/router'
import { onLoad } from '@dcloudio/uni-app'
const modalRef = ref() // 删除弹窗
const goodsAttrSelectRef = ref() // 更改sku
const shoppingData = ref([])
const shoppingSelect = ref([])
const shoppingSelectAll = ref(false)
const shoppingCheck = ref(null);
const totalPrice = ref(0);
const isManage = ref(false);
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()
onLoad(() => {
handleGetCartList()
const {
handleCartNumberInputChange,
handleCartNumberChange
} = useCartNumber({afterChange: computeSelectInfoByShoppingSelect})
onHide(() => {
modalRef.value?.close()
goodsAttrSelectRef.value?.close()
})
watch(shoppingSelect, (shoppingSelect) => {
let price = 0
for (let id in shoppingSelect) {
let store = shoppingData.value.filter(item => item.id == shoppingSelect[id])[0]
price += store.truePrice * store.cartNum
}
totalPrice.value = price
const scrollTop = ref(0)
onPageScroll((e) => {
scrollTop.value = e.scrollTop
})
watch(shoppingData, (shoppingData) => {
let price = 0
for (let id in shoppingSelect.value) {
let store = shoppingData.filter(item => item.id == shoppingSelect.value[id])[0]
price += store.truePrice * store.cartNum
}
totalPrice.value = price
})
const handleGetCartList = async () => {
const shopping = await getCartList()
if (shopping) {
shoppingData.value = shopping.valid
}
}
const handleShoppingSelectAll = (e) => {
shoppingSelectAll.value = e
if (!shoppingSelectAll.value) {
shoppingSelect.value = []
return
}
shoppingSelect.value = shoppingData.value.map(item => item.id)
}
const handleShoppingSelect = (value) => {
shoppingSelectAll.value = value.length == shoppingData.value.length
}
const handleChangeNum = async (event, cart) => {
await getCartNum({
number: event.value,
id: cart.id,
})
handleGetCartList()
}
const handleSubmitOrder = () => {
if (shoppingSelect.value.length <= 0) {
uni.showToast({
icon: 'none',
title: '请选择',
duration: 2000
});
return
}
navigateTo({
url: '/pages/submitOrder/submitOrder',
query: {
cartId: shoppingSelect.value.toString()
}
})
}
const changeMange = () => {
isManage.value = !isManage.value
}
const handleDelete = async () => {
if (shoppingSelect.value.length <= 0) return
uni.showModal({
title: '提示',
content: '确认从购物车删除',
success: async (res) => {
if (res.confirm) {
await getCartDel({
ids: shoppingSelect.value
})
handleGetCartList()
uni.showToast({
title: '已删除',
duration: 2000
});
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
}
</script>
<style lang="less">
.shopping-checkbox {}
.shopping-action {
padding-left: 34rpx;
flex: 1;
display: flex;
justify-content: space-between;
&-checkbox {
flex: 1
}
&-total {
line-height: 48rpx;
font-size: 34rpx;
color: #333333;
margin-right: 10rpx;
}
&-btn {
width: 224rpx;
}
}
.shopping-manage {
<style lang="scss">
.cart-manage {
padding: 20rpx 34rpx;
font-size: 28rpx;
color: #333333;
@ -237,4 +254,157 @@ const handleDelete = async () => {
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>