Java项目实战跟练day10——菜品管理(新增、分页查询的实现)

Java项目实战跟练day10——springboot + mybatis plus开发

新增菜品

新增菜品,是将新增页面录入的菜品信息插入到dish表,如果添加了口味做法,还需要向dish_flavor表插入数据。所以新增菜品涉及两个表:菜品表dish、菜品口味表dish flavor

step1创建类和接口等基本结构:
实体类 DishFlavor
Mapper接口 DishFlavorMapper
业务层接口 DishFlavorService
业务层实现类 DishFlavorServicelmpl
控制层 DishController
DishFlavor.java

/**
菜品口味
 */
@Data
public class DishFlavor implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    //菜品id
    private Long dishId;

    //口味名称
    private String name;

    //口味数据list
    private String value;

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    @TableField(fill = FieldFill.INSERT)
    private Long createUser;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;

    //是否删除
    private Integer isDeleted;
}

DishFlavorMapper.java

@Mapper
public interface DishFlavorMapper  extends BaseMapper<DishFlavor> {
}

DishFlavorService.java

@Service
public interface DishFlavorService extends IService<DishFlavor> {
}

DishFlavorServicelmpl.java

@Service
public class DishFlavorServicelmpl extends ServiceImpl<DishFlavorMapper,DishFlavor> implements DishFlavorService {
}

前后端交互思路:
1、页面(backend/page/food/add.html)发送ajax请求,请求服务端获取菜品分类数据并展示到下拉框中;
2、页面发送请求进行图片上传,请求服务端将图片保存到服务器;
3、页面发送请求进行图片下载,将上传的图片进行回显;
4、点击保存按钮,发送ajax请求,将菜品相关数据以json形式提交到服务端。
新增菜品功能,其实就是处理前端页面发送的这4次请求即可。
前端代码
request1

 this.getDishList()
   // 获取菜品分类
          getDishList () {
            getCategoryList({ 'type': 1 }).then(res => {
              if (res.code === 1) {
                this.dishList = res.data
              } else {
                this.$message.error(res.msg || '操作失败')
              }
            })
          },
// 获取菜品分类列表
const getCategoryList = (params) => {
  return $axios({
    url: '/category/list',
    method: 'get',
    params
  })
}

在这里插入图片描述
后端代码实现:
CategoryController.java

    /**
     * 菜品列表按条件查询
     * @param category
     */
    @GetMapping("/list")
    public R<List<Category>> list(Category category){
        log.info("接收的分类类型为:{}",category);
        //条件构造器
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        //添加条件
        queryWrapper.eq(category.getType()!=null,Category::getType,category.getType());
        //添加排序条件
        //优先按照sort序号排序,再按照更新时间排序
        queryWrapper.orderByDesc(Category::getSort).orderByDesc(Category::getUpdateTime);

        List<Category> list = categoryService.list(queryWrapper);

        return R.success(list);
    }

页面展示:
在这里插入图片描述
request2\3
通过文件上传下载已实现
在这里插入图片描述
前端代码
request4
通过addDish方法实现新增菜品

          submitForm(formName, st) {
            this.$refs[formName].validate((valid) => {
              if (valid) {
                let params = {...this.ruleForm}
                // params.flavors = this.dishFlavors
                params.status = this.ruleForm ? 1 : 0
                params.price *= 100
                params.categoryId = this.ruleForm.categoryId
                params.flavors = this.dishFlavors.map(obj => ({ ...obj, value: JSON.stringify(obj.value) }))
                delete params.dishFlavors
                if(!this.imageUrl){
                  this.$message.error('请上传菜品图片')
                  return 
                }
                if (this.actionType == 'add') {
                  delete params.id
                  addDish(params).then(res => {
                    if (res.code === 1) {
                      this.$message.success('菜品添加成功!')
                      if (!st) {
                        this.goBack()
                      } else {
                        this.dishFlavors = []
                        // this.dishFlavorsData = []
                        this.imageUrl = ''
                        this.ruleForm = {
                          'name': '',
                          'id': '',
                          'price': '',
                          'code': '',
                          'image': '',
                          'description': '',
                          'dishFlavors': [],
                          'status': true,
                          categoryId: ''
                        }
                      }
                    } else {
                      this.$message.error(res.msg || '操作失败')
                    }
                  }).catch(err => {
                    this.$message.error('请求出错了:' + err)
                  })
                } else {
                  delete params.updateTime
                  editDish(params).then(res => {
                    if (res.code === 1) {
                      this.$message.success('菜品修改成功!')
                      this.goBack()
                    } else {
                      this.$message.error(res.msg || '操作失败')
                    }
                  }).catch(err => {
                    this.$message.error('请求出错了:' + err)
                  })
                }
              } else {
                return false
              }
            })
          },
