<template> <div class="upload-file"> <el-upload multiple :action="uploadFileUrl" :before-upload="handleBeforeUpload" :file-list="fileList" :limit="limit" :on-error="handleUploadError" :on-exceed="handleExceed" :on-success="handleUploadSuccess" :show-file-list="false" :headers="headers" :class=" disabled ? 'upload-file-uploader upload-file-uploaderdl' : 'upload-file-uploader' " ref="fileUpload" :disabled="disabled" > <!-- 上传按钮 --> <el-button size="mini" type="primary" v-if="!disabled" >选取文件</el-button > <!-- 上传提示 --> <div class="el-upload__tip" slot="tip" v-if="showTip"> 请上传 <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template> <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template> 的文件 </div> </el-upload> <!-- 文件列表 --> <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul" > <li :key="file.url" :class=" disabled ? 'el-upload-list__item el-upload-list__itemdis ele-upload-list__item-content' : 'el-upload-list__item ele-upload-list__item-content' " v-for="(file, index) in fileList" > <el-link :href="`${file.url}`" :underline="false" target="_blank"> <span class="el-icon-document"> {{ getFileName(file.name) }} </span> </el-link> <div class="ele-upload-list__item-content-action" v-if="!disabled"> <el-link :underline="false" @click="handleDelete(index)" type="danger" >删除</el-link > </div> </li> </transition-group> </div> </template> <script> import { getToken } from "@/utils/auth"; import { listByIds, delOss } from "@/api/system/oss"; export default { name: "FileUpload", props: { // 值 value: [String, Object, Array], // 数量限制 limit: { type: Number, default: 5, }, // 大小限制(MB) fileSize: { type: Number, default: 5, }, // 文件类型, 例如['png', 'jpg', 'jpeg'] fileType: { type: Array, default: () => ["doc", "xls", "ppt", "txt", "pdf"], }, // 是否显示提示 isShowTip: { type: Boolean, default: true, }, disabled: { type: Boolean, default: false, }, }, data() { return { number: 0, uploadList: [], baseUrl: process.env.VUE_APP_BASE_API, uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传文件服务器地址 headers: { Authorization: "Bearer " + getToken(), }, fileList: [], }; }, watch: { value: { async handler(val) { if (val) { let temp = 1; // 首先将值转为数组 let list; if (Array.isArray(val)) { list = val; } else { await listByIds(val).then((res) => { list = res.data.map((oss) => { oss = { name: oss.originalName, url: oss.url, ossId: oss.ossId, }; return oss; }); }); } // 然后将数组转为对象数组 this.fileList = list.map((item) => { item = { name: item.name, url: item.url, ossId: item.ossId }; item.uid = item.uid || new Date().getTime() + temp++; return item; }); } else { this.fileList = []; return []; } }, deep: true, immediate: true, }, }, computed: { // 是否显示提示 showTip() { return this.isShowTip && (this.fileType || this.fileSize); }, }, methods: { // 上传前校检格式和大小 handleBeforeUpload(file) { // 校检文件类型 if (this.fileType) { const fileName = file.name.split("."); const fileExt = fileName[fileName.length - 1]; const isTypeOk = this.fileType.indexOf(fileExt) >= 0; if (!isTypeOk) { this.$modal.msgError( `文件格式不正确, 请上传${this.fileType.join("/")}格式文件!` ); return false; } } // 校检文件大小 if (this.fileSize) { const isLt = file.size / 1024 / 1024 < this.fileSize; if (!isLt) { this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`); return false; } } this.$modal.loading("正在上传文件,请稍候..."); this.number++; return true; }, // 文件个数超出 handleExceed() { this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`); }, // 上传失败 handleUploadError(err) { this.$modal.msgError("上传文件失败,请重试"); this.$modal.closeLoading(); }, // 上传成功回调 handleUploadSuccess(res, file) { if (res.code === 200) { this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId, }); this.uploadedSuccessfully(); } else { this.number--; this.$modal.closeLoading(); this.$modal.msgError(res.msg); this.$refs.fileUpload.handleRemove(file); this.uploadedSuccessfully(); } }, // 删除文件 handleDelete(index) { let ossId = this.fileList[index].ossId; delOss(ossId); this.fileList.splice(index, 1); this.$emit("input", this.listToString(this.fileList)); }, // 上传结束处理 uploadedSuccessfully() { if (this.number > 0 && this.uploadList.length === this.number) { this.fileList = this.fileList.concat(this.uploadList); this.uploadList = []; this.number = 0; this.$emit("input", this.listToString(this.fileList)); this.$modal.closeLoading(); } }, // 获取文件名称 getFileName(name) { // 如果是url那么取最后的名字 如果不是直接返回 if (name.lastIndexOf("/") > -1) { return name.slice(name.lastIndexOf("/") + 1); } else { return name; } }, // 对象转成指定字符串分隔 listToString(list, separator) { let strs = ""; separator = separator || ","; for (let i in list) { strs += list[i].ossId + separator; } return strs != "" ? strs.substr(0, strs.length - 1) : ""; }, }, }; </script> <style scoped lang="scss"> .upload-file-uploader { margin-bottom: 5px; } .upload-file-uploaderdl { display: none; } .upload-file-list .el-upload-list__item { border: 1px solid #e4e7ed; line-height: 2; margin-bottom: 10px; position: relative; } .upload-file-list .el-upload-list__itemdis { border: none; } .upload-file-list .ele-upload-list__item-content { display: flex; justify-content: space-between; align-items: center; color: inherit; } .ele-upload-list__item-content-action .el-link { margin-right: 10px; } </style>