123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663 |
- <template>
- <view class="add-voice-page">
- <van-field
- :value="form.title"
- placeholder="请输入语音标题"
- :border="false"
- clearable
- @change="inputChange"
- label="语音标题"
- />
- <van-field
- :value="form.variety_name"
- placeholder="请选择品种"
- :border="false"
- readonly
- is-link
- label="品种"
- @click-input="showFilter=true"
- @click-icon="showFilter=true"
- />
- <van-field
- :value="form.section_name"
- placeholder="请选择板块名称"
- :border="false"
- readonly
- is-link
- label="板块名称"
- @click-input="showFilter=true"
- @click-icon="showFilter=true"
- />
- <view class="flex audio-box" v-if="recorderStatus==='stop'">
- <image
- :src="temAudio.paused?'../../../static/voice/pause.png':'../../../static/voice/playing.png'"
- mode="aspectFill"
- @click="handlePlayAudio"
- />
- <slider
- activeColor="#E6B77D"
- :max="temAudio.duration"
- :value="temAudio.curTime"
- @change="handleAudioSliderChange($event)"
- block-size="12"
- class="slider"
- />
- <text class="left-time">{{temAudio.curTime|formatTime}}</text>
- <text class="right-time">{{temAudio.duration|formatTime}}</text>
- <view class="del-btn" @click="handleDelRecord">
- <image src="./static/del.png" mode="aspectFill" />
- <text>删除</text>
- </view>
-
- </view>
-
- <view class="empty-voice-box" v-if="recorderStatus==='start'">
- <image src="./static/record.png" mode="aspectFill" />
- <view>无录音(录音时长超过十分钟自动结束)</view>
- </view>
- <view class="animat-box" v-if="recorderStatus==='doing'||recorderStatus==='pause'">
- <view class="con-box">
- <image :class="['img move1',recorderStatus==='doing'?'animat-run':'animat-pause']" src="./static/record-img.png" mode="widthFix" />
- <image :class="['img move2',recorderStatus==='doing'?'animat-run':'animat-pause']" src="./static/record-img.png" mode="widthFix" />
- <image :class="['img move3',recorderStatus==='doing'?'animat-run':'animat-pause']" src="./static/record-img.png" mode="widthFix" />
- </view>
- <view class="bot-text">{{time|formatTime}}</view>
- </view>
- <view class="sound-record-wrap" v-if="recorderStatus!=='stop'">
- <view class="top-text">点击开始录音</view>
- <image class="btn" :src="btnImg" mode="aspectFill" @click="handleClickBtn" />
- <view
- class="del-btn"
- :style="{color:recorderStatus==='doing'&&'#999'}"
- v-if="recorderStatus!=='start'"
- @click="handleResetRecorder"
- >删除</view>
- <view
- class="done-btn"
- v-if="recorderStatus!=='start'"
- @click="handleEndRecorder"
- >完成</view>
- </view>
- <view class="publish-btn" v-if="recorderStatus==='stop'" @click="handlePublish">发布</view>
-
- <!-- 筛选弹窗 -->
- <van-popup
- :show="showFilter"
- position="bottom"
- :close-on-click-overlay="true"
- @close="showFilter = false"
- round
- >
- <view class="fliter-wrap-list">
- <view class="flex top">
- <text style="color:#000">全部选项</text>
- <text style="color:#E3B377" @click="showFilter=false">取消</text>
- </view>
- <van-tree-select
- :items="options"
- :main-active-index="mainActiveIndex"
- :active-id="activeId"
- @click-nav="onClickNav"
- @click-item="onClickItem"
- main-active-class="main-active-class"
- content-active-class="content-active-class"
- />
- </view>
- </van-popup>
- </view>
- </template>
- <script>
- import {apiVoiceSectionList} from '@/api/voice'
- import {baseApiUrl} from '@/utils/config.js'
- import CryptoJS from '@/utils/crypto.js'
- import uniAsync from "@/utils/uni-async.js"; // uni api async 化
- const recorderManager = wx.getRecorderManager();//录音实例
- let innerAudioContext = uni.createInnerAudioContext();//播放音频实例
- let TIMER=null//计时器
- export default {
- filters:{
- formatTime(e){
- let m=parseInt(e/60)
- let s=parseInt(e%60)
- return `${m>9?m:'0'+m}:${s>9?s:'0'+s}`
- }
- },
- computed:{
- btnImg(){
- if(this.recorderStatus==='start'){
- return './static/voice-start.png'
- }else if(this.recorderStatus==='doing'){
- return './static/voice-doing.png'
- }else if(this.recorderStatus==='stop'){
- return './static/voice-pause.png'
- }else if(this.recorderStatus==='pause'){
- return './static/voice-pause.png'
- }
- }
- },
- data() {
- return {
- form:{
- title:'',//语音标题
- variety_name:'',
- variety_id:'',
- section_id:'',
- section_name:'',
- img_url:''
- },
- recorderStatus:'start',//当前录音状态 start开始 doing正在录音 stop停止录音 pause录音暂停
- time:0,
- isReset:false,//是否点击了重置
- temAudio:{
- url:'',//临时音频地址
- duration:'',//时长
- size:'',//大小
- curTime:0,//播放时当前播放的时间
- paused:true,
- },//临时音频文件信息
- showFilter:false,
- options:[],
- mainActiveIndex:0,
- activeId:0,//选择的板块id
- }
- },
- onLoad(){
- // 调取用户授权使用麦克风
- uni.authorize({
- scope: 'scope.record',
- success() {}
- })
- this.listenVoice()
-
- this.getOptionsList()
- },
- onShow(){
- innerAudioContext = uni.createInnerAudioContext()
- this.listenAudio()
- },
- onHide(){
- innerAudioContext.destroy()
- this.temAudio.paused=true
- },
- onUnload(){
- innerAudioContext.destroy()
- },
- methods: {
- //录音事件
- listenVoice(){
- recorderManager.onStart(()=>{
- //录音开始监听事件
- console.log('开始录音');
- this.recorderStatus='doing'
- this.isReset=false
- if(!TIMER){
- TIMER=setInterval(() => {
- this.time++
- }, 1000);
- }
-
- })
- recorderManager.onPause(()=>{
- //录音暂停监听事件
- console.log('录音暂停');
- this.recorderStatus='pause'
- clearInterval(TIMER)
- TIMER=null
- })
- recorderManager.onResume(()=>{
- //录音继续监听事件
- console.log('录音继续');
- this.recorderStatus='doing'
- if(!TIMER){
- TIMER=setInterval(() => {
- this.time++
- }, 1000);
- }
- })
- recorderManager.onStop((e)=>{
- //录音结束监听事件
- console.log('录音结束',e);
- // 如果是点击重置(删除按钮)的 则不做结束处理
- if(!this.isReset){
- this.recorderStatus='stop'
- this.temAudio.url=e.tempFilePath
- this.temAudio.size=e.fileSize
- this.temAudio.duration=parseInt(e.duration/1000)
- }
-
- clearInterval(TIMER)
- TIMER=null
- })
- recorderManager.onError((e)=>{
- //录音事件错误监听
- console.log('录音错误哦',e);
- })
- },
- //点击录音操作按钮
- async handleClickBtn(){
- const setRes=await uniAsync.getSetting()
- console.log(setRes.authSetting['scope.record']);
- if(!setRes.authSetting['scope.record']){
- uni.showToast({
- title:'请打开麦克风交流',
- icon:'none'
- })
- uni.openSetting()
- return
- }
-
- if(this.recorderStatus==='start'){
- recorderManager.start({
- duration:600000,
- format:'mp3'
- })
- }
- if(this.recorderStatus==='doing'){
- recorderManager.pause()//暂停录音
- }
- if(this.recorderStatus==='pause'){
- recorderManager.resume()//继续录音
- }
- },
- //点击重置录音状态
- handleResetRecorder(){
- if(this.recorderStatus==='doing') return
- this.isReset=true
- recorderManager.stop()
- this.recorderStatus='start'
- this.handleDelRecord()
- },
- //点击完成录音
- handleEndRecorder(){
- //点击完成时还不是已结束录音状态
- this.isReset=false
- recorderManager.stop()
- },
- //拖动音频播放进度条
- handleAudioSliderChange(e){
- const value=e.detail.value
- innerAudioContext.seek(value)
- },
- //点击播放\暂停音频
- handlePlayAudio(){
- innerAudioContext.src=this.temAudio.url
- if(this.temAudio.paused){
- innerAudioContext.play()
- }else{
- innerAudioContext.pause()
- }
- },
- //音频播放事件
- listenAudio(){
- innerAudioContext.onPlay(()=>{
- console.log('开始播放录音');
- this.temAudio.paused=false
- })
- innerAudioContext.onPause(()=>{
- console.log('录音播放暂停');
- this.temAudio.paused=true
- })
- // innerAudioContext.onStop(()=>{
- // console.log('录音播放停止');
- // this.temAudio.paused=true
- // innerAudioContext.src=''
- // })
- innerAudioContext.onEnded(()=>{
- console.log('录音播放自然结束');
- this.temAudio.curTime=this.temAudio.duration
- setTimeout(() => {
- this.temAudio.paused=true
- innerAudioContext.src=''
- this.temAudio.curTime=0
- }, 300);
- })
- innerAudioContext.onTimeUpdate(()=>{
- this.temAudio.curTime=parseInt(innerAudioContext.currentTime)
- })
- },
- //删除录音记录
- handleDelRecord(){
- this.recorderStatus='start'
- this.isReset=true
- this.temAudio.url=''
- this.temAudio.duration=''
- this.temAudio.curTime=0
- this.temAudio.paused=true
- this.time=0
- innerAudioContext.stop()
- TIMER=null
- },
- //获取选项数据
- async getOptionsList(){
- const res=await apiVoiceSectionList()
- if(!res.code===200) return
- const arr=res.data||[]
-
- this.options=arr.filter(item=>{
- item.text=item.VarietyName
- item.children=item.Children.filter(_item=>{
- if(_item.Status===1){
- _item.text=_item.SectionName
- _item.id=_item.SectionId
- return _item
- }
- })
- if(item.children.length>0){
- delete item.Children
- return item
- }
- })
- },
- onClickNav({detail}){
- console.log(detail);
- this.mainActiveIndex=detail.index
- },
- onClickItem({detail}){
- console.log(detail);
- this.activeId=detail.id
- this.form.section_id=detail.SectionId
- this.form.section_name=detail.SectionName
- this.form.variety_name=this.options[this.mainActiveIndex].VarietyName
- this.form.variety_id=this.options[this.mainActiveIndex].VarietyId
- this.form.img_url=detail.ImgUrl
- this.showFilter=false
- },
- inputChange(event) {
- this.form.title=event.detail
- },
- // 发布
- handlePublish(){
- if(!this.form.title||!this.form.variety_id){
- uni.showToast({
- title:'请将内容填写完整',
- icon:'none'
- })
- return
- }
- let formData={
- broadcast_name:this.form.title,
- section_id:Number(this.form.section_id),
- section_name:this.form.section_name,
- variety_id:Number(this.form.variety_id),
- variety_name:this.form.variety_name,
- img_url:this.form.img_url,
- author_id:Number(this.$store.state.user.userInfo.user_id),
- author:this.$store.state.user.userInfo.real_name
- }
- uni.uploadFile({
- url: baseApiUrl + "/voice/broadcast/add",
- filePath: this.temAudio.url,
- name: 'file',
- header: {
- Authorization: this.$store.state.user.token,
- },
- formData: formData,
- success: (result) => {
- const { envVersion } = uni.getAccountInfoSync().miniProgram
- const res = envVersion === 'release' ? JSON.parse(CryptoJS.Des3Decrypt(result.data)) : JSON.parse(result.data);
- console.log(res);
- if(res.code===200){
- uni.showToast({
- title:'发布成功',
- icon:'success'
- })
- setTimeout(() => {
- uni.$emit('addVoiceSuccess')
- uni.navigateBack()
- }, 1000);
- }else{
- uni.showToast({
- title:res.msg,
- icon:'none'
- })
- }
- },
- fail: () => {
- console.log('发布失败');
- uni.showToast({
- title:'发布失败,请稍后重试!',
- icon:'none'
- })
- },
- complete: () => {
- console.log('con');
- }
- });
-
- }
- },
- }
- </script>
- <style lang="scss">
- .add-voice-page .van-cell{
- border-bottom: 1px solid #e5e5e5;
- }
- .add-voice-page .van-field__label{
- font-size: 32rpx;
- color: #333;
- }
- /* .add-voice-page .van-cell__title{
- max-width: 6.2em;
- min-width: 6.2em;
- margin-right: 12px;
- font-size: 32rpx;
- color: #333;
- } */
- .add-voice-page .van-cell__value{
- text-align: left;
- font-size: 32rpx;
- }
- .add-voice-page{
- .fliter-wrap-list{
- background-color: #fff;
- padding-top: 53rpx;
- .top{
- font-size: 32rpx;
- justify-content: space-between;
- margin-bottom: 40rpx;
- padding: 0 34rpx;
- }
- .van-sidebar{
- flex-shrink: 0;
- }
- .van-tree-select__content{
- overflow-x: hidden;
- }
- .main-active-class{
- border-color: #E3B377;
- }
- .content-active-class{
- color: #E3B377;
- }
- }
- }
- page{
- padding-bottom:constant(safe-area-inset-bottom);
- padding-bottom:env(safe-area-inset-bottom);
- }
- </style>
- <style lang="scss" scoped>
- .add-voice-page{
- .empty-voice-box{
- height: 50vh;
- padding-top: 150rpx;
- image{
- width: 140rpx;
- height: 140rpx;
- margin-bottom: 20rpx;
- }
- text-align: center;
- color: #999999;
- }
- .sound-record-wrap{
- border-top: 1px solid #E6E6E6;
- padding-top: 126rpx;
- position: relative;
- .top-text{
- text-align: center;
- color: #EE3636;
- position: absolute;
- top: 50rpx;
- left: 50%;
- transform: translateX(-50%);
- }
- .btn{
- width: 118rpx;
- height: 118rpx;
- display: block;
- margin-left: auto;
- margin-right: auto;
- }
- .del-btn{
- position: absolute;
- left: 122rpx;
- bottom: 40rpx;
- font-size: 32rpx;
- color: #EE3636;
- }
- .done-btn{
- position: absolute;
- right: 122rpx;
- bottom: 40rpx;
- font-size: 32rpx;
- color: #EE3636;
- }
- }
- .audio-box{
- background-color: #FDF8F2;
- height: 123rpx;
- align-items: center;
- margin-left: 34rpx;
- margin-right: 34rpx;
- margin-top: 60rpx;
- margin-bottom: 180rpx;
- padding: 0 30rpx;
- position: relative;
- .left-time{
- position: absolute;
- bottom: 20rpx;
- left: 100rpx;
- color: #999999;
- font-size: 20rpx;
- }
- .right-time{
- position: absolute;
- bottom: 20rpx;
- right: 40rpx;
- color: #999999;
- font-size: 20rpx;
- }
- image{
- width: 40rpx;
- height: 48rpx;
- flex-shrink: 0;
- margin-right: 30rpx;
- }
- .slider{
- flex: 1;
- margin: 0 10rpx;
- }
- .del-btn{
- display: flex;
- align-items: center;
- color: #999999;
- font-size: 28rpx;
- position: absolute;
- bottom: -50rpx;
- right: 0;
- image{
- width: 32rpx;
- height: 35rpx;
- margin-right: 10rpx;
- }
- }
- }
- .publish-btn{
- width: 390rpx;
- height: 80rpx;
- text-align: center;
- line-height: 80rpx;
- color: #fff;
- background: #E6B77D;
- font-size: 32rpx;
- border-radius: 40px;
- margin-left: auto;
- margin-right: auto;
- }
- }
- .animat-box{
- height: 50vh;
- .con-box{
- height: 80%;
- background-color: #FAFAFA;
- position: relative;
- }
- .bot-text{
- font-size: 60rpx;
- padding-top: 36rpx;
- text-align: center;
- }
- .img{
- position: absolute;
- width: 100vw;
- top: 27%;
- transform: translateX(100vw);
- }
- .move1{
- animation: move 30s linear infinite;
- }
- .move2{
- animation: move 30s 10s linear infinite;
- }
- .move3{
- animation: move 30s 20s linear infinite;
- }
- .animat-pause{
- animation-play-state: paused;
- }
- .animat-run{
- animation-play-state: running;
- }
- @keyframes move {
- 0%{
- transform: translateX(100vw);
- }
- 100%{
- transform: translateX(-200vw);
- }
- }
- }
- </style>
|