diff --git a/.env.development.yh b/.env.development.yh
index 943c5717..0bc26d12 100644
--- a/.env.development.yh
+++ b/.env.development.yh
@@ -6,5 +6,5 @@ VITE_APP_BASE_API_Url = 'http://25.18.122.65:7001'
# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.78:9786'
# VITE_APP_BASE_H5_API_Url_TRAEXAM = 'http://25.64.32.154:9604'
-# VITE_APP_BASE_H5_API_Url_TRAPRACTICE = 'http://25.64.32.154:9603'
+VITE_APP_BASE_H5_API_Url_TRAPRACTICE = 'http://25.64.32.156:9603'
diff --git a/src/api/preview.js b/src/api/preview.js
index cbf1e63e..86eca834 100644
--- a/src/api/preview.js
+++ b/src/api/preview.js
@@ -10,3 +10,11 @@ export const queryTraStdyInfoPreviewPaging = (data) => {
data
});
};
+export const queryTraListPreviewPaging = (data) => {
+ return request({
+ url: '/trapractice/traPartnerInfo/queryTraPartnerPreviewPaging',
+ method: 'post',
+ toastErrors: true,
+ data
+ });
+};
diff --git a/src/api/traRecord.js b/src/api/traRecord.js
new file mode 100644
index 00000000..761429b5
--- /dev/null
+++ b/src/api/traRecord.js
@@ -0,0 +1,58 @@
+import request from '@/api/request'
+const base_url = '/trapractice'
+
+
+/**练习*/
+// 练习列表页
+export const queryPracticeRecordPaging = (data) => {
+ return request({
+ url: base_url + '/traPartnerExecuteHis/queryTraPartnerExecutePaging',
+ method: 'post',
+ toastErrors: true,
+ data:{
+ traType:'01',
+ ...data
+ }
+ });
+};
+// 练习每一项列表
+export const queryPracticeHis = (data) => {
+ return request({
+ url: base_url + '/traPartnerExecuteHis/queryTraPartnerExecuteHisPaging',
+ method: 'post',
+ toastErrors: true,
+ data
+ });
+};
+// 练习详情 通过 exrId 查询
+export const queryPracticeRecordByExrId = (data) => {
+ return request({
+ url: base_url + '/traCrsPractice/queryPracticeRecordByExrId',
+ method: 'post',
+ toastErrors: true,
+ data
+ });
+};
+
+/**考试*/
+export const queryCrsExamRecordPaging = (data) => {
+ return request({
+ url: base_url + '/traPartnerExecuteHis/queryTraPartnerExecutePaging',
+ method: 'post',
+ toastErrors: true,
+ data:{
+ traType:'02',
+ ...data
+ }
+ });
+};
+// 考试每一项列表
+export const queryCrsExamHisByExamId = (data) => {
+ return request({
+ url: base_url + '/traPartnerExecuteHis/queryTraPartnerExecuteHisPaging',
+ method: 'post',
+ toastErrors: true,
+ data
+ });
+};
+
diff --git a/src/pages.json b/src/pages.json
index 1348a422..9487bedc 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -510,6 +510,15 @@
"titleNView": false
}
}
+ },
+ {
+ "path": "pages/traRecord/index",
+ "style": {
+ "navigationBarTitleText": "陪练记录页",
+ "app-plus": {
+ "titleNView": false
+ }
+ }
}
],
"tabBar": {
diff --git a/src/pages/course/components/chartSeven.vue b/src/pages/course/components/chartSeven.vue
index e937eb79..54ff061e 100644
--- a/src/pages/course/components/chartSeven.vue
+++ b/src/pages/course/components/chartSeven.vue
@@ -119,7 +119,6 @@
dataY: dataY + '%'
});
}
- console.log(vertices)
return vertices;
},
diff --git a/src/pages/course/components/chartSix.vue b/src/pages/course/components/chartSix.vue
index 15860cf5..1b2fba48 100644
--- a/src/pages/course/components/chartSix.vue
+++ b/src/pages/course/components/chartSix.vue
@@ -119,7 +119,6 @@
dataY: dataY + '%'
});
}
- console.log(vertices)
return vertices;
},
diff --git a/src/pages/me/index.vue b/src/pages/me/index.vue
index acca313e..9bc2598e 100644
--- a/src/pages/me/index.vue
+++ b/src/pages/me/index.vue
@@ -97,7 +97,7 @@
-
+
AI陪练记录
diff --git a/src/pages/preview/components/previewAiSparring.vue b/src/pages/preview/components/previewAiSparring.vue
index ee9c7ad0..1a9b36d7 100644
--- a/src/pages/preview/components/previewAiSparring.vue
+++ b/src/pages/preview/components/previewAiSparring.vue
@@ -1,42 +1,67 @@
-
-
-
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/src/pages/sparring/components/answer.vue b/src/pages/sparring/components/answer.vue
index 823c525c..68b93536 100644
--- a/src/pages/sparring/components/answer.vue
+++ b/src/pages/sparring/components/answer.vue
@@ -5,16 +5,19 @@
+
+
+
-
-
+
+
@@ -39,9 +42,20 @@
watch,
toRefs
} from 'vue'
- import { onUnload } from '@dcloudio/uni-app';
+ import {
+ onUnload
+ } from '@dcloudio/uni-app';
import MarkdownPreview from '@/components/markdown-preview/markdown-preview.vue'
import common from '@/common/common'
+ import {
+ useStorageStore
+ } from '@/store/storage.js';
+ import {
+ downloadFile,
+ downloadVoiceFile
+ } from '@/api/common.js'
+
+ const storageStore = useStorageStore();
const emit = defineEmits(['handleEvents', 'changePlay'])
const props = defineProps({
@@ -49,6 +63,10 @@
default: () => ({}),
type: Object
},
+ roleInfo: {
+ default: () => ({}),
+ type: Object
+ },
isAnswering: {
default: false,
type: Boolean
@@ -56,24 +74,31 @@
isLast: {
default: false,
type: Boolean
- }
+ },
+ activeVoiceId: {
+ default: '',
+ type: String
+ },
+ isStudy: {
+ default: true,
+ type: Boolean
+ },
})
- const { isLast, dataInfo } = toRefs(props)
- watch(
- () => props.dataInfo,
- () => {}, {
- deep: true,
- immediate: true
- }
- )
-
+ const {
+ isLast,
+ dataInfo,
+ roleInfo,
+ activeVoiceId,
+ isStudy
+ } = toRefs(props)
const isPlaying = ref(false)
+ const voiceIsPlaying = ref(false)
+ const startPlay = ref(false)
+
const mdText = computed(() => {
let _text = (props.dataInfo?.talkingText || '').replace(/\\n/g, `\n`);
return _text
})
- const fileList = computed(() => props.dataInfo?.talkingFiles || [])
- const crsList = computed(() => props.dataInfo?.talkingCrsList || [])
const activeNames = ref([1, 2])
const changeActive = val => {
@@ -102,6 +127,22 @@
common.navigateTo('/pages/courseDetail/index?crsId=' + item.crsId)
}
const talkVoiceObj = ref(null)
+ const voiceLoading = ref(false)
+ const itemVoice = ref('')
+ // 重播
+ 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 = mdText.value;
if (!_content) {
@@ -109,41 +150,91 @@
return;
}
isPlaying.value = true
- voiceLoading.value = true;
setTimeout(() => {
- downloadFile(props.dataInfo?.talkingVoiceId)
- .then((res) => {
- if (res?.data) {
- common.msg(res.data.message);
- return;
- }
- voiceLoading.value = false;
- itemVoice.value = res.tempFilePath;
- talkVoiceObj.value.src = res.tempFilePath;
+ emit('changePlay', unref(dataInfo)?.id);
+ // readType 阅读内容类型pgrh段落/qns问题
+ if (talkVoiceObj.value.src && talkVoiceObj.value.src === itemVoice.value) {
+ if (voiceIsPlaying.value) return
+ talkVoiceObj.value.play();
+ voiceLoading.value = false;
+ return;
+ }
+ talkVoiceObj.value.src = '';
+ if (itemVoice.value) {
+ setTimeout(() => {
+ talkVoiceObj.value.src = itemVoice.value;
+ if (voiceIsPlaying.value) return
talkVoiceObj.value.play();
- })
- .catch((err) => {
- voiceLoading.value = false;
+ }, 100);
+ } else {
+ voiceLoading.value = true;
+ let _params = {
+ chaId: unref(roleInfo)?.chaId || '',
+ execLogId: unref(dataInfo)?.execLogId || '',
+ };
+ let _url =
+ '/trapractice/traPartnerChat/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;
+ if (voiceIsPlaying.value) return
+ 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;
+ if (voiceIsPlaying.value) return
+ talkVoiceObj.value.play();
+ storageStore.setStorage('audio', _url + _params.teachNo, itemVoice.value);
+ })
+ .catch((err) => {
+ voiceLoading.value = false;
+ emit('changePlay', '');
+ });
+ }
});
+
+ }
}, 100);
};
const initVoice = () => {
talkVoiceObj.value = uni.createInnerAudioContext()
- talkVoiceObj.value.onEnded(()=>{
+ talkVoiceObj.value.onEnded(() => {
emit('changePlay', '')
talkVoiceObj.value.src = ''
+ voiceIsPlaying.value = false
})
- talkVoiceObj.value.onError(()=>{
+ talkVoiceObj.value.onPause(() => {
+ voiceIsPlaying.value = false
+ });
+ talkVoiceObj.value.onPlay(() => {
+ console.log('onPlay');
+ startPlay.value = true
+ voiceIsPlaying.value = true
+ setTimeout(() => {
+ startPlay.value = false
+ }, 300)
+ emit('changePlay', unref(dataInfo)?.id);
+ });
+
+ talkVoiceObj.value.onError(() => {
talkVoiceObj.value.src = ''
+ voiceIsPlaying.value = false
})
- 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
@@ -158,18 +249,45 @@
pauseVoice()
})
watch(() => props.dataInfo.talkingVoice, (val) => {
- if (val) {
+ if (val && isStudy.value) {
initVoice()
}
}, {
deep: true,
immediate: true
})
+ watch(
+ () => props.dataInfo,
+ (val) => {
+ if (val.execLogId && isStudy.value) {
+ playVoice()
+ }
+ }, {
+ deep: true,
+ immediate: true
+ }
+ )
+ watch(
+ () => props.activeVoiceId,
+ (val) => {
+ if (val !== props.dataInfo.id) {
+ if (isPlaying.value) {
+ isPlaying.value = false
+ if (!talkVoiceObj.value) return
+ talkVoiceObj.value.pause()
+ }
+ }
+ }, {
+ deep: true,
+ immediate: true
+ }
+ )
\ No newline at end of file
diff --git a/src/pages/sparring/components/question.vue b/src/pages/sparring/components/question.vue
index 96121d50..ac76bc43 100644
--- a/src/pages/sparring/components/question.vue
+++ b/src/pages/sparring/components/question.vue
@@ -16,7 +16,7 @@
@@ -59,7 +59,6 @@ import { onUnload } from '@dcloudio/uni-app';
})
const { activeVoiceId, dataInfo } = toRefs(props)
const emit = defineEmits(['changePlay'])
- watch(() => props.dataInfo, () => {},{deep: true,immediate: true})
// 声音播放初始化
const talkVoiceObj = ref(null)
@@ -78,14 +77,6 @@ import { onUnload } from '@dcloudio/uni-app';
onUnload(()=>{
pauseVoice()
})
- watch(() => props.dataInfo.talkingVoice,(val)=>{
- if(val){
- initVoice()
- }
- },{
- deep: true,
- immediate: true
- })
const pauseVoice = () => {
if(!talkVoiceObj.value) return
talkVoiceObj.value.pause()
@@ -95,7 +86,10 @@ import { onUnload } from '@dcloudio/uni-app';
const playVoice = () =>{
emit('changePlay', unref(dataInfo)?.id)
if(talkVoiceObj.value && talkVoiceObj.value.src) {
- talkVoiceObj.value.play()
+ setTimeout(()=>{
+ talkVoiceObj.value.src = unref(dataInfo).talkingVoice
+ talkVoiceObj.value.play()
+ },300)
return
}else{
talkVoiceObj.value.src = ''
@@ -110,6 +104,14 @@ import { onUnload } from '@dcloudio/uni-app';
}
const initVoice = () => {
talkVoiceObj.value = uni.createInnerAudioContext()
+ talkVoiceObj.value.onPause(()=>{
+ })
+ talkVoiceObj.value.onPlay(()=>{
+ if(isTesting.value){
+ talkVoiceObj.value.pause()
+ isTesting.value = false
+ }
+ })
talkVoiceObj.value.onEnded(()=>{
emit('changePlay', '')
talkVoiceObj.value.src = ''
@@ -117,14 +119,16 @@ import { onUnload } from '@dcloudio/uni-app';
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)
- }
+ itemVoice.value = unref(dataInfo).talkingVoice
+ talkVoiceObj.value.src = itemVoice.value
+ talkVoiceObj.value.play()
+ isTesting.value = true
+ talkVoiceObj.value.pause()
+ setTimeout(()=>{
+ setVoiceTime(0)
+ },100)
}
+ const isTesting= ref(false)
const setVoiceTime = (sum) => {
sum += 1
if(Math.ceil(talkVoiceObj.value.duration)>0){
@@ -139,6 +143,15 @@ import { onUnload } from '@dcloudio/uni-app';
},200)
}
}
+ watch(() => props.dataInfo, () => {},{deep: true,immediate: true})
+ watch(() => props.dataInfo.talkingVoice,(val)=>{
+ if(val){
+ initVoice()
+ }
+ },{
+ deep: true,
+ immediate: true
+ })
\ No newline at end of file
diff --git a/src/pages/sparring/detail.vue b/src/pages/sparring/detail.vue
index a89955e2..26db1305 100644
--- a/src/pages/sparring/detail.vue
+++ b/src/pages/sparring/detail.vue
@@ -60,7 +60,10 @@
@click="previewFile(item)"> {{ item.dataName }}.{{ item.dataSuffix }}
-
+
+ 预览陪练
+
+
去练习
去考试
@@ -117,8 +120,11 @@
const toChooseRole = type => {
common.navigateTo('/pages/sparring/chooseRole?traId=' + traId.value + '&type=' + type)
}
+ const isPreview = ref(false)
onLoad(params => {
traId.value = params.traId
+ isPreview.value = params.isPreview === '1'
+ console.log(params)
})
onMounted(() => {
getDetailInfo()
diff --git a/src/pages/sparring/result.vue b/src/pages/sparring/result.vue
index d31bcc5a..dcdadc6b 100644
--- a/src/pages/sparring/result.vue
+++ b/src/pages/sparring/result.vue
@@ -23,36 +23,49 @@
-
-
+
+
-
+
+
+
+
+
-
+
维度评价总览
{{item.gradeDimensName}}: {{ item.traGrade }}
-
+
{{item.settDesc}}
-
+
得分
{{ totalScore }}
{{1?'革命尚未成功,同志仍需努力!':'恭喜阁下过关斩将,顺利通关!'}}
-
+
-
+
-
-
+
+
@@ -72,13 +85,18 @@
onLoad,
onUnload
} from '@dcloudio/uni-app';
+ import common from '@/common/common'
import Feedback from './components/feedback.vue';
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 ChartSix from '@/pages/course/components/chartSix.vue';
import ChartSeven from '@/pages/course/components/chartSeven.vue';
- import { partnerChatReport } from "@/api/sparring.js"
+ import TalkingPreviewItem from './components/talking-preview-item.vue'
+ import ImagePreview from '@/components/image-preview/image-preview.vue';
+ import {
+ partnerChatReport
+ } from "@/api/sparring.js"
const traId = ref('')
const execId = ref('')
const feedbackRef = ref()
@@ -87,8 +105,8 @@
const length = ref(6)
const traInfo = ref({})
const traTm = ref('')
- const tabList = ref([
- {
+ const activeVoiceTalkingItemId = ref('')
+ const tabList = ref([{
name: '全部',
value: ''
},
@@ -101,60 +119,135 @@
value: '02'
}
])
-
- // const evalDimens = [{
- // gradeDimensName: '维度1',
- // anlyGrade: 60
- // }, {
- // gradeDimensName: '维度2',
- // anlyGrade: 80
- // }, {
- // gradeDimensName: '维度3',
- // anlyGrade: 30
- // }]
+ const showTalkList = computed(() => {
+ return allTalkList.value.slice(0, 2)
+ })
+ const hideTalkList = computed(() => {
+ return allTalkList.value.slice(2)
+ })
+ const allTalkList = computed(() => {
+ if (!filterType.value) {
+ return traPartnerExecuteAnswerRecords.value
+ } else if (filterType.value === '01') {
+ return traPartnerExecuteAnswerRecords.value.filter((t, index) => {
+ return t.talkingText.indexOf('#15b859') >= 0 || traPartnerExecuteAnswerRecords.value[index + 1]
+ ?.talkingText.indexOf('#15b859') >= 0
+ })
+ } else if (filterType.value === '02') {
+ return traPartnerExecuteAnswerRecords.value.filter((t, index) => {
+ return t.talkingText.indexOf('#d70c18') >= 0 || traPartnerExecuteAnswerRecords.value[index + 1]
+ ?.talkingText.indexOf('#d70c18') >= 0
+ })
+ }
+ })
+ // 关闭播放状态
+ const changePlayItemId = (id = '') => {
+ activeVoiceTalkingItemId.value = id
+ }
+
+ const talkItemEvents = ({
+ type,
+ data,
+ id,
+ info = {}
+ }) => {
+ switch (type) {
+ case 'changePlay':
+ activeVoiceTalkingItemId.value = id;
+ break;
+ case 'scrollToBottom':
+ break;
+ default:
+ break;
+ }
+ };
const feedbackNow = () => {
feedbackRef.value.open({
traId: traId.value
});
}
+ const filterType = ref('')
const changeTab = (info) => {
console.log(info)
+ filterType.value = info.value
}
const evalDimens = ref([])
const traPartnerExecuteAnswerRecords = ref([])
const totalScore = ref(0)
const showLoading = ref(true)
+ const isPass = ref(false)
+ const negativeList = ref([]) // 劣质话术
+ const positiveList = ref([]) // 劣质话术
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){
+ 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=>{
+ } else {
+ traInfo.value = res.body.traPartnerInfo || {}
+ roleInfo.value = res.body.traPartnerCharacterInfoVo || {}
+ traTm.value = res.body.traTm || '0'
+ isPass.value = res.body.traPartnerExecuteHisVo?.traResult === 'P'
+ totalScore.value = res.body.traPartnerExecuteHisVo?.traGrade || '0'
+ positiveList.value = res.body.positiveList || []
+ negativeList.value = res.body.negativeList || []
+ let _evalDimens = res.body.traPartnerSettlement || []
+ evalDimens.value = _evalDimens.map(t => {
return {
...t,
anlyGrade: t.traGrade,
- gradeDimensName: t.gradeDimensName||'维度'
-
+ gradeDimensName: t.gradeDimensName || '维度'
+
}
})
- traPartnerExecuteAnswerRecords.value = res.body.traPartnerExecuteAnswerRecords
- setTimeout(()=>{
+ let _talkingList = res.body.traPartnerExecuteAnswerRecords || []
+ traPartnerExecuteAnswerRecords.value = _talkingList.map(t => {
+ let _content = setTextColor(t.content)
+ if (t.openStyle === '02') {
+ return {
+ ...t,
+ type: 'question',
+ talkingText: _content,
+ isLoading: false,
+ execLogId: t.execLogId || '',
+ intrctWay: '02',
+ id: t.execLogId,
+ ...t,
+ }
+ } else if (t.openStyle === '01') {
+ return {
+ ...t,
+ type: 'answer',
+ talkingText: _content,
+ isLoading: false,
+ execLogId: t.execLogId || '',
+ id: t.execLogId,
+ }
+ } else {
+ return t
+ }
+ })
+ setTimeout(() => {
showLoading.value = false
- },800)
+ }, 800)
}
})
}
+ const setTextColor = (str) => {
+ let _str = str
+ positiveList.value.forEach(t => {
+ _str = _str.split(t).join(`${t}`)
+ })
+ negativeList.value.forEach(t => {
+ _str = _str.split(t).join(`${t}`)
+ })
+ console.log(_str)
+ return _str
+ }
onLoad((params) => {
traId.value = params.traId;
execId.value = params.execId
@@ -179,44 +272,46 @@
padding: calc(var(--status-bar-height) + 90rpx) 0 0rpx;
// background-image: url(@/static/images/sparring/bg.png);
// background-size: cover;
-
-
+
+
}
- .sparring-result-loading {
- position: fixed;
- z-index: 20;
- height: 100vh;
- width: 100vw;
- background-image: url(@/static/images/sparring/bg.png);
-
- .loading-img {
+
+ .sparring-result-loading {
+ position: fixed;
+ z-index: 20;
+ height: 100vh;
+ width: 100vw;
+ background-image: url(@/static/images/sparring/bg.png);
+
+ .loading-img {
+ position: absolute;
+ width: 380rpx;
+ height: 540rpx;
+ top: 40%;
+ transform: translateY(-50%) translateX(-50%);
+ left: 50%;
+ padding-top: 540rpx;
+ line-height: 50rpx;
+ box-sizing: border-box;
+ text-align: center;
+ background-image: url(@/static/images/sparring/waiting.png);
+ background-repeat: no-repeat;
+ background-size: 380rpx 590rpx;
+
+ &::after {
+ content: '报告生成中,请耐心等待 ~ ';
+ display: block;
position: absolute;
- width: 380rpx;
- height: 540rpx;
- top: 40%;
- transform: translateY(-50%) translateX(-50%);
- left: 50%;
- padding-top: 540rpx;
+ left: 0%;
+ width: 100%;
+ bottom: -50rpx;
+ height: 50rpx;
line-height: 50rpx;
- box-sizing: border-box;
text-align: center;
- background-image: url(@/static/images/sparring/waiting.png);
- background-repeat: no-repeat;
- background-size: 380rpx 590rpx;
- &::after{
- content: '报告生成中,请耐心等待 ~ ';
- display: block;
- position: absolute;
- left: 0%;
- width: 100%;
- bottom: -50rpx;
- height: 50rpx;
- line-height: 50rpx;
- text-align: center;
- font-size: 28rpx;
- }
+ font-size: 28rpx;
}
}
+ }
.top-box {
height: 90rpx;
@@ -325,13 +420,56 @@
}
.body-top-collepse-title {
+ padding-top: 10rpx;
position: relative;
- .collepse-tab{
- position: absolute;
- width: 360rpx;
- right: 120rpx;
- top: 4rpx;
+ min-height: 100rpx;
+ .user-info {
+ overflow: hidden;
+ height: 92rpx;
+
+ .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: 76rpx;
+ height: 76rpx;
+ overflow: hidden;
+ }
+
+ }
+
+ .ai-name {
+ float: left;
+ color: #666;
+ font-size: 25rpx;
+ line-height: 35rpx;
+ width: 140rpx;
+ white-space: pre-wrap;
+
+ .ai-name-desc {
+ color: #999;
+ margin-left: 16rpx;
+ display: inline-block;
+ }
+ }
}
+
+ .collepse-tab {
+ position: absolute;
+ width: 300rpx;
+ right: 120rpx;
+ top: 0rpx;
+ z-index: 10;
+ }
+
.collepse-btn {
position: absolute;
right: 0;
@@ -340,6 +478,7 @@
height: 46rpx;
border: 2rpx solid #d4dce8;
border-radius: 23rpx;
+ z-index: 10;
&.show-all {
&::after {
@@ -399,25 +538,25 @@
// top: 2rpx;
// left: 10rpx;
// }
-
- line-height: 40rpx;
- position: relative;
- 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;
- }
+
+ line-height: 40rpx;
+ position: relative;
+ 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 {
@@ -425,32 +564,37 @@
line-height: 50rpx;
}
}
- &-static{
+
+ &-static {
border-top: 2px solid #eee;
padding-top: 38rpx;
background-repeat: no-repeat;
background-size: 270rpx 190rpx;
background-position: right 40rpx;
-
- &.fialed{
+
+ &.fialed {
background-image: url(@/static/images/sparring/def-res.png);
}
- &.pass{
+
+ &.pass {
background-image: url(@/static/images/sparring/pass-res.png);
}
- .static-tip{
+
+ .static-tip {
line-height: 44rpx;
font-size: 32rpx;
margin-bottom: 24rpx;
font-weight: 600;
}
- .static-score{
+
+ .static-score {
font-size: 66rpx;
color: #06f;
font-family: Arial, Helvetica, sans-serif;
marign-bottom: 20rpx;
}
- .static-desc{
+
+ .static-desc {
color: #999;
font-size: 25rpx;
margin-bottom: 32rpx;
@@ -460,14 +604,15 @@
}
.talk-item {
- height: 200rpx;
+ // height: 200rpx;
overflow: hidden;
- background-color: #0f0;
}
+
.my_tabs {
+
// 解决这个圆角的图片,开穿透
:deep(.uv-tabs__wrapper__nav__line) {
- background: linear-gradient(90deg, #06f 0%, rgb(0,159,255) 50%, rgb(255,255,255) 100%) !important;
+ background: linear-gradient(90deg, #06f 0%, rgb(0, 159, 255) 50%, rgb(255, 255, 255) 100%) !important;
}
:deep(.uv-tabs__wrapper__nav__item) {
diff --git a/src/pages/sparring/tip.vue b/src/pages/sparring/tip.vue
index ab45330d..6b97136a 100644
--- a/src/pages/sparring/tip.vue
+++ b/src/pages/sparring/tip.vue
@@ -235,8 +235,8 @@
case 'changePlay':
activeVoiceTalkingItemId.value = id;
break;
- case 'askTip':
- // 获取问答提示
+ case 'scrollToBottom':
+ scrollToBottomNow();
break;
default:
break;
@@ -249,7 +249,8 @@
const answerText = ref('')
const touchBtnCallBack = ref(null)
const initsocketTask = () => {
- socketStore.creatSocket('/trapractice/partnersocket/open?summary=');
+ let _src = talkingType.value === 'preview'?'/trapractice/partnersocket/open':'/trapractice/partnersocket/open'
+ socketStore.creatSocket(_src + '?summary=');
// unref(SocketObj).on('open', (res)=>{
// if(!answerIsOver.value){
// sendMessage({
@@ -346,26 +347,31 @@
console.log('开始回答!');
answerIsOver.value = false;
answerText.value = '';
- talkingList.value.pop(); detailInfo.chaName
+ talkingList.value.pop();
talkingList.value.push({
type: 'answer',
talkingText: answerText.value,
isLoading: false,
+ execLogId: body.execLogId||'',
id: _id,
...body,
askData: {
...askData.value
},
- talkingFiles: [],
- talkingCrsList: []
});
} else if (body.event === 'token') {
answerIsOver.value = false;
answerText.value += body.data;
+ console.log(answerText.value)
+ talkingList.value[talkingList.value.length - 1].talkingText = answerText.value;
} else if (body.event === 'end') {
console.log('完成回答!');
answerIsOver.value = true;
+ } else if (body.event === 'recordAi') {
+ console.log('推送声音id!');
+ talkingList.value[talkingList.value.length - 1].execLogId = body.execLogId
}
+ scrollToBottomNow();
return;
}
if (commond === 'ASK-RE-ANSWER') {
diff --git a/src/pages/traRecord/components/examRecordItem.vue b/src/pages/traRecord/components/examRecordItem.vue
new file mode 100644
index 00000000..8087220a
--- /dev/null
+++ b/src/pages/traRecord/components/examRecordItem.vue
@@ -0,0 +1,248 @@
+
+
+
+
+
+
+
+
+ {{ item.traName }}
+
+
+
+ {{ item.maxGrade || '0' }}
+ 历史最高分
+
+
+
+
+ {{ item.executeHisNum || 0 }}
+
+
+ 考试记录
+
+
+
+
+
+
+
+
+
+ 考试时间:{{ item_list.startPracticeTm }}
+
+
+
+ 考试得分:{{ item_list.traGrade }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/traRecord/components/examRecordList.vue b/src/pages/traRecord/components/examRecordList.vue
new file mode 100644
index 00000000..e021485b
--- /dev/null
+++ b/src/pages/traRecord/components/examRecordList.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/traRecord/components/practiceRecordItem.vue b/src/pages/traRecord/components/practiceRecordItem.vue
new file mode 100644
index 00000000..c96a9e80
--- /dev/null
+++ b/src/pages/traRecord/components/practiceRecordItem.vue
@@ -0,0 +1,250 @@
+
+
+
+
+
+
+
+
+ {{ item.traName }}
+
+
+
+ {{ item.maxGrade || '0' }}
+ 历史最高分
+
+
+
+
+ {{ item.executeHisNum || '0' }}
+
+
+ 练习记录
+
+
+
+
+
+
+
+
+
+ 练习时间:{{ item_list.startPracticeTm }}
+
+
+
+ 练习得分:{{item_list.traGrade }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/traRecord/components/practiceRecordList.vue b/src/pages/traRecord/components/practiceRecordList.vue
new file mode 100644
index 00000000..30bc5634
--- /dev/null
+++ b/src/pages/traRecord/components/practiceRecordList.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/traRecord/index.vue b/src/pages/traRecord/index.vue
new file mode 100644
index 00000000..46388ad0
--- /dev/null
+++ b/src/pages/traRecord/index.vue
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+ 陪练记录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/traRecord/useItemList.js b/src/pages/traRecord/useItemList.js
new file mode 100644
index 00000000..2ff3c9b1
--- /dev/null
+++ b/src/pages/traRecord/useItemList.js
@@ -0,0 +1,112 @@
+import {
+ computed,
+ reactive,
+ nextTick,
+ ref
+} from 'vue';
+
+
+// 计算两个标准时间的时间差值
+export const formatDuration = (startTm, endTm) => {
+ if (endTm === null || startTm === null) return "00:00:00";
+ // 解析时间字符串为时间戳(毫秒)
+ const startTime = new Date(startTm).getTime();
+ const endTime = new Date(endTm).getTime();
+
+ // 计算时间差(秒),确保为正数
+ const seconds = Math.abs(Math.floor((endTime - startTime) / 1000));
+ // 计算时、分、秒
+ const hours = Math.floor(seconds / 3600);
+ const minutes = Math.floor((seconds % 3600) / 60);
+ const remainingSeconds = seconds % 60;
+
+ // 补零格式化函数(统一处理所有单位)
+ const formatNumber = (num) => num.toString().padStart(2, '0');
+
+ // 小时、分钟、秒均保持两位数格式
+ return `${formatNumber(hours)}:${formatNumber(minutes)}:${formatNumber(remainingSeconds)}`;
+};
+
+// 秒数转换成小时,带小数点的小时
+export const secondsToHours = (seconds) => {
+ if (typeof seconds === 'number') {
+ // 转换为小时并保留一位小数
+ return (seconds / 3600).toFixed(1);
+ }
+ return '0.0';
+};
+
+export function useItemList(fetchFunction, item) {
+ const status = ref('loadmore'); // loadmore - 加载前,loading - 加载中,nomore - 没有数据
+ const limit = 5;
+ const page = ref(0);
+ const total = ref(-1);
+ const data_list = reactive([]);
+ const show_list_state = ref(false);
+
+ const list_div_height = computed(() => {
+ const statusHeight = status.value === 'nomore' ? 0 : 100;
+ if (!show_list_state.value) {
+ return '0';
+ } else if (status.value === 'loading') {
+ return data_list.length * 136 + statusHeight + 'rpx';
+ } else {
+ return data_list.length * 136 + statusHeight + 'rpx';
+ }
+ });
+ // 点击获取详情
+ const show_list_click = (num = -1) => {
+ if (num === 0) return;
+ show_list_state.value = !show_list_state.value;
+ if (show_list_state.value) {
+ nextTick(() => {
+ getData('first');
+ });
+ }
+ };
+
+ const getData = (from = '') => {
+ if (from === 'first') {
+ if (total.value !== -1) {
+ return;
+ }
+ status.value = 'loading';
+ total.value = -1;
+ page.value = 1;
+ data_list.length = 0;
+ } else {
+ if (status.value !== 'loadmore' && status.value !== '') return;
+ status.value = 'loading';
+ page.value++;
+ }
+ fetchFunction({
+ page: page.value,
+ limit: limit
+ })
+ .then((res) => {
+ total.value = res.total;
+ data_list.push(...res.body);
+ })
+ .finally(() => {
+ if (data_list.length >= total.value) {
+ status.value = 'nomore';
+ } else {
+ status.value = 'loadmore';
+ }
+ });
+ };
+ const clear = () => {
+ total.value = -1
+ data_list.length = 0
+ show_list_state.value = false
+ }
+ return {
+ status,
+ data_list,
+ show_list_state,
+ list_div_height,
+ show_list_click,
+ getData,
+ clear
+ };
+}
\ No newline at end of file
diff --git a/src/pagesB.json b/src/pagesB.json
index d1d11dc2..d4a3b69b 100644
--- a/src/pagesB.json
+++ b/src/pagesB.json
@@ -116,6 +116,15 @@
"titleNView": false
}
}
- }
+ },
+ {
+ "path": "pages/traRecord/index",
+ "style": {
+ "navigationBarTitleText": "陪练记录页",
+ "app-plus": {
+ "titleNView": false
+ }
+ }
+ },
]
}
\ No newline at end of file