Vue+Element+七牛云多文件上传组件_进度条展示_多文件格式

<template>
    <div class="">
        <!-- 上传 -->
        <el-upload class="upload-demo" :limit="5" action="#" :before-upload="beforeUpload"
            accept=".mp4,.mov,.png,.jpeg,.jpg,.pdf,.docx" :on-exceed="handleExceed" multiple :show-file-list="false">
            <el-button size="small" type="primary" icon="el-icon-upload">上传</el-button>
        </el-upload>

        <!-- 上传列表 -->
        <el-dialog
          append-to-body
          title="上传列表"
          :visible.sync="show_upload"
          width="40%">
          <div class="dis-flex flex-wrap">
            <div v-for="item,index in list" :key="index" style="width: 100%;border:1px solid #F2F6FC;margin-bottom: 5px;">
                    <div class="w-100" style="position: relative;">
                        <div style="position: absolute;width: 100%;height: 45px;display: flex;align-items: center;text-align: center;">
                            <div style="width: 100%;font-size: 12px;">
                                <div style="flex: 1;">{{item.name}}</div>
                                <div style="font-weight: bold;">{{parseInt(item.percent)}}%</div>
                            </div>
                            <div style="width: 80px;">
                                <div v-if="item.is_cancel == 0 && item.percent < 100" @click="cancel(index)"><i class="el-icon-circle-close"></i></div>
                                <div  v-if="item.is_cancel == 1" style="font-size: 10px;">已取消</div>
                                <div v-if="item.is_cancel == 0 && item.percent >= 100" style="font-size: 18px;color: #fff;"><i class="el-icon-success"></i></div>
                            </div>
                        </div>
                        <div class="jdy-progress-bar" :style="{ width: item.percent+'%' ,background:getGradient(item.percent)}"></div>
                    </div>
            </div>
          </div>
        </el-dialog>
    </div>
</template>
<script>
    import * as qiniu from 'qiniu-js'
    export default {
        props:{
            group_id:String
        },
        data() {
            return {
                domain: '',//七牛云解析域名
                qiniuToken: '', //七牛Token
                index: 0,
                list: [],
                show_upload:false,
                linearColors: [{ v: 25, s: '#F7564A', e: '#F7564A' }, { v: 50, s: '#F7564A', e: '#F7E04B' }, { v: 100, s: '#F7E04B', e: '#25CCDB', ef: true }, { v: 100, s: '#25CCDB', e: '#25CCDB' }]
            }
        },
        created() {
            this.getQiniuToken();
        },
        methods: {
            beforeUpload(file) {
                let typeArr = file.type.split('/');
                if (typeArr[0] != 'video' && typeArr[0] != 'image' && file.type != 'application/pdf') {
                    this.$message.error('文件格式错误!暂不支持'+file.type+'文件');
                    return false; // 终止上传
                } else {
                    this.show_upload = true;
                    this.uploadVideo(file, this.index); // 上传视频到七牛云
                    this.index = this.index + 1;
                }
            },
            uploadVideo(file, index) {
                const _this = this;
                let indexd = file.name.lastIndexOf('.');
                let suffix = file.name.substring(indexd);
                let prefix = file.name.substring(0, indexd);
                // key:文件资源名,为空字符串时则文件资源名也为空,为 null 或者 undefined 时则自动使用文件的 hash 作为文件名   
                const key = 'video/' + prefix + '_' + Date.now() + suffix;
                _this.list.push({
                    is_cancel: 0, //是否取消
                    name: key, //上传文件名
                    percent: 0, //进度
                    subscription: null, //取消对象
                    imgLink: '' //缩略图
                })
                // _this.qiniuToken 由后端提供,通过接口获取
                var observable = qiniu.upload(file, key, _this.qiniuToken, {
                    useCdnDomain: true,
                    region: qiniu.region.z2, // 根据地区不同,官网有不同的配置
                    concurrentRequestLimit: 1000,
                });
                var observer = {
                    next(res) { // 用于展示上传进度
                        _this.list[index].percent = res.total.percent;
                    },
                    error(err) {
                        console.log({err})
                        _this.$message({
                            type: 'warning',
                            message: err.message + ',刷新页面重试!'
                        })
                    },
                    complete(res) {
                        let typeArr = file.type.split('/');
                        _this.saveQiniuUrl({
                            file_url: _this.domain + res.key,
                            extension: typeArr[1],
                            type: typeArr[0],
                            size: file.size,
                        });
                    },
                };
                this.list[index].subscription = observable.subscribe(observer); // 开始上传(赋值给一个全局的参数,可以在合适的时机通过:subscription.unsubscribe() 终止上传)
            },
            //取消上传
            cancel(index) {
                this.list[index].subscription.unsubscribe();
                this.list[index].is_cancel = 1;
            },
            //获取Token
            getQiniuToken() {
                this.util.sendAjax(this, this.ruleForm, 'admin/Util/getQiniuToken').then((res) => {
                    if (res.code == 0) {
                        this.qiniuToken = res.data.token;
                        this.domain = res.data.domain
                    }
                })
            },
            // 选取文件超过数量提示
            handleExceed(files, fileList) {
                this.$message.warning(`最多可选择5个文件,本次选择了 ${files.length} 个文件`);
            },
            //保存链接
            saveQiniuUrl(result) {
                result.group_id = this.group_id;
                this.util.sendAjax(this, result, 'admin/Util/saveQiniuUrl').then((res) => {
                    if (res.code == 0) {
                        this.$emit('getGroupFile');
                    }
                })
            },
            getGradient (percentage) {
              let linecolor = this.getColorItem(percentage)
              if (linecolor) {
                return 'linear-gradient(90deg,' + linecolor.s + ',' + linecolor.e + ')'
              } else {
                return ''
              }
            },
            // 根据进度 获取颜色数组
            getColorItem (p) {
              let mp = p
              for (let sub of this.linearColors) {
                if (!sub.ef && mp <= sub.v) {
                  return sub
                } else if (sub.ef && mp < sub.v) {
                  return sub
                }
              }
              return null
            }
        }
    }
</script>
<style>
.jdy-progress-bar {
      transition: width 1s;
            height: 45px;
    }
</style>

posted @ 2023-06-08 10:09  窦戈  阅读(818)  评论(0编辑  收藏  举报