微信小程序——购物车面向对象逻辑编写

微信小程序——购物车面向对象逻辑编写

业务逻辑:

我们要在微信小程序客户端中构造购物车,实现对购物车的增加商品、删除商品、修改商品数量、查询购物车商品等操作,即对应增删改查操作

逻辑架构分析

缓存(前端数据库)

我们需要一个数据库来储存购物车里的数据,在微信小程序中缓存提供了API接口,我们可以调用微信小程序的缓存来存储购物车中的数据;

模型层(与缓存交互)

模型层将用于与购物车有关的读取、更新、插入缓存的业务逻辑编写,还有一些计算总数、总价等等方法;

控制器层(控制数据驱动wxml)

调用模型层的方法,将数据打印打wxml

业务需求分析

在这里插入图片描述

业务代码编写

接下来将一一分析每个业务逻辑的代码编写

添加商品

用户在商品详情界面时,会将商品加入到购物车,然后进行购买。

控制层
 onAddingToCartTap:function(){
    this.addToCart();
    var counts=this.data.cartTotalCounts+this.data.productCounts;
    this.setData({
      cartTotalCounts: counts
    })
  },
addToCart:function(){
    var tempObj = {}, keys = ['id', 'name', 'main_img_url', 'price'];
    for (var key in this.data.product) {
      if (keys.indexOf(key) >= 0) {
        tempObj[key] = this.data.product[key];
      }
    }
    cart.add(tempObj, this.data.productCounts);
  },

在控制中调用

addToCart方法,将商品的信息组装成新的字典:先定义我们需要的key和新的字典对象tempObject,然后遍历product中的key,判断key是否存在于keys中,如果存在,我们就重新在tempObject中组装一个键值对。然后调用cart.add方法,该方法将在后面详述;

因为本业务还需要显示购物车的实时商品数量,所以这里还需要将购物车的商品数量加上刚刚添加的商品数量,重新绑定数据。

模型层

cart.add方法:

/*
    * 加入到购物车
    * 如果之前没有样的商品,则直接添加一条新的记录, 数量为 counts
    * 如果有,则只将相应数量 + counts
    * @params:
    * item - {obj} 商品对象,
    * counts - {int} 商品数目,
    * */
  add(item, counts) {
    var cartData = this.getCartDataFromLocal();
    if (!cartData) {
      cartData = [];
    }
    var isHadInfo = this._isHasThatOne(item.id, cartData);
    //新商品
    if (isHadInfo.index == -1) {
      item.counts = counts;
      item.selectStatus = true;  //默认在购物车中为选中状态
      cartData.push(item);
    }
    //已有商品
    else {
      cartData[isHadInfo.index].counts += counts;
    }
    this.execSetStorageSync(cartData);  //更新本地缓存
    return cartData;
  };

在该方法中,我们要将控制层接收的商品信息item存入到缓存中:

首先,我们得读取原本缓存中的商品信息,调用方法getCartDataFromLocal();

如果缓存中没有购物车的数据就重新新建数组,给传入的字典对象设置新的键值对数目和选择状态,然后插入到购物车数组中。最后再将购物车数组同步到缓存中execSetStorageSync(cartData);

如果缓存中有购物车的数据,就读出然后再调用_isHasThatOne方法传入id和购物车数组来判断该id的商品是否已经存在该数据库中,如果存在,会得到index,然后根据index就直接在数组中索引对应的index下标下的商品数目上更新即可,如果不存在就得设置新的键值对数目和选择状态,然后插入到购物车数组中。最后再将购物车数组同步到缓存中execSetStorageSync(cartData);

 /*
    * 获取购物车
    * param
    * flag - {bool} 是否过滤掉不下单的商品
    */
  getCartDataFromLocal(flag) {
    var res = wx.getStorageSync(this._storageKeyName);
    if (!res) {
      res = [];
    }
    //在下单的时候过滤不下单的商品,
    if (flag) {
      var newRes = [];
      for (let i = 0; i < res.length; i++) {
        if (res[i].selectStatus) {
          newRes.push(res[i]);
        }
      }
      res = newRes;
    }

    return res;
  };
