雷达图绘制,继续联调
This commit is contained in:
+9
-10
@@ -64,20 +64,19 @@ export function downloadFile(id) {
|
||||
}
|
||||
// 获取音频 通用
|
||||
export function downloadVoiceFile(url) {
|
||||
const token = getToken();
|
||||
const header = {
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
};
|
||||
if (token)
|
||||
header['summary'] = token
|
||||
let baseUrl = get_base_url();
|
||||
let _params = new FormData()
|
||||
const token = getToken();
|
||||
const header = {
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
};
|
||||
if (token)
|
||||
header['summary'] = token
|
||||
let baseUrl = get_base_url();
|
||||
let _params = new FormData()
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.downloadFile({
|
||||
url: `${baseUrl}${url}`,
|
||||
header,
|
||||
success(result) {
|
||||
console.log(result)
|
||||
success(result) {
|
||||
resolve(result)
|
||||
},
|
||||
fail(error) {
|
||||
|
||||
@@ -11,3 +11,19 @@ export const getCourseStudyInfoApi = (data) => {
|
||||
});
|
||||
};
|
||||
|
||||
// 获取课程学习 知识点 接口
|
||||
export const queryTraStdyBatchWaitParagraphInfoApi = (data) => {
|
||||
return request({
|
||||
url: base_url + '/traStdyInfo/queryTraStdyBatchWaitParagraphInfo',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
// 学习段落完成
|
||||
export const studyParagraphOverApi = (data) => {
|
||||
return request({
|
||||
url: base_url + '/traStdyInfo/studyParagraphOver',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<view class="chart-box">
|
||||
<view class="cont-box">
|
||||
<view v-for="width in 3" :class="`percent-${width * 25}`"></view>
|
||||
<view class="data-box">
|
||||
<view class="line-box">
|
||||
<view v-for="width in 3" :class="`percent-${width * 25}`"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed} from "vue"
|
||||
const props = defineProps({
|
||||
data:{
|
||||
default:() => [60,70,80,90],
|
||||
type: Array
|
||||
},
|
||||
width:{
|
||||
default: 300,
|
||||
type: [Number,String]
|
||||
},
|
||||
height:{
|
||||
default: 300,
|
||||
type: [Number,String]
|
||||
}
|
||||
})
|
||||
const chartWidth = computed(() => props.width + 'rpx')
|
||||
const chartHeight = computed(() => props.height + 'rpx')
|
||||
const styleFour = ref('polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)')
|
||||
const styleFourResult = computed(()=>{
|
||||
let score = props.data
|
||||
let _tx = 50
|
||||
let _ty = 50 - Math.floor((score[0]/100)*50)
|
||||
let _rx = 50 + Math.floor((score[1]/100)*50)
|
||||
let _ry = 50
|
||||
let _bx = 50
|
||||
let _by = 50 + Math.floor((score[2]/100)*50)
|
||||
let _lx = 50 - Math.floor((score[3]/100)*50)
|
||||
let _ly = 50
|
||||
return `polygon(${_tx}% ${_ty}%, ${_rx}% ${_ry}%, ${_bx}% ${_by}%, ${_lx}% ${_ly}%)`
|
||||
})
|
||||
console.log(styleFourResult.value)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chart-box{
|
||||
width: 100%;
|
||||
height: 500rpx;
|
||||
background:linear-gradient( 270deg, #4a74ff 0%, #6fa7fe 100%);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
.cont-box{
|
||||
background-color: #87abfe;
|
||||
width: v-bind(chartWidth);
|
||||
height: v-bind(chartHeight);
|
||||
clip-path: v-bind(styleFour);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
&::before{
|
||||
content: '';
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 3rpx;
|
||||
background-color: rgba(255, 255, 255, .3);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 20;
|
||||
}
|
||||
&::after{
|
||||
content: '';
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 3rpx;
|
||||
background-color: rgba(255, 255, 255, .3);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 20;
|
||||
}
|
||||
@for $i from 1 through 3 {
|
||||
.percent-#{$i*25}{
|
||||
width: $i * 25%;
|
||||
height: $i * 25%;
|
||||
clip-path: v-bind(styleFour);
|
||||
background-color: rgba(255, 255, 255, .3);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: (4 - $i) * 2;
|
||||
&::before{
|
||||
content: '';
|
||||
display: block;
|
||||
width: calc(100% - 10rpx);
|
||||
height: calc(100% - 10rpx);
|
||||
background-color: #87abfe;
|
||||
clip-path: v-bind(styleFour);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
.data-box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
clip-path: v-bind(styleFourResult);
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 12;
|
||||
overflow: hidden;
|
||||
.line-box{
|
||||
display: block;
|
||||
width: calc(100% - 24rpx);
|
||||
height: calc(100% - 24rpx);
|
||||
// background-color: #6691fe;
|
||||
background-color: #6691fe;
|
||||
clip-path: v-bind(styleFourResult);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 14;
|
||||
}
|
||||
|
||||
@for $i from 1 through 3 {
|
||||
.percent-#{$i*25}{
|
||||
background-color: rgba(255, 255, 255, .1);
|
||||
z-index: (4 - $i) * 2 + 10;
|
||||
&::before{
|
||||
background-color: #6692ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<view class="chart-box">
|
||||
<view class="cont-box">
|
||||
<view class="total-line total-line1"></view>
|
||||
<view class="total-line total-line2"></view>
|
||||
<view class="total-line total-line3"></view>
|
||||
<view v-for="width in 3" :class="`percent-${width * 25}`"></view>
|
||||
<view class="data-box">
|
||||
<view class="line-box">
|
||||
<view v-for="width in 3" :class="`percent-${width * 25}`"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed} from "vue"
|
||||
const props = defineProps({
|
||||
data:{
|
||||
default:() => [60,70,80,90],
|
||||
type: Array
|
||||
},
|
||||
width:{
|
||||
default: 300,
|
||||
type: [Number,String]
|
||||
},
|
||||
height:{
|
||||
default: 300,
|
||||
type: [Number,String]
|
||||
}
|
||||
})
|
||||
let _scale = .8
|
||||
const chartWidth = computed(() => props.width / _scale + 'rpx')
|
||||
const chartHeight = computed(() => props.height / _scale + 'rpx')
|
||||
const styleFour = computed(()=>{
|
||||
// let _blank = (50 - Math.round(100 * 1.732 / 3))/2
|
||||
// let _margin = _blank +
|
||||
let _tx = 50
|
||||
let _ty = 50 - Math.round(100 * 1.732 / 3)* _scale
|
||||
let _rx = 50 + 50 *_scale
|
||||
let _ry = 50 + Math.round(100 * 1.732 / 6)* _scale
|
||||
let _bx = 50 - 50 *_scale
|
||||
let _by = 50 + Math.round(100 * 1.732 / 6)* _scale
|
||||
return `polygon(${_tx}% ${_ty}%, ${_rx}% ${_ry}%, ${_bx}% ${_by}%)`
|
||||
})
|
||||
const styleFourResult = computed(()=>{
|
||||
let score = props.data
|
||||
let _tx = 50
|
||||
let _ty = 50 - setPercent(score[0], Math.round(100 * 1.732 / 3 * _scale * 100)/100)
|
||||
let _rx = 50 + setPercent(score[1], Math.round(50 *_scale * 100)/100)
|
||||
let _ry = 50 + setPercent(score[1], Math.round(100 * 1.732 / 6 * _scale * 100)/100)
|
||||
let _bx = 50 - setPercent(score[2], Math.round(50 *_scale * 100)/100)
|
||||
let _by = 50 + setPercent(score[2], Math.round(100 * 1.732 / 6 * _scale * 100)/100)
|
||||
return `polygon(${_tx}% ${_ty}%, ${_rx}% ${_ry}%, ${_bx}% ${_by}%)`
|
||||
})
|
||||
const setPercent = (precent, show) => {
|
||||
return Math.floor((precent/100) * show)
|
||||
}
|
||||
console.log(styleFourResult.value)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chart-box{
|
||||
width: 100%;
|
||||
height: 500rpx;
|
||||
background:linear-gradient( 270deg, #4a74ff 0%, #6fa7fe 100%);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
.cont-box{
|
||||
background-color: #87abfe;
|
||||
width: v-bind(chartWidth);
|
||||
height: v-bind(chartHeight);
|
||||
clip-path: v-bind(styleFour);
|
||||
position: absolute;
|
||||
top: 60%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
.total-line{
|
||||
width: 57.7%;
|
||||
height: 3rpx;
|
||||
background-color: rgba(255, 255, 255, .3);
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
z-index: 20;
|
||||
&.total-line1{
|
||||
top: 64.5%;
|
||||
left: 46.5%;
|
||||
transform: rotateZ(30deg);
|
||||
}
|
||||
&.total-line2{
|
||||
top: 64.5%;
|
||||
left:-4.5%;
|
||||
transform: rotateZ(150deg);
|
||||
}
|
||||
&.total-line3{
|
||||
top: 21.5%;
|
||||
left: 21%;
|
||||
transform: rotateZ(-90deg);
|
||||
}
|
||||
}
|
||||
@for $i from 1 through 3 {
|
||||
.percent-#{$i*25}{
|
||||
width: $i * 25%;
|
||||
height: $i * 25%;
|
||||
clip-path: v-bind(styleFour);
|
||||
background-color: rgba(255, 255, 255, .3);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: (4 - $i) * 2;
|
||||
&::before{
|
||||
content: '';
|
||||
display: block;
|
||||
width: calc(100% - 10rpx);
|
||||
height: calc(100% - 10rpx);
|
||||
background-color: #87abfe;
|
||||
clip-path: v-bind(styleFour);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
.data-box{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
clip-path: v-bind(styleFourResult);
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 12;
|
||||
overflow: hidden;
|
||||
.line-box{
|
||||
display: block;
|
||||
width: calc(100% - 24rpx);
|
||||
height: calc(100% - 24rpx);
|
||||
// background-color: #6691fe;
|
||||
background-color: #6691fe;
|
||||
clip-path: v-bind(styleFourResult);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 14;
|
||||
}
|
||||
|
||||
@for $i from 1 through 3 {
|
||||
.percent-#{$i*25}{
|
||||
background-color: rgba(255, 255, 255, .1);
|
||||
z-index: (4 - $i) * 2 + 10;
|
||||
&::before{
|
||||
background-color: #6692ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -2,39 +2,52 @@
|
||||
<view class="ai-answer" v-if="type === 0">
|
||||
<view class="user-info">
|
||||
<view class="avatar-box">
|
||||
<ImagePreview class="img-box" :imgId="''"></ImagePreview>
|
||||
<ImagePreview class="img-box" :imgId="dataInfo?.userInfo?.imgAddr"></ImagePreview>
|
||||
</view>
|
||||
<view class="ai-name">
|
||||
梁安娜
|
||||
<view class="ai-name-desc">AI课程教练</view>
|
||||
{{ dataInfo?.userInfo?.teacherName }}
|
||||
<view class="ai-name-desc">{{dataInfo?.userInfo?.teacherDesc}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="talking-info">
|
||||
<view class="talking-gif is-play"></view>
|
||||
<view :class="['talking-gif', activeVoiceId === dataInfo.id?'is-play':'']"></view>
|
||||
<view class="talking-cont">
|
||||
<view class="talking-text">
|
||||
{{ dataInfo.pgrphContent }}
|
||||
</view>
|
||||
<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>
|
||||
<!-- <ChartFour/>
|
||||
<ChartThree/> -->
|
||||
</view>
|
||||
<!-- <view class="talking-cont">
|
||||
<view class="talking-text">
|
||||
阿列克山大是快乐的你艾德卡省的mask安东拉森扣篮大赛了快递那里是啊克里斯蒂娜老师的阿萨是看,
|
||||
</view>
|
||||
<!-- <ImagePreview class="cont-img-box" :imgId="''"></ImagePreview>
|
||||
<VideoPreview class="cont-img-box" :imgId="''"></VideoPreview> -->
|
||||
</view>
|
||||
<view class="talking-cont">
|
||||
<view class="talking-text">
|
||||
阿列克山大是快乐的你艾德卡省的mask安东拉森扣篮大赛了快递那里是啊克里斯蒂娜老师的阿萨是看,
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="btns-cont">
|
||||
<view class="replay-btn">
|
||||
<view class="replay-btn" @click="restartPlay">
|
||||
<image class="icon" src="@/static/images/course/replay.png" style="width: 100%;height: 100%;"></image>
|
||||
</view>
|
||||
<view class="play-btn">
|
||||
<image class="icon" v-if="false" src="@/static/images/course/play.png" style="width: 100%;height: 100%;"></image>
|
||||
<image class="icon" src="@/static/images/course/pause.png" style="width: 100%;height: 100%;"></image>
|
||||
<image
|
||||
class="icon"
|
||||
src="@/static/images/course/play.png"
|
||||
style="width: 100%;height: 100%;"
|
||||
@click="playVoice"
|
||||
v-show="activeVoiceId !== dataInfo.id"
|
||||
></image>
|
||||
<image
|
||||
class="icon"
|
||||
v-show="activeVoiceId === dataInfo.id"
|
||||
src="@/static/images/course/pause.png"
|
||||
style="width: 100%;height: 100%;"
|
||||
@click="pauseVoice"
|
||||
></image>
|
||||
</view>
|
||||
<view class="next-learn-btn">继续学<image class="icon icon-iamge" src="@/static/images/course/goon.png" ></image></view>
|
||||
<!-- <view class="replay-learn-btn">重新学<image class="icon icon-iamge" src="@/static/images/course/restart.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">继续
|
||||
<!-- <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">继续
|
||||
<image class="icon icon-iamge" src="@/static/images/course/goon.png" ></image></view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -45,7 +58,7 @@
|
||||
<ImagePreview class="img-box" :imgId="''"></ImagePreview>
|
||||
</view>
|
||||
<view class="ai-name">
|
||||
玛卡巴卡
|
||||
{{ '李想' }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -53,7 +66,7 @@
|
||||
<view class="talking-gif"></view>
|
||||
<view class="talking-cont">
|
||||
<view class="talking-text">
|
||||
阿列克山大是快乐的你艾德卡省的mask安东拉森扣篮大赛了快递那里是啊克里斯蒂娜老师的阿萨是看,
|
||||
{{ dataInfo.talkingContent }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="btns-cont">
|
||||
@@ -67,18 +80,103 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else></view>
|
||||
<view class="user-answer" v-else-if="type===2">
|
||||
<view class="user-info">
|
||||
<view class="avatar-box">
|
||||
<ImagePreview class="img-box" :imgId="''"></ImagePreview>
|
||||
</view>
|
||||
<view class="ai-name">
|
||||
{{ '李想' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="talking-info-less">
|
||||
<view class="talking-text">
|
||||
{{ dataInfo.talkingContent }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ImagePreview from '@/components/image-preview/image-preview.vue'
|
||||
import VideoPreview from '@/components/image-preview/video-preview.vue'
|
||||
import { watch, unref, ref, toRefs } from 'vue'
|
||||
import ImagePreview from '@/components/image-preview/image-preview.vue'
|
||||
import VideoPreview from '@/components/image-preview/video-preview.vue'
|
||||
import { downloadVoiceFile } from "@/api/common.js"
|
||||
import { studyParagraphOverApi } from "@/api/study.js"
|
||||
import ChartFour from "./chartFour.vue"
|
||||
import ChartThree from "./chartThree.vue"
|
||||
|
||||
const props = defineProps({
|
||||
type:{
|
||||
default: 0,// 1: userAnswer 0: AIAnswer
|
||||
type:[Number,String]
|
||||
},
|
||||
dataInfo: {
|
||||
default: () => ({}),
|
||||
type: Object
|
||||
},
|
||||
activeVoiceId:{
|
||||
default:'',
|
||||
type: String
|
||||
}
|
||||
})
|
||||
const { type, dataInfo, activeVoiceId } = toRefs(props)
|
||||
const emit = defineEmits(['changePlay', 'nextQuestion'])
|
||||
watch('activeVoiceId',(val) => {
|
||||
if(val !== unref(dataInfo).id){
|
||||
pauseVoice()
|
||||
}
|
||||
})
|
||||
|
||||
const talkVoiceObj = uni.createInnerAudioContext()
|
||||
talkVoiceObj.onEnded(()=>{
|
||||
// talkVoiceObj.src = ''
|
||||
emit('changePlay',unref(dataInfo)?.id)
|
||||
})
|
||||
const pauseVoice = () => {
|
||||
talkVoiceObj.pause()
|
||||
emit('changePlay',unref(dataInfo)?.id)
|
||||
}
|
||||
const restartPlay = () => {
|
||||
if(talkVoiceObj.src){
|
||||
talkVoiceObj.seek(0)
|
||||
talkVoiceObj.play()
|
||||
}else{
|
||||
playVoice()
|
||||
}
|
||||
}
|
||||
const playVoice = (readType = 'pgth') =>{
|
||||
// readType 阅读内容类型pgrh段落/qns问题
|
||||
emit('changePlay', unref(dataInfo)?.id)
|
||||
if(talkVoiceObj.src){
|
||||
talkVoiceObj.play()
|
||||
}else{
|
||||
let _params = {
|
||||
crsId: unref(dataInfo)?.crsId || '',
|
||||
pgrphId: unref(dataInfo)?.pgrphId || '',
|
||||
qnsId: unref(dataInfo)?.qnsId || '',
|
||||
readType: readType,
|
||||
teachNo: unref(dataInfo)?.userInfo?.teacherNo, // 必填
|
||||
content: unref(dataInfo)?.pgrphContent,
|
||||
}
|
||||
let _url = '/trastudy/traStdyInfo/readContent?' + Object.keys(_params).map(t=>{
|
||||
return encodeURIComponent(t) + '=' + encodeURIComponent(_params[t])
|
||||
}).join('&')
|
||||
downloadVoiceFile(_url).then(res=>{
|
||||
talkVoiceObj.src = res.tempFilePath
|
||||
talkVoiceObj.play()
|
||||
})
|
||||
}
|
||||
}
|
||||
const showNextBtn = ref(true)
|
||||
const goOnGetQues = () => {
|
||||
studyParagraphOverApi({
|
||||
pgrphId:unref(dataInfo)?.pgrphId
|
||||
}).then(res=>{
|
||||
showNextBtn.value = false
|
||||
emit('nextQuestion', unref(dataInfo))
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -239,7 +337,7 @@
|
||||
}
|
||||
}
|
||||
.user-answer{
|
||||
|
||||
overflow: hidden;
|
||||
.user-info{
|
||||
overflow: hidden;
|
||||
.avatar-box{
|
||||
@@ -265,6 +363,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.talking-info-less{
|
||||
padding: 20rpx;
|
||||
float: right;
|
||||
border-radius: 15rpx;
|
||||
background-color: #06f;
|
||||
color: #fff;
|
||||
}
|
||||
.talking-info{
|
||||
padding: 20rpx;
|
||||
border-radius: 15rpx;
|
||||
|
||||
+121
-67
@@ -7,7 +7,6 @@
|
||||
<uv-icon class="arrow-icon" name="arrow-left" @click="common.navigateBack()"/>
|
||||
语言选择,开启学习之旅
|
||||
</view>
|
||||
<!-- <video v-if="videoUrlShow" :src="videoUrlShow" controls></video> -->
|
||||
<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">
|
||||
@@ -23,7 +22,6 @@
|
||||
<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 class="talking-time">00:26</view> -->
|
||||
</view>
|
||||
</view>
|
||||
<uv-radio :name="item.teacherNo" class="radio-box" @click.stop/>
|
||||
@@ -31,7 +29,6 @@
|
||||
</uv-radio-group>
|
||||
<view class="start-btns" @click="nextStep">
|
||||
开启学习之旅
|
||||
<!-- <view class="touch-btn">开启学习之旅</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -41,8 +38,19 @@
|
||||
课程学习
|
||||
</view>
|
||||
<view class="talking-list">
|
||||
<view class="study-num">1/20</view>
|
||||
<TalkingItem class="talking-item" v-for="item in 8" :type="item%2"></TalkingItem>
|
||||
<view class="study-num">
|
||||
<view class="color-blue">1</view> / 20
|
||||
</view>
|
||||
<TalkingItem
|
||||
class="talking-item"
|
||||
v-for="item in talkingList"
|
||||
:type="item.type"
|
||||
:dataInfo="item"
|
||||
:activeVoiceId="activeVoiceTalkingItemId"
|
||||
@changePlay="changePlayItemId"
|
||||
@nextQuestion="nextQuestionSuccess"
|
||||
></TalkingItem>
|
||||
<!-- <video v-if="videoUrlShow" :src="videoUrlShow" controls></video> -->
|
||||
</view>
|
||||
<view class="talk-btns">
|
||||
<view
|
||||
@@ -66,9 +74,6 @@
|
||||
<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 class="translate-btn">转文字 发送
|
||||
<image class="btn-box" src="/src/static/images/course/to-text.png" mode=""></image>
|
||||
</view> -->
|
||||
</view>
|
||||
<!-- <view class="talk-dialog">
|
||||
<view class="voice-gif"></view>
|
||||
@@ -84,7 +89,7 @@ import { onLoad,onShow,onHide } from '@dcloudio/uni-app';
|
||||
import { previewFile, downloadFile, downloadVoiceFile } from "@/api/common.js"
|
||||
import { getToken } from '@/common/common.js'
|
||||
import { get_base_url } from '@/api/request'
|
||||
import { getCourseStudyInfoApi } from "@/api/study.js"
|
||||
import { getCourseStudyInfoApi, queryTraStdyBatchWaitParagraphInfoApi } 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'
|
||||
@@ -94,6 +99,9 @@ const step = ref(0)
|
||||
const teacherList = ref([])
|
||||
const choiceTeacher = ref('')
|
||||
const videoUrlShow = ref('')
|
||||
const talkingList = ref([])
|
||||
const activeVoiceTalkingItemId = ref('')
|
||||
|
||||
const getData = async () => {
|
||||
try{
|
||||
const { body } = await getCourseStudyInfoApi({crsId: crsId.value})
|
||||
@@ -107,7 +115,7 @@ const getData = async () => {
|
||||
}else{
|
||||
step.value = 2
|
||||
choiceTeacher.value = body.choiceTeacher
|
||||
initWS(2)
|
||||
initsocketTask(2)
|
||||
}
|
||||
}catch{
|
||||
|
||||
@@ -116,6 +124,20 @@ const getData = async () => {
|
||||
// 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(()=>{
|
||||
@@ -133,21 +155,30 @@ const playTeacherVoice = (item) =>{
|
||||
teacherVoiceObj.play()
|
||||
}else{
|
||||
downloadVoiceFile('/trastudy/traStdyInfo/trialListening?teachNo='+item.teacherNo).then(res=>{
|
||||
// item.voiceObj = uni.createInnerAudioContext()
|
||||
console.log(res)
|
||||
item.voicePath = res.tempFilePath
|
||||
teacherVoiceObj.src = item.voicePath
|
||||
teacherVoiceObj.play()
|
||||
// item.voiceObj.src = res.tempFilePath
|
||||
// item.voiceObj.play()
|
||||
})
|
||||
}
|
||||
}
|
||||
var WS = null
|
||||
var socketTask = null
|
||||
const nextStep = () => {
|
||||
if(choiceTeacher.value){
|
||||
initWS(1)
|
||||
teacherVoiceObj.destroy()
|
||||
initsocketTask(1)
|
||||
setTimeout(()=>{
|
||||
if( socketTask && socketTask.readyState === 1){
|
||||
sendMessage({
|
||||
"commond" : 'open',
|
||||
"body" : {
|
||||
crsId: crsId.value,
|
||||
teacherNo: choiceTeacher.value
|
||||
}
|
||||
})
|
||||
step.value = 2
|
||||
getGraphInfoUnStudy()
|
||||
}
|
||||
},200)
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '请选择一位教师!',
|
||||
@@ -156,68 +187,87 @@ const nextStep = () => {
|
||||
});
|
||||
}
|
||||
}
|
||||
const reconnectTimer = null // 重连timer
|
||||
const isManualClose = false // 是否手动关闭
|
||||
const getGraphInfoUnStudy = () => {
|
||||
queryTraStdyBatchWaitParagraphInfoApi({crsId: crsId.value}).then(res=>{
|
||||
console.log(res)
|
||||
let _id = new Date().getTime() + 'id'
|
||||
talkingList.value.push({
|
||||
...res.body,
|
||||
type: 0,
|
||||
userInfo: {...choiceTeacherInfo.value},
|
||||
id: _id
|
||||
})
|
||||
})
|
||||
}
|
||||
// 继续 执行方法
|
||||
const nextQuestionSuccess = (info) => {
|
||||
let _id = new Date().getTime() + 'id'
|
||||
talkingList.value.push({
|
||||
crsId: info.crsId,
|
||||
pgrphId: info.pgrphId,
|
||||
talkingContent: '继续',
|
||||
type: 2,
|
||||
id: _id
|
||||
})
|
||||
getGraphInfoUnStudy()
|
||||
}
|
||||
|
||||
const initWS = ($step) => {
|
||||
WS = uni.connectSocket({
|
||||
const reconnectTimer = null // 重连timer
|
||||
const isManualClose = ref(false) // 是否手动关闭
|
||||
|
||||
const initsocketTask = ($step) => {
|
||||
socketTask = uni.connectSocket({
|
||||
url: get_base_url() + '/trastudy/trasoket/open?summary=' + getToken(),
|
||||
complete: function(){}
|
||||
})
|
||||
WS.onMessage = (event) => {
|
||||
console.log(event,111)
|
||||
}
|
||||
WS.onmessage = (event) => {
|
||||
console.log(event,121)
|
||||
}
|
||||
WS.onSocketMessage = (event) => {
|
||||
console.log(event,222)
|
||||
}
|
||||
WS.onOpen = () =>{
|
||||
console.log('建立链接')
|
||||
}
|
||||
WS.onError = (event) => {
|
||||
console.log('error',event)
|
||||
}
|
||||
// WS.onclose = () => {
|
||||
uni.onSocketMessage((res)=>{
|
||||
let _data = JSON.parse(res.data)
|
||||
console.log(_data)
|
||||
})
|
||||
uni.onSocketOpen((e)=>{
|
||||
console.log('链接成功!')
|
||||
})
|
||||
uni.onSocketError((e)=>{
|
||||
console.log(e,111)
|
||||
})
|
||||
uni.onSocketClose((e)=>{
|
||||
// 重连
|
||||
reconnect()
|
||||
})
|
||||
// socketTask.onMessage = (event) => {
|
||||
// console.log(event,111)
|
||||
// }
|
||||
// socketTask.onOpen = () =>{
|
||||
// console.log('建立链接')
|
||||
// }
|
||||
// socketTask.onError = (event) => {
|
||||
// console.log('error',event)
|
||||
// }
|
||||
// socketTask.onclose = () => {
|
||||
// // 重连
|
||||
// // initWS()
|
||||
// // initsocketTask()
|
||||
// }
|
||||
setTimeout(()=>{
|
||||
if( WS && WS.readyState === 1){
|
||||
let _params = $step === 1 ?{
|
||||
"commond" : 'open',
|
||||
"body" : {
|
||||
crsId: crsId.value,
|
||||
teacherNo: choiceTeacher.value
|
||||
}
|
||||
}:{}
|
||||
sendMessage(_params)
|
||||
step.value = 2
|
||||
}
|
||||
WS.close()
|
||||
},100)
|
||||
}
|
||||
const reconnect = ()=> {
|
||||
if(reconnectTimer || isManualClose) return
|
||||
if(reconnectTimer || isManualClose.value) return
|
||||
reconnectTimer = setTimeout(()=>{
|
||||
initWS(2)
|
||||
initsocketTask(2)
|
||||
},3000)
|
||||
}
|
||||
const sendMessage = (data) => {
|
||||
WS.send({
|
||||
const sendMessage = (data) => {
|
||||
socketTask.send({
|
||||
data: JSON.stringify(data)
|
||||
})
|
||||
}
|
||||
const closeWebSocket = () => {
|
||||
isManualClose = true
|
||||
if(WS){
|
||||
WS.close()
|
||||
WS = null
|
||||
isManualClose.value = true
|
||||
if(socketTask){
|
||||
// socketTask.close()
|
||||
socketTask = null
|
||||
uni.closeSocket({})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onLoad((params) => {
|
||||
crsId.value = params.crsId||'';
|
||||
crsNum.value = params.crsNum||'';
|
||||
@@ -240,9 +290,6 @@ const startRecord = () => {
|
||||
const stopRecord = () => {
|
||||
unref(recordObj).stop()
|
||||
}
|
||||
// onMounted(()=>{
|
||||
// initRecord()
|
||||
// })
|
||||
// #endif
|
||||
//#ifndef APP-PLUS
|
||||
const recordObj = {}
|
||||
@@ -255,12 +302,12 @@ onMounted(()=>{
|
||||
onShow(()=>{
|
||||
getData();
|
||||
})
|
||||
onHide(()=>{
|
||||
closeWebSocket()
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
onHide(()=>{
|
||||
closeWebSocket()
|
||||
})
|
||||
// onUnmounted(()=>{
|
||||
// closeWebSocket()
|
||||
// })
|
||||
const playRecord = () => {
|
||||
audioObj.src = audioPath.value
|
||||
unref(audioObj).play()
|
||||
@@ -283,7 +330,9 @@ const showOverlayTalking = (obj) => {
|
||||
touchX.value = obj.changedTouches[0].pageX
|
||||
touchY.value = obj.changedTouches[0].pageY
|
||||
baseY.value = obj.currentTarget.offsetTop
|
||||
//#ifdef APP-PLUS
|
||||
startRecord()
|
||||
// #endif
|
||||
}
|
||||
const hideOverlayTalking = (obj) => {
|
||||
showTalkingModel.value = false
|
||||
@@ -361,6 +410,10 @@ const handleMove = (obj) => {
|
||||
line-height: 36rpx;
|
||||
text-align: center;
|
||||
margin-bottom: 15rpx;
|
||||
.color-blue{
|
||||
color: #06f;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
.talking-item{
|
||||
margin-bottom: 46rpx;
|
||||
@@ -556,4 +609,5 @@ const handleMove = (obj) => {
|
||||
background-color: #06f;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user