Newer
Older
KaiFengH5 / src / views / components / uploadFile.vue
@zhangdeliang zhangdeliang on 24 May 5 KB 项目初始化
<template>
  <!-- 公共图片上传 -->
  <div class="uploaderPage">
    <!-- 上传图片 -->
    <van-uploader
      v-model="fileList"
      :after-read="afterRead"
      :max-count="maxCount"
      :max-size="50 * 1024 * 1024"
      @oversize="onOversize"
      :accept="acceptFormat"
      :disabled="isDisabled"
      :before-delete="deleBrfore"
      @delete="deleteFile"
    >
    </van-uploader>
    <div v-if="acceptFormat == 'video/*'">
      <!-- 显示视频列表 -->
      <div v-if="fileList.length > 0">
        <p v-for="item in fileList" :key="item.fileNo" class="van-ellipsis blueFont" @click="checkVideo(item.url)">
          {{ item.file ? item.file.name : item.name }}
        </p>
      </div>
      <!-- 查看视频弹窗 -->
      <van-popup v-model:show="showVideo" class="uploadVideo">
        <video v-if="showVideo" style="width: 100vw; height: auto" title="视频" :src="videoUrl" :autoPlay="true" />
      </van-popup>
    </div>
  </div>
</template>

<script setup name="uploaderPage">
import { fileUpload, fileDelete } from '@/api/publicApi.js';
import { useStore } from '@/pinia/store.js';
import { getCurrentInstance } from 'vue';

const props = defineProps({
  //最大上传数
  maxCount: {
    type: Number,
    default: 1,
  },
  //保存的文件数组
  saveFileArr: {
    type: Array,
    default: () => [],
  },
  // 文件格式
  acceptFormat: {
    type: String,
    default: 'image/*', //  video/*
  },
  // 是否禁用文件上传
  isDisabled: {
    type: Boolean,
    default: false,
  },
});
const pinias = useStore();
const { proxy } = getCurrentInstance();
const emit = defineEmits();
const fileList = ref([]); //文件列表
const maxCount = props.maxCount; //最大上传数
const acceptFormat = props.acceptFormat; //文件格式
console.log(acceptFormat);
const showVideo = ref(false);
const videoUrl = ref('');

// 查看视频弹窗
function checkVideo(url) {
  videoUrl.value = url;
  showVideo.value = true;
}

// 上传图片2
const afterRead = (fileOBJ) => {
  fileOBJ.status = 'uploading';
  fileOBJ.message = '上传中...';
  let imgFile = null;
  if (fileOBJ.file.size / 1024 > 500 && fileOBJ.file.type.includes('image')) {
    blobToBase64(fileOBJ.file, fileOBJ.file.name).then((res) => {
      imgFile = res;
    });
  } else {
    imgFile = fileOBJ.file;
  }
  // 配置表单
  let formData = new FormData();
  let config = {
    headers: { 'Content-Type': 'multipart/form-data' },
  };
  formData.append('files', imgFile);
  fileUpload(formData, config).then((res) => {
    if (res && res.data.code == 1) {
      fileOBJ.status = 'done';
      fileOBJ.message = '上传成功';
      // 业务参数赋值
      fileOBJ.url = res.data.data[0].fileCloudStorageKey;
      fileOBJ.fileNo = res.data.data[0].fileNo;
      fileOBJ.fileCloundInfo = res.data.data[0];
      console.log(fileList.value);
      emit('update:saveFileArr', fileList.value); //绑定的传值赋值
    } else {
      fileOBJ.status = 'failed';
      fileOBJ.message = '上传失败';
      console.log(fileList.value);
    }
  });
};
// 图片删除
const deleBrfore = async (file) => {
  return true;
};

const deleteFile = () => {
  emit('update:saveFileArr', fileList.value);
};
const blobToBase64 = async (blob, fileName) => {
  const reader = await new FileReader(); // 实例化一个reader文件
  await reader.readAsDataURL(blob); // 添加二进制文件
  return new Promise((resolve, reject) => {
    reader.onload = async (event) => {
      const base64 = await event.target.result; // 获取到它的base64文件
      const scale = 0.6; // 设置缩放比例 (0-1)
      let file = await compressImg(base64, scale, fileName);
      resolve(file);
    };
  });
};
// 压缩大小
const compressImg = (base64, scale, fileName) => {
  // 处理缩放,转换格式
  // 用canvas来压缩
  const img = new Image();
  img.src = base64;
  return new Promise((resolve, reject) => {
    img.onload = async () => {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      canvas.setAttribute('width', img.width * scale);
      canvas.setAttribute('height', img.height * scale);
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
      // 转成base64 文件
      base64 = canvas.toDataURL('image/jpeg', 0.8); //0到1之间的取值,主要用来选定图片的质量,默认值是0.92,超出范围也会选择默认值
      const arr = base64.split(',');
      const mime = arr[0].match(/:(.*?);/)[1];
      const bytes = atob(arr[1]);
      const bytesLength = bytes.length;
      const u8arr = new Uint8Array(bytesLength);
      for (let i = 0; i < bytes.length; i++) {
        u8arr[i] = bytes.charCodeAt(i);
      }
      const file = await new File([u8arr], fileName, { type: mime });
      resolve(file);
    };
  });
};
function onOversize() {
  proxy.showFailToast('上传的文件最大为50M');
}
onMounted(() => {
  console.log('修改时图片回显--', props.saveFileArr);
  // 修改时图片回显
  fileList.value = [];
  // debugger;
  props.saveFileArr.map((item) => {
    let params = {
      fileNo: item.fileNo,
      name: item.name,
      status: 'success',
      url: item.url,
    };
    fileList.value.push(params);
    console.log('回显数据', fileList.value);
  });
});
onBeforeUnmount(() => {
  fileList.value = [];
});
</script>
<style lang="less">
/* 添加这段样式后,Primary Button 会变成红色 */
:root:root {
  --van-uploader-size: 150px;
}
.van-uploader__file-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.uploaderPage {
  width: 100%;
  .blueFont {
    color: #0c60e1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}
</style>