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

307 lines
8.2 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']" :mark="[index]" @change="onChange"/>
<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="onChange"/>
<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" :mark="[-1]" @change="onChange"/>
<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 {computed, onMounted, ref} from "@vue/composition-api";
import {onShow} from '@dcloudio/uni-app'
import {changeCartNum, getCartGroup, postCartDel} from "@/api/store";
import CheckboxIcon from "@/components/CheckboxIcon.vue";
import {VUE_APP_RESOURCES_URL} from '../config/index'
const webUrl = VUE_APP_RESOURCES_URL
const ready = ref(false)
onShow(() => {
getCart()
ready.value = true
})
const list = ref([])
const getCart = async () => {
const res = await getCartGroup()
if (res.success) {
list.value = res.data['valid']
handleAll(false)
}
}
const navToStore = (id) => {
uni.navigateTo({
url: '/pagesInn/inn/innHome?id=' + id
})
}
const total = computed(() => {
let price = 0
list.value.forEach(item => {
item['carts'].forEach(goods => {
if (goods.state) price += goods['cartNum'] * goods['truePrice']
})
})
return price
})
const isAll = ref(false)
const onChange = (state, mark) => {
if (mark.length === 1) {
if (mark[0] === -1) {
handleAll(state)
} else {
list.value[mark[0]]['state'] = state
list.value[mark[0]]['carts'] = list.value[mark[0]]['carts'].map(goods => {
goods.state = state
return goods
})
}
}
if (mark.length === 2) {
list.value[mark[0]]['carts'][mark[1]]['state'] = state
const length = list.value[mark[0]]['carts'].length
let count = 0
list.value[mark[0]]['carts'] = list.value[mark[0]]['carts'].map((goods, gIndex) => {
if (gIndex === mark[1]) goods['state'] = state
if (goods['state']) count++
return goods
})
list.value[mark[0]]['state'] = count === length
}
}
const handleAll = (state) => {
isAll.value = state
list.value = list.value.map(item => {
item.state = state
item.carts = item.carts.map(goods => {
goods.state = state
return goods
})
return item
})
}
const changeNum = (event) => {
changeCartNum(event.name, event.value)
}
const selectCount = computed(() => {
let count = 0
list.value.forEach(item => {
item['carts'].forEach(goods => {
if (goods.state) count++
})
})
return count
})
const handleIds = () => {
if (selectCount.value === 0) {
uni.showToast({
title: "请选择产品",
icon: "none",
duration: 2000
})
return []
}
let ids = []
list.value.forEach(item => {
item['carts'].forEach(goods => {
if (goods['state']) ids.push(goods['id'])
})
})
return ids
}
const remove = () => {
const ids = 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 getCart()
}
})
}
const submit = () => {
const ids = 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>