Files
xdd-uniapp-new/pages/cart.vue
T
2024-02-06 12:42:46 +08:00

309 lines
8.4 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>
<view class="pages-cart" v-if="ready">
<u-navbar leftIcon="trash" title="购物车" fixed @leftClick="remove"/>
<view class="tc" style="margin-top: 300rpx" v-if="list.length===0">
<image style="width: 420rpx;height: 418rpx" :src="webUrl+'/20240106211138206789.png'" mode="scaleToFill"/>
</view>
<view class="group-item" v-for="(item,index) in list" :key="index">
<view class="flex jc-between">
<view class="flex ai-center">
<CheckboxIcon style="margin-right: 24rpx;" :default-state="item['state']" @change="value => onChange(value, index, '')"/>
<image class="store-cover" :src="item['merAvatar']"
mode="scaleToFill"/>
<view style="color:#333333;font-size: 30rpx">{{ item['merName'] }}</view>
</view>
<view class="flex ai-center" style="color:#E92727;font-size: 24rpx" @click="navToStore(item['merId'])">
进店逛逛
<image style="width: 24rpx;height: 24rpx" :src="webUrl+'/20240109234706982937.png'" mode="scaleToFill"/>
</view>
</view>
<view class="goods-box">
<view class="goods flex ai-center" v-for="(goods,gIndex) in item['carts']" :key="gIndex">
<CheckboxIcon style="margin-right: 24rpx;" :default-state="goods['state']" :mark="[index,gIndex]"
@change="value => onChange(value, index, gIndex)"/>
<image class="goods-cover flex-0" :src="goods['productInfo']['attrInfo']['image']" mode="scaleToFill"
v-if="goods['productInfo']['attrInfo']['image']"/>
<image class="goods-cover flex-0" :src="goods['productInfo']['image']" mode="scaleToFill" v-else/>
<view style="width: 100%">
<view class="one-t">{{ goods['productInfo']['storeName'] }}</view>
<view class="sku ai-center">规格{{ goods['productInfo']['attrInfo']['sku'] }}</view>
<view class="flex jc-between ai-center" style="width: 100%;margin-top: 26rpx;">
<view style="color:#E92727;font-size: 32rpx;">
<text class="bold" style="font-size: 24rpx"></text>
{{ goods['truePrice'] }}
</view>
<u-number-box class="num-step" v-model="goods['cartNum']" :name="goods['id']"
:max="goods['productInfo']['attrInfo']['stock']" integer disabledInput
iconStyle="color: #fff" @change="changeNum">
<template v-slot:minus>
<view class="num-btn flex jc-center ai-center">
<u-icon name="minus" size="12" color="#FFFFFF"/>
</view>
</template>
<template v-slot:input>
<view class="num-input tc">{{ goods['cartNum'] }}</view>
</template>
<template v-slot:plus>
<view class="num-btn flex jc-center ai-center">
<u-icon name="plus" size="12" color="#FFFFFF"/>
</view>
</template>
</u-number-box>
</view>
</view>
</view>
</view>
</view>
<view class="footer-fixed flex jc-between ai-center">
<view style="margin-left: 32rpx;">
<CheckboxIcon style="margin-right: 24rpx;" :default-state="isAll" @change="value => onAllChange(value)"/>
<text style="color:#666666;font-size: 32rpx">已选({{ selectCount }})</text>
</view>
<view class="flex ai-center">
<view style="margin-right: 20rpx;color:#666666;font-size: 32rpx">合计:
<text class="bold" style="color:#E92727">{{ total }}</text>
</view>
<view class="btn-submit bold flex jc-center ai-center" @click="submit">结算</view>
</view>
</view>
</view>
</template>
<script setup>
import {changeCartNum, getCartGroup, postCartDel} from "@/api/store";
import {VUE_APP_RESOURCES_URL} from '../config/index'
import CheckboxIcon from "@/components/CheckboxIcon.vue";
const webUrl = VUE_APP_RESOURCES_URL
export default {
name: 'CartIndex',
components: {
CheckboxIcon
},
data() {
return {
webUrl,
ready: false,
isAll: false,
selectCount: 0,
total: 0,
list: []
}
},
onShow() {
this.ready = true
this.getCart()
},
methods: {
async getCart() {
const res = await getCartGroup()
if (res.success) {
this.list = res.data['valid']
this.list.map(item => {
item.state = false
if (item.carts) {
item.carts.map(child => {
child.state = false
})
}
})
this.handleAll(true)
}
},
onChange(state, index, childIndex) {
if (childIndex === '') {
this.list[index].state = state
this.list[index].carts.map(good => {
good.state = state
})
} else {
this.list[index].carts[childIndex].state = state
let count = 0
this.list[index].carts.map(good => {
if (good.state) {
count++
}
})
this.list[index].state = count === this.list[index].carts.length
}
this.$forceUpdate()
this.calcAll()
},
onAllChange() {
this.handleAll(!this.isAll)
},
handleAll(state) {
this.list.map(item => {
item.state = state
if (item.carts) {
item.carts.map(good => {
good.state = state
})
}
})
this.isAll = state
this.calcAll()
},
calcAll() {
let total = 0
let count = 0
let goodsAll = 0
this.list.map(item => {
if (item.carts) {
item.carts.map(good => {
goodsAll++
if (good.state) {
total += good.cartNum * good.truePrice
count++
}
})
}
})
this.total = total
this.selectCount = count
this.isAll = goodsAll === count
},
navToStore(id) {
uni.navigateTo({
url: '/pagesInn/inn/innHome?id=' + id
})
},
handleIds() {
const ids = []
this.list.map(item => {
item.carts.map(good => {
if (good.state) {
ids.push(good.id)
}
})
})
return ids
},
remove() {
const _this = this
const ids = _this.handleIds()
if (ids.length === 0) return
uni.showModal({
title: '确认删除已选商品?',
content: '',
showCancel: true,
cancelText: '取消',
confirmText: '确认',
success: async () => {
const res = await postCartDel(ids)
if (res.success) await _this.getCart()
}
})
},
submit() {
const ids = this.handleIds()
if (ids.length === 0) return
const param = ids.join(',')
uni.navigateTo({
url: '/pages/order/OrderSubmission/index?id=' + param
})
}
}
}
</script>
<style scoped lang="less">
view {
box-sizing: border-box;
}
.pages-cart {
min-height: 100vh;
padding-top: calc(var(--status-bar-height) + 54px);
padding-bottom: 100rpx;
}
.group-item {
width: 710rpx;
margin: 12rpx 20rpx;
padding: 8rpx 8rpx 32rpx 20rpx;
background: #FFFFFF;
border-radius: 12rpx;
.store-cover {
width: 48rpx;
height: 48rpx;
margin-right: 8rpx;
border-radius: 50%;
}
}
.goods-box {
.goods {
margin-top: 24rpx;
.goods-cover {
width: 160rpx;
height: 160rpx;
margin-right: 16rpx;
border-radius: 8rpx;
}
.one-t {
width: 420rpx;
color: #333333;
font-size: 30rpx;
line-height: 42rpx;
font-weight: bold;
}
.sku {
display: inline-flex;
height: 42rpx;
margin-top: 12rpx;
padding: 0 20rpx;
border-radius: 22rpx;
background: #FDF1F3;
color: #999999;
font-size: 28rpx;
}
.num-btn {
width: 40rpx;
height: 40rpx;
background: rgba(236, 236, 238, 1);
border: 2px solid rgba(236, 236, 238, 1);
border-radius: 50%;
}
.num-input {
width: 64rpx;
color: #333333;
font-size: 30rpx;
}
}
}
.footer-fixed {
position: fixed;
left: 0;
bottom: 0;
width: 100vw;
height: 100rpx;
box-shadow: 0 6rpx 12rpx rgba(0, 0, 0, 0.16);
background: #FFFFFF;
.btn-submit {
width: 196rpx;
height: 100rpx;
background: #FD5749;
color: #FFFFFF;
font-size: 32rpx;
}
}
</style>