From 8b8f77cfccaa326ba2ff58b75657ee1e4b829d03 Mon Sep 17 00:00:00 2001
From: MT-Fire <798521692@qq.com>
Date: Thu, 12 Mar 2026 10:24:22 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=94=99=E8=AF=AF?=
=?UTF-8?q?=E6=BB=9A=E5=8A=A8=E5=88=B0=E5=BA=95=E9=83=A8=E7=9A=84=E9=97=AE?=
=?UTF-8?q?=E9=A2=98=E3=80=82=E5=88=A0=E9=99=A4=E5=AD=97=E6=95=B0=E6=98=BE?=
=?UTF-8?q?=E7=A4=BA=EF=BC=8C=E6=B7=BB=E5=8A=A0toast=E6=8F=90=E7=A4=BA?=
=?UTF-8?q?=E8=B6=85=E8=BF=87=E5=AD=97=E6=95=B0=E3=80=82=E8=BE=93=E5=85=A5?=
=?UTF-8?q?=E6=A1=86=E6=89=A9=E5=A4=A7=E6=8C=89=E9=92=AE=E7=A7=BB=E5=8A=A8?=
=?UTF-8?q?=E8=87=B3=E5=B7=A6=E4=BE=A7=E3=80=82=E5=88=A0=E9=99=A4=E4=BE=A7?=
=?UTF-8?q?=E8=BE=B9=E6=A0=8F=E8=BE=B9=E6=A1=86=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/chat/MessageList.vue | 5 +-
src/components/input/ChatInput.vue | 94 +++++++++++++++-----------
src/components/sidebar/ChatSidebar.vue | 5 +-
3 files changed, 61 insertions(+), 43 deletions(-)
diff --git a/src/components/chat/MessageList.vue b/src/components/chat/MessageList.vue
index 040534f..28572ae 100644
--- a/src/components/chat/MessageList.vue
+++ b/src/components/chat/MessageList.vue
@@ -229,7 +229,10 @@ defineExpose({
});
onMounted(() => {
- scrollToBottom(false);
+ // 只有当有消息时才滚动到底部,否则保持在顶部显示欢迎界面
+ if (visibleMessages.value.length > 0) {
+ scrollToBottom(false);
+ }
});
diff --git a/src/components/input/ChatInput.vue b/src/components/input/ChatInput.vue
index d0d4d8f..48e28be 100644
--- a/src/components/input/ChatInput.vue
+++ b/src/components/input/ChatInput.vue
@@ -54,6 +54,7 @@
v-model="inputText"
:placeholder="placeholder"
:rows="1"
+ @beforeinput="handleBeforeInput"
@input="autoResize"
@focus="isFocused = true"
@blur="isFocused = false"
@@ -90,6 +91,11 @@
@@ -190,7 +179,7 @@ const props = withDefaults(
placeholder: "输入你的问题...",
isStreaming: false,
sendOnEnter: false,
- maxChars: 4000,
+ maxChars: 10,
disabled: false,
// 默认全部支持
supports_thinking: true,
@@ -231,6 +220,18 @@ const textareaRef = ref(null);
const fileInputRef = ref(null);
const imageInputRef = ref(null);
+// toast 节流
+let lastToastTime = 0;
+const toastThrottleMs = 2000;
+
+function showThrottledToast(message: string, type: 'error' = 'error') {
+ const now = Date.now();
+ if (now - lastToastTime >= toastThrottleMs) {
+ lastToastTime = now;
+ window.$toast?.(message, type);
+ }
+}
+
// 计算属性
const charCount = computed(() => inputText.value.length);
const isUploading = computed(() => attachments.value.some((a) => a.uploading));
@@ -254,6 +255,27 @@ function autoResize() {
textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)+1}px`;
}
+// 处理输入前事件,限制字数
+function handleBeforeInput(event: InputEvent) {
+ // 如果不是插入文本的操作(如删除、退格等),允许
+ if (!event.data) return;
+
+ // 检查输入后是否会超过限制
+ const currentLength = inputText.value.length;
+ const insertLength = event.data?.length || 0;
+ const selectionStart = (event.target as HTMLTextAreaElement).selectionStart || 0;
+ const selectionEnd = (event.target as HTMLTextAreaElement).selectionEnd || 0;
+ const selectedLength = selectionEnd - selectionStart;
+
+ // 计算输入后的长度
+ const newLength = currentLength - selectedLength + insertLength;
+
+ if (newLength > props.maxChars) {
+ event.preventDefault();
+ showThrottledToast(`已超${props.maxChars}字上限,请删除部分内容`);
+ }
+}
+
// 处理键盘事件
function handleKeydown(event: KeyboardEvent) {
// Ctrl+Enter 或 Cmd+Enter 发送
@@ -298,6 +320,22 @@ async function handlePaste(event: ClipboardEvent) {
const items = event.clipboardData?.items;
if (!items) return;
+ // 检查粘贴文本是否会超过字数限制
+ const text = event.clipboardData?.getData('text');
+ if (text) {
+ const textarea = event.target as HTMLTextAreaElement;
+ const selectionStart = textarea.selectionStart || 0;
+ const selectionEnd = textarea.selectionEnd || 0;
+ const selectedLength = selectionEnd - selectionStart;
+ const newLength = inputText.value.length - selectedLength + text.length;
+
+ if (newLength > props.maxChars) {
+ event.preventDefault();
+ showThrottledToast(`已超${props.maxChars}字上限,请删除部分内容`);
+ return;
+ }
+ }
+
for (const item of items) {
if (item.type.startsWith("image/")) {
event.preventDefault();
@@ -718,26 +756,6 @@ onMounted(() => {
}
}
-.toolbar-right {
- display: flex;
- align-items: center;
- gap: 16px;
-}
-
-.char-count {
- font-size: 12px;
- color: #9ca3af;
-
- &.warning {
- color: #f59e0b;
- }
-}
-
-.send-hint {
- font-size: 12px;
- color: #9ca3af;
-}
-
@keyframes pulse {
0%,
100% {
diff --git a/src/components/sidebar/ChatSidebar.vue b/src/components/sidebar/ChatSidebar.vue
index c83f3b9..ab5cf35 100644
--- a/src/components/sidebar/ChatSidebar.vue
+++ b/src/components/sidebar/ChatSidebar.vue
@@ -279,7 +279,6 @@ if (typeof window !== "undefined") {
position: relative;
height: 100vh;
background: #ffffff;
- border-right: 1px solid #e2e8f0;
transition: width 0.3s ease;
overflow: hidden;
flex-shrink: 0;
@@ -690,8 +689,6 @@ if (typeof window !== "undefined") {
cursor: col-resize;
z-index: 10;
- &:hover {
- background: rgba(59, 130, 246, 0.3);
- }
+
}