• 黑马苍穹外卖7 用户下单+订单支付(微信小程序支付流程图)


    地址簿

    数据库表设计
    在这里插入图片描述
    就是基本增删改查,与前面的类似。

    用户下单

    用户点餐业务流程:
    在这里插入图片描述
    购物车-订单提交-订单支付-下单成功

    展示购物车数据,不需要提交到后端
    在这里插入图片描述
    数据库设计:两个表【订单表orders,订单明细表order_detail】
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    DTO:
    在这里插入图片描述
    VO:
    在这里插入图片描述
    controller:

    @RestController("UserOrderController")//作为Bean名称,避免与admin端名称重复
    @RequestMapping("/user/order")
    @Api(tags = "B端用户订单接口")
    public class OrderController {
    
        @Autowired
        private OrderService orderService;
    
        @PostMapping("/submit")
        @ApiOperation("用户下单")
        public Result<OrderSubmitVO> submit(@RequestBody OrdersSubmitDTO submitDTO){
            return Result.success(orderService.submit(submitDTO));//传入DTO返回VO
        }
    

    service :
    @Transactional//设计几多个数据表,需要保证数据一致性,需要事务注解–保证原子性,全成功或全失败

    @Transactional//事务注解 -方法执行完提交才插入
        @Override
        public OrderSubmitVO submit(OrdersSubmitDTO submitDTO) {
        //处理各种业务异常检查(地址是否为空,购物车是否为空)
            AddressBook addressBook = addressBookMapper.getById(submitDTO.getAddressBookId());
            if (addressBook == null) {
                throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
            }
            //检查当前用户的购物车是否为空
            Long userId = BaseContext.getCurrentId();//当前用户ID
    
            ShoppingCart shoppingCart = new ShoppingCart();
            shoppingCart.setUserId(userId);
            List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
            if (list == null || list.size() == 0) {
                throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
            }
            //1.增加一条订单信息
            Orders orders = new Orders();
            BeanUtils.copyProperties(submitDTO, 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);//用户ID
    
            orderMapper.insert(orders);
            //2.增加多条订单详情
            List<OrderDetail> orderDetailList = new ArrayList<>();//整个批量插入
            for (ShoppingCart cart : list) {//遍历购物车里的数据
                OrderDetail orderDetail = new OrderDetail();//订单单明细
                BeanUtils.copyProperties(cart, orderDetail);
                orderDetail.setOrderId(orders.getId());//设置当前订单明细关联的订单id
                orderDetailList.add(orderDetail);
            }
    
            orderDetailMapper.insertBatch(orderDetailList);
    
            //3.删除用户购物车
            shoppingCartMapper.deleteByUserId(userId);
    
            //4.封装VO对象并返回
            OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .id(orders.getId())
                .orderNumber(orders.getNumber())
                .orderTime(orders.getOrderTime())
                .orderAmount(orders.getAmount())
                .build();
    
            return orderSubmitVO;
    
        }
    

    增加1订单
    mapper:

     void insert(Orders orders);
    

    xml:出入后返回订单主键值

    <insert id="insert" parameterType="Orders" useGeneratedKeys="true" keyProperty="id">
            insert into orders (number, status, user_id, address_book_id, order_time, checkout_time, pay_status, pay_method,amount, remark, phone, address, consignee, estimated_delivery_time, delivery_status,pack_amount, tableware_number, tableware_status)
            values (#{number}, #{status}, #{userId}, #{addressBookId}, #{orderTime}, #{checkoutTime}, #{payMethod},
                    #{payStatus}, #{amount}, #{remark}, #{phone}, #{address}, #{consignee}, #{estimatedDeliveryTime},
                    #{deliveryStatus}, #{packAmount}, #{tablewareNumber}, #{tablewareStatus})
        insert>
    

    批量增加订单详情:

     void insertBatch(List<OrderDetail> orderDetailList);
    
    <insert id="insertBatch">
            insert into order_detail (name, image, order_id, dish_id, setmeal_id, dish_flavor, number, amount)
            values
            <foreach collection="orderDetailList" item="od" separator=",">
                (#{od.name},#{od.image},#{od.orderId} ,#{od.dishId},#{od.setmealId},#{od.dishFlavor},#{od.number},#{od.amount})
            foreach>
        insert>
    

    订单支付(*流程)

    微信支付介绍

    在这里插入图片描述JSAPI下单:商户调用该接口在后台生成预支付交易单,返回表示,

    微信支付准备工作

    两个问题:

    1.调用过程如何保证数据安全?

    获取微信支付平台整证书、商户私钥文件
    从微信商户平台得到两个文件

    2.微信后台如何调用到商户系统?

    当前商务系统的ip就是本地电脑ip这个局域网的IP,微信后跳调用不到,应该用公网IP。
    获取临时域名:
    cpolar.exe内网穿透生成一个临时域名。
    略。

    从用户发起支付订单开始看:

    @PutMapping("/payment")
        @ApiOperation("订单支付")
        public Result<OrderPaymentVO> payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception {
    
            //订单支付
            OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO);
            //生成预交易订单
            return Result.success(orderPaymentVO);
        }
    
    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
            );
    
            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;
        }
    
  • 相关阅读:
    机器学习之机器如何学习
    奇瑞新能源小蚂蚁,一款实用好看的居家小车
    docker 命令
    我们为什么喜欢看疯狂科学家开飞艇?
    第2关:计算商品的总费用
    Java中使用Jsoup实现网页内容爬取与Html内容解析并使用EasyExcel实现导出为Excel文件
    大数据培训之自定义bean对象实现序列化接口
    B43 - 基于STM32单片机的自动视力检测仪
    【用示例学习与理解C++系列】timerfd与epoll的使用
    Win11快捷复制粘贴不能用怎么办?Win11快捷复制粘贴不能用
  • 原文地址:https://blog.csdn.net/weixin_44040169/article/details/139954376