【uniapp】上传视频录像

<template>
  <view class="video">
    <view class="tips">{{ tips }}</view>
    <view class="file">
      <view class="item" v-for="v in fileList">
        <image
          v-if="type.image.includes(v.type)"
          class="img"
          @click="toPreview(v)"
          :src="v.url"
          :style="{ ...imageStyle }"
        ></image>
        <text
          v-else
          class="iconfont"
          :class="filterIcon(v)"
          @click="toPreview(v)"
        ></text>
        <text class="iconfont icon-shanchu del" @click="del(v)"></text>
      </view>
      <view
        class="button"
        hover-class="feedback-hover"
        @click="clickUpload"
        v-if="fileList.length < maxCount"
      >
        <text class="iconfont icon-jia"></text>
      </view>
    </view>
  </view>
</template>
<script lang="ts" setup>
import { reactive, toRefs } from 'vue';
import TnButton from '@tuniao/tnui-vue3-uniapp/components/button/src/button.vue';
import PerViewFile from '../previewFile/index.vue';
import { baseUrl, api } from '@/http/config';
import type { FileType } from './index.d';
const emits = defineEmits(['clickUpload']);
const defaultProps = defineProps({
  action: {
    type: String,
    default: 'common/upload',
  },
  tips: {
    type: String,
    default: '请上传录像',
  },
  imageStyle: {
    type: Object,
    default: {},
  },
  maxSize: {
    type: Number,
    default: 20,
  },
  maxCount: {
    type: Number,
    default: 1,
  },
});
const state = reactive({
  fileList: <any>[],
  type: {
    image: ['jpg', 'jpeg', 'png', 'gif'],
    video: [
      'mp4',
      'avi',
      'rmvb',
      'rm',
      'asf',
      'divx',
      'mpg',
      'mpeg',
      'mpe',
      'wmv',
      'mkv',
      'vob',
    ],
    audio: ['mp3', 'wav', 'wma', 'ogg', 'ape', 'flac'],
    pdf: ['pdf'],
    word: ['doc', 'docx'],
    excel: ['xls', 'xlsx'],
    ppt: ['ppt', 'pptx'],
  },
});

const uploadFile = (file: any) => {
  uni.showLoading({ title: '上传中', mask: true });
  // 以文件流的方式上传文件
  uni.uploadFile({
    url: baseUrl + api + defaultProps.action,
    filePath: file.tempFilePath || '',
    name: 'file',
    formData: {},
    header: {
      'Content-Type': 'multipart/form-data',
      token: uni.getStorageSync('token'),
    },
    success: async (uploadFileRes) => {
      uni.hideLoading();
      // console.log('uploadFileRes>>', file);
      if (uploadFileRes && uploadFileRes.errMsg == 'uploadFile:ok') {
        if (uploadFileRes?.statusCode === 200) {
          const item =
            uploadFileRes && uploadFileRes.data
              ? JSON.parse(uploadFileRes.data) || {}
              : {};
          state.fileList.push({
            type: file.tempFilePath.split('.').pop(),
            url: file.tempFilePath,
            id: item.data,
          });
          emits('clickUpload', state.fileList);
        }
      }
    },
    fail: (err) => {
      uni.hideLoading();
      console.log('图片上传接口调用失败', err);
    },
  });
};
const clickUpload = () => {
  uni.chooseVideo({
    count: 1,
    sourceType: ['camera', 'album'],
    maxDuration: 30,
    mediaType: ['video'],
    success: (res: any) => {
      if (res.size / 1024 / 1024 > defaultProps.maxSize) {
        return uni.showToast({
          icon: 'none',
          title: `只能上传${defaultProps.maxSize}M以内 请重新上传!`,
        });
      }
      uploadFile(res);
    },
  });
};
const filterIcon = (v: FileType) => {
  const { video, audio, pdf, word, excel, ppt } = state.type;
  // if (image.includes(v.type)) {
  //   return 'icon-tupian';
  // } else
  if (video.includes(v.type)) {
    return 'icon-shipin2';
  } else if (audio.includes(v.type)) {
    return 'icon-yinpin1';
  } else if (pdf.includes(v.type)) {
    return 'icon-pdf';
  } else if (word.includes(v.type)) {
    return 'icon-word';
  } else if (excel.includes(v.type)) {
    return 'icon-excel';
  } else if (ppt.includes(v.type)) {
    return 'icon-ppt';
  }
};
const toPreview = (v: FileType) => {
  const { image, video, audio, pdf, word, excel, ppt } = state.type;
  if (image.includes(v.type)) {
    uni.previewImage({
      urls: [v.url],
    });
  } else if (video.includes(v.type)) {
    uni.navigateTo({
      url: `/pages/components/video/index?params=${JSON.stringify(v)}`,
    });
  } else if (audio.includes(v.type)) {
    uni.navigateTo({
      url: `/pages/components/audio/index?params=${JSON.stringify(v)}`,
    });
  } else if (
    pdf.includes(v.type) ||
    word.includes(v.type) ||
    excel.includes(v.type) ||
    ppt.includes(v.type)
  ) {
    uni.showLoading({
      title: '加载中',
    });
    uni.downloadFile({
      url: v.url, //后端返回的文件地址
      success: function (res) {
        if (res.statusCode === 200) {
          uni.openDocument({
            filePath: res.tempFilePath,
            success: function (res) {
              console.log(res, '打开文件成功');
            },
            fail: (err) => {
              uni.showToast({
                title: '打开文件失败请重试',
                icon: 'none',
              });
            },
          });
        } else {
          uni.showToast({
            title: '打开文件失败请重试',
            icon: 'none',
          });
        }
        uni.hideLoading();
      },
      fail: (err) => {
        uni.hideLoading();
        uni.showToast({
          title: '加载失败请重试',
          icon: 'none',
        });
      },
    });
  }
};
const del = (v: FileType) => {
  const index = state.fileList.findIndex((item: any) => item.url === v.url);
  state.fileList.splice(index, 1);
  emits('clickUpload', state.fileList);
};
const { fileList, type } = toRefs(state);
</script>
<style lang="scss" scoped>
.tips {
  font-size: 14px;
  color: #bab8b8;
  margin-bottom: 20px;
}
.file {
  display: flex;
  flex-wrap: wrap;
  .item {
    width: 160rpx;
    height: 160rpx;
    border-radius: 4rpx;
    margin-bottom: 230rpx;
    border: 2rpx dashed #999;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-right: 20rpx;
    .iconfont {
      font-size: 128rpx;
    }
    .del {
      position: absolute;
      top: -6rpx;
      right: -8rpx;
      font-size: 40rpx;
      color: red;
    }
  }
}
.button {
  width: 160rpx;
  height: 160rpx;
  border-radius: 4rpx;
  border: 2rpx dashed #999;
  display: flex;
  justify-content: center;
  align-items: center;
  .iconfont {
    font-size: 40rpx;
    color: #999;
  }
}
</style>
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值