Files

326 lines
9.0 KiB
Vue
Raw Permalink 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="$VUE_APP_RESOURCES_URL+'/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['hotelId'])">
进店逛逛
<image style="width: 24rpx;height: 24rpx" :src="$VUE_APP_RESOURCES_URL+'/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"
@click="navToGoods(goods['productId'])"
v-if="goods['productInfo']['attrInfo']['image']"/>
<image class="goods-cover flex-0" :src="goods['productInfo']['image']" mode="scaleToFill"
@click="navToGoods(goods['productId'])" v-else/>
<view style="width: 100%">
<view class="one-t" @click="navToGoods(goods['productId'])">{{ goods['productInfo']['storeName'] }}</view>
<view class="sku ai-center" @click="navToGoods(goods['productId'])">
规格{{ 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;" @click="navToGoods(goods['productId'])">
<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>
import {changeCartNum, getCartGroup, postCartDel} from "@/api/store";
import CheckboxIcon from "@/components/CheckboxIcon.vue";
import {VUE_APP_RESOURCES_URL} from '../config/index'
export default {
components: {CheckboxIcon},
data() {
return {
ready: false,
webUrl: VUE_APP_RESOURCES_URL,
list: [],
isAll: false
}
},
computed: {
total() {
let price = 0
this.list.forEach(item => {
item['carts'].forEach(goods => {
if (goods.state) price += Math.round(goods['cartNum'] * goods['truePrice'] * 100) / 100
})
})
return Math.round(price * 100) / 100
},
selectCount() {
let count = 0
this.list.forEach(item => {
item['carts'].forEach(goods => {
if (goods.state) count++
})
})
return count
}
},
onShow() {
this.getCart()
this.ready = true
},
methods: {
async getCart() {
const res = await getCartGroup()
if (res.success) {
this.list = res.data['valid']
this.handleAll(false)
}
},
handleAll(state) {
this.isAll = state
this.list = this.list.map(item => {
item.state = state
item.carts = item.carts.map(goods => {
goods.state = state
return goods
})
return item
})
},
navToStore(id) {
if (id === 0) {
uni.showToast({
title: '店铺装修中~',
icon: 'none',
duration: 3000
})
return
}
uni.navigateTo({
url: '/pagesInn/inn/innHome?id=' + id
})
},
onChange(state, mark) {
if (mark.length === 1) {
if (mark[0] === -1) {
this.handleAll(state)
} else {
this.list[mark[0]]['state'] = state
this.list[mark[0]]['carts'] = this.list[mark[0]]['carts'].map(goods => {
goods.state = state
return goods
})
}
}
if (mark.length === 2) {
this.list[mark[0]]['carts'][mark[1]]['state'] = state
const length = this.list[mark[0]]['carts'].length
let count = 0
this.list[mark[0]]['carts'] = this.list[mark[0]]['carts'].map((goods, gIndex) => {
if (gIndex === mark[1]) goods['state'] = state
if (goods['state']) count++
return goods
})
this.list[mark[0]]['state'] = count === length
}
},
changeNum(event) {
changeCartNum(event.name, event.value)
},
handleIds() {
if (this.selectCount === 0) {
uni.showToast({
title: "请选择产品",
icon: "none",
duration: 2000
})
return []
}
let ids = []
this.list.forEach(item => {
item['carts'].forEach(goods => {
if (goods['state']) ids.push(goods['id'])
})
})
return ids
},
remove() {
const ids = this.handleIds()
if (ids.length === 0) return
uni.showModal({
title: '确认删除已选商品?',
content: '',
showCancel: true,
cancelText: '取消',
confirmText: '确认',
success: async (result) => {
if (result.confirm) {
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;
margin-top: 12rpx;
padding: 10rpx 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>