diff --git a/.env.development b/.env.development index cb00b5c1..70a0c5e5 100644 --- a/.env.development +++ b/.env.development @@ -19,13 +19,14 @@ VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7001' # DEV # app入口 - +#VITE_APP_BASE_API_Url = 'http://25.18.122.65:7001' # VITE_APP_BASE_API_Url = 'http://25.16.122.91:9786' # VITE_APP_BASE_API_Url = 'http://25.18.122.66:9786' # h5专用地址x2 + # VITE_APP_BASE_H5_API_Url = 'http://25.18.122.65:7001' -# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.91:9786' +VITE_APP_BASE_H5_API_Url = 'http://25.18.122.91:9786' # VITE_APP_BASE_H5_API_Url = 'http://25.18.122.78:9786' # VITE_APP_BASE_H5_API_Url_TRAAPP = 'http://192.168.247.200' # VITE_APP_BASE_H5_API_Url_TRASTUDY = 'http://25.64.32.154:9602' diff --git a/src/api/common.js b/src/api/common.js index 4656ddad..3a75acb3 100644 --- a/src/api/common.js +++ b/src/api/common.js @@ -169,6 +169,21 @@ export function downloadVoiceFile(url) { }); }); } +// 获取音频 通用参数 +export function downloadVoiceParams(url) { + const token = getToken(); + const header = { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + }; + if (token) + header['summary'] = token + let baseUrl = get_base_url(url); + return { + url: `${baseUrl}${url}`, + header, + timeout: 180000, + } +} export function getAudioByText(data) { diff --git a/src/pages/course/components/talkingItem.vue b/src/pages/course/components/talkingItem.vue index 4ac7555a..5cced8fb 100644 --- a/src/pages/course/components/talkingItem.vue +++ b/src/pages/course/components/talkingItem.vue @@ -220,6 +220,7 @@ import VideoPreview from '@/components/image-preview/video-preview.vue'; import { downloadVoiceFile, + downloadVoiceParams, uploadVoiceFile, getAudioByText } from '@/api/common.js'; @@ -238,7 +239,8 @@ useStorageStore } from '@/store/storage.js'; import { - onUnload + onUnload, + onHide } from '@dcloudio/uni-app'; import Subject from '@/components/examination/subject.vue'; @@ -246,6 +248,7 @@ const storageStore = useStorageStore(); const audioCacheObj = computed(() => storageStore.audioObj); + const isGettingId = computed(() => storageStore.getGettingVoiceId); const props = defineProps({ type: { default: 0, // 1: userAnswer 0: AIAnswer @@ -434,12 +437,25 @@ initVoice(); }); onUnload(() => { - pauseVoice(); + // pauseVoice(); + console.log('onUnload') + talkVoiceObj.value?.destroy() + if(downloadFnc.value && downloadFnc.value.abord) downloadFnc.value?.abord() + downloadFnc.value = null + }); + onHide(() => { + console.log('onHide') + voiceLoading.value = false; + if(downloadFnc.value && downloadFnc.value.abord) downloadFnc.value?.abord() + downloadFnc.value = null }); let prevTime = -1; let pauseTime = -1; + const startPlay = ref(false) + const voiceIsPlaying = ref(false) talkVoiceObj.value.onEnded(() => { console.log('onEnded'); + voiceIsPlaying.value = false if(props.activeVoiceId){ emit('changePlay', ''); } @@ -449,6 +465,8 @@ }); talkVoiceObj.value.onStop(() => { console.log('onStop'); + voiceLoading.value = false; + voiceIsPlaying.value = false if(props.activeVoiceId){ emit('changePlay', ''); } @@ -457,13 +475,22 @@ talkVoiceObj.value.src = ''; }); talkVoiceObj.value.onPause(() => { + voiceIsPlaying.value = false + voiceLoading.value = false; prevTime = talkVoiceObj.value.currentTime; pauseTime = prevTime + if(downloadFnc.value && downloadFnc.value.abord) downloadFnc.value?.abord() + downloadFnc.value = null }); talkVoiceObj.value.onPlay(() => { console.log('onPlay'); prevTime = talkVoiceObj.value.currentTime; pauseTime = prevTime + startPlay.value = true + voiceIsPlaying.value = true + setTimeout(()=> { + startPlay.value= false + },300) emit('changePlay', unref(dataInfo)?.id); }); @@ -475,7 +502,7 @@ prevTime = talkVoiceObj.value.currentTime; } } else { - if (props.isPlaying && (talkVoiceObj.value.currentTime > 0) && props.activeVoiceId) { + if (props.isPlaying && (talkVoiceObj.value.currentTime > 0) && props.activeVoiceId && !startPlay.value) { console.log(pauseTime , prevTime) emit('changePlay', ''); } @@ -491,7 +518,7 @@ // emit('changePlay', ''); }); const pauseVoice = () => { - console.log('手动') + voiceLoading.value = false; if (!talkVoiceObj.value) return; talkVoiceObj.value.pause(); emit('changePlay', ''); @@ -510,7 +537,10 @@ playVoice(); } }; + const downloadFnc = ref(null) const playVoice = (readType = 'pgth') => { + console.log('playVoice11111111') + if(voiceIsPlaying.value) return let _content = showContent.value; if (!_content) { common.msg('没有可以播放的文字信息!'); @@ -518,15 +548,16 @@ } setTimeout(() => { emit('changePlay', unref(dataInfo)?.id); - console.log(1) // readType 阅读内容类型pgrh段落/qns问题 if (talkVoiceObj.value.src && talkVoiceObj.value.src === itemVoice.value) { + if(voiceIsPlaying.value) return talkVoiceObj.value.play(); return; } talkVoiceObj.value.src = ''; if (itemVoice.value) { setTimeout(() => { + if(voiceIsPlaying.value) return talkVoiceObj.value.src = itemVoice.value; talkVoiceObj.value.play(); }, 100); @@ -578,24 +609,53 @@ if (url) { voiceLoading.value = false; itemVoice.value = url; + if(voiceIsPlaying.value) return talkVoiceObj.value.src = url; talkVoiceObj.value.play(); } else { - downloadVoiceFile(_url) - .then((res) => { + storageStore.setGettingVoiceId(unref(dataInfo)?.id); + let _paramsObj = downloadVoiceParams(_url) + downloadFnc.value = uni.downloadFile({ + ..._paramsObj, + success(res) { if (res?.data) { common.msg(res.data.message); return; } voiceLoading.value = false; itemVoice.value = res.tempFilePath; + if(voiceIsPlaying.value) return talkVoiceObj.value.src = res.tempFilePath; - talkVoiceObj.value.play(); - storageStore.setStorage('audio', _url + _params.teachNo, itemVoice.value); - }) - .catch((err) => { - voiceLoading.value = false; - }); + // 判斷是否在當前頁面 + if(unref(isGettingId) === unref(dataInfo)?.id){ + talkVoiceObj.value.play(); + storageStore.setStorage('audio', _url + _params.teachNo, itemVoice.value); + } + }, + complete() { + voiceLoading.value = false; + downloadFnc.value = null + }, + }); + // downloadVoiceFile(_url) + // .then((res) => { + // if (res?.data) { + // common.msg(res.data.message); + // return; + // } + // voiceLoading.value = false; + // if() + // itemVoice.value = res.tempFilePath; + // talkVoiceObj.value.src = res.tempFilePath; + // // 判斷是否在當前頁面 + // if(unref(isGettingId) === unref(dataInfo)?.id){ + // talkVoiceObj.value.play(); + // storageStore.setStorage('audio', _url + _params.teachNo, itemVoice.value); + // } + // }) + // .catch((err) => { + // voiceLoading.value = false; + // }); } }); diff --git a/src/pages/course/components/touchBtn.vue b/src/pages/course/components/touchBtn.vue index 03dddf4b..c8d0ccfe 100644 --- a/src/pages/course/components/touchBtn.vue +++ b/src/pages/course/components/touchBtn.vue @@ -1,54 +1,24 @@ \ No newline at end of file + .overlay-radio-box { + position: absolute; + left: 100rpx; + top: 5rpx; + pointer-events: none; + } + } + } + } + } + } +} + diff --git a/src/pages/courseRecord/components/practiceRecordItem.vue b/src/pages/courseRecord/components/practiceRecordItem.vue index 94d44492..10da90da 100644 --- a/src/pages/courseRecord/components/practiceRecordItem.vue +++ b/src/pages/courseRecord/components/practiceRecordItem.vue @@ -40,7 +40,7 @@ - 练习时长:{{ formatDuration(item_list.exrStartTm, item_list.exrEndTm) }} + 练习时长:{{ item_list.stdtTmLenS || '--' }} @@ -61,7 +61,7 @@ import { computed, ref, reactive } from 'vue'; import common from '@/common/common'; import { queryPracticeHis } from '@/api/courseRecord.js'; - import { useItemList, formatDuration } from '../useItemList.js'; + import { useItemList } from '../useItemList.js'; const props = defineProps({ item: { diff --git a/src/pages/courseRecord/components/studyRecordItem.vue b/src/pages/courseRecord/components/studyRecordItem.vue index 7941a248..446f92ed 100644 --- a/src/pages/courseRecord/components/studyRecordItem.vue +++ b/src/pages/courseRecord/components/studyRecordItem.vue @@ -40,7 +40,7 @@ - 学习时长:{{ formatDuration(item_list.startTm, item_list.endTm) }} + 学习时长:{{ item_list.stdtTmLenS || '--' }} @@ -61,7 +61,7 @@ import { computed } from 'vue'; import common from '@/common/common'; import { queryStdyBatchByCrsId } from '@/api/courseRecord.js'; - import { useItemList, formatDuration, secondsToHours } from '../useItemList.js'; + import { useItemList, secondsToHours } from '../useItemList.js'; const props = defineProps({ item: { type: Object, diff --git a/src/pages/courseRecord/useItemList.js b/src/pages/courseRecord/useItemList.js index 2ff3c9b1..dca33100 100644 --- a/src/pages/courseRecord/useItemList.js +++ b/src/pages/courseRecord/useItemList.js @@ -7,25 +7,25 @@ import { // 计算两个标准时间的时间差值 -export const formatDuration = (startTm, endTm) => { - if (endTm === null || startTm === null) return "00:00:00"; - // 解析时间字符串为时间戳(毫秒) - const startTime = new Date(startTm).getTime(); - const endTime = new Date(endTm).getTime(); - - // 计算时间差(秒),确保为正数 - const seconds = Math.abs(Math.floor((endTime - startTime) / 1000)); - // 计算时、分、秒 - const hours = Math.floor(seconds / 3600); - const minutes = Math.floor((seconds % 3600) / 60); - const remainingSeconds = seconds % 60; - - // 补零格式化函数(统一处理所有单位) - const formatNumber = (num) => num.toString().padStart(2, '0'); - - // 小时、分钟、秒均保持两位数格式 - return `${formatNumber(hours)}:${formatNumber(minutes)}:${formatNumber(remainingSeconds)}`; -}; +// export const formatDuration = (startTm, endTm) => { +// if (endTm === null || startTm === null) return "00:00:00"; +// // 解析时间字符串为时间戳(毫秒) +// const startTime = new Date(startTm).getTime(); +// const endTime = new Date(endTm).getTime(); +// +// // 计算时间差(秒),确保为正数 +// const seconds = Math.abs(Math.floor((endTime - startTime) / 1000)); +// // 计算时、分、秒 +// const hours = Math.floor(seconds / 3600); +// const minutes = Math.floor((seconds % 3600) / 60); +// const remainingSeconds = seconds % 60; +// +// // 补零格式化函数(统一处理所有单位) +// const formatNumber = (num) => num.toString().padStart(2, '0'); +// +// // 小时、分钟、秒均保持两位数格式 +// return `${formatNumber(hours)}:${formatNumber(minutes)}:${formatNumber(remainingSeconds)}`; +// }; // 秒数转换成小时,带小数点的小时 export const secondsToHours = (seconds) => { diff --git a/src/pages/index/dialog.vue b/src/pages/index/dialog.vue index 85ef606f..ae474ff7 100644 --- a/src/pages/index/dialog.vue +++ b/src/pages/index/dialog.vue @@ -1114,6 +1114,7 @@ .talking-list { height: calc(100% - 772rpx); + min-height: 300rpx; padding: 12rpx 24rpx; box-sizing: border-box; min-height: 300rpx; diff --git a/src/pages/login/login.vue b/src/pages/login/login.vue index 02979bcc..1acfe4f0 100644 --- a/src/pages/login/login.vue +++ b/src/pages/login/login.vue @@ -354,7 +354,7 @@ .main_div { display: flex; flex-direction: column; - overflow: hidden; + // overflow: hidden; max-height: 100vh; } diff --git a/src/store/storage.js b/src/store/storage.js index 62ae21c7..f6baf020 100644 --- a/src/store/storage.js +++ b/src/store/storage.js @@ -10,7 +10,8 @@ export const useStorageStore = defineStore('storageStore',{ showPreviewDetail: false, fileType: 'iamge', fileId: '', - fileSrc: '' + fileSrc: '', + gettingVoiceId: '' }), getters:{ imgObj(state){ @@ -37,8 +38,14 @@ export const useStorageStore = defineStore('storageStore',{ getFileSrc(state){ return state.fileSrc }, + getGettingVoiceId(state){ + return state.gettingVoiceId + }, }, actions:{ + setGettingVoiceId(id){ + return this.gettingVoiceId = id + }, setShowPreviewDetail({ status = false, fileType = 'image', fileId = '', fileSrc = '' }){ this.showPreviewDetail = status this.fileId = fileId