fix: 维度结果页

This commit is contained in:
杨航
2025-11-13 17:27:29 +08:00
parent dbf48a3ca4
commit 6d75ed60d2
10 changed files with 579 additions and 117 deletions
+32
View File
@@ -49,4 +49,36 @@ export const queryTraPartnerCharacterInfoById = (data) => {
method: 'post',
data
});
};
// 结束陪练 /trapractice/traPartnerChatReport/partnerChatReportTrigger?execId=
export const partnerChatReportTrigger = (data) => {
return request({
url: base_url + '/traPartnerChatReport/partnerChatReportTrigger',
method: 'post',
data
});
};
// 问答提示/trapractice/traPartnerChat/partnerChatPrompt
export const partnerChatPrompt = (data) => {
return request({
url: base_url + '/traPartnerChat/partnerChatPrompt',
method: 'post',
data
});
};
// 获取报告traPartnerChatReport/partnerChatReport
export const partnerChatReport = (data) => {
return request({
url: base_url + '/traPartnerChatReport/partnerChatReport',
method: 'post',
data
});
};
// 反馈
export const insertTraPartnerFeedback = (data) => {
return request({
url: base_url + '/traPartnerFeedback/insertTraPartnerFeedback',
method: 'post',
data
});
};
+1
View File
@@ -1,6 +1,7 @@
import { get_base_url } from '@/api/request';
// #ifdef APP-PLUS
import showDialog from '@/common/dialogMessage'
import common from '@/common/common'
// #endif
function msg(title, duration = 1000) {
uni.showToast({
+5 -5
View File
@@ -15,15 +15,15 @@
</view>
<view class="title" v-if="fromType === 'tra'">
<image class="title-icon icon-tra" src="@/static/images/sparring/den-icon.png" alt=""> </image>
维度分析22
维度分析
</view>
<view class="total-score" v-if="fromType === 'crs'">
<view class="score-num">{{ score }}</view>
<image class="total-score-icon" src="@/static/images/course/score.png" alt=""></image>
</view>
<view v-for="(item,index) in dataList" :class="['score-item', 'score-item'+(index+1)]">
<view class="score-item-name">维度{{ item }}</view>
<view class="score-item-score">{{ item }}</view>
<view class="score-item-name">{{ item.gradeDimensName || item.gradeDimens }}</view>
<view class="score-item-score">{{ item.anlyGrade }}</view>
</view>
</view>
</template>
@@ -31,7 +31,7 @@
export default{
props:{
dataList:{
default:() => [10,20,30,40,50,60,78],
default:() => [],
type: Array
},
score:{
@@ -54,7 +54,7 @@
},
computed:{
dataValue(){
return this.dataList//.map(t=>t.anlyGrade)
return this.dataList.map(t=>t.anlyGrade)
},
chartWidth(){
return this.size + 'rpx'
+5 -5
View File
@@ -15,15 +15,15 @@
</view>
<view class="title" v-if="fromType === 'tra'">
<image class="title-icon icon-tra" src="@/static/images/sparring/den-icon.png" alt=""> </image>
维度分析22
维度分析
</view>
<view class="total-score" v-if="fromType === 'crs'">
<view class="score-num">{{ score }}</view>
<image class="total-score-icon" src="@/static/images/course/score.png" alt=""></image>
</view>
<view v-for="(item,index) in dataList" :class="['score-item', 'score-item'+(index+1)]">
<view class="score-item-name">维度维{{ item }}</view>
<view class="score-item-score">{{ item }}</view>
<view class="score-item-name">{{ item.gradeDimensName || item.gradeDimens }}</view>
<view class="score-item-score">{{ item.anlyGrade }}</view>
</view>
</view>
</template>
@@ -31,7 +31,7 @@
export default{
props:{
dataList:{
default:() => [20,30,40,50,60,78],
default:() => [],
type: Array
},
score:{
@@ -54,7 +54,7 @@
},
computed:{
dataValue(){
return this.dataList//.map(t=>t.anlyGrade)
return this.dataList.map(t=>t.anlyGrade)
},
chartWidth(){
return this.size + 'rpx'
+23 -14
View File
@@ -1,5 +1,5 @@
<template>
<view class="answer-content" v-if="props.isLoading">
<view class="answer-content" v-if="props.dataInfo.isLoading">
<view class="talking-cont">
<CommonLoading color="#06f" />
</view>
@@ -8,7 +8,7 @@
<view class="talking-cont">
<MarkdownPreview :mdString="mdText" />
</view>
<view class="btns-cont" v-if="!props.isLoading">
<view class="btns-cont" v-if="!props.dataInfo.isLoading">
<view class="replay-btn" @click="reAnswer" v-if="!props.dataInfo.isHistory">
<image class="icon" src="@/static/images/dialog/answer-restart1.png" style="width: 100%; height: 100%"></image>
</view>
@@ -35,7 +35,9 @@
onMounted,
computed,
ref,
unref,
watch,
toRefs
} from 'vue'
import { onUnload } from '@dcloudio/uni-app';
import MarkdownPreview from '@/components/markdown-preview/markdown-preview.vue'
@@ -47,10 +49,6 @@
default: () => ({}),
type: Object
},
isLoading: {
default: false,
type: Boolean
},
isAnswering: {
default: false,
type: Boolean
@@ -60,7 +58,7 @@
type: Boolean
}
})
const { isLast, dataInfo } = toRefs(props)
watch(
() => props.dataInfo,
() => {}, {
@@ -68,13 +66,6 @@
immediate: true
}
)
watch(
() => props.isLoading,
() => {}, {
deep: true,
immediate: true
}
)
const isPlaying = ref(false)
const mdText = computed(() => {
@@ -110,6 +101,7 @@
const previewCrs = item => {
common.navigateTo('/pages/courseDetail/index?crsId=' + item.crsId)
}
const talkVoiceObj = ref(null)
const playVoice = (readType = 'pgth') => {
let _content = mdText.value;
if (!_content) {
@@ -136,6 +128,23 @@
}, 100);
};
const initVoice = () => {
talkVoiceObj.value = uni.createInnerAudioContext()
talkVoiceObj.value.onEnded(()=>{
emit('changePlay', '')
talkVoiceObj.value.src = ''
})
talkVoiceObj.value.onError(()=>{
talkVoiceObj.value.src = ''
})
if(unref(dataInfo).intrctWay === '02'){
itemVoice.value = unref(dataInfo).talkingVoice
talkVoiceObj.value.src = itemVoice.value
setTimeout(()=>{
setVoiceTime(0)
},100)
}
}
const pauseVoice = () => {
if (!talkVoiceObj.value) return
talkVoiceObj.value.pause()
+16 -18
View File
@@ -37,8 +37,8 @@
nextTick
} from 'vue';
import {
insertTraAskFeedback
} from "@/api/dialog.js"
insertTraPartnerFeedback
} from "@/api/sparring.js"
import {
optionErrorIcon
} from '@/common/imgSvg'
@@ -47,10 +47,6 @@
const emit = defineEmits(['feedbackAnswer'])
const feedback_popup_bottom = ref('0px') // 反馈框下距离
const feedbackPopupRef = ref(null)
// FM("01", "虚假信息"),
// AE("02", "回答不准确"),
// NH("03", "没有帮助"),
// OTHER("04", "其他"),
const feedbackTypeList = reactive([{
value: "01",
label: "场景问题",
@@ -59,11 +55,13 @@
label: "功能问题",
}, {
value: "03",
label: "没有帮助",
}, {
value: "04",
label: "其他",
}])
label: "陪练内容",
},
// {
// value: "04",
// label: "其他",
// },
])
const feedbackInfo = ref({
type: [], // 反馈类型
text: '', // 反馈内容
@@ -86,14 +84,13 @@
common.msg('反馈内容不能为空!')
return
}
// todo 待接口
// todo 待接口refineId=PARTNERINFO02506403215920251024093412000000348&fbkTyp=01&fbkContent=测试
const params = JSON.parse(JSON.stringify({
askId: answerData.value.seqNo,
traId: answerData.value.traId,
fbkTyp: feedbackInfo.value.type.join(','),
reqBatch: answerData.value.reqBatch,
fbkContent: feedbackInfo.value.text
}))
insertTraAskFeedback(params).then(res=>{
insertTraPartnerFeedback(params).then(res=>{
common.msg('反馈提交成功!')
feedbackInfo.value = {
type: [], // 反馈类型
@@ -195,7 +192,7 @@
.feedback_item {
float: left;
width: calc(50% - 20rpx);
width: calc(33.3% - 27rpx);
border: 2rpx solid #F0F0F0;
background-color: #F0F0F0;
border-radius: 16rpx;
@@ -206,8 +203,9 @@
color: #000000;
text-align: center;
margin-bottom: 20rpx;
&:nth-child(2n){
margin-left: 40rpx;
margin-right: 40rpx;
&:nth-child(3n){
margin-right: 0rpx;
}
}
}
+80 -9
View File
@@ -1,9 +1,9 @@
<template>
<view class="talking-item">
<!-- 头像信息 -->
<view class="user-info">
<view class="user-info" v-if="talkingType === 'answer'">
<view class="avatar-box">
<ImagePreview class="img-box" :imgId="roleInfo?.ossAddr"></ImagePreview>
<ImagePreview class="img-box" :src="roleInfo?.ossAddr"></ImagePreview>
</view>
<view class="ai-name">
{{ roleInfo?.chaName }}
@@ -13,19 +13,29 @@
<questionVue v-if="talkingType === 'question'" @changePlay="changePlay" :dataInfo="talkingInfo" :isLast="isLast"
:activeVoiceId="activeVoiceId"></questionVue>
<answerVue v-else-if="talkingType === 'answer'" @changePlay="changePlay" :dataInfo="props.talkingInfo" :isLast="isLast"
:isLoading="!!props.talkingInfo.isLoading" :isAnswering="props.isAnswering" @handleEvents="handleEvents">
:isAnswering="props.isAnswering" @handleEvents="handleEvents">
</answerVue>
<view v-else></view>
<view class="talking-tips" v-if="talkingType === 'answer'">
<view class="talking-tips-btn" @click="getTips()">回答提示</view>
<view class="talking-tips-loading" v-if="loadingTips">
<CommonLoading color="#06f" />
</view>
<view class="talking-tips-cont" v-else>{{tipsContent}}</view>
</view>
</view>
</template>
<script setup>
import {
toRefs,
watch
watch,
ref
} from 'vue'
import questionVue from './question.vue';
import answerVue from './answer.vue';
import ImagePreview from '@/components/image-preview/image-preview.vue';
import { partnerChatPrompt } from "@/api/sparring.js"
const emit = defineEmits(['handleEvents'])
const props = defineProps({
@@ -33,6 +43,14 @@
default: 'question',
type: String
},
traId: {
default: '',
type: String
},
execId: {
default: '',
type: String
},
talkingInfo: {
default: () => ({}),
type: Object
@@ -63,8 +81,12 @@
immediate: true
})
const {
talkingType
talkingType,
talkingInfo
} = toRefs(props)
const loadingTips = ref(false)
const tipsContent = ref('')
const handleEvents = (type, info = {}) => {
emit('handleEvents', {
type,
@@ -73,6 +95,19 @@
info
})
}
const getTips = () => {
loadingTips.value = true
partnerChatPrompt({
execId: props.execId,
traId: props.traId,
content: props.talkingInfo.talkingText
}).then(res=>{
tipsContent.value = res.body
loadingTips.value = false
}).catch(()=> {
loadingTips.value =false
})
}
const changePlay = (id) => {
emit('handleEvents', {
type: 'changePlay',
@@ -87,7 +122,8 @@
.talking-item {
overflow: hidden;
margin-top: 0rpx;
position: relative;
margin-bottom: 24rpx;
&+.talking-item {
margin-top: 30rpx;
}
@@ -99,16 +135,18 @@
width: 76rpx;
height: 76rpx;
border: 3rpx solid #fff;
background-color: #f1f1f1;
// background-color: #f1f1f1;
overflow: hidden;
border-radius: 10rpx;
margin-right: 16rpx;
margin-bottom: 16rpx;
.img-box {
width: 100%;
height: 100%;
width: 76rpx;
height: 76rpx;
overflow: hidden;
}
}
.ai-name {
@@ -124,5 +162,38 @@
}
}
}
.talking-tips{
float: left;
position: relative;
padding-top: 60rpx;
width: 100%;
&-btn{
position: absolute;
left: 50%;
top: 22rpx;
height: 24rpx;
line-height: 24rpx;
font-size: 24rpx;
color: #06f;
transform: translateX(-50% );
padding-left: 30rpx;
background: url(@/static/images/sparring/ask-icon.png) no-repeat;
background-position: left center;
background-size: 24rpx 24rpx;
}
&-cont{
width: 100%;
font-size: 24rpx;
line-height: 38rpx;
color: #8191AA;
}
.talking-tips-loading{
display: flex;
justify-content: center;
min-height: 40rpx;
padding-top: 20rpx;
}
}
}
</style>
+91 -50
View File
@@ -10,10 +10,10 @@
<view class="body-content">
<view class="body-top">
<view class="body-top-title">
{{'陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称'}}
{{ traInfo.traName}}
</view>
<view class="body-top-time">
陪练时长{{'12分 15秒'}}
陪练时长{{traTm}}
</view>
<view class="body-top-tip">陪练详情</view>
<view class="body-top-collepse-title">
@@ -32,40 +32,23 @@
</view>
<view class="body-bottom">
<view class="body-bottom-title">维度评价总览</view>
<view class="body-bottom-item">
<view class="item-title">话术完整性 {{ 88 }}
<image class="item-title-icon" src="@/static/images/sparring/info-icon.png"></image>
<view class="body-bottom-item" v-for="item in evalDimens">
<view class="item-title">{{item.gradeDimensName}} {{ item.traGrade }}
<!-- <image class="item-title-icon" src="@/static/images/sparring/info-icon.png"></image> -->
</view>
<view class="item-cont">逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性</view>
</view>
<view class="body-bottom-item">
<view class="item-title">话术完整性 {{ 88 }}
<image class="item-title-icon" src="@/static/images/sparring/info-icon.png"></image>
</view>
<view class="item-cont">逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性</view>
</view>
<view class="body-bottom-item">
<view class="item-title">话术完整性 {{ 88 }}
<image class="item-title-icon" src="@/static/images/sparring/info-icon.png"></image>
</view>
<view class="item-cont">逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性</view>
</view>
<view class="body-bottom-item">
<view class="item-title">话术完整性 {{ 88 }}
<image class="item-title-icon" src="@/static/images/sparring/info-icon.png"></image>
</view>
<view class="item-cont">逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性逻辑贯穿性</view>
<view class="item-cont">{{item.settDesc}}</view>
</view>
<view :class="['body-bottom-static', 'pass','fialed']">
<view class="static-tip">得分</view>
<view class="static-score">{{ 97 }}</view>
<view class="static-desc">革命尚未成功同志仍需努力</view>
<view class="static-score">{{ totalScore }}</view>
<view class="static-desc">{{1?'革命尚未成功同志仍需努力':'恭喜阁下过关斩将,顺利通关!'}}</view>
<view class="static-charts">
<!-- <ChartThree v-if="length === 3" fromType="tra" :dataList="evalDimens" />
<ChartThree v-if="length === 3" fromType="tra" :dataList="evalDimens" />
<ChartFour v-if="length === 4" fromType="tra" :dataList="evalDimens" />
<ChartFive v-if="length === 5" fromType="tra" :dataList="evalDimens" />-->
<ChartSix fromType="tra" />
<!-- <ChartSeven v-if="length === 7" fromType="tra" :dataList="evalDimens"/> -->
<ChartFive v-if="length === 5" fromType="tra" :dataList="evalDimens" />
<ChartSix v-if="length === 6" fromType="tra" :dataList="evalDimens" />
<ChartSeven v-if="length === 7" fromType="tra" :dataList="evalDimens"/>
</view>
</view>
</view>
@@ -91,11 +74,15 @@
import ChartFive from '@/pages/course/components/chartFive.vue';
import ChartSix from '@/pages/course/components/chartSix.vue';
import ChartSeven from '@/pages/course/components/chartSeven.vue';
import { partnerChatReport } from "@/api/sparring.js"
const traId = ref('')
const execId = ref('')
const feedbackRef = ref()
const roleInfo = ref({})
const showAllTalk = ref(false)
const length = ref(6)
const traInfo = ref({})
const traTm = ref('')
const tabList = ref([
{
name: '全部',
@@ -111,24 +98,57 @@
}
])
const evalDimens = [{
gradeDimensName: '维度1',
anlyGrade: 60
}, {
gradeDimensName: '维度2',
anlyGrade: 80
}, {
gradeDimensName: '维度3',
anlyGrade: 30
}]
// const evalDimens = [{
// gradeDimensName: '维度1',
// anlyGrade: 60
// }, {
// gradeDimensName: '维度2',
// anlyGrade: 80
// }, {
// gradeDimensName: '维度3',
// anlyGrade: 30
// }]
const feedbackNow = () => {
feedbackRef.value.open({});
feedbackRef.value.open({
traId: traId.value
});
}
const changeTab = (info) => {
console.log(info)
}
const evalDimens = ref([])
const traPartnerExecuteAnswerRecords = ref([])
const totalScore = ref(0)
const getData = () => {
// execId=db2f275b-c04a-4572-83dd-74a95ff49d67&traId=PARTNERINFO02501812207220251103160409000007402
partnerChatReport({
// traId: traId.value,
// execId: execId.value
traId: 'PARTNERINFO02501812207220251103160409000007402',
execId: 'db2f275b-c04a-4572-83dd-74a95ff49d67'
}).then(res=>{
if(res.body.code === 200){
setTimeout(getData, 2000)
}else{
traInfo.value = res.body.traPartnerInfo
roleInfo.value = res.body.traPartnerCharacterInfoVo
traTm.value = res.body.traTm
evalDimens.value = res.body.traPartnerSettlement.map(t=>{
return {
...t,
anlyGrade: t.traGrade,
gradeDimensName: t.gradeDimensName||'维度'
}
})
traPartnerExecuteAnswerRecords.value = res.body.traPartnerExecuteAnswerRecords
}
})
}
onLoad((params) => {
traId.value = params.traId;
execId.value = params.execId
getData()
});
onMounted(() => {})
</script>
@@ -314,22 +334,42 @@
&-title {
font-size: 32rpx;
line-height: 64rpx;
font-weight: 600;
}
&-item {
padding: 23rpx 0;
.item-title {
line-height: 40rpx;
margin-bottom: 24rpx;
font-weight: 500;
.item-title-icon{
width: 24rpx;
height: 26rpx;
// line-height: 40rpx;
// margin-bottom: 24rpx;
// font-weight: 500;
// .item-title-icon{
// width: 24rpx;
// height: 26rpx;
// position: relative;
// top: 2rpx;
// left: 10rpx;
// }
line-height: 40rpx;
position: relative;
top: 2rpx;
left: 10rpx;
}
padding: 0rpx 46rpx 0rpx 26rpx;
line-height: 42rpx;
font-size: 29rpx;
margin-bottom: 16rpx;
&::before {
content: '';
display: block;
background-color: #000;
width: 12rpx;
height: 12rpx;
border-radius: 50%;
position: absolute;
left: 0rpx;
top: 14rpx;
}
}
.item-cont {
@@ -354,6 +394,7 @@
line-height: 44rpx;
font-size: 32rpx;
margin-bottom: 24rpx;
font-weight: 600;
}
.static-score{
font-size: 66rpx;
+326 -16
View File
@@ -8,14 +8,14 @@
<view class="top-box">
<view class="top-title">
<view class="back-icon" @click="common.navigateBack()"></view>
{{ '陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称陪练名称' }}
{{ detailInfo.traName }}
</view>
</view>
<view class="body-content">
<scroll-view :class="[' body-content index-dialog-body', detailInfo.traInterTyp === '01'?'talking-type1':'']" :scroll-y="true" refresher-default-style="none"
:scroll-top="scrollTop" :show-scrollbar="false" :scroll-with-animation="false">
<view :class="['body-content-role', showRoleInfo?'':'hide-info']">
<view :class="['role-title']">
<ImagePreview class="role-title-avatar" :src="'/traoss/tras3/show/S3F0250181220722025110316545500000431780'"
:isCache="true">
<ImagePreview class="role-title-avatar" :src="detailInfo.ossAddr" :isCache="true">
</ImagePreview>
<view class="role-title-info" @click="showRoleInfo = !showRoleInfo">
<view class="arrow-r-icon"></view>
@@ -56,12 +56,22 @@
<!-- sceneDesc -->
{{ detailInfo.sceneDesc }}
</view>
<view class="talking-box">
<TalkingItem v-for="(item, index) in talkingList" :talkingType="item.type" :talkingInfo="item" :roleInfo="detailInfo"
:traId="traId" :execId="execId"
:isLast="index + 1 === talkingList.length" :isAnswering="!answerIsOver"
:activeVoiceId="activeVoiceTalkingItemId" @handleEvents="talkItemEvents"></TalkingItem>
</view>
</scroll-view>
<view class="over-btn-box" v-if="detailInfo.traInterTyp === '01'">
<view class="over-btn" @click="overTalking">
结束陪练
</view>
</view>
<TouchBtn class="body-bottom" @uploadVoice="uploadRecordNow" @startRecord="changePlayItemId('')"
:isLoading="false" :isDisabled="false" />
<view class="body-bottom" v-if="false">
:isLoading="!answerIsOver" :isDisabled="false" v-if="detailInfo.traInterTyp === '01'"/>
<view class="body-bottom" v-else>
<view class="body-bottom-btn" @click="toTalking">
<view class="center-text">
<image class="type-icon" src="@/static/images/sparring/video-icon.png"
v-if="detailInfo.traInterTyp === '03'"></image>
@@ -79,8 +89,10 @@
<script setup>
import {
ref,
unref,
onMounted,
computed
computed,
nextTick
} from 'vue'
import {
onShow,
@@ -91,18 +103,46 @@
import TouchBtn from './components/touchBtn.vue';
import ImagePreview from '@/components/image-preview/image-preview.vue';
import {
queryTraPartnerCharacterInfoById
commonUploadVoiceFile
} from '@/api/common.js';
import {
queryTraPartnerCharacterInfoById,
partnerChatReportTrigger
} from "@/api/sparring.js"
import CardSwiper from './components/card-swiper.vue';
import {
useSocketStore
} from '@/store/socket.js';
import {
useStorageStore
} from '@/store/storage.js';
import {
storeToRefs
} from 'pinia';
import TalkingItem from './components/talking-item.vue'
const socketStore = useSocketStore();
const {
SocketObj
} = storeToRefs(socketStore);
const traId = ref('')
const chaId = ref('')
const talkingType = ref('')
const detailInfo = ref({})
const roleList = ref([])
const currentIndex = ref(0)
const showRoleInfo = ref(false)
const showLoading = ref(true)
const gender = ref('m')
const talkingList = ref([])
// {
// type: 'answer',
// talkingText: 'asad我是回答内容',
// isLoading: false,
// id: new Date().getTime(),
// },
const askData = ref({})
const execId = ref('')
const answerIsOver = ref(true);
const getDetailInfo = () => {
queryTraPartnerCharacterInfoById({
@@ -113,13 +153,68 @@
detailInfo.value = {
...res.body
}
if (detailInfo.value.traInterTyp === '01') {
initsocketTask()
}
setTimeout(() => {
showLoading.value = false
}, Math.random() * 1000 + 500)
})
}
const scrollTop = ref(99999);
const scrollToBottomNow = (time = 100) => {
nextTick(() => {
setTimeout(() => {
scrollTop.value += 100;
scrollTop.value += 100;
}, time);
});
};
const uploadRecordNow = (voicePath) => {
console.log(voicePath)
//#ifndef APP-PLUS
// h5 假数据
// #endif
//#ifdef APP-PLUS
talkingList.value.push({
type: 'question',
talkingText: '',
isLoading: true
});
scrollToBottomNow();
commonUploadVoiceFile(voicePath, '/trapractice/traPartnerChat/voiceTrans', {})
.then((_res) => {
console.log(_res)
if (!!(_res.body.transContent || '').trim()) {
askData.value = {
execId: execId.value,
intrctWay: '02', //01-文本;02-语音;03-图片
intrctContent: _res.body.transContent,
bucketKey: _res.body.fileId,
ossFileAddr: _res.body.ossFileAddr,
talkingVoice: voicePath
};
sendMessage({
commond: 'ASK',
body: askData.value
});
} else {
talkingList.value.pop();
uni.showToast({
title: '未识别到文字',
icon: 'none',
duration: 1000
});
}
})
.catch((err) => {
talkingList.value.pop();
uni.showToast({
title: '系统异常,请联系管理员',
icon: 'none',
duration: 1000
});
});
// #endif
}
const toTalking = () => {
common.navigateTo('/pages/sparring/chooseRole?traId=' + traId.value + '&chaId=' + chaId)
@@ -129,13 +224,205 @@
const changePlayItemId = (id = '') => {
activeVoiceTalkingItemId.value = id
}
const talkItemEvents = ({
type,
data,
id,
info = {}
}) => {
switch (type) {
case 'changePlay':
activeVoiceTalkingItemId.value = id;
break;
case 'askTip':
// 获取问答提示
break;
default:
break;
}
};
const watchFlag = ref(1);
const showModelComfirm = ref(false)
const reconcatNum = ref(0)
const answerText = ref('')
const touchBtnCallBack = ref(null)
const initsocketTask = () => {
socketStore.creatSocket('/trapractice/partnersocket/open?summary=');
// unref(SocketObj).on('open', (res)=>{
// if(!answerIsOver.value){
// sendMessage({
// "commond" : 'ASK-RE-START',
// "body" : {
// execId: execId.value,
// seqNo: seqNo.value,
// answerContent: answerText.value
// }
// })
// }
// })
unref(SocketObj).on('error', () => {
if (watchFlag.value === 1 || showModelComfirm.value) return;
if (reconcatNum.value === 5) {
common.msg('系统网络异常,请稍后再试!');
return;
}
showModelComfirm.value = true;
common
.show('提示信息', '网络环境不稳定,请重试!', false, '', '确认')
.then((res) => {
reconcatNum.value += 1;
common.redirectTo(`/pages/index/dialog`);
})
.finally(() => {
showModelComfirm.value = false;
});
});
unref(SocketObj).on('message', (res) => {
const {
rtnCode,
body,
commond
} = JSON.parse(res.data);
let _id = new Date().getTime() + 'id';
if (rtnCode === '0000') {
if (commond === 'ASK-OPEN') {
// 新连接
sendMessage({
commond: 'ASK-START',
body: {
traId: traId.value,
chaId: chaId.value,
talkingType: talkingType.value
}
});
return;
}
if (commond === 'ASK-START') {
// console.log('开启对话!')
execId.value = body.execId;
return;
}
if (commond === 'ASK') {
console.log('发送问题成功!');
console.log(body);
console.log(talkingList.value[talkingList.value.length - 1].isLoading);
if (talkingList.value.length > 0 && talkingList.value[talkingList.value.length - 1].isLoading) {
talkingList.value.pop();
}
// seqNo.value = body.seqNo;
// touchBtnCallBack.value && touchBtnCallBack.value();
// touchBtnCallBack.value = null;
talkingList.value.push({
type: 'question',
talkingText: body.content,
isLoading: false,
intrctWay: '02',
id: _id,
...body,
talkingVoice: askData.value.talkingVoice
});
talkingList.value.push({
type: 'answer',
isLoading: true,
id: _id + 'loading'
});
scrollToBottomNow();
return;
}
if (commond === 'ASK-STOP') {
console.log('停止回答标记!');
stopAnswerCallBack.value && stopAnswerCallBack.value(askData.value);
setTimeout(() => {
stopAnswerCallBack.value = null;
answerIsOver.value = true;
}, 10);
return;
}
if (commond === 'ASK-ANSWER') {
console.log('ASK-ANSWER',body);
if (body.event === 'start') {
console.log('开始回答!');
answerIsOver.value = false;
answerText.value = '';
talkingList.value.pop(); detailInfo.chaName
talkingList.value.push({
type: 'answer',
talkingText: answerText.value,
isLoading: false,
id: _id,
...body,
askData: {
...askData.value
},
talkingFiles: [],
talkingCrsList: []
});
} else if (body.event === 'token') {
answerIsOver.value = false;
answerText.value += body.data;
} else if (body.event === 'end') {
console.log('完成回答!');
answerIsOver.value = true;
}
return;
}
if (commond === 'ASK-RE-ANSWER') {
// console.log('开始继续回答!')
if (body.event === 'start') {
answerIsOver.value = false;
answerText.value = '';
} else if (body.event === 'token') {
answerIsOver.value = false;
answerText.value = body.data;
} else if (body.event === 'end') {
answerIsOver.value = true;
}
return;
}
if (commond === 'ASK-ERR') {
console.log('提问失败,系统异常!');
return;
}
} else {
if (['0005', 'QQ0005'].includes(res.rtnCode)) {
goto_login_fun();
}
}
});
watchFlag.value += 1;
};
const overTalking = () => {
partnerChatReportTrigger({
execId: execId.value,
traId: traId.value
}).then(res=>{
watchFlag.value = 1;
socketStore?.closeSocket();
common.navigateTo('/pages/sparring/result?traId=' + traId.value + '&execId=' + execId.value)
})
}
const sendMessage = (data) => {
unref(SocketObj).send(data);
};
//#ifdef APP-PLUS
onShow(() => {});
// #endif
onLoad((params) => {
traId.value = params.traId;
chaId.value = params.chaId;
talkingType.value = params.type;
getDetailInfo()
});
onUnload(() => {
watchFlag.value = 1;
socketStore?.closeSocket();
});
onMounted(() => {
getDetailInfo()
// getDetailInfo()
})
</script>
@@ -251,7 +538,10 @@
padding: 10rpx 24rpx 20rpx;
box-sizing: border-box;
overflow-y: auto;
&.talking-type1{
padding: 10rpx 24rpx 140rpx;
}
.body-content-role {
background-color: #fff;
border-radius: 16rpx;
@@ -414,8 +704,28 @@
text-align: center;
}
}
.talking-box{
padding-top: 24rpx;
}
}
.over-btn-box{
position: absolute;
bottom: 180rpx;
height: 140rpx;
padding: 0 23rpx;
width: 100%;
.over-btn{
float: right;
width: 194rpx;
height: 76rpx;
line-height: 72rpx;
border: 2rpx solid #06f;
border-radius: 15rpx;
text-align: center;
color:#06f;
margin-top: 34rpx;
}
}
.body-bottom {
height: 180rpx;
background-color: #fff;
Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B