微信小程序简陋购物车(逻辑什么的都有)

关于样式丑的说法,自行改成好看的就好

<style lang="less">
page {
  background: #f4f4f4;
}

.cart-top {
  background: #fff;
  .receive {
    padding: 20rpx;
    display: flex;
    justify-content: space-between;
  }
  .address {
    padding: 0 20rpx 20rpx;
  }
  .address-bar {
    display: block;
    width: 750rpx;
    height: 15rpx;
  }
}

.list-title {
  border-top: 20rpx #f4f4f4 solid;
  padding: 20rpx;
  border-bottom: 1px #dddddd solid;
  background: #fff;
}

.ware-list {
  padding-bottom: 80rpx;
  background: #fff;
}
.ware-item {
  display: flex;
  padding: 0 20rpx;
}
.choice-button {
  width: 70rpx;
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
.ware-content {
  display: flex;
  flex: 1;
  padding: 20rpx 0;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px #f5f5f5 solid;

  .ware-image {
    margin-right: 20rpx;
    image {
      display: block;
      width: 160rpx;
      height: 160rpx;
    }
  }
  .ware-title {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    margin-bottom: 20rpx;
  }

  .ware-info {
    flex: 1;
  }

  .ware-info-btm {
    display: flex;
    justify-content: space-between;
    .ware-price {
      font-size: 18px;
      color: #ff6066;
      span {
        font-size: 12px;
      }
    }
  }
}

.cart-total {
  background: #fff;
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 95rpx;
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;

  .total-button {
    box-sizing: border-box;
    padding-left: 20rpx;
    margin-right: 50rpx;
    display: flex;
    align-items: center;

    icon {
      margin-right: 20rpx;
    }
  }

  .total-center {
    flex: 1;
    .colorRed {
      text {
        font-size: 12px;
      }
    }

    .price-tips {
      color: #999;
      font-size: 12px;
    }
  }

  .accounts {
    flex-shrink: 0;
    width: 230rpx;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #ff6066;
    color: #fff;
  }
}
.calculate {
  display: flex;
  .rect {
    width: 50rpx;
    height: 50rpx;
    line-height: 50rpx;
    border: 1px #666 solid;
    text-align: center;
  }
  .number {
    line-height: 50rpx;
    width: 90rpx;
    padding: 5rpx;
    box-sizing: border-box;
    text-align: center;
  }
}

.cart-empty {
  padding: 20rpx;
  background: #fff;
  text-align: center;
}

.empty{
  display: flex;
  padding:100rpx 0;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  
  image{
    width:120rpx;
    height:120rpx;
    margin-bottom:50rpx;
  }
}
</style>
<template>
  <view class="container">

    <view wx:if="{{cartData.length > 0}}">
      <!-- 收货人信息 -->
      <view class="cart-top" wx:if="{{address.addr}}">
        <view class="receive">
          <view class="name">
            收货人: {{address.userName}}
          </view>
          <view class="phonen-number">
            {{address.telNumber}}
          </view>
        </view>
        <view class="address">
          收货地址: {{address.addr}}
        </view>
        <image src="../images/[email protected]" class="address-bar">
      </view>

      <view class="cart-empty" wx:if="{{!address.addr}}" bindtap="handleAddress">
        添加地址 
      </view>

      <view class="list-title">
        优购生活馆
      </view>

      <!-- 购物车列表 -->
      <view class="ware-list">
        <view wx:for="{{cartData}}" wx:key="{{index}}">
          <view class="ware-item">

          <!-- 左侧的按钮 -->
            <view class="choice-button" @tap="handleSelect({{item}})">
              <icon type="success" color="{{item.checked ? 'red' : '#999'}}" size="18"/>
            </view>

            <view class="ware-content">

                <!-- 左侧的图片 -->
              <navigator class="ware-image" url="/pages/goods_detail?goods_id={{item.goods_id}}">
                <image src="{{item.goods_small_logo}}"/>
              </navigator>

              <!-- 右边的商品信息 -->
              <view class="ware-info">
                <navigator url="/pages/goods_detail?goods_id={{item.goods_id}}" class="ware-title">
                  {{item.goods_name}}
                </navigator>
                <view class="ware-info-btm">
                  <view class="ware-price">
                    <span></span>{{item.goods_price}}
                  </view>

                  <!-- 修改商品的数量 -->
                  <view class="calculate">
                    <view class="calculate">
                      <view class="rect" @tap="handleCompouted({{item}}, -1)">-</view>
                      <view class="number">{{item.count}}</view>
                      <view class="rect" @tap="handleCompouted({{item}}, 1)">+</view>
                    </view>
                  </view>
                </view>
              </view>

            </view>
          </view>
        </view>
      </view>

      <!-- 结算 -->
      <view class="cart-total">
        <view class="total-button" @tap="handleAllSelect">
          <icon type="success" color="{{allSelect ? 'red' : '#999'}}" size="18"/>全选
        </view>
        <view class="total-center">
          <view class="total-price">
            合计: 
            <text class="colorRed">
              <text></text>{{allPrice}}
            </text>
          </view>
          <view class="price-tips">
            包含运费
          </view>
        </view>
        <view class="accounts" bindtap="handleSubmit" >
          结算({{allCount}})
        </view>
      </view>
    </view>
    <!-- 购物车数量为空的时候 -->
    <view class="empty" wx:if="{{cartData.length == 0}}" >
      <image src="../images/[email protected]"/>
      购物车为空
    </view>
  </view>
</template>

<script>
import wepy from 'wepy';
import cartManage from '../utils/cartManage';
import request from '../utils/request';
import authManage from '../utils/authManage';

/*
  1. 从商品详情页添加到购物车 cartManage.add
  2. 动态修改购物车的总价格  cartManage.updatePrice
  3. 修改购物车商品的选中状态 cartManage.update
  4. 修改购物车商品全选的状态 cartManage.updataAllChecked
  5. 修改购物车商品的数量  cartManage.update
*/

export default class Cart extends wepy.page {
  config = {
    navigationBarTitleText: '搜索'
  };

  data = {
    // 存储购物车列表,默认是空数组
    cartData: (cartManage.data && cartManage.data.goods) || [],
    allSelect: true,
    allPrice: 0,
    address: {
      userName: '',
      telNumber: '',
      addr: ''
    },
    allCount: cartManage.data.allCount
  };

  onShow() {

    this.updateData();

    // 页面打开时候判断是否是全选
    this.cartData.forEach(v => {
      if (!v.checked) {
        this.allSelect = false;
      }
    });
  }

  // 判断是否是全选
  isAllSelelct() {
    const { cartData } = this;

    // 只要有一个商品没选中, 取消全选状态
    for (let i = 0, v; (v = cartData[i++]); ) {
      if (!v.checked) {
        this.allSelect = false;
        return;
      }

      this.allSelect = true;
    }
  }

  // 更新data数据
  updateData() {
    // 更新data的数据
    this.cartData = cartManage.data.goods;

    // 更新价格
    this.allPrice = cartManage.data.allPrice;

    // 更新总数
    this.allCount = cartManage.data.allCount;
  }

  methods = {
    handleCompouted: function(item, num) {
      item.count += Number(num);

      if (item.count == 0) {
        //  调用对话弹窗 wx.showModal
        wx.showModal({
          content: '确定删除商品吗?',
          success: res => {
            if (res.confirm) {
              // 点击确定就删除商品
              cartManage.remove(item);
              this.updateData();
              this.$apply();
            }
          }
        });
      } else {
        cartManage.update(item);
        this.updateData();
      }
    },

    handleSelect: function(item) {
      item.checked = !item.checked;

      cartManage.update(item);

      this.updateData();

      // 判断是否是全部选中
      this.isAllSelelct();
    },

    // 点击全选时候触发
    handleAllSelect: function() {
      const { allSelect } = this;
      this.allSelect = !allSelect;

      cartManage.updataAllChecked(this.allSelect);

      // 更新价格
      this.allPrice = cartManage.data.allPrice;
    },

    // 添加收货地址
    handleAddress: function() {
      wx.chooseAddress({
        success: res => {
          this.address = {
            userName: res.userName,
            telNumber: res.telNumber,
            addr: `${res.provinceName}${res.cityName}${res.countyName}${
              res.detailInfo
            }`
          };

          // 把收货地址存到本地
          cartManage.addAddr(this.address);
          this.$apply();
        }
      });
    },

    // 提交整个订单
    handleSubmit: function() {
      // 提交订单的参数
      const data = {
        order_price: this.allPrice,
        consignee_addr: this.address.addr,
        goods: this.cartData.map(v => {
          return {
            goods_id: v.goods_id,
            goods_number: v.count,
            goods_price: v.goods_price
          };
        })
      };

      // 判断是否登录
      if (!authManage.isAuth) {
        wx.navigateTo({
          url: '/pages/login'
        });
        return;
      }

      // 提交订单
      request({
        url: 'api/public/v1/my/orders/create',
        data,
        method: 'POST',
        header: { Authorization: authManage.getToken() },
        success: res => {
          const {data} = res.data;
          this.pay( { order_number: data.order_number } )
        }
      });
    }
  };


  // 处理订单支付
  pay(data){
    request({
      url: "api/public/v1/my/orders/req_unifiedorder",
      data,
      method: 'POST',
      header: { Authorization: authManage.getToken() },
      success: res => {
        const {data} = res.data;
        wx.requestPayment(data.wxorder);
      }
    })
  }
}
</script>

管理登录状态


// 管理登录状态
// 有个问题要注意, 当token过期时候我们没有处理
const authManage = {

  // 判断是否已登录
  isAuth: false,

  // 初始化方法
  init: function(){
      this.isAuth = !!this.getToken();
  },

  // 把token保存到本地
  setToken: function(token){
      this.isAuth = true;
      wx.setStorageSync("token", token)
  },

  // 获取token
  getToken: function(){
      return wx.getStorageSync("token");
  }
}
 
authManage.init();

export default authManage;

管理购物车数据

// 管理购物车数据
// 把数据存储到本地,但是有些项目是通过接口来实现

// 管理购物车的单例
const cartManage = {

    // 购物车数据
    data: {
        goods: [],  // 购物车商品列表
        allPrice: 0, // 合计价格
        address: {}, // 收货地址 
        allCount: 0,
    },

    // 管理类初始化
    init: function(){
        // 初始化goods
        this.data = this.getData() || this.data;

        // 初始化合计价格
        this.updatePrice();
    },

    // 把收货地址添加到本地存储
    addAddr: function(addr){
        this.data.address = addr;
        this.setData();
    },

    // 添加商品
    add: function(item){
        const {goods} = this.data;
        // 判断商品是否存在
        let isEixst = false;

        // 返回新的商品列表,新的列表可能是修改过商品的数量
        const newGoods = goods.map(v => {
            // 当商品存在时候数量加1
            if(v.goods_id == item.goods_id){
                // 确定商品存在
                isEixst = true;
                v.count += 1;
            }
            return v;
        })

        // 如果商品存在就不会调用push方法
        if(isEixst){
            this.data.goods = newGoods;
        }else{
            this.data.goods.push(item);
        }

        this.updatePrice();
    },

    // 删除商品
    remove: function(item){
        const {goods} = this.data;

        const newGoods = goods.filter(v => {
            // 如果找到该需要删除的商品, id相等的不返回, 相当于删除掉了该商品
            return !(v.goods_id == item.goods_id)
        });

        this.data.goods = newGoods;
        
        console.log(newGoods)

        this.updatePrice();
    },

    // 更新商品
    update: function(item){

        const {goods} = this.data;

        const newGoods = goods.map(v => {
            // 找到需要更新的商品
            if(item.goods_id == v.goods_id){
                // 返回新的商品
                return item;
            }
            return v;
        });

        this.data.goods = newGoods;

        this.updatePrice();
    },

    // 管理所有商品的选中状态
    // isChecked为true时候,就是全部选中
    // isChecked为false时候, 就是全部不选中
    updataAllChecked: function(isChecked){

        const {goods} = this.data;

        const newGoods = goods.map(v => {
            v.checked = isChecked;
            return v;
        });

        this.data.goods = newGoods;

        this.updatePrice();
    },

    // 更新合计的价格
    updatePrice: function(){
        const {goods} = this.data;
        let price = 0;

        goods.forEach(v => {
            // 商品必须是选中的状态
            if(v.checked){
                price += +v.goods_price * v.count;
            }
        })

        this.data.allPrice = price;

        this.updateAllCount();

        this.setData();

        return this.data.allPrice;
    },

    // 管理数量
    updateAllCount: function(){
        const {goods} = this.data;

        // 通过循环过滤, 过滤的条件商品必须是选中状态
        const newGoods = goods.filter(v => {
            return v.checked
        });

        this.data.allCount = newGoods.length;
    },

    // 把数据存储到本地
    setData: function(){
        wx.setStorageSync("cartData", this.data);
    },

    // 把数据从本地存储获取回来
    getData: function(){
        return wx.getStorageSync("cartData")
    }

}

// 执行初始化
cartManage.init();

export default cartManage;


猜你喜欢

转载自blog.csdn.net/Q_MUMU/article/details/85251438
今日推荐