黑马程序员——瑞吉外卖项目解析(4)

文件上传下载

import com.cc.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.UUID;

@RestController
@RequestMapping("/common")
@Slf4j
public class CommonController {

    //拿到yml里保存的文件路径
    @Value("${takeOutFile.fileLocaltion}")
    private String fileLoaction;


    /**
     * 上传图片
     * @param file 文件名称,和前台传来的文件名称是一致的
     * @return
     */
    @PostMapping("/upload")
    public Result<String> upLoadFile(MultipartFile file){
        //这里的file只是一个临时的文件存储,临时存储到某一个位置,然后待接收完毕后再转存到目标位置上,然后再把这个临时文件删除
        //截取文件后缀
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.'));
        //生成UUID
        String randomUUID = UUID.randomUUID().toString();
        //拼接文件最后名称,结果为文件本体名字+UUID+后缀
        String fileName = file.getOriginalFilename() + randomUUID + suffix;

        //保证存储的位置有这个文件夹
        File dir = new File(fileLoaction);
        if (!dir.exists()) {
            //目标存储位置不存在,就创建一个文件夹
            dir.mkdirs();
        }

        try {
            //转存文件到指定位置+文件的名称全拼
            file.transferTo(new File(fileLoaction+fileName));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //把文件的名字上传回去,方便后续回显读取路径
        return Result.success(fileName);
    }


    /**
     * 文件回显接口
     * @param httpServletResponse 响应对象
     * @param name 上传的文件名称
     * @throws IOException IO异常
     */
    @GetMapping("/download")
    public void fileDownload(HttpServletResponse httpServletResponse,String name) throws IOException {
        //把刚刚存的文件读取到内存中,准备回显
        FileInputStream fileInputStream = new FileInputStream(new File(fileLoaction+name));

        //把读取到内存中的图片用输出流写入Servlet响应对象里
        ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();

        //可选项,选择响应类型
        httpServletResponse.setContentType("image/jpeg");

        //用byte数组写入,注意是小写b,不是大写,大写就是包装类了
        byte[] fileArray = new byte[1024];
        int length=0;
        try {
            //只要没读到数组的尾部就一直读下去,这部分是IO的内容
            while ((length=fileInputStream.read(fileArray))!=-1) {
                //写入响应流,从0开始,写入到数组末尾长度
                servletOutputStream.write(fileArray, 0, length);
                //把流里的东西挤出来
                servletOutputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭流
            fileInputStream.close();
            servletOutputStream.close();
        }
        return;
    }

}

新增菜品

/**
     * 新增菜品
     * @param dishDto 传输对象
     * @return
     */
    @PostMapping()
    public Result<String> addDish(@RequestBody DishDto dishDto) {
        log.info(dishDto.toString());
        dishService.addDishWithFlavor(dishDto);
        return Result.success("保存成功");
    }

菜品信息分页查询

/**
     * 菜品信息分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public Result<Page> page(int page,int pageSize,String name){

        //构造分页构造器对象
        Page<Dish> pageInfo = new Page<>(page,pageSize);
        //DishDto是前端要的东西和后端的Dish不一样,要扩展一下
        Page<DishDto> dishDtoPage = new Page<>();

        //条件构造器
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        //添加过滤条件
        queryWrapper.like(name != null,Dish::getName,name);
        //添加排序条件
        queryWrapper.orderByDesc(Dish::getUpdateTime);

        //执行分页查询
        dishService.page(pageInfo,queryWrapper);

        //对象拷贝,忽略record对象,因为record就是查出来的记录数,也就是pageInfo
        BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");

        List<Dish> records = pageInfo.getRecords();
        //将List集合搬入Dto中
        //这里是流式编程的内容,或者用foreach来进行搬运也可以解决
        List<DishDto> list = records.stream().map((item) -> {
            DishDto dishDto = new DishDto();

            BeanUtils.copyProperties(item,dishDto);

            Long categoryId = item.getCategoryId();//分类id
            //根据id查询分类对象
            Category category = categoryService.getById(categoryId);
            if(category != null){
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            return dishDto;
        }).collect(Collectors.toList());
        dishDtoPage.setRecords(list);

        return Result.success(dishDtoPage);
    }

修改菜品

 /**
     * 更新菜品操作
     * @param dishDto
     * @return
     */
    @PutMapping()
    public Result<String> updateDish(@RequestBody DishDto dishDto) {
        log.info(dishDto.toString());
        dishService.updateDishWithFlavor(dishDto);

        /*
        * 大面积全清理的写法
        * */
        //Set keys = redisTemplate.keys("dish_*");
        //redisTemplate.delete(keys);

        //精确删除,在售状态的
        String redisKey = "dish_" + dishDto.getCategoryId() + "_" + dishDto.getStatus()+"_1";
        log.info("准备清理key为:{} 的缓存数据",redisKey);
        redisTemplate.delete(redisKey);


        return Result.success("更新成功");
    }

重写服务

/**
     * 更新口味操作,和上面的添加操作异曲同工
     * @param dishDto
     */
    @Override
    @Transactional
    public void updateDishWithFlavor(DishDto dishDto) {
        //Dish表是可以直接更新操作的,这里也是一样的,传入的是Dish的子类,可以直接操作,默认也就是按Dish类更新了
        dishService.updateById(dishDto);
        //Dish_Flavor表比较特殊,所以需要先删除再插入
        //Dish_Flavor表字段删除,所有当前dish id的口味
        LambdaQueryWrapper<DishFlavor> lambdaQueryWrapper = new LambdaQueryWrapper();
        //子类可以直接获取父类的内容了
        lambdaQueryWrapper.eq(DishFlavor::getDishId, dishDto.getId());
        dishFlavorService.remove(lambdaQueryWrapper);
        //再插入
        List<DishFlavor> flavorList=dishDto.getFlavors();
        //遍历
        for (DishFlavor dishFlavors:flavorList) {
            dishFlavors.setDishId(dishDto.getId());
        }
        //saveBatch是批量集合的存储
        dishFlavorService.saveBatch(flavorList);
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
很抱歉,我不能提供特定项目的代码或数据库。但是,我可以帮助您了解如何创建一个外卖项目的基本数据库结构,以供参考。 一个基本的外卖项目可能包括以下几个主要表格: 1. 用户表(users):存储用户的个人信息,如用户ID、用户名、密码、手机号码、地址等。 ```sql CREATE TABLE users ( user_id INT PRIMARY KEY, username VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, phone_number VARCHAR(20), address VARCHAR(255) ); ``` 2. 商家表(restaurants):存储商家的信息,如商家ID、商家名称、地址等。 ```sql CREATE TABLE restaurants ( restaurant_id INT PRIMARY KEY, name VARCHAR(255) NOT NULL, address VARCHAR(255) ); ``` 3. 菜品表(dishes):存储不同菜品的信息,如菜品ID、菜品名称、价格等。 ```sql CREATE TABLE dishes ( dish_id INT PRIMARY KEY, name VARCHAR(255) NOT NULL, price DECIMAL(10, 2) NOT NULL, restaurant_id INT, FOREIGN KEY (restaurant_id) REFERENCES restaurants (restaurant_id) ); ``` 4. 订单表(orders):存储用户下的订单信息,如订单ID、用户ID、商家ID、订单状态等。 ```sql CREATE TABLE orders ( order_id INT PRIMARY KEY, user_id INT, restaurant_id INT, status VARCHAR(50), FOREIGN KEY (user_id) REFERENCES users (user_id), FOREIGN KEY (restaurant_id) REFERENCES restaurants (restaurant_id) ); ``` 5. 订单详情表(order_details):存储每个订单中菜品的详细信息,如订单详情ID、订单ID、菜品ID、数量等。 ```sql CREATE TABLE order_details ( detail_id INT PRIMARY KEY, order_id INT, dish_id INT, quantity INT, FOREIGN KEY (order_id) REFERENCES orders (order_id), FOREIGN KEY (dish_id) REFERENCES dishes (dish_id) ); ``` 以上只是一个简单的外卖项目数据库结构示例,实际的项目可能会更加复杂。您可以根据您的具体需求进行调整和扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值