|
@@ -22,7 +22,17 @@
|
|
|
<li :key="index" v-if="session['datas'].length > 0">
|
|
|
<span class="title">{{session['title']}}</span>
|
|
|
<ul>
|
|
|
- <li v-for="(item, cindex) in session['datas']" :key="cindex" @click="switchSession(item)">{{item['tittle']}}</li>
|
|
|
+ <li
|
|
|
+ v-for="(item, cindex) in session['datas']"
|
|
|
+ :key="cindex"
|
|
|
+ :class="{'active': item['id'] === cSessionId}"
|
|
|
+ @mouseenter="sessionDelId = item['id']"
|
|
|
+ @mouseleave="sessionDelId = ''">
|
|
|
+ <span @click="switchSession(item)">{{item['tittle']}}</span>
|
|
|
+ <span v-if="sessionDelId === item['id']" @click="onSessionDeleteHandle(item['id'])">
|
|
|
+ <DeleteOutlined />
|
|
|
+ </span>
|
|
|
+ </li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</template>
|
|
@@ -364,9 +374,11 @@
|
|
|
<script setup>
|
|
|
import {
|
|
|
LoadingOutlined,
|
|
|
+ DeleteOutlined,
|
|
|
UpOutlined,
|
|
|
DownOutlined
|
|
|
} from "@ant-design/icons-vue";
|
|
|
+import { Modal } from 'ant-design-vue';
|
|
|
import dayjs from 'dayjs';
|
|
|
import { fetchEventSource } from '@microsoft/fetch-event-source';
|
|
|
import PDFViewer from '@/components/pdf/PdfCanvas.vue';
|
|
@@ -400,12 +412,15 @@ const historys = ref([])
|
|
|
let historyIndex = -1;
|
|
|
const cQuestion = ref('')
|
|
|
|
|
|
+const cSessionId = ref('')
|
|
|
+const sessionDelId = ref('')
|
|
|
const isSessionNew = ref(true)
|
|
|
const startNewSessionHandle = () => {
|
|
|
cQuestion.value = ''
|
|
|
historys.value = []
|
|
|
historyIndex = -1
|
|
|
isSessionNew.value = true
|
|
|
+ cSessionId.value = ''
|
|
|
}
|
|
|
|
|
|
const onKeydownHandle = (e) => {
|
|
@@ -441,6 +456,7 @@ const onSendHandle = (status = true) => {
|
|
|
streamMock: false,
|
|
|
msg: '',
|
|
|
originAnswer: '',
|
|
|
+ oDocs: '',
|
|
|
docs: []
|
|
|
}
|
|
|
})
|
|
@@ -652,6 +668,7 @@ const quest = async (isFllow) => {
|
|
|
originAnswer: '',
|
|
|
streamMock: false,
|
|
|
streamMsg: '',
|
|
|
+ oDocs: '',
|
|
|
docs: []
|
|
|
};
|
|
|
activeIndex.value = 0;
|
|
@@ -775,31 +792,31 @@ const handleKnowledgeResponse = (msg, id) => {
|
|
|
});
|
|
|
timers.value = [];
|
|
|
}
|
|
|
- endTime.value = Date.now();
|
|
|
- var time = ((endTime.value - startTime.value) / 1000).toFixed(0);
|
|
|
- historys.value[historyIndex].currentResponse.hintTxt = `已深度思考(用时 ${time} 秒)`;
|
|
|
- historys.value[historyIndex].currentResponse.time = time;
|
|
|
- historys.value[historyIndex].currentResponse.loading = false;
|
|
|
- aiLoading.value=true;
|
|
|
- historys.value[historyIndex].currentResponse.originAnswer = rData.choices[0]?.delta?.content.replaceAll(
|
|
|
- '\n',
|
|
|
- ` \n`
|
|
|
+ endTime.value = Date.now();
|
|
|
+ var time = ((endTime.value - startTime.value) / 1000).toFixed(0);
|
|
|
+ historys.value[historyIndex].currentResponse.hintTxt = `已深度思考(用时 ${time} 秒)`;
|
|
|
+ historys.value[historyIndex].currentResponse.time = time;
|
|
|
+ historys.value[historyIndex].currentResponse.loading = false;
|
|
|
+ aiLoading.value=true;
|
|
|
+ historys.value[historyIndex].currentResponse.originAnswer = rData.choices[0]?.delta?.content.replaceAll(
|
|
|
+ '\n',
|
|
|
+ ` \n`
|
|
|
+ );
|
|
|
+ historys.value[historyIndex].currentResponse.msg = rData.choices[0]?.delta?.content.replaceAll('\n', ` \n`);
|
|
|
+ let num = getNum(historys.value[historyIndex].currentResponse.msg);
|
|
|
+ while (num) {
|
|
|
+ const docsNum = historys.value[historyIndex].currentResponse.docs.length;
|
|
|
+ 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;
|
|
|
+ height: 20px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 4px 4px 4px 4px;
|
|
|
+ border: 1px solid #BACAE3;">${num}</span>`
|
|
|
);
|
|
|
- historys.value[historyIndex].currentResponse.msg = rData.choices[0]?.delta?.content.replaceAll('\n', ` \n`);
|
|
|
- let num = getNum(historys.value[historyIndex].currentResponse.msg);
|
|
|
- while (num) {
|
|
|
- const docsNum = historys.value[historyIndex].currentResponse.docs.length;
|
|
|
- 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;
|
|
|
- height: 20px;
|
|
|
- background: #FFFFFF;
|
|
|
- border-radius: 4px 4px 4px 4px;
|
|
|
- border: 1px solid #BACAE3;">${num}</span>`
|
|
|
- );
|
|
|
|
|
|
- num = getNum(historys.value[historyIndex].currentResponse.msg);
|
|
|
- }
|
|
|
+ num = getNum(historys.value[historyIndex].currentResponse.msg);
|
|
|
+ }
|
|
|
} else {
|
|
|
|
|
|
aiLoading.value = false;
|
|
@@ -834,6 +851,7 @@ const handleKnowledgeResponse = (msg, id) => {
|
|
|
}
|
|
|
|
|
|
if (!historys.value[historyIndex].currentResponse.docs.length) {
|
|
|
+ historys.value[historyIndex].currentResponse.oDocs = JSON.stringify(rData.docs)
|
|
|
if (rData.docs && rData.docs.length) {
|
|
|
handleDocs(rData.docs);
|
|
|
}
|
|
@@ -1033,6 +1051,11 @@ const getNum = (str) => {
|
|
|
return null;
|
|
|
}
|
|
|
};
|
|
|
+const getNumAll = (str) => {
|
|
|
+ return Array.from(str.matchAll(/\[\[(\d+)\]\]/g), match => {
|
|
|
+ return parseInt(match[1])
|
|
|
+ });
|
|
|
+}
|
|
|
|
|
|
const sessionId = ref('');
|
|
|
const sessionCreate = () => {
|
|
@@ -1046,6 +1069,20 @@ const sessionCreate = () => {
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
+const sessionDelete = (id) => {
|
|
|
+ const sendData = {
|
|
|
+ id
|
|
|
+ }
|
|
|
+ ManagerAPI.delete(sendData).then((res) => {
|
|
|
+ if (res.data) {
|
|
|
+ initSessionLists();
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+const getSessionList = async (times) => {
|
|
|
+ const res = await ManagerAPI.list(userStore.user.syUser.Id, times);
|
|
|
+ return res.data
|
|
|
+}
|
|
|
const sessionLists = reactive([
|
|
|
{
|
|
|
title: '今天',
|
|
@@ -1072,13 +1109,12 @@ const sessionLists = reactive([
|
|
|
datas: []
|
|
|
}
|
|
|
])
|
|
|
-const sessionList = async (times) => {
|
|
|
- const res = await ManagerAPI.list(userStore.user.syUser.Id, times);
|
|
|
- return res.data
|
|
|
+const initSessionLists = () => {
|
|
|
+ sessionLists.forEach(async (session) => {
|
|
|
+ session['datas'] = await getSessionList(session['times'])
|
|
|
+ })
|
|
|
}
|
|
|
-sessionLists.forEach(async (session) => {
|
|
|
- session['datas'] = await sessionList(session['times'])
|
|
|
-})
|
|
|
+initSessionLists();
|
|
|
const getQuestionList = async (chatId) => {
|
|
|
const res = await ManagerAPI.getQuestionList({
|
|
|
chatId
|
|
@@ -1086,30 +1122,59 @@ const getQuestionList = async (chatId) => {
|
|
|
return res.data
|
|
|
}
|
|
|
const switchSession = async (item) => {
|
|
|
+ cSessionId.value = sessionId.value = item['id']
|
|
|
+ isSessionNew.value = false;
|
|
|
const results = await getQuestionList(item['id'])
|
|
|
historys.value = []
|
|
|
results.forEach((item) => {
|
|
|
+ let nums = getNumAll(item['answer']);
|
|
|
+ let msg = item['answer'];
|
|
|
+ const id = questHistories.value.length;
|
|
|
+ nums.forEach(num => {
|
|
|
+ msg = 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;
|
|
|
+ height: 20px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 4px 4px 4px 4px;
|
|
|
+ border: 1px solid #BACAE3;">${num}</span>`
|
|
|
+ )
|
|
|
+ })
|
|
|
+ const docs = JSON.parse(item['answerSources']) || []
|
|
|
historys.value.push({
|
|
|
question: item['question'],
|
|
|
dsChecked: true,
|
|
|
sourceVisible: false,
|
|
|
currentResponse: {
|
|
|
+ id,
|
|
|
loading: false,
|
|
|
hintTxt: `已深度思考(用时 ${item['thinkTime']} 秒)`,
|
|
|
- msg: item['answer'],
|
|
|
- docs: item['answerSources'] || []
|
|
|
+ msg: msg,
|
|
|
+ docs: docs
|
|
|
}
|
|
|
})
|
|
|
+ activeIndex.value = 5
|
|
|
historyIndex = results.length - 1;
|
|
|
+ handleDocs(docs)
|
|
|
})
|
|
|
}
|
|
|
+const onSessionDeleteHandle = (id) => {
|
|
|
+ Modal.confirm({
|
|
|
+ content: () => '确定删除该条记录,删除将无法恢复!',
|
|
|
+ onOk () {
|
|
|
+ sessionDelete(id);
|
|
|
+ },
|
|
|
+ cancelText: '取消',
|
|
|
+ okText: '确定',
|
|
|
+ });
|
|
|
+}
|
|
|
// 埋点采集数据
|
|
|
const collectQuestion = () => {
|
|
|
- const { question, originAnswer, docs, time, keywords = [] } = historys.value[historyIndex].currentResponse;
|
|
|
+ const { question, originAnswer, oDocs, time, keywords = [] } = historys.value[historyIndex].currentResponse;
|
|
|
const param = {
|
|
|
question,
|
|
|
answer: originAnswer,
|
|
|
- answerSources: docs,
|
|
|
+ answerSources: oDocs,
|
|
|
thinkTime: time,
|
|
|
questionType: askType.value === 'zcfg' ? '政策法规' : '土地市场',
|
|
|
keywords: Array.isArray(keywords) ? keywords.join(',') : keywords,
|
|
@@ -1125,7 +1190,9 @@ const collectQuestion = () => {
|
|
|
ManagerAPI.collect(param).then((res) => {
|
|
|
if (res.data) {
|
|
|
// 记录日志,用来反馈
|
|
|
- historys.value[historyIndex].currentResponse.logId = res.data;
|
|
|
+ sessionLists.forEach(async (session) => {
|
|
|
+ session['datas'] = await getSessionList(session['times'])
|
|
|
+ })
|
|
|
}
|
|
|
});
|
|
|
};
|