index.vue 21.6 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
<template>
  <div class="eagle-upload" :class="[size]">
    <ul class="el-upload-list el-upload-list--picture-card">
      <!-- 已上传图片列表,支持拖拽改变顺序 -->
      <drag-field v-model="imageList" @change="onDragFile" :draggable="draggable">
        <div v-for="(url, index) in imageList" :key="index" class="el-upload-list__item-wrapper">
          <li class="el-upload-list__item">
            <template v-if="type === 'all'">
              <img v-if="isImage(url)" :src="url" alt class="el-upload-list__item-thumbnail" />
              <div v-else alt class="el-upload-list__item-thumbnail--file" :class="url | fileTypeFilter"></div>
            </template>
            <template v-else>
              <img v-if="type === 'image'" :src="url" alt class="el-upload-list__item-thumbnail" />
              <div v-else alt class="el-upload-list__item-thumbnail--file" :class="url | fileTypeFilter"></div>
            </template>
            <div v-if="!cornerClose" class="el-upload-list__item-actions">
              <span v-if="isImage(url)" class="el-upload-list__item-preview" @click="onPreview(url, index)">
                <i class="el-icon-zoom-in"></i>
              </span>
              <span v-else class="el-upload-list__item-preview" @click="onDownload(url)">
                <i class="el-icon-download"></i>
              </span>
              <span v-if="!disabled && !readonly" class="el-upload-list__item-delete" @click="onRemove(url, index)">
                <i class="el-icon-delete"></i>
              </span>
            </div>
            <div v-else class="el-upload-list__item-actions">
              <div v-if="isImage(url)" class="block-preview" @click="onPreview(url, index)">
                <i class="el-icon-view"></i>
              </div>
              <div v-else class="block-download" @click="onDownload(url)">
                <i class="el-icon-download"></i>
              </div>
            </div>
          </li>
          <div v-if="cornerClose && !disabled && !readonly" class="corner-close" @click="onRemove(url, index)">
            <i class="el-icon-close"></i>
          </div>
        </div>
      </drag-field>
      <!-- 默认上传按钮 -->
      <el-upload
        v-if="!readonly && (!limit || imageList.length < limit)"
        :action="action"
        :data="data"
        :name="name"
        :headers="headers"
        :file-list="fileList"
        :disabled="disabled"
        :multiple="multiple"
        :limit="limit"
        :drag="drag"
        :show-file-list="false"
        list-type="picture-card"
        :on-exceed="onExceed"
        :on-success="onSuccess"
        :on-error="onError"
        :before-upload="onBeforeUpload"
        :http-request="isCustomRequest ? onHttpRequest : undefined"
      >
        <i class="el-icon-plus"></i>
      </el-upload>
    </ul>
    <!-- 图片查看器 -->
    <slot
      v-if="$scopedSlots['image-viewer'] || $slots['image-viewer']"
      name="image-viewer"
      :show="isImageViewerShow"
      :index="defaultIndex"
      :list="filteredImageList"
      :close="closeViewer"
      :open="openViewer"
    ></slot>
    <template v-else>
      <el-image-viewer v-if="isImageViewerShow" :initial-index="defaultIndex" :on-close="closeViewer" :url-list="filteredImageList" />
    </template>
  </div>
</template>

<script>
import ElImageViewer from './image-viewer';

const imgExtensions = ['.bmp', '.jpg', '.jpeg', '.png', '.tif', '.gif', '.pcx', '.tga', '.exif', '.fpx', '.svg', '.heic'];

// 获取文件类型
const getFileType = function(url) {
  return `${/\.[^.]+$/.exec(url)[0]}`.toLowerCase();
};

