【瑞吉外卖】-复盘(六)

文章详细介绍了瑞吉外卖项目中的关键功能实现,包括用户地址簿管理,使用ThreadLocal处理购物车数据,AtomicInteger确保计算金额的原子性,BigDecimal处理精度,IdWorker生成订单号,以及下单过程中的事务处理和数据操作。
摘要由CSDN通过智能技术生成

瑞吉外卖项目复盘(六)

课程内容

  • 用户地址簿功能
  • 菜品展示
  • 购物车(使用ThreadLocal获取当前登录的用户ID,对响应的购物车数据进行操作)
  • 下单(计算金额时使用AtomicInteger保证原子操作,实体类中金额的类型是BigDemical,订单号使用IdWorker实现)

用户地址簿功能

移动端消费者用户的地址信息。同一个用户可以有多个地址信息,但是只能有一个默认地址

对于地址簿管理,我们需要实现以下几个功能:

  • 新增地址
    • 需要记录当前是哪个用户的地址(关联当前登录用户)
  • 设置默认地址
    • 每个用户可以有很多地址,但是默认地址只能有一个
    • 先将该用户的所有地址的is_default更新为0,然后将当前是设置的默认地址的is_default设置为1
  • 根据ID查询地址
  • 查询默认地址
    • 根据当前的登录用户ID以及is_default进行查询,查询当前登录用户is_default为1的地址信息
  • 查询指定用户的全部地址
    • 根据当前登录用户ID,查询所有的地址列表

菜品展示

在首页需要根据分类来展示菜品和套餐。如果菜品设置了口味信息,需要展示
按钮,否则显示
按钮。

前端与后端的交互逻辑:

  1. 首先要获取分类数据(菜品分类和套餐分类)
  2. 获取第一个分类下的菜品或者套餐信息。
    1. 根据分类ID查询套餐信息
    2. 根据分类ID查询菜品列表(在实现添加套餐功能中已实现,但是之前查询的只是菜品的基本信息,不包含菜品的口味信息

查询菜品方法修改:

  1. 根据分类ID查询,查询目前正在起售的菜品列表(已实现)
  2. 遍历菜品列表,并查询菜品的分类信息以及菜品的口味列表
  3. 组装DishDto并返回

根据分类ID查询套餐:

套餐的查询比较简单,需要根据CategoryId,Status查询,然后再根据UpdateTime降序排列即可。没有涉及其它表格。

购物车

需要实现的功能有:

  1. 添加购物车
  2. 查询购物车
  3. 清空购物车

对于同一个菜品/套餐,如果选择多份不需要添加多条记录,增加数量number即可

加入购物车实现逻辑:

  1. 获取当前用户,为购物车对象赋值
  2. 根据当前登录用户ID及本次添加的菜品ID/套餐ID,查询购物车中是否存在统一菜品/套餐。
  3. 如果已经存在,就在原本数量基础上加1
  4. 如果不存在,则添加到购物车,数量默认就是1

查询购物车:

根据当前登陆用户ID查询购物车列表,并对查询结果进行创建时间的倒序排序

清空购物车:

清空购物车,登录用户ID,删除购物车数据

下单

点击去结算按钮,跳到订单确认页面,点击去支付则完成下单操作。

orders订单表:

order_detail订单表:

当点击”去结算“按钮,需要获取用户的默认收货地址(已实现)购物车中的数据(已实现)进行下单操作(需要往订单表oreders中插入一条记录,并且需要往order_detail中插入一条或多条记录)

下单操作具体逻辑

  1. 获得当前用户id,查询当前用户的购物车数据
  2. 根据当前登录用户id,查询用户数据
  3. 根据地址ID,查询地址数据
  4. 组装订单明细数据,批量保存订单明细
  5. 组装订单数据,批量保存订单明细
  6. 删除当前用户的购物车列表数据

上述逻辑中,计算购物车商品的总金额时,为保证我们每一次执行的累加计算是一个原子操作,我们这里用到了JDK中提供的原子类AtomicInteger。订单号使用Mybatisplus的IdWorker生成

@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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值