el-upload文件上传,更新表格进度条

459 阅读2分钟

el-upload中单文件多文件上传,有表格进度条 也可以直接看这篇文章: blog.csdn.net/l976425836/… 作者大大写的很好

image.png

<el-upload
  ref="uploadMutiple"
  action=""
  :show-file-list="false"
  :multiple="true"
  :before-upload="beforeUpload"
  style="float: right;"
>
  <el-button size="mini" type="primary">选择文件</el-button>
</el-upload>

<el-table
  :data="uploadFilesList"
  ref="singleTable"
  highlight-current-row
  style="width: 100%">
  <el-table-column
    type="index"
    label="序号"
    align="center"
  >
  </el-table-column>
  <el-table-column
    prop="videoName"
    label="视频名称"
    show-overflow-tooltip
    align="center">
  </el-table-column>
  <el-table-column prop="videoName" label="上传状态" width="300">
    <template slot-scope="scope">
      <span>{{scope.row.status}}</span>
    </template>
  </el-table-column>
  <el-table-column label="上传进度" width="300">
    <template slot-scope="scope">
      <el-progress :percentage="scope.row.progress" />
    </template>
  </el-table-column>
  <el-table-column label="操作" align="center">
    <template slot-scope="scope">
      <el-button
        size="mini"
        type="text"
        v-if="scope.row.status !== '上传失败'"
        @click="reView(scope.row)">预览</el-button>
      <el-button
        size="mini"
        type="text"
        @click="handleDelete(scope.row)">删除</el-button>
    </template>
  </el-table-column>
</el-table>
<el-dialog
  :visible.sync="innerVisible"
  v-el-drag-dialog
  :modal="false"
  :close-on-click-modal="false"
  :show-close="false"
  width="55%"
  class="videoPage"
  >
  <div slot="title">
    <el-row :gutter="20">
      <el-col :span="24">
        <span class="backContent">{{ vName }}</span>
        <span class="close" style="color: #909399" @click="handleClose">
    <i class="el-dialog__close el-icon el-icon-close"></i>
  </span>
      </el-col>
    </el-row>
  </div>
  <div class="video_stream">
    <div id="videoBackOne"></div>
  </div>
</el-dialog>

// 实现的方法
beforeUpload(file) {
  const isMP4 = file.type === 'video/mp4';
  const isMP3 = file.type === 'audio/mp3';
  const isLt = file.size / 1024 / 1024 < this.fileLtSize
  if (!isMP4 && !isMP3) {
    this.$message.error('上传文件只能是 MP4 或 MP3 格式!');
    return false; // 文件类型不正确,阻止上传
  }
  if (!isLt) {
    this.$message.error('上传视频文件大小不能超过' + this.fileLtSize + 'MB!')
    return false; // 文件大小超出限制,阻止上传
  }
  const fileObj = {
    videoName: file.name,
    id: '',
    progress: 0,
    videoUrl: file.fileUrl,
    status: '上传中'
  };
  this.uploadFilesList.push(fileObj);
  this.httpRequest(fileObj, file);
  return false; // 阻止默认上传行为
},
async httpRequest(fileObj, file, callback) {
  this.uploadLoading = true
  let formData = new FormData();
  formData.append('files', file)
  const reqConfig = {
    headers: {
    // 根据后台接口去写自己的请求头
    },
    // 获取上传进度
    onUploadProgress: (progressEvent) => {
      const progress = (progressEvent.loaded / progressEvent.total * 100) | 0;
      this.$set(fileObj, 'progress', progress); // 更新进度
    }
  };
  this.$axios.post(后台接口, formData, reqConfig).then((res) => {
    if(res.status === 200) { // 这个具体看后台接口返回的结果
      const videoList = res.data.data.videoList
      if(videoList.length > 0) {
        // 假设每个文件的上传状态都在 videoFiles 数组中
        // 唯一标识这个,如果有别的更好的,根据文件名去,是因为新追加的没有id,可以拿到uid,但是后台返回的数据里面,没有uid。具体看后台返回的数据
        const fileStatus = videoList.find(f => f.fileName === fileObj.videoName);
        if (fileStatus && fileStatus.uploadStatus == '上传成功') {
          // 如果后台返回上传成功,则更新状态,需要更新全部数据,我一开始只更新了进度和状态,导致预览和删除功能失效。
          this.$set(fileObj, 'progress', 100);
          this.$set(fileObj, 'videoName', fileStatus.fileName);
          this.$set(fileObj, 'videoUrl', fileStatus.fileUrl);
          this.$set(fileObj, 'status', fileStatus.uploadStatus);
          this.$set(fileObj, 'id', fileStatus.id);
        } else {
          // 如果后台返回的不是上传成功,则视为失败
          this.$set(fileObj, 'progress', 0);
          this.$set(fileObj, 'status', '上传失败');
        }
      } else {
        // 如果响应中没有 videoFiles 或其长度为0,也视为失败
        this.$set(fileObj, 'progress', 0);
        this.$set(fileObj, 'status', '上传失败');
      }
    } else {
      // 如果响应中没有 videoFiles 或其长度为0,也视为失败
      this.$set(fileObj, 'progress', 0);
      this.$set(fileObj, 'status', '上传失败');
    }
  }).catch(() => { // 失败状态
      // 捕获到错误,更新状态为上传失败
      this.$set(fileObj, 'progress', 0);
      this.$set(fileObj, 'status', '上传失败');
      // 可以在这里处理错误,例如打印错误日志或显示错误信息
      console.error('上传失败');
    })
},
// 预览和删除也写一下吧,就当是提醒自己了,实现方法,我应该是已经写过了播放器的那个,但是发现在后续做的过程中,播放器还是会出问题
// 预览
reView(row) {
  console.log('播放视频', row);
  this.vName = row.videoName
  this.innerVisible = true;
  this.initVideoBack(row.videoUrl)
},
// 初始化播放器 导致视频播放器显示不出来的问题主要是没有高度
initVideoBack(currentUrl) {
  if (this.player) {
    this.player.destroy()
    this.player = null
  }
  this.$nextTick(() => {
    this.player = new Player({
      id: 'videoBackOne',
      url: currentUrl,
      // autoplay: true,
      height: '90%',
      width: '100%',
      videoAttributes: {
        crossOrigin: 'anonymous'
      }
    });
    this.player.on(Events.ERROR, (error) => {
      console.log(error) // xgplayer 中的 Errors 对象
    })
  })
},
// 删除
handleDelete(row) {
  // 判断是否有 row.id,如果没有则直接在前端删除,否则调用接口删除
  if (row.id) {
    // 调用接口删除服务器上的数据
    this.deleteFromServer(row);
  } else {
    // 直接在前端删除
    this.deleteFromFrontEnd(row);
  }
},
// 这个删除可能有问题,但是一般正常的操作,文件名不能是一样的
deleteFromFrontEnd(row) {
  // 在前端删除操作
  // 找到要删除的元素索引
  const index = this.uploadFilesList.findIndex(file => file.videoName === row.videoName);
  this.$confirm(`确定删除剧集【${row.videoName}】吗?`, '提交', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'success'
  }).then(() => {
    if (index !== -1) {
      // 从列表中移除元素
      this.uploadFilesList.splice(index, 1);
      this.$message({
        message: '删除成功!',
        type: 'success'
      });
    }
  })
},