day 06 商品图片上传
此文档是根据上课流程编写,更多细节及图片请参见刘老师的专栏
江哥的专栏
一. 完成商品CRUD操作
商品上下架操作
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 id="updateStatus"> UPDATE tb_item SET status=#{status},updated=now() WHERE id IN( <foreach collection="ids" item="id" separator=","> #{id} </foreach> ) </update>
二. 实现商品详情信息的展现
业务说明
一般用户查询商品时,只需要展现展示商品相关信息即可,如果用户点击某个商品时才会展现商品详情,因为商品详情信息是大字段,检索相对较慢浪费性能。
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<ItemDesc> { }
富文本编辑器介绍
<script type="text/javascript"> $(function(){ KindEditor.ready(function(){ KindEditor.create("#editor") }) }) </script> <textarea style="width:700px;height:350px" id="editor"></textarea>
重构商品新增
由于商品的新增是将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); }
重构商品编辑
查询到商品的详情信息,返回给用户,然后将修改后的内容执行两次入库操作。
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); }
重构商品更新
用户在更新商品时,要更新两张表的数据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); }
重构商品删除
i. 编写ItemServiceImpl
public void deleteItems(Integer[] ids) { //itemMapper.deleteBatchIds(Arrays.asList(ids)); //MP itemMapper.deleteItems(Arrays.asList(ids)); //手写SQL itemDescMapper.deleteBatchIds(Arrays.asList(ids))); }
三. 实现商品图片上传
文件上传入门案例
i. 页面标识
<h1>实现文件长传</h1> <!--enctype="开启多媒体标签" --> <form action="http://localhost:8091/file" method="post" enctype="multipart/form-data"> <input name="fileImage" type="file" /> <input type="submit" value="提交"/> </form>
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"; } }
业务实现
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<String> 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(); //报错返回 } } }
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。