|
|
@@ -21,8 +21,26 @@
|
|
|
</view>
|
|
|
<view class="content">
|
|
|
<view class="title">承诺录音</view>
|
|
|
- <view class="tip">请上传 大小不超过 10MB 格式为 mp3/wav/wma 的文件</view>
|
|
|
- <Upload :accept="audio" :maxCount="1" @fileList="onUpload($event, 'recording')" :fileList="recording">
|
|
|
+ <view class="tip">请上传 大小不超过 10MB 格式为 mp3/wav/wma/m4a 的文件</view>
|
|
|
+ <!-- <view class="recorder-buttons">
|
|
|
+ <button class="record-btn" :class="{ recording: isRecording }" @click="handleRecord"
|
|
|
+ :disabled="isRecording">
|
|
|
+ {{ isRecording ? '录音中...' : '开始录音' }}
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <button class="stop-btn" @click="handleStop" :disabled="!isRecording">
|
|
|
+ 停止录音
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <button class="play-btn" @click="handlePlay" :disabled="!localId">
|
|
|
+ 播放录音
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view v-if="audioDuration" class="audio-info">
|
|
|
+ 录音时长: {{ audioDuration }}秒
|
|
|
+ </view> -->
|
|
|
+ <!-- <Upload accept="audio" :maxCount="1" @fileList="onUpload($event, 'recording')" :fileList="recording">
|
|
|
<view class="upload-block" slot="content">
|
|
|
<view class="icon-bg">
|
|
|
<image src="/static/login/cameraIcon.png" mode="widthFix"
|
|
|
@@ -35,32 +53,13 @@
|
|
|
</view>
|
|
|
|
|
|
|
|
|
- </Upload>
|
|
|
+ </Upload> -->
|
|
|
</view>
|
|
|
<view class="content">
|
|
|
<view class="title">承诺录像</view>
|
|
|
<view class="tip">请上传 大小不超过 50MB 格式为 mp4/mov/mkv/wmv 的文件</view>
|
|
|
- <view v-if="videoRecording.length > 0">
|
|
|
- <uni-icons class="icon iconfont icon-cuo" type="trash-filled" size="20"
|
|
|
- @tap="delectVideo"></uni-icons>
|
|
|
- <video ref="myVideo" :src="videoRecording[0].mediaUrl" class="video-container" controls></video>
|
|
|
- </view>
|
|
|
- <Upload v-else :accept="'video'" :maxCount="1" @fileList="onUpload($event, 'videoRecording')"
|
|
|
- :fileList="videoRecording">
|
|
|
- <view class="upload-block" slot="content">
|
|
|
- <view class="icon-bg">
|
|
|
- <image src="/static/login/cameraIcon.png" mode="widthFix"
|
|
|
- style="width: 52rpx;height: 52rpx;">
|
|
|
- </image>
|
|
|
- <view style="font-weight: 400;font-size: 26rpx;color: #C9CDD4;margin-top: -13rpx;">上传</view>
|
|
|
-
|
|
|
- </view>
|
|
|
-
|
|
|
- </view>
|
|
|
-
|
|
|
-
|
|
|
- </Upload>
|
|
|
- <!-- <view class="media-area">
|
|
|
+
|
|
|
+ <view class="media-area">
|
|
|
<view v-if="formData.videoUrl">
|
|
|
<uni-icons class="icon iconfont icon-cuo" type="trash-filled" size="20"
|
|
|
@tap="delectVideo"></uni-icons>
|
|
|
@@ -76,12 +75,15 @@
|
|
|
count: 9,
|
|
|
size: 2,
|
|
|
}" :videoFromData="{
|
|
|
- count: 1,
|
|
|
- size: 50,
|
|
|
- }" :maxVideo="1" :fileType="mediaType" addImg="/static/discover/ic_upload.png"
|
|
|
- deleteImg="/static/discover/ic_delete.png" @onSuccess="onSuccess"
|
|
|
- @onMediaTypeSelect="selectMediaType" @onError="onCancel"></clUpload>
|
|
|
- </view> -->
|
|
|
+ count: 1,
|
|
|
+ size: 50,
|
|
|
+ }" :maxVideo="1" :fileType="mediaType" addImg="/static/login/cameraIcon.png"
|
|
|
+ deleteImg="/static/login/cameraIcon.png" @onSuccess="onSuccess"
|
|
|
+ @onMediaTypeSelect="selectMediaType" @onError="onCancel">
|
|
|
+
|
|
|
+
|
|
|
+ </clUpload>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
<view class="footer-bar">
|
|
|
@@ -102,13 +104,36 @@
|
|
|
<script>
|
|
|
import clUpload from '@/components/cl-upload/cl-upload/cl-upload.vue'
|
|
|
import Upload from '@/components/upload/index.vue';
|
|
|
+import { initWechatSDKWithRecorder, wechatRecorder } from '@/utils/wechat';
|
|
|
+import { baseUrl } from '@/common/config.js'
|
|
|
|
|
|
export default {
|
|
|
- components: { Upload, clUpload },
|
|
|
+ components: { Upload, clUpload, },
|
|
|
data() {
|
|
|
return {
|
|
|
+ isRecording: false,
|
|
|
+ localId: null,
|
|
|
+ serverId: null,
|
|
|
+ audioDuration: 0,
|
|
|
+
|
|
|
+ headers: {
|
|
|
+ Authorization: `tf: ${uni.getStorageSync('access-token')}`,
|
|
|
+ },
|
|
|
+ uploadApi: baseUrl + '/common/upload', // 默认使用图片上传接口
|
|
|
videoUrl: '',
|
|
|
fileList: [],
|
|
|
+ formData: {
|
|
|
+ title: '',
|
|
|
+ content: '',
|
|
|
+ location: '',
|
|
|
+ address: '',
|
|
|
+ latitude: '',
|
|
|
+ longitude: '',
|
|
|
+ visibleRange: '',
|
|
|
+ videoUrl: '',
|
|
|
+ videoCoverUrl: '',
|
|
|
+ imageUrls: [],
|
|
|
+ },
|
|
|
mediaType: 'all', // 默认为图片模式,上传第一个文件后确定类型
|
|
|
uploadApi: baseUrl + '/common/upload', // 默认使用图片上传接口
|
|
|
fieldName: '',
|
|
|
@@ -117,6 +142,11 @@ export default {
|
|
|
videoRecording: [],
|
|
|
}
|
|
|
},
|
|
|
+ computed: {
|
|
|
+ maxCount() {
|
|
|
+ return this.mediaType === 'video' ? 1 : 9
|
|
|
+ },
|
|
|
+ },
|
|
|
|
|
|
onLoad(query) {
|
|
|
console.log(query)
|
|
|
@@ -128,6 +158,8 @@ export default {
|
|
|
this.recording = fieldVal[1] ? fieldVal[1] : []
|
|
|
this.videoRecording = fieldVal[2] ? fieldVal[2] : []
|
|
|
}
|
|
|
+ // 初始化微信SDK(包含录音功能)
|
|
|
+ this.initRecorder();
|
|
|
|
|
|
console.log(this.commitment, 'query')
|
|
|
console.log(this.recording, 'query')
|
|
|
@@ -139,7 +171,162 @@ export default {
|
|
|
},
|
|
|
onShow() {
|
|
|
},
|
|
|
+ beforeUnmount() {
|
|
|
+ this.stopDurationTimer();
|
|
|
+ },
|
|
|
methods: {
|
|
|
+ async initRecorder() {
|
|
|
+ try {
|
|
|
+ await initWechatSDKWithRecorder();
|
|
|
+
|
|
|
+ // 设置录音事件监听
|
|
|
+ wechatRecorder.on('onStart', () => {
|
|
|
+ this.isRecording = true;
|
|
|
+ this.audioDuration = 0;
|
|
|
+ // 计时器显示录音时长
|
|
|
+ this.startDurationTimer();
|
|
|
+ });
|
|
|
+
|
|
|
+ wechatRecorder.on('onStop', (res) => {
|
|
|
+ this.isRecording = false;
|
|
|
+ this.localId = res.localId;
|
|
|
+ this.stopDurationTimer();
|
|
|
+ });
|
|
|
+
|
|
|
+ wechatRecorder.on('onUpload', (res) => {
|
|
|
+ this.serverId = res.serverId;
|
|
|
+ console.log('录音上传成功:', this.serverId);
|
|
|
+ // 可以在这里将serverId上传到自己的服务器
|
|
|
+ });
|
|
|
+
|
|
|
+ wechatRecorder.on('onError', (err) => {
|
|
|
+ console.error('录音错误:', err);
|
|
|
+ uni.showToast({ title: err.errMsg || '录音失败', icon: 'none' });
|
|
|
+ });
|
|
|
+
|
|
|
+ } catch (err) {
|
|
|
+ console.error('初始化录音失败:', err);
|
|
|
+ uni.showToast({ title: '无法使用录音功能', icon: 'none' });
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ handleRecord() {
|
|
|
+ if (this.isRecording) return;
|
|
|
+
|
|
|
+ wechatRecorder.startRecording((err, msg) => {
|
|
|
+ if (err) {
|
|
|
+ uni.showToast({ title: err.errMsg, icon: 'none' });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ handleStop() {
|
|
|
+ if (!this.isRecording) return;
|
|
|
+
|
|
|
+ wechatRecorder.stopRecording((err, res) => {
|
|
|
+ if (err) {
|
|
|
+ uni.showToast({ title: err.errMsg, icon: 'none' });
|
|
|
+ } else {
|
|
|
+ this.localId = res.localId;
|
|
|
+ // 上传录音到微信服务器
|
|
|
+ this.uploadAudio();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ handlePlay() {
|
|
|
+ if (!this.localId) return;
|
|
|
+
|
|
|
+ wechatRecorder.playVoice(this.localId, (err) => {
|
|
|
+ if (err) {
|
|
|
+ uni.showToast({ title: err.errMsg, icon: 'none' });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ uploadAudio() {
|
|
|
+ wechatRecorder.uploadVoice(this.localId, (err, res) => {
|
|
|
+ if (err) {
|
|
|
+ uni.showToast({ title: '上传失败', icon: 'none' });
|
|
|
+ } else {
|
|
|
+ this.serverId = res.serverId;
|
|
|
+ uni.showToast({ title: '录音上传成功', icon: 'success' });
|
|
|
+ // 将serverId发送到后端保存
|
|
|
+ this.saveRecording(res.serverId);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ saveRecording(serverId) {
|
|
|
+ // 调用后端接口保存录音
|
|
|
+ // this.$api.saveRecording({ serverId }).then(res => {
|
|
|
+ // console.log('录音保存成功');
|
|
|
+ // });
|
|
|
+ },
|
|
|
+
|
|
|
+ startDurationTimer() {
|
|
|
+ this.durationTimer = setInterval(() => {
|
|
|
+ this.audioDuration++;
|
|
|
+ }, 1000);
|
|
|
+ },
|
|
|
+
|
|
|
+ stopDurationTimer() {
|
|
|
+ if (this.durationTimer) {
|
|
|
+ clearInterval(this.durationTimer);
|
|
|
+ this.durationTimer = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ onSuccess(reslut) {
|
|
|
+ // 把服务端返回的图片地址添加到list中与组件数据同步
|
|
|
+ if (reslut.code === 200) {
|
|
|
+ const isVideo =
|
|
|
+ reslut.url.endsWith('.mp4') ||
|
|
|
+ reslut.url.endsWith('.mov') ||
|
|
|
+ reslut.url.endsWith('.mkv') ||
|
|
|
+ reslut.url.endsWith('.wmv')
|
|
|
+ if (isVideo) {
|
|
|
+ this.formData.videoUrl = baseUrl + reslut.url
|
|
|
+ this.formData.videoCoverUrl = baseUrl + reslut.coverUrl
|
|
|
+ } else {
|
|
|
+ this.fileList.push(baseUrl + reslut.url)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.mediaType = 'all'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 确定媒体类型
|
|
|
+ selectMediaType(type) {
|
|
|
+ if (type === 'image') {
|
|
|
+ this.uploadApi = baseUrl + '/common/uploads'
|
|
|
+ this.mediaType = 'image'
|
|
|
+ } else if (type === 'video') {
|
|
|
+ this.uploadApi = baseUrl + '/common/uploadVi'
|
|
|
+ this.mediaType = 'video'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 处理媒体类型取消事件
|
|
|
+ onCancel() {
|
|
|
+ this.uploadApi = baseUrl + '/common/uploads'
|
|
|
+ this.mediaType = 'all'
|
|
|
+ },
|
|
|
+ delectVideo() {
|
|
|
+ uni.showModal({
|
|
|
+ title: '提示',
|
|
|
+ content: '是否要删除此视频',
|
|
|
+ success: res => {
|
|
|
+ if (res.confirm) {
|
|
|
+ this.formData.videoUrl = ''
|
|
|
+ this.formData.videoCoverUrl = ''
|
|
|
+ // 重置媒体类型
|
|
|
+ this.mediaType = 'all'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ })
|
|
|
+ },
|
|
|
|
|
|
// upload事件
|
|
|
onUpload(e, t) {
|
|
|
@@ -206,4 +393,29 @@ export default {
|
|
|
justify-content: space-between;
|
|
|
margin-bottom: 20rpx;
|
|
|
}
|
|
|
+
|
|
|
+::v-deep .file-list-row {
|
|
|
+ width: 160rpx;
|
|
|
+ height: 160rpx;
|
|
|
+ background: #F7F8FA;
|
|
|
+ border-radius: 12rpx;
|
|
|
+
|
|
|
+ .add-image {
|
|
|
+ border: none !important;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep .media-area,
|
|
|
+.video-container {
|
|
|
+ width: 160rpx;
|
|
|
+ height: 160rpx;
|
|
|
+
|
|
|
+ .uni-video-cover-duration {
|
|
|
+ font-size: 20rpx;
|
|
|
+ font-weight: 400;
|
|
|
+ position: absolute;
|
|
|
+ right: 8rpx;
|
|
|
+ bottom: 4rpx;
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|