JLBA202505130001_关于吉林银行新建AI智能培训系统的需求_热门问题推荐,问答样式调整

This commit is contained in:
杨航
2026-01-08 09:47:54 +08:00
parent 529f4f4829
commit 600a57d5b8
2 changed files with 190 additions and 108 deletions
+1 -1
View File
@@ -11,5 +11,5 @@ VITE_APP_BASE_H5_API_Url = 'http://25.18.122.91:9786'
# VITE_APP_BASE_H5_API_Url_TRAPRACTICE = 'http://25.64.32.156:9603' # VITE_APP_BASE_H5_API_Url_TRAPRACTICE = 'http://25.64.32.156:9603'
# VITE_APP_BASE_H5_API_Url_TRAAPP = 'http://25.64.32.154:9601' # VITE_APP_BASE_H5_API_Url_TRAAPP = 'http://25.64.32.154:9601'
# VITE_APP_BASE_H5_API_Url_TRAAPP = 'http://25.64.32.158:9601' # VITE_APP_BASE_H5_API_Url_TRAAPP = 'http://25.64.32.158:9601'
VITE_APP_BASE_H5_API_Url_TRASTUDY = 'http://25.64.32.154:9602' # VITE_APP_BASE_H5_API_Url_TRASTUDY = 'http://25.64.32.154:9602'
+189 -107
View File
@@ -3,31 +3,17 @@
<!-- <MarkdownPreview/> --> <!-- <MarkdownPreview/> -->
<view class="top-bg"></view> <view class="top-bg"></view>
<view class="bot-bg"></view> <view class="bot-bg"></view>
<scroll-view <scroll-view class="index-dialog-body" :scroll-y="true" upper-threshold="0" refresher-enabled="true"
class="index-dialog-body" refresher-default-style="none" @refresherrefresh="scrolltolower">
:scroll-y="true"
upper-threshold="0"
refresher-enabled="true"
refresher-default-style="none"
@refresherrefresh="scrolltolower"
>
<view class="body-title"> <view class="body-title">
<!-- <uv-icon class="arrow-icon" name="arrow-left" @click="common.navigateBack()"/> --> <!-- <uv-icon class="arrow-icon" name="arrow-left" @click="common.navigateBack()"/> -->
AI问答 AI问答
<view class="top-desc">内容由AI生成</view> <view class="top-desc">内容由AI生成</view>
<view class="seek-setting"> <view class="seek-setting">
<image <image src="@/static/images/dialog/new-dialog.png" alt="" class="image-icon-new" @click="createNewDialog">
src="@/static/images/dialog/new-dialog.png" </image>
alt="" <image src="@/static/images/dialog/history.png" alt="" class="image-icon"
class="image-icon-new" @click="showMenuList = !showMenuList"></image>
@click="createNewDialog"
></image>
<image
src="@/static/images/dialog/history.png"
alt=""
class="image-icon"
@click="showMenuList = !showMenuList"
></image>
<view :class="['more-list', showMenuList ? 'show' : '']"> <view :class="['more-list', showMenuList ? 'show' : '']">
<view class="more-item" @click.stop="showHistory">历史</view> <view class="more-item" @click.stop="showHistory">历史</view>
<view class="more-item" @click.stop="toMessage">消息</view> <view class="more-item" @click.stop="toMessage">消息</view>
@@ -36,7 +22,7 @@
</view> </view>
</view> </view>
<view class="ai-info"> <view class="ai-info" v-show="talkingList.length === 0">
<!-- <image src="@/static/images/dialog/pet-3.png" alt="" class="image-pet-bg"></image> --> <!-- <image src="@/static/images/dialog/pet-3.png" alt="" class="image-pet-bg"></image> -->
<image src="@/static/images/dialog/pet-bg-base.png" alt="" class="image-pet-bg"></image> <image src="@/static/images/dialog/pet-bg-base.png" alt="" class="image-pet-bg"></image>
<image :src="luimgAddr" alt="" class="image-pet" mode="widthFix"></image> <image :src="luimgAddr" alt="" class="image-pet" mode="widthFix"></image>
@@ -46,7 +32,17 @@
<view class="info-btn">试试他的能力</view> <view class="info-btn">试试他的能力</view>
</view> </view>
</view> </view>
<view class="questions-view"> <view class="talking-list talking-list-qns" v-show="talkingList.length === 0">
<scroll-view class="talking-scroll-list" :scroll-y="true" :scroll-top="scrollTop" :show-scrollbar="false"
:scroll-with-animation="false">
<view class="question-item-box" v-show="talkingList.length === 0" v-for="item in questionList">
<view class="question-item" @click="sendText(item.hotContent)">
{{ item.hotContent }}
</view>
</view>
</scroll-view>
</view>
<!-- <view class="questions-view">
<scroll-view :scroll-x="true" :show-scrollbar="false"> <scroll-view :scroll-x="true" :show-scrollbar="false">
<view class="question-row"> <view class="question-row">
<view <view
@@ -67,24 +63,20 @@
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
</view> </view> -->
<view class="talking-list"> <view class="talking-list" v-show="talkingList.length > 0">
<scroll-view <scroll-view class="talking-scroll-list" :scroll-y="true" :scroll-top="scrollTop" :show-scrollbar="false"
class="talking-scroll-list" :scroll-with-animation="false">
:scroll-y="true" <TalkingItem v-for="(item, index) in talkingList" :talkingType="item.type" :talkingInfo="item"
:scroll-top="scrollTop" :isLast="index + 1 === talkingList.length" :isAnswering="!answerIsOver"
:show-scrollbar="false" :activeVoiceId="activeVoiceTalkingItemId" @handleEvents="talkItemEvents"></TalkingItem>
:scroll-with-animation="false"
> <view class="question-item-box mt-16" v-for="item in talkQnsList">
<TalkingItem <view class="question-item" @click="sendText(item.hotContent)">
v-for="(item, index) in talkingList" {{ item.hotContent }}
:talkingType="item.type" </view>
:talkingInfo="item" </view>
:isLast="index + 1 === talkingList.length"
:isAnswering="!answerIsOver"
:activeVoiceId="activeVoiceTalkingItemId"
@handleEvents="talkItemEvents"
></TalkingItem>
</scroll-view> </scroll-view>
</view> </view>
<view class="router-list"> <view class="router-list">
@@ -119,23 +111,16 @@
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
<TouchBtn <TouchBtn class="talk-btns" @uploadVoice="uploadRecordNow" @submitAnswer="submitAnswerNow"
class="talk-btns" @startRecord="startRecordCallback" :loadingText="sendLoadingText" :isLoading="!answerIsOver"
@uploadVoice="uploadRecordNow" :adjustPosition="true" :isDisabled="isHistory" />
@submitAnswer="submitAnswerNow"
@startRecord="startRecordCallback"
:loadingText="sendLoadingText"
:isLoading="!answerIsOver"
:adjustPosition="true"
:isDisabled="isHistory"
/>
<History ref="historyRef" @showDetail="showHistoryDetail"></History> <History ref="historyRef" @showDetail="showHistoryDetail"></History>
<PreviewVue ref="previewRef" /> <PreviewVue ref="previewRef" />
</scroll-view> </scroll-view>
</view> </view>
<badge ref="badgeRef"></badge> <badge ref="badgeRef"></badge>
<points ref="pointsRef"></points> <points ref="pointsRef"></points>
<!-- 反馈组件 --> <!-- 反馈组件 -->
<Feedback ref="feedbackRef" @feedbackAnswer="feedbackAnswer"></Feedback> <Feedback ref="feedbackRef" @feedbackAnswer="feedbackAnswer"></Feedback>
<!-- <file-preview ref="previewFileRef" :file-id="'603058d8-88e0-43d2-8242-3132b85bc91c'" v-model="showPreview" /> --> <!-- <file-preview ref="previewFileRef" :file-id="'603058d8-88e0-43d2-8242-3132b85bc91c'" v-model="showPreview" /> -->
@@ -144,19 +129,49 @@
</template> </template>
<script setup> <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 common from '@/common/common';
import { setupKeyboardHeightListener } from '@/common/common'; import {
setupKeyboardHeightListener
} from '@/common/common';
import TouchBtn from '@/pages/course/components/touchBtn.vue'; import TouchBtn from '@/pages/course/components/touchBtn.vue';
import TalkingItem from './components/talking-item.vue'; import TalkingItem from './components/talking-item.vue';
import PreviewVue from './components/preview.vue'; import PreviewVue from './components/preview.vue';
import { useSocketStore } from '@/store/socket.js'; import {
import { useStorageStore } from '@/store/storage.js'; useSocketStore
import { storeToRefs } from 'pinia'; } from '@/store/socket.js';
import { onLoad, onShow, onUnload, onHide, onBackPress } from '@dcloudio/uni-app'; import {
import { get_base_url, goto_login_fun } from '@/api/request'; useStorageStore
import { getUserInfo, getPhoneEnvBool } from '@/common/common'; } from '@/store/storage.js';
import { commonUploadVoiceFile } from '@/api/common.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 { import {
queryHotQuestionApi, queryHotQuestionApi,
insertTraAskFeedback, insertTraAskFeedback,
@@ -166,23 +181,31 @@
} from '@/api/dialog.js'; } from '@/api/dialog.js';
import Feedback from './components/feedback.vue'; import Feedback from './components/feedback.vue';
import History from './components/history.vue'; import History from './components/history.vue';
import badge from '@/components/points-and-badge/badge'; import badge from '@/components/points-and-badge/badge';
import points from '@/components/points-and-badge/points'; import points from '@/components/points-and-badge/points';
import usePointsAndBadge from '@/components/points-and-badge/usePointsAndBadge'; import usePointsAndBadge from '@/components/points-and-badge/usePointsAndBadge';
const { pointAndBadgesRun, badgeRef, pointsRef } = usePointsAndBadge(); const {
pointAndBadgesRun,
badgeRef,
pointsRef
} = usePointsAndBadge();
const { statusBarHeight } = uni.getWindowInfo(); const {
statusBarHeight
} = uni.getWindowInfo();
const pageTopPadding = computed(() => statusBarHeight + 'px'); const pageTopPadding = computed(() => statusBarHeight + 'px');
const socketStore = useSocketStore(); const socketStore = useSocketStore();
const { SocketObj } = storeToRefs(socketStore); const {
SocketObj
} = storeToRefs(socketStore);
const feedbackRef = ref(); const feedbackRef = ref();
const watermarkRef = ref(); const watermarkRef = ref();
const userInfo = ref(getUserInfo()); const userInfo = ref(getUserInfo());
const luimgAddr = computed(()=> unref(userInfo)?.mascotInfo?.imgAddr || '') const luimgAddr = computed(() => unref(userInfo)?.mascotInfo?.imgAddr || '')
const userParams = '/' + (unref(userInfo)?.loginName??'') const userParams = '/' + (unref(userInfo)?.loginName ?? '')
const questionList = ref([ const questionList = ref([
// '对公小程序开户流程?', // '对公小程序开户流程?',
// '厅堂服务经理2025年管理办法?', // '厅堂服务经理2025年管理办法?',
@@ -229,6 +252,7 @@
const showModelComfirm = ref(false); const showModelComfirm = ref(false);
const reconcatNum = ref(1); const reconcatNum = ref(1);
const askTime = ref(0) const askTime = ref(0)
const talkQnsList = ref([])
const initsocketTask = () => { const initsocketTask = () => {
isHistory.value = false; isHistory.value = false;
socketStore.creatSocket('/traask/asksocket/open?summary='); socketStore.creatSocket('/traask/asksocket/open?summary=');
@@ -262,7 +286,11 @@
}); });
}); });
unref(SocketObj).on('message', (res) => { 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'; let _id = new Date().getTime() + 'id';
if (rtnCode === '0000') { if (rtnCode === '0000') {
if (commond === 'ASK-OPEN') { if (commond === 'ASK-OPEN') {
@@ -329,7 +357,7 @@
if (commond === 'ASK-ANSWER') { if (commond === 'ASK-ANSWER') {
if (body.event === 'start') { if (body.event === 'start') {
console.log('开始回答!'); console.log('开始回答!');
if (askTime.value === 0){ if (askTime.value === 0) {
pointAndBadgesRun('06') pointAndBadgesRun('06')
askTime.value = 1 askTime.value = 1
} }
@@ -361,6 +389,7 @@
let _data = body.data; let _data = body.data;
talkingList.value[talkingList.value.length - 1].talkingFiles = _data.knowledgeList || []; talkingList.value[talkingList.value.length - 1].talkingFiles = _data.knowledgeList || [];
talkingList.value[talkingList.value.length - 1].talkingCrsList = _data.crsList || []; talkingList.value[talkingList.value.length - 1].talkingCrsList = _data.crsList || [];
talkQnsList.value = _data.qnsList || []//questionList.value.splice(0, 3);
} }
return; return;
} }
@@ -398,6 +427,9 @@
}, 3000); }, 3000);
}; };
const sendMessage = (data) => { const sendMessage = (data) => {
if (data.commond === 'ASK') {
talkQnsList.value = []
}
unref(SocketObj).send(data); unref(SocketObj).send(data);
}; };
watch( watch(
@@ -417,7 +449,12 @@
const isDownloading = ref(false) const isDownloading = ref(false)
const stopAnswerCallBack = ref(null); const stopAnswerCallBack = ref(null);
const talkItemEvents = ({ type, data, id, info = {} }) => { const talkItemEvents = ({
type,
data,
id,
info = {}
}) => {
switch (type) { switch (type) {
case 'reAnswer': case 'reAnswer':
console.log('重新提问回答'); console.log('重新提问回答');
@@ -492,7 +529,7 @@
}); });
break; break;
case 'preview': case 'preview':
common.navigateTo('/pages/index/preview?fileId=' + info.docId); common.navigateTo('/pages/index/preview?fileId=' + info.docId);
// if (getPhoneEnvBool('AND')) { // if (getPhoneEnvBool('AND')) {
// common.navigateTo('/pages/index/preview?fileId=' + info.docId); // common.navigateTo('/pages/index/preview?fileId=' + info.docId);
// } else { // } else {
@@ -530,8 +567,7 @@
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
console.log('开始下载:', fileUrl); console.log('开始下载:', fileUrl);
const dtask = plus.downloader.createDownload( const dtask = plus.downloader.createDownload(
fileUrl, fileUrl, {
{
filename: localFilePath filename: localFilePath
}, },
(d, status) => { (d, status) => {
@@ -676,28 +712,28 @@
scrollToBottomNow(); scrollToBottomNow();
commonUploadVoiceFile(voicePath, '/traask/traAskchat/voiceTrans', {}) commonUploadVoiceFile(voicePath, '/traask/traAskchat/voiceTrans', {})
.then((_res) => { .then((_res) => {
if (!!(_res.body.transContent || '').trim()) { if (!!(_res.body.transContent || '').trim()) {
askData.value = { askData.value = {
reqBatch: reqBatch.value, reqBatch: reqBatch.value,
intrctWay: '02', //01-文本;02-语音;03-图片 intrctWay: '02', //01-文本;02-语音;03-图片
intrctContent: _res.body.transContent, intrctContent: _res.body.transContent,
bucketKey: _res.body.fileId, bucketKey: _res.body.fileId,
ossFileAddr: _res.body.ossFileAddr, ossFileAddr: _res.body.ossFileAddr,
talkingVoice: voicePath, talkingVoice: voicePath,
voiceTime: voiceTime voiceTime: voiceTime
}; };
sendMessage({ sendMessage({
commond: 'ASK', commond: 'ASK',
body: askData.value body: askData.value
}); });
} else { } else {
talkingList.value.pop(); talkingList.value.pop();
uni.showToast({ uni.showToast({
title: '未识别到文字', title: '未识别到文字',
icon: 'none', icon: 'none',
duration: 1000 duration: 1000
}); });
} }
}) })
.catch((err) => { .catch((err) => {
talkingList.value.pop(); talkingList.value.pop();
@@ -726,7 +762,9 @@
commond: 'ASK', commond: 'ASK',
body: askData.value body: askData.value
}); });
setHeight({height: 0}) setHeight({
height: 0
})
}; };
const startRecordCallback = () => { const startRecordCallback = () => {
// 开始录音回调 // 开始录音回调
@@ -793,7 +831,7 @@
}; };
onLoad(() => { onLoad(() => {
//#ifdef APP-PLUS //#ifdef APP-PLUS
plus.screen.lockOrientation('portrait-primary') plus.screen.lockOrientation('portrait-primary')
// #endif // #endif
changeAppHeightBottom(); changeAppHeightBottom();
if (!common.isLogin()) { if (!common.isLogin()) {
@@ -824,9 +862,9 @@
const keyboardHeight = ref('0px'); const keyboardHeight = ref('0px');
const setHeight = (res) => { const setHeight = (res) => {
keyboardHeight.value = (res.height || 0) + 'px'; keyboardHeight.value = (res.height || 0) + 'px';
setTimeout(()=>{ setTimeout(() => {
console.log(totalBotHeight.value) console.log(totalBotHeight.value)
},1000) }, 1000)
}; };
const keyBoardIsHide = computed(() => { const keyBoardIsHide = computed(() => {
return parseInt(keyboardHeight.value) == 0; return parseInt(keyboardHeight.value) == 0;
@@ -837,7 +875,8 @@
// #ifdef APP-PLUS // #ifdef APP-PLUS
isIos = (plus.os.name == "iOS") isIos = (plus.os.name == "iOS")
// #endif // #endif
return isIos || keyBoardIsHide.value ? 0 + 'px' : parseInt(keyboardHeight.value) + parseInt(bottomHeight.value) + 'px'; return isIos || keyBoardIsHide.value ? 0 + 'px' : parseInt(keyboardHeight.value) + parseInt(bottomHeight.value) +
'px';
}); });
const changeAppHeightBottom = (height) => { const changeAppHeightBottom = (height) => {
//#ifdef APP-PLUS //#ifdef APP-PLUS
@@ -846,15 +885,15 @@
// 计算安全区域底部高度 // 计算安全区域底部高度
bottomHeight.value = systemInfo.screenHeight - systemInfo.safeArea.bottom + 'px'; bottomHeight.value = systemInfo.screenHeight - systemInfo.safeArea.bottom + 'px';
console.log(systemInfo) console.log(systemInfo)
console.log(systemInfo.screenHeight , systemInfo.safeArea.bottom ) console.log(systemInfo.screenHeight, systemInfo.safeArea.bottom)
// #endif // #endif
}; };
const deleteFolder = () => { const deleteFolder = () => {
//#ifdef APP-PLUS //#ifdef APP-PLUS
plus.io.resolveLocalFileSystemURL('_doc/pdf_view', function (entry) { plus.io.resolveLocalFileSystemURL('_doc/pdf_view', function(entry) {
console.log('entry', entry); console.log('entry', entry);
entry.removeRecursively(function (res) { entry.removeRecursively(function(res) {
console.log('删除成功'); console.log('删除成功');
}); });
}); });
@@ -871,7 +910,7 @@
nextTick(() => { nextTick(() => {
watermarkRef.value?.updateWatermarkText(); watermarkRef.value?.updateWatermarkText();
}); });
}); });
// #endif // #endif
onUnload(() => { onUnload(() => {
@@ -932,7 +971,8 @@
font-weight: 500; font-weight: 500;
color: #000; color: #000;
position: relative; position: relative;
.top-desc{
.top-desc {
position: absolute; position: absolute;
bottom: -10rpx; bottom: -10rpx;
font-size: 18rpx; font-size: 18rpx;
@@ -941,7 +981,7 @@
transform: translateX(-50%); transform: translateX(-50%);
} }
.top-desc{ .top-desc {
position: absolute; position: absolute;
bottom: -10rpx; bottom: -10rpx;
font-size: 18rpx; font-size: 18rpx;
@@ -949,6 +989,7 @@
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
} }
// margin-bottom: 23rpx; // margin-bottom: 23rpx;
.arrow-icon { .arrow-icon {
position: absolute; position: absolute;
@@ -971,6 +1012,7 @@
line-height: 32rpx; line-height: 32rpx;
text-align: right; text-align: right;
padding-right: 48rpx; padding-right: 48rpx;
.more-list { .more-list {
position: absolute; position: absolute;
top: 100%; top: 100%;
@@ -982,9 +1024,11 @@
padding: 16rpx 0; padding: 16rpx 0;
display: none; display: none;
z-index: 21; z-index: 21;
&.show { &.show {
display: block; display: block;
} }
.more-item { .more-item {
line-height: 60rpx; line-height: 60rpx;
font-size: 29rpx; font-size: 29rpx;
@@ -993,6 +1037,7 @@
z-index: 22; z-index: 22;
} }
} }
.image-icon { .image-icon {
width: 30rpx; width: 30rpx;
height: 32rpx; height: 32rpx;
@@ -1145,13 +1190,50 @@
} }
.talking-list { .talking-list {
height: calc(100% - 772rpx); height: calc(100% - 328rpx);
min-height: 300rpx; min-height: 300rpx;
padding: 12rpx 24rpx; padding: 12rpx 24rpx;
box-sizing: border-box; box-sizing: border-box;
min-height: 300rpx; min-height: 300rpx;
&.talking-list-qns {
height: calc(100% - 600rpx);
}
.talking-scroll-list { .talking-scroll-list {
height: 100%; height: 100%;
.question-item-box {
float: left;
width: 100%;
&.mt-16 {
margin-top: 16rpx;
.question-item {
margin-bottom: 0rpx;
}
}
.question-item {
// white-space: nowrap;
float: left;
width: auto;
min-height: 66rpx;
line-height: 56rpx;
background-color: #fff;
border: 2rpx solid #e0dede;
padding: 5rpx 16rpx;
border-radius: 11rpx;
margin-bottom: 16rpx;
// display: inline-block;
font-size: 26rpx;
&:last-child {
margin-right: 0;
}
}
}
} }
} }
} }
@@ -1165,4 +1247,4 @@
// height: 100%; // height: 100%;
// } // }
// } // }
</style> </style>