微信小程序实现购物车功能
主要功能介绍:登录状态及未登录状态下,将推荐商品加入购物车,购物车数量的加减,及单个商品的删除,移入收藏夹,批量管理: 批量删除,批量移至收藏夹,全选,等功能
新增需求:当在结算状态下:库存不足的商品不可选中,当在管理模式下,库存不足的商品依然可以选中,然后进行操作,管理模式,及结算模式之间切换时保留在当前状态下的操作,不可改变
优化点:当价格位数超出8位,改变显示效果,等
解决方案:商品选中状态,调用接口处理,未登录时,后端生成一个零时uid,用来绑定该微信用户。
cart.wxml文件:
<view class='cart_content'>
<wxs module="filters" src="../../utils/filter.wxs"></wxs>
<view class="transparent_mask" wx:if="{{transparent_mask}}" bindtap="close_mask" catchtouchmove='ture'></view>
<view id="cart-list-wp" bindtap="handleTrans_mask">
<block wx:if="{{cart_list_show && isDataLoading}}">
<view class="administration">
<text wx:if="{{!batchOpt && cart_list.cart_num > 0}}">共{{cart_list.cart_num}}件商品</text>
<text wx:if="{{batchOpt && cart_nums > 0}}">共{{cart_nums}}件商品</text>
<text bindtap="sel_checkbox" data-type="batchOpt" data-sele="{{batchOpt ? 0 : 1}}" wx:if="{{cart_list.cart_list.length > 0}}">{{batchOpt ? '完成' : '管理'}}</text>
</view>
<view class="{{!batchOpt ? 'cart_list_con' : 'cart_list_con1'}}">
<!-- 购物车店铺商品 -->
<view class="bbctouch-cart-container" wx:if="{{cart_list.cart_list.length}}">
<view class="store_pre" wx:for='{{cart_list.cart_list}}' wx:for-index='idstore' wx:key="index">
<view class="store_pre_top" data-store-id='{{item[0]}}'>
<!-- 不可选择 -->
<image src="{{img_url}}site/cart_no_seleted.png" data-type='store' class="store_select" wx:if="{{item[4] == 2 && !batchOpt}}"></image>
<!-- 可选择 -->
<image src="{{item[3]==1 ? img_url + 'site/cart_seleted.png' : img_url + 'site/cartlist_not_sle.png'}}" data-type='store' data-sele='{{item[3]}}' data-store-index='{{idstore}}' class="store_select" catchtap='sel_checkbox' data-storeid="{{item[0]}}" wx:if="{{item[4] != 2 || batchOpt}}"></image>
<view class="store_des" data-store-id="{{item[0]}}" catchtap='go_vendor'>
<image class="store_des_image" src="{{img_url}}site/cart_store.png"></image>
<text class="store_des_text">{{item[1]}}</text>
<image class="store_des_rightdown" src="{{img_url}}site/cart_right.png"></image>
</view>
</view>
<!-- 店铺中的商品 -->
<view class="store_cart_list">
<view class="cart_list_pre" wx:for='{{item[2]}}' cart_id="{{item.cart_id}}" gid="{{item.gid}}" wx:for-index='idgoods' wx:key="index">
<!-- 库存充足 -->
<image class="cart_list_pre_sel" src="{{item['is_check']==1 ? img_url + 'site/cart_seleted.png' : img_url + 'site/cartlist_not_sle.png'}}" data-type='goods' data-sele="{{item['is_check']}}" data-store-index='{{idstore}}' data-gid="{{item.gid}}" data-goods-index='{{idgoods}}' catchtap='sel_checkbox' data-cartid="{{item.cart_id}}" wx:if="{{filters.toNum(item.storage) > 0 || batchOpt}}"></image>
<!-- 库存不足 -->
<image class="cart_list_pre_sel" src="{{img_url}}site/cart_no_seleted.png" wx:if="{{filters.toNum(item.storage) <= 0 && !batchOpt}}"></image>
<view class="list_pre_img" data-goods-id='{{item.gid}}' data-cart-id="{{item.cart_id}}" catchtap='go_goods_detail' bindlongpress="handleLongTap">
<image src="{{item.goods_image_url}}" mode="aspectFit"></image>
</view>
<view class="list_pre_des">
<view class="list_pre_des_name {{item.storage <= 0 ? 'list_pre_des_name1' : ''}}" data-goods-id='{{item.gid}}' catchtap='go_goods_detail' bindlongpress="handleLongTap">{{item.goods_name}}</view>
<!-- 价格的length 小于8 的显示方式 -->
<view class="list_pre_des_bot" wx:if="{{filters.toLength(item.goods_price) < 8}}">
<view class="list_pre_des_price {{filters.toNum(item.storage) <= 0 ? 'list_pre_des_price1' : ''}}">
<text>¥</text>
<text>{{filters.toSplit(item.goods_price)[0]}}</text>.
<text>{{filters.toSplit(item.goods_price)[1]}}</text>
</view>
<view class="list_pre_des_num" wx:if="{{filters.toNum(item.storage) > 0 && isPriceOptShow && !batchOpt}}">
<text data-cart-id='{{item.cart_id||item.gid}}' data-store-index='{{idstore}}' data-s2='{{item.goods_storage}}' data-storage="{{item.storage}}" data-goods-index='{{idgoods}}' data-type='minus' data-gid="{{item.gid}}" catchtap='cart_num' data-value='{{item.goods_num}}'>-</text>
<input type="number" data-cart-id='{{item.cart_id||item.gid}}' data-s2='{{item.goods_storage}}' data-storage="{{item.storage}}" bindblur='cart_num' data-store-index='{{idstore}}' data-gid="{{item.gid}}" data-type='in' data-goods-index='{{idgoods}}' value="{{item.goods_num}}"></input>
<text data-cart-id='{{item.cart_id||item.gid}}' data-gid="{{item.gid}}" data-s2='{{item.goods_storage}}' data-storage="{{item.storage}}" data-store-index='{{idstore}}' data-goods-index='{{idgoods}}' data-type='add' catchtap='cart_num' data-value='{{item.goods_num}}'>+</text>
</view>
<view wx:if="{{filters.toNum(item.storage) <= 0}}" class="insufficient_stock1">库存不足</view>
</view>
<!-- 价格的length 大于等于8 的显示方式 -->
<view class="list_pre_des_bot" wx:if="{{filters.toLength(item.goods_price) >= 8}}">
<view class="list_pre_des_price {{filters.toNum(item.storage) <= 0 ? 'list_pre_des_price1' : ''}}" wx:if="{{!item.price_overrun}}">
<text>¥</text>
<text>{{filters.toSplit(item.goods_price)[0]}}</text>.
<text>{{filters.toSplit(item.goods_price)[1]}}</text>
</view>
<view class="list_pre_des_price {{filters.toNum(item.storage) <= 0 ? 'list_pre_des_price1' : ''}}" wx:else>
<text>¥</text>
<text>{{filters.toSubstring((filters.toSplit(item.goods_price)[0]),0,3)}}</text>...
</view>
<view class="list_pre_des_num" wx:if="{{filters.toNum(item.storage) > 0 && item.price_overrun && !batchOpt}}">
<text data-cart-id='{{item.cart_id||item.gid}}' data-store-index='{{idstore}}' data-s2='{{item.goods_storage}}' data-storage="{{item.storage}}" data-goods-index='{{idgoods}}' data-type='minus' data-gid="{{item.gid}}" catchtap='cart_num' data-value='{{item.goods_num}}'>-</text>
<input type="number" data-cart-id='{{item.cart_id||item.gid}}' data-s2='{{item.goods_storage}}' data-storage="{{item.storage}}" bindblur='cart_num' data-gid="{{item.gid}}" data-store-index='{{idstore}}' data-type='in' data-goods-index='{{idgoods}}' value="{{item.goods_num}}"></input>
<text data-cart-id='{{item.cart_id||item.gid}}' data-s2='{{item.goods_storage}}' data-storage="{{item.storage}}" data-store-index='{{idstore}}' data-goods-index='{{idgoods}}' data-type='add' data-gid="{{item.gid}}" catchtap='cart_num' data-value='{{item.goods_num}}'>+</text>
</view>
<view class="cart_list_close1" wx:if="{{item.price_overrun && !batchOpt}}">
<image src="{{img_url}}site/cart_list_close.png" class="cart_list_close" bindtap="cartListClose" data-cart-id="{{item.cart_id}}"></image>
</view>
<view class="list_pre_num" wx:if="{{item.storage > 0 && !item.price_overrun && !batchOpt}}" data-cart-id="{{item.cart_id}}" bindtap="priceOverrun">*{{item.goods_num}}</view>
<view wx:if="{{item.storage <= 0}}" class="insufficient_stock">库存不足</view>
</view>
</view>
<!-- 单个商品操作 -->
<view class="cart_list_pre_opt" wx:if="{{item.isOpen == true}}" bindtap="hideOpt" data-cart-id="{{item.cart_id}}">
<view class="move_favorites" wx:if="{{key}}" bindtap="batchCollection" data-gid="{{item.gid}}" data-cartid="{{item.cart_id}}" data-type="single">
<text>移至</text>
<text>收藏夹</text>
</view>
<view class="delete_goods" data-cart-id="{{item.cart_id}}" data-gid='{{item.gid}}' data-type="single" catchtap='del_goods' data-storeid="{{item[0]}}">删除</view>
</view>
</view>
</view>
</view>
</view>
<!-- 失效商品 -->
<view class="invalid_goods" wx:if="{{cart_list.lose_cart_list.length}}">
<view class="invalid_goods_top">
<text>失效商品{{cart_list.lose_cart_list.length}}件</text>
<text data-type="invalid" catchtap='del_goods'>清空失效商品</text>
</view>
<view class="invalid_goods_list">
<view class="invalid_goods_pre" wx:for="{{cart_list.lose_cart_list}}" wx:key="index">
<view class="invalid_tips"><text>失</text><text>效</text></view>
<view class="invalid_des">
<view class="invalid_des_img">
<image src="{{item.goods_image_url}}" mode="aspectFit"></image>
</view>
<view class="invalid_des_con">
<view class="invalid_goods_name">{{item.goods_name}}</view>
<view class="invalid_goods_buy">商品已失效,无法购买</view>
</view>
</view>
</view>
</view>
</view>
</view>
</block>
<!-- 购物车无数据-->
<view class="no_cart_goods" wx:if="{{!cart_list_show}}">
<view class="empty">
<image src="{{img_url+'cart_empty.png'}}"></image>
<text class="cart-em">购物车空空如也~</text>
<text>去挑选中意的商品吧</text>
</view>
</view>
<!-- 推荐商品 -->
<view class="pick_goods" wx:if="{{tuijian_goods.length > 0 && isDataLoading && !batchOpt}}">
<view class="pick_goods_top">
<image src="{{img_url}}site/pick_bg.png" />
</view>
<view class="pick_list">
<view class="pick_list_pre" wx:for="{{tuijian_goods}}" wx:key="index">
<image class="pick_list_pre_img" mode="aspectFit" src="{{item.goods_img_url}}" data-goods-id='{{item.gid}}' catchtap='go_goods_detail'></image>
<view class="pick_list_pre_des">
<view class="pick_list_pre_name" data-goods-id='{{item.gid}}' catchtap='go_goods_detail'>{{item.goods_name}}</view>
<view class="pick_lsit_pre_bottom">
<view class="pick_list_pre_price">
<text>¥</text>
<text>{{filters.toSplit(item.goods_price)[0]}}</text>.
<text>{{filters.toSplit(item.goods_price)[1]}}</text>
</view>
<image class="add_cart_list" src="{{img_url}}site/add_cart_list.png" bindtap="add_cartList" data-item="{{item}}" data-gid="{{item.gid}}"></image>
</view>
</view>
</view>
</view>
</view>
<!-- 合计结算 -->
<view class="total_settlement" wx:if="{{cart_list && cart_list.cart_list.length && !batchOpt}}">
<view class="total_settlement_left">
<image src="{{cart_list.is_check==1 ? img_url + 'site/cart_seleted.png' : img_url + 'site/cartlist_not_sle.png'}}" data-type='all' data-sele="{{cart_list.is_check}}" catchtap='sel_checkbox'></image>
<text>全选</text>
</view>
<view class="total_settlement_right">
<view class="total_settlement_price">
<view class="total_settlement_price1">合计:<text>¥{{cart_list.sum ? cart_list.sum : 0}}</text></view>
<view class="total_settlement_freight">不包含运费</view>
</view>
<view class="total_settlement_text grey" wx:if="{{cart_list.checked_num == 0}}">结算({{cart_list.checked_num}})</view>
<view class="total_settlement_text" catchtap='go_confirm_order' wx:else>结算({{cart_list.checked_num}})</view>
</view>
</view>
<!-- 批量移至收藏夹,批量删除 -->
<view class="total_settlement" wx:if="{{cart_list && cart_list.cart_list.length && batchOpt}}">
<view class="total_settlement_left">
<image src="{{cart_list.is_check==1 ? img_url + 'site/cart_seleted.png' : img_url + 'site/cartlist_not_sle.png'}}" data-type='all' data-sele="{{cart_list.is_check}}" catchtap='sel_checkbox'></image>
<text>全选</text>
</view>
<view class="total_settlement_right">
<view class="batch_move" bindtap="batchCollection" wx:if="{{key}}" data-type="batch">移至收藏夹</view>
<view class="batch_del" bindtap="del_goods" data-type="batch">删除</view>
</view>
</view>
<!-- 库存不足的弹框 -->
<view class="insufficient_stock" wx:if="{{insufficient_stock}}">
<view class="insufficient_stock_top">
<view class="insufficient_stock_title">商品库存不足</view>
<image class="insufficient_stock_close" bindtap="close_mask" src="{{img_url}}site/insufficient_stock_close.png"></image>
</view>
<scroll-view class="insufficient_stock_con" scroll-y>
<view class="insufficient_stock_pre" wx:for="{{insufficient_stock_arr}}" wx:key="index">
<text class="insufficient_stock_name">{{item.goods_name}}</text>
<text class="insufficient_stock_num">[剩余库存{{item.goods_storage}}件]</text>
</view>
</scroll-view>
</view>
</view>
</view>
<view class="error-tips" hidden='{{is_show_tip==1?false:true}}'>
{{tip_content}}
</view>
<common title="购物车" />
cart.js文件:
const { adjustTokenMathMLAttrs } = require("../../towxml/lib/parse5");
//获取应用实例
const app = getApp({})
//提示事件
var errorTipsShow = function(that, err_con) {
that.setData({
is_show_tip: 1,
tip_content: err_con
});
setTimeout(function() {
that.setData({
is_show_tip: 0
})
}, 2000);
};
//获取购物车数据
var get_cart_list = function(that, isfirst) {
let key = wx.getStorageSync('token');
let uuid = wx.getStorageSync('uuid')
if(!key){ //未登录
wx.request({
url: app.globalData.ser_url + '/index.php?app=cache_cart&mod=cart_list',
data: {
key: uuid,
cart_type:!that.data.batchOpt ? 'buy' : 'manage'
},
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function(res) {
if(res.data.code == 200){
that.setData({
cart_list: res.data.datas,
batchOpt:that.data.batchOpt ? true : false, //页面刚进入时,不显示批量操作
isPriceOptShow:!that.data.batchOpt ? true : false
});
let cart_list_data = res.data.datas;
if(cart_list_data && (cart_list_data.cart_list.length > 0 || cart_list_data.lose_cart_list.length > 0)){
if(that.data.batchOpt){
that.setData({
cart_nums:cart_list_data.cart_num
})
}
that.setData({
cart_list_show:true,
})
}else{
that.setData({
cart_list_show:false,
batchOpt:false,
})
}
}
},
complete(){
// wx.hideLoading();
}
})
}else{ //已登录
wx.request({
url: app.globalData.ser_url + '/index.php?app=cart&mod=cart_list_store_new',
data: {
key: wx.getStorageSync('token'),
cart_type:!that.data.batchOpt ? 'buy' : 'manage'
},
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function(res) {
if(res.data.code == 200){
if(res.data.datas.cart_list.length == 0){
that.setData({
batchOpt:false
})
}
that.setData({
cart_list: res.data.datas,
batchOpt:that.data.batchOpt ? true : false, //页面刚进入时,不显示批量操作
isPriceOptShow:!that.data.batchOpt ? true : false
});
let cart_list_data = res.data.datas;
if(cart_list_data && (cart_list_data.cart_list.length > 0 || cart_list_data.lose_cart_list.length > 0)){
if(that.data.batchOpt){
that.setData({
cart_nums:cart_list_data.cart_num
})
}
that.setData({
cart_list_show:true,
})
}else{
that.setData({
cart_list_show:false
})
}
}
},
complete(){
// wx.hideLoading();
}
})
}
}
//计算总价事件
var cal_total_price = function(that) {
var data = that.data.cart_list;
var num = 0;
var sel_num = 0;
var cartIds = [];
var gids = [];
if (data.cart_list.length > 0) {
for (var i = 0; i < data.cart_list.length; i++) {
if (data.cart_list[i][2].length > 0) {
for (var j = 0; j < data.cart_list[i][2].length; j++) {
if (data.cart_list[i][2][j]['is_check'] > 0) {
num = num + data.cart_list[i][2][j]['goods_price'] * data.cart_list[i][2][j]['goods_num']
sel_num += 1;
cartIds.push(data.cart_list[i][2][j]['cart_id'])
gids.push(data.cart_list[i][2][j]['gid'])
}
}
}
}
}
data.sum = parseFloat(num).toFixed(2);
that.setData({
cart_list: data,
sel_num:sel_num,
cartIds:cartIds,
gids:gids
});
//如果店铺下的商品库存不足,该商品就不能再勾选了
that.data.cart_list && that.data.cart_list.cart_list &&that.data.cart_list.cart_list.map((item,index)=>{
item[2].map((item1,index1)=>{
if(item1.storage <= 0){
item1.is_sele = 0
}
})
})
that.setData({
cart_list:that.data.cart_list
})
var length = 0;
that.data.cart_list.cart_list.map(item=>{
length += item[2].length
})
that.setData({
settlement_button:!that.data.sel_num ? true : false, //如果结算的数量为0,则,结算按钮置灰
all_goods_num:length //购物车列表中的总商品数量
})
}
Page({
data: {
tip_content: '', //错误提示内容
is_show_tip: 0,
indicatorDots: false,
autoplay: true,
interval: 5000,
duration: 1000,
key: '',
tuijian_goods: {},
cart_list: '',
isloading: true,
img_url: app.globalData.img_url, //图片地址
sel_num:0, //结算,选中的商品总数
batchOpt:false, //批量管理操作
cartIds:[], //批量删除操作的数组
gids:[], //批量移入收藏夹数组
price_overrun:false, //价格是否超过8位
transparent_mask:false, //透明蒙层
settlement_button:false, //结算按钮是否置灰
all_goods_num:0, //购物车列表总数
uuid:'', //未登录,前端自动生成用户唯一标识uuid
isDataLoading:false, //购物车数据是否加载完毕
isPriceOptShow:true, //商品加减的是否显示
insufficient_stock:false, //点击结算库存不足的弹框
insufficient_stock_arr:[], //点击结算,库存不足显示的弹框数据
cart_list_show:true, //购物车列表无数据是否显示,
cart_nums:0, //管理状态下共几件商品
},
onLoad: function(options) {
// 生命周期函数--监听页面加载
//获取token 如果没有跳转登录注册页 否则进入个人中心
if (options.s) {
this.setData({
s: options.s
})
}
// 获取用户唯一标识UUID(规则:客户端类型+下划线+36位唯一字符串uuid)
let key = wx.getStorageSync('token');
let uuid = wx.getStorageSync('uuid');
if(key){
this.setData({
key:'key'
})
}else if(!uuid){
let uuid = app.initUUID('2'); //client 1 h5 ,2 wx_xcx, 3 app
wx.setStorageSync('uuid', uuid)
}else{
let uuid = wx.getStorageSync('uuid')
this.setData({
uuid
})
}
//获取购物车数据
get_cart_list(this);
// 获取推荐商品数据
this.get_tuijian_goods();
//回到页面顶部
this.goTop();
this.setData({
batchOpt:false //页面刚进入,都在结算页面下
})
},
onPageScroll(e){
this.data.cart_list && this.data.cart_list.cart_list && this.data.cart_list.cart_list.map((item,index)=>{
item[2].map((item1,index1)=>{
item1.isOpen = false
})
this.setData({
cart_list:this.data.cart_list,
})
})
},
DataInit(data, num) {
let cart_list = this.data.cart_list;
let store = data.store_info;
let goods_info = data.goods_info;
goods_info.goods_num = num;
goods_info.is_sele = 1;
goods_info.goods_image_url = data.goods_image.split(',')[0];
if (!cart_list) {
cart_list = {
cart_list: [
[store.vid, store.store_name, [goods_info], 1]
],
sum: (parseFloat(goods_info.goods_price) * num).toFixed(2),
total_sel: 1
}
} else {
let vid = store.vid;
let hasvid = false;
for (var i = 0; i < cart_list.cart_list.length; i++) {
let el = cart_list.cart_list[i];
if (el[0] == vid) {
el[2].push(goods_info);
hasvid = true;
break;
}
}
if (!hasvid) {
cart_list.cart_list.push([store.vid, store.store_name, [goods_info], 1])
}
let sum = 0;
cart_list.cart_list.map(el => {
el[2].map(el2 => {
sum = (parseFloat(sum) + parseFloat(el2.goods_price) * parseInt(el2.goods_num)).toFixed(2);
})
})
cart_list.sum = sum;
}
this.setData({
cart_list
})
},
onShow() {
console.info(222);
var key = wx.getStorageSync('token');
let uuid = wx.getStorageSync('uuid');
if (key) {
//将可以存到data里
this.setData({
key: key
})
} else if(uuid){
this.setData({
uuid
})
}else{
let uuid = app.initUUID('2'); //client 1 h5 ,2 wx_xcx, 3 app
wx.setStorageSync('uuid', uuid)
}
console.info(333);
get_cart_list(this);
this.get_tuijian_goods();
//回到页面顶部
this.goTop();
this.setData({
batchOpt:false, //页面刚进入,都在结算页面下
isPriceOptShow:true, //数量编辑操作是否存在
})
},
onHide() {
this.setData({
cart_list: '',
isloading: true
})
},
//商品删除
del_goods: function(e) {
var del_data = this;
let DelData = del_data.data.cart_list.cart_list;
let key = wx.getStorageSync('token')
let uuid = wx.getStorageSync('uuid');
let gid = !key ? e.currentTarget.dataset.gid : e.currentTarget.dataset.cartId;
let storeid = e.currentTarget.storeid; //店铺id
let source_type = e.currentTarget.dataset.type; //商品删除的来源: 单个: single 批量: batch 失效:invalid
//批量选中状态的gid
var DelGids = [];
DelData.map(item=>{
let del_data_goods = item[2].filter(item1=>item1.is_check == 1);
if(del_data_goods.length > 0){
if(!key){
del_data_goods.map(item2=>{
DelGids.push(item2.gid)
})
}else{
del_data_goods.map(item2=>{
DelGids.push(item2.cart_id)
})
}
}
})
//失效商品一键清空 的 登录:cart_id 未登录:gid
var invalidGids = [];
let invalid_data = del_data.data.cart_list.lose_cart_list;
invalid_data.map(item=>{
if(key){
invalidGids.push(item.cart_id)
}else{
invalidGids.push(item.gid)
}
})
if(source_type == 'batch' && DelGids.toString() == ''){ //无选中商品
wx.showToast({
title: '请先选中商品',
icon:'none',
duration:500
})
}else{
var params = {};
if(!key){
params = {
key:uuid,
gid: source_type == 'single' ? gid : source_type == 'batch' ? DelGids.toString() : source_type == 'invalid' ? invalidGids.toString() : ''
}
}else{
params = {
key,
cart_id:source_type == 'single' ? gid : source_type == 'batch' ? DelGids.toString() : source_type == 'invalid' ? invalidGids.toString() : ''
}
}
var url = !key ? '/index.php?app=cache_cart&mod=cart_del' : '/index.php?app=cart&mod=cart_del_new'
wx.request({
url: app.globalData.ser_url + url,
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: params,
success: function(res) {
if (res.data.code == 200) {
wx.showToast({
title: '删除成功',
icon:'none',
duration:500
})
if(!del_data.data.batchOpt){
//重新获取数据
get_cart_list(del_data);
}else{
del_data.del_opt(del_data,source_type,DelData,gid,DelGids);
}
} else {
wx.showModal({
title: '',
content: res.data.error,
showCancel: false,
confirmColor: '#333',
})
}
}
})
}
},
//管理模式下,单个删除,和批量删除 this, 类型来源,购物车列表数据 ,商品的gid或者cart_id, 批量操作选中的商品的gid和cart_id的数组
del_opt(del_data,source_type,DelData,gid,DelGids){
let key = wx.getStorageSync('token');
if(source_type == 'single'){ //单个商品删除
DelData.map((item,index)=>{
if(!key){
item[2].map((item1,index1)=>{
if(item1.gid == gid){
item[2].splice(index1,1)
}
})
if(item[2].length == 0){ //如果该店铺没有商品,就删除该店铺
DelData.splice(index,1)
}
}else{
item[2].map((item1,index1)=>{
if(item1.cart_id == gid){
item[2].splice(index1,1)
}
})
if(item[2].length == 0){ //如果该店铺没有商品,就删除该店铺
DelData.splice(index,1)
}
}
})
}else if(source_type == 'batch'){ //批量删除
DelData.forEach(item=>{
DelGids.forEach(item3=>{
item[2].forEach((item2,index2)=>{
if(!key && item2.gid == item3){
item[2].splice(index2,1)
}else if(key && item2.cart_id == item3){
item[2].splice(index2,1)
}
})
})
})
DelData = DelData.filter(item=>{
return item[2].length > 0
})
}else if(source_type == 'invalid'){ //清空失效商品
//失效商品一键清空
let invalid_data = del_data.data.cart_list.lose_cart_list;
invalid_data = [];
del_data.data.cart_list.lose_cart_list = invalid_data; //失效商品赋值
}
//计算总数量
let cart_nums = 0;
let lose_list_length = 0;
lose_list_length = del_data.data.cart_list.lose_cart_list.length; //失效商品的总数量
cart_nums = DelData.map(item=>{
if(item.length > 0){
return cart_nums + item[2].length
}
})
if(lose_list_length > 0){ //如果有失效商品
cart_nums = cart_nums.length + lose_list_length;
}else{
cart_nums = cart_nums.length;
}
del_data.setData({
cart_nums:cart_nums
})
//购物车中无商品以及无失效商品,就变为结算状态
if(!DelData || DelData.length == 0 && lose_list_length == 0){
del_data.setData({
cart_list_show:!true,
batchOpt:false,
})
}
if(!DelData || DelData.length == 0 && lose_list_length > 0){
del_data.setData({
cart_list_show:true,
batchOpt:true,
})
get_cart_list(del_data)
}
del_data.data.cart_list.cart_list = DelData; //购物车列表数据赋值
del_data.setData({
cart_list:del_data.data.cart_list
})
},
//全选按钮 店铺 商品的复选框事件
sel_checkbox: function(e) {
let key = wx.getStorageSync('token');
this.setData({
key:key
})
let uuid = wx.getStorageSync('uuid') //未登录需要传递uuid,用户的唯一标识
let that = this;
let optData = that.data.cart_list.cart_list;
let is_check = e.currentTarget.dataset.sele; //是否选中
let datatype = e.currentTarget.dataset.type; //复选框的来源,商品,店铺,全选 管理 完成
if(datatype == "goods"){ //单个商品
if(!that.data.batchOpt){
var gid = !key ? e.currentTarget.dataset.gid : e.currentTarget.dataset.cartid; //单个商品的gid(未登录) 单个商品的cart_id(已登录)
}else{
var gid = !key ? e.currentTarget.dataset.gid : e.currentTarget.dataset.cartid; //单个商品的gid(未登录) 单个商品的cart_id(已登录)
optData.map(item=>{
let selGid = item[2].filter(item1=>item1.gid == e.currentTarget.dataset.gid);
if(selGid.length > 0){
selGid[0].is_check = selGid[0].is_check == 1 ? 0 : 1
}
let sel_store = item[2].every(item1=>item1.is_check == 1);
//如果该店铺下所有商品为选中,该店铺为选中状态
item[3] = sel_store ? 1 : 0;
})
//如果所有店铺为选中状态,则全选为选中状态
let noSel = optData.every(item1=>item1[3] == 1);
that.data.cart_list.is_check = noSel ? 1 : 0;
that.data.cart_list.cart_list = optData;
that.setData({
cart_list:that.data.cart_list
})
}
}else if(datatype == "store"){ //选中店铺
if(!that.data.batchOpt){
let storeid = e.currentTarget.dataset.storeid; //当前店铺id
let cur_store_data = optData.filter(item=>item[0] == storeid);
if(cur_store_data.length > 0){
let cur_store_goods = cur_store_data[0][2];
var gids = [];
cur_store_goods.map((item,index)=>{
if(!key){ //未登录,传店铺商品的gid
gids.push(item.gid)
}else{ //已登录,传店铺商品的cart_id
gids.push(item.cart_id)
}
})
}
}else{
let storeid = e.currentTarget.dataset.storeid; //当前店铺id
let cur_store_data = optData.filter(item=>item[0] == storeid);
if(cur_store_data.length > 0){
let cur_store_goods = cur_store_data[0][2];
var gids = [];
cur_store_goods.map((item,index)=>{
if(!key){ //未登录,传店铺商品的gid
gids.push(item.gid)
}else{ //已登录,传店铺商品的cart_id
gids.push(item.cart_id)
}
})
}
// let storeid = e.currentTarget.dataset.storeid;
optData.map(item=>{
if(item[0] == storeid){
item[2].map(item1=>{
item1.is_check = item[3] == 0 ? 1 : 0
})
item[3] = item[3] == 0 ? 1 : 0
}
let noSel = optData.every(item1=>item1[3] == 1);
that.data.cart_list.is_check = noSel ? 1 : 0;
})
that.data.cart_list.cart_list = optData;
that.setData({
cart_list:that.data.cart_list
})
}
}else if(datatype == 'batchOpt'){ //管理--》完成 0 完成--》管理 1
that.setData({
batchOpt:!that.data.batchOpt,
isPriceOptShow : is_check == 1 ? false : true, //商品数量加减的操作,是否显示, 完成页面无,管理页面有
})
get_cart_list(that);
that.goTop();
// if(!that.data.batchOpt){
// get_cart_list(that);
// }else{
// optData.map(item=>{
// item[2].map(item1=>{
// item1.is_check = 0;
// item1.price_overrun = false
// })
// item[3] = 0;
// })
// that.data.cart_list.is_check = 0;
// that.data.cart_list.cart_list = optData;
// that.setData({
// cart_list:that.data.cart_list
// })
// }
}else if(datatype == 'all'){
if(!that.data.batchOpt){
var allGids = [];
optData.map(item=>{
item[2].map(item1=>{
if(!key){
allGids.push(item1.gid)
}else{
allGids.push(item1.cart_id)
}
})
})
}else{
var allGids = [];
optData.map(item=>{
item[2].map(item1=>{
if(!key){
allGids.push(item1.gid)
}else{
allGids.push(item1.cart_id)
}
})
})
optData.map(item=>{
item[2].map(item1=>{
item1.is_check = that.data.cart_list.is_check == 1 ? 0 : 1
})
item[3] = that.data.cart_list.is_check == 1 ? 0 : 1
})
that.data.cart_list.is_check = that.data.cart_list.is_check == 0 ? 1 : 0
that.setData({
cart_list:that.data.cart_list
})
}
// if(!that.data.batchOpt){
// var allGids = [];
// optData.map(item=>{
// item[2].map(item1=>{
// if(!key){
// allGids.push(item1.gid)
// }else{
// allGids.push(item1.cart_id)
// }
// })
// })
// }else{
// optData.map(item=>{
// item[2].map(item1=>{
// item1.is_check = that.data.cart_list.is_check == 1 ? 0 : 1
// })
// item[3] = that.data.cart_list.is_check == 1 ? 0 : 1
// })
// that.data.cart_list.is_check = that.data.cart_list.is_check == 0 ? 1 : 0
// that.setData({
// cart_list:that.data.cart_list
// })
// }
}
//单个商品的选中状态变更 goods 店铺的选中状态的变更 store
var params = {};
// if(!that.data.batchOpt){
if(!key){
params = {
key: uuid,
gids:datatype == "goods" ? gid : datatype == "store" ? gids : datatype == 'all' ? allGids : '',
is_check: is_check == 1 ? 0 : 1
}
}else{
params = {
key: key,
cart_ids:datatype == "goods" ? gid : datatype == "store" ? gids : datatype == 'all' ? allGids : '',
is_check: is_check == 1 ? 0 : 1
}
}
// }
if(params.gids || params.cart_ids){
var url = !key ? '/index.php?app=cache_cart&mod=cart_edit_check' : '/index.php?app=cart&mod=cart_edit_check'
wx.request({
url: app.globalData.ser_url + url,
data: params,
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function(res) {
if (res.data.code == 200) {
if(!that.data.batchOpt){
//重新获取数据
get_cart_list(that);
}
} else {
errorTipsShow(that, res.data.error);
}
}
})
}
},
//数量加减事件
cart_num: function(e) {
var cart_data = this;
var cart_id = e.currentTarget.dataset.cartId;
var ope_type = e.currentTarget.dataset.type;
var tar_num = e.currentTarget.dataset.value;
var storeindex = e.currentTarget.dataset.storeIndex;
var goodsindex = e.currentTarget.dataset.goodsIndex;
var now_input_num = cart_data.data.cart_list.cart_list[storeindex][2][goodsindex].goods_num;
var g_s = e.currentTarget.dataset.storage || e.currentTarget.dataset.s2;
let key =wx.getStorageSync('token');
let uuid = wx.getStorageSync('uuid');
let gid = e.currentTarget.dataset.gid;
if (ope_type == 'minus') { //减
if (now_input_num != 1) {
if(tar_num <= g_s){
tar_num = now_input_num * 1 - 1;
}else{
wx.showToast({
title: '库存不足',
icon:'none',
duration:1000
})
tar_num = g_s;
}
} else {
return;
}
} else if (ope_type == 'in') { //输入
tar_num = e.detail.value * 1;
if (tar_num < 1) {
tar_num = 1;
}else if(tar_num <= g_s && tar_num >= 999){
wx.showToast({
title: '超过购买上限',
icon:'none',
duration:1000
})
tar_num = 999
}else if(tar_num > g_s){
wx.showToast({
title: '库存不足',
icon:'none',
duration:1000
})
tar_num = g_s;
}
var cart_list = cart_data.data.cart_list;
cart_data.setData({
cart_list: cart_list
});
} else { //加
if(tar_num >= 999){
wx.showToast({
title: '超过购买上限',
icon:'none',
duration:1000
})
tar_num = 999
}else{
if(tar_num <= g_s){
tar_num = now_input_num * 1 + 1;
}else{
wx.showToast({
title: '库存不足',
icon:'none',
duration:1000
})
tar_num = g_s;
}
}
var cart_list = cart_data.data.cart_list;
cart_data.setData({
cart_list: cart_list
});
}
if (tar_num <= g_s) {
if (!key) { // 离线状态 购物车商品数量变更
wx.request({
url: app.globalData.ser_url + '/index.php?app=cache_cart&mod=cart_edit_quantity',
data: {
key:uuid,
gid:gid,
quantity: tar_num
},
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: function(res) {
if (res.data.code == 200) {
//更新数量
var cart_list = cart_data.data.cart_list;
cart_list.cart_list[storeindex][2][goodsindex]['goods_num'] = tar_num;
cart_list.sum = res.data.datas.total_price;
cart_data.setData({
cart_list: cart_list
});
} else {
errorTipsShow(cart_data, res.data.error);
}
}
})
return;
}else{ //登录之后
wx.request({
url: app.globalData.ser_url + '/index.php?app=cart&mod=cart_edit_quantity_xcx',
data: {
key: key,
cart_id: cart_id,
quantity: tar_num
},
header: {
'content-type': 'application/json' // 默认值
},
success: function(res) {
if (res.data.state == 200) {
//更新数量
var cart_list = cart_data.data.cart_list;
cart_list.cart_list[storeindex][2][goodsindex]['goods_num'] = tar_num;
cart_data.setData({
cart_list: cart_list
});
cal_total_price(cart_data);
} else {
errorTipsShow(cart_data, res.data.error);
}
}
})
}
} else {
wx.showToast({
title: '库存不足',
duration:700,
icon:'none'
})
}
},
get_input_num: function(e) {},
//进入店铺事件
go_vendor: function(e) {
if (getCurrentPages().length > 8) {
wx.redirectTo({
url: '/pages/shopHomePage/shopHomePage?vid=' + e.currentTarget.dataset.storeId
})
} else {
wx.navigateTo({
url: '/pages/shopHomePage/shopHomePage?vid=' + e.currentTarget.dataset.storeId
})
}
},
//进入商品详情页事件
go_goods_detail: function(e) {
if (getCurrentPages().length > 8) {
wx.redirectTo({
url: '../goods_detail/goods_detail?gid=' + e.currentTarget.dataset.goodsId
})
} else {
wx.navigateTo({
url: '../goods_detail/goods_detail?gid=' + e.currentTarget.dataset.goodsId
})
}
},
//去结算事件
go_confirm_order: function(e) {
let key = wx.getStorageSync('token');
let that = this;
if (!key) {
app.goLogin();
return;
}else{
let cart_list_data = that.data.cart_list.cart_list;
var cart_ids = ''; //选中的商品cart_id
cart_list_data.map(item=>{
item[2].map(item1=>{
if(item1.is_check == 1){
if(cart_ids == ''){
cart_ids = item1.cart_id + '|' + item1.goods_num
}else{
cart_ids = cart_ids + ',' + (item1.cart_id + '|' + item1.goods_num)
}
}
})
})
wx.request({
url: app.globalData.ser_url + '/index.php?app=buy&mod=checkBuyCart',
data: {
key: key,
cart_id:cart_ids, //格式:购物车id|商品数量,购物车id|商品数量,如768|1,761|1
},
header: {
'content-type': 'application/json' // 默认值
},
success: function(res) {
if(res.data.code == 200 && res.data.datas.state == 'suc'){ //成功,可以去结算
var t = [];
for (var i = 0; i < that.data.cart_list.cart_list.length; i++) {
for (var j = 0; j < that.data.cart_list.cart_list[i][2].length; j++) {
if (that.data.cart_list.cart_list[i][2][j].is_check == 1) {
var a = that.data.cart_list.cart_list[i][2][j].cart_id;
var e = parseInt(that.data.cart_list.cart_list[i][2][j].goods_num);
var r = a + "|" + e;
t.push(r)
}
}
}
if (t.length > 0) {
var a = t.toString();
wx.navigateTo({
url: '../confirm_order/confirm_order?ifcart=1&cart_id=' + a
})
} else {
errorTipsShow(that, '请先选中商品');
}
}else if(res.data.code == 200 && res.data.datas.error_code == 'storage_empty_error'){ //有库存不足的商品
that.setData({
insufficient_stock:true,
insufficient_stock_arr:res.data.datas.data,
transparent_mask:true
})
}else if(res.data.code == 200 && res.data.datas.error_code == 'goods_error'){ //商品信息发生了变化,请刷新购物车
wx.showModal({
title:'提示',
content:'商品信息发生变化,请刷新购物车重新结算',
showCancel:false, //不显示取消按钮
confirmColor:'#FB1B1B',
success:function(res){
if (res.confirm) {
//获取购物车数据
get_cart_list(that);
// 获取推荐商品数据
that.get_tuijian_goods();
}
}
})
}
}
})
}
},
// 获取推荐商品数据
get_tuijian_goods: function(e) {
let key = wx.getStorageSync('token');
var that = this;
wx.request({
url: app.globalData.ser_url + '/index.php?app=goods&mod=getRecGoodsList',
data: {
key: key
},
header: {
'content-type': 'application/json' // 默认值
},
success: function(res) {
if(res.data.code == 200){
var goods_list = res.data.datas.goods_list;
that.setData({
tuijian_goods: goods_list,
isDataLoading:true //购物车数据是否加载完毕
});
let gids = [];
goods_list && goods_list.forEach(el => {
gids.push(el.gid);
})
}
}
});
},
//价格超出
priceOverrun(e){
let that = this;
let cartId = e.currentTarget.dataset.cartId;
that.data.cart_list.cart_list.map((item,index)=>{
item[2].map((item1,index1)=>{
if(item1.cart_id == cartId){
item1.price_overrun = true
}else{
item1.price_overrun = false
}
})
that.setData({
cart_list:that.data.cart_list
})
})
},
//关闭当前这个价格超出的数量加减的关闭按钮
cartListClose(e){
let that = this;
let cartId = e.currentTarget.dataset.cartId;
that.data.cart_list.cart_list.map((item,index)=>{
item[2].map((item1,index1)=>{
if(item1.cart_id == cartId){
item1.price_overrun = false
}else{
item1.price_overrun = false
}
})
that.setData({
cart_list:that.data.cart_list
})
})
},
//点击透明蒙层,影藏透明蒙层,及单个商品呢的操作
handleTrans_mask(){
let that = this;
that.data.cart_list && that.data.cart_list.cart_list && that.data.cart_list.cart_list.map((item,index)=>{
item[2].map((item1,index1)=>{
item1.isOpen = false
})
that.setData({
cart_list:that.data.cart_list
})
})
},
//长按事件, 操作单个商品:移至收藏夹 ,删除
handleLongTap(e){
let that = this;
let key = wx.getStorageSync('token');
let cartId = e.currentTarget.dataset.cartId;
let goodsId = e.currentTarget.dataset.goodsId;
that.setData({
key:key
})
that.data.cart_list.cart_list.map((item,index)=>{
item[2].map((item1,index1)=>{
if(item1.gid == goodsId){
item1.isOpen = true
}else{
item1.isOpen = false
}
})
that.setData({
cart_list:that.data.cart_list
})
})
},
//隐藏单个商品的批量操作框
hideOpt(e){
let that = this;
let cartId = e.currentTarget.dataset.cartId;
that.data.cart_list.cart_list.map((item,index)=>{
item[2].map((item1,index1)=>{
if(item1.cart_id == cartId){
item1.isOpen = false
}else{
item1.isOpen = false
}
})
that.setData({
cart_list:that.data.cart_list,
})
})
},
//加入购物车
add_cartList(e){
let that = this;
let key = wx.getStorageSync('token');
that.setData({
key
})
let uuid = wx.getStorageSync('uuid')
let gid = e.currentTarget.dataset.gid;
var item = e.currentTarget.dataset.item;
if (!key) { //未登录
let url = app.globalData.ser_url + '/index.php?app=cache_cart&mod=cart_add';
wx.request({
url,
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: {
key:uuid,
is_from_live:'0', //是否来自直播:0否1是
gid,
quantity:1 //数量
},
success: function (res) {
if(res.data.code == 200 && res.data.datas.status == '1'){
wx.showToast({
title:'添加成功',
duration:500,
icon:'success'
})
//一键回到页面顶部
that.goTop();
get_cart_list(that);
}else{
wx.showToast({
title: res.data.datas.msg,
duration:500,
icon:'none'
})
}
}
})
} else { //已登录
let url = app.globalData.ser_url + '/index.php?app=cart&mod=cart_add';
wx.request({
url,
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: {
key,
is_from_live:'0', //是否来自直播:0否1是
gid,
quantity:1 //数量
},
success: function (res) {
if(res.data.code == 200 && res.data.datas.status == true){
wx.showToast({
title:'添加成功',
duration:500,
icon:'success'
})
//一键回到页面顶部
that.goTop();
get_cart_list(that);
}else{
wx.showToast({
title: res.data.datas.msg,
icon:'none',
duration:500
})
}
}
})
}
},
//移至收藏夹 单个, 批量
batchCollection(e){
let that = this;
let key = wx.getStorageSync('token');
let cartid = e.currentTarget.dataset.cartid; //单个商品cart_id
let source_type = e.currentTarget.dataset.type;
//批量商品cart_id
let cartlistData = that.data.cart_list.cart_list;
var batchCartIds = [];
cartlistData.map(item=>{
let collection_data_goods = item[2].filter(item1=>item1.is_check == 1);
collection_data_goods.map(item2=>{
batchCartIds.push(item2.cart_id)
})
})
if(source_type == 'batch' && batchCartIds.toString() == ''){ //无选中商品
wx.showToast({
title: '请先选中商品',
icon:'none',
duration:500
})
}else{
let url = app.globalData.ser_url + '/index.php?app=cart&mod=followgoods';
wx.request({
url,
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: {
key,
cart_id:source_type == 'single' ? cartid : source_type == 'batch' ? batchCartIds.toString() : ''
},
success: function (res) {
if(res.data.code == 200){
wx.showToast({
title: res.data.datas.msg,
icon:'none',
duration:500
})
}
if(!that.data.batchOpt){
get_cart_list(that);
}else{
that.del_opt(that,source_type,cartlistData,cartid,batchCartIds);
}
if(source_type == 'batch'){
that.goTop(); //回到顶部
}
}
})
}
},
//关闭弹出商品库存不足的蒙层
close_mask(){
this.setData({
transparent_mask:false,
insufficient_stock:false
})
},
//一键回到页面顶部
goTop(){
//回到页面顶部
if (wx.pageScrollTo) {
wx.pageScrollTo({
scrollTop: 0
})
} else {
wx.showModal({
title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
}
}
})
效果图: