学习目标

1、完成区域管理开发

2、完成桌台管理开发

3、完成分类管理开发

4、完成菜品管理开发

第一章 商家平台-区域管理

  1. 在商家用户建立品牌、门店、员工后,就需要对当前的门店划分区域,每个门店都可以维护自己的餐厅区域,注意的桌台的数据归属我们采用多租户功能区实现这里不需要考虑【多租户】后面有专题去简介

1、功能区拆解

image.png

红色区域:此处为查询条件功能区,筛选列表信息

功能 说明
区域名称 输入区域名称,键盘按enter触发搜索列表
状态 下拉框,显示【启用、禁用】,change触发搜索列表

蓝色区域:区域维护功能

功能 说明
添加 新增区域信息
修改 修改区域信息
删除 删除区域信息==【真实删除】==,删除时,会有再次确认提示
禁用、启用 禁用启用区域

2、数据库结构

  1. CREATE TABLE `tab_table_area` (
  2. `id` bigint(18) NOT NULL COMMENT '桌台区域id',
  3. `area_name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '区域名称',
  4. `created_time` datetime DEFAULT NULL COMMENT '创建时间',
  5. `updated_time` datetime DEFAULT NULL COMMENT '创建时间',
  6. `sharding_id` bigint(18) DEFAULT NULL COMMENT '分库id',
  7. `store_id` bigint(18) NOT NULL COMMENT '门店主键id',
  8. `enterprise_id` bigint(18) NOT NULL COMMENT '商户号',
  9. `sort_no` int(11) DEFAULT NULL COMMENT '排序',
  10. `enable_flag` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT '是否有效',
  11. PRIMARY KEY (`id`)
  12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='桌台区域';

自动填充

下列字段,无需手动填充,系统会自动填充下列字段

字段 注释 填充方式
id 主键 雪花算法
enterprise_id 商户号 mybatis-plus-多租户拦截
created_time 创建时间 mybatis-plus-自动填充组件
updated_time 修改时间 mybatis-plus-自动填充组件
sharding_id 分库id mybatis-plus-自动填充组件
store_id 门店id mybatis-plus-多租户拦截

3、功能开发

在开始业务开发之前,我们首先看一下区域管理的UML图

image.png

TableAreaController:对TableAreaFace接口进行dubbo的RPC调用,为dubbo服务的消费者

TableAreaFace:区域管理dubbo接口定义

TableAreaFaceImpl:区域管理dubbo接口定义实现,这里做VO和POJO的转换

ITableAreaService:区域管理的业务接口定义,为TableAreaFaceImpl提供核心业务逻辑的定义

TableAreaServiceImpl:区域管理的业务接口定义实现

3.1、TableAreaFace接口

TableAreaFace:区域管理dubbo接口定义

  1. package com.itheima.restkeeper;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.exception.ProjectException;
  4. import com.itheima.restkeeper.req.TableAreaVo;
  5. import java.util.List;
  6. /**
  7. * @ClassName TableAreaFace.java
  8. * @Description 桌台区域dubbo服务
  9. */
  10. public interface TableAreaFace {
  11. /**
  12. * @param tableAreaVo 查询条件
  13. * @param pageNum 当前页
  14. * @param pageSize 每页大小
  15. * @return Page<TableAreaVo>
  16. * @Description 区域列表
  17. */
  18. Page<TableAreaVo> findTableAreaVoPage(TableAreaVo tableAreaVo,
  19. int pageNum,
  20. int pageSize)throws ProjectException;
  21. /**
  22. * @param tableAreaVo 对象信息
  23. * @return TableAreaVo
  24. * @Description 创建区域
  25. */
  26. TableAreaVo createTableArea(TableAreaVo tableAreaVo)throws ProjectException;
  27. /**
  28. * @param tableAreaVo 对象信息
  29. * @return Boolean
  30. * @Description 修改区域
  31. */
  32. Boolean updateTableArea(TableAreaVo tableAreaVo)throws ProjectException;
  33. /**
  34. * @param checkedIds 选择对象信息Id
  35. * @return Boolean
  36. * @Description 删除区域
  37. */
  38. Boolean deleteTableArea(String[] checkedIds)throws ProjectException;
  39. /**
  40. * @param tableAreaId 选择对象信息Id
  41. * @return TableAreaVo
  42. * @Description 查找区域
  43. */
  44. TableAreaVo findTableAreaByTableAreaId(Long tableAreaId)throws ProjectException;
  45. /***
  46. * @description 查询区域下拉框
  47. * @return: List<TableAreaVo>
  48. */
  49. List<TableAreaVo> findTableAreaVoList()throws ProjectException;
  50. }

3.2、TableAreaFaceImpl接口实现

TableAreaFaceImpl:区域管理dubbo接口定义实现,这里做VO和POJO的转换

  1. package com.itheima.restkeeper.face;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.TableAreaFace;
  4. import com.itheima.restkeeper.enums.TableAreaEnum;
  5. import com.itheima.restkeeper.exception.ProjectException;
  6. import com.itheima.restkeeper.pojo.TableArea;
  7. import com.itheima.restkeeper.req.TableAreaVo;
  8. import com.itheima.restkeeper.service.ITableAreaService;
  9. import com.itheima.restkeeper.utils.BeanConv;
  10. import com.itheima.restkeeper.utils.EmptyUtil;
  11. import com.itheima.restkeeper.utils.ExceptionsUtil;
  12. import lombok.extern.slf4j.Slf4j;
  13. import org.apache.dubbo.config.annotation.DubboService;
  14. import org.apache.dubbo.config.annotation.Method;
  15. import org.springframework.beans.factory.annotation.Autowired;
  16. import java.util.List;
  17. /**
  18. * @ClassName TableAreaFaceImpl.java
  19. * @Description 桌台区域dubbo服务
  20. */
  21. @Slf4j
  22. @DubboService(version = "${dubbo.application.version}",timeout = 5000,
  23. methods ={
  24. @Method(name = "findTableAreaVoPage",retries = 2),
  25. @Method(name = "createTableArea",retries = 0),
  26. @Method(name = "updateTableArea",retries = 0),
  27. @Method(name = "deleteTableArea",retries = 0)
  28. })
  29. public class TableAreaFaceImpl implements TableAreaFace {
  30. @Autowired
  31. ITableAreaService tableAreaService;
  32. @Override
  33. public Page<TableAreaVo> findTableAreaVoPage(TableAreaVo tableAreaVo,
  34. int pageNum,
  35. int pageSize)throws ProjectException {
  36. try {
  37. //查询区域分页
  38. Page<TableArea> page = tableAreaService.findTableAreaVoPage(tableAreaVo, pageNum, pageSize);
  39. Page<TableAreaVo> pageVo = new Page<>();
  40. BeanConv.toBean(page,pageVo);
  41. //结果集转换
  42. List<TableArea> tableAreaList = page.getRecords();
  43. List<TableAreaVo> tableAreaVoList = BeanConv.toBeanList(tableAreaList,TableAreaVo.class);
  44. pageVo.setRecords(tableAreaVoList);
  45. //返回结果
  46. return pageVo;
  47. } catch (Exception e) {
  48. log.error("查询区域列表异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  49. throw new ProjectException(TableAreaEnum.PAGE_FAIL);
  50. }
  51. }
  52. @Override
  53. public TableAreaVo createTableArea(TableAreaVo tableAreaVo) throws ProjectException{
  54. try {
  55. //创建区域
  56. return BeanConv.toBean( tableAreaService.createTableArea(tableAreaVo), TableAreaVo.class);
  57. } catch (Exception e) {
  58. log.error("保存区域异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  59. throw new ProjectException(TableAreaEnum.CREATE_FAIL);
  60. }
  61. }
  62. @Override
  63. public Boolean updateTableArea(TableAreaVo tableAreaVo) throws ProjectException{
  64. try {
  65. //修改区域
  66. return tableAreaService.updateTableArea(tableAreaVo);
  67. } catch (Exception e) {
  68. log.error("保存区域异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  69. throw new ProjectException(TableAreaEnum.UPDATE_FAIL);
  70. }
  71. }
  72. @Override
  73. public Boolean deleteTableArea(String[] checkedIds)throws ProjectException {
  74. try {
  75. //删除区域
  76. return tableAreaService.deleteTableArea(checkedIds);
  77. } catch (Exception e) {
  78. log.error("删除区域异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  79. throw new ProjectException(TableAreaEnum.DELETE_FAIL);
  80. }
  81. }
  82. @Override
  83. public TableAreaVo findTableAreaByTableAreaId(Long tableAreaId)throws ProjectException {
  84. try {
  85. //按id查询区域
  86. TableArea tableArea = tableAreaService.getById(tableAreaId);
  87. if (!EmptyUtil.isNullOrEmpty(tableArea)){
  88. return BeanConv.toBean(tableArea,TableAreaVo.class);
  89. }
  90. return null;
  91. } catch (Exception e) {
  92. log.error("查找区域所有区域异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  93. throw new ProjectException(TableAreaEnum.SELECT_AREA_FAIL);
  94. }
  95. }
  96. @Override
  97. public List<TableAreaVo> findTableAreaVoList()throws ProjectException {
  98. try {
  99. //查询区域
  100. return BeanConv.toBeanList(tableAreaService.findTableAreaVoList(),TableAreaVo.class);
  101. } catch (Exception e) {
  102. log.error("查找区域所有区域异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  103. throw new ProjectException(TableAreaEnum.SELECT_AREA_LIST_FAIL);
  104. }
  105. }
  106. }

3.3、ITableAreaService业务接口

ITableAreaService:区域管理的业务接口定义,为TableAreaFaceImpl提供核心业务逻辑的定义

  1. package com.itheima.restkeeper.service;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.pojo.TableArea;
  4. import com.itheima.restkeeper.pojo.TableArea;
  5. import com.baomidou.mybatisplus.extension.service.IService;
  6. import com.itheima.restkeeper.req.TableAreaVo;
  7. import java.util.List;
  8. /**
  9. * @Description:桌台区域 服务类
  10. */
  11. public interface ITableAreaService extends IService<TableArea> {
  12. /**
  13. * @Description 区域列表
  14. * @param tableAreaVo 查询条件
  15. * @param pageNum 当前页
  16. * @param pageSize 每页大小
  17. * @return Page<TableArea>
  18. */
  19. Page<TableArea> findTableAreaVoPage(TableAreaVo tableAreaVo, int pageNum, int pageSize);
  20. /**
  21. * @Description 创建区域
  22. * @param tableAreaVo 对象信息
  23. * @return TableArea
  24. */
  25. TableArea createTableArea(TableAreaVo tableAreaVo);
  26. /**
  27. * @Description 修改区域
  28. * @param tableAreaVo 对象信息
  29. * @return Boolean
  30. */
  31. Boolean updateTableArea(TableAreaVo tableAreaVo);
  32. /**
  33. * @Description 删除区域
  34. * @param checkedIds 选择的区域ID
  35. * @return Boolean
  36. */
  37. Boolean deleteTableArea(String[] checkedIds);
  38. /***
  39. * @description 查询区域下拉框
  40. * @return: List<TableArea>
  41. */
  42. List<TableArea> findTableAreaVoList();
  43. }

3.4、TableAreaServiceImpl接口实现

TableAreaServiceImpl:区域管理的业务接口定义实现

  1. package com.itheima.restkeeper.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  4. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  5. import com.itheima.restkeeper.basic.BasicPojo;
  6. import com.itheima.restkeeper.constant.SuperConstant;
  7. import com.itheima.restkeeper.mapper.TableAreaMapper;
  8. import com.itheima.restkeeper.pojo.TableArea;
  9. import com.itheima.restkeeper.req.TableAreaVo;
  10. import com.itheima.restkeeper.service.ITableAreaService;
  11. import com.itheima.restkeeper.utils.BeanConv;
  12. import com.itheima.restkeeper.utils.EmptyUtil;
  13. import org.springframework.stereotype.Service;
  14. import java.util.ArrayList;
  15. import java.util.Arrays;
  16. import java.util.List;
  17. /**
  18. * @Description:桌台区域 服务实现类
  19. */
  20. @Service
  21. public class TableAreaServiceImpl extends ServiceImpl<TableAreaMapper, TableArea> implements ITableAreaService {
  22. @Override
  23. public Page<TableArea> findTableAreaVoPage(TableAreaVo tableAreaVo, int pageNum, int pageSize) {
  24. //构建分页对象
  25. Page<TableArea> page = new Page<>(pageNum,pageSize);
  26. QueryWrapper<TableArea> queryWrapper = new QueryWrapper<>();
  27. //按区域名称查询
  28. if (!EmptyUtil.isNullOrEmpty(tableAreaVo.getAreaName())) {
  29. queryWrapper.lambda().likeRight(TableArea::getAreaName,tableAreaVo.getAreaName());
  30. }
  31. //按是否有效查询
  32. if (!EmptyUtil.isNullOrEmpty(tableAreaVo.getEnableFlag())) {
  33. queryWrapper.lambda().eq(TableArea::getEnableFlag,tableAreaVo.getEnableFlag());
  34. }
  35. //按sortNo升序排列
  36. queryWrapper.lambda().orderByAsc(TableArea::getSortNo);
  37. //返回结果
  38. return page(page, queryWrapper);
  39. }
  40. @Override
  41. public TableArea createTableArea(TableAreaVo tableAreaVo) {
  42. //转换TableAreaVo为TableArea
  43. TableArea tableArea = BeanConv.toBean(tableAreaVo, TableArea.class);
  44. //执行保存
  45. boolean flag = save(tableArea);
  46. if (flag){
  47. return tableArea;
  48. }
  49. return null;
  50. }
  51. @Override
  52. public Boolean updateTableArea(TableAreaVo tableAreaVo) {
  53. //转换TableAreaVo为TableArea
  54. TableArea tableArea = BeanConv.toBean(tableAreaVo, TableArea.class);
  55. //按ID执行修改
  56. return updateById(tableArea);
  57. }
  58. @Override
  59. public Boolean deleteTableArea(String[] checkedIds) {
  60. //构建选中的List<Sring>集合
  61. List<String> ids = Arrays.asList(checkedIds);
  62. List<Long> idsLong = new ArrayList<>();
  63. ids.forEach(n->{
  64. idsLong.add(Long.valueOf(n));
  65. });
  66. //批量删除
  67. return removeByIds(idsLong);
  68. }
  69. @Override
  70. public List<TableArea> findTableAreaVoList() {
  71. //构建查询条件
  72. QueryWrapper<TableArea> queryWrapper = new QueryWrapper<>();
  73. queryWrapper.lambda().eq(BasicPojo::getEnableFlag, SuperConstant.YES);
  74. //执行list查询
  75. return list(queryWrapper);
  76. }
  77. }

3.5、TableAreaController类

TableAreaController:对TableAreaFace接口进行dubbo的RPC调用,为dubbo服务的消费者

  1. package com.itheima.restkeeper.web;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.TableAreaFace;
  4. import com.itheima.restkeeper.basic.ResponseWrap;
  5. import com.itheima.restkeeper.enums.TableAreaEnum;
  6. import com.itheima.restkeeper.exception.ProjectException;
  7. import com.itheima.restkeeper.req.TableAreaVo;
  8. import com.itheima.restkeeper.utils.EmptyUtil;
  9. import com.itheima.restkeeper.utils.ExceptionsUtil;
  10. import com.itheima.restkeeper.utils.ResponseWrapBuild;
  11. import io.swagger.annotations.Api;
  12. import io.swagger.annotations.ApiImplicitParam;
  13. import io.swagger.annotations.ApiImplicitParams;
  14. import io.swagger.annotations.ApiOperation;
  15. import lombok.extern.slf4j.Slf4j;
  16. import org.apache.dubbo.config.annotation.DubboReference;
  17. import org.springframework.validation.annotation.Validated;
  18. import org.springframework.web.bind.annotation.*;
  19. import java.util.List;
  20. /**
  21. * @ClassName TableAreaController.java
  22. * @Description 区域Controller
  23. */
  24. @RestController
  25. @RequestMapping("table-area")
  26. @Slf4j
  27. @Api(tags = "区域controller")
  28. public class TableAreaController {
  29. @DubboReference(version = "${dubbo.application.version}",check = false)
  30. TableAreaFace tableAreaFace;
  31. /**
  32. * @Description 区域列表
  33. * @param tableAreaVo 查询条件
  34. * @return
  35. */
  36. @PostMapping("page/{pageNum}/{pageSize}")
  37. @ApiOperation(value = "查询区域分页",notes = "查询区域分页")
  38. @ApiImplicitParams({
  39. @ApiImplicitParam(name = "tableAreaVo",value = "区域查询对象",dataType = "TableAreaVo"),
  40. @ApiImplicitParam(paramType = "path",name = "pageNum",value = "页码",dataType = "Integer"),
  41. @ApiImplicitParam(paramType = "path",name = "pageSize",value = "每页条数",dataType = "Integer")
  42. })
  43. public ResponseWrap<Page<TableAreaVo>> findTableAreaVoPage(
  44. @RequestBody TableAreaVo tableAreaVo,
  45. @PathVariable("pageNum") int pageNum,
  46. @PathVariable("pageSize") int pageSize) {
  47. Page<TableAreaVo> tableAreaVoPage = tableAreaFace.findTableAreaVoPage(tableAreaVo, pageNum, pageSize);
  48. return ResponseWrapBuild.build(TableAreaEnum.SUCCEED,tableAreaVoPage);
  49. }
  50. /**
  51. * @Description 添加区域
  52. * @param tableAreaVo 对象信息
  53. * @return
  54. */
  55. @PostMapping
  56. @ApiOperation(value = "添加区域",notes = "添加区域")
  57. @ApiImplicitParam(name = "tableAreaVo",value = "区域对象",required = true,dataType = "TableAreaVo")
  58. ResponseWrap<TableAreaVo> createTableArea(@RequestBody TableAreaVo tableAreaVo) {
  59. TableAreaVo tableAreaVoResult = tableAreaFace.createTableArea(tableAreaVo);
  60. return ResponseWrapBuild.build(TableAreaEnum.SUCCEED,tableAreaVoResult);
  61. }
  62. /**
  63. * @Description 修改区域
  64. * @param tableAreaVo 对象信息
  65. * @return
  66. */
  67. @PatchMapping
  68. @ApiOperation(value = "修改区域",notes = "修改区域")
  69. @ApiImplicitParam(name = "tableAreaVo",value = "区域对象",required = true,dataType = "TableAreaVo")
  70. ResponseWrap<Boolean> updateTableArea(@RequestBody TableAreaVo tableAreaVo) {
  71. Boolean flag = tableAreaFace.updateTableArea(tableAreaVo);
  72. return ResponseWrapBuild.build(TableAreaEnum.SUCCEED,flag);
  73. }
  74. /**
  75. * @Description 删除区域
  76. * @param tableAreaVo 查询对象
  77. * @return
  78. */
  79. @DeleteMapping
  80. @ApiOperation(value = "删除区域",notes = "删除区域")
  81. @ApiImplicitParam(name = "tableAreaVo",value = "区域查询对象",required = true,dataType = "TableAreaVo")
  82. ResponseWrap<Boolean> deleteTableArea(@RequestBody TableAreaVo tableAreaVo ) {
  83. //获得所有选择的区域IDS
  84. String[] checkedIds = tableAreaVo.getCheckedIds();
  85. Boolean flag = tableAreaFace.deleteTableArea(checkedIds);
  86. return ResponseWrapBuild.build(TableAreaEnum.SUCCEED,flag);
  87. }
  88. /**
  89. * @Description 查找区域
  90. * @param tableAreaId 区域id
  91. * @return
  92. */
  93. @GetMapping("{tableAreaId}")
  94. @ApiOperation(value = "查找区域",notes = "查找区域")
  95. @ApiImplicitParam(paramType = "path",name = "tableAreaId",value = "区域Id",example = "1",dataType = "Long")
  96. ResponseWrap<TableAreaVo> findTableAreaByTableAreaId(@PathVariable("tableAreaId") Long tableAreaId) {
  97. TableAreaVo tableAreaVo = tableAreaFace.findTableAreaByTableAreaId(tableAreaId);
  98. return ResponseWrapBuild.build(TableAreaEnum.SUCCEED, tableAreaVo);
  99. }
  100. /**
  101. * @Description 查找区域
  102. * @return
  103. */
  104. @GetMapping("list")
  105. @ApiOperation(value = "查找区域列表",notes = "查找区域列表")
  106. ResponseWrap<List<TableAreaVo>> findTableAreaVoList() {
  107. List<TableAreaVo> list = tableAreaFace.findTableAreaVoList();
  108. return ResponseWrapBuild.build(TableAreaEnum.SUCCEED,list);
  109. }
  110. @PostMapping("update-tableArea-enableFlag")
  111. @ApiOperation(value = "修改区域状态",notes = "修改区域状态")
  112. ResponseWrap<Boolean> updateTableAreaEnableFlag(@RequestBody TableAreaVo tableAreaVo) {
  113. Boolean flag = tableAreaFace.updateTableArea(tableAreaVo);
  114. return ResponseWrapBuild.build(TableAreaEnum.SUCCEED,flag);
  115. }
  116. }

第二章 商家平台-桌台管理

  1. 商家建立区域后,需要为区域指定对于的桌台,桌台的就餐人数,以及各种状态【空闲、开桌、锁桌】等切换,注意的桌台的数据归属我们采用多租户功能区实现这里不需要考虑【多租户】后面有专题去简介

image.png

1、功能区拆解

image.png

红色区域:此处为查询条件功能区,筛选列表信息

功能 说明
桌台名称 输入桌台名称,键盘按enter触发搜索列表
就餐人数 输入就餐人数,键盘按enter触发搜索列
桌台状体 下拉框,显示【空闲、开台、锁桌】,change触发搜索列表
状态 下拉框,显示【启用、禁用】,change触发搜索列表

蓝色区域:桌台维护功能

功能 说明
添加 新增桌台信息
修改 修改桌台信息
删除 删除桌台信息==【真实删除】==,删除时,会有再次确认提示
禁用、启用 禁用启用桌台
空闲、锁台 切换桌台状态

2、数据库结构

  1. CREATE TABLE `tab_table` (
  2. `id` bigint(18) NOT NULL COMMENT '桌台id',
  3. `area_id` bigint(18) DEFAULT NULL COMMENT '区域ID',
  4. `table_name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '桌台名称',
  5. `table_seat_number` int(11) NOT NULL COMMENT '桌台座位数目',
  6. `table_status` varchar(32) COLLATE utf8_bin NOT NULL COMMENT 'FREE:空闲 USER:开桌 lOCK 锁桌',
  7. `created_time` datetime DEFAULT NULL COMMENT '创建时间',
  8. `updated_time` datetime DEFAULT NULL COMMENT '创建时间',
  9. `sharding_id` bigint(18) DEFAULT NULL COMMENT '分库id',
  10. `store_id` bigint(18) NOT NULL COMMENT '门店主键id',
  11. `enterprise_id` bigint(18) NOT NULL COMMENT '商户号',
  12. `sort_no` int(11) DEFAULT NULL COMMENT '排序',
  13. `enable_flag` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT '是否有效',
  14. PRIMARY KEY (`id`)
  15. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='桌台';

自动填充

下列字段,无需手动填充,系统会自动填充下列字段

字段 注释 填充方式
id 主键 雪花算法
enterprise_id 商户号 mybatis-plus-多租户拦截
created_time 创建时间 mybatis-plus-自动填充组件
updated_time 修改时间 mybatis-plus-自动填充组件
sharding_id 分库id mybatis-plus-自动填充组件
store_id 门店id mybatis-plus-多租户拦截

3、功能开发

image.png

TableController:对TableFace接口进行dubbo的RPC调用,为dubbo服务的消费者

TableFace:桌台管理dubbo接口定义

TableFaceImpl:桌台管理dubbo接口定义实现,这里做VO和POJO的转换

ITableService:桌台管理的业务接口定义,为TableFaceImpl提供核心业务逻辑的定义

TableServiceImpl:桌台管理的业务接口定义实现

3.1、TableFace接口

桌台管理dubbo接口定义

  1. package com.itheima.restkeeper;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.exception.ProjectException;
  4. import com.itheima.restkeeper.req.TableVo;
  5. import java.util.List;
  6. /**
  7. * @Description 桌台dubbo接口服务
  8. */
  9. public interface TableFace {
  10. /**
  11. * @param tableVo 查询条件
  12. * @param pageNum 当前页
  13. * @param pageSize 每页大小
  14. * @return
  15. * @Description 桌台列表
  16. */
  17. Page<TableVo> findTableVoPage(TableVo tableVo,
  18. int pageNum,
  19. int pageSize)throws ProjectException;
  20. /**
  21. * @param tableVo 对象信息
  22. * @return TableVo
  23. * @Description 创建桌台
  24. */
  25. TableVo createTable(TableVo tableVo)throws ProjectException;
  26. /**
  27. * @param tableVo 对象信息
  28. * @return Boolean
  29. * @Description 修改桌台
  30. */
  31. Boolean updateTable(TableVo tableVo)throws ProjectException;
  32. /**
  33. * @param checkedIds 选择对象信息Id
  34. * @return Boolean
  35. * @Description 删除桌台
  36. */
  37. Boolean deleteTable(String[] checkedIds)throws ProjectException;
  38. /**
  39. * @param tableId 选择对象信息Id
  40. * @return TableVo
  41. * @Description 查找桌台
  42. */
  43. TableVo findTableByTableId(Long tableId)throws ProjectException;
  44. /***
  45. * @description 查询桌台下拉框
  46. * @return: List<TableVo>
  47. */
  48. List<TableVo> findTableVoList()throws ProjectException;
  49. }

3.2、TableFaceImpl接口实现

桌台管理dubbo接口定义实现,这里做VO和POJO的转换

  1. package com.itheima.restkeeper.face;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.TableFace;
  4. import com.itheima.restkeeper.enums.TableEnum;
  5. import com.itheima.restkeeper.exception.ProjectException;
  6. import com.itheima.restkeeper.pojo.Table;
  7. import com.itheima.restkeeper.req.TableVo;
  8. import com.itheima.restkeeper.service.ITableService;
  9. import com.itheima.restkeeper.utils.BeanConv;
  10. import com.itheima.restkeeper.utils.EmptyUtil;
  11. import com.itheima.restkeeper.utils.ExceptionsUtil;
  12. import com.itheima.restkeeper.utils.ResponseWrapBuild;
  13. import io.seata.spring.annotation.GlobalTransactional;
  14. import lombok.extern.slf4j.Slf4j;
  15. import org.apache.dubbo.config.annotation.DubboService;
  16. import org.apache.dubbo.config.annotation.Method;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import java.util.List;
  19. /**
  20. * @Description 桌台dubbo接口实现
  21. */
  22. @Slf4j
  23. @DubboService(version = "${dubbo.application.version}",timeout = 5000,
  24. methods ={
  25. @Method(name = "findTableVoPage",retries = 2),
  26. @Method(name = "createTable",retries = 0),
  27. @Method(name = "updateTable",retries = 0),
  28. @Method(name = "deleteTable",retries = 0)
  29. })
  30. public class TableFaceImpl implements TableFace {
  31. @Autowired
  32. ITableService tableService;
  33. @Override
  34. public Page<TableVo> findTableVoPage(TableVo tableVo,
  35. int pageNum,
  36. int pageSize) throws ProjectException{
  37. try {
  38. //查询所有桌台
  39. Page<Table> page = tableService.findTableVoPage(tableVo, pageNum, pageSize);
  40. Page<TableVo> pageVo = new Page<>();
  41. BeanConv.toBean(page,pageVo);
  42. //结果集转换
  43. List<Table> tableList = page.getRecords();
  44. List<TableVo> tableVoList = BeanConv.toBeanList(tableList,TableVo.class);
  45. pageVo.setRecords(tableVoList);
  46. return pageVo;
  47. } catch (Exception e) {
  48. log.error("查询桌台列表异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  49. throw new ProjectException(TableEnum.SELECT_TABLE_LIST_FAIL);
  50. }
  51. }
  52. @Override
  53. public TableVo createTable(TableVo tableVo) throws ProjectException{
  54. try {
  55. //添加桌台
  56. return BeanConv.toBean( tableService.createTable(tableVo), TableVo.class);
  57. } catch (Exception e) {
  58. log.error("保存桌台异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  59. throw new ProjectException(TableEnum.CREATE_FAIL);
  60. }
  61. }
  62. @Override
  63. @GlobalTransactional
  64. public Boolean updateTable(TableVo tableVo) throws ProjectException{
  65. try {
  66. //修改桌台
  67. return tableService.updateTable(tableVo);
  68. } catch (Exception e) {
  69. log.error("保存桌台异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  70. throw new ProjectException(TableEnum.UPDATE_FAIL);
  71. }
  72. }
  73. @Override
  74. public Boolean deleteTable(String[] checkedIds) throws ProjectException{
  75. try {
  76. //删除桌台
  77. return tableService.deleteTable(checkedIds);
  78. } catch (Exception e) {
  79. log.error("删除桌台异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  80. throw new ProjectException(TableEnum.DELETE_FAIL);
  81. }
  82. }
  83. @Override
  84. public TableVo findTableByTableId(Long tableId)throws ProjectException {
  85. try {
  86. //按ID查询桌台
  87. Table table = tableService.getById(tableId);
  88. if (!EmptyUtil.isNullOrEmpty(table)){
  89. return BeanConv.toBean(table,TableVo.class);
  90. }
  91. return null;
  92. } catch (Exception e) {
  93. log.error("查找桌台所有桌台异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  94. throw new ProjectException(TableEnum.SELECT_TABLE_FAIL);
  95. }
  96. }
  97. @Override
  98. public List<TableVo> findTableVoList()throws ProjectException {
  99. try {
  100. //查询桌台列表,用在哪里?是否要注意状态
  101. return BeanConv.toBeanList(tableService.findTableVoList(),TableVo.class);
  102. } catch (Exception e) {
  103. log.error("查找桌台所有桌台异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  104. throw new ProjectException(TableEnum.SELECT_TABLE_LIST_FAIL);
  105. }
  106. }
  107. }

3.3、ITableService业务接口

桌台管理的业务接口定义,为TableFaceImpl提供核心业务逻辑的定义

  1. package com.itheima.restkeeper.service;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.baomidou.mybatisplus.extension.service.IService;
  4. import com.itheima.restkeeper.pojo.Table;
  5. import com.itheima.restkeeper.req.TableVo;
  6. import java.util.List;
  7. /**
  8. * @Description:桌台服务类
  9. */
  10. public interface ITableService extends IService<Table> {
  11. /**
  12. * @param tableVo 查询条件
  13. * @param pageNum 当前页
  14. * @param pageSize 每页大小
  15. * @return Page<Table>
  16. * @Description 门店列表
  17. */
  18. Page<Table> findTableVoPage(TableVo tableVo, int pageNum, int pageSize);
  19. /**
  20. * @param tableVo 对象信息
  21. * @return Table
  22. * @Description 创建门店
  23. */
  24. Table createTable(TableVo tableVo);
  25. /**
  26. * @param tableVo 对象信息
  27. * @return Boolean
  28. * @Description 修改门店
  29. */
  30. Boolean updateTable(TableVo tableVo);
  31. /**
  32. * @param checkedIds 选择的门店ID
  33. * @return Boolean
  34. * @Description 删除门店
  35. */
  36. Boolean deleteTable(String[] checkedIds);
  37. /***
  38. * @description 查询门店下拉框
  39. * @return: List<Table>
  40. */
  41. List<Table> findTableVoList();
  42. /***
  43. * @description 当桌台处于空闲状态,进行开桌
  44. * @param tableVo
  45. * @return
  46. */
  47. Boolean openTable(TableVo tableVo);
  48. }

3.4、TableServiceImpl业务接口实现

桌台管理的业务接口定义实现

  1. package com.itheima.restkeeper.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  4. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  5. import com.itheima.restkeeper.basic.BasicPojo;
  6. import com.itheima.restkeeper.constant.SuperConstant;
  7. import com.itheima.restkeeper.pojo.Table;
  8. import com.itheima.restkeeper.mapper.TableMapper;
  9. import com.itheima.restkeeper.req.TableVo;
  10. import com.itheima.restkeeper.service.ITableService;
  11. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  12. import com.itheima.restkeeper.utils.BeanConv;
  13. import com.itheima.restkeeper.utils.EmptyUtil;
  14. import org.springframework.stereotype.Service;
  15. import java.util.ArrayList;
  16. import java.util.Arrays;
  17. import java.util.List;
  18. /**
  19. * @Description:桌台 服务实现类
  20. */
  21. @Service
  22. public class TableServiceImpl extends ServiceImpl<TableMapper, Table> implements ITableService {
  23. @Override
  24. public Page<Table> findTableVoPage(TableVo tableVo,int pageNum,int pageSize) {
  25. //构建分页对象
  26. Page<Table> page = new Page<>(pageNum,pageSize);
  27. QueryWrapper<Table> queryWrapper = new QueryWrapper<>();
  28. //按桌台名称查询
  29. if (!EmptyUtil.isNullOrEmpty(tableVo.getTableName())) {
  30. queryWrapper.lambda().likeRight(Table::getTableName,tableVo.getTableName());
  31. }
  32. //按就餐人数查询
  33. if (!EmptyUtil.isNullOrEmpty(tableVo.getTableSeatNumber())) {
  34. queryWrapper.lambda().eq(Table::getTableSeatNumber,tableVo.getTableSeatNumber());
  35. }
  36. //按桌台使用状态查询
  37. if (!EmptyUtil.isNullOrEmpty(tableVo.getTableStatus())) {
  38. queryWrapper.lambda().eq(Table::getTableStatus,tableVo.getTableStatus());
  39. }
  40. //按桌台有效性查询
  41. if (!EmptyUtil.isNullOrEmpty(tableVo.getEnableFlag())) {
  42. queryWrapper.lambda().eq(Table::getEnableFlag,tableVo.getEnableFlag());
  43. }
  44. //按sortNo升序排列
  45. queryWrapper.lambda().orderByAsc(Table::getSortNo);
  46. //返回分页结果
  47. return page(page,queryWrapper);
  48. }
  49. @Override
  50. public Table createTable(TableVo tableVo) {
  51. //转换TableVo为Table
  52. Table table = BeanConv.toBean(tableVo, Table.class);
  53. //执行保存
  54. boolean flag = save(table);
  55. if (flag){
  56. return table;
  57. }
  58. return null;
  59. }
  60. @Override
  61. public Boolean updateTable(TableVo tableVo) {
  62. //转换TableVo为Table
  63. Table table = BeanConv.toBean(tableVo, Table.class);
  64. //执行按ID进行修改
  65. return updateById(table);
  66. }
  67. @Override
  68. public Boolean deleteTable(String[] checkedIds) {
  69. //构建选择ids的List<String>集合
  70. List<String> ids = Arrays.asList(checkedIds);
  71. List<Long> idsLong = new ArrayList<>();
  72. ids.forEach(n->{
  73. idsLong.add(Long.valueOf(n));
  74. });
  75. //执行批量移除
  76. return removeByIds(idsLong);
  77. }
  78. @Override
  79. public List<Table> findTableVoList() {
  80. //构建查询条件:有效状态
  81. QueryWrapper<Table> queryWrapper = new QueryWrapper<>();
  82. queryWrapper.lambda().eq(BasicPojo::getEnableFlag, SuperConstant.YES);
  83. //执行list查询
  84. return list(queryWrapper);
  85. }
  86. @Override
  87. public Boolean openTable(TableVo tableVo) {
  88. //构建条件:SuperConstant.FREE
  89. LambdaQueryWrapper<Table> lambdaQueryWrapper = new LambdaQueryWrapper();
  90. lambdaQueryWrapper
  91. .eq(Table::getTableStatus,SuperConstant.FREE).eq(Table::getId,tableVo.getId());
  92. //执行update条件查询
  93. return update(BeanConv.toBean(tableVo,Table.class),lambdaQueryWrapper);
  94. }
  95. }

3.5、TableController类

对TableFace接口进行dubbo的RPC调用,为dubbo服务的消费者

  1. package com.itheima.restkeeper.web;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.TableFace;
  4. import com.itheima.restkeeper.basic.ResponseWrap;
  5. import com.itheima.restkeeper.enums.TableEnum;
  6. import com.itheima.restkeeper.exception.ProjectException;
  7. import com.itheima.restkeeper.req.TableVo;
  8. import com.itheima.restkeeper.utils.EmptyUtil;
  9. import com.itheima.restkeeper.utils.ExceptionsUtil;
  10. import com.itheima.restkeeper.utils.ResponseWrapBuild;
  11. import io.swagger.annotations.Api;
  12. import io.swagger.annotations.ApiImplicitParam;
  13. import io.swagger.annotations.ApiImplicitParams;
  14. import io.swagger.annotations.ApiOperation;
  15. import lombok.extern.slf4j.Slf4j;
  16. import org.apache.dubbo.config.annotation.DubboReference;
  17. import org.springframework.web.bind.annotation.*;
  18. import java.util.List;
  19. /**
  20. * @ClassName TableController.java
  21. * @Description 桌台Controller
  22. */
  23. @RestController
  24. @RequestMapping("table")
  25. @Slf4j
  26. @Api(tags = "桌台controller")
  27. public class TableController {
  28. @DubboReference(version = "${dubbo.application.version}",check = false)
  29. TableFace tableFace;
  30. /**
  31. * @Description 桌台列表
  32. * @param tableVo 查询条件
  33. * @return
  34. */
  35. @PostMapping("page/{pageNum}/{pageSize}")
  36. @ApiOperation(value = "查询桌台list",notes = "查询桌台list")
  37. @ApiImplicitParams({
  38. @ApiImplicitParam(name = "tableVo",value = "桌台查询对象",dataType = "TableVo"),
  39. @ApiImplicitParam(paramType = "path",name = "pageNum",value = "页码",dataType = "Integer"),
  40. @ApiImplicitParam(paramType = "path",name = "pageSize",value = "每页条数",dataType = "Integer")
  41. })
  42. public ResponseWrap<Page<TableVo>> findTableVoPage(
  43. @RequestBody TableVo tableVo,
  44. @PathVariable("pageNum") int pageNum,
  45. @PathVariable("pageSize") int pageSize) {
  46. Page<TableVo> tableVoList = tableFace.findTableVoPage(tableVo,pageNum,pageSize);
  47. return ResponseWrapBuild.build(TableEnum.SUCCEED,tableVoList);
  48. }
  49. /**
  50. * @Description 添加桌台
  51. * @param tableVo 对象信息
  52. * @return
  53. */
  54. @PostMapping
  55. @ApiOperation(value = "添加桌台",notes = "添加桌台")
  56. @ApiImplicitParam(name = "tableVo",value = "桌台对象",required = true,dataType = "TableVo")
  57. ResponseWrap<TableVo> createTable(@RequestBody TableVo tableVo) {
  58. TableVo tableVoResult = tableFace.createTable(tableVo);
  59. return ResponseWrapBuild.build(TableEnum.SUCCEED,tableVoResult);
  60. }
  61. /**
  62. * @Description 修改桌台
  63. * @param tableVo 对象信息
  64. * @return
  65. */
  66. @PatchMapping
  67. @ApiOperation(value = "修改桌台",notes = "修改桌台")
  68. @ApiImplicitParam(name = "tableVo",value = "桌台对象",required = true,dataType = "TableVo")
  69. ResponseWrap<Boolean> updateTable(@RequestBody TableVo tableVo) {
  70. Boolean flag = tableFace.updateTable(tableVo);
  71. return ResponseWrapBuild.build(TableEnum.SUCCEED,flag);
  72. }
  73. /**
  74. * @Description 查找桌台
  75. * @param tableId 桌台id
  76. * @return
  77. */
  78. @GetMapping("{tableId}")
  79. @ApiOperation(value = "查找桌台",notes = "查找桌台")
  80. @ApiImplicitParam(paramType = "path",name = "tableId",value = "桌台Id",dataType = "Long")
  81. ResponseWrap<TableVo> findTableByTableId(@PathVariable("tableId") Long tableId) {
  82. TableVo tableVo = tableFace.findTableByTableId(tableId);
  83. return ResponseWrapBuild.build(TableEnum.SUCCEED,tableVo);
  84. }
  85. /**
  86. * @Description 删除桌台
  87. * @param tableVo 查询对象
  88. * @return
  89. */
  90. @DeleteMapping
  91. @ApiOperation(value = "删除桌台",notes = "删除桌台")
  92. @ApiImplicitParam(name = "tableVo",value = "桌台查询对象",required = true,dataType = "TableVo")
  93. ResponseWrap<Boolean> deleteTable(@RequestBody TableVo tableVo ) {
  94. //拿到选中桌台的IDS
  95. String[] checkedIds = tableVo.getCheckedIds();
  96. Boolean flag = tableFace.deleteTable(checkedIds);
  97. return ResponseWrapBuild.build(TableEnum.SUCCEED,flag);
  98. }
  99. /**
  100. * @Description 查找桌台
  101. * @return
  102. */
  103. @GetMapping("list")
  104. @ApiOperation(value = "查找桌台列表",notes = "查找桌台列表")
  105. ResponseWrap<List<TableVo>> findTableVoList() {
  106. List<TableVo> list = tableFace.findTableVoList();
  107. return ResponseWrapBuild.build(TableEnum.SUCCEED,list);
  108. }
  109. @PostMapping("update-table-enableFlag")
  110. @ApiOperation(value = "修改桌台有效状态",notes = "修改桌台有效状态")
  111. ResponseWrap<Boolean> updateTableEnableFlag(@RequestBody TableVo tableVo) {
  112. Boolean flag = tableFace.updateTable(tableVo);
  113. return ResponseWrapBuild.build(TableEnum.SUCCEED,flag);
  114. }
  115. @PostMapping("update-table-tableStatus")
  116. @ApiOperation(value = "修改桌台状态",notes = "修改桌台状态")
  117. ResponseWrap<Boolean> updateTableStatus(@RequestBody TableVo tableVo) {
  118. Boolean flag = tableFace.updateTable(tableVo);
  119. return ResponseWrapBuild.build(TableEnum.SUCCEED,flag);
  120. }
  121. }

第三章 商家平台-分类管理

  1. 菜品的分类主要是为菜品进行分类,在点餐的app端用户可以根据菜品分类去筛选菜品,帮助用户快速找到锁需要的菜品注意的分类的数据归属我们采用多租户功能区实现这里不需要考虑【多租户】后面有专题去简介

image.png

1、功能区拆解

image.png

红色区域:此处为查询条件功能区,筛选列表信息

功能 说明
分类名称 输入分类名称,键盘按enter触发搜索列表
状态 下拉框,显示【启用、禁用】,change触发搜索列表

蓝色区域:菜品分类维护功能

功能 说明
添加 新增分类信息
修改 修改分类信息
删除 删除分类信息==【真实删除】==,删除时,会有再次确认提示
禁用、启用 禁用启用分类

image.png

在添加或修改菜品分类时候,我们会从数字字典中获得分类类型【菜品、套餐】,用于区分是单个菜品还是套餐

2、数据库结构

  1. CREATE TABLE `tab_category` (
  2. `id` bigint(18) NOT NULL COMMENT '分类id',
  3. `category_type` varchar(11) COLLATE utf8_bin DEFAULT NULL COMMENT '类型 菜品:DISH 套餐:MEAL',
  4. `category_name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '分类名称',
  5. `enable_flag` varchar(18) CHARACTER SET utf8 DEFAULT NULL COMMENT '是否有效',
  6. `created_time` datetime DEFAULT NULL COMMENT '创建时间',
  7. `updated_time` datetime DEFAULT NULL COMMENT '创建时间',
  8. `sharding_id` bigint(18) DEFAULT NULL COMMENT '分库id',
  9. `store_id` bigint(18) NOT NULL COMMENT '门店主键id',
  10. `enterprise_id` bigint(18) NOT NULL COMMENT '商户号',
  11. `sort_no` int(11) DEFAULT NULL COMMENT '排序',
  12. PRIMARY KEY (`id`)
  13. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='菜品及套餐分类';

自动填充

下列字段,无需手动填充,系统会自动填充下列字段

字段 注释 填充方式
id 主键 雪花算法
enterprise_id 商户号 mybatis-plus-多租户拦截
created_time 创建时间 mybatis-plus-自动填充组件
updated_time 修改时间 mybatis-plus-自动填充组件
sharding_id 分库id mybatis-plus-自动填充组件
store_id 门店id mybatis-plus-多租户拦截

3、功能开发

image.png

CategoryController:对CategoryFace接口进行dubbo的RPC调用,为dubbo服务的消费者

CategoryFace:菜品分类管理dubbo接口定义

CategoryFaceImpl:菜品分类管理dubbo接口定义实现,这里做VO和POJO的转换

ICategoryService:菜品分类管理的业务接口定义,为CategoryFaceImpl提供核心业务逻辑的定义

CategoryServiceImpl:菜品分类管理的业务接口定义实现

3.1、CategoryFace接口

品分类管理dubbo接口定义

  1. package com.itheima.restkeeper;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.exception.ProjectException;
  4. import com.itheima.restkeeper.req.CategoryVo;
  5. import java.util.List;
  6. /**
  7. * @ClassName CategoryFace.java
  8. * @Description 菜品分类dubbo服务接口
  9. */
  10. public interface CategoryFace {
  11. /**
  12. * @Description 分类列表
  13. * @param categoryVo 查询条件
  14. * @param pageNum 当前页
  15. * @param pageSize 每页条数
  16. * @return Page<CategoryVo>
  17. */
  18. Page<CategoryVo> findCategoryVoPage(CategoryVo categoryVo,
  19. int pageNum,
  20. int pageSize)throws ProjectException;
  21. /**
  22. * @Description 创建分类
  23. * @param categoryVo 对象信息
  24. * @return CategoryVo
  25. */
  26. CategoryVo createCategory(CategoryVo categoryVo)throws ProjectException;
  27. /**
  28. * @Description 修改分类
  29. * @param categoryVo 对象信息
  30. * @return Boolean
  31. */
  32. Boolean updateCategory(CategoryVo categoryVo)throws ProjectException;
  33. /**
  34. * @Description 删除分类
  35. * @param checkedIds 选择对象信息Id
  36. * @return Boolean
  37. */
  38. Boolean deleteCategory(String[] checkedIds)throws ProjectException;
  39. /**
  40. * @Description 查找分类
  41. * @param categoryId 选择对象信息Id
  42. * @return CategoryVo
  43. */
  44. CategoryVo findCategoryByCategoryId(Long categoryId)throws ProjectException;
  45. /***
  46. * @description 查询分类下拉框
  47. * @return: List<CategoryVo>
  48. */
  49. List<CategoryVo> findCategoryVoList()throws ProjectException;
  50. }

3.2、CategoryFaceImpl接口实现

菜品分类管理dubbo接口定义实现,这里做VO和POJO的转换

  1. package com.itheima.restkeeper.face;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.CategoryFace;
  4. import com.itheima.restkeeper.enums.CategoryEnum;
  5. import com.itheima.restkeeper.exception.ProjectException;
  6. import com.itheima.restkeeper.pojo.Category;
  7. import com.itheima.restkeeper.req.CategoryVo;
  8. import com.itheima.restkeeper.service.ICategoryService;
  9. import com.itheima.restkeeper.utils.BeanConv;
  10. import com.itheima.restkeeper.utils.EmptyUtil;
  11. import com.itheima.restkeeper.utils.ExceptionsUtil;
  12. import lombok.extern.slf4j.Slf4j;
  13. import org.apache.dubbo.config.annotation.DubboService;
  14. import org.apache.dubbo.config.annotation.Method;
  15. import org.springframework.beans.factory.annotation.Autowired;
  16. import java.util.List;
  17. /**
  18. * @ClassName CategoryFaceImpl.java
  19. * @Description 菜品分类dubbo服务接口实现
  20. */
  21. @Slf4j
  22. @DubboService(version = "${dubbo.application.version}",timeout = 5000,
  23. methods ={
  24. @Method(name = "findCategoryVoPage",retries = 2),
  25. @Method(name = "createCategory",retries = 0),
  26. @Method(name = "updateCategory",retries = 0),
  27. @Method(name = "deleteCategory",retries = 0)
  28. })
  29. public class CategoryFaceImpl implements CategoryFace {
  30. @Autowired
  31. ICategoryService categoryService;
  32. @Override
  33. public Page<CategoryVo> findCategoryVoPage(CategoryVo categoryVo,
  34. int pageNum,
  35. int pageSize)throws ProjectException {
  36. try {
  37. //查询分类分页
  38. Page<Category> page = categoryService.findCategoryVoPage(categoryVo, pageNum, pageSize);
  39. Page<CategoryVo> pageVo = new Page<>();
  40. BeanConv.toBean(page,pageVo);
  41. //结果集转换
  42. List<Category> categoryList = page.getRecords();
  43. List<CategoryVo> categoryVoList = BeanConv.toBeanList(categoryList,CategoryVo.class);
  44. pageVo.setRecords(categoryVoList);
  45. //返回结果
  46. return pageVo;
  47. } catch (Exception e) {
  48. log.error("查询分类列表异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  49. throw new ProjectException(CategoryEnum.PAGE_FAIL);
  50. }
  51. }
  52. @Override
  53. public CategoryVo createCategory(CategoryVo categoryVo)throws ProjectException {
  54. try {
  55. //创建分类
  56. return BeanConv.toBean( categoryService.createCategory(categoryVo), CategoryVo.class);
  57. } catch (Exception e) {
  58. log.error("保存分类异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  59. throw new ProjectException(CategoryEnum.CREATE_FAIL);
  60. }
  61. }
  62. @Override
  63. public Boolean updateCategory(CategoryVo categoryVo) throws ProjectException{
  64. try {
  65. //修改分类
  66. return categoryService.updateCategory(categoryVo);
  67. } catch (Exception e) {
  68. log.error("保存分类异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  69. throw new ProjectException(CategoryEnum.UPDATE_FAIL);
  70. }
  71. }
  72. @Override
  73. public Boolean deleteCategory(String[] checkedIds) {
  74. try {
  75. //删除分类
  76. return categoryService.deleteCategory(checkedIds);
  77. } catch (Exception e) {
  78. log.error("删除分类异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  79. throw new ProjectException(CategoryEnum.DELETE_FAIL);
  80. }
  81. }
  82. @Override
  83. public CategoryVo findCategoryByCategoryId(Long categoryId)throws ProjectException {
  84. try {
  85. //按分类id查询分类
  86. Category category = categoryService.getById(categoryId);
  87. if (!EmptyUtil.isNullOrEmpty(category)){
  88. return BeanConv.toBean(category,CategoryVo.class);
  89. }
  90. return null;
  91. } catch (Exception e) {
  92. log.error("查找分类所有分类异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  93. throw new ProjectException(CategoryEnum.SELECT_CATEGORY_FAIL);
  94. }
  95. }
  96. @Override
  97. public List<CategoryVo> findCategoryVoList()throws ProjectException {
  98. try {
  99. //查询分类下拉框
  100. return BeanConv.toBeanList(categoryService.findCategoryVoList(),CategoryVo.class);
  101. } catch (Exception e) {
  102. log.error("查找分类所有分类异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  103. throw new ProjectException(CategoryEnum.SELECT_CATEGORY_LIST_FAIL);
  104. }
  105. }
  106. }

3.3、ICategoryService业务接口

菜品分类管理的业务接口定义,为CategoryFaceImpl提供核心业务逻辑的定义

  1. package com.itheima.restkeeper.service;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.baomidou.mybatisplus.extension.service.IService;
  4. import com.itheima.restkeeper.pojo.Category;
  5. import com.itheima.restkeeper.req.CategoryVo;
  6. import java.util.List;
  7. /**
  8. * @Description:菜品及套餐分类 服务类
  9. */
  10. public interface ICategoryService extends IService<Category> {
  11. /**
  12. * @Description 分类列表
  13. * @param categoryVo 查询条件
  14. * @param pageNum 当前页
  15. * @param pageSize 当前页
  16. * @return Page<Category>
  17. */
  18. Page<Category> findCategoryVoPage(CategoryVo categoryVo, int pageNum, int pageSize);
  19. /**
  20. * @Description 创建分类
  21. * @param categoryVo 对象信息
  22. * @return Category
  23. */
  24. Category createCategory(CategoryVo categoryVo);
  25. /**
  26. * @Description 修改分类
  27. * @param categoryVo 对象信息
  28. * @return Boolean
  29. */
  30. Boolean updateCategory(CategoryVo categoryVo);
  31. /**
  32. * @Description 删除分类
  33. * @param checkedIds 选择的分类ID
  34. * @return Boolean
  35. */
  36. Boolean deleteCategory(String[] checkedIds);
  37. /***
  38. * @description 查询分类下拉框
  39. * @return: List<Category>
  40. */
  41. List<Category> findCategoryVoList();
  42. /***
  43. * @description 查询当前门店的分类
  44. * @param storeId
  45. * @return List<Category>
  46. */
  47. List<Category> findCategoryVoByStoreId(Long storeId);
  48. }

3.4、CategoryServiceImpl业务接口实现

菜品分类管理的业务接口定义实现

  1. package com.itheima.restkeeper.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  4. import com.itheima.restkeeper.basic.BasicPojo;
  5. import com.itheima.restkeeper.constant.SuperConstant;
  6. import com.itheima.restkeeper.pojo.Category;
  7. import com.itheima.restkeeper.mapper.CategoryMapper;
  8. import com.itheima.restkeeper.req.CategoryVo;
  9. import com.itheima.restkeeper.service.ICategoryService;
  10. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  11. import com.itheima.restkeeper.utils.BeanConv;
  12. import com.itheima.restkeeper.utils.EmptyUtil;
  13. import org.springframework.stereotype.Service;
  14. import java.util.ArrayList;
  15. import java.util.Arrays;
  16. import java.util.List;
  17. /**
  18. * @Description:菜品分类业务服务实现类
  19. */
  20. @Service
  21. public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {
  22. @Override
  23. public Page<Category> findCategoryVoPage(CategoryVo categoryVo, int pageNum, int pageSize) {
  24. //构建Page<Category>分页对象
  25. Page<Category> page = new Page<>(pageNum,pageSize);
  26. QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
  27. //按分类类型查询
  28. if (!EmptyUtil.isNullOrEmpty(categoryVo.getCategoryType())) {
  29. queryWrapper.lambda().eq(Category::getCategoryType,categoryVo.getCategoryType());
  30. }
  31. //按分类名称查询
  32. if (!EmptyUtil.isNullOrEmpty(categoryVo.getCategoryName())) {
  33. queryWrapper.lambda().likeRight(Category::getCategoryName,categoryVo.getCategoryName());
  34. }
  35. //按分类有效性查询
  36. if (!EmptyUtil.isNullOrEmpty(categoryVo.getEnableFlag())) {
  37. queryWrapper.lambda().eq(Category::getEnableFlag,categoryVo.getEnableFlag());
  38. }
  39. //按sortNo升序排列
  40. queryWrapper.lambda().orderByAsc(Category::getSortNo);
  41. //执行page查询返回结果
  42. return page(page, queryWrapper);
  43. }
  44. @Override
  45. public Category createCategory(CategoryVo categoryVo) {
  46. //转换CategoryVo为Category
  47. Category category = BeanConv.toBean(categoryVo, Category.class);
  48. //执行保存
  49. boolean flag = save(category);
  50. if (flag){
  51. return category;
  52. }
  53. return null;
  54. }
  55. @Override
  56. public Boolean updateCategory(CategoryVo categoryVo) {
  57. //转换CategoryVo为Category
  58. Category category = BeanConv.toBean(categoryVo, Category.class);
  59. //执行updateById修改
  60. return updateById(category);
  61. }
  62. @Override
  63. public Boolean deleteCategory(String[] checkedIds) {
  64. //构建选中ids的List<String>
  65. List<String> ids = Arrays.asList(checkedIds);
  66. List<Long> idsLong = new ArrayList<>();
  67. ids.forEach(n->{
  68. idsLong.add(Long.valueOf(n));
  69. });
  70. //执行removeByIds批量移除
  71. return removeByIds(idsLong);
  72. }
  73. @Override
  74. public List<Category> findCategoryVoList() {
  75. //构建查询条件:SuperConstant.YES
  76. QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
  77. queryWrapper.lambda().eq(BasicPojo::getEnableFlag, SuperConstant.YES);
  78. //执行list查询
  79. return list(queryWrapper);
  80. }
  81. @Override
  82. public List<Category> findCategoryVoByStoreId(Long storeId) {
  83. //构建查询条件:SuperConstant.YES
  84. QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
  85. queryWrapper.lambda().eq(Category::getStoreId,storeId)
  86. .eq(BasicPojo::getEnableFlag, SuperConstant.YES);
  87. //执行list查询
  88. return list(queryWrapper);
  89. }
  90. }

3.5、CategoryController类

对TableFace接口进行dubbo的RPC调用,为dubbo服务的消费者

  1. package com.itheima.restkeeper.web;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.CategoryFace;
  4. import com.itheima.restkeeper.basic.ResponseWrap;
  5. import com.itheima.restkeeper.enums.CategoryEnum;
  6. import com.itheima.restkeeper.exception.ProjectException;
  7. import com.itheima.restkeeper.req.CategoryVo;
  8. import com.itheima.restkeeper.utils.ResponseWrapBuild;
  9. import io.swagger.annotations.Api;
  10. import io.swagger.annotations.ApiImplicitParam;
  11. import io.swagger.annotations.ApiImplicitParams;
  12. import io.swagger.annotations.ApiOperation;
  13. import lombok.extern.slf4j.Slf4j;
  14. import org.apache.dubbo.config.annotation.DubboReference;
  15. import org.springframework.web.bind.annotation.*;
  16. import java.util.List;
  17. /**
  18. * @ClassName CategoryController.java
  19. * @Description 分类Controller
  20. */
  21. @RestController
  22. @RequestMapping("category")
  23. @Slf4j
  24. @Api(tags = "分类controller")
  25. public class CategoryController {
  26. @DubboReference(version = "${dubbo.application.version}",check = false)
  27. CategoryFace categoryFace;
  28. /**
  29. * @Description 分类列表
  30. * @param categoryVo 查询条件
  31. * @return
  32. */
  33. @PostMapping("page/{pageNum}/{pageSize}")
  34. @ApiOperation(value = "查询分类分页",notes = "查询分类分页")
  35. @ApiImplicitParams({
  36. @ApiImplicitParam(name = "categoryVo",value = "分类查询对象",required = false,dataType = "CategoryVo"),
  37. @ApiImplicitParam(paramType = "path",name = "pageNum",value = "页码",dataType = "Integer"),
  38. @ApiImplicitParam(paramType = "path",name = "pageSize",value = "每页条数",dataType = "Integer")
  39. })
  40. public ResponseWrap<Page<CategoryVo>> findCategoryVoPage(
  41. @RequestBody CategoryVo categoryVo,
  42. @PathVariable("pageNum") int pageNum,
  43. @PathVariable("pageSize") int pageSize) {
  44. Page<CategoryVo> categoryVoPage = categoryFace.findCategoryVoPage(categoryVo, pageNum, pageSize);
  45. return ResponseWrapBuild.build(CategoryEnum.SUCCEED,categoryVoPage);
  46. }
  47. /**
  48. * @Description 添加分类
  49. * @param categoryVo 对象信息
  50. * @return
  51. */
  52. @PostMapping
  53. @ApiOperation(value = "添加分类",notes = "添加分类")
  54. @ApiImplicitParam(name = "categoryVo",value = "分类对象",required = true,dataType = "CategoryVo")
  55. ResponseWrap<CategoryVo> createCategory(@RequestBody CategoryVo categoryVo) {
  56. CategoryVo categoryVoResult = categoryFace.createCategory(categoryVo);
  57. return ResponseWrapBuild.build(CategoryEnum.SUCCEED,categoryVoResult);
  58. }
  59. /**
  60. * @Description 修改分类
  61. * @param categoryVo 对象信息
  62. * @return
  63. */
  64. @PatchMapping
  65. @ApiOperation(value = "修改分类",notes = "修改分类")
  66. @ApiImplicitParam(name = "categoryVo",value = "分类对象",required = true,dataType = "CategoryVo")
  67. ResponseWrap<Boolean> updateCategory(@RequestBody CategoryVo categoryVo) {
  68. Boolean flag = categoryFace.updateCategory(categoryVo);
  69. return ResponseWrapBuild.build(CategoryEnum.SUCCEED,flag);
  70. }
  71. /**
  72. * @Description 删除分类
  73. * @param categoryVo 查询对象
  74. * @return
  75. */
  76. @DeleteMapping
  77. @ApiOperation(value = "删除分类",notes = "删除分类")
  78. @ApiImplicitParam(name = "categoryVo",value = "分类查询对象",required = true,dataType = "CategoryVo")
  79. ResponseWrap<Boolean> deleteCategory(@RequestBody CategoryVo categoryVo ) {
  80. //获得所有选择分类IDS
  81. String[] checkedIds = categoryVo.getCheckedIds();
  82. Boolean flag = categoryFace.deleteCategory(checkedIds);
  83. return ResponseWrapBuild.build(CategoryEnum.SUCCEED,flag);
  84. }
  85. /**
  86. * @Description 查找分类
  87. * @param categoryId 分类id
  88. * @return
  89. */
  90. @GetMapping("{categoryId}")
  91. @ApiOperation(value = "查找分类",notes = "查找分类")
  92. @ApiImplicitParam(paramType = "path",name = "categoryId",value = "分类Id",dataType = "Long")
  93. ResponseWrap<CategoryVo> findCategoryByCategoryId(@PathVariable("categoryId") Long categoryId) {
  94. CategoryVo categoryVo = categoryFace.findCategoryByCategoryId(categoryId);
  95. return ResponseWrapBuild.build(CategoryEnum.SUCCEED,categoryVo);
  96. }
  97. /**
  98. * @Description 查找分类
  99. * @return
  100. */
  101. @GetMapping("list")
  102. @ApiOperation(value = "查找分类列表",notes = "查找分类列表")
  103. ResponseWrap<List<CategoryVo>> findCategoryVoList() {
  104. List<CategoryVo> list = categoryFace.findCategoryVoList();
  105. return ResponseWrapBuild.build(CategoryEnum.SUCCEED,list);
  106. }
  107. @PostMapping("update-category-enableFlag")
  108. @ApiOperation(value = "修改分类状态",notes = "修改分类状态")
  109. ResponseWrap<Boolean> updateCategoryEnableFlag(@RequestBody CategoryVo categoryVo) {
  110. Boolean flag = categoryFace.updateCategory(categoryVo);
  111. return ResponseWrapBuild.build(CategoryEnum.SUCCEED,flag);
  112. }
  113. }

第四章 商家平台-菜品管理

  1. 门店管理进行菜品管理的功能,包括对菜品的添加、修改、删除、禁用、启用、起售、停售、查看详情等功能,注意的菜品的数据归属我们采用多租户功能区实现这里不需要考虑【多租户】后面有专题去简介

image.png

1、功能区拆解

image.png

红色区域:此处为查询条件功能区,筛选列表信息

功能 说明
编码 输入菜品编码【简码】,键盘按enter触发搜索列表
菜品名称 输入菜品名称,键盘按enter触发搜索列表
分类 下拉框,显示菜品分类【数字字典】,change触发搜索列表
状态 下拉框,显示【启用、禁用】,change触发搜索列表

蓝色区域:菜品维护功能

功能 说明
添加 新增菜品信息
修改 修改菜品信息
删除 删除菜品信息==【真实删除】==,删除时,会有再次确认提示
详情 右侧弹出菜品详细信息
禁用、启用 禁用启用菜品
起售、停售 起售、停售菜品

image.png

2、数据库结构

  1. CREATE TABLE `tab_dish` (
  2. `id` bigint(18) NOT NULL COMMENT '菜品Id',
  3. `dish_name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '菜品名称',
  4. `dish_number` int(9) DEFAULT NULL COMMENT '菜品数量',
  5. `category_id` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '菜品分类id',
  6. `price` decimal(12,4) NOT NULL COMMENT '菜品价格',
  7. `reduce_price` decimal(12,4) NOT NULL COMMENT '菜品优惠价格',
  8. `code` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '商品码',
  9. `description` varchar(400) COLLATE utf8_bin DEFAULT NULL COMMENT '描述信息',
  10. `dish_status` varchar(11) COLLATE utf8_bin NOT NULL COMMENT 'YES 停售 NO 起售',
  11. `created_time` datetime DEFAULT NULL COMMENT '创建时间',
  12. `updated_time` datetime DEFAULT NULL COMMENT '创建时间',
  13. `sharding_id` bigint(18) DEFAULT NULL COMMENT '分库id',
  14. `store_id` bigint(18) NOT NULL COMMENT '门店主键id',
  15. `enterprise_id` bigint(18) NOT NULL COMMENT '商户号',
  16. `sort_no` int(11) DEFAULT NULL COMMENT '排序',
  17. `enable_flag` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT '是否有效',
  18. PRIMARY KEY (`id`)
  19. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='菜品管理';
  1. CREATE TABLE `tab_dish_flavor` (
  2. `id` bigint(18) NOT NULL COMMENT '主键Id',
  3. `dish_id` bigint(18) DEFAULT NULL COMMENT '菜品id',
  4. `data_key` varchar(255) CHARACTER SET utf8 NOT NULL COMMENT '数据字典KEY【数字字典统一管理】',
  5. `created_time` datetime DEFAULT NULL COMMENT '创建时间',
  6. `updated_time` datetime DEFAULT NULL COMMENT '创建时间',
  7. `sharding_id` bigint(18) DEFAULT NULL COMMENT '分库id',
  8. `enable_flag` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT '是否有效',
  9. PRIMARY KEY (`id`)
  10. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4COMMENT='菜品口味';

自动填充

下列字段,无需手动填充,系统会自动填充下列字段

字段 注释 填充方式
id 主键 雪花算法
enterprise_id 商户号 mybatis-plus-多租户拦截
created_time 创建时间 mybatis-plus-自动填充组件
updated_time 修改时间 mybatis-plus-自动填充组件
sharding_id 分库id mybatis-plus-自动填充组件
store_id 门店id mybatis-plus-多租户拦截

3、功能开发

image.png

DishController:对DishFace接口进行dubbo的RPC调用,为dubbo服务的消费者

DishFace:菜品管理dubbo接口定义,对AffixFace图片接口调用

DishFaceImpl:菜品管理dubbo接口定义实现,这里做VO和POJO的转换

IDishService:菜品管理的业务接口定义,为DishFaceImpl提供核心业务逻辑的定义

DishServiceImpl:菜品管理的业务接口定义实现

3.1、DishFace接口

菜品管理dubbo接口定义

  1. package com.itheima.restkeeper;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.exception.ProjectException;
  4. import com.itheima.restkeeper.req.DishVo;
  5. /**
  6. * @ClassName DishFace.java
  7. * @Description 菜品接口
  8. */
  9. public interface DishFace {
  10. /**
  11. * @Description 菜品列表
  12. * @param dishVo 查询条件
  13. * @param pageNum 当前页
  14. * @param pageSize 每页条数
  15. * @return Page<DishVo>
  16. */
  17. Page<DishVo> findDishVoPage(DishVo dishVo,
  18. int pageNum,
  19. int pageSize)throws ProjectException;
  20. /**
  21. * @Description 创建菜品
  22. * @param dishVo 对象信息
  23. * @return DishVo
  24. */
  25. DishVo createDish(DishVo dishVo)throws ProjectException;
  26. /**
  27. * @Description 修改菜品
  28. * @param dishVo 对象信息
  29. * @return Boolean
  30. */
  31. Boolean updateDish(DishVo dishVo) throws ProjectException;
  32. /**
  33. * @Description 删除菜品
  34. * @param checkedIds 选择对象信息Id
  35. * @return Boolean
  36. */
  37. Boolean deleteDish(String[] checkedIds)throws ProjectException;
  38. /**
  39. * @Description 查找菜品
  40. * @param dishId 选择对象信息Id
  41. * @return DishVo
  42. */
  43. DishVo findDishByDishId(Long dishId)throws ProjectException;
  44. }

3.2、DishFaceImpl接口实现

菜品管理dubbo接口定义实现,这里做VO和POJO的转换

  1. package com.itheima.restkeeper.face;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.AffixFace;
  4. import com.itheima.restkeeper.DishFace;
  5. import com.itheima.restkeeper.constant.AppletCacheConstant;
  6. import com.itheima.restkeeper.enums.DishEnum;
  7. import com.itheima.restkeeper.exception.ProjectException;
  8. import com.itheima.restkeeper.pojo.Dish;
  9. import com.itheima.restkeeper.pojo.DishFlavor;
  10. import com.itheima.restkeeper.req.AffixVo;
  11. import com.itheima.restkeeper.req.DishVo;
  12. import com.itheima.restkeeper.service.IDishFlavorService;
  13. import com.itheima.restkeeper.service.IDishService;
  14. import com.itheima.restkeeper.utils.BeanConv;
  15. import com.itheima.restkeeper.utils.EmptyUtil;
  16. import com.itheima.restkeeper.utils.ExceptionsUtil;
  17. import lombok.extern.slf4j.Slf4j;
  18. import org.apache.dubbo.config.annotation.DubboReference;
  19. import org.apache.dubbo.config.annotation.DubboService;
  20. import org.apache.dubbo.config.annotation.Method;
  21. import org.redisson.api.RAtomicLong;
  22. import org.redisson.api.RLock;
  23. import org.redisson.api.RedissonClient;
  24. import org.springframework.beans.factory.annotation.Autowired;
  25. import org.springframework.transaction.annotation.Transactional;
  26. import java.util.ArrayList;
  27. import java.util.List;
  28. import java.util.concurrent.TimeUnit;
  29. import java.util.stream.Collectors;
  30. /**
  31. * @ClassName DishFaceImpl.java
  32. * @Description 菜品接口实现
  33. */
  34. @Slf4j
  35. @DubboService(version = "${dubbo.application.version}",timeout = 5000,
  36. methods ={
  37. @Method(name = "findDishVoPage",retries = 2),
  38. @Method(name = "createDish",retries = 0),
  39. @Method(name = "updateDish",retries = 0),
  40. @Method(name = "deleteDish",retries = 0)
  41. })
  42. public class DishFaceImpl implements DishFace {
  43. @Autowired
  44. IDishService dishService;
  45. @Autowired
  46. IDishFlavorService dishFlavorService;
  47. @Autowired
  48. RedissonClient redissonClient;
  49. @DubboReference(version = "${dubbo.application.version}",check = false)
  50. AffixFace affixFace;
  51. @Override
  52. public Page<DishVo> findDishVoPage(DishVo dishVo,
  53. int pageNum,
  54. int pageSize)throws ProjectException {
  55. try {
  56. //查询菜品分页
  57. Page<Dish> page = dishService.findDishVoPage(dishVo, pageNum, pageSize);
  58. Page<DishVo> pageVo = new Page<>();
  59. BeanConv.toBean(page,pageVo);
  60. //结果集转换
  61. List<Dish> dishList = page.getRecords();
  62. List<DishVo> dishVoList = BeanConv.toBeanList(dishList,DishVo.class);
  63. if (!EmptyUtil.isNullOrEmpty(dishVoList)){
  64. dishVoList.forEach(n->{
  65. //处理附件
  66. List<AffixVo> affixVoList = affixFace.findAffixVoByBusinessId(n.getId());
  67. if (!EmptyUtil.isNullOrEmpty(affixVoList)){
  68. n.setAffixVo(affixVoList.get(0));
  69. }
  70. //处理口味1
  71. List<DishFlavor> dishFlavors = dishFlavorService.findDishFlavorByDishId(n.getId());
  72. List<String> dishFavorList = new ArrayList<>();
  73. for (DishFlavor dishFlavor : dishFlavors) {
  74. dishFavorList.add(String.valueOf(dishFlavor.getDataKey()));
  75. }
  76. String[] dishFlavorDataKey = new String[dishFavorList.size()];
  77. dishFavorList.toArray(dishFlavorDataKey);
  78. n.setHasDishFlavor(dishFlavorDataKey);
  79. });
  80. }
  81. pageVo.setRecords(dishVoList);
  82. //返回结果
  83. return pageVo;
  84. } catch (Exception e) {
  85. log.error("查询菜品列表异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  86. throw new ProjectException(DishEnum.PAGE_FAIL);
  87. }
  88. }
  89. @Override
  90. @Transactional
  91. public DishVo createDish(DishVo dishVo) throws ProjectException{
  92. try {
  93. //创建菜品
  94. DishVo dishVoResult = BeanConv.toBean(dishService.createDish(dishVo), DishVo.class);
  95. dishVoResult.setHasDishFlavor(dishVo.getHasDishFlavor());
  96. //绑定附件
  97. if (!EmptyUtil.isNullOrEmpty(dishVoResult)){
  98. affixFace.bindBusinessId(AffixVo.builder()
  99. .businessId(dishVoResult.getId())
  100. .id(dishVo.getAffixVo().getId())
  101. .build());
  102. }
  103. dishVoResult.setAffixVo(AffixVo.builder()
  104. .pathUrl(dishVo.getAffixVo().getPathUrl())
  105. .businessId(dishVoResult.getId())
  106. .id(dishVo.getAffixVo().getId()).build());
  107. //构建初始化库存
  108. String key = AppletCacheConstant.REPERTORY_DISH+dishVoResult.getId();
  109. RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
  110. atomicLong.set(dishVoResult.getDishNumber());
  111. return dishVoResult;
  112. } catch (Exception e) {
  113. log.error("保存菜品异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  114. throw new ProjectException(DishEnum.CREATE_FAIL);
  115. }
  116. }
  117. @Override
  118. @Transactional
  119. public Boolean updateDish(DishVo dishVo) throws ProjectException {
  120. Boolean flag = false;
  121. //修改菜品
  122. flag = dishService.updateDish(dishVo);
  123. //处理菜品图片
  124. if (flag){
  125. List<AffixVo> affixVoList = affixFace.findAffixVoByBusinessId(dishVo.getId());
  126. List<Long> affixIds = affixVoList.stream()
  127. .map(AffixVo::getId)
  128. .collect(Collectors.toList());
  129. if (!affixIds.contains(dishVo.getAffixVo().getId())){
  130. //删除图片
  131. flag = affixFace.deleteAffixVoByBusinessId(dishVo.getId());
  132. //绑定新图片
  133. affixFace.bindBusinessId(AffixVo.builder()
  134. .businessId(dishVo.getId())
  135. .id(dishVo.getAffixVo().getId())
  136. .build());
  137. }
  138. }
  139. //构建redis库存
  140. String key = AppletCacheConstant.REPERTORY_DISH+dishVo.getId();
  141. RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
  142. atomicLong.set(dishVo.getDishNumber());
  143. return flag;
  144. }
  145. @Override
  146. @Transactional
  147. public Boolean deleteDish(String[] checkedIds)throws ProjectException {
  148. try {
  149. Boolean flag = dishService.deleteDish(checkedIds);
  150. for (String checkedId : checkedIds) {
  151. //删除图片
  152. affixFace.deleteAffixVoByBusinessId(Long.valueOf(checkedId));
  153. //删除菜品库存
  154. String key = AppletCacheConstant.REPERTORY_DISH+checkedId;
  155. RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
  156. atomicLong.delete();
  157. }
  158. return flag;
  159. } catch (Exception e) {
  160. log.error("删除菜品异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  161. throw new ProjectException(DishEnum.DELETE_FAIL);
  162. }
  163. }
  164. @Override
  165. public DishVo findDishByDishId(Long dishId)throws ProjectException {
  166. try {
  167. //按菜品ID查找菜品
  168. Dish dish = dishService.getById(dishId);
  169. if (!EmptyUtil.isNullOrEmpty(dish)){
  170. return BeanConv.toBean(dish,DishVo.class);
  171. }
  172. return null;
  173. } catch (Exception e) {
  174. log.error("查找菜品所有菜品异常:{}", ExceptionsUtil.getStackTraceAsString(e));
  175. throw new ProjectException(DishEnum.SELECT_DISH_FAIL);
  176. }
  177. }
  178. }

3.3、IDishService业务接口

菜品管理的业务接口定义,为DishFaceImpl提供核心业务逻辑的定义

  1. package com.itheima.restkeeper.service;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.pojo.Dish;
  4. import com.itheima.restkeeper.pojo.Dish;
  5. import com.baomidou.mybatisplus.extension.service.IService;
  6. import com.itheima.restkeeper.req.DishVo;
  7. import java.util.List;
  8. /**
  9. * @Description:菜品管理 服务类
  10. */
  11. public interface IDishService extends IService<Dish> {
  12. /**
  13. * @Description 菜品列表
  14. * @param dishVo 查询条件
  15. * @param pageNum 当前页
  16. * @param pageSize 每页条数
  17. * @return Page<Dish>
  18. */
  19. Page<Dish> findDishVoPage(DishVo dishVo, int pageNum, int pageSize);
  20. /**
  21. * @Description 创建菜品
  22. * @param dishVo 对象信息
  23. * @return Dish
  24. */
  25. Dish createDish(DishVo dishVo);
  26. /**
  27. * @Description 修改菜品
  28. * @param dishVo 对象信息
  29. * @return Boolean
  30. */
  31. Boolean updateDish(DishVo dishVo);
  32. /**
  33. * @Description 删除菜品
  34. * @param checkedIds 选择的菜品ID
  35. * @return Boolean
  36. */
  37. Boolean deleteDish(String[] checkedIds);
  38. /***
  39. * @description 查询分类下所有菜品
  40. * @param categoryId
  41. * @return List<Dish>
  42. */
  43. List<Dish> findDishVoByCategoryId(Long categoryId);
  44. /***
  45. * @description 查询店铺下所有起售且有效菜品
  46. * @param storeId
  47. * @return List<Dish>
  48. */
  49. List<Dish> findDishVoByStoreId(Long storeId);
  50. /***
  51. * @description 增减菜品库存数量
  52. * @param step 增减步长
  53. * @return Boolean
  54. */
  55. Boolean updateDishNumber(Long step, Long dishId);
  56. /***
  57. * @description 查询所有有效的菜品信息
  58. * @return
  59. */
  60. List<Dish> findDishVos();
  61. }

3.4、DishServiceImpl业务接口实现

菜品管理的业务接口定义实现

  1. package com.itheima.restkeeper.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  4. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  5. import com.google.common.collect.Lists;
  6. import com.itheima.restkeeper.constant.SuperConstant;
  7. import com.itheima.restkeeper.pojo.Dish;
  8. import com.itheima.restkeeper.mapper.DishMapper;
  9. import com.itheima.restkeeper.pojo.DishFlavor;
  10. import com.itheima.restkeeper.req.DishVo;
  11. import com.itheima.restkeeper.service.IDishFlavorService;
  12. import com.itheima.restkeeper.service.IDishService;
  13. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  14. import com.itheima.restkeeper.utils.BeanConv;
  15. import com.itheima.restkeeper.utils.EmptyUtil;
  16. import org.springframework.beans.factory.annotation.Autowired;
  17. import org.springframework.stereotype.Service;
  18. import org.springframework.transaction.annotation.Transactional;
  19. import java.util.ArrayList;
  20. import java.util.Arrays;
  21. import java.util.List;
  22. /**
  23. * @Description:菜品管理 服务实现类
  24. */
  25. @Service
  26. public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements IDishService {
  27. @Autowired
  28. IDishFlavorService dishFlavorService;
  29. @Autowired
  30. DishMapper dishMapper;
  31. @Override
  32. public Page<Dish> findDishVoPage(DishVo dishVo, int pageNum, int pageSize) {
  33. //构建Page<Dish>分页对象
  34. Page<Dish> page = new Page<>(pageNum,pageSize);
  35. QueryWrapper<Dish> queryWrapper = new QueryWrapper<>();
  36. //按分类查询
  37. if (!EmptyUtil.isNullOrEmpty(dishVo.getCategoryId())) {
  38. queryWrapper.lambda().eq(Dish::getCategoryId,dishVo.getCategoryId());
  39. }
  40. //按菜品名称查询
  41. if (!EmptyUtil.isNullOrEmpty(dishVo.getDishName())) {
  42. queryWrapper.lambda().likeRight(Dish::getDishName,dishVo.getDishName());
  43. }
  44. //按简码查询
  45. if (!EmptyUtil.isNullOrEmpty(dishVo.getCode())) {
  46. queryWrapper.lambda().likeRight(Dish::getCode,dishVo.getCode());
  47. }
  48. //按有效性查询
  49. if (!EmptyUtil.isNullOrEmpty(dishVo.getEnableFlag())) {
  50. queryWrapper.lambda().eq(Dish::getEnableFlag,dishVo.getEnableFlag());
  51. }
  52. //按sortNo升序
  53. queryWrapper.lambda().orderByAsc(Dish::getSortNo);
  54. //执行page返回结果
  55. return page(page, queryWrapper);
  56. }
  57. @Override
  58. @Transactional
  59. public Dish createDish(DishVo dishVo) {
  60. //转换DishVo为Dish
  61. Dish dish = BeanConv.toBean(dishVo, Dish.class);
  62. //执行保存
  63. boolean flag = save(dish);
  64. //保存菜品和口味中间表信息
  65. if (flag){
  66. List<DishFlavor> list = Lists.newArrayList();
  67. List<String> dataKeys = Arrays.asList(dishVo.getHasDishFlavor());
  68. dataKeys.forEach(n->{
  69. DishFlavor dishFlavor = DishFlavor.builder()
  70. .dishId(dish.getId())
  71. .dataKey(n)
  72. .build();
  73. list.add(dishFlavor);
  74. });
  75. flag = dishFlavorService.saveBatch(list);
  76. }
  77. if (flag){
  78. return dish;
  79. }
  80. return null;
  81. }
  82. /**
  83. * @Description 菜品拥有的口味
  84. */
  85. private List<String> dishHasDishFlavor(Long dishId){
  86. QueryWrapper<DishFlavor> queryWrapper = new QueryWrapper<>();
  87. queryWrapper.lambda().eq(DishFlavor::getDishId,dishId);
  88. List<DishFlavor> list = dishFlavorService.list(queryWrapper);
  89. ArrayList<String> listDataKeys = Lists.newArrayList();
  90. if (!EmptyUtil.isNullOrEmpty(list)){
  91. list.forEach(n->{
  92. listDataKeys.add(String.valueOf(n.getDataKey()));
  93. });
  94. }
  95. return listDataKeys;
  96. }
  97. @Override
  98. public Boolean updateDish(DishVo dishVo) {
  99. Dish dish = BeanConv.toBean(dishVo, Dish.class);
  100. boolean flag = updateById(dish);
  101. if (flag){
  102. //删除以往有的口味
  103. QueryWrapper<DishFlavor> queryWrapper = new QueryWrapper<>();
  104. queryWrapper.lambda().eq(DishFlavor::getDishId,dish.getId());
  105. dishFlavorService.remove(queryWrapper);
  106. }
  107. //添加新口味
  108. List<DishFlavor> list = Lists.newArrayList();
  109. List<String> newDishHasDishFlavors = Arrays.asList(dishVo.getHasDishFlavor());
  110. newDishHasDishFlavors.forEach(n->{
  111. DishFlavor dishFlavors = DishFlavor.builder()
  112. .dishId(dish.getId())
  113. .dataKey(n)
  114. .build();
  115. list.add(dishFlavors);
  116. });
  117. flag = dishFlavorService.saveBatch(list);
  118. return flag;
  119. }
  120. @Override
  121. public Boolean deleteDish(String[] checkedIds) {
  122. //构建选择ids的List<String>
  123. List<String> ids = Arrays.asList(checkedIds);
  124. List<Long> idsLong = new ArrayList<>();
  125. ids.forEach(n->{
  126. idsLong.add(Long.valueOf(n));
  127. });
  128. //批量移除菜品
  129. boolean flag = removeByIds(idsLong);
  130. //批量移除菜品口味
  131. if (flag){
  132. QueryWrapper<DishFlavor> queryWrapper = new QueryWrapper<>();
  133. queryWrapper.lambda().in(DishFlavor::getDishId,idsLong);
  134. flag = dishFlavorService.remove(queryWrapper);
  135. }
  136. return flag;
  137. }
  138. @Override
  139. public List<Dish> findDishVoByCategoryId(Long categoryId) {
  140. //构建查询条件:菜品起售,菜品有效
  141. LambdaQueryWrapper<Dish> lambdaQueryWrapper = new LambdaQueryWrapper<>();
  142. lambdaQueryWrapper.eq(Dish::getCategoryId,categoryId)
  143. .eq(Dish::getEnableFlag,SuperConstant.YES)
  144. .eq(Dish::getDishStatus,SuperConstant.YES);
  145. //执行list查询
  146. return list(lambdaQueryWrapper);
  147. }
  148. @Override
  149. public List<Dish> findDishVoByStoreId(Long storeId) {
  150. //构建查询条件:店铺ID,菜品起售,菜品有效
  151. LambdaQueryWrapper<Dish> lambdaQueryWrapper = new LambdaQueryWrapper<>();
  152. lambdaQueryWrapper.eq(Dish::getStoreId,storeId)
  153. .eq(Dish::getEnableFlag,SuperConstant.YES)
  154. .eq(Dish::getDishStatus,SuperConstant.YES);
  155. //执行list查询
  156. return list(lambdaQueryWrapper);
  157. }
  158. @Override
  159. public Boolean updateDishNumber(Long step,Long dishId) {
  160. //修改菜品数量
  161. Integer row = dishMapper.updateDishNumber(step,dishId);
  162. return row==1 ? true:false;
  163. }
  164. @Override
  165. public List<Dish> findDishVos() {
  166. QueryWrapper<Dish> queryWrapper = new QueryWrapper<>();
  167. queryWrapper.lambda().eq(Dish::getEnableFlag,SuperConstant.YES)
  168. .eq(Dish::getDishStatus,SuperConstant.YES);
  169. return list(queryWrapper);
  170. }
  171. }

3.5、DishController类

对DishFace接口进行dubbo的RPC调用,为dubbo服务的消费者

  1. package com.itheima.restkeeper.web;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.itheima.restkeeper.DishFace;
  4. import com.itheima.restkeeper.basic.ResponseWrap;
  5. import com.itheima.restkeeper.enums.DishEnum;
  6. import com.itheima.restkeeper.req.DishVo;
  7. import com.itheima.restkeeper.utils.ResponseWrapBuild;
  8. import io.swagger.annotations.Api;
  9. import io.swagger.annotations.ApiImplicitParam;
  10. import io.swagger.annotations.ApiImplicitParams;
  11. import io.swagger.annotations.ApiOperation;
  12. import lombok.extern.slf4j.Slf4j;
  13. import org.apache.dubbo.config.annotation.DubboReference;
  14. import org.springframework.web.bind.annotation.*;
  15. /**
  16. * @ClassName DishController.java
  17. * @Description 菜品Controller
  18. */
  19. @RestController
  20. @RequestMapping("dish")
  21. @Slf4j
  22. @Api(tags = "菜品controller")
  23. public class DishController {
  24. @DubboReference(version = "${dubbo.application.version}",check = false)
  25. DishFace dishFace;
  26. /**
  27. * @Description 菜品列表
  28. * @param dishVo 查询条件
  29. * @return
  30. */
  31. @PostMapping("page/{pageNum}/{pageSize}")
  32. @ApiOperation(value = "查询菜品分页",notes = "查询菜品分页")
  33. @ApiImplicitParams({
  34. @ApiImplicitParam(name = "dishVo",value = "菜品查询对象",dataType = "DishVo"),
  35. @ApiImplicitParam(paramType = "path",name = "pageNum",value = "页码",dataType = "Integer"),
  36. @ApiImplicitParam(paramType = "path",name = "pageSize",value = "每页条数",dataType = "Integer")
  37. })
  38. public ResponseWrap<Page<DishVo>> findDishVoPage(
  39. @RequestBody DishVo dishVo,
  40. @PathVariable("pageNum") int pageNum,
  41. @PathVariable("pageSize") int pageSize) {
  42. Page<DishVo> dishVoPage = dishFace.findDishVoPage(dishVo, pageNum, pageSize);
  43. return ResponseWrapBuild.build(DishEnum.SUCCEED,dishVoPage);
  44. }
  45. /**
  46. * @Description 添加菜品
  47. * @param dishVo 对象信息
  48. * @return
  49. */
  50. @PostMapping
  51. @ApiOperation(value = "添加菜品",notes = "添加菜品")
  52. @ApiImplicitParam(name = "dishVo",value = "菜品对象",required = true,dataType = "DishVo")
  53. ResponseWrap<DishVo> createDish(@RequestBody DishVo dishVo) {
  54. DishVo dishVoResult = dishFace.createDish(dishVo);
  55. return ResponseWrapBuild.build(DishEnum.SUCCEED,dishVoResult);
  56. }
  57. /**
  58. * @Description 修改菜品
  59. * @param dishVo 对象信息
  60. * @return
  61. */
  62. @PatchMapping
  63. @ApiOperation(value = "修改菜品",notes = "修改菜品")
  64. @ApiImplicitParam(name = "dishVo",value = "菜品对象",required = true,dataType = "DishVo")
  65. ResponseWrap<Boolean> updateDish(@RequestBody DishVo dishVo) {
  66. Boolean flag = dishFace.updateDish(dishVo);
  67. return ResponseWrapBuild.build(DishEnum.SUCCEED,flag);
  68. }
  69. /**
  70. * @Description 删除菜品
  71. * @param dishVo 查询对象
  72. * @return
  73. */
  74. @DeleteMapping
  75. @ApiOperation(value = "删除菜品",notes = "删除菜品")
  76. @ApiImplicitParam(name = "dishVo",value = "菜品查询对象",required = true,dataType = "DishVo")
  77. ResponseWrap<Boolean> deleteDish(@RequestBody DishVo dishVo ) {
  78. //获得所有选中的菜品IDS
  79. String[] checkedIds = dishVo.getCheckedIds();
  80. Boolean flag = dishFace.deleteDish(checkedIds);
  81. return ResponseWrapBuild.build(DishEnum.SUCCEED,flag);
  82. }
  83. /**
  84. * @Description 查找菜品
  85. * @param dishId 菜品id
  86. * @return
  87. */
  88. @GetMapping("{dishId}")
  89. @ApiOperation(value = "查找菜品",notes = "查找菜品")
  90. @ApiImplicitParam(paramType = "path",name = "dishId",value = "菜品Id",dataType = "Long")
  91. ResponseWrap<DishVo> findDishByDishId(@PathVariable("dishId") Long dishId) {
  92. DishVo dishVo = dishFace.findDishByDishId(dishId);
  93. return ResponseWrapBuild.build(DishEnum.SUCCEED,dishVo);
  94. }
  95. @PostMapping("update-dish-enableFlag")
  96. @ApiOperation(value = "修改菜品有效状态",notes = "修改菜品有效状态")
  97. ResponseWrap<Boolean> updateDishEnableFlag(@RequestBody DishVo dishVo) {
  98. Boolean flag = dishFace.updateDish(dishVo);
  99. return ResponseWrapBuild.build(DishEnum.SUCCEED,flag);
  100. }
  101. @PostMapping("update-dish-dishStatus")
  102. @ApiOperation(value = "修改菜品状态",notes = "修改菜品状态")
  103. ResponseWrap<Boolean> updateDishDishStatus(@RequestBody DishVo dishVo) {
  104. Boolean flag = dishFace.updateDish(dishVo);
  105. return ResponseWrapBuild.build(DishEnum.SUCCEED,flag);
  106. }
  107. }

课堂讨论

1、概述区域、桌台、分类、菜品表之间的关系,及关键字段。

2、项目中区域、桌台、分类、菜品是否有企业归属及门店归属的概念?在设计数据库的时候需要注意什么?

3、菜品的库存的控制你是这么理解的?菜品库存与那些操作有关?

4、设计一下==《汽车维修4S美容中心》==中的表结构

课后任务

1、完成区域、桌台、分类、菜品管理开发,同步到git【☆☆☆☆☆】

2、完成当天课堂讨论,同步到git【☆☆☆☆☆】

3、完成2-5道sql练习【☆☆☆☆】

4、梳理项目一业务,同步到git【☆☆☆】