瑞吉外卖业务开发(4)

简介: 瑞吉外卖业务开发

瑞吉外卖业务开发(3)https://developer.aliyun.com/article/1530407

新增套餐

需求分析

套餐就是菜品的集合。

后台系统中可以管理套餐信息,通过新增套餐功能来添加一个新的套餐,在添加套餐时需要选择当前套餐所属的套餐分类和包含的菜品,并且需要上传套餐对应的图片,在移动端会按照套餐分类来展示对应的套餐。

数据模型

新增套餐,其实就是将新增页面录入的套餐信息插入到setmeal表,还需要向setmeal_dish表插入套餐和菜品关联数据所以在新增套餐时,涉及到两个表:

  • setmeal 套餐表
  • setmeal_dish套餐菜品关系表

代码开发

准备工作

需要准备好的类和接口

  • 实体类SetmealDish,直接导入即可
  • DTO SetmealDto 直接导入即可
  • Mapper接口SetmealDishMapper
  • 业务层接口SetmealDishService
  • 业务层实现类SetmealDishServiceImpl
  • 控制层SetmealController

梳理交互过程

在开发代码之前,需要梳理一下新增套餐时前端页面和服务端的交互过程:

1、页面(backend/page/combo/add.html)发送ajax请求,请求服务端获取套餐分类数据并展示到下拉框中

2、页面发送ajax请求,请求服务端获取菜品分类数据并展示到添加菜品窗口中

3、页面发送ajax请求,请求服务端,根据菜品分类查询对应的菜品数据并展示到添加菜品窗口中

4、页面发送请求进行图片上传,请求服务端将图片保存到服务器

5、页面发送请求进行图片下载,将上传的图片进行回显

6、点击保存按钮,发送ajax请求,将套餐相关数据以json形式提交到服务端

开发新增套餐功能,其实就是在服务端编写代码去处理前端页面发送的这6次请求即可。

/**  
 * 根据条件查询对应的菜品数据  
 * @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 = dishService.list(queryWrapper);  
    return R.success(list);  
}
@Autowired  
private SetmealDishService setmealDishService;  
@Transactional  
@Override  
public void saveWithDish(SetmealDto setmealDto) {  
    //保存套餐的基本信息  
    this.save(setmealDto);  
    //保存套餐和菜品的关联信息  
    List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();  
setmealDishes.stream().map((item)->{  
        item.setSetmealId(setmealDto.getId());  
        return item;  
    }).collect(Collectors.toList());  
   setmealDishService.saveBatch(setmealDishes);  
  
  
}

controller

/**  
 * 新增套餐  
 * @param setmealDto  
 * @return  
 */  
@PostMapping  
public R<String> save(@RequestBody SetmealDto setmealDto){  
    setmealService.saveWithDish(setmealDto);  
    return R.success("新建套餐成功");  
}

套餐列表分页信息

在开发代码之前,需要梳理一下套餐分页查询时前端页面和服务端的交互过程:

1、页面(backend/page/combo/list.html)发送ajax请求,将分页查询参数(page.pageSize,name)提交到服务端,获取分页数据

2、页面发送请求,请求服务端进行图片下载,用于页面图片展示

开发套餐信息分页查询功能,其实就是在服务端编写代码去处理前端页面发送的这2次请求即可。

