【瑞吉外卖 | day07】移动端菜品展示、购物车、下单

avatar
作者
筋斗云
阅读量:0

在这里插入图片描述

文章目录

瑞吉外卖 — day7

  • 移动端相关业务功能 —— 菜品展示、购物车、下单

1. 导入用户地址簿相关功能代码

1.1 需求分析

  • 地址簿,指的是移动端消费者用户的地址信息,用户登录成功后可以维护自己的地址信息。同一个用户可以有多个地址信息,但是只能有一个默认地址

1.2 数据模型

  • 用户的地址信息会存储在address_book表,即地址簿表中。

1.3 代码开发

  • 导入功能代码

    实体类AddressBook(直接从课程资料中导入即可)

    Mapper接口AddressBookMapper

    业务层接口AddressBookService

    业务层实现类AddressBookServicelmpl

    控制层AddressBookController(直接从课程资料中导入即可)

  • AddressBookController代码

    /**  * 地址簿管理  */ @Slf4j @RestController @RequestMapping("/addressBook") public class AddressBookController {      @Autowired     private AddressBookService addressBookService;      /**      * 新增      */     @PostMapping     public R<AddressBook> save(@RequestBody AddressBook addressBook) {         addressBook.setUserId(BaseContext.getCurrentId());         log.info("addressBook:{}", addressBook);         addressBookService.save(addressBook);         return R.success(addressBook);     }      /**      * 设置默认地址      */     @PutMapping("default")     public R<AddressBook> setDefault(@RequestBody AddressBook addressBook) {         log.info("addressBook:{}", addressBook);         LambdaUpdateWrapper<AddressBook> wrapper = new LambdaUpdateWrapper<>();         wrapper.eq(AddressBook::getUserId, BaseContext.getCurrentId());         wrapper.set(AddressBook::getIsDefault, 0);         //SQL:update address_book set is_default = 0 where user_id = ?         addressBookService.update(wrapper);          addressBook.setIsDefault(1);         //SQL:update address_book set is_default = 1 where id = ?         addressBookService.updateById(addressBook);         return R.success(addressBook);     }      /**      * 根据id查询地址      */     @GetMapping("/{id}")     public R get(@PathVariable Long id) {         AddressBook addressBook = addressBookService.getById(id);         if (addressBook != null) {             return R.success(addressBook);         } else {             return R.error("没有找到该对象");         }     }      /**      * 查询默认地址      */     @GetMapping("default")     public R<AddressBook> getDefault() {         LambdaQueryWrapper<AddressBook> queryWrapper = new LambdaQueryWrapper<>();         queryWrapper.eq(AddressBook::getUserId, BaseContext.getCurrentId());         queryWrapper.eq(AddressBook::getIsDefault, 1);          //SQL:select * from address_book where user_id = ? and is_default = 1         AddressBook addressBook = addressBookService.getOne(queryWrapper);          if (null == addressBook) {             return R.error("没有找到该对象");         } else {             return R.success(addressBook);         }     }      /**      * 查询指定用户的全部地址      */     @GetMapping("/list")     public R<List<AddressBook>> list(AddressBook addressBook) {         addressBook.setUserId(BaseContext.getCurrentId());         log.info("addressBook:{}", addressBook);          //条件构造器         LambdaQueryWrapper<AddressBook> queryWrapper = new LambdaQueryWrapper<>();         queryWrapper.eq(null != addressBook.getUserId(), AddressBook::getUserId, addressBook.getUserId());         queryWrapper.orderByDesc(AddressBook::getUpdateTime);          //SQL:select * from address_book where user_id = ? order by update_time desc         return R.success(addressBookService.list(queryWrapper));     } } 

2. 菜品展示

2.1 需求分析

  • 用户登录成功后跳转到系统首页,在首页需要根据分类来展示菜品和套餐
    。如果菜品设置了口味信息,需要展示洗择规格按钮,否则显示==+==按钮。

2.2 代码开发

  • 前端与服务端交互过程

    1、页面(front/index.html)发送ajax请求,获取分类数据(菜品分类和套餐分类)

    2、页面发送ajax请求,获取第一个分类下的菜品或者套餐

  • 页面(front/index.html)发送ajax请求,获取分类数据(菜品分类和套餐分类)

  • 页面发送ajax请求,获取第一个分类下的菜品或者套餐

    DishController中:

    @GetMapping("list")     public R<List<DishDto>> list(Dish dish){         //构造查询条件         LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();         queryWrapper.eq(dish.getCategoryId()!=null, Dish::getCategoryId, dish.getCategoryId());         //添加条件,查询状态为1的菜品         queryWrapper.eq(Dish::getStatus,1);         //添加排序条件         queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);          List<Dish> list = dishService.list(queryWrapper);          List<DishDto> dishDtoList = list.stream().map((item) -> {             DishDto dishDto = new DishDto();             BeanUtils.copyProperties(item,dishDto);              Long categoryId = item.getCategoryId();             //根据id查询分类对象             Category category = categoryService.getById(categoryId);              if(category != null){                 String categoryName = category.getName();                 dishDto.setCategoryName(categoryName);             }              //当前菜品的id             Long dishId = item.getId();             LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper = new LambdaQueryWrapper<>();             lambdaQueryWrapper.eq(DishFlavor::getDishId,dishId);             List<DishFlavor> dishFlavorList = dishFlavorService.list(lambdaQueryWrapper);             dishDto.setFlavors(dishFlavorList);              return dishDto;         }).collect(Collectors.toList());          return R.success(dishDtoList);     } 

    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.2 数据模型

  • 购物车对应的数据表为shopping_cart表

3.3 代码开发

  • 前段与服务端交互过程

    1、点击加入购物车或者按钮,页面发送ajax请求,请求服务端,将菜品或者套餐添加到购物车

    2、点击购物车图标,页面发送ajax请求,请求服务端查询购物车中的菜品和套餐

    3、点击清空购物车按钮,页面发送ajax请求,请求服务端来执行清空购物车操作

  • 创建需要的类和接口

    实体类ShoppingCart ( 直接从课程资料中导入即可)

    Mapper接口ShoppingCartMapper

    业务层接口ShoppingCartService

    业务层实现类ShoppingCartServicelmpl

    控制层ShoppingCartController

  • 将菜品或者套餐添加到购物车

    @RestController @RequestMapping("shoppingCart") @Slf4j public class ShoppingCartController {      @Autowired     private ShoppingCartService shoppingCartService;      /**      * 添加购物车      * @param shoppingCart      * @return      */     @PostMapping("add")     public R<ShoppingCart> add(@RequestBody ShoppingCart shoppingCart){         log.info("购物车数据:{}",shoppingCart);          //设置用户id,指定当前是哪个用户的购物车数据         Long currentId = BaseContext.getCurrentId();         shoppingCart.setUserId(currentId);          LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();         queryWrapper.eq(ShoppingCart::getUserId,currentId);          //查询当前菜品或套餐,是否在购物车中         Long dishId = shoppingCart.getDishId();         if(dishId != null){             //添加到购物车的是菜品             queryWrapper.eq(ShoppingCart::getDishId,dishId);         }else{             //添加到购物车的是套餐             queryWrapper.eq(ShoppingCart::getSetmealId,shoppingCart.getSetmealId());         }          ShoppingCart cart = shoppingCartService.getOne(queryWrapper);          //如果已存在,在原来数量基础上+1         if(cart != null){             Integer number = cart.getNumber();             cart.setNumber(number+1);             shoppingCartService.updateById(cart);          }else{             //如果不存在,则添加到购物车,数量默认就是1             shoppingCart.setNumber(1);             shoppingCart.setCreateTime(LocalDateTime.now());             shoppingCartService.save(shoppingCart);             cart = shoppingCart;         }          return R.success(cart);     } } 
  • 查询购物车中的菜品和套餐

    /**      * 查看购物车当前数据      * @return      */     @GetMapping("list")     public R<List<ShoppingCart>> list(){         log.info("查看购物车...");          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);     } 
  • 清空购物车操作

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

4. 下单

4.1 需求分析

  • 移动端用户将菜品或者套餐加入购物车后,可以点击购物车中的去结算按钮,页面跳转到订单确认页面,点击去支付按钮则完成下单操作。

4.2 数据模型

  • orders:订单表
    order_ detail::订单明细表

4.3 代码开发

  • 前端页面与服务端交互过程

    1、在购物车中点击去结算按钮,页面跳转到订单确认页面

    2、在订单确认页面,发送ajax请求,请求服务端获取当前登录用户的默认地址

    3、在订单确认页面,发送ajax请求,请求服务端获取当前登录用户的购物车数据

    4、在订单确认页面点击去支付按钮, 发送ajax请求, 请求服务端完成下单操作

  • 基本的类和接口

    实体类Orders、OrderDetail (直接从课程资料中导入即可)

    Mapper接口OrderMapper、OrderDetailMapper

    业务层接口OrderService、OrderDetailService

    业务层实现类OrderServicelmpl、OrderDetailServicelmpl

    控制层OrderController、OrderDetailController

  • OrderController代码:

    @RestController @RequestMapping("order") @Slf4j public class OrderController {      @Autowired     private OrdersService ordersService;      /**      * 用户下单      * @param orders      * @return      */     @PostMapping("submit")     public R<String> submit(@RequestBody Orders orders){         log.info("订单数据:{}",orders);         ordersService.submit(orders);         return R.success("下单成功");     } }  
  • OrdersServiceImpl代码:

    @Service public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders>         implements OrdersService{      @Autowired     private ShoppingCartService shoppingCartService;      @Autowired     private UserService userService;      @Autowired     private AddressBookService addressBookService;      @Autowired     private OrderDetailService orderDetailService;      /**      * 用户下单      * @param orders      */     @Override     @Transactional     public void submit(Orders orders) {         //获取当前用户id         Long currentId = BaseContext.getCurrentId();          //查询当前用户购物车数据         LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();         queryWrapper.eq(ShoppingCart::getUserId,currentId);         List<ShoppingCart> shoppingCarts = shoppingCartService.list(queryWrapper);          if(shoppingCarts == null || shoppingCarts.size() == 0){             throw new CustomerException("购物车为空,不能下单");         }          //查询用户数据         User user = userService.getById(currentId);          //查询地址数据         Long addressBookId = orders.getAddressBookId();         AddressBook addressBook = addressBookService.getById(addressBookId);         if(addressBook == null){             throw new CustomerException("用户地址信息有误,不能下单");         }          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表插入数据,一条数据         orders.setId(orderId);         orders.setOrderTime(LocalDateTime.now());         orders.setCheckoutTime(LocalDateTime.now());         orders.setStatus(2);         orders.setAmount(new BigDecimal(amount.get()));//总金额         orders.setUserId(currentId);         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);          //向order_detail表插入数据,多条数据         orderDetailService.saveBatch(orderDetails);          //清空购物车数据         shoppingCartService.remove(queryWrapper);     } }  

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!