Files
tra-app/src/pages/course/study.vue
T

974 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>