HTML部分
<div class="img-file-row">
<div style="flex:1;">
<div><div class="img-handel">
<el-button type="primary" name="onRemove" @click="onRemove()" v-show="isEditing">删除</el-button>
<el-button type="primary" :name="isEditing ? 'finishEdit' : 'Editing'" @click="onEditingToggle()" :disabled="isShowUpload" v-html="isEditing ? '完成编辑' : '编辑'"></el-button>
<el-button type="primary" name="moreUpload" @click="open = true" :disabled="isShowUpload">批量上传</el-button></div>
<el-checkbox-group class="img-wrapper" v-model="imgsChecked" :class="{'edit-state\':isEditing}" v-if="isNoShowTable">
<el-checkbox class="cxl-img-item" :label="file.fileId" v-for="(file,index) in fileList" :key="file.fileId">
<a class="img-name" @click="downloadFile(fileUrl + 'bpm/applymain/files_download' + '?' + 'fileId=' + file.fileId)" download="" target="_blank" :title="file.remarkNode">
{{file.fileName}}
</a>
</el-checkbox>
</el-checkbox-group>
<template v-else>
<el-table
ref="multipleTable"
:data="fileList"
tooltip-effect="dark"
style="width: 100%"
:class="{'cxl-img-table edit-state':isEditing}"
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
align="center"
width="55">
</el-table-column>
<el-table-column label="附件名称" align="center">
<template slot-scope="scope">
<a class="img-name" style="cursor: pointer" @click="downloadFile(fileUrl + 'bpm/applymain/files_download' + '?' + 'fileId=' + scope.row.fileId)" download="" target="_blank" :title="scope.row.remarkNode">
{{ scope.row.fileName}}
</a>
</template>
</el-table-column>
<el-table-column prop="userName" label="上传附件人员" width="120" align="center"></el-table-column>
<el-table-column prop="receTime" label="上传时间" show-overflow-tooltip align="center"></el-table-column>
<el-table-column prop="checkFlag" label="附件状态" show-overflow-tooltip align="center">
<template slot-scope="scope">
<tp-select size="mini" :codeType="uploadParam.AttachmentViewPermissionName" @change="changeAttachmentViewPermission(scope.row)" :disabled="(isShowUploadSelect && uploadParam.userCode != scope.row.createBy) || isShowUpload || uploadParam.isShowUploadAttachmentViewPermission" v-model="scope.row.checkFlag">
</tp-select>
</template>
</el-table-column>
</el-table>
</template>
<el-dialog top="10%" :title="title" custom-class="dialogForm" :visible.sync="open" @close="onCloseSelect">
<div class="select-wrapper">
<el-upload ref="upload" list-type="text" multiple :auto-upload="false">
<el-button slot="trigger" size="small" type="primary">点击选择附件</el-button>
<el-button style="margin-left: 10px;" size="small" type="primary" @click="upload()">上传</el-button>
<el-button style="margin-left: 10px;" size="small" type="primary" @click="reload()" v-show="uploadError.length">重新上传</el-button>
</el-upload>
</div>
</el-dialog>
</div>
<el-dialog top="5%" :title="title" class="dialog-large" custom-class="dialogForm" :visible.sync="bigImage" @close="onBigImage">
<view-img :fileSrc="viewImgSrc" :index="viewIndex" :lastIndex ="fileList.length" @changeIndex="onHandleChangeIndex"></view-img>
</el-dialog>
<div class="toolbar-btn toolbar-pagination" style="padding-bottom:10px;">
<el-pagination @size-change="onHandleSizeChange" @current-change="onHandleCurrentChange" :page-size="paginationOpt.pageSize" :total="paginationOpt.total" :current-page="paginationOpt.currentPage" :page-sizes="[8, 16, 32, 40]" layout="total, sizes, prev, pager, next, jumper">
</el-pagination>
</div>
</div>
</div>
</div>
js部分
data: function () {
return {
bigImage: false,
viewImgSrc: '',
viewIndex: '',
isEditing: false,
title: '上传附件',
open: false,
dialogImageUrl: '',
dialogVisible: false,
imgsChecked: [],
uploadError: [],
menus: [],
d_searchParms: {},
fileList: [],
paginationOpt: {
pageSize: 8,
currentPage: 1,
total: 8
},
fileUrl: ""
}
},
computed: {
isShowUpload: function () {
return this.uploadParam && this.uploadParam.bizNo && this.uploadParam.bizCode && this.uploadParam.docType
},
isShowUploadSelect: function () {
return !this.isShowUpload && !this.uploadParam.isShowUploadAttachmentViewPermission
}
},
props: {
isShowMenu: {
type: Boolean,
default: true
},
pageSize: Number,
currentPage: Number,
menuParentCode: String,
menuSize: {
type: Number,
default: 100
},
docType: String,
bizCode: String,
fileName: String,
bizNo: String,
uploadParam: Object,
isLoadWhenOpening: false,
isSearchByBizNo: false,
fileLoadUrl: {
type: String,
default: "http://127.0.0.1:8805/"
},
isNoShowTable: {
type: Boolean,
default: true
},
},
created: function () {
this.initProp()
},
methods: {
initProp: function () {
this.fileUrl = this.fileLoadUrl;
if (this.pageSize) {
this.paginationOpt = this.pageSize
}
if (this.currentPage) {
this.currentPage = this.currentPage
}
if (!this.isShowMenu) {
var parms = {}
if (this.uploadParam.docType) {
parms['docType'] = this.uploadParam.docType
}
if (this.uploadParam.bizCode) {
parms['bizCode'] = this.uploadParam.bizCode
}
if (this.uploadParam.fileName) {
parms['fileName'] = this.uploadParam.fileName
}
if (this.uploadParam.bizNo) {
parms['bizNo'] = this.uploadParam.bizNo
}
if (this.uploadParam.applyId) {
parms['applyId'] = this.uploadParam.applyId
}
if (this.uploadParam.remarkNode) {
parms['remarkNode'] = this.uploadParam.remarkNode
}
this.d_searchParms = parms
} else {
// this.initMenulist()
}
this.onGetImgList()
},
initMenulist: function () {
var _this = this,
url, parms = {
size: this.menuSize,
parentCode: ''
}
if (this.menuParentCode) {
parms.parentCode = this.menuParentCode
}
url = Vue.tpUtil.getUrl({
apiName: 'uploadGetFileMenus',
contextName: 'fs',
serachParms: parms
})
Vue.tpUtil.http.get(url).then(function (res) {
if (res.resCode === '0000') {
_this.menus = res.resData.content
}
});
},
onGetImgList: function () {
var url, _this = this,
apiName = 'uploadGetFileList'
_parms = {
page: this.paginationOpt.currentPage - 1,
size: this.paginationOpt.pageSize
}, data = Object.assign({}, this.uploadParam);
// _parms = Object.assign(_parms, this.d_searchParms)
if (this.uploadParam.bizNo) {
_parms['bizNo'] = this.uploadParam.bizNo;
}
if (this.uploadParam.AttachmentViewPermission === 'A') {
apiName = 'uploadFindFilesList'
}
url = Vue.tpUtil.getUrl({
apiName: apiName,
contextName: 'bpm',
serachParms: _parms
})
Vue.tpUtil.http.post(url, data).then(function (res) {
if (res.resCode === '0000') {
if (res.resData) {
_this.paginationOpt.total = res.resData.totalElements;
_this.fileList = _this.onImgListHandle(res.resData.content);
} else {
_this.paginationOpt = {
pageSize: 0,
currentPage: 0,
total: 0
}
}
}
});
},
onImgListHandle: function (list) {
list.forEach(function (elem) {
if (!elem.thumbnailUrl) {
elem.thumbnailUrl = 'static/img/notImage.jpg'
}
})
return list
},
upload: function () {
// 手动上传
var uploadFiles = this.$refs.upload.uploadFiles,
len = uploadFiles.length,
flag = 0;
if (len > 0) {
this.ajaxUpload(uploadFiles, 0);
/* for (var i = 0; i < len; i++) {
if (i === len - 1) {
flag = 1;
}
uploadFiles[i].data = this.addFileName(uploadFiles[i].name);
this.ajaxUpload(uploadFiles[i], flag);
}*/
} else {
Vue.tpUtil.alert({
msg: '请传入要上传的文件'
})
}
},
addFileName: function (name) {
var obj = this.uploadParam
obj.fileName = name
return obj
},
ajaxUpload: function (files, len) {
var _this = this,
fileUrl = this.fileUrl;
if (typeof XMLHttpRequest === 'undefined') {
return;
}
//自执行strat
var file = files[len],
uploadFiles = _this.$refs.upload.uploadFiles;
uploadFiles[len].data = _this.addFileName(uploadFiles[len].name);
//自执行end
// 文件大小判断strat
var isLt = file.size / 1024 / 1024 < parseInt(this.uploadParam.size);
if (!isLt) {
this.$message.error('单个文件大小不能超过' + this.uploadParam.size + 'M');
return;
}
//end
var xhr = new XMLHttpRequest(),
action = Vue.tpUtil.getUrl({
apiName: 'uploadAddFile',
contextName: 'bpm'
}),
formData = new FormData();
// 遍历传参对象
if (file.data) {
Object.keys(file.data).forEach(function (key) {
formData.append(key, file.data[key]);
});
}
formData.append('file', file.raw);
if (xhr.upload) {
xhr.upload.onprogress = function progress(e) {
if (e.total > 0) {
e.percent = e.loaded / e.total * 100;
}
_this.$refs.upload.handleProgress(e, file.raw);
};
}
xhr.onerror = function error(e) {
console.log(e)
// option.onError(e);
};
xhr.onload = function onload() {
var res = _this.getBody(xhr)
if (xhr.status !== 200) {
_this.uploadError.push(file)
// return _this.$refs.upload.handleError(_this.getError(action, file, xhr),file.raw);
}
if (res.resCode === '0000') {
_this.$refs.upload.handleSuccess(res, file.raw);
// _this.onUploadDone('上传完成,且全部成功,点击确定关闭');
} else {
_this.onUploadDone(res.resMsg);
}
//自执行
len++;
if (files.length > len) {
_this.ajaxUpload(files, len)
} else {
_this.paginationOpt.currentPage = 1;
_this.onGetImgList();
}
/*if (flag) {
_this.paginationOpt.currentPage = 1;
_this.onGetImgList();
}*/
return false
};
xhr.open('post', fileUrl + action, true);
xhr.send(formData);
},
getBody: function (xhr) {
var text = xhr.responseText || xhr.response;
if (!text) {
return text;
}
try {
return JSON.parse(text);
} catch (e) {
return text;
}
},
getError: function (action, option, xhr) {
var msg;
if (xhr.response) {
msg = xhr.status + xhr.response.error || xhr.response;
} else if (xhr.responseText) {
msg = xhr.status + xhr.responseText;
} else {
msg = 'fail to post' + action + xhr.status;
}
var err = new Error(msg);
err.status = xhr.status;
err.method = 'post';
err.url = action;
return err;
},
onSearchBizNo: function () {
this.d_bizCode = '';
if (this.d_bizNo) {
this.d_searchParms = {}
this.d_searchParms.bizNo = this.d_bizNo
this.onGetImgList()
}
},
onHandleselect: function (code) {
this.d_bizNo = '';
this.d_bizCode = code;
this.d_searchParms = {}
this.paginationOpt.currentPage = 1;
this.d_searchParms.bizCode = code
this.onGetImgList()
},
onHandleSizeChange: function (size) {
this.paginationOpt.size = size;
this.onGetImgList()
},
onHandleCurrentChange: function (currentPage) {
this.paginationOpt.currentPage = currentPage;
this.onGetImgList()
},
onViewImg: function (index) {
var url = this.fileList[index].downloadUrl;
this.viewIndex = index;
this.bigImage = true;
if (/\.png|jpg|jpeg|pdf$/g.test(url)) {
this.viewImgSrc = url;
} else {
this.viewImgSrc = 'static/img/doc.jpg';
}
},
onBigImage: function () {
this.onbigImage = true
},
onHandleChangeIndex: function (changeIndex) {
var url = this.fileList[changeIndex].downloadUrl;
this.viewIndex = changeIndex;
// this.viewImgSrc = url;
if (/\.png|jpg|jpeg|pdf$/g.test(url)) {
this.viewImgSrc = url;
} else {
this.viewImgSrc = 'static/img/doc.jpg';
}
},
onCloseSelect: function () {
this.open = false;
this.uploadError = [];
this.$refs.upload.clearFiles();
this.onGetImgList();
},
cancel: function () {
// 取消上传待完善
this.$refs.upload.abort();
},
onUploadDone: function (mag) {
this.$alert(mag)
},
reload: function () {
var _this = this,
flag = 0,
errorList = this.uploadError,
len = errorList.length;
this.uploadError = [];
_this.ajaxUpload(errorList, 0);
/*errorList.forEach(function (elem, index) {
if (index === len - 1) {
flag = 1
}
_this.ajaxUpload(elem, flag);
})*/
},
onDownloadFile: function (url) {
window.open(url, '下载');
},
//多文件下载
downloadFile: function (url) {
if (window.navigator.msSaveBlob) {
// console.log('IE')
window.open(url, '');
// window.location = url;
} else {
// 谷歌浏览器 创建a标签 添加download属性下载
let downloadElement = document.createElement('a');
downloadElement.href = url;
downloadElement.target = '_blank';
downloadElement.download = 'model.json'; // 下载后文件名
document.body.appendChild(downloadElement);
downloadElement.click(); // 点击下载
document.body.removeChild(downloadElement); // 下载完成移除元素
window.URL.revokeObjectURL(url); // 释放掉blob对象
}
// var iframe = document.createElement("iframe");
// iframe.style.display = "none"; // 防止影响页面
// iframe.style.height = 0; // 防止影响页面
// iframe.src = url;
// document.body.appendChild(iframe); // 这一行必须,iframe挂在到dom树上才会发请求
// // 5分钟之后删除(onload方法对于下载链接不起作用,就先抠脚一下吧)
// setTimeout(function () {
// iframe.remove();
// }, 5 * 60 * 1000);
},
onEditingToggle: function () {
// 已编辑状态
this.isEditing = !this.isEditing
this.imgsChecked = []
},
onRemove: function () {
var _this = this,
idArray = [],
url;
// 删除已有照片
if (this.imgsChecked.length > 0) {
url = Vue.tpUtil.getUrl({
apiName: 'uploadRemoveFile',
contextName: 'bpm',
})
Vue.tpUtil.confirm({
msg: '确认删除吗,确定后不可撤销'
}).then(function () {
for (var k in _this.imgsChecked) {
_this.fileList = _this.fileList.filter(function (elem) {
return elem.fileId !== _this.imgsChecked[k]
})
if (_this.isNoShowTable) {
idArray.push(_this.imgsChecked[k])
} else {
idArray.push(_this.imgsChecked[k].fileId)
}
}
_this.imgsChecked = []
Vue.tpUtil.http.post(url, {
fileId: idArray
}).then(function (res) {
if (res.resCode === '0000') {
_this.$emit('removeFile', idArray)
_this.onGetImgList()
}
});
});
} else {
this.$alert('请先选择文件')
}
},
onAdd: function () {
// <a class="img-name" :href=" fileUrl + 'bpm/applymain/files_download' + '?' + 'fileId=' + file.fileId" download="" target="_blank">
var _this = this,
idArray = [],
url, imgsChecked = this.imgsChecked || [];
// 下载已有照片
if (imgsChecked.length > 0) {
Vue.tpUtil.confirm({
msg: '确认下载吗?'
}).then(function () {
for (var k in imgsChecked) {
url = _this.fileUrl + 'bpm/applymain/files_download' + '?' + 'fileId=' + imgsChecked[k].fileId;
_this.downloadFile(url)
}
});
} else {
this.$alert('请先选择文件')
}
},
//时间格式化
formatDate: function (row, column) {
return Vue.filter('time')(row[column.property], 'yyyy-MM-dd HH:mm');
},
handleSelectionChange: function (val) {
this.imgsChecked = val;
},
changeAttachmentViewPermission: function (val) {
var url = Vue.tpUtil.getUrl({
apiName: 'uploadEditFilePermission',
contextName: 'bpm'
}),
_this = this;
if (val && val.fileId) {
Vue.tpUtil.http.post(url, val).then(function (res) {
if (res.resCode === '0000') {
_this.onGetImgList();
}
});
}
}
},
//引入图片预览组件,参考另一篇博文
components: {
ViewImg: ViewImg
}