/*购物车中是否已经存在该商品*/
  _isHasThatOne(id, arr) {
    var item,
      result = { index: -1 };
    for (let i = 0; i < arr.length; i++) {
      item = arr[i];
      if (item.id == id) {
        result = {
          index: i,
          data: item
        };
        break;
      }
    }
    return result;
  };
 /*本地缓存 保存/更新*/
  execSetStorageSync(data) {
    wx.setStorageSync(this._storageKeyName, data);
  };

getCartDataFromLocal(flag)方法分两种情况获得购物车数据,一种是获得选中商品的数据,另一种是获得全部商品的数据。

以上代码不再赘述,自行理解;

查看所有商品

 onShow: function () {
    var cartData = cart.getCartDataFromLocal(),
      countsInfo = cart.getCartTotalCounts(true);
    this.setData({
      selectedCounts: countsInfo.counts1,
      selectedTypeCounts: countsInfo.counts2,
      account: this._calcTotalAccountAndCounts(cartData).account,
      cartData: cartData
    });
  },

我们需要利用getCartDataFromLocal方法将购物车的数据读出

同时计算选中商品的数目cart.getCartTotalCounts(true);

然后再计算其价格_calcTotalAccountAndCounts(cartData);

最后完成绑定数据

 /* 计算购物车商品数据*/
  _calcTotalAccountAndCounts: function (data) {
    var len = data.length,
      account = 0,
      selectedCounts = 0,
      selectedTypeCounts = 0;
    let multiple = 100;
    for (let i = 0; i < len; i++) {
      //避免 0.05 + 0.01 = 0.060 000 000 000 000 005 的问题,乘以 100 *100
      if (data[i].selectStatus) {
        account += data[i].counts * multiple * Number(data[i].price) * multiple;
        selectedCounts += data[i].counts;
        selectedTypeCounts++;
      }
    }
    return {
      selectedCounts: selectedCounts,
      selectedTypeCounts: selectedTypeCounts,
      account: account / (multiple * multiple)
    }
  },

_calcTotalAccountAndCounts方法完成对选中商品数据的计算,首先还是对商品的状态进行判定,如果是选中的情况,那么就累加其价格和数目,还有商品种类。最后进行返回。计算价格前先乘以100是为了防止js的浮点运算的误差。

修改商品数目

前端代码

<view class="btns {{item.counts==1?'disabled':''}}" bindtap="changeCounts" 
										data-id="{{item.id}}" data-type="cut">-</view>
<view class="counts">{{item.counts}}</view>
<view class="btns" bindtap="changeCounts" data-id="{{item.id}}" data-type="add">+</view>
 /*调整商品数目*/
  changeCounts: function (event) {
    var id = cart.getDataSet(event, 'id'),
      type = cart.getDataSet(event, 'type'),
      index = this._getProductIndexById(id),
      counts = 1;
    if (type == 'add') {
      cart.addCounts(id);
    } else {
      counts = -1;
      cart.cutCounts(id);
    }
    //更新商品页面
    this.data.cartData[index].counts += counts;
    this._resetCartData();
  },

在这里我们需要更新购物车商品的数量,首先我们得获得商品的id和商品是加是减,然后根据商品id找到该id在购物车数组中的下标**_getProductIndexById**(),并返回,然后根据下标和加减type来进行操作cart.addCounts(id);,更新缓存中的数据和页面数据,最后更新购物车的商品数据**_resetCartData**()。

  /*根据商品id得到 商品所在下标*/
  _getProductIndexById: function (id) {
    var data = this.data.cartData,
      len = data.length;
    for (let i = 0; i < len; i++) {
      if (data[i].id == id) {
        return i;
      }
    }
  },

