974 lines
24 KiB
Vue
974 lines
24 KiB
Vue
<template>
|
||
<view class="course-study max_page">
|
||
<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">
|
||
{{chooseRate}}倍
|
||
<img src="@/static/images/course/setting.png" alt="">
|
||
</view>
|
||
<view class="body-title">
|
||
<uv-icon class="arrow-icon" name="arrow-left" @click="common.navigateBack()"/>
|
||
语言选择,开启学习之旅
|
||
</view>
|
||
<view class="voice-list">
|
||
<uv-radio-group v-model="choiceTeacher">
|
||
<view class="voice-item" v-for="item in teacherList" :key="item.teacherNo" @click="choiceTeacher = item.teacherNo">
|
||
<view class="avatar-box">
|
||
<ImagePreview class="img-box" :imgId="item.imgAddr" :isCache="true" :width="120" :height="160"></ImagePreview>
|
||
</view>
|
||
<view class="right-cont">
|
||
<view class="right-name">{{item.teacherName}}</view>
|
||
<view class="right-desc">描述:{{item.voiceDesc || '--'}}</view>
|
||
<view class="audio-box">
|
||
<view :class="['talking-gif', activeVoiceTeachNo === item.teacherNo ? 'is-play':'']"></view>
|
||
<view class="play-btn" @click="playTeacherVoice(item)">
|
||
<image class="icon" v-if="activeVoiceTeachNo !== item.teacherNo" src="@/static/images/course/play-blue.png" style="width: 100%;height: 100%;"></image>
|
||
<image class="icon" v-else src="@/static/images/course/stop-blue.png" style="width: 100%;height: 100%;"></image>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<uv-radio :name="item.teacherNo" class="radio-box" @click.stop/>
|
||
</view>
|
||
</uv-radio-group>
|
||
<view class="start-btns" @click="nextStep">
|
||
开启学习之旅
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="course-study-body" v-show="step === 2" @click="playRecord">
|
||
<view class="seek-setting" @click="showSeekModel = true">
|
||
{{chooseRate}} 倍
|
||
<img src="@/static/images/course/setting.png" alt="">
|
||
</view>
|
||
<view class="body-title" @click="scrollToBottomNow">
|
||
<uv-icon class="arrow-icon" name="arrow-left" @click="common.navigateBack()"/>
|
||
课程学习{{scrollTop}}
|
||
</view>
|
||
<scroll-view
|
||
class="talking-list"
|
||
:scroll-y="true"
|
||
:scroll-top="scrollTop"
|
||
:show-scrollbar="false"
|
||
:scroll-with-animation="true"
|
||
>
|
||
<!-- <view class="talking-list-cont" id="scroll-box" ref="scrollBoxRef"> -->
|
||
<view class="study-num">
|
||
<view class="color-blue">{{ showOrder }}</view> / {{ pgrphNum }}
|
||
</view>
|
||
<TalkingItem
|
||
class="talking-item"
|
||
v-for="item,index in talkingList"
|
||
:key="'item' + item.id"
|
||
:type="item.type"
|
||
:dataInfo="item"
|
||
:activeVoiceId="activeVoiceTalkingItemId"
|
||
:isPlaying="activeVoiceTalkingItemId === item.id"
|
||
:voiceRate="chooseRate"
|
||
@changePlay="changePlayItemId"
|
||
@nextQuestion="nextQuestionSuccess"
|
||
@withdraw="withdrawNow"
|
||
@finishQuestion="finishQuestionNow"
|
||
:id="'item' + item.id"
|
||
:isLast="talkingList.length === (index+1)"
|
||
></TalkingItem>
|
||
<!-- <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" src="/src/static/images/course/jianpan.png" mode=""></image>
|
||
</view>
|
||
</view>
|
||
</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">
|
||
<view class="box-title">倍速
|
||
</view>
|
||
<view class="box-btns">
|
||
<view
|
||
v-for="item in rateList"
|
||
:class="{'is-active':item === chooseRate}"
|
||
@click="chooseRateNow(item)"
|
||
>{{item}}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</uv-overlay>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { reactive, ref, computed, unref, onMounted, onUnmounted, getCurrentInstance, nextTick } from 'vue';
|
||
import { onLoad,onShow,onHide } from '@dcloudio/uni-app';
|
||
import {
|
||
previewFile,
|
||
downloadFile,
|
||
commonUploadVoiceFile,
|
||
downloadVoiceFile,
|
||
uploadVoiceFile,
|
||
} from "@/api/common.js"
|
||
import { getToken } from '@/common/common.js'
|
||
import { get_base_url, goto_login_fun } from '@/api/request'
|
||
import {
|
||
getCourseStudyInfoApi,
|
||
queryTraStdyBatchWaitParagraphInfoApi,
|
||
audioTranscriptionsApi,
|
||
deleteTraStdyInfoByIdApi,
|
||
queryTraStdyBatchWaitQuestionInfoApi,
|
||
studyAnswerTextUpApi,
|
||
withdrawalAnswerApi,
|
||
waitMakeEvaluateApi
|
||
} from "@/api/study.js"
|
||
import common from '@/common/common';
|
||
import TalkingItem from '@/pages/course/components/talkingItem.vue'
|
||
import ImagePreview from '@/components/image-preview/image-preview.vue'
|
||
|
||
import { useSocketStore } from "@/store/socket.js"
|
||
import { storeToRefs } from 'pinia'
|
||
|
||
const socketStore = useSocketStore()
|
||
const { SocketObj } = storeToRefs(socketStore)
|
||
|
||
const { proxy } = getCurrentInstance()
|
||
const crsNum = ref('');
|
||
const crsId = ref('');
|
||
const step = ref(0)
|
||
const teacherList = ref([])
|
||
const choiceTeacher = ref('')
|
||
const videoUrlShow = ref('')
|
||
const talkingList = ref([])
|
||
const activeVoiceTalkingItemId = ref('')
|
||
const answerValue = ref('')
|
||
const inputRef = ref('')
|
||
// 初始化数据
|
||
const getData = async () => {
|
||
try{
|
||
const { body } = await getCourseStudyInfoApi({crsId: crsId.value})
|
||
initsocketTask()
|
||
teacherList.value = body.teacheList.map(t=>({
|
||
...t,
|
||
voicePath: '',
|
||
voiceObj: null
|
||
}))
|
||
if(body.stdyProgressFlag === 'N'){
|
||
step.value = 1
|
||
}else{
|
||
common.show('提示信息', '此门课程已有学习历史,请选择是否继续学习?',true, '重新开始','继续学习').then((res) => {
|
||
if(res) {
|
||
// 继续学习 , 获取学习历史接口
|
||
// 滚动到最下面
|
||
scrollToBottomNow()
|
||
choiceTeacher.value = body.choiceTeacher
|
||
sendMessage({
|
||
"commond" : 'STDY',
|
||
"body" : {
|
||
crsId: crsId.value,
|
||
teacherNo: choiceTeacher.value
|
||
}
|
||
})
|
||
step.value = 2
|
||
}else{
|
||
// 重新开始
|
||
// 删除学习信息
|
||
deleteTraStdyInfoByIdApi({
|
||
id:''
|
||
}).then(res=>{
|
||
step.value = 1
|
||
teacherList.value = body.teacheList.map(t=>({
|
||
...t,
|
||
voicePath: '',
|
||
voiceObj: null
|
||
}))
|
||
}).catch(t=>{
|
||
step.value = 1
|
||
teacherList.value = body.teacheList.map(t=>({
|
||
...t,
|
||
voicePath: '',
|
||
voiceObj: null
|
||
}))
|
||
})
|
||
}
|
||
}).finally(() => {})
|
||
}
|
||
}catch{
|
||
|
||
}
|
||
// downloadFile('S3F0250640161332025061618052000000267276').then(res=>{
|
||
// videoUrlShow.value = res.tempFilePath
|
||
// })
|
||
};
|
||
|
||
// 关闭播放状态
|
||
const changePlayItemId = (id) => {
|
||
if(activeVoiceTalkingItemId.value === id){
|
||
activeVoiceTalkingItemId.value = ''
|
||
}else{
|
||
activeVoiceTalkingItemId.value = id
|
||
}
|
||
}
|
||
// 选择的教师对象信息
|
||
const choiceTeacherInfo = computed(()=>{
|
||
return teacherList.value.find(t=> t.teacherNo === choiceTeacher.value)
|
||
})
|
||
|
||
const activeVoiceTeachNo = ref('')
|
||
const teacherVoiceObj = uni.createInnerAudioContext()
|
||
teacherVoiceObj.onEnded(()=>{
|
||
activeVoiceTeachNo.value = ''
|
||
teacherVoiceObj.src = ''
|
||
})
|
||
const playTeacherVoice = (item) =>{
|
||
teacherVoiceObj.stop()
|
||
teacherVoiceObj.src = ''
|
||
let _isStop = item.teacherNo === activeVoiceTeachNo.value
|
||
activeVoiceTeachNo.value = _isStop ? '' : item.teacherNo
|
||
if(_isStop) return
|
||
if(item.voicePath){
|
||
teacherVoiceObj.src = item.voicePath
|
||
teacherVoiceObj.play()
|
||
}else{
|
||
downloadVoiceFile('/trastudy/traStdyInfo/trialListening?teachNo='+item.teacherNo).then(res=>{
|
||
item.voicePath = res.tempFilePath
|
||
teacherVoiceObj.src = item.voicePath
|
||
teacherVoiceObj.play()
|
||
})
|
||
}
|
||
}
|
||
var socketTask = null
|
||
const nextStep = () => {
|
||
if(choiceTeacher.value){
|
||
teacherVoiceObj.destroy()
|
||
sendMessage({
|
||
"commond" : 'STDY',
|
||
"body" : {
|
||
crsId: crsId.value,
|
||
teacherNo: choiceTeacher.value
|
||
}
|
||
})
|
||
step.value = 2
|
||
}else{
|
||
uni.showToast({
|
||
title: '请选择一位教师!',
|
||
icon: "none",
|
||
duration:1000
|
||
});
|
||
}
|
||
}
|
||
|
||
const pgrphNum = ref(1)
|
||
const showOrder = ref(0)
|
||
// 获取段落
|
||
const getGraphInfoUnStudy = () => {
|
||
queryTraStdyBatchWaitParagraphInfoApi({
|
||
crsId: crsId.value,
|
||
stdyId: unref(stdyId),
|
||
stdyBatch: unref(stdyBatch)
|
||
}).then(res=>{
|
||
let _id = new Date().getTime() + 'id'
|
||
lastTalkingInfo.value = {
|
||
...res.body,
|
||
type: 3,
|
||
userInfo: {...choiceTeacherInfo.value},
|
||
id: _id
|
||
}
|
||
talkingList.value.push(lastTalkingInfo.value)
|
||
|
||
pgrphNum.value = res.body.pgrphNum
|
||
showOrder.value = res.body.showOrder
|
||
logId.value = res.body.logId || ''
|
||
scrollToBottomNow()
|
||
})
|
||
}
|
||
const lastTalkingInfo = ref({})
|
||
const qstLogId = ref('')
|
||
// 获取问题
|
||
const getQuestionInfoUnStudy = (pgrphId) => {
|
||
queryTraStdyBatchWaitQuestionInfoApi({
|
||
crsId: crsId.value,
|
||
stdyId: unref(stdyId),
|
||
stdyBatch: unref(stdyBatch),
|
||
logId: unref(logId),
|
||
pgrphId
|
||
}).then(res=>{
|
||
let _id = new Date().getTime() + 'id'
|
||
lastTalkingInfo.value = {
|
||
...res.body,
|
||
type: 4,
|
||
userInfo: {...choiceTeacherInfo.value},
|
||
id: _id
|
||
}
|
||
talkingList.value.push(lastTalkingInfo.value)
|
||
qstLogId.value = res.body.qstLogId
|
||
scrollToBottomNow()
|
||
})
|
||
}
|
||
|
||
// 继续 执行方法
|
||
const nextQuestionSuccess = (info) => {
|
||
let _id = new Date().getTime() + 'id'
|
||
talkingList.value.push({
|
||
crsId: info.crsId,
|
||
pgrphId: info.pgrphId,
|
||
talkingContent: '继续',
|
||
type: 0,
|
||
id: _id
|
||
})
|
||
scrollToBottomNow()
|
||
// getGraphInfoUnStudy()
|
||
getQuestionInfoUnStudy(info.pgrphId)
|
||
}
|
||
const scrollBoxRef = ref()
|
||
const scrollTop = ref(99999)
|
||
const scrollToBottomNow = () => {
|
||
nextTick(()=>{
|
||
setTimeout(() => {
|
||
scrollTop.value += 1
|
||
scrollTop.value += 1
|
||
let _arr = talkingList.value || []
|
||
if(_arr.length && _arr.length > 0){
|
||
let _last = talkingList.value[talkingList.value.length - 1]
|
||
uni.pageScrollTo({
|
||
selector: '#item' + _last.id,
|
||
duration: 300
|
||
})
|
||
}
|
||
},200)
|
||
})
|
||
}
|
||
|
||
const reconnectTimer = null // 重连timer
|
||
const isManualClose = ref(false) // 是否手动关闭
|
||
|
||
const stdyId = ref('')
|
||
const stdyBatch = ref('')
|
||
const logId = ref('')
|
||
// ws 初始化逻辑
|
||
const initsocketTask = () => {
|
||
socketStore.creatSocket()
|
||
unref(SocketObj).on('message', (res)=>{
|
||
const { rtnCode, body, commond } = JSON.parse(res.data)
|
||
if(rtnCode === '0000'){
|
||
if(commond === 'STDYBTH' && !stdyId.value){
|
||
stdyId.value = body.stdyId || ''
|
||
stdyBatch.value = body.stdyBatch || ''
|
||
logId.value = body.logId || ''
|
||
getGraphInfoUnStudy()
|
||
}
|
||
}else{
|
||
if(['0005', 'QQ0005'].includes(res.rtnCode)) {
|
||
goto_login_fun();
|
||
}
|
||
}
|
||
})
|
||
}
|
||
const reconnect = ()=> {
|
||
if(reconnectTimer || isManualClose.value) return
|
||
reconnectTimer = setTimeout(()=>{
|
||
initsocketTask()
|
||
},3000)
|
||
}
|
||
const sendMessage = (data) => {
|
||
unref(SocketObj).send(data)
|
||
}
|
||
const closeWebSocket = () => {
|
||
isManualClose.value = true
|
||
if(socketTask){
|
||
// socketTask.close()
|
||
socketTask = null
|
||
uni.closeSocket({})
|
||
}
|
||
}
|
||
// ws 结束
|
||
|
||
onLoad((params) => {
|
||
crsId.value = params.crsId||'';
|
||
crsNum.value = params.crsNum||'';
|
||
});
|
||
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
|
||
}
|
||
//#ifndef APP-PLUS
|
||
// h5 假数据
|
||
let _id = new Date().getTime() + 'id'
|
||
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
|
||
commonUploadVoiceFile(audioPath.value, '/trastudy/traStdyInfo/studyAnswerVoiceUp', _data).then(res=>{
|
||
console.log(res.data)
|
||
let _res = JSON.parse(res.data)
|
||
if(_res.rtnCode === '0000'){
|
||
let _id = new Date().getTime() + 'id'
|
||
talkingList.value.push({
|
||
crsId: crsId.value,
|
||
pgrphId: unref(lastTalkingInfo).pgrphId,
|
||
qnsId: unref(lastTalkingInfo).qnsId,
|
||
talkingContent: '',
|
||
talkingVoice: audioPath.value,
|
||
intrctId: res.body||'',
|
||
type: 1,
|
||
userInfo: {...choiceTeacherInfo.value},
|
||
id: _id
|
||
})
|
||
scrollToBottomNow()
|
||
}
|
||
}).catch(err=>{
|
||
uni.showToast({
|
||
title: err||'系统异常,请联系管理员',
|
||
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({
|
||
crsId: crsId.value,
|
||
pgrphId: unref(lastTalkingInfo).pgrphId,
|
||
qstLogId: unref(lastTalkingInfo).qstLogId,
|
||
qnsId: unref(lastTalkingInfo).qnsId,
|
||
talkingContent: answerValue.value,
|
||
talkingVoice: '',
|
||
intrctId: res.body||'',
|
||
type: 2,
|
||
userInfo: {...choiceTeacherInfo.value},
|
||
id: _id
|
||
})
|
||
scrollToBottomNow()
|
||
answerValue.value = ''
|
||
keyboardIsShow.value = !keyboardIsShow.value
|
||
}
|
||
})
|
||
}else{
|
||
keyboardIsShow.value = !keyboardIsShow.value
|
||
}
|
||
}else{
|
||
keyboardIsShow.value = !keyboardIsShow.value
|
||
}
|
||
}else{
|
||
uni.showToast({
|
||
title: '请先获取问题信息!',
|
||
icon: "none",
|
||
duration:1000
|
||
})
|
||
}
|
||
}
|
||
// 撤回
|
||
const withdrawNow = (data) => {
|
||
withdrawalAnswerApi({
|
||
intrctId: data.intrctId
|
||
}).then(res=> {
|
||
// 删除撤回的数据item
|
||
common.msg('撤回成功!')
|
||
talkingList.value = talkingList.value.filter(t => t.intrctId !== data.intrctId)
|
||
})
|
||
}
|
||
// 完成
|
||
const finishQuestionNow = (data) => {
|
||
waitMakeEvaluateApi({
|
||
qstLogId: data.qstLogId
|
||
}).then(res=> {
|
||
console.log(res.body.processStat)
|
||
common.msg('完成成功,开始获取评分维度数据!')
|
||
// qstLogId 问题日志ID String
|
||
// qnsId 问题ID String
|
||
// processStat 状态 String
|
||
// message 处理消息 String
|
||
})
|
||
}
|
||
|
||
const showSeekModel = ref(false)
|
||
const rateList = ref(['0.5', '0.8', '1.0', '1.5', '2.0'])
|
||
const chooseRate = ref('1.0')
|
||
const chooseRateNow = (item) => {
|
||
chooseRate.value = item
|
||
showSeekModel.value = false
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.course-study{
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
.top-bg{
|
||
background: linear-gradient(16deg,rgba(234,246,255,0) 0%,#c3e6ff 100%);
|
||
height: 480rpx;
|
||
width: 750rpx;
|
||
}
|
||
.bot-bg{
|
||
// background-color: #F6F8FF;
|
||
background: linear-gradient(136deg,rgba(234,246,255,0) 0%,#c3e6ff 100%);
|
||
width: 750rpx;
|
||
flex: 1;
|
||
}
|
||
.seek-setting{
|
||
position: absolute;
|
||
z-index: 3;
|
||
right: 20rpx;
|
||
top: 68rpx;
|
||
font-size: 26rpx;
|
||
width: 140rpx;
|
||
height: 52rpx;
|
||
padding: 10rpx 0;
|
||
overflow: hidden;
|
||
line-height: 32rpx;
|
||
text-align: right;
|
||
padding-right: 48rpx;
|
||
|
||
img{
|
||
width: 30rpx;
|
||
height: 32rpx;
|
||
position: absolute;
|
||
right: 0;
|
||
top: 10rpx;
|
||
}
|
||
}
|
||
.course-study-body{
|
||
position: absolute;
|
||
overflow: hidden;
|
||
left:0;
|
||
top: 0;
|
||
height: 100%;
|
||
width: 100%;
|
||
padding:0 0rpx;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
flex-direction: column;
|
||
.body-title{
|
||
height: 150rpx;
|
||
text-align: center;
|
||
font-size: 33rpx;
|
||
padding-top: 70rpx;
|
||
line-height: 46rpx;
|
||
box-sizing: border-box;
|
||
font-weight: 500;
|
||
color:#000;
|
||
position: relative;
|
||
// margin-bottom: 23rpx;
|
||
.arrow-icon{
|
||
position: absolute;
|
||
left:36rpx;
|
||
top:80rpx;
|
||
color: #000;
|
||
}
|
||
}
|
||
.talking-list{
|
||
flex:1;
|
||
overflow-y: auto;
|
||
padding: 30rpx;
|
||
background: url(@/static/images/course/study-bg.png) no-repeat;
|
||
background-size: cover;
|
||
border-radius: 30rpx 30rpx 0 0;
|
||
box-sizing: border-box;
|
||
width: 100%;
|
||
.talking-list-cont{
|
||
padding: 0;
|
||
}
|
||
.study-num{
|
||
height: 36rpx;
|
||
line-height: 36rpx;
|
||
text-align: center;
|
||
margin-bottom: 15rpx;
|
||
.color-blue{
|
||
color: #06f;
|
||
display: inline;
|
||
}
|
||
}
|
||
.talking-item{
|
||
margin-bottom: 46rpx;
|
||
}
|
||
}
|
||
.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;
|
||
}
|
||
}
|
||
}
|
||
.voice-list{
|
||
flex:1;
|
||
overflow-y: auto;
|
||
padding: 10rpx 40rpx 30rpx;
|
||
.voice-item{
|
||
min-height: 246rpx;
|
||
width: 100%;
|
||
overflow: hidden;
|
||
background-color: #fff;
|
||
border-radius: 16rpx;
|
||
display: flex;
|
||
padding: 25rpx;
|
||
position: relative;
|
||
&:not(:last-child){
|
||
margin-bottom: 30rpx;
|
||
}
|
||
.avatar-box{
|
||
width: 160rpx;
|
||
height: 207rpx;
|
||
margin-right: 20rpx;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
background-color: #ccc;
|
||
.img-box{
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
.right-cont{
|
||
flex:1;
|
||
.right-name{
|
||
width: 380rpx;
|
||
line-height: 40rpx;
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
margin-bottom: 25rpx;
|
||
word-break: break-all;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
overflow: hidden;
|
||
}
|
||
.right-desc{
|
||
width: 380rpx;
|
||
line-height: 38rpx;
|
||
font-size: 25rpx;
|
||
color: #999;
|
||
margin-bottom: 12rpx;
|
||
word-break: break-all;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
overflow: hidden;
|
||
}
|
||
.audio-box{
|
||
width: 90%;
|
||
height: 70rpx;
|
||
line-height: 70rpx;
|
||
background-color: #eaf2ff;
|
||
padding: 15rpx 25rpx;
|
||
overflow: hidden;
|
||
.talking-gif{
|
||
width: 140rpx;
|
||
height: 40rpx;
|
||
// background-color: #ccc;
|
||
background: url(@/static/images/course/voice-gray.png) no-repeat;
|
||
background-size: 100%;
|
||
box-sizing: border-box;
|
||
float: left;
|
||
&.is-play{
|
||
background: url(@/static/images/course/voice-gif.gif) no-repeat;
|
||
background-size: 100%;
|
||
}
|
||
}
|
||
.talking-time{
|
||
float: right;
|
||
text-align: right;
|
||
line-height: 40rpx;
|
||
font-size: 23rpx;
|
||
color: #b1bbd3;
|
||
}
|
||
.play-btn{
|
||
float:right;
|
||
width: 35rpx;
|
||
height: 40rpx;
|
||
padding-top:2rpx;
|
||
line-height: 35rpx;
|
||
margin-left: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
.radio-box{
|
||
position: absolute;
|
||
right: 20rpx;
|
||
top: 20rpx;
|
||
}
|
||
}
|
||
.start-btns{
|
||
margin-top:20rpx;
|
||
height: 80rpx;
|
||
width: 100%;
|
||
background-color: #06f;
|
||
color:#fff;
|
||
text-align: center;
|
||
line-height: 80rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.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>
|