2025-10-23 10:21:37 +08:00
|
|
|
|
<template>
|
2025-10-23 17:25:39 +08:00
|
|
|
|
<view class="cart-container">
|
|
|
|
|
|
<u-navbar id="uNavbarId" back-text="购物车" :back-text-style="navBarTitle"
|
|
|
|
|
|
:background="{background: 'transparent' }" :border-bottom="false" back-icon-color="#000" title-color="#000">
|
|
|
|
|
|
<template v-slot:right>
|
|
|
|
|
|
<view class="right-menu">
|
|
|
|
|
|
<view @click="handleManage">
|
|
|
|
|
|
{{isManage?'退出管理':'管理'}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</u-navbar>
|
|
|
|
|
|
|
|
|
|
|
|
<scroll-view scroll-y="true" :style="'height:'+scrollHeight+'px'">
|
|
|
|
|
|
<view class="cart-list">
|
|
|
|
|
|
<view class="cart-item" v-for="item in cartList">
|
|
|
|
|
|
<view class="left">
|
|
|
|
|
|
<u-checkbox v-model="item.isCheck" shape="circle" active-color="#305def"></u-checkbox>
|
|
|
|
|
|
<image style="height: 160rpx;width: 160rpx;" :src="getImageUrl(item.product.image_url)" mode="">
|
|
|
|
|
|
</image>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<u-row class="right">
|
|
|
|
|
|
<u-col :span="10">
|
|
|
|
|
|
<view>{{item.product.name}}</view>
|
|
|
|
|
|
<view>
|
|
|
|
|
|
<image class="icon" src="/static/icon/rongdou.png" mode=""></image>
|
|
|
|
|
|
{{item.product.rongdou_price}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view>
|
|
|
|
|
|
<image class="icon" src="/static/icon/jifen.png" mode=""></image>
|
|
|
|
|
|
{{item.product.points_price}}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view>
|
|
|
|
|
|
<u-number-box bg-color="#E3ECFF" v-model="item.quantity"
|
|
|
|
|
|
@change="handleChangeQuantity(item)" :min="1"
|
|
|
|
|
|
:max="item.product.stock"></u-number-box>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</u-col>
|
|
|
|
|
|
<u-col :span="2" text-align="right">
|
|
|
|
|
|
<template v-if="!isManage">
|
|
|
|
|
|
x{{item.quantity}}
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template v-else>
|
|
|
|
|
|
<image @click="handleDeleteCart([item])" style="width: 40rpx;height: 40rpx;"
|
|
|
|
|
|
src="/static/icon/delete.png" mode="">
|
|
|
|
|
|
</image>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</u-col>
|
|
|
|
|
|
</u-row>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="box-div">
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</scroll-view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="box-bottom" id="boxBottom">
|
|
|
|
|
|
<u-checkbox v-model="isAllCheck" shape="circle" @change="handleSelectAll">全选</u-checkbox>
|
|
|
|
|
|
<view class="right">
|
|
|
|
|
|
合计:豆{{rongdou}} 分{{point}}
|
|
|
|
|
|
<u-button class="u-m-l-10" @click="handleSubmit">{{isManage?'删除':'结算'}}</u-button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 确认是否删除 -->
|
|
|
|
|
|
<u-modal v-model="showDel" content="是否删除选中的商品" :show-cancel-button="true" @confirm="handleDel"></u-modal>
|
|
|
|
|
|
<!-- 提示 -->
|
|
|
|
|
|
<u-toast ref="msgRef" />
|
2025-10-23 10:21:37 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
2025-10-23 17:25:39 +08:00
|
|
|
|
<script setup>
|
|
|
|
|
|
import {
|
|
|
|
|
|
computed,
|
|
|
|
|
|
onMounted,
|
|
|
|
|
|
ref,
|
|
|
|
|
|
getCurrentInstance
|
|
|
|
|
|
} from 'vue';
|
|
|
|
|
|
import {
|
|
|
|
|
|
mallAPI
|
|
|
|
|
|
} from '../../api/mall.js';
|
|
|
|
|
|
import {
|
|
|
|
|
|
getImageUrl
|
|
|
|
|
|
} from '../../util/common.js'
|
|
|
|
|
|
|
|
|
|
|
|
const msgRef = ref()
|
|
|
|
|
|
|
|
|
|
|
|
const instance = getCurrentInstance();
|
|
|
|
|
|
const scrollHeight = ref(0)
|
|
|
|
|
|
const loadHeight = () => {
|
|
|
|
|
|
uni.getSystemInfo({
|
|
|
|
|
|
success(res) {
|
|
|
|
|
|
let screenHeight = res.screenHeight
|
|
|
|
|
|
uni.createSelectorQuery().in(instance.proxy).select("#uNavbarId").boundingClientRect((
|
|
|
|
|
|
data) => {
|
|
|
|
|
|
scrollHeight.value = screenHeight - data.height
|
|
|
|
|
|
}).exec()
|
|
|
|
|
|
uni.createSelectorQuery().in(instance.proxy).select("#boxBottom").boundingClientRect((
|
|
|
|
|
|
data) => {
|
|
|
|
|
|
scrollHeight.value = scrollHeight - data.height
|
|
|
|
|
|
}).exec()
|
2025-10-23 10:21:37 +08:00
|
|
|
|
}
|
2025-10-23 17:25:39 +08:00
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const navBarTitle = {
|
|
|
|
|
|
fontWeight: '510',
|
|
|
|
|
|
fontStyle: 'Medium',
|
|
|
|
|
|
fontSize: '40rpx',
|
|
|
|
|
|
lineHeight: '52px'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const isManage = ref(false)
|
|
|
|
|
|
|
|
|
|
|
|
const handleManage = () => {
|
|
|
|
|
|
isManage.value = !isManage.value
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const isAllCheck = computed(() => {
|
|
|
|
|
|
if (cartList.value.length == 0) return false
|
|
|
|
|
|
let tmpData = cartList.value.filter(item => item.isCheck)
|
|
|
|
|
|
calculate()
|
|
|
|
|
|
if (tmpData.length == cartList.value.length) return true
|
|
|
|
|
|
else return false
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const handleSelectAll = () => {
|
|
|
|
|
|
if (isAllCheck.value) cartList.value.forEach(item => item.isCheck = false)
|
|
|
|
|
|
else cartList.value.forEach(item => item.isCheck = true)
|
|
|
|
|
|
calculate()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleChangeQuantity = (item) => {
|
|
|
|
|
|
mallAPI.editCartQuantity(item)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const showDel = ref(false)
|
|
|
|
|
|
const delItems = ref([])
|
|
|
|
|
|
const handleDeleteCart = (items) => {
|
|
|
|
|
|
delItems.value = items
|
|
|
|
|
|
showDel.value = true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleDel = async () => {
|
|
|
|
|
|
for (var i = 0; i < delItems.value.length; i++) {
|
|
|
|
|
|
await mallAPI.deleteCart(delItems.value[i].id)
|
2025-10-23 10:21:37 +08:00
|
|
|
|
}
|
2025-10-23 17:25:39 +08:00
|
|
|
|
loadData()
|
|
|
|
|
|
msgRef.value.show({
|
|
|
|
|
|
title: '删除成功',
|
|
|
|
|
|
type: 'success'
|
|
|
|
|
|
})
|
2025-10-23 10:21:37 +08:00
|
|
|
|
}
|
2025-10-23 17:25:39 +08:00
|
|
|
|
|
|
|
|
|
|
const handleSubmit = () => {
|
|
|
|
|
|
if (isManage.value) {
|
|
|
|
|
|
// 删除
|
|
|
|
|
|
delItems.value = cartList.value.filter(item => item.isCheck)
|
|
|
|
|
|
showDel.value = true
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 支付
|
|
|
|
|
|
const ids = cartList.value.map(item => item.id)
|
|
|
|
|
|
mallAPI.createOrder({
|
|
|
|
|
|
cart_item_ids: ids
|
|
|
|
|
|
}).then(response => {
|
|
|
|
|
|
if (response.success) {
|
|
|
|
|
|
// 进入支付页面
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: '/pages/home/pay?preOrderId=' + response.data
|
|
|
|
|
|
.preOrderId
|
|
|
|
|
|
})
|
|
|
|
|
|
} else {
|
|
|
|
|
|
msgRef.value.show({
|
|
|
|
|
|
title: '操作失败',
|
|
|
|
|
|
type: 'error'
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const rongdou = ref(0)
|
|
|
|
|
|
const point = ref(0)
|
|
|
|
|
|
|
|
|
|
|
|
const calculate = () => {
|
|
|
|
|
|
rongdou.value = 0
|
|
|
|
|
|
point.value = 0
|
|
|
|
|
|
cartList.value.forEach(item => {
|
|
|
|
|
|
if (item.isCheck) {
|
|
|
|
|
|
rongdou.value += item.quantity * item.product.rongdou_price
|
|
|
|
|
|
point.value += item.quantity * item.product.points_price
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const cartList = ref([])
|
|
|
|
|
|
|
|
|
|
|
|
const loadData = () => {
|
|
|
|
|
|
mallAPI.getCartList().then(res => {
|
|
|
|
|
|
cartList.value = res.data.items
|
|
|
|
|
|
cartList.value.forEach(item => item.isCheck = false)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
loadHeight()
|
|
|
|
|
|
loadData()
|
|
|
|
|
|
})
|
2025-10-23 10:21:37 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
2025-10-23 17:25:39 +08:00
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
.cart-container {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100vh;
|
|
|
|
|
|
background: linear-gradient(180deg, #E3E8FF 0%, #FFFFFF 100%);
|
|
|
|
|
|
background-blend-mode: lighten;
|
|
|
|
|
|
|
|
|
|
|
|
.right-menu {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
margin-right: 24rpx;
|
|
|
|
|
|
font-family: Work Sans;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
font-style: Medium;
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
leading-trim: NONE;
|
|
|
|
|
|
line-height: 100%;
|
|
|
|
|
|
letter-spacing: -2%;
|
|
|
|
|
|
|
|
|
|
|
|
.del-text {
|
|
|
|
|
|
color: red;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.add-text {
|
|
|
|
|
|
color: #305DEF;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.cart-list {
|
|
|
|
|
|
.cart-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
background: #E3ECFF;
|
|
|
|
|
|
padding: 20rpx;
|
|
|
|
|
|
margin-bottom: 10rpx;
|
2025-10-23 10:21:37 +08:00
|
|
|
|
|
2025-10-23 17:25:39 +08:00
|
|
|
|
.left {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.right {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
margin-left: 20rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
|
|
width: 30rpx;
|
|
|
|
|
|
height: 30rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.box-div {
|
|
|
|
|
|
padding: 60rpx 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.box-bottom {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
padding: 20rpx 40rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
bottom: 0;
|
|
|
|
|
|
background: #F5F8FF;
|
|
|
|
|
|
|
|
|
|
|
|
.right {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|