Files
tra-app/src/pages/courseRecord/components/talkingItem.vue
T

925 lines
23 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.
<!-- type:
0纯文本信息不翻译
1语音回答
2 文本回答
3 段落信息
4 问题信息
5 统计信息
6 发送loading状态
7 教师反馈文本不翻译
8 问题反馈信息
9 已学完当前知识点反馈信息
-->
<template>
<view :class="['ai-answer', props.class]" :id="props.id" v-if="[3,4,5,8,9].indexOf(type) >= 0">
<!-- 对话信息 -->
<view :class="['talking-info', [4].indexOf(type) >= 0 ? 'talking-info-less':''] ">
<!-- 语音加载状态 -->
<view :class="['talking-gif', !voiceLoading && (activeVoiceId === dataInfo.id)?'is-play':'']"
v-if="!([3, 4, 5, 8, 9].indexOf(type) >= 0)">
<CommonLoading color="#06f" v-show="voiceLoading" />
</view>
<view class="talking-cont">
<!-- 题干/段落内容 -->
<view class="talking-num"> {{dataInfo.titleNum||''}} </view>
<view class="talking-num"> {{dataInfo.title||''}} </view>
<text class="talking-text" v-if="[3, 5, 6, 9].indexOf(type) >= 0 && !dataInfo.isLoading">
{{ showContent }}
</text>
<text class="talking-text" v-if="[4].indexOf(type) >= 0 && dataInfo.qnsTyp === 'ES'">
<!-- 请您思考并作答:<br> -->
{{ showContent }}
</text>
<!-- 试题问题 -->
<Subject v-if="[4, 8].indexOf(type) >= 0" :isPreview="!isLast" :item="subjectInfo"
:mode="mode" :clearResult="type === 4" @subject_click="subject_click" />
<!-- <esQuestion v-if="[4, 8].indexOf(type) >= 0 && dataInfo.qnsTyp === 'ES'" @changePlay="changePlay"
:activeVoiceId="activeVoiceId" :dataInfo="esSubjectInfo" /> -->
<!-- 试题问题反馈 -->
<!-- <RadioSubjectRequest v-if="[8].indexOf(type) >= 0 && dataInfo.qnsTyp !== 'ES'" :item="dataInfo" :mode="mode" @subject_click="subject_click" /> -->
<!-- 段落图片视频预览 -->
<!-- <view v-if="type === 3" style="overflow: hidden;">
<ImagePreview class="cont-img-box" v-if="(dataInfo.imageAddrs||[]).length>0" :imgId="dataInfo.imageAddrs[0]" :previewDetail="true"></ImagePreview>
<VideoPreview class="cont-img-box" v-if="(dataInfo.vidoAddrs||[]).length>0" :fileId="dataInfo.vidoAddrs[0]"></VideoPreview>
</view> -->
<!-- 举例预览 -->
<view class="talking-text" v-if="type === 3 && dataInfo.exampie " style="overflow: hidden;">
举例{{ dataInfo.exampie }}
</view>
<view style="overflow: hidden;">
<ImagePreview class="cont-img-box" v-if="dataInfo.imgAddr" :src="dataInfo.imgAddr" :previewDetail="true">
</ImagePreview>
<VideoPreview class="cont-img-box" v-if="dataInfo.vidAddr"
:src="dataInfo.vidAddr"
:picSrc="dataInfo.vidImgAddr"
></VideoPreview>
</view>
<!-- 维度信息预览 -->
<!-- <view v-if="[4, 8].indexOf(type) >= 0 && dataInfo.qnsTyp === 'ES'" style="padding-top: 16rpx;">
<ChartFour v-if="esSubjectInfo?.evalSettingVos?.length === 4" :dataList="esSubjectInfo.evalSettingVos"
:score="intrctGrade" />
<ChartThree v-if="esSubjectInfo?.evalSettingVos?.length === 3" :dataList="esSubjectInfo.evalSettingVos"
:score="intrctGrade" />
<ChartFive v-if="esSubjectInfo?.evalSettingVos?.length === 5" :dataList="esSubjectInfo.evalSettingVos"
:score="intrctGrade" />
</view> -->
<!-- 参考答案 -->
<view class="talking-text" v-if="type === 5 && !dataInfo.isLoading" style="overflow: hidden;">
参考答案{{ dataInfo.itemAnswer }}
</view>
</view>
<view class="btns-cont" v-show="!dataInfo.isLoading" v-if="!([3, 8, 4].indexOf(type) >= 0)">
<!-- 重新播放 -->
<view class="replay-btn" @click.stop="restartPlay" v-if="!([5, 8, 9].indexOf(type) >= 0)">
<image class="icon" src="@/static/images/course/replay.png" style="width: 100%;height: 100%;"></image>
</view>
<!-- 播放/暂停 -->
<view class="play-btn" v-if="!([5, 8, 9].indexOf(type) >= 0)">
<image class="icon" src="@/static/images/course/play.png" style="width: 100%;height: 100%;"
@click.stop="playVoice()" v-show="!isPlaying"></image>
<image class="icon" v-show="isPlaying" src="@/static/images/course/pause.png"
style="width: 100%;height: 100%;" @click.stop="pauseVoice"></image>
</view>
</view>
</view>
</view>
<!-- ai回答 -->
<view :class="['ai-answer', props.class]" :id="props.id" v-if="[7].indexOf(type) >= 0">
<view :class="['talking-info', [4,7].indexOf(type) >= 0 ? 'talking-info-less':''] ">
<view class="talking-cont">
<view class="talking-text">
{{ showContent }}
</view>
</view>
</view>
</view>
<!-- 用户对话 -->
<view :class="['user-answer', props.class]" :id="props.id" v-else-if="[1, 2].indexOf(type) >= 0">
<view class="talking-info">
<view class="right-time">{{voiceTime}}</view>
<view class="talking-cont">
<text :class="['talking-text translate-text loading']">
{{ showContent }}
</text>
</view>
<view class="btns-cont">
<!-- <view class="replay-btn">
<image class="icon" src="@/static/images/course/replay.png" style="width: 100%;height: 100%;"></image>
</view> -->
<view class="play-btn">
<image class="icon" @click.stop="playQnsVoice('qns', dataInfo)" v-show="!isPlaying"
src="@/static/images/course/play-blue.png" style="width: 100%;height: 100%;"></image>
<image class="icon" v-show="isPlaying" @click.stop="pauseVoice" src="@/static/images/course/stop-blue.png"
style="width: 100%;height: 100%;"></image>
</view>
<view class="icon text-btn" v-if="type === 1" @click.stop="translateVoice(dataInfo)"></view>
<view class="icon text-right-btn" @click.stop="finishQuestion(dataInfo)" v-show="isLast">完成</view>
<view class="icon text-right-btn" @click.stop="withdraw" v-show="showWithdraw">撤回
<!-- v-show="showWithdraw" -->
</view>
</view>
</view>
</view>
<view :class="['user-answer', props.class]" :id="props.id" v-else-if="[0, 6].indexOf(type) >= 0">
<view class="talking-info-less">
<text class="talking-text" v-if="type === 0">
{{ showContent }}
</text>
</view>
</view>
<view v-else></view>
</template>
<script setup>
import {
watch,
unref,
ref,
toRefs,
computed,
nextTick,
onMounted
} from 'vue'
import ImagePreview from '@/components/image-preview/image-preview.vue'
import VideoPreview from '@/components/image-preview/video-preview.vue'
import {
downloadVoiceFile,
uploadVoiceFile,
getAudioByText
} from "@/api/common.js"
import {
studyParagraphOverApi,
getAskAboutRawApi
} from "@/api/study.js"
import ChartFour from "@/pages/course/components/chartFour.vue"
import ChartThree from "@/pages/course/components/chartThree.vue"
import ChartFive from '@/pages/course/components/chartFive.vue'
import common from '@/common/common';
import {
useStorageStore
} from "@/store/storage.js"
import {
onUnload
} from '@dcloudio/uni-app'
import esQuestion from './esQuestion.vue'
import Subject from '@/components/examination/subject.vue'
// import RadioSubjectRequest from '@/pages/wrong_question_record/components/radio-subject.vue'
const storageStore = useStorageStore()
const audioCacheObj = computed(() => storageStore.audioObj)
const props = defineProps({
type: {
default: 0, // 1 userAnswer 0: AIAnswer
type: [Number, String]
},
dataInfo: {
default: () => ({}),
type: Object
},
teacherInfo: {
default: () => ({}),
type: Object
},
activeVoiceId: {
default: '',
type: String
},
isLast: {
default: false,
type: Boolean
},
isPlaying: {
default: false,
type: Boolean
},
voiceRate: {
default: '1.0',
type: [Number, String],
},
isTransform: {
default: false,
type: Boolean
},
lastQuestionInfo: {
default: () => ({}),
type: Object
},
class: {
default: '',
type: String
},
id: {
default: '',
type: String
}
})
const {
type,
dataInfo,
activeVoiceId,
isPlaying,
isLast,
lastQuestionInfo,
teacherInfo
} = toRefs(props)
const emit = defineEmits(['changePlay', 'nextQuestion', 'withdraw', 'finishQuestion', 'answerQuestion'])
const changePlay = (val) => {
emit('changePlay', val)
}
// 声音播放初始化
const talkVoiceObj = ref(uni.createInnerAudioContext())
talkVoiceObj.value.playbackRate = Number(props.voiceRate)
const itemVoice = ref('')
const subjectInfo = computed(() => {
return {
...dataInfo.value,
...(dataInfo.value?.traQnsInfoVo || {}),
my_answer: dataInfo.value?.traQnsInfoVo?.anserResult || ''
}
})
const esSubjectInfo = computed(() => {
return {
...dataInfo.value,
...(dataInfo.value.itemVos && dataInfo.value.itemVos.length > 0 ?
dataInfo.value.itemVos[0] :
{})
}
})
const intrctGrade = computed(() => {
let _sum = 0
let _arr = esSubjectInfo.value.evalSettingVos || []
_arr.forEach(t => {
_sum += t.anlyGrade
})
return _sum
})
const mode = ref('study') // 考试 examination 练习practice 学习study
const showWithdraw = computed(() => {
let _isMe = unref(lastQuestionInfo).qstLogId === unref(dataInfo).qstLogId
let _isQuestion = unref(lastQuestionInfo).isQuestion
return _isMe && _isQuestion
})
const voiceLoading = ref(false)
watch(() => props.teacherInfo, (val) => {
itemVoice.value = ''
talkVoiceObj.value.src = ''
}, {
deep: true,
immediate: true
})
watch(() => props.isPlaying, (val) => {
if (!val) {
talkVoiceObj.value?.pause()
}
}, {
deep: true,
immediate: true
})
watch(() => props.voiceRate, (val) => {
talkVoiceObj.value.playbackRate = Number(val)
}, {
deep: true,
immediate: true
})
watch(() => props.lastTalkingInfo, () => {}, {
deep: true,
immediate: true
})
watch(() => props.dataInfo, () => {}, {
deep: true,
immediate: true
})
const showGoOnStudyBtn = computed(() => {
if (!(showNextBtn.value && isLast.value)) {
return false
}
if (type.value === 5) {
return true
}
if (type.value === 8) {
return !!dataInfo.value.traQnsInfoVo?.judgeResult
}
if (type.value === 9) {
return dataInfo.value.stdyStat === 'Y'
}
return false
})
const transformContent = ref('')
const showContentBase = computed(() => {
if (props.isTransform) {
return transformContent.value
} else {
if (props.type === 1) return unref(dataInfo)?.chatContent || unref(dataInfo)?.talkingContent
else if (props.type === 2) return unref(dataInfo)?.chatContent || unref(dataInfo)?.talkingContent
else if (props.type === 3) return unref(dataInfo)?.chatContent || unref(dataInfo)?.pgrphContent
else if (props.type === 4) return unref(dataInfo)?.chatContent || unref(dataInfo)?.qnsContent
else if (props.type === 5) return unref(dataInfo)?.chatContent || unref(dataInfo)?.analyContent
else if (props.type === 9) return unref(dataInfo)?.chatContent || unref(dataInfo)?.analyContent
else if (props.type === 0) return unref(dataInfo)?.chatContent || unref(dataInfo)?.talkingContent
else return unref(dataInfo)?.chatContent || unref(dataInfo)?.talkingContent
}
})
const showContent = computed(() => {
let _str = showContentBase.value || ''
return _str.replace(/\/n/g, "\n")
})
const changeBr = (str = '') => {
return str.replace(/\/n/g, "\n")
}
const voiceTime = ref('')
const itemInfo = ref({})
onMounted(() => {
initVoice()
})
onUnload(() => {
pauseVoice()
})
talkVoiceObj.value.onEnded(() => {
emit('changePlay', '')
talkVoiceObj.value.src = ''
})
talkVoiceObj.value.onError(() => {
talkVoiceObj.value.src = ''
})
const pauseVoice = () => {
if (!talkVoiceObj.value) return
talkVoiceObj.value.pause()
emit('changePlay', '')
}
// 重播
const restartPlay = () => {
if (itemVoice.value) {
emit('changePlay', '')
emit('changePlay', unref(dataInfo)?.id)
setTimeout(() => {
talkVoiceObj.value.src = itemVoice.value
talkVoiceObj.value.seek(0)
talkVoiceObj.value.play()
}, 100)
} else {
playVoice()
}
}
const playVoice = (readType = 'pgth') => {
let _content = showContent.value
if (!_content) {
common.msg('没有可以播放的文字信息!')
return
}
emit('changePlay', unref(dataInfo)?.id)
// readType 阅读内容类型pgrh段落/qns问题
if (talkVoiceObj.value.src && talkVoiceObj.value.src === itemVoice.value) {
emit('changePlay', unref(dataInfo)?.id)
talkVoiceObj.value.play()
return
}
talkVoiceObj.value.src = ''
if (itemVoice.value) {
setTimeout(() => {
talkVoiceObj.value.src = itemVoice.value
talkVoiceObj.value.play()
}, 100)
} else {
voiceLoading.value = true
let _type = props.type == 2 ? 'ans' : props.type == 3 ? 'pgrh' : props.type == 4 ? 'qns' : ''
let _readId = props.type == 2 ? unref(dataInfo)?.intrctId : props.type == 3 ? unref(dataInfo)?.pgrphId : props
.type == 4 ? unref(dataInfo)?.qnsId : ''
let _params = {
crsId: unref(dataInfo)?.crsId || '',
pgrphId: unref(dataInfo)?.pgrphId || '',
qnsId: unref(dataInfo)?.qnsId || '',
readType: _type, // 2 文本回答 3, 段落信息 4 问题信息
teachNo: unref(teacherInfo)?.teacherNo, // 必填
readId: _readId
// content: _content
}
let _url = '/trastudy/traStdyInfo/readContent?' + Object.keys(_params).map(t => {
return encodeURIComponent(t) + '=' + encodeURIComponent(_params[t])
}).join('&')
storageStore.getStorageById('audio', _url + _params.teachNo, (url) => {
if (url) {
voiceLoading.value = false
itemVoice.value = url
talkVoiceObj.value.src = url
talkVoiceObj.value.play()
} else {
downloadVoiceFile(_url).then(res => {
if (res?.data) {
common.msg(res.data.message)
return
}
voiceLoading.value = false
itemVoice.value = res.tempFilePath
talkVoiceObj.value.src = res.tempFilePath
talkVoiceObj.value.play()
storageStore.setStorage('audio', _url + _params.teachNo, itemVoice.value)
}).catch((err) => {
voiceLoading.value = false
})
}
})
}
}
const saveFile = (buffer, filePath, cb = () => {}) => {
let fileManager = uni.getFileSystemManager()
fileManager.writeFile({
filePath: filePath,
data: buffer,
encoding: 'binary',
success: cb,
file: () => {
voiceLoading.value = false
}
})
}
const initVoice = (readType = 'qns', item, isplay = false) => {
if (unref(dataInfo).talkingVoice) {
itemVoice.value = unref(dataInfo).talkingVoice
talkVoiceObj.value.src = itemVoice.value
setTimeout(() => {
setVoiceTime(0)
}, 100)
}
}
const setVoiceTime = (sum) => {
sum += 1
if (talkVoiceObj.value.duration) {
voiceTime.value = (Math.ceil(talkVoiceObj.value.duration) || 0) + 's'
} else {
if (sum === 10) {
voiceTime.value = 0 + 's'
return
}
setTimeout(() => {
setVoiceTime(sum)
}, 200)
}
}
const playQnsVoice = (readType = 'qns', item) => {
if (type.value === 2) {
// 文本转语音
playVoice(readType)
return
}
// readType 阅读内容类型pgrh段落/qns问题
emit('changePlay', unref(dataInfo)?.id)
setTimeout(() => {
itemVoice.value = item.talkingVoice
talkVoiceObj.value.src = item.talkingVoice
talkVoiceObj.value.play()
}, 100)
}
const translateLoading = ref(false)
// 翻译
const translateVoice = (item) => {
if (!item.talkingVoice) return
translateLoading.value = true
uploadVoiceFile(item.talkingVoice, {}).then(res => {
let _data = JSON.parse(res.data)
item.talkingContent = _data.body.text
translateLoading.value = false
}).catch(() => {
translateLoading.value = false
})
}
const showNextBtn = ref(true)
const showGoonBtn = computed(() => {
return showNextBtn.value && [3, 6].indexOf(props.type) >= 0 && isLast.value // && !isPlaying.value
})
const isClick = ref(false)
const goOnGetQues = () => {
if (isClick.value) return
clickNow()
if ([5, 8].indexOf(props.type) >= 0) {
// 完成问题
emit('nextQuestion', unref(dataInfo))
} else if ([3].indexOf(props.type) >= 0) {
// 完成段落
emit('nextQuestion', unref(dataInfo), 'overGraph')
} else if ([9].indexOf(props.type) >= 0) {
// 下一段落
emit('nextQuestion', unref(dataInfo), 'nextGraph')
}
}
const clickNow = () => {
isClick.value = true
setTimeout(() => {
isClick.value = false
}, 800)
}
const goOnRestart = () => {
if (isClick.value) return
clickNow()
emit('nextQuestion', unref(dataInfo), 'reStart')
}
const goOnRestartPrgh = () => {
if (isClick.value) return
clickNow()
emit('nextQuestion', unref(dataInfo), 'reStartPrgh')
}
// 撤回
const withdraw = () => {
if (isClick.value) return
clickNow()
emit('withdraw', unref(dataInfo))
}
// 完成
const finishQuestion = (data) => {
if (isClick.value) return
clickNow()
emit('finishQuestion', data)
}
// 答题 选择
const subject_click = (type, data) => {
if (['answer', 'choose'].includes(type)) {
emit('answerQuestion', {
...data,
...unref(dataInfo)
})
}
}
</script>
<style lang="scss">
.ai-answer {
width: 100%;
overflow: hidden;
margin-bottom: 20rpx;
.user-info {
overflow: hidden;
.avatar-box {
float: left;
width: 76rpx;
height: 76rpx;
border: 3rpx solid #fff;
background-color: #f1f1f1;
overflow: hidden;
border-radius: 10rpx;
margin-right: 16rpx;
margin-bottom: 16rpx;
.img-box {
width: 100%;
height: 100%;
}
}
.ai-name {
float: left;
color: #666;
font-size: 25rpx;
line-height: 35rpx;
.ai-name-desc {
color: #999;
margin-left: 16rpx;
display: inline-block;
}
}
}
.talking-info {
padding: 20rpx;
border-radius: 15rpx;
background-color: #fff;
overflow: hidden;
padding-bottom: 30rpx;
width: 100%;
&.talking-info-less {
float: left;
min-width: 400rpx;
padding-bottom: 20rpx;
}
.talking-gif {
width: 200rpx;
height: 38rpx;
background: url(@/static/images/course/voice-gray.png) no-repeat;
background-size: contain;
padding-left: 168rpx;
&.is-play {
background: url(@/static/images/course/voice-gif.gif) no-repeat;
background-size: contain;
}
}
.talking-cont {
margin: 16rpx 0;
overflow: hidden;
min-height: 48rpx;
&.last-cont {
margin-bottom: 0;
.talking-text {
margin-bottom: 0;
}
}
.talking-num {
font-size: 30rpx;
margin-bottom: 20rpx;
}
.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: 36px;
}
}
.cont-img-box {
width: 433rpx;
height: 269rpx;
border-radius: 15rpx;
overflow: hidden;
background-color: #fafafa;
margin-bottom: 20rpx;
}
}
.btns-cont {
overflow: hidden;
border-top: 3rpx solid #eee;
.replay-btn {
float: left;
width: 46rpx;
height: 46rpx;
overflow: hidden;
margin-right: 16rpx;
margin-top: 25rpx;
}
.play-btn {
float: left;
width: 46rpx;
height: 46rpx;
overflow: hidden;
margin-right: 16rpx;
margin-top: 25rpx;
}
.next-learn-btn {
float: left;
padding: 0 60rpx 0 20rpx;
height: 62rpx;
line-height: 62rpx;
font-size: 30rpx;
background-color: #06f;
color: #fff;
border-radius: 8rpx;
margin-top: 16rpx;
margin-right: 16rpx;
position: relative;
&.replay-study-btn {
float: right;
}
&.restart {
background-color: #eaf2ff;
color: #06f;
}
.icon-iamge {
width: 25rpx;
height: 25rpx;
position: absolute;
right: 20rpx;
top: 50%;
margin-top: -12rpx;
}
}
.replay-learn-btn {
float: left;
padding: 0 60rpx 0 20rpx;
height: 62rpx;
line-height: 62rpx;
font-size: 30rpx;
color: #06f;
background-color: #eaf2ff;
border-radius: 8rpx;
margin-top: 16rpx;
margin-right: 16rpx;
position: relative;
.icon-iamge {
width: 25rpx;
height: 25rpx;
position: absolute;
right: 20rpx;
top: 50%;
margin-top: -12rpx;
}
}
.next-btn {
float: right;
padding: 0 60rpx 0 20rpx;
height: 62rpx;
line-height: 62rpx;
font-size: 30rpx;
background-color: #06f;
color: #fff;
border-radius: 8rpx;
margin-top: 16rpx;
position: relative;
.icon-iamge {
width: 25rpx;
height: 25rpx;
position: absolute;
right: 20rpx;
top: 50%;
margin-top: -12rpx;
}
}
}
}
}
.user-answer {
overflow: hidden;
width: 100%;
margin-bottom: 20rpx;
.user-info {
overflow: hidden;
.avatar-box {
float: right;
width: 76rpx;
height: 76rpx;
border: 3rpx solid #fff;
background-color: #f1f1f1;
overflow: hidden;
border-radius: 10rpx;
margin-left: 16rpx;
margin-bottom: 16rpx;
.img-box {
width: 100%;
height: 100%;
}
}
.ai-name {
float: right;
color: #666;
font-size: 25rpx;
line-height: 35rpx;
}
}
.talking-info-less {
padding: 20rpx;
float: right;
border-radius: 15rpx;
background-color: #06f;
color: #fff;
}
.talking-info {
padding: 20rpx;
border-radius: 15rpx;
background-color: #06f;
padding-bottom: 30rpx;
position: relative;
color: #fff;
.talking-gif {
width: 200rpx;
height: 38rpx;
background: url(@/static/images/course/voice-gray.png) no-repeat;
background-size: contain;
padding-left: 168rpx;
&.is-play {
background: url(@/static/images/course/voice-white.gif) no-repeat;
background-size: contain;
}
}
.right-time {
position: absolute;
right: 20rpx;
top: 20rpx;
font-size: 28rpx;
height: 38rpx;
line-height: 38rpx;
}
.talking-cont {
margin-top: 16rpx;
overflow: hidden;
.talking-text {
font-size: 28rpx;
line-height: 48rpx;
margin-bottom: 20rpx;
word-break: break-all;
white-space: pre-line;
overflow: hidden;
&.translate-text {
min-height: 48rpx;
}
}
}
.btns-cont {
overflow: hidden;
border-top: 3rpx solid #eee;
.replay-btn {
float: left;
width: 46rpx;
height: 46rpx;
overflow: hidden;
margin-right: 16rpx;
margin-top: 25rpx;
}
.play-btn {
float: left;
width: 46rpx;
height: 46rpx;
overflow: hidden;
margin-right: 16rpx;
margin-top: 25rpx;
}
.text-btn {
float: left;
width: 46rpx;
height: 46rpx;
overflow: hidden;
line-height: 46rpx;
text-align: center;
color: #fff;
margin-right: 16rpx;
margin-top: 25rpx;
background-color: #67A4ff;
font-size: 24rpx;
font-weight: bold;
border-radius: 20rpx;
}
.text-right-btn {
float: right;
padding: 0 10rpx;
height: 46rpx;
overflow: hidden;
line-height: 46rpx;
text-align: center;
margin-left: 16rpx;
margin-top: 25rpx;
}
.next-btn {
float: right;
padding: 0 60rpx 0 20rpx;
height: 62rpx;
line-height: 62rpx;
font-size: 30rpx;
background-color: #06f;
color: #fff;
border-radius: 8rpx;
margin-top: 16rpx;
position: relative;
.icon-iamge {
width: 25rpx;
height: 25rpx;
position: absolute;
right: 20rpx;
top: 50%;
margin-top: -12rpx;
}
}
}
}
}
</style>