@GetMapping("/page")  
public R<Page> page(int page,int pageSize,String name){  
     Page<Setmeal> pageInfo = new Page<>();  
     Page<SetmealDto> setmealDtoPage=new Page<>();  
  
    LambdaQueryWrapper<Setmeal> queryWrapper=new LambdaQueryWrapper<>();  
    queryWrapper.like(name!=null,Setmeal::getName,name);  
    queryWrapper.orderByDesc(Setmeal::getUpdateTime);  
    setmealService.page(pageInfo,queryWrapper);  
    BeanUtils.copyProperties(pageInfo,setmealDtoPage,"records");  
    List<Setmeal> records = pageInfo.getRecords();  
  
  
   List<SetmealDto> list=  records.stream().map((item)->{  
        SetmealDto setmealDto = new SetmealDto();  
       BeanUtils.copyProperties(item,setmealDto);  
        Long categoryId = item.getCategoryId();  
        Category category = categoryService.getById(categoryId);  
       if(category!=null){  
           String name1 = category.getName();  
           setmealDto.setCategoryName(name1);  
  
       }  
       return setmealDto;  
    }).collect(Collectors.toList());  
   setmealDtoPage.setRecords(list);  
    return R.success(setmealDtoPage);

删除套餐

需求分析

删除套餐有批量删除和单个删除,我们可以用数组接收传过来的id,这样就可以使用一个来实现批量删除和单个删除的功能,还要注意的是,我们在删除套餐的时候还要删除与之对应的套餐,菜品关系表的相关信息,(我套餐都没了还要套餐菜品关系干啥)

手机验证码登录

阿里云短信服务-介绍

阿里云短信服务(Short Message Service)是广大企业客户快速触达手机用户所优选使用的通信能力。调用API或用群发助手,即可发送验证码、通知类和营销类短信;国内验证短信秒级触达,到达率最高可达99%;国际/港澳台短信覆盖200多个国家和地区,安全稳定,广受出海企业选用。

应用场景:

  • 验证码
  • 短信通知
  • 推广短信

步骤

  1. 导入maven坐标
  2. 调用api
<dependency>
<groupId>com.aliyun</ groupId>
<artifactId>aliyun-java-sdk-core< / artifactId><version>4.5.16</version>
< / dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi< / artifactId><version>2.1.0</version>
</ dependency>

需求分析

为了方便用户登录,移动端通常都会提供通过手机验证码登录的功能。

手机验证码登录的优点:

  • 方便快捷,无需注册,直接登录
  • 使用短信验证码作为登录凭证,无需记忆密码
  • 安全
    登录流程:
    输入手机号>获取验证码>输入验证码>点击登录>登录成功
    注意:通过手机验证码登录,手机号是区分不同用户的标识。

数据模型

代码开发

流程梳理

在开发代码之前,需要梳理一下登录时前端页面和服务端的交互过程:

1、在登录页面(front/page/login.html)输入手机号,点击【获取验证码】按钮,页面发送ajax请求,在服务端调用短信服务API给指定手机号发送验证码短信

2、在登录页面输入验证码,点击【登录】按钮,发送ajax请求,在服务端处理登录请求

开发手机验证码登录功能,其实就是在服务端编写代码去处理前端页面发送的这2次请求即可。

地址簿

需求分析

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

数据模型

导入功能代码

功能代码清单

  • 实体类AddressBook(直接从课程资料中导入即可)
  • Mapper接口AddressBookMapper
  • 业务层接口AddressBookService
  • 业务层实现类AddressBookServicelmpl
  • 控制层AddressBookController (直接从课程资料中导入即可)

菜品展示

用户登录成功后跳转到系统首页,在首页需要根据分类来展示菜品和套餐。如果菜品设置了口味信息,需要展示

选择规格按钮,否则显示按钮。

代码开发

在开发代码之前,需要梳理一下前端页面和服务端的交互过程:

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

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

开发菜品展示功能,其实就是在服务端编写代码去处理前端页面发送的这2次请求即可。

注意:首页加载完成后,还发送了一次ajax请求用于加载购物车数据,此处可以将这次请求的地址暂时修改一下,从静态json文件获取数据,等后续开发购物车功能时再修改回来,如下:

菜品展示的同时获得菜品的口味信息

@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 = dishService.list(queryWrapper);  
  
  
  
        List<DishDto> dishDtoList  = list.stream().map((item) -> {  
            DishDto dishDto = new DishDto();  
            //拷贝Dish里面的属性到DishDto  
            BeanUtils.copyProperties(item, dishDto);  
            //查询到分类id  
            Long categoryId = item.getCategoryId();  
            Category category = categoryService.getById(categoryId);  
            if (category != null) {  
                //通过分类id查询到分类名称  
                String categoryName = category.getName();  
                dishDto.setCategoryName(categoryName);  
            }  
  
            Long dishid = item.getId();//获取dishid  
            //获取口味表  
            LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();  
            dishFlavorLambdaQueryWrapper.eq(DishFlavor::getDishId,dishid);  
  
            List<DishFlavor> dishFlavors = dishFlavorService.list(dishFlavorLambdaQueryWrapper);  
            dishDto.setFlavors(dishFlavors);  
  
            return dishDto;  
//最后通过collect收集成集合  
        }).collect(Collectors.toList());  
        return R.success(dishDtoList);  
    }

查询套餐信息

@GetMapping("/list")  
public R<List<Setmeal>> listR(@RequestBody 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());  
    List<Setmeal> list = setmealService.list(queryWrapper);  
    return R.success(list);  
  
}

购物车

需求分析

移动端用户可以将菜品或者套餐添加到购物车。对于菜品来说,如果设置了口味信息

则需要选择规格后才能

加入购物车;对于套餐来说,可以直接点击将当前套餐加入购物车。在购物车中可以修改菜品和套餐的数量,也可以清空购物车。

代码实现

1、点击[加入购物车]

或者[+]按钮,页面发送ajax请求,请求服务端,将菜品或者套餐添加到购物车

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

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

开发购物车功能,其实就是在服务端编写代码去处理前端页面发送的这3次请求即可。

准备工作

在开发业务功能前,先将需要用到的类和接口基本结构创建好:

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

●Mapper接口ShoppingCartMapper

●业务层接口ShoppingCartService

