版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Mr_EvanChen/article/details/83899143
1、后端部分
Controller代码
// 上传
@PostMapping("upload")
@ResponseBody
public Result upload(MultipartFile files, Integer id, String type){
fileService.upload(files, id, type);
return success().setRet(0);
}
// 下载
@GetMapping("download")
@ResponseBody
public void download(HttpServletResponse response, Integer id){
fileService.download(response, id);
}
Service代码
@Value("${fileServer.storeDir}")
private String storeDir;
@Autowired
private FileMapper fileMapper;
@Override
public void upload(MultipartFile file, Integer id, String type) {
logger.info("文件关联id:{}, 文件名:{}", id, file.getOriginalFilename());
logger.info("文件后缀名:{}", file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")));
if(!file.isEmpty()){
String dir = getStoreDir();
File tempFile = new File(dir + System.currentTimeMillis() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")));
try {
file.transferTo(tempFile);
FileInfo fileInfo = new FileInfo()
.setName(file.getOriginalFilename())
.setPath(tempFile.getAbsolutePath())
.setSize(tempFile.length())
.setTarget(id)
.setCreateDate(new Date())
.setMd5(FileUtil.md5(tempFile))
.setType(type);
fileMapper.insert(fileInfo);
} catch (IOException e) {
logger.error(e.getMessage(), e);
throw new InternalServerException("file build error");
}
}
}
@Override
public void download(HttpServletResponse response, Integer id) {
FileInfo fileInfo = fileMapper.findFileById(id);
logger.info("下载文件名:{}", fileInfo.getName());
File file = new File(fileInfo.getPath());
if (!FileUtil.isExistingFile(file)) {
throw new ResourceNotFoundException("file not found");
}
try (OutputStream outputStream = response.getOutputStream();
InputStream inputStream = new FileInputStream(file)) {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileInfo.getName(), "UTF-8"));
FileCopyUtils.copy(inputStream, outputStream);
} catch (IOException e) {
logger.error("下载文件失败!",e);
throw new RemoteServiceUnavailableException("file download error");
}
}
private String getStoreDir(){
String dir = storeDir + File.separator ;
// String dir = storeDir + File.separator + System.currentTimeMillis() + File.separator;
try {
FileUtil.mkdir(dir);
} catch (IOException e) {
logger.error("获取存储目录失败!",e);
throw new InternalServerException("file build error");
}
return dir;
}
private void delFile(String path){
try {
FileUtil.delete(path);
} catch (IOException e) {
logger.error("删除文件失败!",e);
throw new InternalServerException("file delete error");
}
}
在application.yml配置文件中设置文件存储路径(这里假设是本地的E:\ptms中)、以及限制上传文件大小(这里设置为40M)。
# 应用名称
spring:
application:
name: ptms
resources:
static-locations: classpath:/static
cache:
period: PT1M # 60 SECONDS
servlet:
multipart:
max-file-size: 40Mb
max-request-size: 40Mb
fileServer:
storeDir: E:\ptms
2、前端部分
前端代码如下,只看核心的上传下载即可。上传的控件采用element的el-upload控件,下载采用的是window.location.href。同时,在表单验证完之后,提交表单之前,还做了文件大小的校验,采用的是遍历this.$refs.upload.uploadFiles。
<template>
<div>
<el-form class="mt10 pd10 elForm" :rules="rules" ref="ruleForm" :model="ruleForm" label-width="130px" :label-position="labelPosition">
<el-form-item label="项目名称:" prop="name" :inline-message="true">
<el-col :span="8">
<el-input placeholder="请输入项目名称" v-model="ruleForm.name"></el-input>
</el-col>
</el-form-item>
<el-form-item label="项目版本:" prop="version">
<el-col :span="8">
<el-input placeholder="请输入项目版本" v-model="ruleForm.version"></el-input>
</el-col>
</el-form-item>
<el-form-item label="产品系列:" prop="productSeriesId">
<el-col :span="8">
<el-select v-model="ruleForm.productSeriesId" placeholder="请选择产品系列" @change="chooseProductSeries" filterable clearable size="medium">
<el-option v-for="item in productSeries" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="项目起止:" prop="date1">
<el-date-picker v-model="ruleForm.date1" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
<el-form-item label="项目描述:" prop="description">
<el-col :span="8">
<el-input placeholder="请输入项目描述" v-model="ruleForm.description" type="textarea"></el-input>
</el-col>
</el-form-item>
<el-form-item label="操作备注:" v-if="this.$route.params.id != null">
<el-col :span="8">
<el-input placeholder="请输入操作备注" v-model="ruleForm.remark" type="textarea"></el-input>
</el-col>
</el-form-item>
<el-form-item label="已上传附件:" v-if="fileUploaded">
<el-col :span="11">
<template>
<el-table :data="tableData" border>
<el-table-column prop="id" label="文件id" v-if="false"></el-table-column>
<el-table-column prop="name" label="文件名称" min-width="180" show-overflow-tooltip>
<template slot-scope="scope">
<a href="javascript:" @click="downloadFile(scope.row.id)" class="aLink">{{scope.row.name}}</a>
</template>
</el-table-column>
<el-table-column prop="size" label="文件大小" min-width="100" show-overflow-tooltip></el-table-column>
<el-table-column prop="createDate" label="上传时间" min-width="120" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
<el-button type="text" @click="downloadFile(scope.row.id)">下载</el-button>
<el-button type="text" @click="deleteFile(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</template>
</el-col>
</el-form-item>
<el-form-item label="附件上传:">
<el-col :span="8">
<el-upload class="upload-demo" ref="upload" name="files" :data="uploadData" action="/ptms/api/v1/File/upload" multiple
:on-preview="handlePreview" :on-remove="handleRemove" :on-success="handleSuccess" :on-error="handleError" :auto-upload="false">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<span slot="tip" class="el-upload__tip" style="margin-left: 20px; font-weight: bold">单个文件大小不超过{{maxFileSize}}}M</span>
</el-upload>
</el-col>
</el-form-item>
<el-form-item>
<template slot-scope="scope">
<el-button type="primary" @click="submit('ruleForm')" class="btn-min-w">提交</el-button>
<el-button @click="cancel()" class="btn-min-w">返回</el-button>
</template>
</el-form-item>
</el-form>
</div>
</template>
<script>
import tableOperation from '@/components/layout/tableOperation'
import * as api from '@/api/ptms'
import {tips} from '../../static/js/global.js'
import moment from 'moment'
export default {
inject:['reload'],
components:{ tableOperation},
data(){
return{
labelPosition: 'right',
ruleForm: {
name:'',
version:'',
description:'',
productSeriesId: '',
date1: [],
createdBy: sessionStorage.getItem("userId"),
actor: sessionStorage.getItem("username"),
remark: '',
},
productSeries: [],
rules: {
name: [
{ required: true, message: '请输入项目名称', trigger: 'blur' }
],
},
uploadData:{
id: null,
type: 'project'
},
id: null,
tableData: [{}],
fileUploaded: false,
maxFileSize: 40,
}
},
created() {
// 跳转页面获取信息
api.projectForm({id: this.$route.params.id})
.then((res)=>{
if(res.ret > -1){
console.log(res.data)
this.productSeries = res.data.productSeries;
if(this.$route.params.id != null){
this.ruleForm.name = res.data.project.name;
this.ruleForm.version = res.data.project.version;
this.ruleForm.description = res.data.project.description;
this.ruleForm.productSeriesId = res.data.project.productSeriesId;
this.ruleForm.createdBy = res.data.project.createdBy;
if(res.data.project.startTime != null){
this.ruleForm.date1.push(new Date(res.data.project.startTime));
}
if(res.data.project.endTime != null){
this.ruleForm.date1.push(new Date(res.data.project.endTime));
}
this.id = this.$route.params.id;
this.showFileList(this.id);
}
}
})
},
methods:{
chooseProductSeries(val){
this.ruleForm.productSeriesId = val;
},
// 添加、修改项目
submit(formName) {
this.$refs[formName].validate((valid) => {
if(valid){
//文件大小校验
let flag = true;
this.$refs.upload.uploadFiles.map((item) => {
if(item.size / 1024 / 1024 > this.maxFileSize){
tips(this, item.name + '超过允许文件大小' + this.maxFileSize + 'M,请重新选择!', 'warning');
flag = false;
}
});
if(flag){
const id = (typeof (this.$route.params.id) === 'undefined') ? null : this.$route.params.id;
let startTime = null;
let endTime = null;
if(this.ruleForm.date1 != null && this.ruleForm.date1.length > 1){
if(typeof this.ruleForm.date1[0] === 'object'){
startTime = moment(this.ruleForm.date1[0]).format("YYYY-MM-DD");
endTime = moment(this.ruleForm.date1[1]).format("YYYY-MM-DD");
}else{
startTime = this.ruleForm.date1[0];
endTime = this.ruleForm.date1[1];
}
}
api.projectFormAction({id: id, name: this.ruleForm.name, version: this.ruleForm.version, createdBy: this.ruleForm.createdBy,
productSeriesId: this.ruleForm.productSeriesId, description:this.ruleForm.description, startTime: startTime,
endTime:endTime, actor: this.ruleForm.actor, remark: this.ruleForm.remark})
.then((res)=>{
console.log("项目信息", res.data)
if(res.data === "existed"){
tips(this, '该项目名称已存在', 'warning');
return;
}
//上传文件
if(this.$refs.upload.uploadFiles.length > 0){
this.uploadData.id = res.data;
this.submitUpload();
}else {
tips(this, this.id == null ? '添加成功!' :'修改成功!', 'success');
this.$router.push('/projectList');
}
})
}
}
})
},
// 下载文件
downloadFile(val){
window.location.href = "/ptms/api/v1/File/download?id=" + val;
},
// 删除文件
deleteFile(val){
this.$confirm('确认删除该附件?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
api.deleteFile({id: val})
.then((res) => {
if(res.ret === 0){
tips(this, '附件删除成功!', 'success');
this.showFileList(this.id);
// this.reload();
}
})
}).catch(() =>{
// 取消
});
},
// 展示已上传文件列表
showFileList(id){
api.getFilesByTarget({target: id, type: this.uploadData.type})
.then((res) => {
if(res.data.files.length > 0){
this.fileUploaded = true;
res.data.files.forEach((item) => {
item.size = (item.size / 1024 ).toFixed(2) + " KB";
item.createDate = moment(item.createDate).format('YYYY-MM-DD HH:mm:ss');
});
this.tableData = res.data.files;
}else {
this.fileUploaded = false;
}
})
},
handleSuccess(response, file, fileList){
console.log("successFile: ", file);
if(response.ret < 0){
console.log("response: ", response);
this.$refs.upload.clearFiles();
tips(this, '上传失败!', 'error');
}else {
tips(this, this.id == null ? '添加成功!' :'修改成功!', 'success');
this.$router.push('/projectList');
}
},
handleError(err, file, fileList){
console.log("err: ", err);
console.log("errorFile: ", file);
tips(this, '上传失败!', 'error');
},
submitUpload() {
this.$refs.upload.submit();
},
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
// 取消返回上一页
cancel() {
this.$router.back(-1);
}
}
}
</script>
<style lang="scss" scoped>
</style>
3、最终效果如下