Web实现登陆后合并本地购物车和数据库的购物车(前端Vue逻辑和后端node接口)

分析

添加购物车

  1. 商品添加到购物车
  2. 加入购物车前判断是否已登录(本文主要实现下面第2点)
    • 未登录,将记录添加到Vuex的cart模块中
    • 修改本地购物车后,成功登录后,合并本地购物车并清空本地购物车
    • 已登录,请求更新数据库的购物车表

使用到的技术

  1. Vuex
    - Vuex模块化,创建cart模块带命名空间,state存储购物车列表
    - Vuex模块化在模块中获取其他模块的state,使用actions的context的rootState
    - 使用异步actions,store.dispatch(‘cart/mergeLocalCart’)
    - 使用async和await获取请求的数据
  2. Axios
    - POST请求,带参数
    - Promise对象
  3. nodejs
    - MySQL数据库新增、查询、修改
    - 使用async和await获取请求的数据
    - 取出需要的数据使用 arr.map()
    - 查找购物车内是否已存在某一商品使用 arr.findIndex()
    - req获取POST的参数,req.body
  4. 测试接口工具 Postwoman
    - 谷歌的Http接口插件

实现

前端

  1. Vuex创建cart模块,主要存本地购物车列表 [ { 商品id、商品名、商品图片、商品价格、已选数量、是否选择、是否有效 } , { … } , … ]
/* Vuex的cart模块的state */
state: () => {
    return {
      //{pro_id, pro_name, pro_main_images, pro_price, count: 1//已选择件数, selected: true, isEffective: true, pro_stock}
      list: []
    }
  },
  1. Vuex的getters、mutations主要处理购物车其他逻辑,比如有效商品列表、金额、件数,已选商品列表、金额、件数,是否全选,增删改查购物车列表等
  2. Vuex的actions添加合并本地购物车函数mergeLocalCart。
    - 判断是否登录,查询user模块的用户id,在管理购物车表时也需要用户id来查询用户所有购物车记录。
    - 从购物车的有效商品列表中取出需要的数据 arr.map()
    - axios使用post请求(request时axios封装后的函数返回Promise对象),将用户id和本地购物车参数传过去
    - 使用mutations的修改购物车函数,将购物车清空 [],ctx.commit
	/* Vuex的cart模块的actions */
	//合并本地购物车
    async mergeLocalCart(ctx) {
      const userId = ctx.rootState.user.user.u_id;
      // console.log("Store-Cart-userid",userId)
      // 判断是否登录
      if (userId) {
        // 调用合并API接口函数进行购物合并
        const cartList = ctx.getters.validList.map(({ pro_id, pro_price, selected, count }) => {
          return { pro_id, pro_price, selected, count }
        })
        const res = await mergeCart(userId, cartList)
        // console.log("Api-Cart-合并购物车mergeLocalCart-res", res);
        // 合并成功将本地购物车删除
        ctx.commit('setCartList', [])
      } else {
        console.log("用户还未登录");
      }
    }
/* api的购物车请求*/
/**
 * axios的POST请求:合并本地购物车
 * @param {Array} cartList - 本地购物车数组
 * @param {String} item.pro_id - 商品pro_id
 * @param {Integer} item.pro_price - 商品价格
 * @param {Boolean} item.selected - 是否选中
 * @param {Integer} item.count - 数量
 */
 export const mergeCart = (userId, cartList) => {
   //cartList 是 { pro_id, pro_price, selected, count }对象数组
  return request('/cart/merge', 'post', {userId,cartList})
}
 
  
  1. 在登录后,使用actions的mergeLocalCart,store.dispatch(‘cart/mergeLocalCart’)
	/*登陆页面login-form.vue的主要代码*/
	 //登陆成功后合并购物车操作
     store.dispatch('cart/mergeLocalCart').then(()=>{
       // 2. 提示
       Message({ type: "success", text: "登录成功" });
       // 3. 跳转
       router.push(route.query.redirectUrl || "/");
     })

