<template>
  <div :class="$options.name" :show="show" :size="size" :style="style">
    <div class="upload-list-tray">
      <!-- 托盘头部 -->
      <div class="header" ref="header" @dblclick.stop.prevent="dblclickHeader">
        <div class="left">
          <div class="title">
            <span class="upload-count" slot="reference">上传队列</span>
            <div class="upload-info" v-if="liveSpeed && liveSpeed > 0">
              <el-divider :direction="`vertical`" />
              <div class="info-item live-speed">
                <label>速度</label>
                <span>{{ $g.getSize(liveSpeed) }}/s</span>
              </div>
              <div class="info-item taken-time" v-if="takenTime && takenTime > 0">
                <label>已耗时</label>
                <span>{{
                    $g.date.toHourMinuteSecondByMillisecond(takenTime * 1000, {
                      zh: true,
                      hideMilliSecond: true,
                      hideZero: true,
                    })
                  }}</span>
              </div>
              <div class="info-item remain-time" v-if="remainTime && remainTime > 0">
                <label>剩余</label
                ><span>{{
                  $g.date.toHourMinuteSecondByMillisecond(remainTime * 1000, {
                    zh: true,
                    hideMilliSecond: true,
                    hideZero: true,
                  })
                }}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="right" @mousedown.stop>
          <!-- 控制文件的图标按钮 -->
          <div class="file-btns" v-if="showDelSuccessIconBtn || showErrorIconBtn">
            <div
              class="icon-btn"
              v-if="showDelSuccessIconBtn"
              @click.stop="clearAllSuccessFile"
              title="清除所有已经成功的上传记录"
            >
              <i class="el-icon-delete" style="color: #67c23a"></i>
            </div>
            <div
              class="icon-btn"
              v-if="showErrorIconBtn"
              @click.stop="clearAllErrorFile"
              title="清除所有失败的上传记录"
            >
              <i class="el-icon-delete-solid" style="color: #f56c6c"></i>
            </div>
            <div
              class="icon-btn"
              v-if="showErrorIconBtn"
              @click.stop="uploadAllErrorFile"
              title="重新上传所有失败的文件"
            >
              <i class="el-icon-upload2" style="color: #409eff"></i>
            </div>
            <template v-if="uploadList.length > maxShowUploadFileCount">
              <div
                class="icon-btn"
                v-if="expandAllUploadList"
                @click.stop="expandAllUploadList = false"
                title="折叠只显示前10条上传记录"
              >
                <i class="el-icon-folder" style="color: #409eff"></i>
              </div>
              <el-tooltip
                v-else
                :content="`请谨慎展开列表，这将导致您的网页很卡！`"
                :effect="`dark`"
                :enterable="false"
                :placement="`top-start`"
                :popper-class="`sg-el-tooltip`"
                :transition="`none`"
                :disabled="uploadList.length < 200"
              >
                <div
                  class="icon-btn"
                  @click.stop="expandAllUploadList = true"
                  title="展开所有上传记录"
                >
                  <i class="el-icon-folder-opened" style="color: #409eff"></i>
                </div>
              </el-tooltip>
            </template>
          </div>
          <!-- 控制托盘的图标按钮 -->
          <div class="tray-btns">
            <div
              class="icon-btn"
              v-if="size !== 'lg' && showRightBottomBtn"
              @click.stop="toRightBottomPosition"
              title="回到原来的位置"
            >
              <i class="el-icon-bottom-right"></i>
            </div>
            <div
              class="icon-btn"
              v-if="size !== 'mn'"
              @click.stop="size = 'mn'"
              title="最小化"
            >
              <i class="el-icon-minus"></i>
            </div>
            <div
              class="icon-btn"
              v-if="size !== 'md'"
              @click.stop="size = 'md'"
              title="还原"
            >
              <i :class="size === 'lg' ? 'el-icon-copy-document' : 'el-icon-d-caret'"></i>
            </div>
            <div
              class="icon-btn"
              v-if="size !== 'lg'"
              @click.stop="size = 'lg'"
              title="全屏"
            >
              <i class="el-icon-full-screen"></i>
            </div>
            <div class="icon-btn" @click.stop="close">
              <i class="el-icon-close"></i>
            </div>
          </div>
        </div>
      </div>
      <!-- 上传中的文件列表 -->
      <div class="upload-file-list">
        <ul>
          <li
            v-for="(a, i) in expandAllUploadList ? uploadList : uploadList.slice(0, 10)"
            :key="i"
            :title="
              a.size > 1024 * 1024 * 500
                ? `超大文件上传中，请耐心等待，切勿关闭或刷新浏览器！`
                : ''
            "
          >
            <div class="left">
              <div class="icon-btns">
                <el-button
                  title="移出上传队列"
                  :show="a.status === 'error'"
                  class="remove-icon-btn icon-btn"
                  type="danger"
                  icon="el-icon-delete-solid"
                  size="mini"
                  plain
                  circle
                  @click.stop="removeUploadFile(a)"
                ></el-button>
              </div>
              <!-- 动画加载旋转 -->
              <div
                class="fileLoading"
                v-loading="a.percent < 100"
                v-if="a.percent < 100 && a.status !== 'error'"
              ></div>
              <!-- 上传成功icon -->
              <div class="loadingSuccessIcon" v-if="a.percent === 100">
                <i class="el-icon-success" style="color: #67c23a"></i>
              </div>
              <!-- 上传失败icon -->
              <div class="loadingEorrorIcon" v-if="a.status === 'error'">
                <i class="el-icon-error" style="color: #f56c6c"></i>
              </div>
              <span class="name" :title="a.filePath || a.name">
                {{ a.filePath || a.name }}
                <!-- {{ a.filePath && a.filePath.includes(`/`) ? `[路径：${a.filePath}]` : "" }} -->
              </span>
              <el-tag class="size" size="mini"
              >{{ $g.getSize(a.size * (a.percent / 100)) }}/{{
                  $g.getSize(a.size)
                }}</el-tag
              >
              <!-- <el-progress class="progress" :percentage="a.percent"></el-progress> -->
              <el-progress
                class="progress"
                style="width: 100%"
                type="line"
                :percentage="parseInt(a.percent)"
                :show-text="true"
                :stroke-width="10"
                :text-inside="false"
                :color="'#409EFF'"
                :define-back-color="'#eee'"
              />
            </div>
            <div class="right">
              <span class="tip" :color="a.color">{{ a.tip }}</span>
              <div class="icon-btns">
                <el-button
                  :show="a.status === 'error'"
                  title="重新上传"
                  class="upload-icon-btn icon-btn"
                  type="primary"
                  icon="el-icon-upload2"
                  size="mini"
                  plain
                  circle
                  @click.stop="startUploadFile(a)"
                ></el-button>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <!-- 折叠按钮 -->
      <sgCollapseBtn
        style="z-index: 1"
        :collapseLabel="`上传记录`"
        v-model="expandAllUploadList"
        v-if="uploadList.length > maxShowUploadFileCount"
      />
      <div class="footer">
        <div class="text" v-html="popoverContent"></div>
        <div class="progress" v-if="uploadList.length > 1 && totalPercentage < 100">
          <label>。总进度</label>
          <el-progress
            style="width: 100%"
            type="line"
            :percentage="parseInt(totalPercentage)"
            :show-text="true"
            :stroke-width="10"
            :text-inside="false"
            :color="'#409EFF'"
            :define-back-color="'#eee'"
          />
        </div>
      </div>
    </div>

    <!-- 拖拽移动窗体 -->
    <sgDragMove
      :data="dragMoveDoms"
      :cursor="{
        grab: 'default',
        grabbing: 'default',
      }"
      nearPadding="10"
      :disabled="size === 'lg' && disabledDragMove"
      @dragStart="$emit(`dragStart`, dragMoveDoms)"
      @dragging="
        showRightBottomBtn = true;
        $emit(`dragging`, dragMoveDoms);
      "
      @dragEnd="$emit(`dragEnd`, dragMoveDoms)"
      mousemoveNearSide
    />

    <!-- 拖拽改变窗体尺寸 -->
    <sgDragSize
      v-if="resizeable_"
      :disabled="size === 'lg'"
      @dragStart="disabledDragMove = true"
      @dragging="draggingSize"
      @dragEnd="disabledDragMove = false"
      :minWidth="minWidth"
      :minHeight="minHeight"
    />
  </div>