export default {
  name: 'Upload',
  components: {
    ElImageViewer,
    DragField: {
      props: { value: Array, draggable: Boolean },
      render(h) {
        // 是否开启可拖拽改变图片顺序,需要项目安装vuedraggable
        if (this.draggable) {
          return h(
            'draggable',
            {
              props: { value: this.value },
              on: {
                input: e => this.$emit('input', e),
                change: e => this.$emit('change', e),
              },
            },
            this.$slots.default,
          );
        } else {
          return h('div', this.$slots.default);
        }
      },
    },
  },
  props: {
    value: String,
    // 是否禁用
    disabled: Boolean,
    // 是否只读
    readonly: Boolean,
    // 是否支持多选文件
    multiple: Boolean,
    // 最大上传数量
    limit: Number,
    // 是否启用拖拽上传
    drag: Boolean,
    // 是否启用拖拽改变顺序
    draggable: Boolean,
    // 上传地址
    action: String,
    // 自定义请求头
    headers: {
      type: Object,
      default: () => ({}),
    },
    // 删除图片时确认提示
    deleteConfirm: Boolean,
    // 上传时附带的额外参数
    data: {
      type: Object,
      default: () => ({}),
    },
    // 上传文件字段名
    name: {
      type: String,
      default: 'file',
    },
    // 返回值处理
    responseFilter: Function,
    // 上传文件之前的钩子
    beforeUpload: Function,
    // 上传类型
    type: {
      type: String,
      default: 'all', // all, image, file
    },
    // 上传文件类型限制
    fileType: String,
    // 大小
    size: {
      type: String,
      default: 'large', // mini, small, large
    },
    // HTTP请求库
    http: Function,
    // 自定义请求方法
    httpRequest: Function,
    // 是否开启角标删除按钮
    cornerClose: Boolean,
  },
  data() {
    return {
      fileList: [], // ElementUI Upload 默认文件列表
      imageList: [], // 图片url列表
      isImageViewerShow: false, // 图片预览显示状态
      currentIndex: 0, // 当前预览图片下标
    };
  },
  computed: {
    // 请求自定义
    isCustomRequest() {
      return Boolean(this.http) || Boolean(this.httpRequest) || Boolean(this.$axios);
    },
    // 预览图片列表,去除文件
    filteredImageList() {
      if (this.type === 'all') {
        return this.imageList.filter(url => imgExtensions.some(key => `${url}`.toLowerCase().includes(key)));
      }
      return this.imageList;
    },
    // 预览文件列表默认下标
    defaultIndex() {
      if (this.type === 'all') {
        const currentUrl = this.imageList[this.currentIndex];
        return this.filteredImageList.findIndex(url => url === currentUrl);
      } else {
        return this.currentIndex;
      }
    },
  },
  filters: {
    // 处理文件拓展名对应的class
    fileTypeFilter(val) {
      const fileType = getFileType(val);
      if (['.doc', '.docx'].includes(fileType)) {
        return 'word';
      }
      if (['.xls', '.xlsx', '.csv'].includes(fileType)) {
        return 'excel';
      }
      if (['.ppt', '.pptx'].includes(fileType)) {
        return 'ppt';
      }
      if (['.pdf'].includes(fileType)) {
        return 'pdf';
      }
      if (['.zip', '.rar', '.7z'].includes(fileType)) {
        return 'zip';
      }
      if (['.mp3', 'wav', 'wma', 'ogg', 'aac', 'm4a'].includes(fileType)) {
        return 'audio';
      }
      if (['.mp4', '.mkv', 'wmv', 'mov', 'avi', 'rm', 'rmvb', 'flv', '3gp'].includes(fileType)) {
        return 'video';
      }
      return '';
    },
  },
  watch: {
    value: {
      handler(val) {
        if (val) {
          let imageList = [];
          let fileList = [];
          val.split(',').forEach(url => {
            imageList.push(url);
            fileList.push({ url });
          });
          this.imageList = imageList;
          this.fileList = fileList;
        } else {
          this.fileList = [];
          this.imageList = [];
        }
      },
      immediate: true,
    },
  },
  methods: {
    // 判断url是否为图片
    isImage(url) {
      return imgExtensions.some(key => `${url}`.toLowerCase().includes(key));
    },
    // 删除图片
    onRemove(url, index) {
      if (this.deleteConfirm) {
        this.$confirm(`确定删除当前${this.isImage(url) ? '图片' : '文件'}吗?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        })
          .then(() => {
            this.removeImage(index);
          })
          .catch(() => {});
      } else {
        this.removeImage(index);
      }
    },
    // 移除图片
    removeImage(index) {
      this.imageList.splice(index, 1);
      this.fileList.splice(index, 1);
      this.$emit('input', this.imageList.join(','));
    },
    // 预览图片
    onPreview(url, index) {
      this.currentIndex = index;
      this.$nextTick(this.openViewer);
    },
    // 打开图片预览
    openViewer() {
      this.isImageViewerShow = true;
    },
    // 关闭图片预览
    closeViewer() {
      this.isImageViewerShow = false;
    },
    // 下载文件
    onDownload(url) {
      window.open(url);
    },
    // 上传之前校验
    onBeforeUpload(file) {
      if (this.type === 'all') {
        if (this.beforeUpload) {
          return this.beforeUpload(file);
        }
        return true;
      }
      const fileType = getFileType(file.name);
      if (this.type === 'image') {
        if (!`${file.type}`.toLowerCase().includes('image')) {
          this.$message.warning('请上传图片');
          return false;
        }
      } else if (this.type === 'file') {
        if (`${file.type}`.toLowerCase().includes('image') || (this.fileType && !fileType.includes(this.fileType))) {
          this.$message.warning(`请上传${this.fileType || ''}文件`);
          return false;
        }
      }
      if (this.beforeUpload) {
        return this.beforeUpload(file);
      }
      return true;
    },
    // 自定义上传
    onHttpRequest(option) {
      const formData = new FormData();
      if (option.data) {
        Object.keys(option.data).forEach(key => {
          formData.append(key, option.data[key]);
        });
      }
      formData.append(option.filename, option.file, option.file.name);
      if (this.httpRequest) {
        this.httpRequest({ ...option, formData });
      } else {
        const request = this.http || this.$axios;
        if (request && request.post) {
          request
            .post(option.action, formData, { headers: option.headers })
            .then(response => {
              this.onSuccess(response.data);
            })
            .catch(error => {
              this.onError(error);
            });
        }
      }
    },
    // 上传失败
    onError(err) {
      this.$message.error('上传失败, 系统异常!');
    },
    // 上传成功
    onSuccess(response) {
      if (response.success) {
        const { result } = response || {};
        if (this.responseFilter) {
          this.imageList.push(this.responseFilter(response));
        } else if (result) {
          this.imageList.push(result[0]);
        }
        this.$emit('input', this.imageList.join(','));
      } else {
        if (response.businessException) {
          this.$message.error('上传失败!' + response.message);
        } else {
          this.$message.error('上传失败!');
        }
      }
      this.$emit('upload', response);
    },
    // 文件超出个数限制
    onExceed() {
      this.$message.warning('文件个数超出限制!');
    },
    // 拖动图片
    onDragFile() {
      this.$emit('input', this.imageList.join(','));
    },
  },
};
</script>

<style lang="scss">
.eagle-upload {
  &,
  .el-upload-list.el-upload-list--picture-card {
    display: inline-flex;
    flex-wrap: wrap;
  }
  /* 当上传内容为文件时,默认显示对应的图标 */
  .el-upload-list__item-thumbnail--file {
    height: 100%;
    width: 100%;
    background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='60' height='60'%3E%3Cpath d='M176 160h304a472.432 472.432 0 0 1 64 64l128 208a64 64 0 0 1-64 64H176a64 64 0 0 1-64-64V224a64 64 0 0 1 64-64z' fill='%23A1CBFE'/%3E%3Cpath d='M176 288h688q64 0 64 64v432q0 64-64 64H176q-64 0-64-64V352q0-64 64-64z' fill='%234799FE'/%3E%3Cpath d='M336 688h368q32 0 32 32t-32 32H336q-32 0-32-32t32-32z' fill='%23FFF'/%3E%3Cpath d='M832 336h16q32 0 32 32v16q0 32-32 32h-16q-32 0-32-32v-16q0-32 32-32z' fill='%23A1CBFE'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 60%;
    &.word {
      background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='81' height='81'%3E%3Cpath d='M665.6 0l256 256v716.8a51.2 51.2 0 0 1-51.2 51.2H153.6a51.2 51.2 0 0 1-51.2-51.2V51.2A51.2 51.2 0 0 1 153.6 0zM284.16 360.96l94.72 330.24h56.32l64-248.32h2.56l64 248.32h56.32l94.72-330.24h-61.44l-61.44 250.88h-2.56l-64-250.88h-56.32L409.6 611.84h-2.56L345.6 360.96z' fill='%234E97FF'/%3E%3Cpath d='M665.6 0l256 256h-256z' fill='%23A4D2FF'/%3E%3C/svg%3E");
    }
    &.excel {
      background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='81' height='81'%3E%3Cpath d='M139.456 0c-8.896 0-22.24 4.48-35.616 13.344-13.344 8.928-13.344 26.72-13.344 35.616v921.6c0 13.376 4.48 26.72 13.344 35.648 13.376 13.344 26.72 17.792 35.616 17.792h752.448c13.344 0 26.688-4.48 35.616-13.344 8.896-8.928 8.896-22.272 8.896-35.616V289.376L651.488 0h-512z' fill='%235ACC9B'/%3E%3Cpath d='M936.416 289.376h-231.52c-13.344 0-26.72-4.448-35.616-13.344-8.896-8.896-13.344-22.272-13.344-35.616V0l280.48 289.376z' fill='%23BDEBD7'/%3E%3Cpath d='M477.824 538.72L362.08 378.432h80.128l75.712 115.776 80.128-115.776h75.68L557.984 538.72l124.64 173.632H598.08L517.952 587.68l-84.608 124.672h-80.16z' fill='%23FFF'/%3E%3C/svg%3E");
    }
    &.ppt {
      background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='81' height='81'%3E%3Cpath d='M880.085 1017.43h-736.17a58.539 58.539 0 0 1-58.582-58.283V58.283C85.333 26.368 111.445 0 143.915 0h513.024l281.728 288.768v670.379c0 32.298-26.112 58.282-58.582 58.282z' fill='%23FF9540'/%3E%3Cpath d='M644.437 0a15.36 15.36 0 0 0-1.152 6.059v229.888c0 32.554 27.179 59.434 60.928 59.434h234.454v-.384L645.632 0h-1.195z' fill='%23FFF' fill-opacity='.496'/%3E%3Cpath d='M511.403 573.355h-55.51v115.882h-75.178V361.045h137.898c80.086 2.219 121.6 36.608 124.63 103.894 1.152 72.149-42.667 108.373-131.84 108.373zm-6.016-154.368h-49.494v97.92h49.494c38.912-.768 58.922-17.195 60.074-48.982-1.152-31.744-21.162-47.829-60.074-48.938z' fill='%23FFF'/%3E%3C/svg%3E");
    }
    &.pdf {
      background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='81' height='81'%3E%3Cpath d='M136.533 0a49.12 49.12 0 0 0-35.84 15.36C91.307 25.6 85.333 38.4 85.333 51.2v921.6a49.12 49.12 0 0 0 15.36 35.84 50.547 50.547 0 0 0 35.84 15.36h750.933a49.12 49.12 0 0 0 35.84-15.36 50.547 50.547 0 0 0 15.36-35.84V290.133L648.533 0z' fill='%23FF5562'/%3E%3Cpath d='M938.666 290.133H699.733a52.493 52.493 0 0 1-51.2-51.2V0z' fill='%23FFBBC0'/%3E%3Cpath d='M708.266 865.333c-53.76 0-101.6-92.213-127.146-152-42.667-17.92-89.6-34.133-134.827-45.226-40.106 26.56-107.52 65.76-159.626 65.76-32.427 0-55.467-16.214-64-44.374-6.827-23.04-.854-39.253 5.973-47.786q20.48-28.16 84.48-28.16c34.133 0 77.653 5.973 126.293 17.92a762.026 762.026 0 0 0 91.307-75.094c-12.8-59.733-26.453-156.16 8.533-200.533 17.067-21.333 43.52-28.16 75.094-18.773 34.986 10.24 47.786 31.573 52 47.786 14.506 58.027-52 136.534-97.334 182.667 10.24 40.107 23.04 81.92 39.254 120.32 65.066 28.96 141.813 71.627 150.4 118.56 3.413 16.213-1.707 31.573-14.507 44.373-11.094 9.333-23.04 14.507-35.84 14.507zm-79.36-129.706C661.334 801.333 692 832 708.267 832c2.56 0 5.974-.853 11.094-5.12 5.973-5.973 5.973-10.24 5.12-13.653-3.414-17.067-30.667-45.227-95.573-77.654zm-315.733-87.894c-41.813 0-53.76 10.24-57.173 14.507-.853 1.707-4.267 5.973-.853 17.92 2.56 10.24 9.333 20.48 31.573 20.48 27.307 0 66.56-15.36 112.64-42.667-33.333-6.826-62.293-10.24-86.187-10.24zm168.96-5.12a921.586 921.586 0 0 1 81.92 27.307c-9.333-24.747-17.066-50.347-23.893-75.093-18.773 16.213-38.4 32.426-58.027 47.786zM588 366.933c-9.333 0-16.213 3.414-22.187 10.24-17.92 22.187-19.626 78.507-5.973 150.187 52-55.467 80.213-106.667 73.333-133.973-.853-4.267-4.266-16.214-28.16-23.04A46.413 46.413 0 0 0 588 366.933z' fill='%23FFF'/%3E%3C/svg%3E");
    }
    &.zip {
      background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='81' height='81'%3E%3Cpath d='M61.156 685.511h910.222V921.6c0 28.444-24.178 52.622-52.622 52.622H113.778c-28.445 0-52.622-24.178-52.622-52.622V685.511z' fill='%2389D543'/%3E%3Cpath d='M61.156 352.711h910.222v332.8H61.156z' fill='%23FA6A68'/%3E%3Cpath d='M113.778 64h804.978c28.444 0 52.622 24.178 52.622 52.622v236.09H61.156v-236.09C61.156 88.178 85.333 64 113.778 64z' fill='%2360CEF8'/%3E%3Cpath d='M391.111 64H652.8v910.222H391.111z' fill='%23FDB84B'/%3E%3Cpath d='M760.889 442.311v-28.444H270.222v193.422H760.89V442.31zm-35.556 8.533v122.312H305.778V450.844h419.555z' fill='%23FFF'/%3E%3C/svg%3E");
    }
    &.audio {
      background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Cpath d='M136.533 0c-12.8 0-26.453 5.12-35.84 15.36-9.386 10.24-15.36 23.04-15.36 35.84v921.6c0 12.8 5.12 26.453 15.36 35.84 10.24 10.24 23.04 15.36 35.84 15.36h750.934c12.8 0 26.453-5.12 35.84-15.36 10.24-10.24 15.36-23.04 15.36-35.84V298.667L640 0H136.533z' fill='%2348CFAD'/%3E%3Cpath d='M938.667 298.667H692.693c-13.184 0-27.221-5.291-36.864-15.787A50.56 50.56 0 0 1 640 245.93V0l298.667 298.667z' fill='%237FEFD3'/%3E%3Cpath d='M682.581 531.925c-14.506-32.682-44.97-46.805-72.533-50.602-27.179-3.84-51.67 1.962-69.76 5.888v250.88c1.92 36.522-19.072 75.69-56.32 98.261-49.493 29.995-108.97 19.2-132.779-24.15-23.808-43.349-2.986-102.826 46.507-132.863 37.973-23.04 81.75-22.059 110.848-.854V477.952l-.17-.085.17-.47v-76.544c0-9.216 7.125-16.853 15.915-16.853a15.787 15.787 0 0 1 14.25 9.6c25.003 22.827 48.64 31.232 74.966 41.899 20.906 8.533 39.594 21.546 51.37 39.381 12.032 17.493 17.152 39.68 17.622 57.173l-.086-.128z' fill='%23FFF'/%3E%3C/svg%3E");
    }
    &.video {
      background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='81' height='81'%3E%3Cpath d='M140.109 3.738c-12.621 0-26.112 5.094-35.354 15.283C95.488 29.21 89.6 41.958 89.6 54.707v917.555c0 12.75 5.043 26.368 15.155 35.687 10.087 10.189 22.733 15.309 35.328 15.309H880.82c12.621 0 26.087-5.12 35.328-15.31 10.112-10.188 15.155-22.937 15.155-35.686v-679.68L645.12 3.738H140.109z' fill='%238286EE'/%3E%3Cpath d='M931.328 292.608h-235.7c-12.62 0-26.086-5.12-35.327-15.309a49.126 49.126 0 0 1-15.155-35.686V3.738l286.182 288.87z' fill='%23AFB2FD'/%3E%3Cpath d='M537.523 744.346H295.526c-24.985 0-45.414-22.887-45.414-50.893V514.099c0-27.98 20.429-50.893 45.414-50.893h241.997c24.96 0 45.389 22.912 45.389 50.893v179.354c0 28.006-20.429 50.893-45.389 50.893m173.952-12.16l-97.792-81.46a21.683 21.683 0 0 1-7.782-16.665V554.88a21.669 21.669 0 0 1 7.782-16.666l97.792-81.459c13.952-11.648 35.047-1.613 35.047 16.64V715.52c0 18.278-21.095 28.314-35.072 16.666' fill='%23FFF'/%3E%3C/svg%3E");
    }
  }
  /* 上传项外部类,用于撑开布局,显示角标按钮 */
  .el-upload-list__item-wrapper {
    position: relative;
    display: inline-block;
    margin-right: 10px;
  }
  /* 自定义角标删除按钮样式 */
  .el-upload-list__item {
    margin-right: 0 !important;
  }
  /* 自定义角标删除按钮样式 */
  .corner-close {
    position: absolute;
    top: 0;
    right: 0;
    transform: translateX(50%) translateY(-50%);
    height: 30px;
    width: 30px;
    min-width: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(lighten($red, 15%), 0.5);
    color: #fff;
    border-radius: 50%;
    z-index: 20;
    font-size: 16px;
    cursor: pointer;
    &:hover {
      background-color: $red;
    }
  }
  /* 修改卡片样式 */
  .el-upload--picture-card {
    line-height: 1.5;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  /* 修改图片按钮样式 */
  .el-upload-list--picture-card .el-upload-list__item-actions {
    display: flex;
    align-items: center;
    justify-content: space-around;
    .el-upload-list__item-preview,
    .el-upload-list__item-delete {
      display: inline-flex;
      align-items: center;
      justify-content: center;
    }
    span + span {
      margin-left: 0;
    }
    &::after {
      display: none;
    }
    .block-preview,
    .block-download {
      height: 100%;
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
    }
  }
  /* 修改拖拽上传的默认样式 */
  .el-upload-dragger {
    height: 100%;
    width: 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background-color: transparent;
    &.is-dragover {
      border-color: transparent;
    }
  }
  /* 修改图片上传组件卡片模式默认样式 */
  &.mini {
    .el-upload--picture-card,
    .el-upload-list--picture-card .el-upload-list__item {
      height: 60px;
      width: 60px;
    }
    .el-upload--picture-card i {
      font-size: 20px;
    }
    .corner-close {
      height: 20px;
      width: 20px;
      min-width: 20px;
      font-size: 12px;
    }
  }
  &.small {
    .el-upload--picture-card,
    .el-upload-list--picture-card .el-upload-list__item {
      height: 100px;
      width: 100px;
    }
    .corner-close {
      height: 24px;
      width: 24px;
      min-width: 24px;
      font-size: 14px;
    }
  }
  /* 图片缩略图 */
  .el-upload-list--picture-card .el-upload-list__item-thumbnail {
    object-fit: cover;
  }
}
</style>