drag-file-upload.vue 4.17 KB
<template>
  <div v-if="show">
    <image-purview
      v-if="uploadList[0]"
      :status="uploadList[0].status"
      :url="uploadList[0].url"
      :progress="uploadList[0].showProgress"
      :percentage="uploadList[0].percentage"
      :remove="true"
      @remove-image="handleRemove"
    ></image-purview>

    <div v-show="!uploadList[0]" class="upload-box">
      <Upload
        ref="upload"
        :show-upload-list="false"
        :data="{ bucket: bucket }"
        :on-success="handleSuccess"
        :on-error="handleError"
        :default-file-list="defaultList"
        :format="format"
        :max-size="maxSize"
        :on-format-error="handleFormatError"
        :on-exceeded-size="handleMaxSize"
        action="/Api/upload/image"
      >
        <Icon type="ios-cloud-upload-outline" :title="uploadIconTitle"></Icon>
      </Upload>
      <Icon v-if="skn" type="ios-cloud-outline" title="调用图片服务" @click.native="browseOnline"></Icon>
    </div>

    <modal-skn-image v-model="sknImageModel" :skn="skn" @selected="selected"></modal-skn-image>
  </div>
</template>
<script>
import _ from 'lodash';

export default {
  name: 'DragFileUpload',
  props: {
    id: {
      type: Object,
    },
    defaultFile: {
      type: String,
    },
    skn: {
      type: [String, Number],
    },
    bucket: {
      type: String,
      default() {
        return 'goodsimg';
      },
    },
    maxSize: {
      type: Number,
      default: 2048,
    },
    formatMaxSizeMsg: {
      type: Function,
      default() {
        return file => '文件 ' + file.name + ' 太大,不能超过 2M。';
      },
    },
    format: {
      type: Array,
      default() {
        return ['jpg', 'jpeg', 'png'];
      },
    },
    formatErrMsg: {
      type: Function,
      default() {
        return file => `文件 ${file.name} 格式不正确,请上传 jpg 或 png 格式的图片。`;
      },
    },
    uploadIconTitle: {
      type: String,
      default: '上传图片',
    },
  },
  data() {
    const _this = this;

    return {
      imgUrl: '',
      visible: false,
      show: true,
      sknImageModel: false,
      uploadList: [],
      defaultList: _this.defaultFile ? [{ url: _this.defaultFile }] : [],
    };
  },
  watch: {
    defaultFile(newValue) {
      if (newValue) {
        this.defaultList = [{ url: newValue }];
      }
    },
  },
  mounted() {
    this.uploadList = this.$refs.upload.fileList;
  },
  methods: {
    handleView(url) {
      this.imgUrl = url;
      this.visible = true;
    },
    handleRemove() {
      const file = this.uploadList[0];
      const files = this.$refs.upload.fileList;

      this.$refs.upload.fileList.splice(files.indexOf(file), 1);
      this.uploadList = this.$refs.upload.fileList;
      this.$emit('remove', this.id);
    },
    handleSuccess(response, file, files) {
      if (_.get(response, 'data.imagesList.length', 0)) {
        file.url = response.data.imagesList[0];
      }

      this.uploadList = files;
      this.$emit('success', this.id, file);
    },
    handleError() {
      this.$Notice.error('上传失败');
      this.$emit('error', this.id);
    },
    handleFormatError(file) {
      this.$Notice.warning({
        title: '文件格式不正确',
        desc: this.formatErrMsg(file),
      });
    },
    handleMaxSize(file) {
      this.$Notice.warning({
        title: '超出文件大小限制',
        desc: this.formatMaxSizeMsg(file),
      });
    },
    browseOnline() {
      this.sknImageModel = true;
    },
    selected(url) {
      this.uploadList = this.defaultList = [{ url }];
      this.$emit('success', this.id, { url });
    },
  },
};
</script>
<style lang="scss">
.upload-box {
  width: 100px;
  height: 100px;
  background: #fff;
  border: 1px dashed #dddee1;
  border-radius: 4px;
  text-align: center;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: border-color 0.2s ease;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;

  &:hover {
    border-color: #2d8cf0;
  }

  .ivu-upload {
    height: 30px;
  }

  .ivu-icon {
    font-size: 30px;
    margin: 0 2px;
    color: #000;
    transition: color 0.2s ease;

    &:hover {
      color: #2d8cf0;
    }
  }
}
</style>