瑞吉外卖 —— 8、菜品展示、购物车、下单

目录

1、用户地址簿 

1.1、分析

1.1.1、需求分析

1.1.2、数据模型

1.1.3、导入代码

2、菜品展示

2.1、分析

2.1.1、需求分析 

2.1.2、交互过程

2.2、代码

2.2.1、代码修改 

2.2.2、获取套餐信息

3、购物车

3.1、分析

3.1.1、需求分析

3.1.2、数据模型

3.1.3、交互过程

3.2、代码

3.2.1、向购物车添加菜品或套餐

3.2.2、获取购物车信息

3.2.3、清空购物车

3.2.4、减少购物车菜品或套餐

4、用户下单

4.1、分析

4.1.1、需求分析

4.1.2、数据模型

4.1.3、交互过程

4.1.4、准备工作

4.2、代码

4.2.1、支付


1、用户地址簿 

1.1、分析

1.1.1、需求分析

1.1.2、数据模型

用户的地址信息会存储在 address_book 表,即地址簿表中。具体表结构如下:

1.1.3、导入代码

2、菜品展示

2.1、分析

2.1.1、需求分析 

2.1.2、交互过程

2.2、代码

2.2.1、代码修改 

前端在初始化时发送上面的两次请求后,需要都成功才会渲染数据

            initData(){
              // 两次请求都成功蔡渲染页面
              Promise.all([categoryListApi(),cartListApi({})]).then(res=>{
                //获取分类数据
                if(res[0].code === 1){
                  this.categoryList = res[0].data
                  if(Array.isArray(res[0].data) && res[0].data.length > 0){
                    this.categoryId = res[0].data[0].id
                    if(res[0].data[0].type === 1){
                      this.getDishList()
                    }else{
                      this.getSetmealData()
                    }
                  }
                }else{
                  this.$notify({ type:'warning', message:res[0].msg});
                }
                //获取菜品数据
                if(res[1].code === 1){
                  this.cartData = res[1].data
                }else{
                  this.$notify({ type:'warning', message:res[1].msg});
                }
              })
            },

所以将获取购物车的请求修改为获取假数据

//获取购物车内商品的集合
function cartListApi(data) {
    return $axios({
        // 'url': '/shoppingCart/list',
        'url': '/front/cartData.json',
        'method': 'get',
        params:{...data}
    })
}

假数据内容

{"code":1,"msg":null,"data":[],"map":{}}

修改完后便可以看到展示的菜品及图品,但没有其口味信息,因为 DishController 中的 list 方法返回的是 Dish 实体类,而 Dish 中没有口味属性,需要添加口味属性,要返回 DishDto

    /**
     * 根据条件查询菜品数据
     * @param dish
     * @return
     */
    /*@GetMapping("/list")
    public R<List<Dish>> list(Dish dish){
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
        queryWrapper.eq(Dish::getStatus, 1);
        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        List<Dish> list = dishSerivce.list(queryWrapper);
        return R.success(list);
    }*/
    @GetMapping("/list")
    public R<List<DishDto>> list(Dish dish){
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
        queryWrapper.eq(Dish::getStatus, 1);
        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        List<Dish> list = dishSerivce.list(queryWrapper);

        List<DishDto> dishDtoList = list.stream().map((item) -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);

            // 获取分类名称
            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);
            if(category != null){
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }

            // 获取口味信息
            Long dishId = item.getId();
            LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DishFlavor::getDishId, dishId);
            List<DishFlavor> dishFlavorList = dishFlavorService.list(wrapper);
            dishDto.setFlavors(dishFlavorList);

            return dishDto;
        }).collect(Collectors.toList());

        return R.success(dishDtoList);
    }

2.2.2、获取套餐信息

请求:

在 SetmealController 中添加方法

    /**
     * 根据条件获取套餐数据
     * @param setmeal
     * @return
     */
    @GetMapping("/list")
    public R<List<Setmeal>> list(Setmeal setmeal){
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId());
        queryWrapper.eq(setmeal.getStatus() != null, Setmeal::getStatus, setmeal.getStatus());
        queryWrapper.orderByDesc(Setmeal::getUpdateTime);
        List<Setmeal> list = setmealService.list(queryWrapper);
        return R.success(list);
    }

3、购物车

3.1、分析

3.1.1、需求分析

3.1.2、数据模型

购物车对应的数据表为 shopping_cart 表,具体表结构如下:

3.1.3、交互过程

3.1.4、准备工作

 将获取购物车信息的代码改回来

3.2、代码

3.2.1、向购物车添加菜品或套餐

 添加菜品请求:

