drew há 5 anos atrás
pai
commit
445221c100

+ 122 - 6
src/main/vue/src/components/FileUpload.vue

@@ -1,18 +1,47 @@
 <template>
     <el-upload
-        class="upload-demo"
+        class="file-upload"
         :action="uploadUrl"
         :on-success="onSuccess"
         :on-remove="onRemove"
         :headers="headers"
         :file-list="fileList"
+        :limit="filesLimit"
+        :on-exceed="onExceed"
+        :on-preview="onPreview"
+        ref="upload"
     >
-        <el-button type="primary" :disabled="!(!single || fileList.length === 0)" size="mini">点击上传 </el-button>
+        <el-button type="primary" size="mini" slot="trigger">
+            点击上传
+        </el-button>
+        <div class="file-list-item" slot="file" slot-scope="{ file }">
+            <div class="file-name">
+                <i class="status-icon el-icon-warning-outline danger" v-if="file.status === 'fail'"></i>
+                <i class="status-icon el-icon-circle-check success" v-else-if="file.status === 'success'"></i>
+                <i class="status-icon el-icon-loading" v-else></i>
+                {{ file.name }}
+                <i class="opt">
+                    <i class="opt-icon el-icon-search" v-if="file.status === 'success'" @click="preview(file)"></i>
+                    <i class="opt-icon el-icon-download" v-if="file.status === 'success'" @click="download(file)"></i>
+                    <i class="opt-icon el-icon-delete" @click="removeFile(file)"></i>
+                </i>
+            </div>
+            <el-progress
+                v-if="file.status === 'uploading'"
+                :percentage="file.percentage"
+                :show-text="false"
+                :stroke-width="2"
+                class="upload-progress"
+            ></el-progress>
+        </div>
+        <el-image style="width:0;height:0;" :src="previewUrl" :preview-src-list="[previewUrl]" ref="preview">
+        </el-image>
     </el-upload>
 </template>
 
 <script>
 import resolveUrl from 'resolve-url';
+import axios from 'axios';
 export default {
     name: 'FileUpload',
     props: {
@@ -22,13 +51,20 @@ export default {
                 return false;
             }
         },
+        limit: {
+            type: Number,
+            default() {
+                return 10000;
+            }
+        },
         value: {}
     },
     data() {
         return {
             fileList: [],
             watchValue: true,
-            uploadUrl: ''
+            uploadUrl: '',
+            previewUrl: null
         };
     },
     computed: {
@@ -36,6 +72,15 @@ export default {
             return {
                 Authorization: 'Bearer ' + localStorage.getItem('token')
             };
+        },
+        filesLimit() {
+            if (this.single) {
+                return 1;
+            }
+            return this.limit;
+        },
+        disabled() {
+            return this.fileList.length >= this.limit;
         }
     },
     created() {
@@ -51,7 +96,7 @@ export default {
             this.fileList = fileList;
         },
         update(value) {
-            if (this.single) {
+            if (this.filesLimit === 1) {
                 this.fileList = value ? [{ name: value.split('/').pop(), url: value }] : [];
             } else {
                 if (!value) {
@@ -62,6 +107,35 @@ export default {
                     });
                 }
             }
+        },
+        onExceed(files, fileList) {
+            console.log(files, fileList);
+            this.$message.error(`最多上传${this.filesLimit}个文件`);
+        },
+        onPreview(file) {
+            console.log(file);
+        },
+        removeFile(file) {
+            if (file.status === 'uploading') {
+                this.$refs.upload.abort(file);
+            } else if (file.status === 'success') {
+                let index = this.fileList.findIndex(i => i.url === file.url);
+                if (index > -1) {
+                    this.fileList.splice(index, 1);
+                }
+            }
+        },
+        download(file) {
+            window.open(file.url, '_blank');
+        },
+        preview(file) {
+            this.previewUrl = file.url;
+            this.$nextTick(() => {
+                this.$refs.preview.clickHandler();
+            });
+        },
+        isImage(file) {
+            return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(file.url);
         }
     },
     watch: {
@@ -72,7 +146,7 @@ export default {
         },
         fileList(fileList) {
             this.watchValue = false;
-            if (this.single) {
+            if (this.filesLimit === 1) {
                 this.$emit('input', fileList[0] ? fileList[0].url : null);
             } else {
                 this.$emit(
@@ -88,4 +162,46 @@ export default {
 };
 </script>
 
-<style scoped></style>
+<style lang="less" scoped>
+.file-list-item {
+    line-height: 1.8;
+    margin-top: 5px;
+    cursor: pointer;
+    .file-name {
+        padding: 0 90px 0 20px;
+    }
+    .upload-progress {
+        margin-top: 2px;
+        position: absolute;
+        bottom: 0;
+        left: 20px;
+        right: 0;
+        width: auto;
+    }
+    .danger {
+        color: #f56c6c;
+    }
+    .success {
+        color: #67c23a;
+    }
+    .status-icon {
+        position: absolute;
+        left: 0;
+        top: 0;
+        line-height: inherit;
+    }
+    .opt {
+        position: absolute;
+        right: 0;
+        top: 0;
+        line-height: inherit;
+        .opt-icon {
+            margin-left: 15px;
+            transition: color 0.3s;
+            &:hover {
+                color: #409eff;
+            }
+        }
+    }
+}
+</style>

+ 8 - 0
src/main/vue/src/router.js

@@ -86,6 +86,14 @@ const router = new Router({
                     meta: {
                         title: '参数配置'
                     }
+                },
+                {
+                    path: '/upload',
+                    name: 'upload',
+                    component: () => import(/* webpackChunkName: "upload" */ '@/views/Upload.vue'),
+                    meta: {
+                        title: '上传'
+                    }
                 }
                 /**INSERT_LOCATION**/
             ]

+ 15 - 0
src/main/vue/src/views/Upload.vue

@@ -0,0 +1,15 @@
+<template>
+    <div style="width:370px">
+        <file-upload :limit="2" v-model="files"></file-upload>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            files: ['https://ticket-exchange.oss-cn-hangzhou.aliyuncs.com/image/2020-06-22-17-29-37LyLVuKzG.jpg']
+        };
+    }
+};
+</script>
+<style lang="sass" scoped></style>