《苍穹外卖》知识梳理p7-用户下单与模拟微信支付

用户下单与微信支付

一.用户下单

1.1 订单表的设计

订单功能是一个核心的功能;
需要使用2张表:
1.订单表:记录一些订单信息,比如收货人,收获地址,支付金额,下单时间等;
2.订单详情表:记录订单上主要商品的信息,比如:套餐,菜品等;
设计订单表:
在这里插入图片描述
设计订单详情表:
在这里插入图片描述
由于一张订单上可能有多个商品(商品可以是菜品也可以是套餐);而每一个商品对应一个订单详情表,所以订单表与订单详情表是一对多的关系;

1.2 用户下单的DTO

用户下单时必然提交的数据是:
地址簿ID addressBookId,用于关联地址簿表获取地址信息;
总金额amount;
配送状态deliveryStatus;
预计送达时间estimatedDeliveryTime;
打包费packAmount;
备注remark;
餐具数量tablewareNumber;
餐具数量状态tablewareStatus;

1.3 用户下单之后返回的VO

订单ID
订单号;
订单金额;
下单时间;

1.4 用户下单处理流程

1.接收参数ordersSubmitDTO
2.处理可能出现的异常
3.向订单表插入一条数据
4.向订单明细表插入多条数据
5.用户下单成功之后,清空购物车
6.封装VO返回结果

//业务层核心代码
@Override
public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {

    //处理各种业务异常
    AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
    //用户地址不能为空
    if (addressBook==null)
        throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);

    //用户购物车不能为空,查询当前用户的购物车数据;
    Long userId= BaseContext.getCurrentId();
    ShoppingCart shoppingCart=new ShoppingCart();
    shoppingCart.setUserId(userId);
    List<ShoppingCart> shoppingCartList = shoppingCartMapper.list(shoppingCart);
    if (shoppingCartList==null||shoppingCartList.size()==0)
        throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);

    //向订单表插入一条数据
    Orders orders=new Orders();
    BeanUtils.copyProperties(ordersSubmitDTO,orders);
    orders.setOrderTime(LocalDateTime.now());
    orders.setPayStatus(Orders.UN_PAID);  //下单时订单还未支付;
    orders.setStatus(Orders.PENDING_PAYMENT); //订单状态为待支付;
    orders.setNumber(String.valueOf(System.currentTimeMillis())); //使用当前时间的时间戳作为订单号
    orders.setPhone(addressBook.getPhone());
    orders.setConsignee(addressBook.getConsignee());
    orders.setUserId(userId);
    //在使用mapper操作数据库时,由于后边需要使用orderId,因此需要再orderMapper插入数据库时返回主键值;
    orderMapper.insert(orders);

    List<OrderDetail> orderDetails=new ArrayList<>();
    //向订单明细表插入多条数据
    for (ShoppingCart cart:shoppingCartList){
        OrderDetail orderDetail=new OrderDetail();
        BeanUtils.copyProperties(shoppingCart,orderDetail);
        orderDetail.setOrderId(orders.getId());
        orderDetails.add(orderDetail);
    }
    orderDetailMapper.insertBatch(orderDetails);


    //用户下单成功之后,清空购物车
    shoppingCartMapper.deleteByUserId(userId);

    //封装VO返回结果
    OrderSubmitVO orderSubmitVO=OrderSubmitVO.builder()
            .id(orders.getId())
            .orderTime(orders.getOrderTime())
            .orderNumber(orders.getNumber())
            .orderAmount(orders.getAmount())
            .build();

    return orderSubmitVO;
}

二.微信支付

由于需要商户开通才能使用微信支付,因此个人项目可以模拟微信支付;

2.1导入微信支付相关代码

不用修改配置文件application.yml与application-dev.yml;
涉及微信支付工具类的代码已经给出:位于模块sky-common下的com.sky.utils的WeChatPayUtil下;
在这里插入图片描述
点击“去支付”之后,执行了submit提交订单相关操作之后,显示如下:
在这里插入图片描述
点击“确认支付”,发送请求,请求地址为/user/order/payment,调用payment接口,调用业务层接口,并返回OrderPaymentVO对象:

  	private String nonceStr; //随机字符串
    private String paySign; //签名
    private String timeStamp; //时间戳
    private String signType; //签名算法
    private String packageStr; //统一下单接口返回的 prepay_id 参数值
	/**
	 * 订单支付
	 *
	 * @param ordersPaymentDTO
	 * @return
	 */
	@PutMapping("/payment")
	@ApiOperation("订单支付")
	public Result<OrderPaymentVO> payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception {
	    log.info("订单支付:{}", ordersPaymentDTO);
	    OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO);
	    //模拟交易成功
	    orderService.paySuccess(ordersPaymentDTO.getOrderNumber());
	    return Result.success(orderPaymentVO);
	}

修改业务层的payment方法中的部分代码:
正常获取当前登陆用户id,但是这里不调用微信支付的接口,而是直接生成一个空的jsonObject对象;在进行相应的赋值之后,获得的OrderPaymentVO对象仍然为空;
此时,模拟交易成功,直接调用业务层的交易成功的方法,并将“交易成功”的订单号传入;
而交易成功的业务层方法会直接修改订单的状态;

	/**
     * 订单支付
     *
     * @param ordersPaymentDTO
     * @return
     */
    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();
        User user = userMapper.getById(userId);

        //调用微信支付接口,生成预支付交易单
//        JSONObject jsonObject = weChatPayUtil.pay(
//                ordersPaymentDTO.getOrderNumber(), //商户订单号
//                new BigDecimal(0.01), //支付金额,单位 元
//                "苍穹外卖订单", //商品描述
//                user.getOpenid() //微信用户的openid
//        );
        //生成空jsonObject
        JSONObject jsonObject = new JSONObject();

        if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
            throw new OrderBusinessException("该订单已支付");
        }

        OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
        vo.setPackageStr(jsonObject.getString("package"));

        return vo;
    }

交易成功调用方法;

	/**
     * 支付成功,修改订单状态
     *
     * @param outTradeNo
     */
    public void paySuccess(String outTradeNo) {
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();

        // 根据订单号查询当前用户的订单
        Orders ordersDB = orderMapper.getByNumberAndUserId(outTradeNo, userId);

        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        Orders orders = Orders.builder()
                .id(ordersDB.getId())
                .status(Orders.TO_BE_CONFIRMED)
                .payStatus(Orders.PAID)
                .checkoutTime(LocalDateTime.now())
                .build();

        orderMapper.update(orders);
    }

提示支付成功
在这里插入图片描述
另外,前端代码也需要略作修改:
直接打开pay目录下的index.js,ctrf+f查找handleSave
将支付成功下边调用wx.requestPayment({})方法直接注释掉即可,

	// wx.requestPayment({
    //   nonceStr: res.data.nonceStr,
    //   package: res.data.packageStr,
    //   paySign: res.data.paySign,
    //   timeStamp: res.data.timeStamp,
    //   signType: res.data.signType,
    //   success: function (res) {
    //     wx.showModal({
    //       title: '提示',
    //       content: '支付成功',
    //       success: function () {
    //         uni.redirectTo({ url: '/pages/success/index?orderId=' + _this.orderId });
    //       }
    //     })
    //     console.log('支付成功!')
    //   }
    // })
    //uni.redirectTo({url: '/pages/success/index?orderId=' + _this.orderId });
  • 23
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黒猫.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值