/*更新购物车商品数据*/
  _resetCartData: function () {
    var newData = this._calcTotalAccountAndCounts(this.data.cartData); /*重新计算总金额和商品总数*/
    this.setData({
      account: newData.account,
      selectedCounts: newData.selectedCounts,
      selectedTypeCounts: newData.selectedTypeCounts,
      cartData: this.data.cartData
    });
  },

cart.addCounts(id);

  addCounts(id) {
    this._changeCounts(id,1);
  };
  cutCounts(id) {
    this._changeCounts(id, -1);
  };
  /*
    * 修改商品数目
    * params:
    * id - {int} 商品id
    * counts -{int} 数目
    * */
  _changeCounts(id, counts) {
    var cartData = this.getCartDataFromLocal(),
      hasInfo = this._isHasThatOne(id, cartData);
    if (hasInfo.index != -1) {
      if (hasInfo.data.counts > 1) {
        cartData[hasInfo.index].counts += counts;
      }
    }
    this.execSetStorageSync(cartData);  //更新本地缓存
  };

这里的业务逻辑就是获得控制层得到的商品id还有加减指令,然后传入到_changeCounts()中,在该方法中获得购物车所有商品数据,然后根据id查找出在购物车商品数组中的下标,如果下标存在,就利用数组索引完成加减操作,最后更新到缓存中。

删除商品

/*删除商品*/
  delete: function (event) {
    var id = cart.getDataSet(event, 'id'),
      index = this._getProductIndexById(id);
    this.data.cartData.splice(index, 1);//删除某一项商品

    this._resetCartData();
    //this.toggleSelectAll();

    cart.delete(id);  //内存中删除该商品
  },

获得商品的id,然后根据id获得购物车数组下标,最后先在控制器数据中删去,更新购物车数据,然后再调用

cart.delete(id); 实现缓存中同步删除。

delete(ids) {
    if (!(ids instanceof Array)) {
      ids = [ids];
    }
    var cartData = this.getCartDataFromLocal();
    for (let i = 0; i < ids.length; i++) {
      var hasInfo = this._isHasThatOne(ids[i], cartData);
      if (hasInfo.index != -1) {
        cartData.splice(hasInfo.index, 1);  //删除数组某一项
      }
    }
    this.execSetStorageSync(cartData);
  }

在model层中对缓存中指定的商品数据进行删除。

商品选择

前端

<view   class="cart-item-checkbox" ontap="toggleSelect" data-id="{{item.id}}" data-status="{{item.selectStatus}}">
<image wx:if="{{item.selectStatus}}" src="../../imgs/icon/circle@selected.png"></image>
<image wx:else src="../../imgs/icon/circle@noselected.png"></image>
</view>

控制器

/*选择商品*/
  toggleSelect: function (event) {
    var id = cart.getDataSet(event, 'id'),
      status = cart.getDataSet(event, 'status'),
      index = this._getProductIndexById(id);
    this.data.cartData[index].selectStatus = !status;
    this._resetCartData();
  },
  /*全选*/
  toggleSelectAll: function (event) {
    var status = cart.getDataSet(event, 'status') == 'true';
    var data = this.data.cartData,
      len = data.length;
    for (let i = 0; i < len; i++) {
      data[i].selectStatus = !status;
    }
    this._resetCartData();
  },

保存商品选择状态到缓存中

/**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    cart.execSetStorageSync(this.data.cartData);
  },

tus = cart.getDataSet(event, ‘status’) == ‘true’;
var data = this.data.cartData,
len = data.length;
for (let i = 0; i < len; i++) {
data[i].selectStatus = !status;
}
this._resetCartData();
},


保存商品选择状态到缓存中

```js
/**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    cart.execSetStorageSync(this.data.cartData);
  },

总结:购物车的业务逻辑有点像后端逻辑,需要缓存作为数据库,而任何逻辑必须要做的几步就是,从缓存中读出数据,然后根据商品id找出缓存数组中的下标,此外进行任何修改时,都需要保证控制层的数据和缓存同步。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值