新增ai问答演示
This commit is contained in:
+1
-1
@@ -25,6 +25,6 @@ VITE_APP_BASE_H5_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_TRASTUDY = 'http://25.64.16.130:9602'
|
||||
# VITE_APP_BASE_H5_API_Url_TRAASK = 'http://25.64.16.144:9605'
|
||||
VITE_APP_BASE_H5_API_Url_TRAASK = 'http://25.64.16.144:9605'
|
||||
|
||||
|
||||
|
||||
+11
-1
@@ -50,4 +50,14 @@ export const updateLikeStat = (data) => {
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// example /traask/traTestchat/chatVoice
|
||||
export const chatVoice = (data) => {
|
||||
return request({
|
||||
url: '/traask/traTestchat/chatVoice',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="answer-content" v-else>
|
||||
<view :class="['talking-gif', !voiceLoading&&(props.activeVoiceId === dataInfo.id) ? 'is-play' : '']">
|
||||
<view :class="['talking-gif', !voiceLoading&&isPlaying ? 'is-play' : '']">
|
||||
</view>
|
||||
<view class="talking-cont">
|
||||
<MarkdownPreview :mdString="mdText" />
|
||||
@@ -32,9 +32,10 @@
|
||||
<view class="btns-cont">
|
||||
<view class="replay-btn" >
|
||||
<image class="icon" src="@/static/images/course/play.png" style="width: 100%; height: 100%"
|
||||
v-show="!(!voiceLoading&&(props.activeVoiceId === dataInfo.id))"
|
||||
v-show="!isPlaying"
|
||||
@click.stop="playVoice()" ></image>
|
||||
<image class="icon"src="@/static/images/course/pause.png"
|
||||
v-show="isPlaying"
|
||||
style="width: 100%; height: 100%" @click.stop="pauseVoice"></image>
|
||||
</view>
|
||||
</view>
|
||||
@@ -48,9 +49,10 @@ import MarkdownPreview from '@/components/markdown-preview/markdown-preview.vue'
|
||||
import common from '@/common/common'
|
||||
import {
|
||||
downloadVoiceFile,
|
||||
downloadFile
|
||||
} from '@/api/common.js';
|
||||
|
||||
const emit = defineEmits(['handleEvents'])
|
||||
const emit = defineEmits(['handleEvents', 'changePlay'])
|
||||
const props = defineProps({
|
||||
dataInfo: {
|
||||
default: () => ({}),
|
||||
@@ -110,9 +112,11 @@ const isPlaying = ref(false)
|
||||
talkVoiceObj.value.onEnded(()=>{
|
||||
emit('changePlay', '')
|
||||
talkVoiceObj.value.src = ''
|
||||
isPlaying.value = false
|
||||
})
|
||||
talkVoiceObj.value.onError(()=>{
|
||||
talkVoiceObj.value.src = ''
|
||||
isPlaying.value = false
|
||||
})
|
||||
// itemVoice.value = unref(dataInfo).talkingVoice
|
||||
// talkVoiceObj.value.src = itemVoice.value
|
||||
@@ -143,16 +147,9 @@ const isPlaying = ref(false)
|
||||
isPlaying.value = true
|
||||
voiceLoading.value = true;
|
||||
setTimeout(() => {
|
||||
let _params = {}
|
||||
let _url =
|
||||
'/trastudy/traStdyInfo/readContent?' +
|
||||
Object.keys(_params)
|
||||
.map((t) => {
|
||||
return encodeURIComponent(t) + '=' + encodeURIComponent(_params[t]);
|
||||
})
|
||||
.join('&');
|
||||
|
||||
downloadVoiceFile(_url)
|
||||
|
||||
downloadFile(props.dataInfo?.talkingVoiceId)
|
||||
.then((res) => {
|
||||
if (res?.data) {
|
||||
common.msg(res.data.message);
|
||||
@@ -162,7 +159,6 @@ const isPlaying = ref(false)
|
||||
itemVoice.value = res.tempFilePath;
|
||||
talkVoiceObj.value.src = res.tempFilePath;
|
||||
talkVoiceObj.value.play();
|
||||
storageStore.setStorage('audio', _url + _params.teachNo, itemVoice.value);
|
||||
})
|
||||
.catch((err) => {
|
||||
voiceLoading.value = false;
|
||||
|
||||
+143
-169
@@ -3,14 +3,8 @@
|
||||
<!-- <MarkdownPreview/> -->
|
||||
<view class="top-bg"></view>
|
||||
<view class="bot-bg"></view>
|
||||
<scroll-view
|
||||
class="index-dialog-body"
|
||||
:scroll-y="true"
|
||||
upper-threshold="0"
|
||||
refresher-enabled="true"
|
||||
refresher-default-style="none"
|
||||
@refresherrefresh="scrolltolower"
|
||||
>
|
||||
<scroll-view class="index-dialog-body" :scroll-y="true" upper-threshold="0" refresher-enabled="true"
|
||||
refresher-default-style="none" @refresherrefresh="scrolltolower">
|
||||
<view class="body-title">
|
||||
<!-- <uv-icon class="arrow-icon" name="arrow-left" @click="common.navigateBack()"/> -->
|
||||
AI问答演示
|
||||
@@ -49,34 +43,16 @@
|
||||
</scroll-view>
|
||||
</view> -->
|
||||
<view class="talking-list">
|
||||
<scroll-view
|
||||
class="talking-scroll-list"
|
||||
:scroll-y="true"
|
||||
:scroll-top="scrollTop"
|
||||
:show-scrollbar="false"
|
||||
:scroll-with-animation="false"
|
||||
>
|
||||
<TalkingItem
|
||||
v-for="(item, index) in talkingList"
|
||||
:talkingType="item.type"
|
||||
:talkingInfo="item"
|
||||
:isLast="index + 1 === talkingList.length"
|
||||
:isAnswering="!answerIsOver"
|
||||
:activeVoiceId="activeVoiceTalkingItemId"
|
||||
@handleEvents="talkItemEvents"
|
||||
></TalkingItem>
|
||||
<scroll-view class="talking-scroll-list" :scroll-y="true" :scroll-top="scrollTop" :show-scrollbar="false"
|
||||
:scroll-with-animation="false">
|
||||
<TalkingItem v-for="(item, index) in talkingList" :talkingType="item.type" :talkingInfo="item"
|
||||
:isLast="index + 1 === talkingList.length" :isAnswering="!answerIsOver"
|
||||
:activeVoiceId="activeVoiceTalkingItemId" @handleEvents="talkItemEvents"></TalkingItem>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<TouchBtn
|
||||
class="talk-btns"
|
||||
@uploadVoice="uploadRecordNow"
|
||||
@submitAnswer="submitAnswerNow"
|
||||
@startRecord="startRecordCallback"
|
||||
:loadingText="sendLoadingText"
|
||||
:isLoading="!answerIsOver"
|
||||
:adjustPosition="true"
|
||||
:isDisabled="isHistory"
|
||||
/>
|
||||
<TouchBtn class="talk-btns" @uploadVoice="uploadRecordNow" @submitAnswer="submitAnswerNow"
|
||||
@startRecord="startRecordCallback" :loadingText="sendLoadingText" :isLoading="!answerIsOver"
|
||||
:adjustPosition="true" :isDisabled="isHistory" />
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
@@ -85,37 +61,72 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, unref, onMounted, watch, nextTick, computed, onActivated } from 'vue';
|
||||
import {
|
||||
ref,
|
||||
unref,
|
||||
onMounted,
|
||||
watch,
|
||||
nextTick,
|
||||
computed,
|
||||
onActivated
|
||||
} from 'vue';
|
||||
import common from '@/common/common';
|
||||
import { setupKeyboardHeightListener } from '@/common/common';
|
||||
import {
|
||||
setupKeyboardHeightListener
|
||||
} from '@/common/common';
|
||||
import TouchBtn from '@/pages/course/components/touchBtn.vue';
|
||||
import TalkingItem from './components/talking-item.vue';
|
||||
import { useSocketStore } from '@/store/socket.js';
|
||||
import { useStorageStore } from '@/store/storage.js';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { onLoad, onShow, onUnload, onHide, onBackPress } from '@dcloudio/uni-app';
|
||||
import { get_base_url, goto_login_fun } from '@/api/request';
|
||||
import { getUserInfo, getPhoneEnvBool } from '@/common/common';
|
||||
import { commonUploadVoiceFile } from '@/api/common.js';
|
||||
import {
|
||||
useSocketStore
|
||||
} from '@/store/socket.js';
|
||||
import {
|
||||
useStorageStore
|
||||
} from '@/store/storage.js';
|
||||
import {
|
||||
storeToRefs
|
||||
} from 'pinia';
|
||||
import {
|
||||
onLoad,
|
||||
onShow,
|
||||
onUnload,
|
||||
onHide,
|
||||
onBackPress
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
get_base_url,
|
||||
goto_login_fun
|
||||
} from '@/api/request';
|
||||
import {
|
||||
getUserInfo,
|
||||
getPhoneEnvBool
|
||||
} from '@/common/common';
|
||||
import {
|
||||
commonUploadVoiceFile
|
||||
} from '@/api/common.js';
|
||||
import {
|
||||
queryHotQuestionApi,
|
||||
insertTraAskFeedback,
|
||||
queryAskHisByBatchIdPaging,
|
||||
updateLikeStat,
|
||||
updateDownvoteStat
|
||||
updateDownvoteStat,
|
||||
chatVoice
|
||||
} from '@/api/dialog.js';
|
||||
|
||||
const { statusBarHeight } = uni.getWindowInfo();
|
||||
|
||||
const {
|
||||
statusBarHeight
|
||||
} = uni.getWindowInfo();
|
||||
|
||||
const pageTopPadding = computed(() => statusBarHeight + 'px');
|
||||
|
||||
const socketStore = useSocketStore();
|
||||
const { SocketObj } = storeToRefs(socketStore);
|
||||
const {
|
||||
SocketObj
|
||||
} = storeToRefs(socketStore);
|
||||
|
||||
const feedbackRef = ref();
|
||||
const watermarkRef = ref();
|
||||
const userInfo = ref(getUserInfo());
|
||||
const userParams = '/' + (unref(userInfo)?.userName??'') + ' ' + (unref(userInfo)?.loginName??'');
|
||||
const userParams = '/' + (unref(userInfo)?.userName ?? '') + ' ' + (unref(userInfo)?.loginName ?? '');
|
||||
const questionList = ref([
|
||||
// '对公小程序开户流程?',
|
||||
// '厅堂服务经理2025年管理办法?',
|
||||
@@ -151,13 +162,16 @@
|
||||
const answerText = ref('');
|
||||
const answerFileList = ref('');
|
||||
const answerIsOver = ref(true);
|
||||
const talkingList = ref([{
|
||||
type: 'answer',
|
||||
isLoading: false,
|
||||
id: 1 + 'loading',
|
||||
talkingText: '是否手动关闭',
|
||||
talkingVoice: 'askData.value.talkingVoice'
|
||||
}]);
|
||||
const talkingList = ref([
|
||||
// {
|
||||
// type: 'answer',
|
||||
// isLoading: false,
|
||||
// id: 1 + 'loading',
|
||||
// talkingText: '是否手动关闭',
|
||||
// talkingVoice: 'askData.value.talkingVoice'
|
||||
// }
|
||||
|
||||
]);
|
||||
|
||||
const createNewDialog = () => {
|
||||
if (talkingList.value.length === 0) {
|
||||
@@ -188,7 +202,11 @@
|
||||
});
|
||||
});
|
||||
unref(SocketObj).on('message', (res) => {
|
||||
const { rtnCode, body, commond } = JSON.parse(res.data);
|
||||
const {
|
||||
rtnCode,
|
||||
body,
|
||||
commond
|
||||
} = JSON.parse(res.data);
|
||||
let _id = new Date().getTime() + 'id';
|
||||
if (rtnCode === '0000') {
|
||||
if (commond === 'ASK-OPEN') {
|
||||
@@ -313,14 +331,39 @@
|
||||
watchFlag.value += 1;
|
||||
};
|
||||
const sendLoadingText = ref('问题回答中,请在问题回答结束后重试!');
|
||||
const reconnect = () => {
|
||||
if (reconnectTimer || isManualClose.value) return;
|
||||
reconnectTimer = setTimeout(() => {
|
||||
initsocketTask();
|
||||
}, 3000);
|
||||
};
|
||||
const sendMessage = (data) => {
|
||||
unref(SocketObj).send(data);
|
||||
touchBtnCallBack.value && touchBtnCallBack.value();
|
||||
touchBtnCallBack.value = null;
|
||||
let _id = new Date().getTime() + 'id';
|
||||
talkingList.value.push({
|
||||
type: 'question',
|
||||
talkingText: data.body.intrctContent,
|
||||
isLoading: false,
|
||||
...data.body,
|
||||
id: _id + 'q',
|
||||
talkingVoice: askData.value.talkingVoice || ''
|
||||
});
|
||||
talkingList.value.push({
|
||||
type: 'answer',
|
||||
isLoading: true,
|
||||
id: _id + 'loading'
|
||||
});
|
||||
chatVoice({
|
||||
chatVoice: data.body.intrctContent
|
||||
}).then(res => {
|
||||
talkingList.value.pop()
|
||||
talkingList.value.push({
|
||||
type: 'answer',
|
||||
talkingText: res.body.content,
|
||||
isLoading: false,
|
||||
id: _id + 'a',
|
||||
talkingFiles: [],
|
||||
talkingCrsList: [],
|
||||
talkingVoice: '',
|
||||
talkingVoiceId: res.body.fileId
|
||||
});
|
||||
})
|
||||
|
||||
};
|
||||
watch(
|
||||
() => answerText.value,
|
||||
@@ -338,7 +381,12 @@
|
||||
};
|
||||
|
||||
const stopAnswerCallBack = ref(null);
|
||||
const talkItemEvents = ({ type, data, id, info = {} }) => {
|
||||
const talkItemEvents = ({
|
||||
type,
|
||||
data,
|
||||
id,
|
||||
info = {}
|
||||
}) => {
|
||||
switch (type) {
|
||||
case 'reAnswer':
|
||||
console.log('重新提问回答');
|
||||
@@ -423,30 +471,11 @@
|
||||
uni.openDocument({
|
||||
filePath: res,
|
||||
showMenu: true,
|
||||
success: function () {
|
||||
success: function() {
|
||||
console.log('打开文档成功');
|
||||
}
|
||||
});
|
||||
});
|
||||
// uni.downloadFile({
|
||||
// url: fileUrl,
|
||||
// success: function (res) {
|
||||
|
||||
// uni.saveFile({
|
||||
// tempFilePath: res.tempFilePath,
|
||||
// success: function (resS) {
|
||||
// var filePath = resS.savedFilePath
|
||||
// uni.openDocument({
|
||||
// filePath: filePath,
|
||||
// showMenu: true,
|
||||
// success: function () {
|
||||
// console.log('打开文档成功')
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
}
|
||||
break;
|
||||
case 'toCourse':
|
||||
@@ -462,8 +491,7 @@
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log('开始下载:', fileUrl);
|
||||
const dtask = plus.downloader.createDownload(
|
||||
fileUrl,
|
||||
{
|
||||
fileUrl, {
|
||||
filename: localFilePath
|
||||
},
|
||||
(d, status) => {
|
||||
@@ -522,11 +550,6 @@
|
||||
console.log(res);
|
||||
|
||||
talkingList.value = (res.body || []).map((t, index) => {
|
||||
// let _obj = JSON.parse( t.respContent)
|
||||
// console.log(_obj,0)
|
||||
// if(t.chatRole === 'TCH'){
|
||||
// console.log(JSON.parse(_obj),1)
|
||||
// }
|
||||
let _text;
|
||||
let _talkingCrsList;
|
||||
let _talkingFiles;
|
||||
@@ -559,25 +582,6 @@
|
||||
historyRef.value.close();
|
||||
});
|
||||
};
|
||||
const routerTo = (type) => {
|
||||
switch (type) {
|
||||
case 'AI学':
|
||||
common.switchTab('/pages/course/index');
|
||||
break;
|
||||
case 'AI考':
|
||||
common.navigateTo('/pages/testingHall/index');
|
||||
break;
|
||||
case '任务':
|
||||
common.navigateTo('/pages/learningTasks/index');
|
||||
break;
|
||||
case '错题':
|
||||
common.navigateTo('/pages/wrongQuestionRecord/index');
|
||||
break;
|
||||
default:
|
||||
common.msg('页面建设中,敬请期待!');
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const touchBtnCallBack = ref(null);
|
||||
const askData = ref({});
|
||||
@@ -599,27 +603,27 @@
|
||||
scrollToBottomNow();
|
||||
commonUploadVoiceFile(voicePath, '/traask/traAskchat/voiceTrans', {})
|
||||
.then((_res) => {
|
||||
if (!!(_res.body.transContent || '').trim()) {
|
||||
askData.value = {
|
||||
reqBatch: reqBatch.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
|
||||
});
|
||||
}
|
||||
if (!!(_res.body.transContent || '').trim()) {
|
||||
askData.value = {
|
||||
reqBatch: reqBatch.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();
|
||||
@@ -658,26 +662,6 @@
|
||||
common.navigateBack();
|
||||
};
|
||||
|
||||
onBackPress((options) => {
|
||||
const from = options.from;
|
||||
if (from === 'backbutton') {
|
||||
// 判断上一级是否是登录,是登录就返回两层跳过登录页
|
||||
const pages = getCurrentPages();
|
||||
if (pages && pages.length > 1) {
|
||||
const page = pages[pages.length - 2];
|
||||
if (page.route === 'pages/login/login') {
|
||||
if (pages.length == 2) {
|
||||
common.switchTab('/pages/index/index');
|
||||
} else {
|
||||
common.navigateBack(2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
const getQuestionList = () => {
|
||||
queryHotQuestionApi().then((res) => {
|
||||
console.log(res);
|
||||
@@ -694,7 +678,7 @@
|
||||
const loadData = async () => {
|
||||
userInfo.value = getUserInfo();
|
||||
// getQuestionList();
|
||||
initsocketTask();
|
||||
// initsocketTask();
|
||||
};
|
||||
onLoad(() => {
|
||||
changeAppHeightBottom();
|
||||
@@ -745,31 +729,17 @@
|
||||
|
||||
const deleteFolder = () => {
|
||||
//#ifdef APP-PLUS
|
||||
plus.io.resolveLocalFileSystemURL('_doc/pdf_view', function (entry) {
|
||||
plus.io.resolveLocalFileSystemURL('_doc/pdf_view', function(entry) {
|
||||
console.log('entry', entry);
|
||||
entry.removeRecursively(function (res) {
|
||||
entry.removeRecursively(function(res) {
|
||||
console.log('删除成功');
|
||||
});
|
||||
});
|
||||
// #endif
|
||||
};
|
||||
|
||||
//#ifdef APP-PLUS
|
||||
onHide(() => {
|
||||
uni.offKeyboardHeightChange(setHeight);
|
||||
});
|
||||
onShow(() => {
|
||||
uni.onKeyboardHeightChange(setHeight);
|
||||
nextTick(() => {
|
||||
watermarkRef.value?.updateWatermarkText();
|
||||
});
|
||||
});
|
||||
// #endif
|
||||
onUnload(() => {
|
||||
watchFlag.value = 1;
|
||||
deleteFolder();
|
||||
socketStore?.closeSocket();
|
||||
// setupKeyboardHeightListener(changeAppHeightBottom)
|
||||
});
|
||||
defineExpose({
|
||||
refreshData
|
||||
@@ -846,6 +816,7 @@
|
||||
line-height: 32rpx;
|
||||
text-align: right;
|
||||
padding-right: 48rpx;
|
||||
|
||||
.more-list {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
@@ -857,9 +828,11 @@
|
||||
padding: 16rpx 0;
|
||||
display: none;
|
||||
z-index: 21;
|
||||
|
||||
&.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.more-item {
|
||||
line-height: 60rpx;
|
||||
font-size: 29rpx;
|
||||
@@ -868,6 +841,7 @@
|
||||
z-index: 22;
|
||||
}
|
||||
}
|
||||
|
||||
.image-icon {
|
||||
width: 30rpx;
|
||||
height: 32rpx;
|
||||
@@ -1039,4 +1013,4 @@
|
||||
// height: 100%;
|
||||
// }
|
||||
// }
|
||||
</style>
|
||||
</style>
|
||||
@@ -101,6 +101,7 @@
|
||||
</view>
|
||||
<view class="cell_div">
|
||||
<uv-cell-group :border="false">
|
||||
<uv-cell title="问答演示" :isLink="true" @click="common.navigateTo('/pages/example/dialog')"></uv-cell>
|
||||
<uv-cell
|
||||
title="消息通知"
|
||||
:isLink="true"
|
||||
@@ -115,7 +116,6 @@
|
||||
:border="false"
|
||||
@click="common.navigateTo('/pages/preview/index')"
|
||||
></uv-cell>
|
||||
<!-- <uv-cell title="问答演示" :isLink="true" @click="common.navigateTo('/pages/example/dialog')"></uv-cell> -->
|
||||
</uv-cell-group>
|
||||
</view>
|
||||
<view class="cell_div">
|
||||
|
||||
Reference in New Issue
Block a user