【瑞吉外卖】Day05 套餐管理业务开发

目录

  1. 新增套餐
  2. 套餐信息分页查询
  3. 删除套餐

新增套餐_需求分析&数据模型

需求分析

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

数据模型

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

新增套餐_代码开发_准备工作&梳理交互过程

代码开发-准备工作

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

  • 实体类SetmealDish(直接从课程资料中导入即可,Setmeal实体前面课程中已经导入过了)
  • DTO SetmealDto (直接从课程资料中导入即可)
  • Mapper接口SetmealDishMapper
  • 业务层接口SetmealDishService
  • 业务层实现类SetmealDishservicelmpl
  • 控制层SetmealController

代码开发-梳理交互过程

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

  1. 页面(backend/page/combo/add.html)发送ajax请求,请求服务端获取套餐分类数据并展示到下拉框中(已完成)
  2. 页面发送ajax请求,请求服务端,获取菜品分类数据并展示到添加菜品窗口中
  3. 页面发送ajax请求,请求服务端,根据菜品分类查询对应的菜品数据并展示到添加菜品窗口中
  4. 页面发送请求进行图片上传请求服务端将图片保存到服务器(已完成)
  5. 页面发送请求进行图片下载,将上传的图片进行回显(已完成)
  6. 点击保存按钮,发送ajax请求,将套餐相关数据以json形式提交到服务端

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

新增套餐_代码开发_根据分类查询菜品

前端分析

启动项目,进入套餐管理,点击新建套餐,会发现页面发送的请求未被服务端接收

爆系统接口异常,服务端未定义查询菜品的方法

相关代码

在DishController类中,添加list方法
注意:需要添加额外的查询条件,只查询status为1的数据,表示该菜品为起售状态,才能被加入套餐中,供用户选择

@GetMapping("/list")
    public R<List<Dish>> list(Dish dish){

        //构造查询条件
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
        //添加条件,查询状态为1(1为起售,0为停售)的菜品
        queryWrapper.eq(Dish::getStatus,1);

        List<Dish> list = dishService.list(queryWrapper);
        //添加排序条件
        return R.success(list);
    }

新增套餐_代码开发_服务端接收页面提交的数据

前端分析

启动项目,来到添加套餐页面,输入数据,点击保存

查看前端页面发送的请求,请求方式

相关代码(测试版)

在SetmealController类中添加save方法

实现类SetmealServicelmpl,实现接口添加的方法,并向方法中添加代码逻辑

  • 保存套餐的基本信息
  • 保存套餐和菜品的关联信息
@Override
    @Transactional
    public void saveWithDish(SetmealDto setmealDto) {
        //保存套餐的基本信息,操作setmeal,执行insert操作
        save(setmealDto);

        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();

        setmealDishes = setmealDishes.stream().map((item) -> {
            item.setSetmealId(setmealDto.getId());
            return item;
        }).collect(Collectors.toList());

        //保存套餐和菜品的关联信息
        setmealDishService.saveBatch(setmealDishes);
    }

在SetmealController控制层的save方法中,调用saveWithDish方法,将数据保存至数据库

 @PostMapping
    public R<String> save(@RequestBody SetmealDto setmealDto){
        log.info("数据传输对象setmealDto:{}",setmealDto.toString());
        setmealService.saveWithDish(setmealDto);
        return R.success("新增套餐成功");
    }

套餐信息分页查询_需求分析&梳理交互过程

需求分析

  • 系统中的套餐数据很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看
  • 一般的系统中都会以分页的方式来展示列表数据

梳理交互过程

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

  • 页面(backend/page/combo/list.html)发送ajax请求,将分页查询参数(page、pageSize、name)提交到服务端,获取分页数据
  • 页面发送请求,请求服务端进行图片下载,用于页面图片展示

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

套餐信息分页查询_代码开发&功能测试

代码开发

SetmealController类中,添加list方法

@GetMapping("/page")
    public R<Page> list(int page,int pageSize,String name){
        //分页构造器对象
        Page<Setmeal> pageInfo = new Page<>(page, pageSize);
        Page<SetmealDto> dtoPage = new Page<>();

        //构造查询条件对象
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(name != null, Setmeal::getName, name);

        //操作数据库
        setmealService.page(pageInfo,queryWrapper);

        //对象拷贝
        BeanUtils.copyProperties(pageInfo,dtoPage,"records");

        List<Setmeal> records = pageInfo.getRecords();

        List<SetmealDto> list = records.stream().map((item) -> {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(item, setmealDto);
            //获取categoryId
            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);
            if (category != null) {
                String categoryName = category.getName();
                setmealDto.setCategoryName(categoryName);
            }
            return setmealDto;
        }).collect(Collectors.toList());

        dtoPage.setRecords(list);

        return R.success(dtoPage);
    }

注意
在套餐管理界面,套餐分类字段显示的是categoryId对应的中文,但在数据库里查询到的是categoryId,因此需要利用categoryId查询到categoryName,并赋值给数据传输对象SetmealDto

删除套餐_需求分析&梳理交互过程

需求分析

  • 在套餐管理列表页面点击删除按钮,可以删除对应的套餐信息
  • 也可以通过复选框选择多个套餐,点击批量删除按钮一次删除多个套餐
  • 注意对于状态为售卖中的套餐不能删除,需要先停售,然后才能删除。

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

  • 删除单个套餐时,页面发送ajax请求,根据套餐id删除对应套餐
  • 删除多个套餐时,页面发送ajax请求,根据提交的多个套餐id删除对应套餐开发删除套餐功能

其实就是在服务端编写代码去处理前端页面发送的这2次请求即可

  • 观察删除单个套餐和批量删除套餐的请求信息可以发现,两种请求的地址和请求方式都是相同
  • 不同的则是传递的id个数,所以在服务端可以提供一个方法来统一处理。

删除套餐_代码开发&功能测试

代码开发(测试)

在SetmealController中添加delete方法

 @DeleteMapping
    public R<String> delete(@RequestParam List<Long> ids){
        log.info("ids为:",ids);

        return null;
    }

代码开发完善版本

1.在SetmealService接口中添加removeWithDish方法

2.在SetmealServicelmpl实现类中实现对应接口中添加的方法

@Override
    @Transactional
    public void removeWithDish(List<Long> ids) {
        //select count(*) from setmeal where ids in(1,2,3) and status = 1
        //查询套餐状态,确定是否可以删除
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId,ids);
        queryWrapper.eq(Setmeal::getStatus,1);

        int count = super.count(queryWrapper);

        if (count > 0){
            //如果不能删除,抛出一个业务异常
            throw new CustomException("套餐正在售卖中,不能删除");
        }

        //如果可以删除,先删除套餐表中的数据
        super.removeByIds(ids);

        //删除关系表中的数据
        //delete from setmeal_dish where setmeal_id in(1,2,3)
        LambdaQueryWrapper<SetmealDish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishLambdaQueryWrapper.in(SetmealDish::getSetmealId,ids);

        setmealDishService.remove(dishLambdaQueryWrapper);


    }

在SetmealController中完善代码—调用removeWithDish方法,实现套餐数据删除成功

@DeleteMapping
    public R<String> delete(@RequestParam List<Long> ids){
        log.info("ids为:",ids);
        setmealService.removeWithDish(ids);
        return R.success("套餐数据删除成功");

    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值