●业务层实现类ShoppingCartServicelmpl

●控制层ShoppingCartController

controller

@PostMapping("/add")  
public R<ShoppingCart> add(@RequestBody Shopping  
    //设置用户id  
    Long currentId = BaseContext.getCurrentId();  
    shoppingCart.setUserId(currentId);  
  
    //查询当前商品是否在购物车里面  
    Long dishId = shoppingCart.getDishId();   //  
    LambdaQueryWrapper<ShoppingCart> queryWrappe  
  
    queryWrapper.eq(ShoppingCart::getUserId, sho  
  
    if (dishId != null) {  
        //参加到购物车的是菜品  
        queryWrapper.eq(ShoppingCart::getDishId,  
    } else {  
        queryWrapper.eq(ShoppingCart::getSetmeal  
    }  
  
    ShoppingCart one = shoppingCartService.getOn  
    if (one != null) {  
        //如果已经存在只需要商品数量增加即可  
        Integer number = one.getNumber();  
        one.setNumber(number+1);  
        shoppingCartService.updateById(one);  
    } else {  
        //如果不存在,则添加购物车,数量默认就是1  
        shoppingCart.setNumber(1);  
        shoppingCartService.save(shoppingCart);  
        one=shoppingCart;  
    }  
  
  
    //不存在则添加到购物车  
    return R.success(one);  
  
}

查看购物车

* 
 @GetMapping("/list")  
 public R<List<ShoppingCart>> listR() {  
     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);  
 }

用户下单

需求分析

数据模型

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

  • orders:订单表
  • order_detail:订单明细表

在开发代码之前,需要梳理一下用户下单操作时前端页面和服务端的交互过程:1、在购物车中点击

去结算按钮,页面跳转到订单确认页面

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

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

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

开发用户下单功能,其实就是在服务端编写代码去处理前端页面发送的请求即可。

准备工作

在开发业务功能前,先将需要用到的类和接口基本结构创建好:

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

Mapper接口OrderMapper、OrderDetailMapper

业务层接口 OrderService、OrderDetailService

业务层实现类OrderServicelmpl、OrderDetailServicelmpl

控制层OrderController、OrderDetailController

相关文章
|
24天前
|
JSON 前端开发 Java
瑞吉外卖业务开发(2)
瑞吉外卖业务开发
23 3
|
24天前
|
运维 前端开发 测试技术
瑞吉外卖业务开发(1)
瑞吉外卖业务开发
19 3
|
24天前
|
存储 JSON 前端开发
瑞吉外卖业务开发(3)
瑞吉外卖业务开发
22 1
|
26天前
|
供应链 安全 数据挖掘
外卖跑腿系统开发详情丨校园外卖跑腿系统开发指南
开发外卖跑腿系统旨在服务于外卖平台和跑腿服务商,实现用户下单、骑手接单及订单管理等功能。系统包括用户端应用(注册、下单、支付等)、商家管理(菜单更新、订单处理)、骑手端应用(任务接收、配送)以及实时订单管理。此外,系统支持多种支付方式、订单结算、评价反馈机制、数据统计报表和客户服务,确保交易安全、提升效率并优化用户体验。
|
SQL 缓存 JSON
瑞吉外卖笔记
这是一份写给自己的笔记,主要记录瑞吉外卖项目中自己没有了解过的知识点。我将按照功能来分别解析
679 1
|
9月前
|
负载均衡 Java 数据库连接
瑞吉外卖项目
瑞吉外卖项目
68 0
|
9月前
|
存储 安全 数据挖掘
外卖跑腿/同城跑腿/校园跑腿/同城配送外卖系统开发规则玩法/案例设计/逻辑方案/需求程序/源码
外卖跑腿、同城跑腿、校园跑腿和同城配送外卖系统开发,是指开发一个用于管理和协调外卖送餐和快递物品的平台或应用程序。该系统能够连接顾客、骑手和商家,提供顾客下单、骑手接单、派送商品等功能。
|
SQL 前端开发 Java
学习瑞吉外卖项目
以当前热门的外卖点餐为业务基础,业务真实、实用、广泛。基于流行的Spring Boot、mybatis plus等技术框架进行开发。 第一天: 设计产品原型。 新建数据库,导入sql文件。
|
前端开发
瑞吉外卖项目(超详细)
新增套餐 在开发业务功能前,先将需要用到的类和接口基本结构创建好: 实体类SetmealDish
|
Java 数据库连接 mybatis
瑞吉外卖项目(超详细)
公共字段自动填充 Mybatis Plus公共字段自动填充,也就是在插入或者更新的时候为指定字段赋予指定的值,使用它的好处就是可以统一对这些字段进行处理,避免了重复代码。 实现步骤: 1、在实体类的属性上加入@TableField注解,指定自动填充的策略 2、按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口