第四阶段笔记 Jingtao_day06

day 06 商品图片上传

此文档是根据上课流程编写,更多细节及图片请参见刘老师的专栏

江哥的专栏

cgb2008-京淘day06

一. 完成商品CRUD操作
  1. 商品上下架操作

    i. 编辑ItemController

    /* 业务:商品的上下架
       url: http://localhost:8091/item/[instock|reself]
       参数: 1/2
       返回值: SysResult
       SpringMVC参数接收说明:以,分割则自动转化为数组类型
       */
    @RequestMapping("/{op}")
    @ResponseBody
    public SysResult opStock(@PathVariable String op,Long[] ids){
       if(op.equals("instock")){
          System.out.println("=== Instock ===");
          itemService.opStock(ids,2);
       }else if(op.equals("reshelf")){
          System.out.println("=== Reshelf ===");
          itemService.opStock(ids,1);
       }
       return SysResult.success();
    }

    ii. 编辑ItemServiceImpl

    @Override
    public void opStock(Long[] ids,int status) {
       //1.以MP的方法操作数据库 只修改状态码/updated时间
       Item item = new Item();
       QueryWrapper queryWrapper = new QueryWrapper();
       queryWrapper.in("id",ids);
       item.setStatus(status);
       itemMapper.update(item,queryWrapper);
    
       //2.手写SQL
       itemMapper.updateStatus(ids,status);
    }

    iii. 编辑ItemMapper.xml

    void updateStatus(@Param("ids") Long[] ids, @Param("status") int status);
    
       UPDATE tb_item SET status=#{status},updated=now()
       WHERE id IN(
       
          #{id}
       
       )
    
二. 实现商品详情信息的展现
  1. 业务说明

    ​ 一般用户查询商品时,只需要展现展示商品相关信息即可,如果用户点击某个商品时才会展现商品详情,因为商品详情信息是大字段,检索相对较慢浪费性能。

    ​ 1) tb_item;2) tb_item_desc 一对一

    i. 编辑ItemDesc pojo对象

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Accessors(chain = true)
    @TableName("tb_item_desc")
    public class ItemDesc extends BasePojo{
    
        @TableId
        private Long itemId; //与item表中的数据一致
        private String itemDesc;
    }

    ii. 编辑ItemDescMapper

    @Mapper
    public interface ItemDescMapper extends BaseMapper {
    }
  2. 富文本编辑器介绍

    
    
  3. 重构商品新增

    ​ 由于商品的新增是将Item/ItemDesc对象一起新增,所以要实现两张表的入库。

    i. 编辑ItemController

    @RequestMapping("/save")
    @ResponseBody
    public SysResult saveItem(Item item, ItemDesc itemDesc){
       itemService.saveItem(item,itemDesc);
       return SysResult.success();
    }

    ii. 编辑ItemServiceImpl

    // Item表主键自增
    @Override
    @Transactional
    public void saveItem(Item item, ItemDesc itemDesc) {
       item.setStatus(1);
       itemMapper.insert(item);
       //MP用法:如果完成了主键自增,自动实现了主键回显
       //获取主键信息
       itemDesc.setItemId(item.getId());
       itemDescMapper.insert(itemDesc);
    }
  4. 重构商品编辑

    ​ 查询到商品的详情信息,返回给用户,然后将修改后的内容执行两次入库操作。

    i. 编辑ItemController

    /* 业务:根据商品id号,检索商品详情
       url: http://localhost:8091/item/desc/1233
       参数: rest风格
       返回值: SysResult
       SpringMVC参数接收说明:以,分割则自动转化为数组类型
       */
    @RequestMapping("/query/item/desc/{itemId}")
    @ResponseBody
    public SysResult findItemDescById(@PathVariable Long itemId){
       ItemDesc itemDesc = itemService.findItemDescById(itemId);
       return SysResult.success(itemDesc);
    }

    ii. 编辑ItemServiceImpl

    @Override
    public ItemDesc findItemDescById(Long itemId) {
       return itemDescMapper.selectById(itemId);
    }
  5. 重构商品更新

    ​ 用户在更新商品时,要更新两张表的数据Item/ItemDesc

    i. 编辑ItemController

    @RequestMapping("/update")
    @ResponseBody
    public SysResult updateItem(Item item,ItemDesc itemDesc){
       itemService.updateItem(item,itemDesc);
       return SysResult.success();
    }

    ii. 编辑ItemServiceImpl

    public void updateItem(Item item, ItemDesc itemDesc) {
       itemMapper.updateById(item);
       //补全数据
       itemDesc.setItemId(item.getId());
       itemDescMapper.updateById(itemDesc);
    }
  6. 重构商品删除

    i. 编写ItemServiceImpl

    public void deleteItems(Integer[] ids) {
       //itemMapper.deleteBatchIds(Arrays.asList(ids));  //MP
       itemMapper.deleteItems(Arrays.asList(ids));  //手写SQL
       itemDescMapper.deleteBatchIds(Arrays.asList(ids)));
    }