</template>
<script>
import sgCollapseBtn from "./sgCollapseBtn";
import sgDragMove from "./sgDragMove";
import sgDragSize from "./sgDragSize";
export default {
  name: "sgUploadTray",
  components: {
    sgCollapseBtn,
    sgDragMove,
    sgDragSize,
  },
  data() {
    return {
      maxShowUploadFileCount: 10, //默认展示上传数量
      expandAllUploadList: false, //默认折叠

      minWidth: 800,
      minHeight: 40,
      style_bk: null,
      style: {},
      resizeable_: true,
      disabledDragMove: false, //屏蔽移动
      show: false,
      showRightBottomBtn: false,
      size: "md", //lg全屏、md普通、mn最小
      uploadList: [],
      dragMoveDoms: [
        /* {
          canDragDom: elementDOM,//可以拖拽的位置元素
          moveDom: elementDOM,//拖拽同步移动的元素
      } */
      ], //可以拖拽移动的物体

      lastUploadedTotalSize: 0, //记录上次已经下载完成的总大小
      liveSpeed: 0, //瞬时下载速度(单位B)
      takenTime: 0, //已耗时
      remainTime: 0, //剩余下载时长
      interval: null,
      second: 1, //轮训间隔秒钟

      successFileList: [], //成功文件列表
      errorFileList: [], //失败文件列表
      remainFileList: [], //剩余文件列表
    };
  },
  props: ["data", "value", "resizeable", "position"],
  watch: {
    value: {
      handler(d) {
        this.show = d;
      },
      deep: true,
      immediate: true,
    },
    show: {
      handler(d) {
        this.$emit(`input`, d);
      },
      deep: true,
      immediate: true,
    },
    data: {
      handler(d) {
        this.uploadList = d || [];
      },
      deep: true,
      immediate: true,
    },
    uploadList: {
      handler(newValue, oldValue) {
        if (newValue && Object.keys(newValue).length) {
          this.interval || this.startUploadCalcLiveSpeed();
          this.successFileList = newValue.filter((v) => v.percent == 100);
          this.errorFileList = newValue.filter((v) => v.status === "error");
          this.remainFileList = newValue.filter(
            (v) => v.status !== "error" && v.status !== "success"
          );
        } else {
          this.successFileList = [];
          this.errorFileList = [];
          this.remainFileList = [];
        }
      },
      deep: true, //深度监听
      immediate: true, //立即执行
    },
    resizeable: {
      handler(newValue, oldValue) {
        this.resizeable_ = newValue === "" || newValue;
      },
      deep: true, //深度监听
      immediate: true, //立即执行
    },
    size: {
      handler(newValue, oldValue) {
        switch (newValue) {
          case "lg":
          case "mn":
            this.style_bk = JSON.parse(JSON.stringify(this.style));
            delete this.style.width, delete this.style.height;
            break;
          case "md":
            this.style_bk && (this.style = JSON.parse(JSON.stringify(this.style_bk)));
            break;
        }
      },
      deep: true, //深度监听
      immediate: true, //立即执行
    },
  },
  computed: {
    showDelSuccessIconBtn(d) {
      return this.uploadList.some((v) => v.percent == 100);
    },
    showErrorIconBtn(d) {
      return this.uploadList.some((v) => v.status == "error");
    },
    popoverContent(d) {
      let r = [];
      this.successFileList.length &&
      r.push(
        `已上传成功<span style="color: #67C23A;">${this.successFileList.length}</span>个`
      );
      this.errorFileList.length &&
      r.push(`失败<span style="color: #F56C6C;">${this.errorFileList.length}</span>个`);
      this.remainFileList.length &&
      r.push(
        `剩余<span style="color: #409EFF;">${this.remainFileList.length}</span>个`
      );
      if (this.uploadList.length) {
        return `共计${this.uploadList.length}个文件，${
          r.length ? `${r.join("，")}文件` : ``
        }`;
      } else {
        return `暂无待上传文件`;
      }
    },
    // 总体进度
    totalPercentage() {
      if (this.uploadList.length) {
        return parseFloat(
          ((this.successFileList.length / this.uploadList.length) * 100).toFixed(2)
        );
      } else {
        return 0;
      }
    },
    // 真正上传中的文件对象数组
    uploadingFiles(d) {
      let uploadingFiles_ = (this.uploadList || []).filter(
        (v) => v.percent < 100 && v.status !== "error" && v.status !== "success"
      );
      if (uploadingFiles_.length) {
        this.$emit(`changeUploadingListClose`, {
          path: this.position,
          close: this.close,
        });
      } else {
        this.$emit(`changeUploadingListClose`, null);
      }
      return uploadingFiles_;
    },
  },
  mounted() {
    this.$el.style.setProperty("--minWidth", `${this.minWidth}px`); //js往css传递局部参数
    this.$el.style.setProperty("--minHeight", `${this.minHeight}px`); //js往css传递局部参数
    this.dragMoveDoms = [
      {
        canDragDom: this.$refs.header, //托盘的头部可以拖拽
        moveDom: this.$el, //拖拽的时候，整个上传列表一起跟随移动
      },
    ];
  },
  destroyed() {
    clearInterval(this.interval);
  },
  methods: {
    // 开始计算瞬时下载速度
    startUploadCalcLiveSpeed() {
      clearInterval(this.interval);
      this.interval = setInterval(() => {
        this.calcLiveSpeed();
      }, 1000 * this.second);
    },
    // 结束计算瞬时下载速度
    endUploadCalcLiveSpeed(d) {
      clearInterval(this.interval);
      this.interval = null;
      this.liveSpeed = 0;
      this.takenTime = 0;
      this.remainTime = 0;
    },
    // 没有上传进程文件才结束计算速度
    ifNoUploadingFile_EndCalcLiveSpeed(d) {
      this.uploadingFiles.length || this.endUploadCalcLiveSpeed();
    },
    // 计算瞬时下载速度
    calcLiveSpeed(d) {
      this.takenTime++;
      let uploadList = this.uploadList;
      if (uploadList.length) {
        let totalSize = uploadList.reduce(
          (prevResult, current) => prevResult + current.size,
          0
        ); //求和需要上传的文件总大小
        let uploadedTotalSize = uploadList.reduce(
          (prevResult, current) => prevResult + current.size * (0.01 * current.percent),
          0
        ); //求和已经上传的文件总大小
        let remainTotalSize = totalSize - uploadedTotalSize; //剩余需要上传的文件
        if (this.lastUploadedTotalSize) {
          this.liveSpeed = (uploadedTotalSize - this.lastUploadedTotalSize) / this.second; //瞬时速度
          this.remainTime = remainTotalSize / this.liveSpeed; //瞬时剩余时长
        } else {
          this.liveSpeed = 0;
        }
        this.lastUploadedTotalSize = uploadedTotalSize; //记录本次已经上传的总大小
      } else {
        this.endUploadCalcLiveSpeed();
      }
    },
    clearAllSuccessFile() {
      let successFileList = this.uploadList.filter((v) => v.percent == 100);
      if (successFileList.length === 0)
        return this.$message(`暂无可以移除的成功记录，请稍后再试！`);
      this.$emit(`clearAllSuccessFile`, successFileList);
      this.$nextTick(() => {
        successFileList.forEach((file) => {
          file.removeFile(); //移除原始队列
        });
        this.uploadList = this.uploadList.filter((v) => v.percent < 100);
      });
    },
    clearAllErrorFile() {
      let errorFileList = this.uploadList.filter((v) => v.status == "error");
      if (errorFileList.length === 0)
        return this.$message(`暂无可以移除的失败记录，请稍后再试！`);
      this.$emit(`clearAllErrorFile`, errorFileList);
      this.$nextTick(() => {
        errorFileList.forEach((file) => {
          file.removeFile(); //移除原始队列
        });
        this.uploadList = this.uploadList.filter((v) => v.status !== "error");
      });
    },
    uploadAllErrorFile(d) {
      let errorFileList = this.uploadList.filter((v) => v.status == "error");
      errorFileList.forEach((fileData) => this.startUploadFile(fileData));
      if (errorFileList.length === 0) return this.$message(`暂无失败记录，请稍后再试！`);
      this.$emit(`uploadAllErrorFile`, errorFileList);
    },
    draggingSize({ style }) {
      this.disabledDragMove = true;
      this.style = style;
    },
    toRightBottomPosition(d) {
      this.showRightBottomBtn = false;
      let rect = this.$el.getBoundingClientRect();
      this.$el.style.left = `${innerWidth - rect.width}px`;
      this.$el.style.top = `${innerHeight - rect.height}px`;
      // 用下面的写法会清除掉setProperty属性
      /* this.$el.style = {
        left: innerWidth - rect.width + "px",
        top: innerHeight - rect.height + "px",
      }; */
    },
    dblclickHeader(d) {
      switch (this.size) {
        case "lg":
          this.size = "md";
          break;
        case "md":
          this.size = "mn";
          break;
        case "mn":
          this.size = "md";
          break;
        default:
      }
    },
    removeAllFilesFromList() {
      this.uploadList.forEach((file) => {
        file.removeFile(); //移除原始队列
      });
      this.uploadList = []; //移除托盘队列
    },
    removeFileFromList(d) {
      let file = this.uploadList.find((v) => v.uid == d.uid);
      file.removeFile(); //移除原始队列
      this.uploadList.splice(
        this.uploadList.findIndex((v) => v.uid == d.uid),
        1
      ); //移除托盘队列
    },
    // 重新上传失败的记录
    startUploadFile(fileData) {
      fileData.startUpload({ handleTrigger: true });
    },
    // 移出某一个队列文件
    removeUploadFile(d) {
      if (d.status === "error" || d.status === "success") {
        this.removeFileFromList(d);
      } else if (d.percent < 100) {
        this.$confirm(`${d.name}正在上传中，确定要取消吗？`, `提示`, {
          dangerouslyUseHTMLString: true,
          confirmButtonText: `确定`,
          cancelButtonText: `取消`,
          type: "warning",
        })
          .then(() => {
            this.$emit(`stopUpload`, [d]);
            this.$nextTick(() => {
              this.removeFileFromList(d);
              this.ifNoUploadingFile_EndCalcLiveSpeed();
            });
          })
          .catch(() => {});
      } else {
        this.removeFileFromList(d);
      }
    },
    // 关闭托盘
    close({ cb } = {}) {
      let stopUploadList = this.uploadingFiles;
      if (stopUploadList.length) {
        this.$confirm(`您还有正在上传中的文件，确定要取消吗？`, `提示`, {
          dangerouslyUseHTMLString: true,
          confirmButtonText: `确定`,
          cancelButtonText: `取消`,
          type: "warning",
        })
          .then(() => {
            this.show = false;
            this.$emit(`stopUpload`, stopUploadList);
            this.$nextTick(() => {
              this.endUploadCalcLiveSpeed();
              this.removeAllFilesFromList();
              cb && cb(stopUploadList); //完成后回调
            });
          })
          .catch(() => {});
      } else {
        this.show = false;
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.sgUploadTray {
  $headerHeight: 40px; //头部高度
  $footerHeight: 40px; //底部统计上传进度高度
  $collapseBtnHeight: 30px; //折叠按钮高度
  $minWidth: var(--minWidth); //托盘最小宽度
  $minHeight: var(--minHeight); //托盘最小高度
  $loadingWidth: 30px; //加载动画宽度（旋转全全）
  $rightWidth: 200px; //右侧宽度
  $sizeWidth: 200px; //文件大小宽度宽度
  $progressWidth: 100px; //进度条宽度
  $tipWidth: 100px; //提示文本宽度
  // ----------------------------------------
  z-index: 2001; //根据情况自己拿捏(太大了会遮住element的其他弹窗组件)，v-loading默认是2000的z-index
  user-select: none;
  position: fixed;
  right: 10px;
  bottom: 10px;
  width: $minWidth;
  background-color: white;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid #eee;
  font-size: 14px;
  display: none;

  &[show] {
    display: block;
  }

  &[size="lg"] {
    left: 0 !important;
    top: 0 !important;
    width: 100vw;
    height: 100vh;
    transition: none;
    .upload-file-list {
      max-height: calc(100vh - 60px) !important;
    }
  }

  &[size="md"] {
    width: $minWidth;
    height: revert;
  }

  &[size="mn"] {
    width: $minWidth;
    height: $minHeight;
  }

  .upload-list-tray {
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    padding-bottom: 20px;
    width: 100%;
    height: 100%;
    position: relative;

    .header {
      flex-shrink: 0;
      font-size: 16px;
      font-weight: bold;
      width: 100%;
      height: $headerHeight;
      box-sizing: border-box;
      padding: 10px 20px;
      /*从上往下线性渐变背景*/
      background: linear-gradient(#409eff11, white);
      color: #409eff;
      display: flex;
      justify-content: space-between;
      align-items: center;

      .left {
        display: flex;
        align-items: center;
        flex-grow: 1;

        .title {
          display: flex;
          align-items: center;
          flex-wrap: nowrap;
          .upload-info {
            display: flex;
            align-items: center;
            color: black;
            flex-shrink: 0;
            align-items: center;
            font-weight: normal;
            .info-item {
              margin-right: 5px;
              &:last-of-type {
                margin-right: 0;
              }
              span {
                font-family: DIN-Light;
                color: #409eff;
              }
              &.live-speed {
                span {
                  font-family: DIN-Black;
                }
              }
            }
          }
        }
        .icon-btns {
          display: flex;
          align-items: center;
          flex-wrap: nowrap;
          .icon-btn {
            cursor: pointer;
            margin-right: 5px;
            &:last-of-type {
              margin-right: 0;
            }
            i {
              pointer-events: none;
            }

            &:hover {
              opacity: 0.618;
            }
          }
        }
      }

      .right {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        flex-shrink: 0;
        pointer-events: auto;

        .icon-btn {
          margin-left: 10px;
          cursor: pointer;

          i {
            pointer-events: none;
          }

          &:hover {
            opacity: 0.618;
          }
          &:first-of-type {
            margin-left: 0;
          }
        }

        .file-btns {
          margin-left: 10px;
          display: flex;
          flex-wrap: nowrap;
          justify-content: flex-end;
          box-sizing: border-box;
          padding: 0 10px;
          border-right: 1px solid #eee;
        }
        .tray-btns {
          margin-left: 10px;
          display: flex;
          flex-wrap: nowrap;
          justify-content: flex-end;
        }
      }
    }

    .upload-file-list {
      width: 100%;
      flex-grow: 1;
      overflow-y: auto;
      height: max-content;
      max-height: calc(
        100vh - #{$headerHeight} - #{$footerHeight} - #{$collapseBtnHeight} - 40px
      );
      box-sizing: border-box;
      padding: 0 20px;

      ul {
        width: 100%;

        li {
          line-height: 1.6;
          box-sizing: border-box;
          padding: 10px;
          border-radius: 4px;
          display: flex;
          justify-content: space-between;
          align-items: center;
          width: 100%;

          .left {
            width: calc(100% - #{$rightWidth});
            display: flex;
            align-items: center;
            flex-grow: 1;
            flex-shrink: 0;
            // 上传队列记录左侧侧操作按钮
            .icon-btns {
              display: flex;
              flex-wrap: nowrap;
              .icon-btn {
                display: none;
                &[show] {
                  margin-right: 15px;
                  display: block;
                }
              }
            }
            .fileLoading {
              flex-shrink: 0;
              width: 30px;
              margin-right: 5px;
              height: 0;
              transform: scale(0.5);
            }
            .loadingSuccessIcon,
            .loadingEorrorIcon {
              margin-right: 5px;
              width: 30px;
              height: 30px;
              display: flex;
              justify-content: center;
              align-items: center;
              flex-shrink: 0;
            }
            .name {
              text-align: left;
              margin-right: 10px;
              width: calc(
                100% - #{$loadingWidth} - #{$sizeWidth} - #{$progressWidth} - #{$rightWidth} -
                20px
              );
              overflow: hidden;
              white-space: nowrap;
              text-overflow: ellipsis;
              flex-shrink: 0;
              flex-grow: 1;
            }

            .size {
              margin-right: 10px;
              max-width: $sizeWidth;
              /*单行省略号*/
              overflow: hidden;
              white-space: nowrap;
              text-overflow: ellipsis;
              flex-shrink: 0;
            }

            .progress {
              max-width: $progressWidth;
              display: flex;
              align-items: center;
              flex-wrap: nowrap;
              flex-shrink: 0;
            }
          }

          .right {
            display: flex;
            align-items: center;
            justify-content: flex-end;
            width: $rightWidth;

            .tip {
              width: $tipWidth;
              overflow: hidden;
              white-space: nowrap;
              text-overflow: ellipsis;
              flex-shrink: 0;
              text-align: right;

              &[color="red"] {
                color: #f56c6c;
              }

              &[color="green"] {
                color: #67c23a;
              }

              &[color="blue"] {
                color: #409eff;
              }
            }
            // 上传队列记录右侧操作按钮
            .icon-btns {
              display: flex;
              flex-wrap: nowrap;
              .icon-btn {
                display: none;
                &[show] {
                  margin-left: 15px;
                  display: block;
                }
              }
            }
          }

          &:hover {
            background-color: #409eff11;
            color: #409eff;
            .left {
              // 移入上传队列记录左侧操作按钮
              .icon-btns {
                .icon-btn {
                  display: block;
                  &:last-of-type {
                    margin-right: 10px;
                  }
                }
              }
            }
            .right {
              .tip {
                margin-right: 15px;
              }
              // 移入上传队列记录右侧操作按钮
              .icon-btns {
                .icon-btn {
                  display: block;
                  &:first-of-type {
                    margin-left: 0;
                  }
                }
              }
            }
          }
        }
      }
    }

    .footer {
      font-weight: normal;
      flex-shrink: 0;
      font-size: 14px;
      font-weight: bold;
      width: 100%;
      height: $footerHeight;
      box-sizing: border-box;
      padding: 10px 20px;
      margin-bottom: -20px;
      background: linear-gradient(white, #eff2f7);
      color: #909399;
      display: flex;
      align-items: center;
      flex-wrap: nowrap;
      white-space: nowrap;
      * {
        font-weight: normal;
      }
      .text {
        white-space: nowrap;
      }
      .progress {
        max-width: 200px;
        flex-grow: 1;
        white-space: nowrap;
        display: flex;
        align-items: center;
        flex-wrap: nowrap;
        label {
          white-space: nowrap;
          flex-shrink: 0;
          margin-right: 5px;
        }
        >>> .el-progress {
          white-space: nowrap;
          .el-progress__text {
            font-weight: normal;
            font-size: 14px !important;
          }
        }
      }
    }
  }
}
</style>
