shopCar.vue 9.0 KB
<template>
	<!-- 购物车 -->
	<view class="">
		<u-navbar bgColor="#F6F8FA" :placeholder="true" title="购物车" :autoBack="true"></u-navbar>
		<view class="minBox" v-if="data.shopList.length>0">
			<!-- 商品管理 -->
			<view class="topBox flexJ" >
				<view class="amount flexA" @click="toMyAddress">
					<image src="/static/shopCarIc/shopAddress.png" mode=""></image>
					<view class="adress ellipsis">{{data.adress}}</view>
				</view>
				<view class="manage" @click="changingOver">{{data.btnStatus ? '管理' : '完成' }}</view>
			</view>

			<!-- 商品 -->
			<view class="shopBox flexA" v-for="(item,index) in data.shopList" :key="item.id">
				<!-- 选择 -->
				<view class="checkIc" @click.stop="checkShop(index)">
					<image v-if="!item.checkType" src="/static/shopCarIc/checks.png" mode=""></image>
					<image v-else src="/static/shopCarIc/checked.png" mode=""></image>
				</view>
				<!-- 商品图片 -->
				<view class="shopPhoto">
					<image :src="item.image" mode=""></image>
					<image v-if="item.status==0" class="shopStatus" src="/static/shopCarIc/shopType.png" mode=""></image>
				</view>
				<!-- 商品详细 -->
				<view class="infoBox">
					<!-- 商品名称 -->
					<view class="title ellipsis">{{item.name}}</view>
					<!-- 商品数量加减 -->
					<view class="numBox flexJ">
						<view class="rightTitle flexA">
							<text>¥</text>{{item.goods_price}}
						</view>
						<view class="and flexA">
							<image src="/static/shopCarIc/reduce.png" mode="" @click="numBtn(0,item)"></image>
							<view class="num flexC">{{item.total_num}}</view>
							<image src="/static/shopCarIc/add.png" mode="" @click="numBtn(1,item)"></image>
						</view>
					</view>
				</view>
			</view>
			<view class="" style="height: 120rpx;"></view>
		</view>
		<!-- 购物车为空 -->
		<view class="nullBox flexV" v-else>
			<image src="/static/shopCarIc/shopCarNull.png" mode=""></image>
			购物车为空哦
		</view>
		<!-- 底部按钮 -->
		<view class="payBox flexJ" v-if="data.shopList.length > 0">
			<!-- 全选按钮 -->
			<view class="allIc flexA" @click="checkAll">
				<image v-if="!allCheck" src="/static/shopCarIc/checks.png" mode=""></image>
				<image v-else src="/static/shopCarIc/checked.png" mode=""></image>
				<view class="">全选</view>
			</view>
			<!-- 合计金额 -->
			<view class="amountBox flexA">
				<view class="settleBox flexA" v-if="data.btnStatus">
					<view class="settle">合计:</view>
					<view class="money flexA">
						¥{{allMoney}}
					</view>
				</view>
				<!-- 结算和删除按钮 -->
				<view class="btns flexC" @click="settleBtn">
					{{data.btnStatus?'结算':'删除'}}
				</view>
			</view>
		</view>
	</view>
</template>

<script setup>
	import { ref,reactive,computed } from 'vue'
	import {onShow,onLoad} from '@dcloudio/uni-app'
	import { getCarList,getCarAdd,getCarReduce,getDelCar } from '@/api/'
	onShow(()=>{
		getCarLists() //购物车列表
		// 默认地址
		uni.getStorageSync('defaultAdres') ? data.adress = uni.getStorageSync('defaultAdres').diqu + uni.getStorageSync('defaultAdres').address : ''
		console.log('默认',data.adress)
	})
	// 商品数组
	let data = reactive({
		shopList:[],
		btnStatus:true ,// 右上角按钮状态
		adress:'请新建默认地址',
	})
	// 修改右上角按钮状态
	const changingOver = ()=> {
		console.log(data.btnStatus)
		data.btnStatus = !data.btnStatus
	}
	//新建收货地址
	const toMyAddress = ()=> {
		uni.navigateTo({
			url:'/pages/mine/myAddress'
		})
	}
	// 勾选商品
	const checkShop = (index) => {
		// let str = data.shopList.some(item=>item.goodstatus == 3)
		// console.log(str)
		data.shopList[index].checkType = !data.shopList[index].checkType
	}
	const settleBtn = ()=> {
		if(data.btnStatus) {
			// 结算的商品购物车id
			let arrId =  data.shopList.filter(item=>item.checkType).map(it=>it.cart_id)
			uni.navigateTo({
				url:`/pages/shopCar/confirmOrder?ids=${arrId.join(',')}`
			})
		} else {
			let arr = data.shopList.filter(item=>item.checkType).map(it=>it.cart_id)
			getDelCars(arr.join(','))  //删除
		}
	}
	// 删除购物商品
	const getDelCars = async (ids)=>{
	  try {
	    const res = await getDelCar(ids)
		getCarLists()
		uni.showToast({ title:'成功移出购物车~',icon:'none' })
	    console.log('getDelCar', res)
	    // 保存数据
	  } catch (err) {
	    uni.showToast({ title:err,icon:'none' })
	    console.log('getDelCar', err)
	  }
	}
	// 数量加减按钮
	const numBtn = (type,item) => {
		if(type == 0 ) {
			if(item.total_num == 1) return uni.showToast({ title:'至少一件哦~',icon:'none' })
			getCarReduces(item.cart_id,item.total_num - 1)
			item.total_num = item.total_num - 1
		} else {
			getCarAdds(item.cart_id,item.total_num + 1)
			item.total_num = item.total_num + 1
		}
	}
	// 数量加
	const getCarAdds = async (id,num)=>{
	  try {
	    const res = await getCarAdd(id,num)
	    console.log('getCarAdd', res)
	    // 保存数据
	  } catch (err) {
	    uni.showToast({ title:err,icon:'none' })
	    console.log('getCarAdd', err)
	  }
	}
	// 数量减
	const getCarReduces = async (id,num)=>{
	  try {
	    const res = await getCarReduce(id,num)
	    console.log('getCarReduce', res)
	    // 保存数据
	  } catch (err) {
	    uni.showToast({ title:err,icon:'none' })
	    console.log('getCarReduce', err)
	  }
	}
	// 全选
	const checkAll = ()=> {
		if(allCheck.value) {
			data.shopList.forEach(item=>{
				item.checkType = false
			})
		} else {
			data.shopList.forEach(item=>{
				item.checkType = true
			})
		}
	}
	// 购物车列表
	const getCarLists = async ()=>{
	  try {
	    const res = await getCarList()
		res.goods_list.forEach(item=>item.checkType = false)
		data.shopList = res.goods_list
		console.log('是什么', data.shopList)
	    console.log('getCarList', res)
	    // 保存数据
	  } catch (err) {
	    console.log('getCarList', err)
	  }
	}
	// 是否全选
	const allCheck = computed(() => {
		return data.shopList.every(item=> item.checkType === true)
	})
	//总价
	const allMoney = computed(() => {
		return data.shopList.filter(it=>it.checkType).reduce((acc,item)=>{ return acc  + item.total_price*1 },0)
	})
