思路
需求
- 根据菜品类型筛选菜品
- 每个菜品数量变化都需计算总价和实际支付价格
- 点击购物车,显示已选的菜品及数量,改变购物车菜品数量,列表中数量也要变化
实现思路
- 获取所有菜品dishListCopy
- 点击类型,筛选菜品,dishList
- 购物车,展示菜品,chooseDishArr
- 改变列表中菜品数量,改变dishList
- 改变购物车的菜品数量,改变dishListCopy-dishCount
代码实现
.wxml
<view class="mlr-32" wx:if="{{serviceObjectId}}">
<van-row gutter="10">
<van-col span="5">
<view class="radius-20 bg-white">
<view class="dish-type center {{selectedIndex==index?'line-shorter bg':''}}" wx:for="{{dishTypeArr}}" wx:key="index" data-index="{{index}}" data-value="{{item.dictValue}}" bindtap="getOrderList">{{item.dictLabel}}</view>
</view>
</van-col>
<van-col span="18">
<view class="bg-white radius-20">
<view class="flex_l pd-20 mtb-20" wx:for="{{dishList}}" wx:key="index">
<image style="width:140rpx;height:140rpx;border-radius: 10rpx;" src="{{item.dishPicture?pictureURL+item.dishPicture:'/assets/imgs/dishes.png'}}" />
<view class="ml-20 flex-1">
<view class="line-2">{{item.dishName}}</view>
<view class="flex mt-10">
<view class="red mr-10">¥{{item.dishPrice}}</view>
<van-stepper value="{{ item.dishCount }}" data-item="{{item}}" bind:change="onChange" data-type="1" min="0" />
</view>
</view>
</view>
</view>
</van-col>
</van-row>
</view>
<!-- 购物车 -->
<van-popup show="{{ catShow }}" bind:close="catClose" round position="bottom">
<view class="bg-white radius-20">
<view class="bold pt-30 pl-30">已选</view>
<view class="flex_l pd-20 mtb-20" wx:for="{{chooseDishArr}}" wx:key="index">
<image style="width:140rpx;height:140rpx;border-radius: 10rpx;" src="{{item.dishPicture?pictureURL+item.dishPicture:'/assets/imgs/dishes.png'}}" />
<view class="ml-20 flex-1">
<view class="line-2">{{item.dishName}}</view>
<view class="flex mt-10">
<view class="red mr-10">¥{{item.dishPrice}}</view>
<van-stepper value="{{ item.dishCount }}" data-item="{{item}}" bind:change="onChange" data-type="2" min="0" />
</view>
</view>
</view>
</view>
</van-popup>
<van-toast id="van-toast" />
.js
import Toast from '@vant/weapp/toast/toast';
Page({
/**
* 页面的初始数据
*/
data() {
return {
diningStyle: '',//1:,2:
// 选择服务对象
serviceObjectId: '',
isShowCamera: false,
// 下单
enterOrderInfo: {},//下单对象信息
dishTypeArr: [],//菜品类型-字典
dishType: '',//菜品类型
dishList: [],//菜品列表
dishListCopy: [],//菜品列表Copy
selectedIndex: null,// 用于标记被选中的项目索引
chooseDishArr: [],// 已选的菜品
subvention: 0,//补助金额
actualPayment: 0,//实付金额
sumPayment: 0,// 总价格
// 购物车
catShow: false,
}
},
onShow: function () {
},
onLoad(options) {
this.getList()
this.setData({
pictureURL: pictureURL,
enterOrderInfo: wx.getStorageSync('enterOrderInfo'),
serviceObjectId: wx.getStorageSync('enterOrderInfo').serviceObjectId,
selectedIndex: 0,
diningStyle: options.diningStyle
})
},
onServiceObjectFinish(e) {
const {
selectedOptions,
value
} = e.detail;
const text = selectedOptions[0].text
// 查对象详情
wx.http('/', { serviceObjectId: value }).then(res => {
this.setData({
enterOrderInfo: res.data,
serviceObjectName: text,
serviceObjectId: value,
serviceObjectShow: false
})
})
},
// 改变菜品数量
onChange(e) {
// type 1列表 2购物车
let { item, type } = e.currentTarget.dataset
let { serviceObjectId, enterOrderInfo } = this.data
let newCount = e.detail; // 获取新的count值
if (serviceObjectId) {
let chooseDish = this.data.chooseDishArr || []
// 数字不为0则push chooseDishArr
if (newCount > 0) {
const dishWithId1 = chooseDish ? chooseDish.find(dish => dish.dishId === item.dishId) : false;
if (dishWithId1) {
dishWithId1.dishCount = newCount;
} else {
// 如果不存在,向数组中添加新对象
const findObj = item
findObj.dishCount = newCount
chooseDish.push(findObj);
}
} else {
// 移除dishCount为0的项目
chooseDish = chooseDish.filter(dish => dish.dishCount !== 0);
}
let newCopy = this.data.dishListCopy ? this.data.dishListCopy.map(dish => {
if (dish.dishId === item.dishId) {
return { ...dish, dishCount: newCount };
}
return dish;
}) : []
let filterChoose = chooseDish ? chooseDish.map(dish => {
if (dish.dishId === item.dishId) {
return { ...dish, dishCount: newCount };
}
return { ...dish };
}) : []
this.setData({
dishListCopy: newCopy,
chooseDishArr: filterChoose,
}, () => {
// 在这里计算总和
let sum = this.data.dishListCopy.reduce((total, dish) => {
return total + (dish.dishCount * dish.dishPrice);
}, 0);
let actual = sum - enterOrderInfo.subsidyAmount * 1
this.setData({
// 注意chooseDishArr要先赋值(上面先赋值),再filter (否则会出现 两个count1 对象A变为0 前端对象B也变为0 实际数字还是1)
chooseDishArr: filterChoose.filter(dish => dish.dishCount !== 0),
sumPayment: sum,
actualPayment: actual < 0 ? 0 : actual,
});
});
}
let newList = this.data.dishListCopy.filter(dish => dish.dishType == this.data.dishType)
this.setData({
dishList: newList
})
// 若购物车中无菜品则关闭
if (type == 2 && this.data.chooseDishArr.length == 0) {
this.setData({
catShow: false
})
}
},
// 字典
getDicts() {
let that = this
return new Promise((resolve, reject) => {
wx.http('/type/' + 'dish_type').then(res => {
// 将套餐移到数组的第一个位置
res.data.sort((a, b) => {
if (a.dictValue == 4) {
return -1;
} else if (b.dictValue == 4) {
return 1;
}
return 0;
});
that.setData({
dishTypeArr: res.data,
selectedIndex: 0,
})
resolve({
code: 200,
dishTypeArr: res.data,
})
})
})
},
// 点击菜品类型
getOrderList(e) {
let { dishListCopy } = this.data
let { value, index } = e.currentTarget.dataset
// 合并两个数组
let arr1 = this.data.dishListCopy || []
let arr2 = this.data.chooseDishArr || []
let arr = arr1.concat(arr2)
// 创建一个 Map 来存储处理后的结果
let dishesMap = new Map();
arr.forEach(dish => {
if (dishesMap.has(dish.dishId)) {
// 如果 dishId 已经存在
let existingDish = dishesMap.get(dish.dishId);
if (dish.dishCount > 0) {
// 如果当前 dish 的 dishCount 不为 0,更新原有对象的 dishCount
existingDish.dishCount = dish.dishCount;
}
} else {
// 如果 dishId 不存在,添加该项到 Map
dishesMap.set(dish.dishId, dish);
}
});
// 将 Map 转换回数组
let finalDishes = Array.from(dishesMap.values());
this.setData({
chooseDishArr: finalDishes.filter(item => item.dishCount != 0),
dishType: value,
dishList: dishListCopy.filter(dish => dish.dishType == value),
selectedIndex: index
});
console.log(this.data.chooseDishArr, 'finalDishes')
},
getList() {
this.getDicts().then(res1 => {
wx.http('/xx/list').then(res => {
let dishes = res.rows.map(dish => {
return {
...dish,
dishCount: 0
};
});
let arr = res1.dishTypeArr || []
this.setData({
dishType: arr[0].dictValue,
dishListCopy: dishes,
dishList: res.rows.filter(dish => dish.dishType == arr[0].dictValue)
})
})
})
},
// 展开购物车
openShoppingCart() {
let { chooseDishArr } = this.data
if (chooseDishArr.length != 0) {
this.setData({
catShow: true
})
} else {
Toast.fail('请选择菜品');
}
},
catClose() {
let { dishType, dishListCopy } = this.data
let newList = dishListCopy.filter(dish => dish.dishType == dishType)
this.setData({
dishList: newList,
catShow: false
}, () => {
console.log('关闭', dishType, this.data.dishList);
});
},
onUnload() {
wx.removeStorageSync('enterOrderInfo');
},
})