后端接口(‘cart/merge’)

  1. Path:‘cart/merge’
  2. Method:POST
  3. 接收参数:(用户id)req.body.userId;(购物车列表)req.body.cartList;//cartList:[{ pro_id: 1, pro_price: 22, count: 1, selected: true }];
  4. 返回信息:合并后的数据库信息
  5. 操作数据库dao:查询某一用户的购物车信息;修改购物车信息;新增购物车信息;
  /**
   * 查询某一用户的购物车信息
  */
   static queryByUserid(cart_user_id) {
    return new Promise((resolve, reject) => {
      let sql = `SELECT * FROM pin_cart WHERE cart_user_id = ${cart_user_id};`;
      this.query(sql).then(res => {
        resolve(res)
      }).catch(err => {
        reject(err)
      })
    })
  }


  /**
   * 修改购物车
  */
   static updateById(cart_id,good) {
    return new Promise((resolve, reject) => {
      let sql = `UPDATE pinke.pin_cart SET cart_product_id = ${good.pro_id} , cart_old_price = ${good.pro_price} , cart_count = ${good.count} , cart_selected = ${good.selected} ,cart_is_effective = '1' WHERE cart_id = ${cart_id}; `;
      this.query(sql).then(res => {
        resolve(res)
      }).catch(err => {
        reject(err)
      })
    })
  }

  /**
   * 新增购物车商品
  */
   static add(user_id,good) {
    return new Promise((resolve, reject) => {
      let sql = `INSERT INTO pin_cart (cart_user_id, cart_product_id, cart_old_price, cart_count, cart_selected, cart_is_effective) VALUES (${user_id}, ${good.pro_id}, ${good.pro_price}, ${good.count}, ${good.selected}, '1');`;
      this.query(sql).then(res => {
        resolve(res)
      }).catch(err => {
        reject(err)
      })
    })
  }
  1. 数据处理controller
    - 获取客户端传来的数据:用户id和购物车列表
    - 获取客户的所有购物车记录let result = await this.queryByUserid(u_id);
    - 循环每条本地购物车记录,是否在result 中已存在 result.findIndex,如果已存在则更新await this.updateById(result[index].cart_id,good);,不存在则新增await this.add(u_id, good);
    - 重新查询购物车result = await this.queryByUserid(u_id);
    - 返回更新后的购车车信息res.json({ list: result })
module.exports = class user_dao extends require('../dao/cart_dao') {
  /* 合并购物车 */
  static async mergeCart(req, res) {
    //获取客户端本地购物车信息
    let u_id = req.body.userId;
    let cartList = req.body.cartList;//cartList:[{ pro_id: 1, pro_price: 22, count: 1, selected: true }]
    // console.log("mergeCart__________________req.body", req.body);
    //先获取用户的所有购物车信息
    let result = await this.queryByUserid(u_id);
    //循环本地购物车,如果购物车内不存在则新增,若存在则修改
    cartList.forEach(async good => {
      //本地的商品是否在result中存在
      let index = result.findIndex((currVal) => {
        return currVal.cart_product_id === good.pro_id
      })
      // console.log("mergeCart__________________找到的index",index);
      if (index===-1){
        //新增
        await this.add(u_id, good);
        // console.log("mergeCart__________________新增");
      }else{
        //修改
        await this.updateById(result[index].cart_id,good);
        // console.log("mergeCart__________________修改");
      }
    });
    result = await this.queryByUserid(u_id);
    res.json({ list: result })

  }
}
  1. 创建接口( ‘cart/merge’ )
const cart = require('../controller/cart')

/* POST 合并本地购物车. */
router.post('/merge', function (req, res) {
  cart.mergeCart(req, res);
});

结尾

这是笔者的想法实现,如果有更好的想法希望大家留言给出意见,感谢

你可能感兴趣的:(vue.js学习之路,vue.js,前端,node.js,mysql)