需求:用vue框架,结合element-ui进行本地文件得上传,同时对文件需要MD5
界面如下:
标题
同时如果截止时间到了后,需要置灰对应的按钮:发布按钮、导入按钮、删除按钮
html:
就是element-ui得上传组件
auto-upload:true自动上传
beforeUpload:上传之前把对应的文件得信息以及参数拼接好
disabled:截至时间后置灰导入按钮
其他参数没怎么用
<el-upload
class="upload-file"
action="/ignore/"
:before-upload="beforeUpload"
ref="newupload"
multiple
:auto-upload="true"
:disabled="isGrey"
>
<el-button type="text" plain :disabled="isGrey">导入</el-button>
</el-upload>
js:因为要用md5以及一些分块,所以安装了browser-md5-file
import BMF from 'browser-md5-file';//先安装,再引用
const bmf = new BMF();
methods:{
/* 上传文件之前得处理 */
beforeUpload(file){
console.log('当前的文件信息',file)
this.timestamp = new Date().getTime();//当前时间时间戳
//策略文件类型
const rzrk = ['rzrk'];
const notebook = ['ipynb'];
const Image = ['image/png'];
const start = file&&file.name.lastIndexOf('.');
const fileType = file.name.substr(start+1).toLowerCase();
const isExistRzrk = rzrk.includes(fileType)
const isImage = Image.includes(file.type)
const index = 0;
//上传的地址,和后台协商
let url = '/upload_attachment/'
bmf.md5(file,(err,md5)=>{
//上传需要用到的一些参数,和后台协商
this.uploadInfo = {
chunks:Math.ceil(file.size/this.pack_size),//分块
md5: md5,
index:index,
file:file.slice(index*this.pack_size,(index+1)*this.pack_size),
fileName:file.name,
per_size:this.pack_size,
content_type: file.type,
time_stamp: this.timestamp,
string_stamp: this.timestamp,
is_image_type:isImage ?1:0,
normal_file:isExistRzrk?1:0
}
if (isExistRzrk) {
this.commonFile(url,file,'rzrk')
}
else if(notebook.includes(fileType)){
this.commonFile(url,file,'notebook')
}
else {
this.commonFile(url,file,'local')
}
})
},
/* 参数append进formdata里
* state:区别是本地还是策略还是notebook文件
*/
commonFile(url,file,state){
let formdata = new FormData();
const keys = Object.keys(this.uploadInfo)
if (keys) {//上传用得是formdata,把参数放进去
keys.forEach(item=>{
return formdata.append(item,this.uploadInfo[item])
})
}
this.uploadAttachment(formdata,url,file,state)
},
/**
上传附件
* state:区别是本地还是策略还是notebook文件
* file:文件流信息
* **/
uploadAttachment(formdata,url,file,state){
let config = {
headers:{'Content-Type':"multipart/form-data"}
}
axios.post(url,formdata,config).then(({data})=>{
if(data.success == 1){
let json ={
content_type: file.type,
file_id: data.file_id,
file_name: file.name
}
!this.newFileList.includes(json)&&this.newFileList.push(json);//所有上传的文件数组
//分文件类型保存
if (state=='local') {
!this.local_file_ids.includes(data.file_id)&&this.local_file_ids.push(data.file_id);
}
else if (state=='notebook'){
!this.notebook_file_ids.includes(data.file_id)&&this.notebook_file_ids.push(data.file_id);
}
else if (state=='rzrk') {
!this.strategy_file_ids.includes(data.file_id)&&this.strategy_file_ids.push(data.file_id);
}
this.$message('发布成功');
}else{
this.$message(data.error);
}
})
},
}
自此,文件上传结束,文件得预览、下载要和后台协商,文件删除也要请求告诉后台
补充:下面是上传成功后再次从后台请求回文件名,进行表格展示,同时可以预览、下载、删除(其他功能都可以添加)
ps:element-ui也有文件的删除,也可以自己在上传组件基础上添加这些功能,这里需要把自动上传改为手动上传
html:附件部分用的table,所以可以拿到每行得index以及数据
<el-table ref="multipleTable" :data="fileList" tooltip-effect="dark" style="width: 100%" v-if="fileList.length!=0">
<!-- <el-table-column type="selection" ></el-table-column>-->
<el-table-column prop="file_name" > </el-table-column>
<el-table-column >
<template slot-scope="scope">
<el-button @click="previewFile(scope.row,0,scope.$index)" type="text" size="small">查看</el-button>
<a class="download_file" @click="downloadFile(scope.row,1,scope.$index)" >下载</a>
<el-button @click="deleteFile(scope.row,scope.$index)" type="text" size="small" :disabled="isGrey">删除</el-button>
</template>
</el-table-column>
</el-table>
文件删除功能:我这里和后台商量的是,文件上传成功后,后台会返回一个文件的id给前端,然后前端保存下来,前端要展示文件的时候,就把这些id传给后台,后台把文件名等信息传给前端进行展示(其他思路可以商量)
/**
* 作业提交部分的文件删除
*
* **/
deleteFile(row,index){
let json = {
file_ids:JSON.stringify([row.file_id])
}
APIService.deleteAttachment(json).then(res=>{
if (res.success==1){
this.warnTip('删除成功','success')
//筛选新得附件列表,被删除得附件不再显示,当然也可以重新获取附件列表
this.newFileList = this.newFileList.filter(item=>{
return item!=row
})
}
else{
this.warnTip(res.error,'warning')
}
})
.catch(error=>{
//this.warnTip(error,'warning')
console.log('error请求失败',error)
})
},
文件下载和查看功能:这里合后台商量的思路是:前端把当前要预览或者下载的文件的id传给后台,因为共用的一个网址,所以区分预览和下载又加了一个参数判断,(这里的下载是一个a标签,然后给a标签href属性动态赋值,预览就是打开另一个窗口)
/** 下载本地文件 和notebook
* row: 某行文件数据
* state:下载为1,预览为0
* index: 索引
* **/
downloadFile(row,state,index){
this.isPreviewOrDownload(row,state,index)
},
/** 预览某个文件
* row: 某行文件数据
* state:预览为0,下载为1
* index: 索引
* */
previewFile(row,state,index) {
this.isPreviewOrDownload(row,state,index)
},
/**
* 文件预览和下载的逻辑
* **/
isPreviewOrDownload(row,state,index){
//需要什么参数和后台商量
const src = `/download_attachment/?file_id=${row.file_id}&download=${state}`;
if (state==1) {//下载
document.getElementsByClassName('download_file')[index].setAttribute('href',src)
}
else{
const origin = window.location.origin;
window.open(origin + src);
}
},
以上是文件得上传,单个文件得预览、下载和删除功能,欢迎交流