添加套餐请求:

在 ShoppingCartController 添加方法

    /**
     * 向购物车添加菜品或套餐
     * @param shoppingCart
     * @return
     */
    @PostMapping("/add")
    public R<ShoppingCart> add(@RequestBody ShoppingCart shoppingCart){
        // 设置用户id,指定当前是哪个用户的购物车数据
        Long currentId = BaseContext.getCurrentId();
        shoppingCart.setUserId(currentId);

        // 查询当前菜品或套餐是否在购物车中
        Long dishId = shoppingCart.getDishId();
        LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingCart::getUserId, currentId);
        if(dishId != null){
            // 添加到购物车的是菜品
            queryWrapper.eq(ShoppingCart::getDishId, dishId);
        } else {
            // 添加到购物车的是套餐
            queryWrapper.eq(ShoppingCart::getSetmealId, shoppingCart.getSetmealId());
        }
        ShoppingCart cart = shoppingCartService.getOne(queryWrapper);

        if(cart != null){
            // 如果已存在,在原来的数量上加一
            cart.setNumber(cart.getNumber() + 1);
            shoppingCartService.updateById(cart);
        } else {
            // 如果不存在,则添加到购物车,默认数量为1
            shoppingCart.setNumber(1);
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCartService.save(shoppingCart);
            cart = shoppingCart;
        }

        return R.success(cart);
    }

3.2.2、获取购物车信息

 获取购物车信息的请求:

在 ShoppingCartController 添加方法

    /**
     * 查看购物车
     * @return
     */
    @GetMapping("/list")
    public R<List<ShoppingCart>> list(){
        LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingCart::getUserId, BaseContext.getCurrentId());
        queryWrapper.orderByAsc(ShoppingCart::getCreateTime);
        List<ShoppingCart> list = shoppingCartService.list(queryWrapper);
        return R.success(list);
    }

3.2.3、清空购物车

清空购物车请求:

在 ShoppingCartController 添加方法 

    /**
     * 清空购物车
     * @return
     */
    @DeleteMapping("/clean")
    public R<String> clean(){
        LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingCart::getUserId, BaseContext.getCurrentId());
        shoppingCartService.remove(queryWrapper);
        return R.success("清空购物车成功");
    }

3.2.4、减少购物车菜品或套餐

请求:

    /**
     * 减少购物车菜品或套餐
     * @return
     */
    @PostMapping("/sub")
    public R<ShoppingCart> sub(@RequestBody ShoppingCart shoppingCart){
        Long currentId = BaseContext.getCurrentId();
        LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingCart::getUserId, currentId);
        ShoppingCart cart = null;

        // 获取要减少的菜品或套餐信息
        Long dishId = shoppingCart.getDishId();
        if(dishId == null){
            // 减少的是套餐数量
            Long setmealId = shoppingCart.getSetmealId();
            queryWrapper.eq(ShoppingCart::getSetmealId, setmealId);
            cart = shoppingCartService.getOne(queryWrapper);
        } else {
            // 减少的是菜品数量
            queryWrapper.eq(ShoppingCart::getDishId, dishId);
            cart = shoppingCartService.getOne(queryWrapper);
        }

        Integer number = cart.getNumber();
        if(number > 1){
            cart.setNumber(number - 1);
            shoppingCartService.updateById(cart);
        } else {
            shoppingCartService.removeById(cart.getId());
        }

        return R.success(cart);
    }

4、用户下单

4.1、分析

4.1.1、需求分析

4.1.2、数据模型

用户下单业务对应的数据表为 orders 表和 order_detail 表:

orders 表:

order_detail 表

4.1.3、交互过程

4.1.4、准备工作

4.2、代码

4.2.1、支付

支付请求:

① 在 OrderServiceImpl 实现方法

package com.itheima.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.itheima.reggie.common.BaseContext;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.mapper.OrderMapper;
import com.itheima.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> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShoppingCart::getUserId, userId);
        List<ShoppingCart> shoppingCarts = shoppingCartService.list(queryWrapper);

        if(shoppingCarts == null || shoppingCarts.size() == 0){
            throw new CustomException("购物车为空,无法下单");
        }

        // 查询用户数据
        User user = userService.getById(userId);

        // 查询地址信息
        AddressBook addressBook = addressBookService.getById(orders.getAddressBookId());
        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(queryWrapper);
    }
}

② 在 OrderController 中使用方法

    /**
     * 支付订单
     * @param orders
     * @return
     */
    @PostMapping("/submit")
    public R<String> submit(@RequestBody Orders orders){
        orderService.submit(orders);
        return null;
    }

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值