苍穹外卖day04——套餐管理功能实现
套餐管理功能实现
目录
SetmealMapper 和SetmealDishMapper
SetmealMapper.xml和SetmealDishMapper.xml
SetmealMapper和SetmealDishMapper中
增加套餐——需求分析与设计
页面原型
涉及到两个界面
接口设计
业务规则:
- 套餐名称唯一
- 套餐必须属于某个分类
- 套餐必须包含菜品
- 名称、分类、价格、图片为必填项
- 添加菜品窗口需要根据分类类型来展示菜品
- 新增的套餐默认为停售状态
接口设计(共涉及到4个接口):
- 根据类型查询分类(已完成)
- 根据分类id查询菜品
- 图片上传(已完成)
- 新增套餐
DishController层中
/**
* 根据分类id查询菜品
* @param categoryId
* @return
*/
@GetMapping("list")
@ApiOperation("根据分类id查询菜品")
public Result<List<Dish>> list(Long categoryId){
List<Dish> list=dishService.list(categoryId);
return Result.success(list);
}
DishService中
/**
* 根据分类id查询菜品
* @param categoryId
* @return
*/
@Override
public List<Dish> list(Long categoryId) {
Dish dish=Dish.builder()
.categoryId(categoryId)
.status(StatusConstant.ENABLE)
.build();
return dishMapper.list(dish);
}
DishMapper中
/**
* 动态条件查询菜品
* @param dish
* @return
*/
List<Dish> list(Dish dish);
<select id="list" resultType="com.sky.entity.Dish">
select * from dish
<where>
<if test="name != null">and name like concat('%',#{name},'%')</if>
<if test="categoryId != null">and category_id = #{categoryId}</if>
<if test="status != null">and status = #{status}</if>
</where>
order by create_time desc
</select>
接口文档测试
SetmealController中
/**
* 套餐管理
*/
@RestController
@RequestMapping("/admin/setmeal")
@Api("套餐相关接口")
@Slf4j
public class SetmealController {
@Autowired
private SetmealService setmealService;
/**
* 新增套餐
* @param setmealDTO
* @return
*/
@PostMapping
@ApiOperation("新增套餐")
public Result save(@RequestBody SetmealDTO setmealDTO){
setmealService.saveWithDish(setmealDTO);
return Result.success();
}
}
SetmealService中
/**
* 新增套餐,同时增加套餐和菜品关系
* @param setmealDTO
*/
@Override
@Transactional
public void saveWithDish(SetmealDTO setmealDTO) {
Setmeal setmeal=new Setmeal();
BeanUtils.copyProperties(setmealDTO ,setmeal);
//向套餐表插入数据
setmealMapper.insert(setmeal);
//获取生成的套餐id
Long id = setmeal.getId();
List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
setmealDishes.forEach(setmealDish -> {
setmealDish.setSetmealId(id);
});
//保存套餐和菜品的关系
setmealDishMapper.insertBatch(setmealDishes);
}
SetmealMapper 和SetmealDishMapper
/**
* 新增套餐
* @param setmeal
*/
@AutoFill(OperationType.INSERT)
void insert(Setmeal setmeal);
/**
* 批量保存套餐和菜品的关系
* @param setmealDishes
*/
void insertBatch(List<SetmealDish> setmealDishes);
SetmealMapper.xml和SetmealDishMapper.xml
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert into setmeal
(category_id, name, price, status, description, image, create_time, update_time, create_user, update_user)
values (#{categoryId}, #{name}, #{price}, #{status}, #{description}, #{image}, #{createTime}, #{updateTime},
#{createUser}, #{updateUser})
</insert>
<insert id="insertBatch">
insert into setmeal_dish
(setmeal_id,dish_id,name,price,copies)
values
<foreach collection="setmealDishes" item="sd" separator=",">
(#{sd.setmealId},#{sd.dishId},#{sd.name},#{sd.price},#{sd.copies})
</foreach>
</insert>
增加套餐——功能测试
前后端链联调测试
两个表格的数据都没有问题。
套餐分页查询——需求分析与设计
产品原型
业务规则
业务规则:
-
根据页码进行分页展示
-
每页展示10条数据
-
可以根据需要,按照套餐名称、分类、售卖状态进行查询
接口设计:
套餐分页查询——代码实现
SetmealController中
/**
* 分页查询
* @param setmealPageQueryDTO
* @return
*/
@GetMapping("/page")
@ApiOperation("分页查询")
public Result<PageResult> page(SetmealPageQueryDTO setmealPageQueryDTO)
{
PageResult pageResult=setmealService.pageQuery(setmealPageQueryDTO);
return Result.success(pageResult);
}
SetmealService中
/**
* 分页查询
* @param setmealPageQueryDTO
* @return
*/
@Override
public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
int pageNum=setmealPageQueryDTO.getPage();
int pageSize=setmealPageQueryDTO.getPageSize();
PageHelper.startPage(pageNum,pageSize);
Page<SetmealVO> page=setmealMapper.pageQuery(setmealPageQueryDTO);
return new PageResult(page.getTotal(),page.getResult());
}
SetmealMapper中
/**
* 分页查询
* @param setmealPageQueryDTO
* @return
*/
Page<SetmealVO> pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);
对应的XML映射文件
<select id="pageQuery" resultType="com.sky.vo.SetmealVO">
select
s.*,c.name categoryName
from
setmeal s
left join
category c
on
s.category_id = c.id
<where>
<if test="name != null">
and s.name like concat('%',#{name},'%')
</if>
<if test="status != null">
and s.status = #{status}
</if>
<if test="categoryId != null">
and s.category_id = #{categoryId}
</if>
</where>
order by s.create_time desc
</select>
套餐分页查询——功能测试
前后端联调测试正常显示
删除套餐——需求分析与设计
产品原型
业务规则
-
可以一次删除一个套餐,也可以批量删除套餐
-
起售中的套餐不能删除
接口设计
删除套餐——代码实现
SetmealController中
/**
* 批量删除套餐
* @param ids
* @return
*/
@DeleteMapping
@ApiOperation("批量删除套餐")
public Result delete(@RequestParam List<Long> ids){
setmealService.deleteBatch(ids);
return Result.success();
}
SetmealService中
/**
* 批量删除套餐
* @param ids
*/
@Transactional
public void deleteBatch(List<Long> ids) {
ids.forEach(id -> {
Setmeal setmeal = setmealMapper.getById(id);
if(StatusConstant.ENABLE == setmeal.getStatus()){
//起售中的套餐不能删除
throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
}
});
ids.forEach(setmealId -> {
//删除套餐表中的数据
setmealMapper.deleteById(setmealId);
//删除套餐菜品关系表中的数据
setmealDishMapper.deleteBySetmealId(setmealId);
});
}
SetmealMapper和SetmealDishMapper中
/**
* 批量保存套餐和菜品的关系
* @param setmealDishes
*/
void insertBatch(List<SetmealDish> setmealDishes);
/**
* 根据套餐id删除套餐和菜品的关联关系
* @param setmealId
*/
@Delete("delete from setmeal_dish where setmeal_id = #{setmealId}")
void deleteBySetmealId(Long setmealId);
/**
* 根据套餐id删除套餐和菜品的关联关系
* @param setmealId
*/
@Delete("delete from setmeal_dish where setmeal_id = #{setmealId}")
void deleteBySetmealId(Long setmealId);
删除套餐——功能测试
前后端联调测试正常
修改套餐——需求分析与设计
页面原型
接口设计
-
根据id查询套餐
-
根据类型查询分类(已完成)
-
根据分类id查询菜品(已完成)
-
图片上传(已完成)
-
修改套餐
响应数据
SetmealController中
/**
* 根据id查询套餐,用于修改页面回显数据
*
* @param id
* @return
*/
@GetMapping("/{id}")
@ApiOperation("根据id查询套餐")
public Result<SetmealVO> getById(@PathVariable Long id) {
SetmealVO setmealVO = setmealService.getByIdWithDish(id);
return Result.success(setmealVO);
}
/**
* 修改套餐
*
* @param setmealDTO
* @return
*/
@PutMapping
@ApiOperation("修改套餐")
public Result update(@RequestBody SetmealDTO setmealDTO) {
setmealService.update(setmealDTO);
return Result.success();
}
SetmealService中
/**
* 根据id查询套餐和套餐菜品关系
*
* @param id
* @return
*/
public SetmealVO getByIdWithDish(Long id) {
Setmeal setmeal = setmealMapper.getById(id);
List<SetmealDish> setmealDishes = setmealDishMapper.getBySetmealId(id);
SetmealVO setmealVO = new SetmealVO();
BeanUtils.copyProperties(setmeal, setmealVO);
setmealVO.setSetmealDishes(setmealDishes);
return setmealVO;
}
/**
* 修改套餐
*
* @param setmealDTO
*/
@Transactional
public void update(SetmealDTO setmealDTO) {
Setmeal setmeal = new Setmeal();
BeanUtils.copyProperties(setmealDTO, setmeal);
//1、修改套餐表,执行update
setmealMapper.update(setmeal);
//套餐id
Long setmealId = setmealDTO.getId();
//2、删除套餐和菜品的关联关系,操作setmeal_dish表,执行delete
setmealDishMapper.deleteBySetmealId(setmealId);
List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
setmealDishes.forEach(setmealDish -> {
setmealDish.setSetmealId(setmealId);
});
//3、重新插入套餐和菜品的关联关系,操作setmeal_dish表,执行insert
setmealDishMapper.insertBatch(setmealDishes);
}
SetmealMapper中
/**
* 根据id查询套餐
* @param id
* @return
*/
@Select("select * from setmeal where id = #{id}")
Setmeal getById(Long id);
/**
* 更新套餐表
* @param setmeal
*/
@AutoFill(value=OperationType.UPDATE)
void update(Setmeal setmeal);
对应的映射文件
<update id="update">
update setmeal
<set>
<if test="name != null">name=#{name},</if>
<if test="categoryId != null">category_id=#{categoryId},</if>
<if test="price != null">price=#{price},</if>
<if test="image != null">image=#{image},</if>
<if test="description != null">description=#{description},</if>
<if test="status != null">status=#{status},</if>
<if test="updateTime != null">update_time=#{updateTime},</if>
<if test="updateUser != null">update_user=#{updateUser},</if>
</set>
where id=#{id}
</update>
修改套餐——功能测试
页面回显正常,修改也保存无误
起售停售套餐——需求分析与设计
产品原型:
业务规则
- 可以对状态为起售的套餐进行停售操作,可以对状态为停售的套餐进行起售操作
- 起售的套餐可以展示在用户端,停售的套餐不能展示在用户端
- 起售套餐时,如果套餐内包含停售的菜品,则不能起售
接口设计 响应数据
起售停售套餐——代码实现
SetmealController中
/**
* 套餐起售停售
* @param status
* @param id
* @return
*/
@PostMapping("/status/{status}")
@ApiOperation("套餐起售停售")
public Result startOrStop(@PathVariable Integer status, Long id) {
setmealService.startOrStop(status, id);
return Result.success();
}
SetmealService中
/**
* 套餐起售、停售
* @param status
* @param id
*/
public void startOrStop(Integer status, Long id) {
//起售套餐时,判断套餐内是否有停售菜品,有停售菜品提示"套餐内包含未启售菜品,无法启售"
if(status == StatusConstant.ENABLE){
//select a.* from dish a left join setmeal_dish b on a.id = b.dish_id where b.setmeal_id = ?
List<Dish> dishList = dishMapper.getBySetmealId(id);
if(dishList != null && dishList.size() > 0){
dishList.forEach(dish -> {
if(StatusConstant.DISABLE == dish.getStatus()){
throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
}
});
}
}
Setmeal setmeal = Setmeal.builder()
.id(id)
.status(status)
.build();
setmealMapper.update(setmeal);
}
DishMapper 中
/**
* 根据套餐id查询菜品
* @param setmealId
* @return
*/
@Select("select a.* from dish a left join setmeal_dish b on a.id = b.dish_id where b.setmeal_id = #{setmealId}")
List<Dish> getBySetmealId(Long setmealId);
起售停售套餐——功能测试
正常起售停售
更多推荐
所有评论(0)