##
最近开发 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>