feat: disable change & create chat during chat thinking

This commit is contained in:
ulleo
2025-07-21 18:46:14 +08:00
parent e6148d1e2f
commit 6e849121bc
8 changed files with 153 additions and 53 deletions
+8 -7
View File
@@ -10,7 +10,8 @@ export const questionApi = {
}}).catch(e => reject(e))
}), */
// add: (data: any) => request.post('/chat/question', data),
add: (data: any) => request.fetchStream('/chat/question', data),
add: (data: any, controller?: AbortController) =>
request.fetchStream('/chat/question', data, controller),
edit: (data: any) => request.put('/chat/question', data),
delete: (id: number) => request.delete(`/chat/question/${id}`),
query: (id: number) => request.get(`/chat/question/${id}`),
@@ -312,13 +313,13 @@ export const chatApi = {
deleteChat: (id: number | undefined): Promise<string> => {
return request.get(`/chat/delete/${id}`)
},
analysis: (record_id: number | undefined) => {
return request.fetchStream(`/chat/record/${record_id}/analysis`, {})
analysis: (record_id: number | undefined, controller?: AbortController) => {
return request.fetchStream(`/chat/record/${record_id}/analysis`, {}, controller)
},
predict: (record_id: number | undefined) => {
return request.fetchStream(`/chat/record/${record_id}/predict`, {})
predict: (record_id: number | undefined, controller?: AbortController) => {
return request.fetchStream(`/chat/record/${record_id}/predict`, {}, controller)
},
recommendQuestions: (record_id: number | undefined) => {
return request.fetchStream(`/chat/recommend_questions/${record_id}`, {})
recommendQuestions: (record_id: number | undefined, controller?: AbortController) => {
return request.fetchStream(`/chat/recommend_questions/${record_id}`, {}, controller)
},
}
+2 -1
View File
@@ -228,7 +228,7 @@ class HttpService {
return this.request({ ...config, method: 'POST', url, data })
}
public fetchStream(url: string, data?: any): Promise<any> {
public fetchStream(url: string, data?: any, controller?: AbortController): Promise<any> {
const token = wsCache.get('user.token')
const heads: any = {
'Content-Type': 'application/json',
@@ -250,6 +250,7 @@ class HttpService {
method: 'POST',
headers: heads,
body: JSON.stringify(data),
signal: controller?.signal,
})
}
+32 -25
View File
@@ -2,7 +2,7 @@
import { Search } from '@element-plus/icons-vue'
import ChatList from '@/views/chat/ChatList.vue'
import { useI18n } from 'vue-i18n'
import { computed, ref } from 'vue'
import { computed, nextTick, ref } from 'vue'
import { Chat, chatApi, ChatInfo } from '@/api/chat.ts'
import { filter, includes } from 'lodash-es'
import ChatCreator from '@/views/chat/ChatCreator.vue'
@@ -110,37 +110,44 @@ function goEmpty() {
}
const createNewChat = async () => {
goEmpty()
if (isAssistant.value) {
const assistantChat = await assistantStore.setChat()
if (assistantChat) {
onChatCreated(assistantChat)
if (!_loading.value) {
goEmpty()
if (isAssistant.value) {
const assistantChat = await assistantStore.setChat()
if (assistantChat) {
onChatCreated(assistantChat)
}
return
} else {
chatCreatorRef.value?.showDs()
}
return
} else {
chatCreatorRef.value?.showDs()
}
}
function onClickHistory(chat: Chat) {
_currentChat.value = new ChatInfo(chat)
if (chat !== undefined && chat.id !== undefined && !_loading.value) {
_currentChatId.value = chat.id
_loading.value = true
chatApi
.get(chat.id)
.then((res) => {
const info = chatApi.toChatInfo(res)
if (info) {
_currentChat.value = info
goEmpty()
nextTick(() => {
if (chat !== undefined && chat.id !== undefined) {
_currentChat.value = new ChatInfo(chat)
_currentChatId.value = chat.id
_loading.value = true
chatApi
.get(chat.id)
.then((res) => {
const info = chatApi.toChatInfo(res)
if (info) {
_currentChat.value = info
// scrollToBottom()
emits('onClickHistory', info)
}
})
.finally(() => {
_loading.value = false
})
// scrollToBottom()
emits('onClickHistory', info)
}
})
.finally(() => {
_loading.value = false
})
}
})
}
}
+16 -1
View File
@@ -50,14 +50,24 @@ function clickQuestion(question: string): void {
emits('clickQuestion', question)
}
const stopFlag = ref(false)
async function getRecommendQuestions() {
stopFlag.value = false
loading.value = true
try {
const controller: AbortController = new AbortController()
const response = await chatApi.recommendQuestions(props.recordId)
const reader = response.body.getReader()
const decoder = new TextDecoder()
while (true) {
if (stopFlag.value) {
controller.abort()
loading.value = false
break
}
const { done, value } = await reader.read()
if (done) {
break
@@ -125,7 +135,12 @@ async function getRecommendQuestions() {
}
}
defineExpose({ getRecommendQuestions, id: () => props.recordId })
function stop() {
stopFlag.value = true
loading.value = false
}
defineExpose({ getRecommendQuestions, id: () => props.recordId, stop })
</script>
<template>
@@ -1,7 +1,7 @@
<script setup lang="ts">
import BaseAnswer from './BaseAnswer.vue'
import { chatApi, ChatInfo, type ChatMessage, ChatRecord } from '@/api/chat.ts'
import { computed, nextTick } from 'vue'
import { computed, nextTick, ref } from 'vue'
import MdComponent from '@/views/chat/component/MdComponent.vue'
const props = withDefaults(
defineProps<{
@@ -75,7 +75,9 @@ const _loading = computed({
},
})
const stopFlag = ref(false)
const sendMessage = async () => {
stopFlag.value = false
_loading.value = true
if (index.value < 0) {
@@ -92,7 +94,8 @@ const sendMessage = async () => {
if (error) return
try {
const response = await chatApi.analysis(currentRecord.analysis_record_id)
const controller: AbortController = new AbortController()
const response = await chatApi.analysis(currentRecord.analysis_record_id, controller)
const reader = response.body.getReader()
const decoder = new TextDecoder()
@@ -100,6 +103,12 @@ const sendMessage = async () => {
let analysis_answer_thinking = ''
while (true) {
if (stopFlag.value) {
controller.abort()
_loading.value = false
break
}
const { done, value } = await reader.read()
if (done) {
_loading.value = false
@@ -180,8 +189,11 @@ const sendMessage = async () => {
_loading.value = false
}
}
defineExpose({ sendMessage, index: index.value, chatList: _chatList })
function stop() {
stopFlag.value = true
_loading.value = false
}
defineExpose({ sendMessage, index: () => index.value, chatList: () => _chatList.value, stop })
</script>
<template>
+16 -3
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import BaseAnswer from './BaseAnswer.vue'
import { Chat, chatApi, ChatInfo, type ChatMessage, ChatRecord, questionApi } from '@/api/chat.ts'
import { computed, nextTick } from 'vue'
import { computed, nextTick, ref } from 'vue'
const props = withDefaults(
defineProps<{
chatList?: Array<ChatInfo>
@@ -75,7 +75,10 @@ const _loading = computed({
},
})
const stopFlag = ref(false)
const sendMessage = async () => {
stopFlag.value = false
_loading.value = true
if (index.value < 0) {
@@ -92,9 +95,11 @@ const sendMessage = async () => {
if (error) return
try {
const controller: AbortController = new AbortController()
const response = await questionApi.add({
question: currentRecord.question,
chat_id: _currentChatId.value,
controller,
})
const reader = response.body.getReader()
const decoder = new TextDecoder()
@@ -103,6 +108,11 @@ const sendMessage = async () => {
let chart_answer = ''
while (true) {
if (stopFlag.value) {
controller.abort()
break
}
const { done, value } = await reader.read()
if (done) {
_loading.value = false
@@ -216,8 +226,11 @@ function getChatData(recordId?: number) {
})
})
}
defineExpose({ sendMessage, index: index.value })
function stop() {
stopFlag.value = true
_loading.value = false
}
defineExpose({ sendMessage, index: () => index.value, stop })
</script>
<template>
@@ -1,7 +1,7 @@
<script setup lang="ts">
import BaseAnswer from './BaseAnswer.vue'
import { chatApi, ChatInfo, type ChatMessage, ChatRecord } from '@/api/chat.ts'
import { computed, nextTick } from 'vue'
import { computed, nextTick, ref } from 'vue'
import MdComponent from '@/views/chat/component/MdComponent.vue'
const props = withDefaults(
defineProps<{
@@ -75,7 +75,9 @@ const _loading = computed({
},
})
const stopFlag = ref(false)
const sendMessage = async () => {
stopFlag.value = false
_loading.value = true
if (index.value < 0) {
@@ -92,6 +94,7 @@ const sendMessage = async () => {
if (error) return
try {
const controller: AbortController = new AbortController()
const response = await chatApi.predict(currentRecord.predict_record_id)
const reader = response.body.getReader()
const decoder = new TextDecoder()
@@ -100,6 +103,12 @@ const sendMessage = async () => {
let predict_content = ''
while (true) {
if (stopFlag.value) {
controller.abort()
_loading.value = false
break
}
const { done, value } = await reader.read()
if (done) {
_loading.value = false
@@ -186,8 +195,11 @@ const sendMessage = async () => {
_loading.value = false
}
}
defineExpose({ sendMessage, index: index.value, chatList: _chatList })
function stop() {
stopFlag.value = true
_loading.value = false
}
defineExpose({ sendMessage, index: () => index.value, chatList: () => _chatList, stop })
</script>
<template>
+48 -9
View File
@@ -379,12 +379,12 @@ const computedMessages = computed<Array<ChatMessage>>(() => {
})
}
console.log(messages)
return messages
})
const goEmpty = () => {
inputMessage.value = ''
stop()
}
const createNewChatSimple = async () => {
@@ -492,10 +492,6 @@ function getRecommendQuestions(id?: number) {
})
}
onMounted(() => {
getChatList()
})
function quickAsk(question: string) {
inputMessage.value = question
nextTick(() => {
@@ -539,7 +535,7 @@ const sendMessage = async () => {
if (chartAnswerRef.value) {
if (chartAnswerRef.value instanceof Array) {
for (let i = 0; i < chartAnswerRef.value.length; i++) {
const _index = chartAnswerRef.value[i].index
const _index = chartAnswerRef.value[i].index()
if (index === _index) {
await chartAnswerRef.value[i].sendMessage()
break
@@ -567,7 +563,7 @@ const analysisAnswerRef = ref()
async function onAnalysisAnswerFinish(id: number) {
loading.value = false
isTyping.value = false
console.log(id)
console.debug(id)
//await getRecommendQuestions(id)
}
function onAnalysisAnswerError() {
@@ -607,7 +603,7 @@ async function clickAnalysis(id?: number) {
if (analysisAnswerRef.value) {
if (analysisAnswerRef.value instanceof Array) {
for (let i = 0; i < analysisAnswerRef.value.length; i++) {
const _index = analysisAnswerRef.value[i].index
const _index = analysisAnswerRef.value[i].index()
if (index === _index) {
await analysisAnswerRef.value[i].sendMessage()
break
@@ -661,7 +657,7 @@ async function clickPredict(id?: number) {
if (predictAnswerRef.value) {
if (predictAnswerRef.value instanceof Array) {
for (let i = 0; i < predictAnswerRef.value.length; i++) {
const _index = predictAnswerRef.value[i].index
const _index = predictAnswerRef.value[i].index()
if (index === _index) {
await predictAnswerRef.value[i].sendMessage()
break
@@ -702,6 +698,49 @@ function clickInput() {
inputRef.value?.focus()
}
function stop() {
if (recommendQuestionRef.value) {
if (recommendQuestionRef.value instanceof Array) {
for (let i = 0; i < recommendQuestionRef.value.length; i++) {
recommendQuestionRef.value[i].stop()
}
} else {
recommendQuestionRef.value.stop()
}
}
if (chartAnswerRef.value) {
if (chartAnswerRef.value instanceof Array) {
for (let i = 0; i < chartAnswerRef.value.length; i++) {
chartAnswerRef.value[i].stop()
}
} else {
chartAnswerRef.value.stop()
}
}
if (analysisAnswerRef.value) {
if (analysisAnswerRef.value instanceof Array) {
for (let i = 0; i < analysisAnswerRef.value.length; i++) {
analysisAnswerRef.value[i].stop()
}
} else {
analysisAnswerRef.value.stop()
}
}
if (predictAnswerRef.value) {
if (predictAnswerRef.value instanceof Array) {
for (let i = 0; i < predictAnswerRef.value.length; i++) {
predictAnswerRef.value[i].stop()
}
} else {
predictAnswerRef.value.stop()
}
}
}
onMounted(() => {
getChatList()
})
defineExpose({
getHistoryList,
toAssistantHistory,