抽离组件按住说话
This commit is contained in:
@@ -70,6 +70,7 @@ export default class WebSocketUtil {
|
||||
return
|
||||
}
|
||||
}else{
|
||||
clearInterval(this.reconnectTimer); // 清除重连计时器
|
||||
goto_login_fun();
|
||||
return
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="title">
|
||||
<img class="title-icon" src="@/static/images/course/edit.png" alt="" />
|
||||
<image class="title-icon" src="@/static/images/course/edit.png" alt=""> </image>
|
||||
改进建议:
|
||||
</view>
|
||||
<view class="total-score">
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="title">
|
||||
<img class="title-icon" src="@/static/images/course/edit.png" alt="" />
|
||||
<image class="title-icon" src="@/static/images/course/edit.png" alt=""> </image>
|
||||
改进建议:
|
||||
</view>
|
||||
<view class="total-score">
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
</view>
|
||||
<view class="talking-cont">
|
||||
<CommonLoading color="#06f" v-show="dataInfo.isLoading"/>
|
||||
<view class="talking-text" v-if="[3, 5, 6].indexOf(type) >= 0 && !dataInfo.isLoading">
|
||||
<text class="talking-text" v-if="[3, 5, 6].indexOf(type) >= 0 && !dataInfo.isLoading">
|
||||
{{ showContent }}
|
||||
</view>
|
||||
<view class="talking-text" v-if="[4].indexOf(type) >= 0">
|
||||
</text>
|
||||
<text class="talking-text" v-if="[4].indexOf(type) >= 0">
|
||||
<!-- 请您思考并作答:<br> -->
|
||||
{{ showContent }}
|
||||
</view>
|
||||
</text>
|
||||
<view v-if="type === 3">
|
||||
<ImagePreview class="cont-img-box" v-if="(dataInfo.imageAddrs||[]).length>0" :imgId="dataInfo.imageAddrs[0]"></ImagePreview>
|
||||
<VideoPreview class="cont-img-box" v-if="(dataInfo.vidoAddrs||[]).length>0" :imgId="dataInfo.vidoAddrs[0]"></VideoPreview>
|
||||
@@ -82,8 +82,9 @@
|
||||
<view class="user-answer" v-else-if="[1, 2].indexOf(type) >= 0">
|
||||
<view class="user-info">
|
||||
<view class="avatar-box">
|
||||
<!-- <ImagePreview class="img-box" :imgId="''"></ImagePreview> -->
|
||||
<img class="img-box" :src="userInfo.imagePath" alt="" fit="contain" style="width: 100%; height: 100%;"/>
|
||||
<image v-if="userInfo.imagePath" class="img-box" :src="userInfo.imagePath" style="width: 100%; height: 100%;"></image>
|
||||
<ImagePreview v-else-if="userInfo.imageAddr" class="img-box" :src="userInfo.imageAddr" style="width: 100%; height: 100%;"></ImagePreview>
|
||||
<image v-else class="img-box" src="/static/images/me/default_user_avatar.png" style="width: 100%; height: 100%;"></image>
|
||||
</view>
|
||||
<view class="ai-name">
|
||||
{{ userInfo.userName }}
|
||||
@@ -95,10 +96,10 @@
|
||||
<CommonLoading color="#fff" v-show="voiceLoading || dataInfo.isLoading"/>
|
||||
</view>
|
||||
<view class="talking-cont" v-show="!dataInfo.isLoading">
|
||||
<view class="talking-text">
|
||||
<text :class="['talking-text', translateLoading?'loading':'']">
|
||||
<CommonLoading color="#fff" v-show="translateLoading"/>
|
||||
{{ showContent }}
|
||||
</view>
|
||||
</text>
|
||||
</view>
|
||||
<view class="btns-cont" v-show="!dataInfo.isLoading">
|
||||
<!-- <view class="replay-btn">
|
||||
@@ -127,18 +128,19 @@
|
||||
<view class="user-answer" v-else-if="[0, 6].indexOf(type) >= 0">
|
||||
<view class="user-info">
|
||||
<view class="avatar-box">
|
||||
<!-- <ImagePreview class="img-box" :imgId="''"></ImagePreview> -->
|
||||
<img class="img-box" :src="userInfo.imagePath" alt="" fit="contain" style="width: 100%; height: 100%;"/>
|
||||
<image v-if="userInfo.imagePath" class="img-box" :src="userInfo.imagePath" style="width: 100%; height: 100%;"></image>
|
||||
<ImagePreview v-else-if="userInfo.imageAddr" class="img-box" :src="userInfo.imageAddr" style="width: 100%; height: 100%;"></ImagePreview>
|
||||
<image v-else class="img-box" src="/static/images/me/default_user_avatar.png" style="width: 100%; height: 100%;"></image>
|
||||
</view>
|
||||
<view class="ai-name">
|
||||
{{ userInfo.userName }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="talking-info-less">
|
||||
<view class="talking-text" v-if="type === 0">
|
||||
<text class="talking-text" v-if="type === 0">
|
||||
{{ showContent }}
|
||||
</view>
|
||||
<view class="talking-text" v-if="type === 6">
|
||||
</text>
|
||||
<view class="talking-text loading" v-if="type === 6">
|
||||
<CommonLoading color="#fff"/>
|
||||
</view>
|
||||
</view>
|
||||
@@ -202,7 +204,7 @@ const audioCacheObj = computed(() => storageStore.audioObj)
|
||||
const voiceLoading = ref(false)
|
||||
watch(() => props.isPlaying,(val) => {
|
||||
if(!val){
|
||||
talkVoiceObj.value?.stop()
|
||||
talkVoiceObj.value?.pause()
|
||||
}
|
||||
},{
|
||||
deep: true,
|
||||
@@ -216,7 +218,7 @@ const audioCacheObj = computed(() => storageStore.audioObj)
|
||||
})
|
||||
|
||||
const transformContent = ref('')
|
||||
const showContent = computed(() => {
|
||||
const showContentBase = computed(() => {
|
||||
if(props.isTransform){
|
||||
return transformContent.value
|
||||
}else{
|
||||
@@ -228,6 +230,9 @@ const audioCacheObj = computed(() => storageStore.audioObj)
|
||||
else if(props.type === 0) return unref(dataInfo)?.chatContent || unref(dataInfo)?.talkingContent
|
||||
}
|
||||
})
|
||||
const showContent = computed(() => {
|
||||
return showContentBase.value.replace(/\/n/g,"\n")
|
||||
})
|
||||
|
||||
onMounted(()=>{
|
||||
// demoUsage({
|
||||
@@ -333,6 +338,10 @@ const audioCacheObj = computed(() => storageStore.audioObj)
|
||||
}
|
||||
// readType 阅读内容类型pgrh段落/qns问题
|
||||
emit('changePlay', unref(dataInfo)?.id)
|
||||
if(talkVoiceObj.value.src === itemVoice.value) {
|
||||
talkVoiceObj.value.play()
|
||||
return
|
||||
}
|
||||
if(itemVoice.value){
|
||||
setTimeout(()=>{
|
||||
talkVoiceObj.value.src = itemVoice.value
|
||||
@@ -486,9 +495,11 @@ const audioCacheObj = computed(() => storageStore.audioObj)
|
||||
border-radius: 15rpx;
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
padding-bottom: 40rpx;
|
||||
&.talking-info-less{
|
||||
float: left;
|
||||
min-width: 400rpx;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
.talking-gif{
|
||||
width: 200rpx;
|
||||
@@ -508,9 +519,13 @@ const audioCacheObj = computed(() => storageStore.audioObj)
|
||||
.talking-text{
|
||||
font-size: 28rpx;
|
||||
line-height: 48rpx;
|
||||
min-height: 48rpx;
|
||||
margin-bottom: 20rpx;
|
||||
word-break: break-all;
|
||||
white-space: pre-line;
|
||||
&.loading{
|
||||
min-height: 68rpx;
|
||||
}
|
||||
}
|
||||
.cont-img-box{
|
||||
width: 433rpx;
|
||||
@@ -681,6 +696,9 @@ const audioCacheObj = computed(() => storageStore.audioObj)
|
||||
margin-bottom: 20rpx;
|
||||
word-break: break-all;
|
||||
white-space: pre-line;
|
||||
&.loading{
|
||||
min-height: 68rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btns-cont{
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
<template>
|
||||
<view class="talk-btns" ref="talkBtnRef">
|
||||
<view
|
||||
class="touch-btn"
|
||||
@touchstart="showOverlayTalking"
|
||||
@touchend="hideOverlayTalking"
|
||||
@touchmove="handleMove"
|
||||
v-if="!keyboardIsShow"
|
||||
>按住说话
|
||||
</view>
|
||||
<view class="touch-btn" v-if="keyboardIsShow">
|
||||
<uv-input class="input-box" ref="inputRef" v-model.trim="answerValue" maxlength="1000"
|
||||
placeholderStyle='color:#999999;font-size:26rpx' placeholder="请输入答案">
|
||||
</uv-input>
|
||||
</view>
|
||||
<view class="talk-btn-box" @click.stop="showKeyboard">
|
||||
<image class="talk-btn-icon" v-show="!keyboardIsShow" src="/src/static/images/course/jianpan.png" mode=""></image>
|
||||
<image class="talk-btn-icon" v-show="keyboardIsShow" src="/src/static/images/course/send.png" mode=""></image>
|
||||
</view>
|
||||
<uv-overlay :show="showTalkingModel" opacity=".9" @click="showTalkingModel = false">
|
||||
<view class="overlay-box">
|
||||
<view class="circle-bg-box">
|
||||
<view class="icon-box">
|
||||
<image src="/src/static/images/course/talk-icon.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tips-box">松开发送</view>
|
||||
<view class="btns-box">
|
||||
<view :class="['close-btn',isOut?'is-out':'']" >取消
|
||||
<image class="btn-box" v-if="!isOut" src="/src/static/images/course/close.png" mode=""></image>
|
||||
<image class="btn-box" v-else src="/src/static/images/course/close-active.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uv-overlay>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { toRefs, ref, computed, unref, onMounted, onUnmounted, defineEmits, nextTick } from 'vue';
|
||||
const emit = defineEmits(['uploadVoice', 'submitAnswer','startRecord'])
|
||||
const props = defineProps({
|
||||
answerType:{
|
||||
default: 0,
|
||||
type: Number
|
||||
}
|
||||
})
|
||||
const { answerType } = toRefs(props)
|
||||
const showTalkingModel = ref(false)
|
||||
const keyboardIsShow = ref(false)
|
||||
const answerValue = ref('')
|
||||
const talkBtnRef = ref()
|
||||
// 录音
|
||||
const audioPath = ref('')
|
||||
const audioObj = uni.createInnerAudioContext()
|
||||
//#ifdef APP-PLUS
|
||||
// app端
|
||||
const recordObjCom = uni.getRecorderManager()
|
||||
const initRecord = () => {
|
||||
unref(recordObjCom)?.onStop((res, duration)=>{
|
||||
audioPath.value = res.tempFilePath
|
||||
})
|
||||
}
|
||||
const startRecord = () => {
|
||||
unref(recordObjCom).start({format:'mp3'})
|
||||
}
|
||||
const stopRecord = () => {
|
||||
unref(recordObjCom)?.stop?.()
|
||||
}
|
||||
// #endif
|
||||
//#ifndef APP-PLUS
|
||||
const recordObjCom = {}
|
||||
const initRecord = () => {}
|
||||
// #endif
|
||||
onMounted(()=>{
|
||||
initRecord?.()
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
teacherVoiceObj?.stop?.()
|
||||
teacherVoiceObj.src = ''
|
||||
})
|
||||
// const playRecord = () => {
|
||||
// audioObj.src = audioPath.value
|
||||
// unref(audioObj).play()
|
||||
// }
|
||||
// 录音结束
|
||||
|
||||
// 记录 按下移动位置
|
||||
const touchX = ref(0)
|
||||
const touchY = ref(0)
|
||||
const baseY = ref(0)
|
||||
const windowInfo = uni.getWindowInfo()
|
||||
// 计算是否超出按下盒子位置
|
||||
const isOut = computed(() => {
|
||||
let _btnHeight = windowInfo.screenWidth/750 * 234
|
||||
let moveVal = (windowInfo.screenHeight - touchY.value) > _btnHeight
|
||||
return moveVal
|
||||
})
|
||||
const showOverlayTalking = (obj) => {
|
||||
emit('startRecord')
|
||||
if(answerType.value === 4){
|
||||
showTalkingModel.value = true
|
||||
touchX.value = obj.changedTouches[0].pageX
|
||||
touchY.value = obj.changedTouches[0].pageY
|
||||
baseY.value = obj.currentTarget.offsetTop
|
||||
//#ifdef APP-PLUS
|
||||
startRecord()
|
||||
// #endif
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '请先获取问题信息!',
|
||||
icon: "none",
|
||||
duration:1000
|
||||
})
|
||||
}
|
||||
}
|
||||
const hideOverlayTalking = (obj) => {
|
||||
showTalkingModel.value = false
|
||||
//#ifdef APP-PLUS
|
||||
stopRecord()
|
||||
// #endif
|
||||
if(!isOut.value){
|
||||
setTimeout(()=>{
|
||||
emit('uploadVoice', audioPath.value)
|
||||
},1000)
|
||||
}
|
||||
}
|
||||
|
||||
const handleMove = (obj) => {
|
||||
touchX.value = obj.changedTouches[0].pageX
|
||||
touchY.value = obj.changedTouches[0].pageY
|
||||
}
|
||||
// 发送文本
|
||||
const showKeyboard = () => {
|
||||
if(answerType.value === 4){
|
||||
if(keyboardIsShow.value){
|
||||
if(answerValue.value){
|
||||
emit(
|
||||
'submitAnswer',
|
||||
answerValue.value,
|
||||
() => {
|
||||
keyboardIsShow.value = !keyboardIsShow.value
|
||||
answerValue.value = ''
|
||||
}
|
||||
)
|
||||
}else{
|
||||
keyboardIsShow.value = !keyboardIsShow.value
|
||||
}
|
||||
}else{
|
||||
keyboardIsShow.value = !keyboardIsShow.value
|
||||
}
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '请先获取问题信息!',
|
||||
icon: "none",
|
||||
duration:1000
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.talk-btns{
|
||||
height: 150rpx;
|
||||
background-color: #fff;
|
||||
padding: 25rpx 30rpx 0;
|
||||
position: relative;
|
||||
.touch-btn{
|
||||
height: 92rpx;
|
||||
box-shadow: 0 8rpx 20rpx 0 rgba(0,0,0,.06);
|
||||
text-align: center;
|
||||
line-height: 92rpx;
|
||||
color: #000;
|
||||
font-weight: 400;
|
||||
position: relative;
|
||||
.input-box{
|
||||
width: 100%;
|
||||
height: 92rpx;
|
||||
line-height: 92rpx;
|
||||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
padding:0 40rpx 0 40rpx;
|
||||
}
|
||||
}
|
||||
.talk-btn-box{
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 120rpx;
|
||||
right: 0;
|
||||
top:0;
|
||||
.talk-btn-icon{
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
position: absolute;
|
||||
right: 60rpx;
|
||||
top: 50%;
|
||||
margin-top: -20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.overlay-box{
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
// justify-content: flex-end;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.circle-bg-box{
|
||||
height: 234rpx;
|
||||
background: url(@/static/images/course/talking.png) no-repeat;
|
||||
background-size: cover;
|
||||
position: relative;
|
||||
.icon-box{
|
||||
position: absolute;
|
||||
left:50%;
|
||||
top: 50%;
|
||||
margin-left: -17rpx;
|
||||
margin-top: -24rpx;
|
||||
width: 34rpx;
|
||||
height: 48rpx;
|
||||
image{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tips-box{
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
color:#c0c0c0;
|
||||
text-align: center;
|
||||
margin: 12rpx 0 24rpx;
|
||||
}
|
||||
.btns-box{
|
||||
height: 270rpx;
|
||||
// padding: 0 120rpx;
|
||||
width: 154rpx;
|
||||
margin: 0 auto 100rpx;
|
||||
overflow: hidden;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
line-height: 116rpx;
|
||||
.close-btn{
|
||||
float: left;
|
||||
height: 100%;
|
||||
width: 154rpx;
|
||||
overflow: hidden;
|
||||
color:#999;
|
||||
&.is-out{
|
||||
color:#fff;
|
||||
}
|
||||
}
|
||||
.translate-btn{
|
||||
float: right;
|
||||
height: 100%;
|
||||
width: 154rpx;
|
||||
overflow: hidden;
|
||||
color:#999;
|
||||
}
|
||||
.btn-box{
|
||||
width: 100%;
|
||||
height: 154rpx;
|
||||
}
|
||||
}
|
||||
.talk-dialog{
|
||||
width: 506rpx;
|
||||
height: 234rpx;
|
||||
margin: 0 auto;
|
||||
background-color: #06f;
|
||||
}
|
||||
.white-bg-box{
|
||||
height: 365rpx;
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
border-radius: 32rpx 32rpx 0 0;
|
||||
padding: 58rpx 36rpx;
|
||||
.box-title{
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
line-height: 46rpx;
|
||||
margin-bottom: 46rpx;
|
||||
}
|
||||
.box-btns{
|
||||
height: 46rpx;
|
||||
line-height: 46rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #999;
|
||||
.is-active{
|
||||
color: #06f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
+121
-245
@@ -3,7 +3,7 @@
|
||||
<view class="top-bg"></view>
|
||||
<view class="bot-bg"></view>
|
||||
<view class="course-study-body" v-show="step === 1">
|
||||
<view class="seek-setting" @click="showSeekModel = true">
|
||||
<view class="seek-setting" @click="showChangeSeekModelNow">
|
||||
{{chooseRate}}倍
|
||||
<image src="@/static/images/course/setting.png" alt="" class="image-icon"></image>
|
||||
</view>
|
||||
@@ -36,8 +36,8 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="course-study-body" v-show="step === 2" @click="playRecord">
|
||||
<view class="seek-setting" @click="showSeekModel = true">
|
||||
<view class="course-study-body" v-show="step === 2">
|
||||
<view class="seek-setting" @click="showChangeSeekModelNow">
|
||||
{{chooseRate}} 倍
|
||||
<image src="@/static/images/course/setting.png" alt="" class="image-icon"></image>
|
||||
</view>
|
||||
@@ -75,46 +75,14 @@
|
||||
<!-- <video v-if="videoUrlShow" :src="videoUrlShow" controls></video> -->
|
||||
<!-- </view> -->
|
||||
</scroll-view>
|
||||
<view class="talk-btns">
|
||||
<view
|
||||
class="touch-btn"
|
||||
@touchstart="showOverlayTalking"
|
||||
@touchend="hideOverlayTalking"
|
||||
@touchmove="handleMove"
|
||||
v-if="!keyboardIsShow"
|
||||
>按住说话
|
||||
</view>
|
||||
<view class="touch-btn" v-if="keyboardIsShow">
|
||||
<uv-input class="input-box" ref="inputRef" v-model.trim="answerValue" maxlength="1000"
|
||||
placeholderStyle='color:#999999;font-size:26rpx' placeholder="请输入答案">
|
||||
</uv-input>
|
||||
</view>
|
||||
<view class="talk-btn-box" @click.stop="showKeyboard">
|
||||
<image class="talk-btn-icon" v-show="!keyboardIsShow" src="/src/static/images/course/jianpan.png" mode=""></image>
|
||||
<image class="talk-btn-icon" v-show="keyboardIsShow" src="/src/static/images/course/send.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<TouchBtn
|
||||
class="talk-btns"
|
||||
@uploadVoice="uploadRecordNow"
|
||||
@submitAnswer="submitAnswerNow"
|
||||
@startRecord="changePlayItemId('')"
|
||||
:answerType="lastTalkingInfo.type||0"
|
||||
/>
|
||||
</view>
|
||||
<uv-overlay :show="showTalkingModel" opacity=".9" @click="showTalkingModel = false">
|
||||
<view class="overlay-box">
|
||||
<view class="circle-bg-box">
|
||||
<view class="icon-box">
|
||||
<image src="/src/static/images/course/talk-icon.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tips-box">松开发送</view>
|
||||
<view class="btns-box">
|
||||
<view :class="['close-btn',isOut?'is-out':'']" >取消
|
||||
<image class="btn-box" v-if="!isOut" src="/src/static/images/course/close.png" mode=""></image>
|
||||
<image class="btn-box" v-else src="/src/static/images/course/close-active.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="talk-dialog">
|
||||
<view class="voice-gif"></view>
|
||||
</view> -->
|
||||
</view>
|
||||
</uv-overlay>
|
||||
|
||||
<uv-overlay :show="showSeekModel" opacity=".6" @click="showSeekModel = false">
|
||||
<view class="overlay-box">
|
||||
<view class="white-bg-box">
|
||||
@@ -161,6 +129,7 @@ import {
|
||||
import common from '@/common/common';
|
||||
import TalkingItem from '@/pages/course/components/talkingItem.vue'
|
||||
import ImagePreview from '@/components/image-preview/image-preview.vue'
|
||||
import TouchBtn from '@/pages/course/components/touchBtn.vue'
|
||||
|
||||
import { useSocketStore } from "@/store/socket.js"
|
||||
import { useStorageStore } from "@/store/storage.js"
|
||||
@@ -240,8 +209,12 @@ const getData = async () => {
|
||||
// })
|
||||
};
|
||||
|
||||
const showChangeSeekModelNow = () => {
|
||||
// changePlayItemId()
|
||||
showSeekModel.value = true
|
||||
}
|
||||
// 关闭播放状态
|
||||
const changePlayItemId = (id) => {
|
||||
const changePlayItemId = (id = '') => {
|
||||
if(activeVoiceTalkingItemId.value === id){
|
||||
activeVoiceTalkingItemId.value = ''
|
||||
}else{
|
||||
@@ -321,18 +294,18 @@ const getGraphInfoUnStudy = () => {
|
||||
}).then(res=>{
|
||||
let _id = new Date().getTime() + 'id'
|
||||
let _body = res.body|| {}
|
||||
// if(_body.chatContent.haveNext === 'N'){}
|
||||
talkingList.value.push({
|
||||
lastTalkingInfo.value = {
|
||||
crsId: crsId.value,
|
||||
qstLogId: _body.chatBody,
|
||||
pgrphId: _body.pgrphId,
|
||||
logId:_body.chatBody.logId || '',
|
||||
talkingContent: _body.chatContent,
|
||||
chatContent: _body.chatContent,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
..._body.chatBody,
|
||||
type: Number(_body.bodyTyp) || 0,
|
||||
id: _id
|
||||
})
|
||||
}
|
||||
talkingList.value.push(lastTalkingInfo.value)
|
||||
pgrphNum.value = _body.chatBody.pgrphNum
|
||||
showOrder.value = _body.chatBody.showOrder
|
||||
logId.value = _body.chatBody.logId || ''
|
||||
@@ -372,16 +345,17 @@ const getQuestionInfoUnStudy = (pgrphId) => {
|
||||
const nextQuestionSuccess = (info, type='next') => {
|
||||
let _id = new Date().getTime() + 'id'
|
||||
if(type === 'next'){
|
||||
talkingList.value.push({
|
||||
lastTalkingInfo.value = {
|
||||
crsId: info.crsId,
|
||||
pgrphId: info.pgrphId,
|
||||
talkingContent: '继续',
|
||||
type: 0,
|
||||
id: _id
|
||||
})
|
||||
}
|
||||
talkingList.value.push(lastTalkingInfo.value)
|
||||
scrollToBottomNow(0)
|
||||
getQuestionInfoUnStudy(info.pgrphId)
|
||||
}else if( type = 'overGraph'){
|
||||
}else if( type === 'overGraph'){
|
||||
textChartApi({
|
||||
processType: 'PRGH-OVER',
|
||||
requestBody: JSON.stringify({
|
||||
@@ -389,33 +363,37 @@ const nextQuestionSuccess = (info, type='next') => {
|
||||
logId: info?.logId,
|
||||
})
|
||||
}).then(res=>{
|
||||
talkingList.value.push({
|
||||
lastTalkingInfo.value = {
|
||||
crsId: info.crsId,
|
||||
pgrphId: info.pgrphId,
|
||||
talkingContent: '继续',
|
||||
type: 0,
|
||||
id: _id
|
||||
})
|
||||
}
|
||||
talkingList.value.push(lastTalkingInfo.value)
|
||||
scrollToBottomNow(0)
|
||||
getQuestionInfoUnStudy(info.pgrphId)
|
||||
})
|
||||
}else if( type = 'reStart'){
|
||||
}else if( type === 'reStart'){
|
||||
console.log( 'qstLogId',info.qstLogId)
|
||||
// 重新回答
|
||||
textChartApi({
|
||||
processType: 'NEW-ANSER',
|
||||
requestBody: info.qstLogId
|
||||
}).then(res=>{
|
||||
let _body = res.body|| {}
|
||||
talkingList.value.push({
|
||||
lastTalkingInfo.value = {
|
||||
crsId: info.crsId,
|
||||
qstLogId: _body.chatBody,
|
||||
pgrphId: info.pgrphId,
|
||||
talkingContent: _body.chatContent,
|
||||
chatContent: _body.chatContent,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
..._body.chatBody,
|
||||
type: Number(_body.bodyTyp) || 0,
|
||||
id: _id
|
||||
})
|
||||
}
|
||||
|
||||
talkingList.value.push(lastTalkingInfo.value)
|
||||
scrollToBottomNow()
|
||||
})
|
||||
}
|
||||
@@ -491,219 +469,113 @@ const showTalkingModel = ref(false)
|
||||
// 录音
|
||||
const audioPath = ref('')
|
||||
const audioObj = uni.createInnerAudioContext()
|
||||
//#ifdef APP-PLUS
|
||||
// app端
|
||||
const recordObj = uni.getRecorderManager()
|
||||
const initRecord = () => {
|
||||
unref(recordObj)?.onStop((res, duration)=>{
|
||||
audioPath.value = res.tempFilePath
|
||||
})
|
||||
}
|
||||
const startRecord = () => {
|
||||
unref(recordObj).start({format:'mp3'})
|
||||
}
|
||||
const stopRecord = () => {
|
||||
unref(recordObj)?.stop?.()
|
||||
}
|
||||
// #endif
|
||||
//#ifndef APP-PLUS
|
||||
const recordObj = {}
|
||||
const initRecord = () => {}
|
||||
// #endif
|
||||
onMounted(()=>{
|
||||
getData();
|
||||
initRecord?.()
|
||||
})
|
||||
onShow(()=>{
|
||||
// getData();
|
||||
})
|
||||
// onHide(()=>{
|
||||
// teacherVoiceObj.stop()
|
||||
// teacherVoiceObj.src = ''
|
||||
// })
|
||||
onUnmounted(()=>{
|
||||
teacherVoiceObj?.stop?.()
|
||||
teacherVoiceObj.src = ''
|
||||
})
|
||||
const playRecord = () => {
|
||||
audioObj.src = audioPath.value
|
||||
unref(audioObj).play()
|
||||
}
|
||||
// 录音结束
|
||||
|
||||
// 记录 按下移动位置
|
||||
const touchX = ref(0)
|
||||
const touchY = ref(0)
|
||||
const baseY = ref(0)
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
const widowHeight = systemInfo.windowHeight
|
||||
// 计算是否超出按下盒子位置
|
||||
const isOut = computed(() => {
|
||||
let moveVal = (widowHeight - baseY.value)/140 * 234
|
||||
return (widowHeight - moveVal) > touchY.value
|
||||
})
|
||||
const showOverlayTalking = (obj) => {
|
||||
if(lastTalkingInfo.value.type === 4){
|
||||
//#ifdef APP-PLUS
|
||||
showTalkingModel.value = true
|
||||
touchX.value = obj.changedTouches[0].pageX
|
||||
touchY.value = obj.changedTouches[0].pageY
|
||||
baseY.value = obj.currentTarget.offsetTop
|
||||
startRecord()
|
||||
// #endif
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '请先获取问题信息!',
|
||||
icon: "none",
|
||||
duration:1000
|
||||
})
|
||||
}
|
||||
}
|
||||
const hideOverlayTalking = (obj) => {
|
||||
showTalkingModel.value = false
|
||||
//#ifdef APP-PLUS
|
||||
stopRecord()
|
||||
// #endif
|
||||
if(!isOut.value){
|
||||
setTimeout(()=>{
|
||||
let _data = {
|
||||
qnsId: unref(lastTalkingInfo).qnsId,// 问题ID 必输项:true 类型:String
|
||||
pgrphId: unref(lastTalkingInfo).pgrphId,// 段落ID 必输项:true 类型:String
|
||||
qstLogId: unref(qstLogId),// 段落ID 必输项:true 类型:String
|
||||
crsId: crsId.value,// 课程ID 必输项:true 类型:String
|
||||
stdyBatch: stdyBatch.value,// 学习批次 必输项:true 类型:String
|
||||
ansterContent: '',// 回答文本内容 必输项:false 类型:String
|
||||
}
|
||||
let _id = new Date().getTime() + 'id'
|
||||
//#ifndef APP-PLUS
|
||||
// h5 假数据
|
||||
talkingList.value.push({
|
||||
crsId: crsId.value,
|
||||
pgrphId: unref(lastTalkingInfo).pgrphId,
|
||||
qnsId: unref(lastTalkingInfo).qnsId,
|
||||
talkingContent: '',
|
||||
talkingVoice: audioPath.value,
|
||||
type: 1,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
id: _id
|
||||
})
|
||||
scrollToBottomNow()
|
||||
// #endif
|
||||
//#ifdef APP-PLUS
|
||||
const uploadRecordNow = (voicePath) => {
|
||||
|
||||
let _data = {
|
||||
qnsId: unref(lastTalkingInfo).qnsId,// 问题ID 必输项:true 类型:String
|
||||
pgrphId: unref(lastTalkingInfo).pgrphId,// 段落ID 必输项:true 类型:String
|
||||
qstLogId: unref(qstLogId),// 段落ID 必输项:true 类型:String
|
||||
crsId: crsId.value,// 课程ID 必输项:true 类型:String
|
||||
stdyBatch: stdyBatch.value,// 学习批次 必输项:true 类型:String
|
||||
ansterContent: '',// 回答文本内容 必输项:false 类型:String
|
||||
}
|
||||
let _id = new Date().getTime() + 'id'
|
||||
//#ifndef APP-PLUS
|
||||
// h5 假数据
|
||||
talkingList.value.push({
|
||||
crsId: crsId.value,
|
||||
pgrphId: unref(lastTalkingInfo).pgrphId,
|
||||
qnsId: unref(lastTalkingInfo).qnsId,
|
||||
talkingContent: '',
|
||||
talkingVoice: audioPath.value,
|
||||
intrctId: '',
|
||||
isLoading: true,
|
||||
type: 1,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
id: _id
|
||||
})
|
||||
scrollToBottomNow()
|
||||
commonUploadVoiceFile(audioPath.value, '/trastudy/traStdyInfo/studyAnswerVoiceUp', _data).then(res=>{
|
||||
let _res = JSON.parse(res.data)
|
||||
if(_res.rtnCode === '0000'){
|
||||
// talkingList.value.pop()
|
||||
// talkingList.value.push({
|
||||
// crsId: crsId.value,
|
||||
// pgrphId: _data.pgrphId,
|
||||
// qstLogId: _data.qstLogId,
|
||||
// qnsId: _data.qnsId,
|
||||
// talkingContent: '',
|
||||
// talkingVoice: audioPath.value,
|
||||
// intrctId: res.body||'',
|
||||
// type: 1,
|
||||
// userInfo: {...choiceTeacherInfo.value},
|
||||
// id: _id
|
||||
// })
|
||||
talkingList.value = talkingList.value.map(t=>{
|
||||
if(t.id === _id){
|
||||
return {
|
||||
crsId: crsId.value,
|
||||
pgrphId: _data.pgrphId,
|
||||
qstLogId: _data.qstLogId,
|
||||
qnsId: _data.qnsId,
|
||||
talkingContent: '',
|
||||
talkingVoice: audioPath.value,
|
||||
intrctId: res.body||'',
|
||||
type: 1,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
id: _id
|
||||
}
|
||||
}else{
|
||||
return t
|
||||
}
|
||||
})
|
||||
scrollToBottomNow()
|
||||
}else{}
|
||||
}).catch(err=>{
|
||||
talkingList.value = talkingList.value.filter(t=>t.id !== _id)
|
||||
uni.showToast({
|
||||
title: '系统异常,请联系管理员',
|
||||
icon: "none",
|
||||
duration:1000
|
||||
});
|
||||
})
|
||||
// #endif
|
||||
},1000)
|
||||
}
|
||||
}
|
||||
|
||||
const handleMove = (obj) => {
|
||||
touchX.value = obj.changedTouches[0].pageX
|
||||
touchY.value = obj.changedTouches[0].pageY
|
||||
}
|
||||
|
||||
const keyboardIsShow = ref(false)
|
||||
// 发送文本
|
||||
const showKeyboard = () => {
|
||||
if(lastTalkingInfo.value.type === 4){
|
||||
if(keyboardIsShow.value){
|
||||
if(answerValue.value){
|
||||
let _data = {
|
||||
qnsId: unref(lastTalkingInfo).qnsId,// 问题ID 必输项:true 类型:String
|
||||
pgrphId: unref(lastTalkingInfo).pgrphId,// 段落ID 必输项:true 类型:String
|
||||
qstLogId: unref(qstLogId),// 段落ID 必输项:true 类型:String
|
||||
crsId: crsId.value,// 课程ID 必输项:true 类型:String
|
||||
stdyBatch: stdyBatch.value,// 学习批次 必输项:true 类型:String
|
||||
ansterContent: answerValue.value // 回答文本内容 必输项:false 类型:String
|
||||
}
|
||||
studyAnswerTextUpApi(_data).then(res=>{
|
||||
if(res.rtnCode === '0000'){
|
||||
let _id = new Date().getTime() + 'id'
|
||||
talkingList.value.push({
|
||||
scrollToBottomNow()
|
||||
// #endif
|
||||
//#ifdef APP-PLUS
|
||||
talkingList.value.push({
|
||||
crsId: crsId.value,
|
||||
pgrphId: unref(lastTalkingInfo).pgrphId,
|
||||
qnsId: unref(lastTalkingInfo).qnsId,
|
||||
talkingContent: '',
|
||||
talkingVoice: audioPath.value,
|
||||
intrctId: '',
|
||||
isLoading: true,
|
||||
type: 1,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
id: _id
|
||||
})
|
||||
scrollToBottomNow()
|
||||
commonUploadVoiceFile(audioPath.value, '/trastudy/traStdyInfo/studyAnswerVoiceUp', _data).then(res=>{
|
||||
let _res = JSON.parse(res.data)
|
||||
if(_res.rtnCode === '0000'){
|
||||
talkingList.value = talkingList.value.map(t=>{
|
||||
if(t.id === _id){
|
||||
return {
|
||||
crsId: crsId.value,
|
||||
pgrphId: _data.pgrphId,
|
||||
qstLogId: _data.qstLogId,
|
||||
qnsId: _data.qnsId,
|
||||
talkingContent: answerValue.value,
|
||||
talkingVoice: '',
|
||||
talkingContent: '',
|
||||
talkingVoice: audioPath.value,
|
||||
intrctId: res.body||'',
|
||||
type: 2,
|
||||
type: 1,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
id: _id
|
||||
})
|
||||
scrollToBottomNow()
|
||||
answerValue.value = ''
|
||||
keyboardIsShow.value = !keyboardIsShow.value
|
||||
}
|
||||
}else{
|
||||
return t
|
||||
}
|
||||
})
|
||||
}else{
|
||||
keyboardIsShow.value = !keyboardIsShow.value
|
||||
}
|
||||
}else{
|
||||
keyboardIsShow.value = !keyboardIsShow.value
|
||||
}
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '请先获取问题信息!',
|
||||
icon: "none",
|
||||
duration:1000
|
||||
scrollToBottomNow()
|
||||
}else{}
|
||||
}).catch(err=>{
|
||||
talkingList.value = talkingList.value.filter(t=>t.id !== _id)
|
||||
uni.showToast({
|
||||
title: '系统异常,请联系管理员',
|
||||
icon: "none",
|
||||
duration:1000
|
||||
});
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
// 发送文本
|
||||
const submitAnswerNow = (val, cb) => {
|
||||
let _data = {
|
||||
qnsId: unref(lastTalkingInfo).qnsId,// 问题ID 必输项:true 类型:String
|
||||
pgrphId: unref(lastTalkingInfo).pgrphId,// 段落ID 必输项:true 类型:String
|
||||
qstLogId: unref(qstLogId),// 段落ID 必输项:true 类型:String
|
||||
crsId: crsId.value,// 课程ID 必输项:true 类型:String
|
||||
stdyBatch: stdyBatch.value,// 学习批次 必输项:true 类型:String
|
||||
ansterContent: val // 回答文本内容 必输项:false 类型:String
|
||||
}
|
||||
studyAnswerTextUpApi(_data).then(res=>{
|
||||
if(res.rtnCode === '0000'){
|
||||
let _id = new Date().getTime() + 'id'
|
||||
talkingList.value.push({
|
||||
crsId: crsId.value,
|
||||
pgrphId: _data.pgrphId,
|
||||
qstLogId: _data.qstLogId,
|
||||
qnsId: _data.qnsId,
|
||||
talkingContent: val,
|
||||
talkingVoice: '',
|
||||
intrctId: res.body||'',
|
||||
type: 2,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
id: _id
|
||||
})
|
||||
scrollToBottomNow()
|
||||
cb && cb()
|
||||
}
|
||||
})
|
||||
}
|
||||
// 撤回
|
||||
const withdrawNow = (data) => {
|
||||
@@ -724,18 +596,20 @@ const finishQuestionNow = (data) => {
|
||||
// common.msg('完成成功,开始获取评分维度数据!')
|
||||
loadingQstLogId.value = res.body.qstLogId
|
||||
let _id = new Date().getTime() + 'id'
|
||||
talkingList.value.push({
|
||||
lastTalkingInfo.value = {
|
||||
isLoading: true,
|
||||
id: _id,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
type: 5
|
||||
})
|
||||
}
|
||||
talkingList.value.push(lastTalkingInfo.value)
|
||||
scrollToBottomNow(0)
|
||||
getQuestionEvalateRequest(_id,data)
|
||||
})
|
||||
}
|
||||
// 查询问题回答评分
|
||||
const getQuestionEvalateRequest = (id, data) => {
|
||||
console.log( 'qstLogId',data.qstLogId)
|
||||
if(loadingQstLogId.value){
|
||||
queryQuestionEvalateApi({
|
||||
qstLogId:loadingQstLogId.value
|
||||
@@ -744,13 +618,15 @@ const getQuestionEvalateRequest = (id, data) => {
|
||||
let _body = res.body
|
||||
talkingList.value = talkingList.value.map(t=>{
|
||||
if(t.id === id){
|
||||
return {
|
||||
lastTalkingInfo.value = {
|
||||
..._body,
|
||||
pgrphId: data.pgrphId,
|
||||
qstLogId: loadingQstLogId.value,
|
||||
id,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
type: 5
|
||||
}
|
||||
return lastTalkingInfo.value
|
||||
}else{
|
||||
return t
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user