</script>

<style lang="scss">
	.u-icon__icon {
		display: none !important;
	}

	page {
		background: #F6F8FA;
	}

	.minBox {
		width: 100%;
		padding: 24rpx;
		box-sizing: border-box;

		.topBox {
			margin: 24rpx 0;

			.amount {

				image {
					margin-right: 8rpx;
					width: 24rpx;
					height: 24rpx;
				}

				.adress {
					width: 424rpx;
					line-height: 32rpx;
					color: #323233ff;
					font-size: 24rpx;
				}
			}

			.manage {
				color: #323233ff;
				font-size: 32rpx;
				line-height: 40rpx;
			}
		}

		.shopBox {
			padding: 32rpx 24rpx 24rpx 24rpx;
			border-radius: 24rpx;
			background: #ffffffff;
			margin-bottom: 24rpx;

			.checkIc {
				margin-right: 24rpx;

				image {
					width: 36rpx;
					height: 36rpx;
				}
			}

			.shopPhoto {
				position: relative;
				margin-right: 24rpx;
				width: 180rpx;
				height: 180rpx;

				image {
					width: 180rpx;
					height: 180rpx;
					border-radius: 16rpx;
					background: #f5f5f5ff;
				}
				
				.shopStatus {
					position: absolute;
					left: 0;
					top: 0;
					width: 180rpx;
					height: 180rpx;
					border-radius: 16rpx;
					opacity: 0.9;
				}
			}

			.infoBox {
				width: 100%;
				height: 180rpx;
				display: flex;
				flex-direction: column;
				justify-content: space-between;

				.title {
					 color: #323233ff;
					 font-size: 28rpx;
				}

				// .modes {
				// 	color: #00000072;

				// 	text {
				// 		font-size: 22rpx;
				// 		padding: 0 16rpx;
				// 		background: rgba(0, 0, 0, 0.1);
				// 		border-radius: 16rpx;
				// 	}
				// }

				.numBox {
					.rightTitle {
						color: #F33F2E;
						font-size: 40rpx;
						font-weight: 700;

						text {
							margin-top: 10rpx;
							 color: #f33f2eff;
							 font-size: 24rpx;
							 font-weight: 700;
						}
					}

					.and {
						image {
							width: 56rpx;
							height: 56rpx;
						}

						.num {
							width: 64rpx;
							height: 56rpx;
							color: #333333ff;
							font-size: 28rpx;
							background: #f2f3f5ff;
							margin: 0 4rpx;
						}
					}
				}
			}
		}
	}

	.payBox {
		position: fixed;
		bottom: 0;
		width: 100%;
		height: 96rpx;
		background-color: #fff;

		.allIc {
			margin-left: 34rpx;
			color: #646566ff;
			font-size: 26rpx;

			image {
				margin-right: 10rpx;
				width: 32rpx;
				height: 32rpx;
			}
		}

		.amountBox {
			margin-right: 32rpx;

			.settleBox {
				margin-right: 16rpx;

				.settle {
					color: #323233ff;
					font-size: 26rpx;
				}

				.money {
					 color: #f33f2eff;
					 font-size: 32rpx;
					 font-weight: 700;
				}
			}

			.btns {
				width: 236rpx;
				height: 72rpx;
				border-radius: 80rpx;
				opacity: 1;
				background: linear-gradient(-88deg, #fe6434ff 0%, #ff2f2fff 100%);
				color: #ffffffff;
				font-size: 28rpx;
				font-weight: 700;
			}
		}
	}

	.nullBox {
		margin-top: 266rpx;

		image {
			width: 262rpx;
			height: 240rpx;
			margin-bottom: 24rpx;
		}

		 color: #C6C5C8;
		 font-size: 28rpx;
	}
</style>