一、界面(其中有三个图标add.png,yulan.png,shanchu.png可以在iconfont-阿里巴巴矢量图标库这里这搜索下载-分别是添加,浏览,删除)
<el-upload
action
list-type="picture-card"
:auto-upload="false"
:file-list="pics"
:limit="1"
:on-change="handleChange"
:on-success="handleSuccess"
:on-error="handleError"
:on-exceed="handleExceed"
ref="pictureEditRef"
:http-request="submitFile"
>
<img src="../../../assets/add.png" style="width: 40px">
<template slot="file" #file="file">
<img class="el-upload-list__item-thumbnail" :src="file.file.url" alt/>
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
<img src="../../../assets/yulan.png" style="width: 20px">
</span>
<span
v-if="!disabled"
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<img src="../../../assets/shanchu.png" style="width: 20px">
</span>
</span>
</template>
</el-upload>
二、放大弹窗
<el-dialog v-model="dialogVisible" :append-to-body="true">
<img width="100%" :src="dialogImageUrl" alt/>
</el-dialog>
三、初始化
pics: [],
disabled: false,
isPicChanged: false,
dialogImageUrl: "",
dialogVisible: false,
四、js(其中this.ruleForm.newsPhoto换成你的图片属性)
handleRemove(file) {
this.pics = []; // 移除图片时清空图片列表
this.ruleForm.newsPhoto = ''; // 同时清空ruleForm中的图片地址
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.file.url;
this.dialogVisible = true;
},
handleChange(file, filelist) {
this.pics = filelist.slice(0); // 更新图片列表
this.isPicChanged = true;
},
handleSuccess(response) {
if (response.code === 0) {
this.ruleForm.newsPhoto = response.data.file; // 上传成功后保存图片地址
} else {
this.$message.error(response.msg);
}
},
handleError(err) {
console.log("上传失败");
console.log(err);
},
handleExceed() {
this.$message.error("图片最多上传一张!");
},
async submitFile() {
return new Promise((resolve, reject) => {
if (this.pics.length > 0 && this.pics[0].raw) {
let formData = new FormData();
formData.append("file", this.pics[0].raw);
this.$http({
url: 'file/upload',
method: "post",
data: formData
}).then(({data}) => {
if (data.code === 0) {
this.ruleForm.newsPhoto = 'upload/' + data.file;
resolve();
} else {
this.$message.error(data.msg);
reject();
}
}).catch(() => {
this.$message.error('图片上传失败');
reject();
});
} else {
resolve();
}
});
},
五、图片初始化赋值(这个是修改或者详情回显用到的,在进页面获取当前图片数据是赋值给pics,其中this.$base.url是定义的全局属性,是你的后端端口路径)
this.pics.push({
url: this.$base.url+_this.ruleForm.newsPhoto,
});
六、修改时如果图片存在且没有修改可以在提交时添加一下判断(如果不需要修改就忽略,不添加会导致图片每次提交都会重新上传但不影响正常使用)
if (this.isPicChanged) {
this.submitFile().then(() => {
//这里放你的提交代码
})
}
七、后端接口方法
package com.controller;
import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.annotation.IgnoreAuth;
import com.entity.EIException;
import com.utils.R;
/**
* 上传文件映射表
*/
@RestController
@RequestMapping("file")
public class FileController{
/**
* 上传文件
*/
@IgnoreAuth
@RequestMapping("/upload")
public R upload(@RequestParam("file") MultipartFile file) throws Exception {
if (file.isEmpty()) {
throw new EIException("上传文件不能为空");
}
String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
Path projectPath = Paths.get("").toAbsolutePath();
File path = new File(projectPath+"/src/main/resources/static");
if(!path.exists()) {
path = new File("");
}
File upload = new File(path,"/upload/");
if(!upload.exists()) {
upload.mkdirs();
}
File path2 = new File(projectPath+"/target/classes/static");
if(!path2.exists()) {
path2 = new File("");
}
File upload2 = new File(path2,"/upload/");
if(!upload2.exists()) {
upload2.mkdirs();
}
String fileName = UUID.randomUUID().toString() + "." + fileExt;
File dest = new File(upload+"/"+fileName);
file.transferTo(dest);
// 创建文件的副本
File destFile = new File(upload2+"/"+fileName);
try (FileInputStream fis = new FileInputStream(dest);
FileOutputStream fos = new FileOutputStream(destFile)) {
byte[] buffer = new byte[1024];
int length;
// 从源文件读取内容并写入到目标文件
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
return R.ok().put("file", fileName);
}
/**
* 下载文件
*/
@IgnoreAuth
@RequestMapping("/download")
public ResponseEntity<byte[]> download(@RequestParam String fileName) {
try {
File path = new File(ResourceUtils.getURL("classpath:static").getPath());
if(!path.exists()) {
path = new File("");
}
File upload = new File(path.getAbsolutePath(),"/upload/");
if(!upload.exists()) {
upload.mkdirs();
}
File file = new File(upload.getAbsolutePath()+"/"+fileName);
if(file.exists()){
/*if(!fileService.canRead(file, SessionManager.getSessionUser())){
getResponse().sendError(403);
}*/
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", fileName);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);
}
} catch (IOException e) {
e.printStackTrace();
}
return new ResponseEntity<byte[]>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}