Day4
a. 新增套餐
在SetmealController中,定义新增套餐的接口
/**
* 新增套餐
* @param setmealDTO
* @return
*/
@PostMapping
@ApiOperation("新增套餐")
public Result save(@RequestBody SetmealDTO setmealDTO){
log.info("新增套餐:{}", setmealDTO);
setmealService.saveWithDish(setmealDTO);
return Result.success();
}
在SetmealServiceImpl中,实现新增套餐的方法,及其父类接口
/**
* 新增套餐
* @param setmealDTO
*/
@Override
@Transactional
public void saveWithDish(SetmealDTO setmealDTO) {
Setmeal setmeal = new Setmeal();
BeanUtils.copyProperties(setmealDTO, setmeal);
// 向套餐表插入数据
setmealMapper.save(setmeal);
// 获取套餐的主键值
Long setmealId = setmeal.getId();
// 获取套餐数据
List<SetmealDish> setmealDishList = setmealDTO.getSetmealDishes();
if (!setmealDishList.isEmpty()){
setmealDishList.forEach(setmealDish -> {
setmealDish.setSetmealId(setmealId);
});
// 向setmealDish表插入n条数据
setmealDishMapper.insertBatch(setmealDishList);
}
}
在SetmealMapper中,定义新增套餐的方法
/**
* 新增套餐
*/
@AutoFill(OperationType.INSERT)
void save(Setmeal setmeal);
在SetmealMapper.xml文件中,写入动态SQL语句
<insert id="save" 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}, #{create_time}, #{update_time}, #{create_user}, #{update_user})
</insert>
在SetmealDishMapper中,定义批量插入套餐菜品数据的方法
/**
* 批量插入套餐菜品数据
* @param setmealDishList
*/
void insertBatch(List<SetmealDish> setmealDishList);
在SetmealDishMapper.xml,写入批量插入套餐菜品数据的SQL动态语句
<insert id="insertBatch">
insert into setmeal_dish (setmeal_id, dish_id, name, price, copies)
VALUES
<foreach collection="setmealDishList" item="sd" separator=",">
(#{sd.setmealId}, #{sd.dishId}, #{sd.name}, #{sd.price}, #{sd.copies})
</foreach>
</insert>
b. 套餐分页查询
业务规则:
- 根据页码展示菜品信息
- 每页展示10条数据
- 分页查询时可以根据需要输入套餐名称、套餐分类、套餐状态进行查询
在SetmealController中创建分页接口
/**
* 套餐分页查询
* @param setmealPageQueryDTO
* @return
*/
@GetMapping("/page")
@ApiOperation("套餐分页查询")
public Result<PageResult> page(SetmealPageQueryDTO setmealPageQueryDTO){
log.info("套餐分页查询,参数为:{}",setmealPageQueryDTO);
PageResult pageResult = setmealService.pageQuery(setmealPageQueryDTO);
return Result.success(pageResult);
}
在SetmealServiceImpl中实现pagequery方法,及其父类接口
/**
* 套餐分页查询
* @param setmealPageQueryDTO
* @return
*/
@Override
public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
PageHelper.startPage(setmealPageQueryDTO.getPage(), setmealPageQueryDTO.getPageSize());
Page<SetmealVO> page = setmealMapper.pageQuery(setmealPageQueryDTO);
return new PageResult(page.getTotal(), page.getResult());
}
在SetmealMapper中实现pagequery方法,动态SQL语句将写在xml文件中
/**
* 套餐分页查询
* @param setmealPageQueryDTO
* @return
*/
Page<SetmealVO> pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);
在SetmealMapper.xml中,写入分页查询的动态语句
<select id="pageQuery" resultType="com.sky.vo.SetmealVO">
select s.* , c.name as categoryName from setmeal s LEFT OUTER JOIN category c on s.category_id = c.id
<where>
<if test="name != null">
and s.name like concat('%', #{name}, '%')
</if>
<if test="categoryId != null">
and s.category_id = #{categoryId}
</if>
<if test="status != null">
and s.status = #{status}
</if>
</where>
order by s.update_time desc
</select>
c. 删除套餐
业务规则:
- 可以一次删除一个套餐,也可以批量删除菜品
- 起售中的套餐不能删除
- 删除菜品后,关联的套餐菜品数据也需要删除掉
SetmealController中,创建批量删除套餐接口
/**
* 批量删除套餐
* @param ids
* @return
*/
@DeleteMapping
@ApiOperation("批量删除套餐")
public Result delete(@RequestParam List<Long> ids){
log.info("批量删除套餐:{}", ids);
setmealService.deleteBatch(ids);
return Result.success();
}
SetmealServiceImpl中,实现批量删除套餐方法,及其父类接口
/**
* 批量删除套餐
* @param ids
*/
@Override
@Transactional
public void deleteBatch(List<Long> ids) {
if (ids.isEmpty()){
return;
}
// 判断当前菜品是否能够删除---是否存在起售中的菜品
for (Long id : ids) {
Setmeal setmeal = setmealMapper.getById(id);
if (setmeal.getStatus() == StatusConstant.ENABLE){
// 当前套餐为启用状态,不能删除
throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
}
}
// 删除套餐表中的数据
for (Long id : ids) {
setmealMapper.deleteById(id);
// 根据套餐id删除套餐和菜品的关联关系
setmealDishMapper.deleteBySetmealId(id);
}
}
SetmealMapper中,创建删除套餐setmeal方法
/**
* 根据主键id查询套餐
* @param id
* @return
*/
@Select("Select * from setmeal where id = #{id}")
Setmeal getById(Long id);
/**
* 根据主键id删除套餐
* @param id
*/
@Delete("Delete from setmeal where id = #{id}")
void deleteById(Long id);
SetmealDIshMapper中,创建删除套餐菜品setmeal_dish方法
/**
* 根据套餐id删除套餐和菜品的关联关系
* @param setmealId
*/
@Delete("Delete from setmeal_dish where setmeal_id = #{setmealId}")
void deleteBySetmealId(Long setmealId);
d. 修改套餐
(1). 根据id查询套餐,并显示
SetmealController,实现根据id查询套餐
/**
* 根据id查询套餐,用于修改页面回显数据
* @param id
* @return
*/
@GetMapping("/{id}")
@ApiOperation("根据id查询套餐")
public Result<SetmealVO> getByID(@PathVariable Long id){
SetmealVO setmealVO = setmealService.getByIdWithDish(id);
return Result.success(setmealVO);
}
SetmealServiceImpl中,实现根据id查询套餐,及其父类接口
- 通过setmealMapper调用getById()接口
- 通过setmealDishMapper获取套餐关联的菜品信息
/**
* 根据id查询套餐
* @param id
* @return
*/
@Override
public SetmealVO getByIdWithDish(Long id) {
Setmeal setmeal = setmealMapper.getById(id);
List<SetmealDish> setmealDishList = setmealDishMapper.getDishBySetmealId(id);
SetmealVO setmealVO = new SetmealVO();
BeanUtils.copyProperties(setmeal, setmealVO);
setmealVO.setSetmealDishes(setmealDishList);
return setmealVO;
}
setmealDishMapper中,获取套餐关联的菜品信息
/**
* 根据套餐id获取菜关联菜品的数据
* @param setmealId
* @return
*/
@Select("Select * from setmeal_dish where setmeal_id = #{setmealId}")
List<SetmealDish> getDishBySetmealId(Long setmealId);
(2). 再修改套餐
SetmealController,实现修改套餐接口
/**
* 修改套餐
* @param setmealDTO
* @return
*/
@PutMapping
@ApiOperation("修改套餐")
public Result update(@RequestBody SetmealDTO setmealDTO){
log.info("修改套餐:{}", setmealDTO);
setmealService.updateWithDish(setmealDTO);
return Result.success();
}
SetmealServiceImpl中,实现修改套餐方法,及其父类接口
/**
* 修改套餐
* @param setmealDTO
*/
@Override
@Transactional
public void updateWithDish(SetmealDTO setmealDTO) {
Setmeal setmeal = new Setmeal();
BeanUtils.copyProperties(setmealDTO, setmeal);
// 修改套餐基本信息
setmealMapper.update(setmeal);
// 获取套餐id
Long setmealId = setmealDTO.getId();
// 删除原有的套餐关联的菜品信息,操作setmeal_dish表,执行delete
setmealDishMapper.deleteBySetmealId(setmealId);
// 获取套餐关联的菜品信息
List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
if (!setmealDishes.isEmpty()){
setmealDishes.forEach(setmealDish -> {
setmealDish.setSetmealId(setmealId);
});
// 重新向setmeal_dish表插入n条数据
setmealDishMapper.insertBatch(setmealDishes);
}
}
SetmealMapper中,实现修改菜品的接口
/**
* 根据Id修改套餐
* @param setmeal
*/
@AutoFill(OperationType.UPDATE)
void update(Setmeal setmeal);
SetmealMapper.xml中,写入修改菜品的动态SQL语句
<update id="update">
update setmeal
<set>
<if test="categoryId != null">category_id = #{categoryId},</if>
<if test="name != null">name = #{name},</if>
<if test="price != null">price = #{price},</if>
<if test="status != null">status = #{status},</if>
<if test="description != null">description = #{description},</if>
<if test="image != null">image = #{image},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="updateUser != null">update_user = #{updateUser}</if>
</set>
where id = #{id}
</update>
e. 起售停售套餐
业务规则:
- 可以对状态为起售的套餐进行停售操作,可以对状态为停售的套餐进行起售操作
- 起售的套餐可以展示在用户端,停售的套餐不能展示在用户端
- 起售套餐时,如果套餐内包含停售的菜品,则不能起售
在SetmealController中,实现套餐起售、停售接口
/**
* 启售禁售套餐
* @param status
* @param id
* @return
*/
@PostMapping("status/{status}")
@ApiOperation("启售禁售套餐")
public Result startOrStop(@PathVariable Integer status, Long id){
log.info("启售禁售套餐:{}, {}", status, id);
setmealService.startOrStop(status, id);
return Result.success();
}
在SetmealServiceImpl中,实现套餐起售、停售方法,及其父类接口
/**
* 启售停售套餐
* @param status
* @param id
*/
@Override
@Transactional
public void startOrStop(Integer status, Long id) {
// 判断是起售/停售
if (status == StatusConstant.ENABLE){
// 先判断该套餐内的菜品是否包含停售菜品
List<SetmealDish> setmealDishList = setmealDishMapper.getDishBySetmealId(id);
if (!setmealDishList.isEmpty()) {
setmealDishList.forEach(setmealDish -> {
Long dishId = setmealDish.getDishId();
Dish dish = dishMapper.getById(dishId);
if (dish.getStatus() == StatusConstant.DISABLE){
// 套餐内有停售菜品
throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
}
});
}
}
Setmeal setmeal = Setmeal.builder()
.id(id)
.status(status)
.build();
setmealMapper.update(setmeal);
}
Day5:店铺营业状态设置
接口设计:
-
设置营业状态
-
管理端查询营业状态
-
用户端查询营业状态
本项目约定:
-
管理端 发出的请求,统一使用 /admin 作为前缀
-
用户端 发出的请求,统一使用 /user 作为前缀
-
营业状态数据存储方式:基于Redis的字符串来进行存储
-
约定:1表示营业 0表示打烊
-
营业状态数据存储方式:基于Redis的字符串来进行存储
Key | Value |
---|---|
SHOP_STATUS | 1 |
在controller/admin/ShopController中,创建 “设置店铺的营业状态”和“获取店铺的营业状态” 接口方法
@RestController("adminShopController")
@RequestMapping("/admin/shop")
@Api(tags = "店铺相关接口")
@Slf4j
public class ShopController {
public static final String KEY = "SHOP_STATUS";
@Autowired
private RedisTemplate redisTemplate;
/**
* 设置店铺的营业状态
* @param status
* @return
*/
@PutMapping("/{status}")
@ApiOperation("设置店铺的营业状态")
public Result setStatus(@PathVariable Integer status){
log.info("设置店铺的营业状态:{}", status == 1? "营业中":"打烊中");
redisTemplate.opsForValue().set(KEY, status);
return Result.success();
}
/**
* 获取店铺的营业状态
* @return
*/
@GetMapping("/status")
@ApiOperation("获取店铺的营业状态")
public Result<Integer> getStatus(){
Integer status = (Integer) redisTemplate.opsForValue().get(KEY);
log.info("获取到店铺的营业状态为:{}", status == 1? "营业中" : "打烊中");
return Result.success(status);
}
}
在controller/user/ShopController中,创建 “获取店铺的营业状态” 接口方法
@RestController("userShopController")
@RequestMapping("/user/shop")
@Api(tags = "店铺相关接口")
@Slf4j
public class ShopController {
public static final String KEY = "SHOP_STATUS";
@Autowired
private RedisTemplate redisTemplate;
/**
* 获取店铺的营业状态
* @return
*/
@GetMapping("/status")
@ApiOperation("获取店铺的营业状态")
public Result<Integer> getStatus(){
Integer status = (Integer) redisTemplate.opsForValue().get(KEY);
log.info("获取到店铺的营业状态为:{}", status == 1? "营业中" : "打烊中");
return Result.success(status);
}
}