一.公共字段自动填充
1.需求分析
因为公共字段过多会出现代码冗余,不便于维护的问题,所以我们通过想办法为其设置自动填充。

实现思路

2.代码实现
二.新增菜品
1.需求分析
产品原型

业务规则

接口设计





数据库设计
2.代码实现
1.文件上传

controller层实现文件上传,需要调用aliOssUtil工具类,那么就需要创建这个工具类对象,接着我们就应该想办法为这个对象传递参数,想要传递参数,我们想到了IOC容器的自动注入,这里我们使用了一个配置类讲AliOssUtil工具类对象交给IOC容器,然后直接在controller层自动注入即实现了文件上传的功能。
yml配置文件
alioss:
endpoint: ${sky.alioss.endpoint} //访问域名
access-key-id: ${sky.alioss.access-key-id} //访问密钥id
access-key-secret: ${sky.alioss.access-key-secret} //访问密钥密码
bucket-name: ${sky.alioss.bucket-name} //存储桶名称
alioss:
endpoint: oss-cn-beijing.aliyuncs.com
access-key-id: your-access-key-id
access-key-secret: your-access-key-secret
bucket-name: your-bucket-name
controller
@RestController
@Slf4j
@Api("文件上传")
@RequestMapping("/admin/common")
public class CommonController {
@Autowired
private AliOssUtil aliOssUtil;
@PostMapping("/upload")
@ApiOperation("文件上传")
public Result<String> upload(MultipartFile file){
log.info("文件上传:{}",file);
try {
String originalFilename = file.getOriginalFilename();
String substring = originalFilename.substring(originalFilename.lastIndexOf("."));
String objectName = UUID.randomUUID().toString() + substring;
String filePath = aliOssUtil.upload(file.getBytes(), objectName);
return Result.success(filePath);
} catch (Exception e) {
log.error("文件失败的原因:{}",e);
}
return Result.error(MessageConstant.UPLOAD_FAILED);
}
}
配置类
package com.sky.config;
import com.sky.properties.AliOssProperties;
import com.sky.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Slf4j
public class OssConfiguration {
@Bean
@ConditionalOnMissingBean
public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties);
return new AliOssUtil(aliOssProperties.getEndpoint(),
aliOssProperties.getAccessKeyId(),
aliOssProperties.getAccessKeySecret(),
aliOssProperties.getBucketName());
}
}
2.新增菜品
controller
package com.sky.controller.admin;
import com.sky.dto.DishDTO;
import com.sky.result.Result;
import com.sky.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/admin/dish")
@Slf4j
public class DishController {
@Autowired
private DishService dishService;
@PostMapping
public Result saveWithFlavor(@RequestBody DishDTO dishDTO){
log.info("新增菜品:{}",dishDTO);
dishService.saveWithFlavor(dishDTO);
return Result.success();
}
}
service
@Service
@Slf4j
public class DishServiceIml implements DishService {
@Autowired
private DishMapper dishMapper;
@Autowired
private DishFlavorMapper dishFlavorMapper;
@Override
@Transactional
public void saveWithFlavor(DishDTO dishDTO) {
Dish dish = new Dish();
BeanUtils.copyProperties(dishDTO,dish);
dish.setCreateTime(LocalDateTime.now());
dish.setUpdateTime(LocalDateTime.now());
dish.setCreateUser(BaseContext.getCurrentId());
dish.setUpdateUser(BaseContext.getCurrentId());
//新增菜品
dishMapper.saveWithFlavor(dish);
Long dishId = dish.getId();
//新增口味
List<DishFlavor> flavors = dishDTO.getFlavors();
if(flavors != null && !flavors.isEmpty()){
flavors.forEach(dishFlavor -> {
dishFlavor.setDishId(dishId);
});
dishFlavorMapper.saveWithFlavor(flavors);
}
}
}
mapper
@Mapper
public interface DishMapper {
/**
* 根据分类id查询菜品数量
* @param categoryId
* @return
*/
@Select("select count(id) from dish where category_id = #{categoryId}")
Integer countByCategoryId(Long categoryId);
void saveWithFlavor(Dish dish);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.DishMapper">
<insert id="saveWithFlavor" useGeneratedKeys="true" keyProperty="id">
insert into dish (name, category_id, price, image, description, create_time, update_time, create_user,
update_user, status)
values (#{name}, #{categoryId}, #{price}, #{image}, #{description}, #{createTime}, #{updateTime}, #{createUser},
#{updateUser}, #{status})
</insert>
</mapper>
@Mapper
public interface DishFlavorMapper {
void saveWithFlavor(List<DishFlavor> flavors);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.DishFlavorMapper">
<insert id="saveWithFlavor">
insert into dish_flavor (dish_id, name, value) VALUES
<foreach collection="flavors" item="df" separator=",">
(#{df.dishId},#{df.name},#{df.value})
</foreach>
</insert>
</mapper>
三.菜品分页查询
1.需求分析
产品原型

业务规则

接口设计



2.代码实现
controller
@GetMapping("/page")
@ApiOperation("分页查询")
public Result<PageResult> pageQuery(DishPageQueryDTO dishPageQueryDTO){
log.info("分页查询:{}",dishPageQueryDTO);
PageResult pageResult = dishService.pageQuery(dishPageQueryDTO);
return Result.success(pageResult);
}
service
@Override
public PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) {
PageHelper.startPage(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize());
Page<DishVO> page = dishMapper.pageQuery(dishPageQueryDTO);
return new PageResult(page.getTotal(),page.getResult());
}
mapper
Page<DishVO> pageQuery(DishPageQueryDTO dishPageQueryDTO);
<select id="pageQuery" resultType="com.sky.vo.DishVO">
select d.* , c.name as categoryName from dish d left outer join category c on d.category_id = c.id
<where>
<if test="name != null">
and d.name like concat('%',#{name},'%')
</if>
<if test="categoryId != null">
and d.category_id = #{categoryId}
</if>
<if test="status != null">
and d.status = #{status}
</if>
</where>
order by d.create_time desc
</select>
四.删除菜品
1.需求分析
产品原型

业务规则

接口设计

数据库设计

2.代码实现
controller
@DeleteMapping
@ApiOperation("删除菜品")
public Result delete(@RequestParam List<Long> ids){
log.info("删除菜品:{}",ids);
dishService.deleteBatch(ids);
return Result.success();
}
service
@Override
public void deleteBatch(List<Long> ids) {
//菜品是否起售,不满足条件则不能删除
for (Long id :ids) {
Dish dish = dishMapper.select(id);
Object setmealDishId = setmealDishMapper.selectById(id);
if (dish.getStatus() == StatusConstant.ENABLE) {
throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
}
}
//菜品是否与套餐关联
for (Long id :ids) {
Object setmealDishId = setmealDishMapper.selectById(id);
if (setmealDishId != null) {
throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
}
}
//如果可以删除口味数据一并删除
for (Long id :ids){
dishMapper.delete(id);
dishFlavorMapper.delete(id);
}
}
mapper
@Select("select * from dish where id = #{id}")
Dish select(Long id);
package com.sky.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface SetmealDishMapper {
@Select("select setmeal_id from setmeal_dish where dish_id = #{id}")
Object selectById(Long id);
void delete(List<Long> ids);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.SetmealDishMapper">
<delete id="delete">
delete from setmeal_dish where setmeal_id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
</mapper>
五.修改菜品
1.需求分析
产品原型
接口设计



要想实现更新操作,我们应该先查询回显,然后update。
因为这里涉及多表查询,所以我们有两个思路,一个是外连接,一个是两次查询,这里我们使用两次查询的方法。
查询回显结束之后,我们如何实现更新呢。我们依旧采取分别更新的方法进行更新。
首先对dish进行更新。
那么到了对flavors进行更新的时候,因为flavor的数量可能增多或减少,所以这里不建议直接更新,那么我们该怎么呢?我们可以先删除后增加以实现修改的效果
2.代码实现
controller
@PutMapping
@ApiOperation("修改菜品")
public Result updateById(@RequestBody DishDTO dishDTO){
log.info("修改菜品:{}",dishDTO);
dishService.updateById(dishDTO);
return Result.success();
}
service
/**@Override
public void updateById(DishDTO dishDTO) {
Dish dish = new Dish();
BeanUtils.copyProperties(dishDTO,dish);
dish.setUpdateTime(LocalDateTime.now());
dish.setUpdateUser(BaseContext.getCurrentId());
//修改菜品
dishMapper.updateById(dish);
//修改口味
dishFlavorMapper.delete(dishDTO.getId());
if(!dishDTO.getFlavors().isEmpty()){
dishDTO.getFlavors().forEach(flavor -> {
flavor.setDishId(dishDTO.getId());
});
dishFlavorMapper.saveWithFlavor(dishDTO.getFlavors());
}
}
mapper
@Update("UPDATE dish SET name = #{name}, category_id = #{categoryId}, price = #{price}, image = #{image}, description = #{description}, status = #{status}, update_time = #{updateTime}, update_user = #{updateUser} WHERE id = #{id}")
void updateById(Dish dish);