Merge branch 'develop' of http://25.13.9.101:9000/K17_AITS/tra-app into develop

This commit is contained in:
田岩
2025-07-02 14:58:33 +08:00
9 changed files with 615 additions and 69 deletions
+5
View File
@@ -49,6 +49,7 @@ export default function request({
meta,
isStream,
suppressErrors,
toastErrors,
header = {},
timeout = 6000
}) {
@@ -80,6 +81,10 @@ export default function request({
const res = response.data
if (res?.rtnCode === '0000') {
return resolve(res)
}else{
if(toastErrors){
common.msg(res?.message)
}
}
//到这里下面全是异常的处理
if (suppressErrors) { // 静默的接口,报错也不处理,因为下面有公共处理
+2 -5
View File
@@ -1,4 +1,4 @@
import { goto_login_fun } from '@/api/request'
export default class WebSocketUtil {
/**
* WebSocket工具类,用于管理WebSocket连接
@@ -114,10 +114,6 @@ export default class WebSocketUtil {
triggerEvent(event, data) {
if (this.callbacks[event]) {
this.callbacks[event].forEach(callback => callback(data));
uni.$emit('socketEvent',{
type: event,
data
})
}
}
@@ -202,6 +198,7 @@ export default class WebSocketUtil {
} else {
console.error('达到最大重连次数,停止尝试');
this.triggerEvent('error', new Error('达到最大重连次数'));
goto_login_fun()
}
}
+35 -1
View File
@@ -7,6 +7,7 @@ export const getCourseStudyInfoApi = (data) => {
return request({
url: base_url + '/traStdyInfo/queryTraStdyProgressAndTeacher',
method: 'post',
toastErrors: true,
data
});
};
@@ -16,6 +17,7 @@ export const queryTraStdyBatchWaitParagraphInfoApi = (data) => {
return request({
url: base_url + '/traStdyInfo/queryTraStdyBatchWaitParagraphInfo',
method: 'post',
toastErrors: true,
data
});
};
@@ -24,6 +26,7 @@ export const deleteTraStdyInfoByIdApi = (data) => {
return request({
url: base_url + '/traStdyInfo/deleteTraStdyInfoById',
method: 'post',
toastErrors: true,
data
});
};
@@ -33,6 +36,7 @@ export const studyParagraphOverApi = (data) => {
return request({
url: base_url + '/traStdyInfo/studyParagraphOver',
method: 'post',
toastErrors: true,
data
});
};
@@ -41,6 +45,7 @@ export const studyAnswerTextUpApi = (data) => {
return request({
url: base_url + '/traStdyInfo/studyAnswerTextUp',
method: 'post',
toastErrors: true,
data
});
};
@@ -49,6 +54,7 @@ export const queryTraStdyBatchWaitQuestionInfoApi = (data) => {
return request({
url: base_url + '/traStdyInfo/queryTraStdyBatchWaitQuestionInfo',
method: 'post',
toastErrors: true,
data
});
};
@@ -57,6 +63,34 @@ export const audioTranscriptionsApi = (data) => {
return request({
url: base_url + '/traStdyInfo/audioTranscriptions',
method: 'post',
toastErrors: true,
data
});
};
};
// 撤回消息
export const withdrawalAnswerApi = (data) => {
return request({
url: base_url + '/traStdyInfo/withdrawalAnswer',
method: 'post',
toastErrors: true,
data
});
};
// 异步完成回答
// 入参:
// qstLogId 必输项:true 类型:String
// 出参:
// qstLogId 问题日志ID String
// qnsId 问题ID String
// processStat 状态 String
// message 处理消息 String
export const waitMakeEvaluateApi = (data) => {
return request({
url: base_url + '/traStdyInfo/waitMakeEvaluate',
method: 'post',
toastErrors: true,
data
});
};
+352
View File
@@ -0,0 +1,352 @@
<template>
<view :class="['loading', type]">
<view></view>
<view></view>
<view></view>
<view></view>
<view></view>
<view></view>
<view></view>
<view></view>
</view>
</template>
<script>
import { computed } from 'vue'
export default {
name:"loading",
props:{
type:{
default: 'cr',// cl cr easy
type: String
},
size: {
default: '32',
type: [String, Number]
},
color: {
default: 'black',
type: String
}
},
computed:{
loadingWidth(){
return this.size + 'rpx'
},
easyLoadingWidth(){
return Number(this.size) * 15 / 16 + 'rpx'
},
easyLoadingBorderWidth(){
return Number(this.size) / 16 + 'rpx'
},
loadingColor(){
return this.color
}
},
data() {
return {
};
}
}
</script>
<style lang="scss">
.loading.easy {
width: v-bind(easyLoadingWidth);
height: v-bind(easyLoadingWidth);
border-style: solid;
border-color: v-bind(loadingColor);
border-width: v-bind(easyLoadingBorderWidth);
border-top-color: transparent;
border-radius: 100%;
animation: circle infinite 0.75s linear;
}
// 转转转动画
@keyframes circle {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
.loading,
.loading.cl > view {
position: relative;
box-sizing: border-box;
}
.loading.cl {
display: block;
font-size: 0;
color: v-bind(loadingColor);
}
.loading.cl.la-dark {
color: #333;
}
.loading.cl > view {
display: inline-block;
float: none;
background-color: currentColor;
border: 0 solid currentColor;
}
.loading.cl {
width: v-bind(loadingWidth);
height: v-bind(loadingWidth);
}
.loading.cl > view {
position: absolute;
top: 50%;
left: 50%;
width: 25%;
height: 25%;
transform: translate(-50%, -50%);
border-radius: 100%;
animation: ball-spin-clockwise 1s infinite ease-in-out;
}
.loading.cl > view:nth-child(1) {
top: 5%;
left: 50%;
animation-delay: -0.875s;
}
.loading.cl > view:nth-child(2) {
top: 18.1801948466%;
left: 81.8198051534%;
animation-delay: -0.75s;
}
.loading.cl > view:nth-child(3) {
top: 50%;
left: 95%;
animation-delay: -0.625s;
}
.loading.cl > view:nth-child(4) {
top: 81.8198051534%;
left: 81.8198051534%;
animation-delay: -0.5s;
}
.loading.cl > view:nth-child(5) {
top: 94.9999999966%;
left: 50.0000000005%;
animation-delay: -0.375s;
}
.loading.cl > view:nth-child(6) {
top: 81.8198046966%;
left: 18.1801949248%;
animation-delay: -0.25s;
}
.loading.cl > view:nth-child(7) {
top: 49.9999750815%;
left: 5.0000051215%;
animation-delay: -0.125s;
}
.loading.cl > view:nth-child(8) {
top: 18.179464974%;
left: 18.1803700518%;
animation-delay: 0s;
}
.loading.cl.la-sm {
width: 50%;
height: 50%;
}
.loading.cl.la-sm > view {
width:12.5%;
height:12.5%;
transform: translate(-50%, -50%);
}
.loading.cl.la-2x {
width: 64rpx;
height: 64rpx;
}
.loading.cl.la-2x > view {
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
}
.loading.cl.la-3x {
width: 96rpx;
height: 96rpx;
}
.loading.cl.la-3x > view {
width: 24rpx;
height: 24rpx;
transform: translate(-50%, -50%);
}
@keyframes ball-spin-clockwise {
0%,
100% {
opacity: 1;
transform: scale(1);
}
20% {
opacity: 1;
}
80% {
opacity: 0;
transform: scale(0);
}
}
.loading.cr,
.loading.cr > view {
position: relative;
box-sizing: border-box;
}
.loading.cr {
display: block;
font-size: 0;
color: v-bind(loadingColor);
}
.loading.cr.la-dark {
color: #333;
}
.loading.cr > view {
display: inline-block;
float: none;
background-color: currentColor;
border: 0 solid currentColor;
}
.loading.cr {
width: v-bind(loadingWidth);
height: v-bind(loadingWidth);
}
.loading.cr > view {
position: absolute;
top: 50%;
left: 50%;
width: 25%;
height: 25%;
transform: translate(-50%, -50%);
border-radius: 100%;
animation: ball-spin 1s infinite ease-in-out;
}
.loading.cr > view:nth-child(1) {
top: 5%;
left: 50%;
animation-delay: -1.125s;
}
.loading.cr > view:nth-child(2) {
top: 18.1801948466%;
left: 81.8198051534%;
animation-delay: -1.25s;
}
.loading.cr > view:nth-child(3) {
top: 50%;
left: 95%;
animation-delay: -1.375s;
}
.loading.cr > view:nth-child(4) {
top: 81.8198051534%;
left: 81.8198051534%;
animation-delay: -1.5s;
}
.loading.cr > view:nth-child(5) {
top: 94.9999999966%;
left: 50.0000000005%;
animation-delay: -1.625s;
}
.loading.cr > view:nth-child(6) {
top: 81.8198046966%;
left: 18.1801949248%;
animation-delay: -1.75s;
}
.loading.cr > view:nth-child(7) {
top: 49.9999750815%;
left: 5.0000051215%;
animation-delay: -1.875s;
}
.loading.cr > view:nth-child(8) {
top: 18.179464974%;
left: 18.1803700518%;
animation-delay: -2s;
}
.loading.cr.la-sm {
width: 50%;
height: 50%;
}
.loading.cr.la-sm > view {
width:12.5%;
height:12.5%;
transform: translate(-50%, -50%);
}
.loading.cr.la-2x {
width: 64rpx;
height: 64rpx;
}
.loading.cr.la-2x > view {
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
}
.loading.cr.la-3x {
width: 96rpx;
height: 96rpx;
}
.loading.cr.la-3x > view {
width: 24rpx;
height: 24rpx;
transform: translate(-50%, -50%);
}
@keyframes ball-spin {
0%,
100% {
opacity: 1;
transform: scale(1);
}
20% {
opacity: 1;
}
80% {
opacity: 0;
transform: scale(0);
}
}
</style>
+2
View File
@@ -1,10 +1,12 @@
import App from './App'
import { createSSRApp } from 'vue'
import pinia from './store.js'
import CommonLoading from './components/loading.vue'
export function createApp() {
const app = createSSRApp(App)
app.use(pinia)
app.component('CommonLoading',CommonLoading)
return {
app
}
+51 -15
View File
@@ -11,7 +11,9 @@
</view>
</view>
<view :class="['talking-info', [4].indexOf(type) >= 0 ? 'talking-info-less':''] ">
<view :class="['talking-gif', activeVoiceId === dataInfo.id?'is-play':'']"></view>
<view :class="['talking-gif', !voiceLoading && (activeVoiceId === dataInfo.id)?'is-play':'']">
<CommonLoading color="#06f" v-show="voiceLoading"/>
</view>
<view class="talking-cont">
<view class="talking-text" v-if="[3, 5, 6].indexOf(type) >= 0">
{{ dataInfo.pgrphContent }}
@@ -56,7 +58,7 @@
</view>
<!-- <view class="next-learn-btn">继续学<image class="icon icon-iamge" src="@/static/images/course/goon.png" ></image></view>
<view class="replay-study-btn"><image class="icon icon-iamge" src="@/static/images/course/restudy.png" ></image></view> -->
<view class="next-btn" @click="goOnGetQues" v-if="showNextBtn && [3, 5, 6].indexOf(type) >= 0">继续
<view class="next-btn" @click="goOnGetQues" v-if="showNextBtn && [3, 5, 6].indexOf(type) >= 0 && isLast">继续
<image class="icon icon-iamge" src="@/static/images/course/goon.png" ></image></view>
</view>
</view>
@@ -73,9 +75,12 @@
</view>
<view class="talking-info">
<view :class="['talking-gif', activeVoiceId === dataInfo.id?'is-play':'']"></view>
<view :class="['talking-gif', !voiceLoading && (activeVoiceId === dataInfo.id) ? 'is-play' : '']">
<CommonLoading color="#fff" v-show="voiceLoading"/>
</view>
<view class="talking-cont">
<view class="talking-text">
<CommonLoading color="#fff" v-show="translateLoading"/>
{{ dataInfo.talkingContent }}
</view>
</view>
@@ -98,8 +103,8 @@
></image>
</view>
<view class="icon text-btn" v-if="type === 1" @click="translateVoice(dataInfo)"></view>
<view class="icon text-right-btn" @click="translateVoice(dataInfo)" v-if="isLast">完成</view>
<view class="icon text-right-btn" @click="translateVoice(dataInfo)">撤回</view>
<view class="icon text-right-btn" @click="finishQuestion(dataInfo)" v-if="isLast">完成</view>
<view class="icon text-right-btn" @click="withdraw(dataInfo)">撤回</view>
</view>
</view>
</view>
@@ -153,12 +158,19 @@ import { getUserInfo } from '@/common/common';
default:false,
type: Boolean
},
voiceRate: {
default: '1.0',
type:[Number,String],
}
})
const { type, dataInfo, activeVoiceId, isPlaying, isLast} = toRefs(props)
const emit = defineEmits(['changePlay', 'nextQuestion'])
const emit = defineEmits(['changePlay', 'nextQuestion', 'withdraw', 'finishQuestion'])
// 声音播放初始化
const talkVoiceObj = ref(uni.createInnerAudioContext())
talkVoiceObj.value.playbackRate = Number(props.voiceRate)
const userInfo = computed(() => getUserInfo())
const voiceLoading = ref(false)
watch(() => props.isPlaying,(val) => {
if(!val){
talkVoiceObj.value?.stop()
@@ -167,6 +179,12 @@ import { getUserInfo } from '@/common/common';
deep: true,
immediate: true
})
watch(() => props.voiceRate,(val) => {
talkVoiceObj.value.playbackRate = Number(val)
},{
deep: true,
immediate: true
})
talkVoiceObj.value.onEnded(()=>{
emit('changePlay', '')
@@ -183,8 +201,8 @@ import { getUserInfo } from '@/common/common';
}
// 重播
const restartPlay = () => {
emit('changePlay', unref(dataInfo)?.id)
if(itemVoice.value){
emit('changePlay', unref(dataInfo)?.id)
setTimeout(()=>{
talkVoiceObj.value.src = itemVoice.value
talkVoiceObj.value.play()
@@ -198,13 +216,12 @@ import { getUserInfo } from '@/common/common';
// readType 阅读内容类型pgrh段落/qns问题
emit('changePlay', unref(dataInfo)?.id)
if(itemVoice.value){
console.log(1111111,itemVoice.value)
setTimeout(()=>{
talkVoiceObj.value.src = itemVoice.value
talkVoiceObj.value.play()
},100)
}else{
console.log(2,itemVoice.value)
voiceLoading.value = true
let _params = {
crsId: unref(dataInfo)?.crsId || '',
pgrphId: unref(dataInfo)?.pgrphId || '',
@@ -217,9 +234,12 @@ import { getUserInfo } from '@/common/common';
return encodeURIComponent(t) + '=' + encodeURIComponent(_params[t])
}).join('&')
downloadVoiceFile(_url).then(res=>{
voiceLoading.value = false
itemVoice.value = res.tempFilePath
talkVoiceObj.value.src = res.tempFilePath
talkVoiceObj.value.play()
}).catch((err)=>{
voiceLoading.value = false
})
}
}
@@ -237,11 +257,17 @@ import { getUserInfo } from '@/common/common';
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
translateLoading.value = false
}).catch(()=>{
translateLoading.value = false
})
}
const showNextBtn = ref(true)
@@ -254,6 +280,14 @@ import { getUserInfo } from '@/common/common';
emit('nextQuestion', unref(dataInfo))
})
}
// 撤回
const withdraw = (data) => {
emit('withdraw',data)
}
// 完成
const finishQuestion = (data) => {
emit('finishQuestion',data)
}
</script>
<style lang="scss">
@@ -299,14 +333,15 @@ import { getUserInfo } from '@/common/common';
min-width: 400rpx;
}
.talking-gif{
width: 140rpx;
width: 200rpx;
height: 38rpx;
background: url(@/static/images/course/voice-gray.png) no-repeat;
background-size: 100%;
background-size: contain;
margin-bottom: 16rpx;
padding-left: 168rpx;
&.is-play{
background: url(@/static/images/course/voice-gif.gif) no-repeat;
background-size: 100%;
background-size: contain;
}
}
.talking-cont{
@@ -462,14 +497,15 @@ import { getUserInfo } from '@/common/common';
background-color: #06f;
color: #fff;
.talking-gif{
width: 140rpx;
width: 200rpx;
height: 38rpx;
background: url(@/static/images/course/voice-gray.png) no-repeat;
background-size: 100%;
background-size: contain;
margin-bottom: 16rpx;
padding-left: 168rpx;
&.is-play{
background: url(@/static/images/course/voice-white.gif) no-repeat;
background-size: 100%;
background-size: contain;
}
}
.talking-cont{
+168 -48
View File
@@ -3,6 +3,10 @@
<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()"/>
语言选择开启学习之旅
@@ -33,6 +37,10 @@
</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()"/>
课程学习
@@ -50,8 +58,11 @@
: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>
@@ -96,6 +107,22 @@
</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>
@@ -117,7 +144,9 @@ import {
audioTranscriptionsApi,
deleteTraStdyInfoByIdApi,
queryTraStdyBatchWaitQuestionInfoApi,
studyAnswerTextUpApi
studyAnswerTextUpApi,
withdrawalAnswerApi,
waitMakeEvaluateApi
} from "@/api/study.js"
import common from '@/common/common';
import TalkingItem from '@/pages/course/components/talkingItem.vue'
@@ -210,45 +239,6 @@ const changePlayItemId = (id) => {
const choiceTeacherInfo = computed(()=>{
return teacherList.value.find(t=> t.teacherNo === choiceTeacher.value)
})
const keyboardIsShow = ref(false)
// 发送文本
const showKeyboard = () => {
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,
qnsId: unref(lastTalkingInfo).qnsId,
talkingContent: answerValue.value,
talkingVoice: '',
type: 2,
userInfo: {...choiceTeacherInfo.value},
id: _id
})
scrollToBottomNow()
answerValue.value = ''
keyboardIsShow.value = !keyboardIsShow.value
}
})
}else{
keyboardIsShow.value = !keyboardIsShow.value
}
}else{
keyboardIsShow.value = !keyboardIsShow.value
}
// inputRef.value.focus?.()
}
const activeVoiceTeachNo = ref('')
const teacherVoiceObj = uni.createInnerAudioContext()
@@ -482,13 +472,21 @@ const isOut = computed(() => {
return (widowHeight - moveVal) > touchY.value
})
const showOverlayTalking = (obj) => {
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
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
@@ -520,7 +518,6 @@ const hideOverlayTalking = (obj) => {
})
// #endif
//#ifdef APP-PLUS
console.log(222)
commonUploadVoiceFile(audioPath.value, '/trastudy/traStdyInfo/studyAnswerVoiceUp', _data).then(res=>{
console.log(res.data)
let _res = JSON.parse(res.data)
@@ -532,6 +529,7 @@ const hideOverlayTalking = (obj) => {
qnsId: unref(lastTalkingInfo).qnsId,
talkingContent: '',
talkingVoice: audioPath.value,
intrctId: res.body||'',
type: 1,
userInfo: {...choiceTeacherInfo.value},
id: _id
@@ -554,6 +552,83 @@ 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,
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
talkingList.value = talkingList.value.filter(t => t.intrctId !== data.intrctId)
})
}
// 完成
const finishQuestionNow = (data) => {
waitMakeEvaluateApi({
qstLogId: data.qstLogId
}).then(res=> {
console.log(res)
// 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">
@@ -572,6 +647,28 @@ const handleMove = (obj) => {
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;
@@ -841,6 +938,29 @@ const handleMove = (obj) => {
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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB