uniapp实现图片上传,图片预览,录音及录音文件上传功能


##

最近开发 uniapp 小程序,遇到了项目上的开发任务,于是就记录在此,作为经验总结

图片的上传和预览

上传:uni.chooseImage(OBJECT)
预览:uni.previewImage(OBJECT)

录音上传

根据 uniapp 官网提供的 uni.uploadFile(OBJECT) API 来实现录音文件上传功能,具体 OBJECT 参数说明详见链接: uni.uploadFile(OBJECT).

录音

主要根据 uniapp 官网提供的 uni.getRecorderManager() API 来实现录音功能,具体代码详见 uniapp 官网链接: uni.getRecorderManager().
注:APP 端暂不支持暂停和继续录音功能

录音上传

根据 uniapp 官网提供的 uni.uploadFile(OBJECT) API 来实现录音文件上传功能,具体 OBJECT 参数说明详见链接: uni.uploadFile(OBJECT).

直接上代码
<template>
  <view class="card">
    <view class="card_one">
      <view class="header">
        <view class="header1">
          <image
            :src="imgHttps + imgUrl"
            @click="imgPreview(imgUrl, imgHttps)"
          ></image>
          <img :src="imgUrl" alt="" />
        </view>
      </view>
      <view class="bottom">
        <view class="bottom-top" @click="addImg">
          <view> <i class="za za-addImg big1"></i> </view>
          <text>添加图片</text>
        </view>
        <view
          class="bottom-top"
          @touchstart="startRecord"
          @touchend="endRecord"
        >
          <view> <i class="za za-record big"></i> </view>
          <text>点击录音</text>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import { upoadJKUrl, imgHttps } from "@config"; //域名地址信息

const recorderManager = uni.getRecorderManager();

const innerAudioContext = uni.createInnerAudioContext();

innerAudioContext.autoplay = true;

export default {
  name: "micro-class",
  data() {
    return {
      upoadJKUrl,
      imgHttps,
      urlArr: [], //上传图片资源集合
      srcs: [], //用于图片预览
      voicePath: "",
      voicePathArr: [], //上传音频资源集合
      imgUrl: "a.jpg",
    };
  },
  onLoad(data) {
    let self = this;
    recorderManager.onStop(function (res) {
      // //console.log("录音停止了" + JSON.stringify(res)); //返回录音的临时保存地址, 可用于后面的播放
      self.voicePath = res.tempFilePath;
      self.voicePath && self.uploadRecord(self.voicePath); //有录音上传服务器
    });
  },
  methods: {
    startRecord() {
      this.timer = setInterval(() => {
        this.intervalTime += 0.5;
        if (this.intervalTime >= 0.5 && !this.isRecord) {
          this.isRecord = true;
          this.intervalTime = 0;
          recorderManager.start({
            format: "mp3",
          });
        }
      }, 500);
    },

    endRecord() {
      if (this.intervalTime <= 0.5) {
        this.$store.dispatch("showToast", { title: "录音太短了!" });
        return;
      }
      clearInterval(this.timer);
      if (this.isRecord) {
        setTimeout(() => {
          recorderManager.stop();

          this.isRecord = false;
        }, 500); //延迟小段时间停止录音, 更好的体验
      }
    },
    //添加图片
    addImg() {
      uni.chooseImage({
        count: 9,
        success: (res) => {
          let tempFilePaths = res.tempFilePaths;
          tempFilePaths.forEach((item) => {
            uni.uploadFile({
              url: `${this.upoadJKUrl}/across/file/upload`, //仅为示例,非真实的接口地址
              fileType: "image", //ZFB必填,不然报错
              headers: {
                // 修改请求头Content-Type类型 此类型为文件上传
                "Content-Type": "multipart/form-data",
              },
              formData: {
                type: 1, //后端接口所需要的数据
              },
              filePath: item, //这个就是我们上面拍照返回或者先中照片返回的数组
              name: "file",
              success: (uploadFileRes) => {
                let objData = JSON.parse(uploadFileRes.data); //由JSON字符串转换为JSON对象
                this.urlArr.push(this.imgHttps + objData.data.url);
                //去数组第一个
                if (this.urlArr.length > 0) {
                  this.imgUrl = this.urlArr[0];
                }
                this.$store.dispatch("showModal", {
                  content: "图片添加成功",
                });
              },
            });
          });
        },
      });
    },
    // 图片预览
    imgPreview(img, imgHttps) {
      if (img.src == null || img.src == "" || img.src == undefined) {
        this.srcs.push(`${imgHttps}${img.url}`);
      } else {
        this.srcs.push(`${imgHttps}${img.src}`);
      }
      uni.previewImage({
        indicator: "number",
        loop: true,
        urls: this.srcs,
      });
      this.srcs = [];
    },
    //录音文件上传后端服务器
    uploadRecord(tempFilePath) {
      // tempFilePath为RecorderManager对象返回的录音文件临时地址
      //console.log("录音文件上传后端服务器,,,,,", tempFilePath);
      const uploadTask = uni.uploadFile({
        url: `${this.upoadJKUrl}/across/file/upload`, //后端接口地址
        filePath: tempFilePath, //录音结束后返回的临时路径
        name: "file",
        header: {
          "content-type": "multipart/form-data",
          // token: uni.getStorageSync("token"),
        },
        formData: {
          type: 1,
        },
        success: (res) => {
          let objData = JSON.parse(res.data); //由JSON字符串转换为JSON对象
          this.voicePathArr.push(this.imgHttps + objData.data.url);
          this.$store.dispatch("showModal", {
            content: "录音上传成功",
          });
        },
        fail: (res) => {
          this.$store.dispatch("showModal", {
            content: "录音上传失败",
          });
        },
      });
    },
  },
};
</script>

<style scoped lang="scss">
.card {
  height: 100vh;
  display: flex;
  flex-direction: column;

  background-color: #eee;
  box-sizing: border-box;

  .card_one {
    border-radius: 2%;
    padding: 10px 0px 10px;

    .top {
      text-align: center;
      font-weight: 600;
      height: 72rpx;
      line-height: 50rpx;
      box-shadow: 4px 4px 15px #eee;
    }

    .header {
      box-sizing: border-box;
      height: 434rpx;
      margin-bottom: 20rpx;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: rgba(215, 215, 215, 1);
      .header1 {
        height: 180px;
        width: 359px;
        background-color: aqua;
        img {
          width: 100%;
          height: 100%;
          object-fit: cover; // 不变形、铺满
        }
      }
    }
    .bottom {
      display: flex;
      height: 150rpx;
      line-height: 80rpx;
      justify-content: space-evenly;
      .bottom-top {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        .big {
          font-size: 80rpx;
        }
        .big1 {
          font-size: 90rpx;
        }
      }
    }
    .btn {
      padding: 20rpx 40rpx 0;
    }
  }
}
</style>


文章作者: BiLiang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 BiLiang !
评论
  目录