文件上传下载
/**
* 文件上传和下载
*/
@RestController
@RequestMapping("/common")
@Slf4j
public class CommonController {
@Value("${reggie.path}")
private String basePath;
/**
* 文件上传
* @param file
* @return
*/
@PostMapping("/upload")
public R<String> upload(MultipartFile file)
{
// file是一个临时文件, 需要转存到指定位置, 否则本次请求完成后, 临时文件会删除
log.info(file.toString());
// 原始文件名
String originalFilename = file.getOriginalFilename();
// 后缀
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
// 使用UUID重新生成文件名, 防止文件名称重复造成文件覆盖
String fileName = UUID.randomUUID().toString()+suffix;
// 创建目录对象
File dir = new File(basePath);
// 判断当前目录是否存在
if(!dir.exists()){
// 目录不存在, 需要创建
dir.mkdirs();
}
try {
// 将临时文件转存到指定位置
file.transferTo(new File(basePath+ fileName));
} catch (IOException e) {
throw new RuntimeException(e);
}
return R.success(fileName);
}
/**
* 文件下载
* @param name
* @param response
*/
@GetMapping("/download")
public void download(String name, HttpServletResponse response)
{
try {
// 输入流, 读取文件内容
FileInputStream fileInputStream = new FileInputStream(new File(basePath+name));
// 输出流, 将文件写回浏览器, 在浏览器展示图片
ServletOutputStream outputStream = response.getOutputStream();
response.setContentType("image/jpeg");
int len = 0;
byte[] bytes = new byte[1024];
while( (len = fileInputStream.read(bytes)) != -1 ) {
outputStream.write(bytes, 0, len);
}
// 关闭资源
outputStream.close();
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
菜品管理
新增菜品
// DishDto
public class DishDto extends Dish {
private List<DishFlavor> flavors = new ArrayList<>();
private String categoryName;
private Integer copies;
}
// DishServiceImpl
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
@Autowired
private DishFlavorService dishFlavorService;
/**
* 新增菜品, 同时保存对应的口味数据
* @param dishDto
*/
@Override
@Transactional
public void saveWithFlavor(DishDto dishDto) {
// 保存菜品的基本信息到菜品表dish
this.save(dishDto);
// 获取菜品id
Long dishId = dishDto.getId();
// 菜品口味
List<DishFlavor> flavors = dishDto.getFlavors();
flavors = flavors.stream().map( (item) -> {
item.setDishId(dishId);
return item;
}).collect(Collectors.toList());
// 保存菜品的口味数据到菜品口味表dish_flavor
dishFlavorService.saveBatch(flavors);
}
}
总结
- 设计DishDto封装Dish, DishFlavor来接收前端传送的json数据.
- 在数据插入dish表后, 才会有菜品id, 再将菜品id赋给口味数据.
菜品信息分页查询
public R<Page> page(int page, int pageSize, String name)
{
log.info("page={}, pageSize={}, name={}", page, pageSize, name);
Page pageInfo = new Page(page, pageSize);
Page dishDtoPage = new Page<>();
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(StringUtils.isNotEmpty(name), Dish::getName, name);
queryWrapper.orderByDesc(Dish::getUpdateTime);
dishService.page(pageInfo, queryWrapper);
BeanUtils.copyProperties(pageInfo, dishDtoPage, "records");
List<Dish> records = pageInfo.getRecords();
List<DishDto> list = records.stream().map( (item)->{
DishDto dishDto = new DishDto();
BeanUtils.copyProperties(item, dishDto);
// 分类id
Long categoryId = item.getCategoryId();
// 分类对象
Category category = categoryService.getById(categoryId);
// 分类名称
String categoryName = category.getName();
dishDto.setCategoryName(categoryName);
return dishDto;
}).collect(Collectors.toList());
dishDtoPage.setRecords(list);
return R.success(dishDtoPage);
}
总结
- 前端页面需要categoryName, 但是pageInfo中的records中只有categoryId.
- 替换records(BeanUtils复制分页信息), 将原本的dish集合替换为dishDto集合(BeanUtils复制dish信息), 从数据库中通过categoryId查询categoryName, 再将categoryName赋值给dishDto对象.
修改菜品
// Service 回显数据
/**
* 根据id查询菜品信息和对应的口味信息
* @param id
* @return
*/
public DishDto getByIdWithFlavor(Long id) {
// 查询菜品基本信息, 从dish表查询
Dish dish = this.getById(id);
// 查询当前菜品对应的口味信息, 从dish_flavor表查询
LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DishFlavor::getDishId, id);
List<DishFlavor> dishFlavors = dishFlavorService.list(queryWrapper);
DishDto dishDto = new DishDto();
BeanUtils.copyProperties(dish, dishDto);
dishDto.setFlavors(dishFlavors);
return dishDto;
}
// Service 更新数据
/**
* 更新菜品信息, 同时更新对应的口味信息
* @param dishDto
*/
@Override
@Transactional
public void upateWithFlavor(DishDto dishDto) {
// 更新dish表
this.updateById(dishDto);
// 清理当前菜品对应的口味数据
LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DishFlavor::getDishId, dishDto.getId());
dishFlavorService.remove(queryWrapper);
// 添加当前提交过来的口味数据
List<DishFlavor> flavors = dishDto.getFlavors();
flavors = flavors.stream().map( (item) -> {
item.setDishId(dishDto.getId());
return item;
}).collect(Collectors.toList());
dishFlavorService.saveBatch(flavors);
}
总结
- 更新口味数据时无法直接更新, 因为增加口味和删除口味无法通过更新操作实现.
- 增加口味时, 增加的口味数据没有dishId, 所以需要增加dishId.
修改菜品状态
@PostMapping("/status/{status}")
public R<String> updateStatus(@RequestParam List<Long> ids,@PathVariable int status)
{
log.info("id: {}, status: {}", ids, status);
LambdaUpdateWrapper<Dish> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.in(Dish::getId, ids);
updateWrapper.set(Dish::getStatus, status);
dishService.update(updateWrapper);
return R.success("修改菜品售卖状态成功");
}
删除菜品
@Override
@Transactional
public void removeWithDish(List<Long> ids) {
// 查询套餐状态, 确定是否可用删除
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper();
queryWrapper.in(Setmeal::getId, ids);
queryWrapper.eq(Setmeal::getStatus, 1);
int count = this.count(queryWrapper);
if(count > 0){
throw new CustomException("套餐正在售卖中, 不能删除");
}
// 删除套餐表数据
this.removeByIds(ids);
// 删除套餐菜品表数据
LambdaQueryWrapper<SetmealDish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
dishLambdaQueryWrapper.in(SetmealDish::getSetmealId, ids);
setmealDishService.remove(dishLambdaQueryWrapper);
}
根据条件查询菜品数据
@GetMapping("/list")
public R<List<Dish>> list(Dish dish)
{
// 构造查询条件
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
// 查询该分类的菜品
queryWrapper.eq(dish.getCategoryId()!=null, Dish::getCategoryId, dish.getCategoryId());
// 根据name查询菜品
queryWrapper.like(dish.getName()!=null, Dish::getName, dish.getName());
// 查询状态为1(起售状态)的菜品
queryWrapper.eq(Dish::getStatus, 1);
// 添加排序条件
queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
// 查询数据
List<Dish> dishList = dishService.list(queryWrapper);
return R.success(dishList);
}
来源
黑马程序员. 瑞吉外卖项目