admin
2024-11-23 8494738306fa1796d1f3680511ce9a5ad67436ac
提交 | 用户 | 时间
a6316e 1 <template>
A 2   <div class="upload-file">
3     <el-upload
4       multiple
5       :action="uploadFileUrl"
6       :before-upload="handleBeforeUpload"
7       :file-list="fileList"
8       :limit="limit"
9       :on-error="handleUploadError"
10       :on-exceed="handleExceed"
11       :on-success="handleUploadSuccess"
12       :show-file-list="false"
13       :headers="headers"
14       class="upload-file-uploader"
15       ref="fileUpload"
16     >
17       <!-- 上传按钮 -->
18       <el-button size="mini" type="primary">选取文件</el-button>
19       <!-- 上传提示 -->
20       <div class="el-upload__tip" slot="tip" v-if="showTip">
21         请上传
22         <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
23         <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
24         的文件
25       </div>
26     </el-upload>
27
28     <!-- 文件列表 -->
29     <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
30       <li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
31         <el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank">
32           <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
33         </el-link>
34         <div class="ele-upload-list__item-content-action">
35           <el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
36         </div>
37       </li>
38     </transition-group>
39   </div>
40 </template>
41
42 <script>
43 import { getToken } from "@/utils/auth";
44
45 export default {
46   name: "FileUpload",
47   props: {
48     // 值
49     value: [String, Object, Array],
50     // 数量限制
51     limit: {
52       type: Number,
53       default: 5,
54     },
55     // 大小限制(MB)
56     fileSize: {
57       type: Number,
58       default: 5,
59     },
60     // 文件类型, 例如['png', 'jpg', 'jpeg']
61     fileType: {
62       type: Array,
63       default: () => ["doc", "xls", "ppt", "txt", "pdf"],
64     },
65     // 是否显示提示
66     isShowTip: {
67       type: Boolean,
68       default: true
69     }
70   },
71   data() {
72     return {
73       number: 0,
74       uploadList: [],
75       baseUrl: process.env.VUE_APP_BASE_API,
76       uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传文件服务器地址
77       headers: {
78         Authorization: "Bearer " + getToken(),
79       },
80       fileList: [],
81     };
82   },
83   watch: {
84     value: {
85       handler(val) {
86         if (val) {
87           let temp = 1;
88           // 首先将值转为数组
89           const list = Array.isArray(val) ? val : this.value.split(',');
90           // 然后将数组转为对象数组
91           this.fileList = list.map(item => {
92             if (typeof item === "string") {
93               item = { name: item, url: item };
94             }
95             item.uid = item.uid || new Date().getTime() + temp++;
96             return item;
97           });
98         } else {
99           this.fileList = [];
100           return [];
101         }
102       },
103       deep: true,
104       immediate: true
105     }
106   },
107   computed: {
108     // 是否显示提示
109     showTip() {
110       return this.isShowTip && (this.fileType || this.fileSize);
111     },
112   },
113   methods: {
114     // 上传前校检格式和大小
115     handleBeforeUpload(file) {
116       // 校检文件类型
117       if (this.fileType) {
118         const fileName = file.name.split('.');
119         const fileExt = fileName[fileName.length - 1];
120         const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
121         if (!isTypeOk) {
122           this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}格式文件!`);
123           return false;
124         }
125       }
126       // 校检文件名是否包含特殊字符
127       if (file.name.includes(',')) {
128         this.$modal.msgError('文件名不正确,不能包含英文逗号!');
129         return false;
130       }
131       // 校检文件大小
132       if (this.fileSize) {
133         const isLt = file.size / 1024 / 1024 < this.fileSize;
134         if (!isLt) {
135           this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
136           return false;
137         }
138       }
139       this.$modal.loading("正在上传文件,请稍候...");
140       this.number++;
141       return true;
142     },
143     // 文件个数超出
144     handleExceed() {
145       this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
146     },
147     // 上传失败
148     handleUploadError(err) {
149       this.$modal.msgError("上传文件失败,请重试");
150       this.$modal.closeLoading();
151     },
152     // 上传成功回调
153     handleUploadSuccess(res, file) {
154       if (res.code === 200) {
155         this.uploadList.push({ name: res.fileName, url: res.fileName });
156         this.uploadedSuccessfully();
157       } else {
158         this.number--;
159         this.$modal.closeLoading();
160         this.$modal.msgError(res.msg);
161         this.$refs.fileUpload.handleRemove(file);
162         this.uploadedSuccessfully();
163       }
164     },
165     // 删除文件
166     handleDelete(index) {
167       this.fileList.splice(index, 1);
168       this.$emit("input", this.listToString(this.fileList));
169     },
170     // 上传结束处理
171     uploadedSuccessfully() {
172       if (this.number > 0 && this.uploadList.length === this.number) {
173         this.fileList = this.fileList.concat(this.uploadList);
174         this.uploadList = [];
175         this.number = 0;
176         this.$emit("input", this.listToString(this.fileList));
177         this.$modal.closeLoading();
178       }
179     },
180     // 获取文件名称
181     getFileName(name) {
182       // 如果是url那么取最后的名字 如果不是直接返回
183       if (name.lastIndexOf("/") > -1) {
184         return name.slice(name.lastIndexOf("/") + 1);
185       } else {
186         return name;
187       }
188     },
189     // 对象转成指定字符串分隔
190     listToString(list, separator) {
191       let strs = "";
192       separator = separator || ",";
193       for (let i in list) {
194         strs += list[i].url + separator;
195       }
196       return strs != '' ? strs.substr(0, strs.length - 1) : '';
197     }
198   }
199 };
200 </script>
201
202 <style scoped lang="scss">
203 .upload-file-uploader {
204   margin-bottom: 5px;
205 }
206 .upload-file-list .el-upload-list__item {
207   border: 1px solid #e4e7ed;
208   line-height: 2;
209   margin-bottom: 10px;
210   position: relative;
211 }
212 .upload-file-list .ele-upload-list__item-content {
213   display: flex;
214   justify-content: space-between;
215   align-items: center;
216   color: inherit;
217 }
218 .ele-upload-list__item-content-action .el-link {
219   margin-right: 10px;
220 }
221 </style>