• 购物车下单实现思路【vue】


    1、购物车

    • 在购物车页面会有一个点 提示当前购物车内商品的数量
    • 购物车内商品的展示
    • 购物车内商品的选中

    1.1 使用pinia来存储购物车的状态

      state: () => ({
        // 首页订货单元信息 这个主要是用来展示购物车的数量的
        cartMetaInfo: <AnyObject>{},
        // 订货单列表 存储完整的购物车数据
        orderList: <AnyObject[]>[],
        // 点击结算的时候冻结选择的订单和数量进行结算
        freezeOrders: <AnyObject[]>[],
        // 设置一个值来保存用户的选中状态
        selectedOrders:[]
      }),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    1.2 用户将商品加入购物车的时候

    • 1、调用添加商品的API 将商品添加到购物车
    • 2、添加成功后更新购物车内商品数量(这个数量也是存储在后端的)在pinia有一个state来记录这个数值 所以更新数量的方法写在action中
       // 获取首页订货单元信息
        async getCartMeta() {
          try {
            this.cartMetaInfo = await OrderAPI.getCartMeta();
          } catch (e) {
            const err = e as AnyObject;
            showMessage("获取订货单信息失败");
          }
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 3、刷新购物车列表

    注意点: 需要保存用户的选中状态,这个选中状态只是保存在vuex,并没有保存到后端,因为选中状态保存在前端所以购物车的数据都是从vuex中拿到的

    这个方法用来修改购物车中的某个数据 如选中状态

     // action
     // 设置单个订货单数据
        setOrder(index: number, data: AnyObject) {
          Object.assign(this.orderList[index], data);
          this.selectedOrders = state.orderList.filter((o) => o.checked)
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
       // getter
        // 在订货单页面选中的订货单
        selectedOrders(state) {
          return state.orderList.filter((o) => o.checked);
        },
    
        // 在订货单页面选中的订货单的id数组
        selectedOrderIds() {
          const selectedOrders = this.selectedOrders as AnyObject[];
          return selectedOrders.map((o) => o.sku_id);
        },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    // 单选状态改变
    const handleChangeChecked = (index: number) => {
      const flag = list.value[index].checked;
      orderStore.setOrder(index, { checked: !flag });
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • pinia中有一个action来修改购物车列表
        // 设置订货单
        setOrderList(orderList: AnyObject[], isRefresh = true) {
          if (isRefresh) {
            this.orderList = orderList;
          } else {
            this.orderList.push(...orderList);
          }
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    当点击加入购物车的时候会向后端发送网络请求,将商品加入到购物车,之后保存上一次已经选中的商品,重新获取购物车显示的商品个数,(这个步骤也可以等到切换到购物车在做:清空购物车list,重新获取购物车列表,确保购物车中的数据与数据库中的一致,获取到的商品判断是否和之前选中的一样如何一样则将其绑定选中状态)

    2、点击结算按钮

    • 1、当点击结算按钮的时候跳转到订单页面,将已经选择的商品的id去向后端发送网络请求拿到具体的信息
      在这里插入图片描述

    • 2、请求用户余额和返点余额,如果用户已经填写收货地址,就创建订单。

    • 3、如果用户的余额和返点余额抵扣后没有剩余需要支付的则直接生成订单

    • 4、如果还有剩下需要支付的则弹出付款界面使用微信支付。

    3、封装支付

    • 1、将所有的关于关于支付的方法都封装到组件里面,通过判断什么时候调用哪个接口
    const getRealOperation = (): {
      sendData: AnyObject;
      apiFn: (...args: any[]) => Promise<unknown>;
    } => {
      let sendData = {
        ...omit(params.value, "amount", "showAmount", "type", "success", "fail"),
        pay_type: selectedPayType.value,
      };
      console.log(sendData, "????????");
      let apiFn: (...args: any[]) => Promise<unknown>;
      switch (params.value.type) {
        case "continue":
          // 订单继续支付
          apiFn = OrderAPI.payOrder;
          return { sendData, apiFn };
    
        case "recharge":
          // 余额充值
          apiFn = BalanceAPI.recharge;
          return { sendData, apiFn };
    
        case "continueRecharge":
          // 余额充值
          apiFn = BalanceAPI.continueRecharge;
          return { sendData, apiFn };
    
        default:
          // 创建订单
          apiFn = OrderAPI.submitOrder;
          return { sendData, apiFn };
      }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    // 提交订单、创建订单
    const handleSubmitOrder = async () => {
      showLoading();
    
      const { run, data, error, isSuccess, isError } = useAsync();
      const { sendData, apiFn } = getRealOperation();
      if (
        params.value.type == "recharge" ||
        params.value.type == "continueRecharge"
      ) {
        await run(apiFn({ ...omit(sendData) }));
      } else {
        await run(apiFn({ ...omit(sendData, "pay_type") }));
      }
      uni.hideLoading();
    
      if (isSuccess.value) {
        const res = data.value as AnyObject;
        console.log("submit order result: ", res);
        console.log(sendData, "sendData");
    
        if (selectedPayType.value === PayType.BALANCE) {
          await userStore.getDealerBalance();
          toPage("my-order", {}, { prefix: "/order-core", target: 2 });
        } else if (selectedPayType.value === PayType.WX_PAY) {
        // 返回预支付id
          await handlePay(res as OrderResParams);
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在这里插入图片描述

    const handlePay = async (info: OrderResParams) => {
      showLoading();
    
      const { run, data, error, isSuccess, isError } = useAsync();
      await run(PayAPI.getPrepayInfo(info.pay_serial_id));
    
      if (isSuccess.value) {
        console.log("预支付信息:", data.value);
        const payInfo = data.value as AnyObject;
    
        showLoading("购买中");
        uni.requestPayment({
          // 时间戳
          timeStamp: "",
          // 随机字符串
          nonceStr: "",
          // 统一下单接口返回的 prepay_id 参数值
          package: "",
          // 签名类型
          signType: "",
          // 签名
          paySign: "",
          // 调用成功回调
          success() {},
          // 失败回调
          fail() {},
          // 接口调用结束回调
          complete() {},
        });
      }
    
      if (isError.value) {
        uni.hideLoading();
        console.log("预支付失败:", error.value);
        const err = error.value as AnyObject;
        showMessage(err?.msg || "支付失败");
      }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    在这里插入图片描述

  • 相关阅读:
    【Java自定义工具类】百分比计算工具类以及计算相关的问题(138)
    2023,简历石沉大海?软件测试岗位真的已经饱和了....
    为什么.icu域名受欢迎?
    element-ui 表单验证注意事项
    python 2018全国自学考试第5章 第21题 成功!!!左右金字塔建模加平方结果
    HTTP响应状态码
    WebView 以及如何测试
    【无标题】
    性能测试监控指标及分析调优
    YOLO目标检测——无人机航拍行人检测数据集下载分享【含对应voc、coc和yolo三种格式标签】
  • 原文地址:https://blog.csdn.net/weixin_46738453/article/details/136473628