瑞吉外卖业务开发(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

相关文章
|
人工智能 安全 搜索推荐
会声会影2023激活码序列号一键下载安装包教程
Corel VideoStudio会声会影是一款功能操作简单,适合家庭日常使用,完整的影片编辑流程解决方案、从拍摄到分享、新增处理速度加倍。它不仅符合家庭或个人所需的影片剪辑功能,甚至可以挑战专业级的影片剪辑软件。适合普通大众使用,操作简单易懂,界面简洁明快。该软件具有成批转换功能与捕获格式完整的特点,虽然无法与EDIUS,Adobe Premiere,Adobe After Effects和Sony Vegas等专业视频处理工具媲美,但以简单易用、功能丰富的作风赢得了良好的口碑,在国内的普及度较高。
5464 1
|
存储 小程序 前端开发
Uni-app前端开发|基于微信小程序的快递运输管理系统
Uni-app前端开发|基于微信小程序的快递运输管理系统
442 1
|
存储 监控 安全
网络安全与信息安全:保护数据的重要性与实践措施
本文深入探讨了网络安全和信息安全领域内的关键概念,包括网络漏洞、加密技术以及安全意识的重要性。通过分析这些要素,文章提供了实用的策略来增强个人和企业的数据保护能力。我们将探讨如何识别和防范潜在的网络威胁,并强调了持续更新安全知识和采取预防措施的必要性。
|
9月前
|
人工智能 API
通义千问 Qwen 衍生模型包揽 HuggingFace 开源榜单全球前十!
通义千问 Qwen 衍生模型包揽 HuggingFace 开源榜单全球前十!
|
11月前
|
机器学习/深度学习 并行计算 算法
《解锁 C++矩阵运算优化秘籍,助力人工智能算法“光速”飞驰》
矩阵运算是人工智能算法的核心,尤其在深度学习中扮演着至关重要的角色。C++以其高效性和对底层硬件的精细控制能力,提供了多种优化策略,包括内存布局优化、高级算法应用、多线程并行计算及SIMD指令集利用,显著提升了矩阵运算的效率与性能。这些优化措施不仅加快了模型训练速度,还提高了实际应用中的响应速度,为人工智能技术的发展注入了强大动力。
181 8
|
安全 C#
【Azure 应用服务】在安全漏洞扫描中发现有泄露服务器IIS版本的情况,如何实现屏蔽服务版本号信息呢?
【Azure 应用服务】在安全漏洞扫描中发现有泄露服务器IIS版本的情况,如何实现屏蔽服务版本号信息呢?
528 1
|
运维 前端开发 测试技术
瑞吉外卖业务开发(1)
瑞吉外卖业务开发
252 3
多元线性回归模型预测销售额
多元线性回归模型预测销售额
229 0
|
Java 数据可视化
快递驿站取件管理系统|基于SpringBoot的快递栈系统设计与实现(二)
快递驿站取件管理系统|基于SpringBoot的快递栈系统设计与实现
312 0
快递驿站取件管理系统|基于SpringBoot的快递栈系统设计与实现(二)
|
XML Android开发 数据格式
Android Studio App开发实战项目之实现淘宝电商App首页界面(附源码,可用于大作业参考)
Android Studio App开发实战项目之实现淘宝电商App首页界面(附源码,可用于大作业参考)
1622 1