后端(springBoot)

  • 思路:
    1、实现图片上传接口,利用图片工具类将图片上传至服务器或者本地
    2、实现图片删除接口,利用图片工具类对已上传至服务器或者本地的图片删除
    3、实现数据库修改接口,修改数据库中图片访问路径url
  • 图片工具类
//图片上传,支持多张图片public static List<String> upload(List<MultipartFile> files, String path) throws IOException {List<String> msgs = new ArrayList<>();if (files.size() < 1) {msgs.add("file_empty");return msgs;}for (MultipartFile file : files) {String filename = file.getOriginalFilename();assert filename != null;String type = filename.contains(".") ? filename.substring(filename.lastIndexOf(".")) : null;//以uid重新命名避免重复//拼接文件路径,方便前端接收String filepath = path + UUID.randomUUID() + type;File filesPath = new File(path);if (!filesPath.exists()) {filesPath.mkdir();}BufferedOutputStream out = null;try {//输入图片字节流out = new BufferedOutputStream(new FileOutputStream(new File(filepath)));out.write(file.getBytes());msgs.add(filepath);} catch (Exception e) {e.printStackTrace();} finally {if(out != null){out.flush();out.close();}}}return msgs;}//文件删除public static boolean deleteFiles(String filePath){boolean flag = false;//根据路径创建文件对象File file = new File(filePath);//路径是个文件且不为空时删除文件if(file.isFile() && file.exists()){flag = file.delete();}//删除失败时,返回falsereturn flag;}
  • 图片上传接口
@PostMapping("/image")public AjaxResult uploadImage(@RequestParam(value = "file") List<MultipartFile> file) {List<String> imagePath;String path = "此处为需要上传的服务器或本地路径url";// 调用图片上传工具类try{imagePath = UploadFile.upload(file,path);} catch (IOException e){return AjaxResult.error("图片传输异常" + e);}if(imagePath.get(0).equals("file_empty")) {return AjaxResult.error("图片为空");}return AjaxResult.success(imagePath);}
  • 图片删除接口
@DeleteMapping("/deleteFile/{fileName}")public AjaxResult deleteFile(@PathVariable String fileName){String type = fileName.contains(".") ? fileName.substring(fileName.lastIndexOf(".")) : null;String filePath;assert type != null;if(type.equals(".png") || type.equals(".jpeg") || type.equals(".jpg")){filePath = "上传图片的服务器或本地路径url" + fileName;}else{return AjaxResult.error("文件类型不支持");}boolean b = UploadFile.deleteFiles(filePath);if(!b){return AjaxResult.error();}return AjaxResult.success();}
  • 实体类修改接口
    此接口根据实际业务需求,实现可以修改包括图片url在内的数据库update代码,使用string接收url即可
@PutMapping("/update")public AjaxResult update(@RequestBody Entity entity){return toAjax(service.update(entity));}

前端(Vue+ElementUI)

  • 思路
    1、表单中点击上传图片
    2、利用上传文件之前的钩子进行文件类型以及大小校验
    3、利用上传图片成功钩子将图片信息保存在fileList中,方便后续功能使用
    4、利用文件状态改变钩子将文件存储url添加到表单中
    5、利用文件删除钩子移除图片,需要同时删除后台图片、fileList中图片信息、表单信息
    6、利用文件超出个数限制时的钩子做图片上传数量限制提示
    7、图片回显需要在点击修改按钮后进行赋值,回显属性需要数组类型
  • 图片上传类
data() {return {// 图片上传类ImgUpload: {// 图片上传urluploadURL: "上传接口url",// 图片列表fileList: [],// 图片回显列表re_fileList: [],// 图片上传请求头uploadHeaders: {"tk" : getToken()},}}}
  • 图片上传组件
<el-upload:action = "imgUpload.uploadURL":limit = "Number(1)":file-list = "imgUpload.re_fileList":headers = "imgUpload.uploadHeaders":before-upload = "imgHandleBefore":on-success = "imgHandleSuccess":on-change = "imgUploadStateChange":on-remove = "imgHandleRemove":on-exceed = "imgHandleExceed":auto-upload = "true"list-type = "picture"ref = "imgUpload"accept = "image/jpeg,image/png,image/jpg"><el-button size="small" type="primary">点击上传</el-button><div slot="tip" class="el-upload__tip">只能上传一张jpg/jpeg/png图片,且不超过5Mb</div></el-upload>
  • 图片上传前校验
imgHandleBefore(file){const isLt5M = file.size / 1024 / 1024 < 5;const typeArr = ['image/png', 'image/jpeg', 'image/jpg'];const isJPG = typeArr.indexOf(file.type) !== -1;// 文件格式校验if (!isJPG) {this.$message.error('只能上传jpg/jpeg/png图片');return false;}// 文件大小校验if (!isLt5M) {this.$message.error('上传图片大小不能超过5MB!');return false;}return isLt5M && isJPG;}
  • 图片上传成功钩子
imgHandleSuccess(response){if(response.code !== 200){this.$message.error("图片上传失败!");return;}// 得到一个图片信息对象 临时路径const picInfo = { pic: response.data };// 将图片信息对象,push到fileList数组中this.imgUpload.fileList.push(picInfo);}
  • 图片状态改变钩子
imgUploadStateChange(){// 拼接图片访问url到表单中(仅上传一张,上传多张时需要逗号拼接)if(this.imgUpload.fileList.length !== 0){this.form.image = this.imgUpload.fileList[0].pic;}}
  • 图片删除钩子
imgHandleRemove(file){// 由于上传前校验钩子return false时会调用文件删除钩子,删除前先做判断,若上传成功才可删除if(file && file.status === 'success'){// 0、获取将要删除图片的临时路径以及文件名称let filePath = "";if(file.response !== undefined){filePath = file.response.data[0];}else {filePath = file.url;}let imageName = filePath.substring(filePath.lastIndexOf("\\") + 1);// 1、删除单张后台图片,deleteFile为后台删除图片接口deleteFile(imageName).then(response => {if(response.code !== 200){this.$message.error("删除后台图片失败");return;}this.$message.success("删除图片成功");});// 2、调用splice方法,移除图片信息this.imgUpload.fileList.splice(0,1);// 3、同时表单置空this.form.image = "";}}
  • POI图片上传超出数量警告
poiImgHandleExceed(){this.$message.warning("超过图片上传数量!");}
  • 所有图片文件列表以及回显列表置空
// 点击修改按钮和新增按钮时先调用此删除进行清空图片列表resetImgList(){this.imgUpload.fileList = [];this.imgUpload.re_fileList = [];}
  • 修改按钮中进行图片回显
/** 修改数据函数 */handleUpdate(){// 表单置空this.reset();// 图片列表以及回显列表清空this.resetImgList();this.submitLoading = false;this.open = true;this.title = "";// POI图片回显,response.data.imagee是根据后台查出来的单条数据selectDataById(id).then(response=>{this.form = response.data;// 若是多张图片根据逗号拆分let urlStr = response.data.image.split(",");urlStr.forEach(item => {let obj = {};obj.url = item;this.imgUpload.re_fileList.push(obj);});});}
  • 表单取消按钮
cancel() {// 由于图片自动上传,若有已上传图片需要先删除再取消,否则后台会留存图片if(this.imgUpload.fileList.length > 0){this.$alert('请先移除已上传图片', '警告',{confirmButtonText: "确定",type: "warning"})return;}// 对话框关闭this.open = false;// 表单清空this.reset();}

至此完成整个前端后端图片上传流程,若有不足之处,或更好的建议欢迎评论区讨论。