三. 实现商品图片上传
  1. 文件上传入门案例

    i. 页面标识

    实现文件长传

    ii. 编辑FileController

    @RestController
    public class FileController {
        @RequestMapping("/file")
        public String file(MultipartFile fileImage) throws IOException {
            //1.获取图片的名称
            String name = fileImage.getOriginalFilename();
            //2.定义文件目录
            String fileDirPath = "E:/jt_img";
            //3.创建目录
            File fileDir = new File(fileDirPath);
            if(!fileDir.exists()){
                fileDir.mkdirs();
            }
            //4.生成文件全路径
            String filePath = fileDirPath+"/"+name;
            File imageFile = new File(filePath);
            //5.实现文件上传
            fileImage.transferTo(imageFile);
            return "FILE UPLOAD OK";
        }
    }
  2. 业务实现

    i. 描述

    ​ url:localhost:8091/pic/upload?dir=image

    ​ 参数类型:uploadFile

    ​ 返回值JSON结构:{"error":0,"url":"图片保存路径","width":宽度,"height":高度}

    ii. 编辑ImageVO

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Accessors(chain = true)
    public class ImageVO {
        //{"error":0,"url":"图片保存路径","width":宽度,"height":高度}
        private Integer error;
        private String url;
        private Integer width;
        private Integer height;
        public static ImageVO fail(){
           return new ImageVO(1,null,null,null);
        }
        public static ImageVO success(String url,Integer width,Integer height){
           return new ImageVO(0, url, width, height);
        }
    }

    iii. 编辑FileController

    @Autowired
    private FileService fileService;
    /* 业务需求:实现文件上传操作
        url: localhost:8091/pic/upload?dir=image
        参数: uploadFile
        返回值: ImageVO
    */
    @RequestMapping("/pic/upload")
    public ImageVO upload(MultipartFile uploadFile){
        return fileService.upload(uploadFile);
    }

    iv. 编辑FileServiceImpl

    @Service
    public class FileServiceImpl implements FileService{
        private static Set typeSet = new HashSet<>();
        //静态代码块为静态成员赋值
        static {
            typeSet.add(".jpg");
            typeSet.add(".png");
            typeSet.add(".gif");
        }
    
        /* 业务逻辑:实现文件上传
            1.校验图片的类型 jpg png gif
            2.校验文件是否为恶意程序
            3.采用分目录的结构进行存储
            4.避免文件重名 UUID
         */
        @Override
        public ImageVO upload(MultipartFile uploadFile) {
            //1.利用集合校验/利用正则表达式
            String fileName = uploadFile.getOriginalFilename().toLowerCase();
            int index = fileName.lastIndexOf(".");
            String fileType = fileName.substring(index);  //.jpg
            //List Map Set []
            if(!typeSet.contains(fileType))
                return ImageVO.fail();
    
            //2.如果是图片 高度 宽度
            try {
                BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
                int width = bufferedImage.getWidth();
                int height = bufferedImage.getHeight();
                if(width==0||height==0)
                    return ImageVO.fail();
    
                //3.按照 年-月-日 的方式进行目录的划分
                String fileDir = "E:/jt_img";
                String dateDir = new SimpleDateFormat("/yyyy/MM/dd/")
                        .format(new Date());
                //E:/jt_img/2020/12/1/
                String fileDirPath = fileDir+dateDir;
                File dirFile = new File(fileDirPath);
                if(!dirFile.exists())
                    dirFile.mkdirs();
    
                //4.UUID 32位16进制数 --> 2^128
                //  hashCode 8为16进制数 --> 2^32
                String uuid = java.util.UUID.randomUUID().toString()
                        .replace("-", "");
                String uuidName = uuid+fileType;
                File realFile = new File(fileDirPath+uuidName);
                uploadFile.transferTo(realFile);
                String url = "";
                return ImageVO.success(url, width, height);
            } catch (IOException e) {
                e.printStackTrace();
                return ImageVO.fail();  //报错返回
            }
        }
    }
作业: 了解反向代理/正向代理;磁盘地址优化

你可能感兴趣的:(java,intellij-idea)