素材:
<view>
<text class="gwc">购物车</text>
<text class="gl">管理</text>
</view>
<!-- 生效商品区域 -->
<view class="cart-effect">
<block wx:for="{{cartEffectList}}" wx:key="key" wx:for-item="item">
<checkbox-group class="check-group" wx:if="{{item.merchandises.length > 0}}">
<!-- <checkbox class="check-store-all" data-store="{{item.store}}" bind:tap="checkStoreAll" checked="{{item.checked || item.merchandiseChecked}}">
<view class="store">{{item.store}}</view>
</checkbox> -->
<block wx:for="{{item.merchandises}}" wx:key="key" wx:for-item="merchandise">
<movable-area class="move-area">
<movable-view class="move-view" x="{{merchandise.x}}" data-store="{{item.store}}" data-id="{{merchandise.id}}" direction="horizontal" out-of-bounds="true" damping="50" inertia="true" bind:touchstart="touchStart" bind:touchmove="touchMove" bind:touchend="touchEnd" bindchange="touchChange">
<view class="info">
<checkbox class="merchandise-check" data-store="{{item.store}}" data-merchandise="{{merchandise}}" bind:tap="checkSingle" checked="{{merchandise.checked}}"></checkbox>
<view class="merchandise">
<image class="merchandise-img" src="{{merchandise.imgUrl}}"></image>
<view class="merchandise-name">{{merchandise.name}}</view>
<view class="merchandise-price">¥{{merchandise.price}}</view>
<view class="merchandise-amount">
<view class="minus" data-store="{{item.store}}" data-id="{{merchandise.id}}" bind:tap="minusAmount">-</view>
<view class="amount">{{merchandise.amount}}</view>
<view class="plus" data-store="{{item.store}}" data-id="{{merchandise.id}}" bind:tap="plusAmount">+</view>
</view>
</view>
</view>
</movable-view>
</movable-area>
</block>
</checkbox-group>
</block>
</view>
<!-- 结算 -->
<view class="count">
<checkbox class="check-all" bind:tap="checkAll" checked="{{checkedAll}}">全选</checkbox>
<view class="grand">卷后合计:<text style="color: red;">¥{{total}}</text></view>
<button class="lapse {{totalCount > 0 ? 'settle-btn' : ''}}" bind:tap="settleBill" hover-class="settle-bill" disabled="{{totalCount == 0}}" loading="{{showLoading}}">去结算({{totalCount}})</button>
</view>
page {
padding: 16rpx;
padding-bottom: 172rpx;
box-sizing: border-box;
}
.gwc{
display: flex;
margin-top: 120rpx;
margin-left: 30rpx;
}
.gl{
display: flex;
margin-left: 600rpx;
margin-top: -50rpx;
}
checkbox .wx-checkbox-input{
width: 40rpx;
height: 40rpx;
border-radius: 50%;
}
/* 选中后的背景样式 */
checkbox .wx-checkbox-input.wx-checkbox-input-checked{
background: #b0474c;
}
/* 选中后的勾子样式 */
checkbox .wx-checkbox-input.wx-checkbox-input-checked::before{
width: 40rpx;
height: 40rpx;
line-height: 40rpx;
border-radius: 50%;
text-align: center;
font-size:32rpx;
color:#fbfbfd;
background: transparent;
transform:translate(-50%, -50%) scale(1);
-webkit-transform:translate(-50%, -50%) scale(1);
}
/* 生效商品 */
.cart-effect {
display: flex;
flex-direction: column;
}
.cart-effect .check-group {
padding: 16rpx;
box-sizing: border-box;
border-radius: 32rpx;
margin-top: 16rpx;
z-index: 11;
}
.cart-effect .check-group .check-store-all {
display: flex;
justify-content: flex-start;
align-items: center;
}
.cart-effect .check-group .store {
font-size: 36rpx;
font-weight: bolder;
margin-left: 8rpx;
}
.cart-effect .check-group .move-area{
/* 减去删除部分的宽度 */
width: calc(100% - 128rpx);
height: 280rpx;
position: relative;
display: flex;
}
.cart-effect .check-group .move-area .move-view {
display: flex;
justify-content: center;
align-items: center;
height: 95%;
/* 上面减了多少宽度,下面就要加多少,不然无法起到遮挡作用 */
width: calc(100% + 128rpx);
border-radius: 3%;
background-color: #efeff5;
box-sizing: border-box;
z-index: 10;
padding-right: 12rpx;
}
.cart-effect .check-group .move-area .move-view .info {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
overflow: hidden;
box-sizing: border-box;
}
.cart-effect .check-group .move-area .move-view .info .merchandise {
display: grid;
grid-template-columns: 1fr 2fr 2fr;
grid-template-rows: 110rpx 60rpx;
grid-column-gap: 12rpx;
grid-row-gap: 12rpx;
}
.cart-effect .check-group .move-area .move-view .info .merchandise .merchandise-img {
width: 180rpx;
height: 180rpx;
border-radius: 50%;
grid-column: 1 / 2;
grid-row: 1 / 3;
}
.cart-effect .check-group .move-area .move-view .info .merchandise .merchandise-name {
grid-column: 2 / 4;
grid-row: 1 / 2;
font-size: 32rpx;
}
.cart-effect .check-group .move-area .move-view .info .merchandise .merchandise-price {
grid-column: 2 / 3;
grid-row: 2 / 3;
font-size: 32rpx;
font-weight: 550;
}
.cart-effect .check-group .move-area .move-view .merchandise .merchandise-amount {
grid-column: 3 / 4;
grid-row: 2 / 3;
text-align: right;
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: center;
text-align: center;
line-height: 50rpx;
}
.cart-effect .check-group .move-area .move-view .merchandise .merchandise-amount .minus {
font-size: 42rpx;
background-color: #e5e5e5;
border-radius: 16rpx;
}
.cart-effect .check-group .move-area .move-view .merchandise .merchandise-amount .amount {
font-size: 36rpx;
}
.cart-effect .check-group .move-area .move-view .merchandise .merchandise-amount .plus {
background-color: #e5e5e5;
border-radius: 16rpx;
font-size: 42rpx;
}
.cart-lapse .check-group {
background-color: #fbfbfd;
padding: 16rpx;
box-sizing: border-box;
border-radius: 32rpx;
margin-top: 16rpx;
z-index: 11;
}
.cart-lapse .check-group .move-area .move-view {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
/* 上面减了多少宽度,下面就要加多少,不然无法起到遮挡作用 */
width: calc(100% + 128rpx);
background-color: #fbfbfd;
box-sizing: border-box;
z-index: 10;
padding-right: 12rpx;
}
.cart-lapse .check-group .move-area .move-view .info {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
overflow: hidden;
box-sizing: border-box;
}
.cart-lapse .check-group .move-area .move-view .info .merchandise {
display: grid;
grid-template-columns: 1fr 2fr 2fr;
grid-template-rows: 110rpx 60rpx;
grid-column-gap: 12rpx;
grid-row-gap: 12rpx;
}
.cart-lapse .check-group .move-area .move-view .info .merchandise .sold-out {
position: relative;
width: 180rpx;
height: 180rpx;
border-radius: 50%;
}
.cart-lapse .check-group .move-area .move-view .info .merchandise .sold-out .merchandise-img {
width: 100%;
height: 100%;
border-radius: 50%;
grid-column: 1 / 2;
grid-row: 1 / 3;
}
.cart-lapse .check-group .move-area .move-view .info .merchandise .sold-out .status{
width: 100%;
height: 100%;
background-color: #1a1a1a90;
position: absolute;
top: 0;
left: 0;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
color: #fbfbfb;
font-size: 36rpx;
font-weight: 500;
}
.cart-lapse .check-group .move-area .move-view .info .merchandise .merchandise-name {
grid-column: 2 / 4;
grid-row: 1 / 2;
font-size: 32rpx;
}
.cart-lapse .check-group .move-area .move-view .info .merchandise .merchandise-price {
grid-column: 2 / 3;
grid-row: 2 / 3;
font-size: 32rpx;
font-weight: 550;
}
.cart-lapse .check-group .move-area .move-view .merchandise .merchandise-amount {
grid-column: 3 / 4;
grid-row: 2 / 3;
text-align: right;
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: center;
text-align: center;
line-height: 60rpx;
}
.cart-lapse .check-group .move-area .move-view .merchandise .merchandise-amount .minus {
font-size: 42rpx;
background-color: #e5e5e5;
border-radius: 16rpx;
}
.cart-lapse .check-group .move-area .move-view .merchandise .merchandise-amount .amount {
font-size: 36rpx;
}
.cart-lapse .check-group .move-area .move-view .merchandise .merchandise-amount .plus {
background-color: #e5e5e5;
border-radius: 16rpx;
font-size: 42rpx;
}
.count {
width: calc(100% - 32rpx);
box-sizing: border-box;
margin-top: 16rpx;
padding: 16rpx;
background-color: #fbfbfd;
border-radius: 120rpx;
position: fixed;
bottom: 42rpx;
z-index: 99;
display: flex;
justify-content: space-between;
align-items: center;
border: 1rpx solid #e5e5e5;
}
.count .check-all{
font-size: 34rpx;
font-weight: 550;
}
.count .grand {
width: 50%;
text-align: right;
font-size: 32rpx;
font-weight: 550;
}
.count .lapse {
width: 200rpx;
height: 80rpx;
color: #fdfdfd;
border-radius: 120rpx;
font-size: 33rpx;
margin: 0;
text-align: center;
background-color: #65dd6b;
padding: 0;
line-height: 80rpx;
}
.count .settle-btn {
background-color: #65dd6b;
}
.count .settle-bill {
background-color: #d1362f80
}
Page({
/**
* 页面的初始数据
*/
data: {
cartEffectList: [],
// 生效商品
example: [
{
store: "龙门客栈",
checked: false,
merchandiseChecked: false,
merchandises: [
{
id: "1",
imgUrl: "../../images/pic1.jpg",
name: "车厘茄1kg/盒",
price: 17.9,
amount: 1,
status: 0,
x: 0,
checked: false,
},
{
id: "2",
imgUrl: "../../images/pic2.jpg",
name: "小鸡干脆面烧烤鸡肉味16g*12包",
price: 13.9,
amount: 1,
status: 1,
x: 0,
checked: false,
},
]
},
],
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.getCartList();
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 获取用户购物车
*/
getCartList() {
let cartEffectList = this.data.example;
wx.setStorageSync('cartEffectList', cartEffectList);
this.setData({
cartEffectList: cartEffectList,
});
},
/**
* 店铺全选
* @param {*} e
*/
checkStoreAll(e) {
let storeName = e.currentTarget.dataset.store;
let cartEffectList = this.data.cartEffectList;
let updatedCart = cartEffectList.map(store => {
if (store.store === storeName) {
// 切换商店的已勾选标记
store.checked = !store.checked;
// 重置商店的商品已勾选标记
store.merchandiseChecked = false;
store.merchandises = store.merchandises.map(merch => {
// 根据商店的已检查标记更新商品的已选择标记
merch.checked = store.checked;
return merch;
});
}
return store;
});
this.setData({
cartEffectList: updatedCart
});
this.grand();
},
/**
* 单个选择
* @param {*} e
*/
checkSingle(e) {
let storeName = e.currentTarget.dataset.store;
let merchandiseData = e.currentTarget.dataset.merchandise;
let cartEffectList = this.data.cartEffectList;
let updatedCart = cartEffectList.map(store => {
if (store.store === storeName) {
store.merchandises = store.merchandises.map(merch => {
if (merch.id === merchandiseData.id) {
// 更改商品的选择状态
merch.checked = !merch.checked;
// 更改店铺的选中状态
store.merchandiseChecked = merch.checked;
}
return merch;
});
}
return store;
});
this.setData({
cartEffectList: updatedCart
});
this.grand();
},
/**
* 全选
*/
checkAll() {
let cartEffectList = this.data.cartEffectList;
let checkedAll = this.data.checkedAll;
// 使用map方法更新每个商店和商品的选中状态
let updatedCart = cartEffectList.map(store => {
return {
...store,
checked: !checkedAll,
merchandiseChecked: !checkedAll,
merchandises: store.merchandises.map(merch => ({
...merch,
checked: !checkedAll
}))
};
});
this.setData({
cartEffectList: updatedCart,
checkedAll: !checkedAll,
});
this.grand();
},
/**
* 合计
*/
grand() {
let cartEffectList = this.data.cartEffectList;
// 初始化总价和总数量
let total = 0;
let totalCount = 0;
cartEffectList.forEach(store => {
store.merchandises.forEach(merch => {
if (merch.checked) {
total += merch.amount * merch.price;
totalCount += merch.amount;
}
});
});
this.setData({
total: total,
totalCount: totalCount,
});
},
/**
* 减少数量,下限为1
* @param {*} e
*/
minusAmount(e) {
let storeName = e.currentTarget.dataset.store;
let id = e.currentTarget.dataset.id;
let cartEffectList = this.data.cartEffectList;
let updatedCart = cartEffectList.map(store => {
if (store.store === storeName) {
// 更新商店的已选择商品标记
store.merchandiseChecked = true;
store.merchandises = store.merchandises.map(merch => {
if (merch.id === id) {
// 更新商品的选择状态
merch.checked = true;
if (merch.amount > 1) {
merch.amount--;
} else {
wx.showModal({
content: '宝贝数量不能再减少了',
showCancel: false,
});
}
}
return merch;
});
}
return store;
});
this.setData({
cartEffectList: updatedCart
});
this.grand();
},
/**
* 增加数量,上限为99
* @param {*} e
*/
plusAmount(e) {
let storeName = e.currentTarget.dataset.store;
let id = e.currentTarget.dataset.id;
let cartEffectList = this.data.cartEffectList;
let updatedCart = cartEffectList.map(store => {
if (store.store === storeName) {
// 更新店铺的选中状态
store.merchandiseChecked = true;
store.merchandises = store.merchandises.map(merch => {
if (merch.id === id) {
// 更新商品的选择状态
merch.checked = true;
if (merch.amount < 99) {
merch.amount++;
} else {
wx.showModal({
content: '宝贝数量不能再增加了',
showCancel: false,
});
}
}
return merch;
});
}
return store;
});
this.setData({
cartEffectList: updatedCart
});
this.grand();
},
/**
* 结算
*/
settleBill() {
this.setData({
showLoading: true,
});
// 进行深拷贝
let cartEffectList = JSON.parse(JSON.stringify(this.data.cartEffectList));
// 筛选出未选中的商店或没有选中商品的商店
let filteredStores = cartEffectList.filter(store => {
if (store.checked) {
// 如果商店被选中,保留它
return true;
}
// 从商店中筛选出未选中的商品
store.merchandises = store.merchandises.filter(merch => merch.checked);
// 如果筛选后,商店有选中的商品,保留该商店
return store.merchandises.length > 0;
});
wx.navigateTo({
url: `/pages/index/settle-bill/settle-bill?chosenList=${JSON.stringify(filteredStores)}`,
complete: () => {
this.setData({
showLoading: false,
});
}
});
},
})