// 新增接口
const addDish = (params) => {
  return $axios({
    url: '/dish',
    method: 'post',
    data: { ...params }
  })
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
由上可以看出,新增菜品时前端上送数据包括两种实体类,由此引入数据传输对象DTO,全称Data Transfer Objiect,一般用于展示层与服务层之间的数据传输。
后端代码:
DishDto .java

@Data
public class DishDto extends Dish {
    private List<DishFlavor> flavors = new ArrayList<>();
}

DishService .java

@Service
public interface DishService extends IService<Dish> {
    //新增菜品,同时插入菜品对应的口味数据,需要操作两张表:dish、dish_flavor
    public void saveWithFlavor(DishDto dishDto);
}

DishServicelmpl .java

@Slf4j
@Service
public class DishServicelmpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Autowired
    private DishFlavorService dishFlavorService;

    /**
     * 新增菜品,同时保存对应的口味数据
     * @param dishDto
     */
    /**
     * Transactional-->事务管理,需在项目启动类上辅以注解EnableTransactionManagement使用
     * 1)放在接口实现类或接口实现方法上,而不是接口类中。
     * 2)访问权限:public的方法才起作用。@Transactional 注解应该只被应用到public方法上
     */
    @Transactional
    public void saveWithFlavor(DishDto dishDto) {
        //保存菜品的基本信息到菜品表dish
        this.save(dishDto);

        //菜品id,因为前端上送的flavor数据中不包含dishId,需从DishDto中取
        Long dishId = dishDto.getId();

        //菜品口味
        List<DishFlavor> flavors = dishDto.getFlavors();
        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishId);
            return item;
        }).collect(Collectors.toList());

        //保存菜品口味数据到菜品口味表dish_flavor
        dishFlavorService.saveBatch(flavors);
    }
}

DishController .java

@Controller
@RestController
@Slf4j
@RequestMapping("/dish")
public class DishController {

    @Autowired
    private DishService dishService;
    @Autowired
    private DishFlavorService dishFlavorService;

    /**
     * 新增菜品
     * @param dishDto
     * @return
     */
    @PostMapping
    public R<String> addDish(@RequestBody DishDto dishDto){
        log.info(dishDto.toString());
        dishService.saveWithFlavor(dishDto);
        return R.success("新增菜品成功");
    }
}

执行此功能,控制台输出SQL语句如下:
在这里插入图片描述

分页查询菜品信息

前后端交互思路:
1、页面(backend/page/food/list.html)发送ajax请求,将分页查询参数(page、pageSize、name)提交到服务端,获取分页数据;
2、页面发送请求,请求服务端进行图片下载,用于页面图片展示;
开发菜品信息分页查询功能,其实就是处理前端页面发送的这2次请求即可。
前端代码:

            await getDishPage(params).then(res => {
              if (String(res.code) === '1') {
                this.tableData = res.data.records || []
                this.counts = res.data.total
              }
            }).catch(err => {
              this.$message.error('请求出错了:' + err)
            })
// 查询列表接口
const getDishPage = (params) => {
  return $axios({
    url: '/dish/page',
    method: 'get',
    params
  })
}

模拟发送请求:
在这里插入图片描述
后端代码
DishController.java

    /**
     * 分页查询菜品信息
     * @param page
     * @param pageSize
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page, int pageSize,String name){
        log.info("菜品分页信息:page={},pageSize={},name={}",page,pageSize,name);
        //构建分页构造器
        Page pageInfo = new Page(page,pageSize);

        //构建条件构造器
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();

        //添加过滤条件
//        queryWrapper.like(!StringUtils.isEmpty(name), Dish::getName,name);
        queryWrapper.like(name!=null, Dish::getName,name);

        //添加排序条件
        queryWrapper.orderByDesc(Dish::getSort).orderByDesc(Dish::getUpdateTime);

        //执行查询
        dishService.page(pageInfo,queryWrapper);

        return R.success(pageInfo);
    }

效果展示:
在这里插入图片描述
注意要点:
因前端列表中的菜品分类需获取到categoryName字段,但后端只返回categoryId字段。

        <el-table-column
          prop="categoryName"
          label="菜品分类"
        ></el-table-column>

在这里插入图片描述
菜品分类要想正常展示,需作处理,保证前端页面返回DishDto类型的数据:
DishController.java

  /**
     * 分页查询菜品信息
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page, int pageSize,String name){
        log.info("菜品分页信息:page={},pageSize={},name={}",page,pageSize,name);
        //构建分页构造器
        Page<Dish> pageInfo = new Page(page,pageSize);
        Page<DishDto> dishDtoPage = new Page(page,pageSize);

        //构建条件构造器
        LambdaQueryWrapper<Dish> queryWrapper1 = new LambdaQueryWrapper<>();

        //添加过滤条件
        // queryWrapper.like(!StringUtils.isEmpty(name), Dish::getName,name);
        queryWrapper1.like(name!=null, Dish::getName,name);

        //添加排序条件
        queryWrapper1.orderByDesc(Dish::getSort).orderByDesc(Dish::getUpdateTime);

        //执行查询
        dishService.page(pageInfo,queryWrapper1);

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

        List<Dish> records = pageInfo.getRecords();
        List<DishDto> list = records.stream().map((item)->{
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item,dishDto);
            Long categoryId = item.getCategoryId();//获取分类id
            Category category = categoryService.getById(categoryId);//通过id获取分类对象
            if(category!=null){
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            return dishDto;
        }).collect(Collectors.toList());

        dishDtoPage.setRecords(list);

        return R.success(dishDtoPage);
    }

注意dto的用法!!!

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值