<template>
<div class="el-upload-wrapper" :id="id">
<el-scrollbar style="height: 100%">
<template v-if="!isView">
<el-upload
drag
action="#"
:http-request="requestFile"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:on-error="handleError"
:file-list="fileListData"
:disabled="disabled"
list-type="picture-card"
ref="upload"
>
<template>
<img
class="upload-icon"
src="@/assets/images/fileicon/download.png"
/>
{{ uploadName }}上传
</template>
<div slot="file" slot-scope="{ file }" class="file-item-wrapper 111">
<div class="file-item">
<div class="flex">
<img class="mr-10" src="@/assets/images/fileicon/file.png" />
<span class="Fname">{{ file.name }}</span>
</div>
<div class="flex">
<span class="mr-30"
>{{ (file.size / 1024 / 1024).toFixed(2) }}Mb</span
>
<el-image
class="upload-icon"
v-if="isImg(file)"
:src="imgs"
:preview-src-list="[getPreviewImg(file)]"
>
</el-image>
<img
class="upload-icon"
@click="handleDownload(file)"
src="@/assets/images/fileicon/xz.png"
/>
<img
class="upload-icon"
@click="handleRemove(file)"
src="@/assets/images/fileicon/del1.png"
/>
</div>
</div>
<el-progress
v-if="file.percentage"
:percentage="Number(file.percentage.toFixed(2))"
:status="file.percentage == 100 ? 'success' : ''"
></el-progress>
</div>
</el-upload>
</template>
<template v-else>
<div
class="file-item"
:key="index"
v-for="(file, index) in fileListData"
>
<div class="flex">
<img class="mr-10" src="@/assets/images/fileicon/file.png" />
<span class="Fname">{{ file.name }}</span>
</div>
<div class="flex">
<span class="mr-30"
>{{ (file.size / 1024 / 1024).toFixed(2) }}Mb</span
>
<el-image
class="upload-icon"
v-if="isImg(file)"
:src="imgs"
:preview-src-list="[getPreviewImg(file)]"
>
</el-image>
<img
class="upload-icon"
@click="handleDownload(file)"
src="@/assets/images/fileicon/xz.png"
/>
</div>
</div>
</template>
</el-scrollbar>
</div>
</template>
<script>
import { Upload, downloadFile } from "@/api/index.js";
import { newGuid } from "@/utils";
import imgs from "@/assets/images/fileicon/ck.png";
export default {
props: {
keyValue: {
//主键
type: String,
default: "",
},
isView: {
type: Boolean,
default: false, //设备
},
uploadName: {
type: String,
default: "附件",
},
disabled: {
//禁用
type: Boolean,
default: false, //设备
},
multiple: {
type: Boolean,
default: false, //批量
},
filterData: {
type: Array,
default: () => [],
},
fileList: {
//文件列表
type: Array,
default: () => [],
},
fileType: {
//上传文件类型
type: Array,
default: () => ["*"], //gif,jpeg,jpg,png,psd,bmp,rar,zip,pdf,doc,docx,ppt,pptx,txt,xls,xlsx,mp4,wmv
},
thumbnailPathAttr: {
//封面路径字段
type: String,
default: "ThumbFilePath",
},
filePath: {
type: String,
default: "FilePath",
},
category: {
type: String,
default: "planlibrary",
},
memo: {
type: String,
default: "",
},
},
data() {
return {
id: "upload_" + newGuid(),
imgSrcList: [],
imgs,
srcList: [], // 图片预览
dialogImageUrl: "",
dialogTitle: "",
dialogVisible: false,
progressFlag: false, //进度条
statusValue: "",
filterValue: "",
filterStatusData: [],
previewFileData: {},
fileListHeight: "100px",
fileListData: [],
};
},
computed: {
baseUrl() {
return "";
},
},
watch: {
fileList: {
handler(val) {
this.handleRefresh();
},
deep: true,
immmediate: true,
},
},
mounted() {
this.fileListHeight = $("#" + this.id).height() - 200 + "px";
this.handleRefresh();
},
methods: {
handleRefresh() {
this.$nextTick(() => {
this.fileListData = this.fileList.map((item) => {
return {
name: item.FileName,
size: item.FileSize,
url: this.baseUrl + item.FilePath,
imgurl: this.baseUrl + item.ThumbFilePath,
response: {
Data: {
FilePath: item.FilePath,
ThumbFilePath: item.ThumbFilePath || item.FilePathThumb,
},
},
};
});
//图片预览
setTimeout(() => {
this.$previewRefresh();
}, 200);
});
},
Preview() {},
downloadFileData() {},
requestFile(param) {
//覆盖默认上传方式 自定义上传
// 获取上传的文件名
var file = param.file;
//发送请求的参数格式为FormData
const formData = new FormData();
formData.append("formFile", file);
formData.append("folder", this.category);
Upload(
{
folder: this.category,
},
formData
)
.then((res) => {
param.onSuccess(res);
})
.catch((err) => {
param.onError(err);
});
},
beforeAvatarUpload(file) {
if (this.disabled) {
return;
}
let isFlag = true,
type = file.name.substring(file.name.lastIndexOf(".") + 1);
let findIndex = this.fileType.findIndex((node) => node == type);
let notAllow = ["exe", "EXE", "dll"];
if (
(findIndex == -1 && this.fileType.indexOf("*") == -1) ||
notAllow.indexOf("*") > -1
) {
isFlag = false;
this.$nextTick(() => {
this.$message({
type: "warning",
message: "此类型文件不允许上传!",
});
});
}
return isFlag;
},
// handleAvatarProgress(event, file, fileList) {
// //文件上传时
// this.uploadPercent = Number(file.percentage.toFixed(2));
// },
handleAvatarSuccess(res, file) {
//回调
this.$emit("success", res.Data, file);
//图片预览
setTimeout(() => {
this.$previewRefresh();
}, 200);
},
handleRemove(file) {
// 实现缩略图模板时删除文件
let fileList = this.$refs.upload.uploadFiles;
let index = fileList.findIndex((fileItem) => {
return fileItem.uid === file.uid;
});
fileList.splice(index, 1);
this.$emit("success", fileList);
},
handleOpenView(event, file) {
let imgDom = $(event.target)
.parents(".file-item-wrapper")
.find(".el-image img");
imgDom.trigger("click");
},
handlePictureCardPreview(file) {
let response = file.response;
if (response) {
this.previewFileData = response.data[0];
} else {
this.previewFileData = file;
}
this.$nextTick(() => {
this.$refs.fileview.open();
});
},
handleDownload(file) {
downloadFile({ fileName: file.response.Data.FilePath }).then((res) => {
if (!res) {
return;
}
//将blob对象转换为域名结合式的url
let blobUrl = window.URL.createObjectURL(res.data);
let link = document.createElement("a");
document.body.appendChild(link);
link.style.display = "none";
link.href = blobUrl;
// 设置a标签的下载属性,设置文件名及格式,后缀名最好让后端在数据格式中返回
link.download = file.name;
// 自触发click事件
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(blobUrl);
});
},
handleError(err, file, fileList) {
this.$message({
type: "warning",
message: "此类型文件不允许上传!",
});
},
isImg(file) {
if (!file.name) {
return -1;
}
let type = file.name.split(".")[1].toLowerCase();
//判断是否是图片
return (
["gif", "jpeg", "jpg", "png", "bmp"].findIndex((node) => node == type) >
-1
);
},
isVideo(file) {
if (!file.name) {
return -1;
}
let type = file.name.split(".")[1].toLowerCase();
//判断是否是图片
return (
["wmv", "avi", "dat", "asf", "mpeg", "mpg", "mp4"].findIndex(
(node) => node == type
) > -1
);
},
isMp3(file) {
if (!file.name) {
return -1;
}
let type = file.name.split(".")[1].toLowerCase();
//判断是否是图片
return ["mp3"].findIndex((node) => node == type) > -1;
},
isPdf(file) {
if (!file.name) {
return -1;
}
let type = file.name.split(".")[1].toLowerCase();
//判断是否是图片
return ["pdf"].findIndex((node) => node == type) > -1;
},
getPreviewImg(file) {
//文件封面
if (this.isImg(file)) {
// console.log(file);
if (file.response) {
let response = file.response;
if (response.Data) {
// let path = response.Data[this.thumbnailPathAttr];
let path = response.Data[this.filePath];
// console.log(`api/api/File/DownloadByPath?fileName=${path}`)
// return "/api" + path;
return `api/api/File/DownloadByPath?fileName=${path}`;
}
}
} else {
let type = file.name.split(".")[1].toLowerCase();
try {
return require(`@/assets/images/filetype/${type}.png`);
} catch (e) {
return require(`@/assets/images/filetype/file.png`);
}
}
return "";
},
getFileList() {
let list = [];
this.$refs.upload.uploadFiles.forEach((item) => {
let response = item.response;
if (!!response) {
const { Data } = response;
let path = Data.FilePath;
list.push({
FolderId: this.keyValue,
FileName: item.name,
Memo: this.memo,
Category: this.category,
FilePath: path,
FileSize: item.size,
FileExtensions: "." + Data.FilePath.split(".")[1],
FileType: Data.FilePath.split(".")[1],
FilePathThumb: Data.ThumbFilePath,
});
}
});
return list;
},
clearFiles() {
this.$refs.upload.clearFiles();
},
},
};
</script>
<style lang="scss" scoped>
.el-upload-wrapper {
.upload-icon {
margin-right: 5px;
}
::v-deep.el-upload--picture-card,
::v-deep.el-upload-list__item {
height: 135px;
width: 135px;
}
::v-deep.el-upload {
.el-upload-dragger {
width: 100%;
height: 100%;
border: none;
background-color: transparent;
.el-icon-plus {
font-size: 30px;
margin: 13px 0 16px;
}
}
.el-upload-list {
display: none;
}
}
::v-deep .el-scrollbar__view {
height: 100%;
> div {
height: 100%;
}
}
::v-deep .el-upload--picture-card {
width: 100%;
height: 100%;
line-height: normal;
border: none;
}
::v-deep .el-upload-dragger {
width: 100%;
height: 46px;
border-radius: 4px;
background: #0873ee0d;
border: none;
display: flex;
align-items: center;
justify-content: center;
}
.file-item-wrapper {
height: 100%;
}
::v-deep .el-upload-list--picture-card .el-upload-list__item {
height: 46px;
width: 100%;
margin-right: 0;
border: none;
border-radius: 4px;
}
.file-item {
display: flex;
align-items: center;
justify-content: space-between;
line-height: 46px;
background: #0873ee0d;
padding: 0 20px;
margin-bottom: 10px;
color: #666666ff;
.flex {
display: flex;
align-items: center;
}
::v-deep .el-image {
display: flex;
align-items: center;
}
.upload-icon {
cursor: pointer;
margin-right: 10px;
&:hover {
opacity: 0.7;
}
}
.Fname {
color: #00000099;
}
.mr-10 {
margin-right: 10px;
}
.mr-20 {
margin-right: 20px;
}
.mr-30 {
margin-right: 30px;
}
}
}
</style>
-----------------------------------------------------------------------------------------------
2:引入组件
import UploadBox from "@/components/Upload";
3:使用组件
<el-form-item label="" prop="FileList">
<upload-box
:disabled="disabled"
:isView="type === 'view'"
ref="uploadbox"
@success="handleChangeFile"
:category="'AppointmentRecord'"
:fileList="formData.FileList"
></upload-box>
</el-form-item>
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/9d5d7ce86e284edca2cb98a85cb1fba3.png#pic_center)
基于element upload封装上传组件
于 2023-12-15 15:25:26 首次发布