upload-image.vue 4.53 KB
<template>
  <view class="upload-image" hover-class="active" hover-start-time="20" hover-stay-time="70" @click="handleUpload">
    <template v-if="safeValue">
      <image class="upload-image__image" :src="safeValue" mode="aspectFill" @click="previewImage"></image>
      <view v-if="!readOnly" class="upload-image__close" @click.stop="removeImage">
				<u-icon name="close"></u-icon>
      </view>
    </template>
    <template v-else>
      <slot v-if="$slots.default || $slots.$default"></slot>
      <template v-else>
        <template v-if="readOnly">
					<view class="upload-image__icon">
						<u-icon name="photo"></u-icon>
					</view>
        </template>
        <template v-else>
					<view class="upload-image__icon">
						<u-icon name="camera"></u-icon>
					</view>
          <text class="upload-image__text">{{ text }}</text>
        </template>
      </template>
    </template>
  </view>
</template>

<script>
import cache from '@/utils/cache';
import config from '@/config';

const url = config.uploadHost;
const userInfo = cache.get('USERINFO')
const header = {
  'Authorization': 'Bearer ' + userInfo?.accessToken
};

export default {
  name: 'upload-image',
  props: {
    value: String,
    icon: {
      type: String,
      default: 'photocamera'
    },
    text: {
      type: String,
      default: '点击上传'
    },
    readOnly: Boolean,
  },
  computed: {
    safeValue() {
      if (this.value) {
        const imgList = this.value.replace(/^(\s|\,)+|(\s|\,)+$/g, '').split(',') || [];
        return imgList.length > 0 ? imgList[0] : '';
      }
      return '';
    }
  },
  methods: {
    // 预览图片
    previewImage() {
      uni.previewImage({ urls: this.value.replace(/^(\s|\,)+|(\s|\,)+$/g, '').split(',') });
    },
    // 删除图片
    removeImage() {
      uni.showModal({
        title: '提示',
        content: '确定删除这张图片吗?',
        // #ifdef MP-DINGTALK
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        // #endif
        success: (res) => {
          if (res.confirm) {
            this.$emit('input', '');
          }
        }
      });
    },
    // 上传图片
    handleUpload() {
      if (!this.value && !this.readOnly) {
        uni.chooseImage({
          count: 1,
          success: (res) => {
            const tempFilePaths = res.tempFilePaths || [];
            if (tempFilePaths.length > 0) {
              uni.showLoading({ title: '上传中...' });
              uni.uploadFile({
                url,
                header,
                filePath: tempFilePaths[0],
                name: 'file',
                formData: {
                  module: 'dispatch-ma',
                  category: 'opr'
                },
                success: (response) => {
                  uni.hideLoading();
                  const { statusCode } = response;
                  const data = JSON.parse(response.data.replace(/\ufeff/g, '') || '{}');
                  const result = data.result || [];
                  if (statusCode == 200) {
                    this.$emit('input', result[0]);
                  } else {
                    if (result[0]) {
                      this.$emit('input', result[0]);
                    } else {
                      setTimeout(() => {
                        uni.showToast({ title: data.message || response.errMsg || '上传失败', icon: 'none' });
                      }, 1500);
                    }
                  }
                },
                fail: () => {
                  uni.hideLoading();
                  setTimeout(() => {
                    uni.showToast({ title: '系统异常', icon: 'none' });
                  }, 1500);
                }
              });
            }
          }
        });
      }
    }
  }
};
</script>

<style lang="scss">
.upload-image {
  height: 300upx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  color: rgba(151, 151, 151, 0.5);
  &.active {
    background-color: $color-field;
  }
  &__image {
    width: 100%;
    height: 100%;
  }
  &__close {
    position: absolute;
    top: 0;
    right: 0;
    transform: translateX(50%) translateY(-50%);
    background-color: $color-red;
    border-radius: 50%;
    padding: 5upx;
    height: 50upx;
    width: 50upx;
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    color: $color-white;
    line-height: 1;
  }
  &__icon {
    font-size: 70upx;
    padding-bottom: 10upx;
    line-height: 1;
  }
  &__text {
    line-height: 1;
  }
}
</style>