<template>
    <el-upload
        class="file-upload"
        :action="uploadUrl"
        :on-success="onSuccess"
        :headers="headers"
        :file-list="fileList"
        :limit="filesLimit"
        :on-exceed="onExceed"
        :on-preview="onPreview"
        ref="upload"
    >
        <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' && isImage(file)"
                        @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: {
        single: {
            type: Boolean,
            default() {
                return false;
            }
        },
        limit: {
            type: Number,
            default() {
                return 10000;
            }
        },
        value: {},
        format: {
            type: String,
            default: 'string'
        }
    },
    data() {
        return {
            fileList: [],
            emitting: false,
            uploadUrl: '',
            previewUrl: null
        };
    },
    computed: {
        headers() {
            return {
                Authorization: 'Bearer ' + localStorage.getItem('token')
            };
        },
        filesLimit() {
            if (this.single) {
                return 1;
            }
            return this.limit;
        },
        disabled() {
            return this.fileList.length >= this.limit;
        }
    },
    created() {
        this.uploadUrl = resolveUrl(this.$baseUrl, 'upload/file');
        this.update(this.value);
    },
    methods: {
        onSuccess(res, file, fileList) {
            file.url = res;
            this.fileList = fileList;
            this.emit();
        },
        update(value) {
            if (this.filesLimit === 1) {
                if (this.format === 'json') {
                    this.fileList = value ? [{ name: value.name, url: value.url }] : [];
                } else {
                    this.fileList = value ? [{ name: value.split('/').pop(), url: value }] : [];
                }
            } else {
                if (!value) {
                    this.fileList = [];
                } else {
                    this.fileList = value.map(i => {
                        return { name: i.name, url: i.url };
                    });
                }
            }
        },
        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);
                }
            }
            this.emit();
        },
        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);
        },
        emit() {
            this.emitting = true;
            if (this.filesLimit === 1) {
                if (this.format === 'json') {
                    this.$emit(
                        'input',
                        this.fileList[0]
                            ? {
                                  name: this.fileList[0].name,
                                  url: this.fileList[0].url
                              }
                            : null
                    );
                } else {
                    this.$emit('input', this.fileList[0] ? this.fileList[0].url : null);
                }
            } else {
                if (this.format === 'json') {
                    this.$emit(
                        'input',
                        this.fileList.map(i => {
                            return {
                                name: i.name,
                                url: i.url
                            };
                        })
                    );
                } else {
                    this.$emit(
                        'input',
                        this.fileList.map(i => i.url)
                    );
                }
            }
            this.$nextTick(() => {
                this.emitting = false;
            });
        }
    },
    watch: {
        value(value) {
            if (this.emitting) return;
            this.update(value);
        }
    }
};
</script>

<style lang="less" scoped>
.file-list-item {
    line-height: 1.8;
    margin-top: 5px;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
    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: #d7ab41;
            }
        }
    }
}
</style>
