• 瑞吉外卖(28)- 用户下单功能开发(功能完结篇)


    需求分析

    在这里插入图片描述

    数据模型

    在这里插入图片描述

    订单表 - orders

    在这里插入图片描述

    订单明细表 - order_detail

    在这里插入图片描述

    代码开发

    梳理交互过程

    在这里插入图片描述

    分析前端请求

    去结算"页面正常

    在这里插入图片描述

    获得默认地址信息

    在这里插入图片描述

    “去支付”请求

    在这里插入图片描述
    在这里插入图片描述

    搭建框架

    在这里插入图片描述

    实体类Orders.java

    package com.taotao.reggie.entity;
    
    import lombok.Data;
    import java.io.Serializable;
    import java.math.BigDecimal;
    import java.time.LocalDateTime;
    
    /**
     * 订单
     */
    @Data
    public class Orders implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private Long id;
    
        //订单号
        private String number;
    
        //订单状态 1待付款,2待派送,3已派送,4已完成,5已取消
        private Integer status;
    
    
        //下单用户id
        private Long userId;
    
        //地址id
        private Long addressBookId;
    
    
        //下单时间
        private LocalDateTime orderTime;
    
    
        //结账时间
        private LocalDateTime checkoutTime;
    
    
        //支付方式 1微信,2支付宝
        private Integer payMethod;
    
    
        //实收金额
        private BigDecimal amount;
    
        //备注
        private String remark;
    
        //用户名
        private String userName;
    
        //手机号
        private String phone;
    
        //地址
        private String address;
    
        //收货人
        private String consignee;
    }
    
    

    实体类OrderDetail.java

    package com.taotao.reggie.entity;
    
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableId;
    import lombok.Data;
    import java.io.Serializable;
    import java.math.BigDecimal;
    
    /**
     * 订单明细
     */
    @Data
    public class OrderDetail implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private Long id;
    
        //名称
        private String name;
    
        //订单id
        private Long orderId;
    
    
        //菜品id
        private Long dishId;
    
    
        //套餐id
        private Long setmealId;
    
    
        //口味
        private String dishFlavor;
    
    
        //数量
        private Integer number;
    
        //金额
        private BigDecimal amount;
    
        //图片
        private String image;
    }
    
    

    OrderMapper.java

    package com.taotao.reggie.mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.taotao.reggie.entity.Orders;
    import org.apache.ibatis.annotations.Mapper;
    
    /**
     * create by 刘鸿涛
     * 2022/9/29 20:40
     */
    @SuppressWarnings({"all"})
    @Mapper
    public interface OrderMapper extends BaseMapper<Orders> {
        
    }
    
    

    OrderDetailMapper.java

    package com.taotao.reggie.mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.taotao.reggie.entity.OrderDetail;
    import org.apache.ibatis.annotations.Mapper;
    
    /**
     * create by 刘鸿涛
     * 2022/9/29 20:41
     */
    @SuppressWarnings({"all"})
    @Mapper
    public interface OrderDetailMapper extends BaseMapper<OrderDetail> {
    }
    
    

    OrderService.java

    package com.taotao.reggie.service;
    
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.taotao.reggie.entity.Orders;
    
    /**
     * create by 刘鸿涛
     * 2022/9/29 20:42
     */
    @SuppressWarnings({"all"})
    public interface OrderService extends IService<Orders> {
    }
    
    

    OrderDetailService.java

    package com.taotao.reggie.service;
    
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.taotao.reggie.entity.OrderDetail;
    
    /**
     * create by 刘鸿涛
     * 2022/9/29 20:43
     */
    @SuppressWarnings({"all"})
    public interface OrderDetailService extends IService<OrderDetail> {
    }
    
    

    OrderServiceImpl.java

    package com.taotao.reggie.service.impl;
    
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.taotao.reggie.entity.Orders;
    import com.taotao.reggie.mapper.OrderMapper;
    import com.taotao.reggie.service.OrderService;
    import org.springframework.stereotype.Service;
    
    /**
     * create by 刘鸿涛
     * 2022/9/29 20:43
     */
    @SuppressWarnings({"all"})
    @Service
    public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements OrderService {
        
    }
    
    

    OrderDetailServiceImpl.java

    package com.taotao.reggie.service.impl;
    
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.taotao.reggie.entity.OrderDetail;
    import com.taotao.reggie.mapper.OrderDetailMapper;
    import com.taotao.reggie.service.OrderDetailService;
    import org.springframework.stereotype.Service;
    
    /**
     * create by 刘鸿涛
     * 2022/9/29 20:45
     */
    @SuppressWarnings({"all"})
    @Service
    public class OrderDetailServiceImpl extends ServiceImpl<OrderDetailMapper, OrderDetail> implements OrderDetailService {
    }
    
    

    OrderController.java

    package com.taotao.reggie.controller;
    
    import com.taotao.reggie.service.OrderService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * create by 刘鸿涛
     * 2022/9/29 20:54
     */
    @SuppressWarnings({"all"})
    @RestController
    @Slf4j
    @RequestMapping("/order")
    public class OrderController {
        @Autowired
        private OrderService orderService;
    }
    

    OrderDetailController.java

    package com.taotao.reggie.controller;
    
    import com.taotao.reggie.service.OrderDetailService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * create by 刘鸿涛
     * 2022/9/29 20:57
     */
    @SuppressWarnings({"all"})
    @RestController
    @RequestMapping("orderDetail")
    @Slf4j
    public class OrderDetailController {
        private OrderDetailService orderDetailService;
    }
    
    

    编写核心代码

    分析返回数据

    因为返回的三个属性都在orders表内,所以,我们可以使用orders来接收返回值,但是注意,前端返回来的数据是json格式,所以后端我们使用@RequestBody注解

    在这里插入图片描述

    OrderController.java

    package com.taotao.reggie.controller;
    
    import com.taotao.reggie.common.R;
    import com.taotao.reggie.entity.Orders;
    import com.taotao.reggie.service.OrderService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * create by 刘鸿涛
     * 2022/9/29 20:54
     */
    @SuppressWarnings({"all"})
    @RestController
    @Slf4j
    @RequestMapping("/order")
    public class OrderController {
        @Autowired
        private OrderService orderService;
    
        /**
         * 用户下单
         * @param orders
         * @return
         */
        @PostMapping("/submit")
        public R<String> Submit(@RequestBody Orders orders){
            log.info("订单数据:{}",orders);
            orderService.submit(orders);
            return R.success("下单成功");
        }
    }
    
    

    OrderService.java

    package com.taotao.reggie.service;
    
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.taotao.reggie.entity.Orders;
    import org.springframework.web.bind.annotation.PostMapping;
    
    /**
     * create by 刘鸿涛
     * 2022/9/29 20:42
     */
    @SuppressWarnings({"all"})
    public interface OrderService extends IService<Orders> {
        /**
         * 用户下单
         * @param orders
         */
        public void submit(Orders orders);
    }
    
    

    OrderServiceImpl.java

    package com.taotao.reggie.service.impl;
    
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.core.toolkit.IdWorker;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.taotao.reggie.common.BaseContext;
    import com.taotao.reggie.common.CustomException;
    import com.taotao.reggie.entity.*;
    import com.taotao.reggie.mapper.OrderMapper;
    import com.taotao.reggie.service.*;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.math.BigDecimal;
    import java.time.LocalDateTime;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.stream.Collectors;
    
    @Service
    @Slf4j
    public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements OrderService {
    
        @Autowired
        private ShoppingCartService shoppingCartService;
    
        @Autowired
        private UserService userService;
    
        @Autowired
        private AddressBookService addressBookService;
    
        @Autowired
        private OrderDetailService orderDetailService;
    
        /**
         * 用户下单
         * @param orders
         */
        @Transactional
        public void submit(Orders orders) {
            //获得当前用户id
            Long userId = BaseContext.getCurrentId();
    
            //查询当前用户的购物车数据
            LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ShoppingCart::getUserId,userId);
            List<ShoppingCart> shoppingCarts = shoppingCartService.list(wrapper);
    
            if(shoppingCarts == null || shoppingCarts.size() == 0){
                throw new CustomException("购物车为空,不能下单");
            }
    
            //查询用户数据
            User user = userService.getById(userId);
    
            //查询地址数据
            Long addressBookId = orders.getAddressBookId();
            AddressBook addressBook = addressBookService.getById(addressBookId);
            if(addressBook == null){
                throw new CustomException("用户地址信息有误,不能下单");
            }
    
            long orderId = IdWorker.getId();//订单号
    
            //原子类
            AtomicInteger amount = new AtomicInteger(0);
    
            List<OrderDetail> orderDetails = shoppingCarts.stream().map((item) -> {
                OrderDetail orderDetail = new OrderDetail();
                orderDetail.setOrderId(orderId);
                orderDetail.setNumber(item.getNumber());
                orderDetail.setDishFlavor(item.getDishFlavor());
                orderDetail.setDishId(item.getDishId());
                orderDetail.setSetmealId(item.getSetmealId());
                orderDetail.setName(item.getName());
                orderDetail.setImage(item.getImage());
                orderDetail.setAmount(item.getAmount());
                amount.addAndGet(item.getAmount().multiply(new BigDecimal(item.getNumber())).intValue());
                return orderDetail;
            }).collect(Collectors.toList());
    
    
            orders.setId(orderId);
            orders.setOrderTime(LocalDateTime.now());
            orders.setCheckoutTime(LocalDateTime.now());
            orders.setStatus(2);
            orders.setAmount(new BigDecimal(amount.get()));//总金额
            orders.setUserId(userId);
            orders.setNumber(String.valueOf(orderId));
            orders.setUserName(user.getName());
            orders.setConsignee(addressBook.getConsignee());
            orders.setPhone(addressBook.getPhone());
            orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName())
                    + (addressBook.getCityName() == null ? "" : addressBook.getCityName())
                    + (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName())
                    + (addressBook.getDetail() == null ? "" : addressBook.getDetail()));
            //向订单表插入数据,一条数据
            this.save(orders);
    
            //向订单明细表插入数据,多条数据
            orderDetailService.saveBatch(orderDetails);
    
            //清空购物车数据
            shoppingCartService.remove(wrapper);
        }
    }
    

    功能测试

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    扩展资料

    md5加密

    数字摘要算法

    RSA加密

  • 相关阅读:
    冥想第五百二十三天
    如何使用virtualenv的虚拟环境
    【Leetcode】python回溯算法结果出现[[], [], []](列表深拷贝 浅拷贝问题)
    iNFTnews | 从5G到6G:创新与颠覆的竞赛
    FusionAD:用于自动驾驶预测和规划任务的多模态融合
    震惊!强大的接口自动化测试框架2.0,unittest与pytest无缝穿插对接,可以像postman一样编写代码
    python学习笔记——函数
    淘宝API详情接口调用示例
    java开源商城免费搭建 VR全景商城 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城
    springboot 去掉netflix 禁用Eureka
  • 原文地址:https://blog.csdn.net/qq_39123467/article/details/127112392