fix: 对话创建防抖
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
"element-plus": "^2.9.11",
|
||||
"fingerprintjs": "^0.5.3",
|
||||
"hook-fetch": "^2.0.4-beta.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^3.0.3",
|
||||
"pinia-plugin-persistedstate": "^4.3.0",
|
||||
|
||||
3
Yi.Ai.Vue3/pnpm-lock.yaml
generated
3
Yi.Ai.Vue3/pnpm-lock.yaml
generated
@@ -41,6 +41,9 @@ importers:
|
||||
hook-fetch:
|
||||
specifier: ^2.0.4-beta.1
|
||||
version: 2.0.4-beta.1(react@19.1.0)(typescript-api-pro@0.0.7)(vue@3.5.16(typescript@5.8.3))
|
||||
lodash-es:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
nprogress:
|
||||
specifier: ^0.2.0
|
||||
version: 0.2.0
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
<!-- 默认消息列表页 -->
|
||||
<script setup lang="ts">
|
||||
import type { FilesCardProps } from 'vue-element-plus-x/types/FilesCard';
|
||||
import { Loading } from '@element-plus/icons-vue';
|
||||
import { useDebounceFn } from '@vueuse/core';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { nextTick, ref, watch } from 'vue';
|
||||
import ModelSelect from '@/components/ModelSelect/index.vue';
|
||||
import WelecomeText from '@/components/WelecomeText/index.vue';
|
||||
import { useUserStore } from '@/stores';
|
||||
import { useFilesStore } from '@/stores/modules/files';
|
||||
|
||||
import { useSessionStore } from '@/stores/modules/session';
|
||||
|
||||
const userStore = useUserStore();
|
||||
@@ -13,15 +18,45 @@ const filesStore = useFilesStore();
|
||||
|
||||
const senderValue = ref('');
|
||||
const senderRef = ref();
|
||||
const isSending = ref(false); // 发送状态标志
|
||||
|
||||
async function handleSend() {
|
||||
localStorage.setItem('chatContent', senderValue.value);
|
||||
await sessionStore.createSessionList({
|
||||
userId: userStore.userInfo?.userId as number,
|
||||
sessionContent: senderValue.value,
|
||||
sessionTitle: senderValue.value.slice(0, 10),
|
||||
remark: senderValue.value.slice(0, 10),
|
||||
});
|
||||
// 防抖发送函数
|
||||
const debouncedSend = useDebounceFn(async () => {
|
||||
if (!senderValue.value.trim()) {
|
||||
ElMessage.warning('消息内容不能为空');
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSending.value) {
|
||||
ElMessage.warning('请等待上一条消息发送完成');
|
||||
return;
|
||||
}
|
||||
|
||||
const content = senderValue.value;
|
||||
isSending.value = true;
|
||||
|
||||
try {
|
||||
localStorage.setItem('chatContent', content);
|
||||
await sessionStore.createSessionList({
|
||||
userId: userStore.userInfo?.userId as number,
|
||||
sessionContent: content,
|
||||
sessionTitle: content.slice(0, 10),
|
||||
remark: content.slice(0, 10),
|
||||
});
|
||||
senderValue.value = ''; // 清空输入框
|
||||
}
|
||||
catch (error) {
|
||||
console.error('发送消息失败:', error);
|
||||
ElMessage.error('发送消息失败,请重试');
|
||||
}
|
||||
finally {
|
||||
isSending.value = false;
|
||||
}
|
||||
}, 800, { leading: true, trailing: false }); // 800ms防抖
|
||||
|
||||
// 处理发送事件
|
||||
function handleSend() {
|
||||
debouncedSend();
|
||||
}
|
||||
|
||||
function handleDeleteCard(_item: FilesCardProps, index: number) {
|
||||
@@ -33,12 +68,12 @@ watch(
|
||||
(val) => {
|
||||
if (val > 0) {
|
||||
nextTick(() => {
|
||||
senderRef.value.openHeader();
|
||||
senderRef.value?.openHeader();
|
||||
});
|
||||
}
|
||||
else {
|
||||
nextTick(() => {
|
||||
senderRef.value.closeHeader();
|
||||
senderRef.value?.closeHeader();
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -59,6 +94,7 @@ watch(
|
||||
variant="updown"
|
||||
clearable
|
||||
allow-speech
|
||||
:loading="isSending"
|
||||
@submit="handleSend"
|
||||
>
|
||||
<template #header>
|
||||
@@ -96,10 +132,14 @@ watch(
|
||||
</template>
|
||||
<template #prefix>
|
||||
<div class="flex-1 flex items-center gap-8px flex-none w-fit overflow-hidden">
|
||||
<!-- <FilesSelect /> -->
|
||||
<ModelSelect />
|
||||
</div>
|
||||
</template>
|
||||
<template #suffix>
|
||||
<el-icon v-if="isSending" class="is-loading">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
</template>
|
||||
</Sender>
|
||||
</div>
|
||||
</template>
|
||||
@@ -117,4 +157,19 @@ watch(
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-icon.is-loading) {
|
||||
margin-left: 8px;
|
||||
color: var(--el-color-primary);
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { BubbleProps } from 'vue-element-plus-x/types/Bubble';
|
||||
import type { BubbleListInstance } from 'vue-element-plus-x/types/BubbleList';
|
||||
import type { FilesCardProps } from 'vue-element-plus-x/types/FilesCard';
|
||||
import type { ThinkingStatus } from 'vue-element-plus-x/types/Thinking';
|
||||
import { ArrowLeftBold, ArrowRightBold } from '@element-plus/icons-vue';
|
||||
import { ArrowLeftBold, ArrowRightBold, Loading } from '@element-plus/icons-vue';
|
||||
import { ElIcon, ElMessage } from 'element-plus';
|
||||
import { useHookFetch } from 'hook-fetch/vue';
|
||||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
@@ -164,8 +164,12 @@ function handleDataChunk(chunk: AnyObject) {
|
||||
function handleError(err: any) {
|
||||
console.error('Fetch error:', err);
|
||||
}
|
||||
const isSending = ref(false);
|
||||
|
||||
async function startSSE(chatContent: string) {
|
||||
if (isSending.value)
|
||||
return;
|
||||
|
||||
try {
|
||||
// 清空输入框
|
||||
inputValue.value = '';
|
||||
@@ -199,6 +203,8 @@ async function startSSE(chatContent: string) {
|
||||
}
|
||||
}
|
||||
finally {
|
||||
isSending.value = false;
|
||||
|
||||
// 停止打字器状态
|
||||
if (bubbleItems.value.length) {
|
||||
bubbleItems.value[bubbleItems.value.length - 1].typing = false;
|
||||
@@ -348,6 +354,12 @@ function copy(item: any) {
|
||||
<ModelSelect />
|
||||
</div>
|
||||
</template>
|
||||
<!-- 新增的 #suffix 模板 -->
|
||||
<template #suffix>
|
||||
<ElIcon v-if="isSending" class="is-loading">
|
||||
<Loading />
|
||||
</ElIcon>
|
||||
</template>
|
||||
</Sender>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user