|
@@ -275,46 +275,6 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <!-- 历史回答 -->
|
|
|
- <div
|
|
|
- v-show="askType === 'zcfg'"
|
|
|
- class="search-result result-history"
|
|
|
- style="overflow-y: hidden; height: auto"
|
|
|
- v-if="questHistories.length > 0"
|
|
|
- id="messageContainer"
|
|
|
- >
|
|
|
- <template v-for="(qh, i) in [...questHistories].reverse()" :key="`qh-${i}`">
|
|
|
- <div class="top">
|
|
|
- <div class="title">
|
|
|
- <div class="icon"></div>
|
|
|
- <div class="question" style="cursor: pointer">{{ qh.question }}</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="result-panel">
|
|
|
- <div class="result">
|
|
|
- <div class="tabs">
|
|
|
- <div :class="`tab tab-active`">
|
|
|
- <div class="title">回答</div>
|
|
|
- <div class="bottom"></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="result-view">
|
|
|
- <div class="q-r">
|
|
|
- <vue-markdown-it
|
|
|
- :source="qh.msg"
|
|
|
- :toc="true"
|
|
|
- :options="{
|
|
|
- html: true,
|
|
|
- linkify: true
|
|
|
- }"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
</div>
|
|
|
<a-affix v-if="showDoc" style="width: 52%; font-size: 16px" :offset-top="210">
|
|
|
<div
|
|
@@ -426,8 +386,13 @@
|
|
|
</a-dropdown>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="send_btn" @click="onSendHandle">
|
|
|
- <i class="iconfont icon-a-lujing9250"></i>
|
|
|
+ <div class="send_btn">
|
|
|
+ <div v-if="historys.length > 0 && historys[historyIndex].currentResponse.loading" @click="onSendHandle(false)">
|
|
|
+ <i class="stop"></i>
|
|
|
+ </div>
|
|
|
+ <div v-else @click="onSendHandle">
|
|
|
+ <i class="iconfont icon-a-lujing9250"></i>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -445,16 +410,16 @@ import {
|
|
|
import { fetchEventSource } from '@microsoft/fetch-event-source';
|
|
|
import PDFViewer from '@/components/pdf/PdfCanvas.vue';
|
|
|
import WordViewer from '@/components/pdf/WordViewer.vue';
|
|
|
-import AiTextarea from '@/components/TextArea/AiTextarea.vue';
|
|
|
import { VueMarkdownIt } from '@f3ve/vue-markdown-it';
|
|
|
import TxtViewer from '@/components/pdf/TxtViewer.vue';
|
|
|
import { message } from 'ant-design-vue';
|
|
|
-import { h, ref, reactive, defineProps, watch } from 'vue';
|
|
|
-import CommonAPI from '@/api/common';
|
|
|
+import { h, ref, reactive, watch } from 'vue';
|
|
|
import ManagerAPI from '@/api/manager';
|
|
|
import PubsubService from '@/utils/PubsubService';
|
|
|
import { useUserStore } from '@/stores';
|
|
|
|
|
|
+let ctr = null;
|
|
|
+
|
|
|
const visibleMap = reactive({
|
|
|
history: true,
|
|
|
tool: true
|
|
@@ -482,19 +447,24 @@ const startNewSessionHandle = () => {
|
|
|
const onKeydownHandle = (e) => {
|
|
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
|
e.preventDefault();
|
|
|
+ if (historys.value.length > 0 && historys.value[historyIndex].currentResponse.loading) {
|
|
|
+ message.error('回答输出中,请稍后操作或点击停止回答');
|
|
|
+ return;
|
|
|
+ }
|
|
|
onSendHandle();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-const onSendHandle = () => {
|
|
|
- if (historys.value.length > 0 && historys.value[historyIndex].currentResponse.loading) {
|
|
|
- message.error('回答输出中,请稍后操作');
|
|
|
- return;
|
|
|
- }
|
|
|
+const onSendHandle = (status = true) => {
|
|
|
if (!cQuestion.value) {
|
|
|
message.error('请输入问题');
|
|
|
return;
|
|
|
}
|
|
|
+ if (!status) {
|
|
|
+ historys.value[historyIndex].currentResponse.loading = false;
|
|
|
+ stopAI();
|
|
|
+ return;
|
|
|
+ }
|
|
|
historyIndex++;
|
|
|
historys.value.push({
|
|
|
question: cQuestion.value,
|
|
@@ -518,34 +488,20 @@ const toToolPage = (path) => {
|
|
|
}
|
|
|
|
|
|
const aiLoading = ref(false);
|
|
|
-const router = useRouter();
|
|
|
const indicator = h(LoadingOutlined, {
|
|
|
style: {
|
|
|
fontSize: '24px'
|
|
|
},
|
|
|
spin: true
|
|
|
});
|
|
|
-const props = defineProps({
|
|
|
- searchType: '',
|
|
|
- askType: {
|
|
|
- type: String,
|
|
|
- default: 'zcfg'
|
|
|
- }
|
|
|
-});
|
|
|
|
|
|
const modelType = ref('1')
|
|
|
const answerType = ref('0');
|
|
|
-const scope = ref('net');
|
|
|
-
|
|
|
-watch(props.searchType, (val) => {
|
|
|
- activeTab.value = val;
|
|
|
-});
|
|
|
|
|
|
const question = ref('国有土地的使用方式有哪些?');
|
|
|
const statusText = ref('检索中');
|
|
|
const activeIndex = ref(0);
|
|
|
const activeTab = ref('knowledge');
|
|
|
-let ctr = null;
|
|
|
|
|
|
const evaluate = ref(null);
|
|
|
|
|
@@ -562,7 +518,6 @@ const times = ref(0);
|
|
|
const timers = ref([]);
|
|
|
let streamMockInterval = null;
|
|
|
const streamToAnswer = () => {
|
|
|
- console.log('streamToAnswer');
|
|
|
historys.value[historyIndex].currentResponse.index = 0;
|
|
|
streamMockInterval = setInterval(() => {
|
|
|
const { originAnswer = '', msg, streamMsg = '', id, index = 0 } = historys.value[historyIndex].currentResponse;
|
|
@@ -645,7 +600,6 @@ const ask = async (q, isFllow) => {
|
|
|
open.value = false;
|
|
|
showDoc.value = false;
|
|
|
askType.value = 'zcfg';
|
|
|
- // activeTab.value = 'knowledge';
|
|
|
quest(isFllow);
|
|
|
};
|
|
|
|
|
@@ -793,11 +747,10 @@ const quest = async (isFllow) => {
|
|
|
|
|
|
activeTab.value === 'net' ? handleNetResponse(msg, id) : handleKnowledgeResponse(msg, id);
|
|
|
},
|
|
|
- onclose() {
|
|
|
+ onclose () {
|
|
|
if (scb !== null) {
|
|
|
clearInterval(scb);
|
|
|
scb = null;
|
|
|
-
|
|
|
collectQuestion();
|
|
|
}
|
|
|
|
|
@@ -854,9 +807,6 @@ const handleKnowledgeResponse = (msg, id) => {
|
|
|
let num = getNum(historys.value[historyIndex].currentResponse.msg);
|
|
|
while (num) {
|
|
|
const docsNum = historys.value[historyIndex].currentResponse.docs.length;
|
|
|
- if (docsNum && num > docsNum + 1) {
|
|
|
- }
|
|
|
-
|
|
|
historys.value[historyIndex].currentResponse.msg = historys.value[historyIndex].currentResponse.msg.replace(
|
|
|
`[[${num}]]`,
|
|
|
`<span onclick="window.openDocByIndex(${num}, ${id})" class="poi" style=" cursor: pointer; display: inline-block; width: 20px; height: 20px; font-size: 12px; line-height: 20px; text-align: center; margin: 0 5px; border-radius: 10px;background: #d0d5dd; width: 20px;
|
|
@@ -883,9 +833,6 @@ const handleKnowledgeResponse = (msg, id) => {
|
|
|
let num = getNum(historys.value[historyIndex].currentResponse.msg);
|
|
|
while (num) {
|
|
|
const docsNum = historys.value[historyIndex].currentResponse.docs.length;
|
|
|
- if (docsNum && num > docsNum + 1) {
|
|
|
- }
|
|
|
-
|
|
|
historys.value[historyIndex].currentResponse.msg = historys.value[historyIndex].currentResponse.msg.replace(
|
|
|
`[[${num}]]`,
|
|
|
`<span onclick="window.openDocByIndex(${num}, ${id})" class="poi" style=" cursor: pointer; display: inline-block; width: 20px; height: 20px; font-size: 12px; line-height: 20px; text-align: center; margin: 0 5px; border-radius: 10px;background: #d0d5dd; width: 20px;
|
|
@@ -1299,23 +1246,6 @@ const openRecommendedQuestion = (q) => {
|
|
|
);
|
|
|
}
|
|
|
};
|
|
|
-onMounted(() => {
|
|
|
- const { query } = router.currentRoute.value;
|
|
|
- if (query.q) {
|
|
|
- answerType.value = query.type || '0';
|
|
|
- scope.value = query.scope || 'net';
|
|
|
- var ds = '0';
|
|
|
- if (!useUserStore().isLogin) {
|
|
|
- ds = query.ds;
|
|
|
- } else {
|
|
|
- ds = useUserStore().user.user.enableDeepseek
|
|
|
- ? useUserStore().user.user.enableDeepseek + ''
|
|
|
- : query.ds;
|
|
|
- }
|
|
|
- activeTab.value = scope.value;
|
|
|
- }
|
|
|
-
|
|
|
-});
|
|
|
|
|
|
defineExpose({ changeActiveTab, stopAI });
|
|
|
|
|
@@ -1497,16 +1427,27 @@ defineExpose({ changeActiveTab, stopAI });
|
|
|
>.send_btn {
|
|
|
background: linear-gradient( 124deg, #505DFF 0%, #418CFF 100%);
|
|
|
border-radius: 5px;
|
|
|
- width: 40px;
|
|
|
- height: 40px;
|
|
|
- line-height: 40px;
|
|
|
- text-align: center;
|
|
|
- color: #fff;
|
|
|
cursor: pointer;
|
|
|
- >i {
|
|
|
- font-size: 20px;
|
|
|
+ >div {
|
|
|
+ width: 40px;
|
|
|
+ height: 40px;
|
|
|
+ text-align: center;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ >i {
|
|
|
+ font-size: 20px;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ >.stop {
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ border-radius: 2px;
|
|
|
+ display: block;
|
|
|
+ background: rgba(255,255,255,.9);
|
|
|
+ margin: auto;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
}
|