From c22eaf781c0737dfa84bb2c06cd5561482e1b015 Mon Sep 17 00:00:00 2001 From: Lexcubia Date: Fri, 25 Apr 2025 14:28:01 +0800 Subject: [PATCH] =?UTF-8?q?feat(chat):=20=E4=BC=98=E5=8C=96=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E4=BC=9A=E8=AF=9D=E5=88=97=E8=A1=A8=E5=B9=B6=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=96=B0=E5=BB=BA=E4=BC=9A=E8=AF=9D=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构 HistoryList 组件,使其在展开和折叠状态下均有更好展示 - 在 ChatModeSelector 中添加新建会话按钮 - 优化 ChatInterface 样式,提高输入区域可用性 - 调整 chat store 中的 startNewChat 方法逻辑 --- src/components/chat/HistoryList.vue | 180 +++++++++++++++----- src/store/chat.js | 6 +- src/views/chat/ChatInterface.vue | 73 +++------ src/views/chat/ChatModeSelector.vue | 244 ++++++++++++++++------------ 4 files changed, 305 insertions(+), 198 deletions(-) diff --git a/src/components/chat/HistoryList.vue b/src/components/chat/HistoryList.vue index 5859bad..e9355bd 100644 --- a/src/components/chat/HistoryList.vue +++ b/src/components/chat/HistoryList.vue @@ -1,38 +1,68 @@ \ No newline at end of file diff --git a/src/store/chat.js b/src/store/chat.js index b7e8fc2..b4ac1fb 100644 --- a/src/store/chat.js +++ b/src/store/chat.js @@ -301,9 +301,9 @@ export const useChatStore = defineStore('chat', { startNewChat() { // 如果当前有活跃会话,将其标记为完成 - if (this.conversationId && this.messages[this.conversationId]) { - this.messages[this.conversationId].conversationStatus = 'finished' - } + // if (this.conversationId && this.messages[this.conversationId]) { + // this.messages[this.conversationId].conversationStatus = 'finished' + // } // 只清除当前会话相关的消息缓存 if (this.conversationId) { diff --git a/src/views/chat/ChatInterface.vue b/src/views/chat/ChatInterface.vue index 2ca14ac..82259ab 100644 --- a/src/views/chat/ChatInterface.vue +++ b/src/views/chat/ChatInterface.vue @@ -73,13 +73,6 @@
- - 新会话 - { if (!currentConversation.conversationStatus) return false return ['finished', 'typing'].includes(currentConversation.conversationStatus) }) -const newChatButtonsDisabled = computed(() => { - if (!chatStore.currentConversation) return false - const currentConversation = chatStore.currentConversation - if (!currentConversation.conversationStatus) return false - return ['typing'].includes(currentConversation.conversationStatus) -}) // 获取最后一条包含dafen字段的消息 const lastMessageWithDafen = computed(() => { @@ -684,52 +671,40 @@ html.dark .background-section .background-content { } .input-area { - position: absolute; - bottom: 0; - left: 0; - right: 0; display: flex; align-items: flex-end; - gap: 12px; - padding: 16px; - background: var(--el-color-primary-light-8); + gap: 8px; + padding: 16px 20px; border-top: 1px solid var(--el-border-color-light); - z-index: 3; - :deep(.el-textarea) { + background-color: var(--el-bg-color); + position: relative; + z-index: 1; + + .el-textarea { flex: 1; - - .el-textarea__inner { - min-height: 40px !important; - padding: 8px 12px; - font-size: 14px; - line-height: 1.5; - border-radius: 4px; - border-color: var(--el-border-color); - background-color: var(--el-bg-color); - transition: all 0.3s; + + :deep(.el-textarea__inner) { + border-radius: 8px; resize: none; - - &:hover { - border-color: var(--el-border-color-hover); - } - - &:focus { - border-color: var(--el-color-primary); - box-shadow: 0 0 0 2px var(--el-color-primary-light-8); - } - + padding: 8px 12px; + min-height: 40px !important; + max-height: 120px; + line-height: 24px; + font-size: 14px; + &:disabled { - background-color: var(--el-fill-color-light); - border-color: var(--el-border-color-lighter); - color: var(--el-text-color-placeholder); + background-color: var(--el-input-disabled-bg); cursor: not-allowed; } - - &::placeholder { - color: var(--el-text-color-placeholder); - } } } + + .send-btn { + height: 40px; + padding: 0 20px; + border-radius: 8px; + font-size: 14px; + } } // Dark mode override for input area diff --git a/src/views/chat/ChatModeSelector.vue b/src/views/chat/ChatModeSelector.vue index cd6ba02..99bbef9 100644 --- a/src/views/chat/ChatModeSelector.vue +++ b/src/views/chat/ChatModeSelector.vue @@ -23,14 +23,19 @@ :collapse="settingsStore.sidebarCollapsed" @select="selectMode" > + + + 新建会话 + + {{ mode.name }} - + - + { } } +const handleNewChat = () => { + chatStore.startNewChat() +} + const isMobile = ref(false) const checkMobile = () => { @@ -162,6 +171,7 @@ onUnmounted(() => { padding: 0 16px; display: flex; align-items: center; + flex-shrink: 0; &-title { display: flex; @@ -186,8 +196,18 @@ onUnmounted(() => { background-color: transparent; border: none; padding: 8px; - flex-grow: 1; - overflow-y: auto; + overflow: visible; +} + +.new-chat-item { + margin-bottom: 12px !important; + border: 1px solid var(--el-border-color-lighter); + background-color: var(--el-fill-color-light) !important; + + &:hover { + box-shadow: var(--el-box-shadow-light); + color: var(--el-color-primary); + } } :deep(.mode-item) { @@ -200,7 +220,7 @@ onUnmounted(() => { overflow: hidden; .el-icon { - margin-right: 12px; + margin: 0; font-size: 18px; width: 18px; } @@ -216,11 +236,12 @@ onUnmounted(() => { } &:not(.is-active):hover { - background-color: var(--el-color-primary-light-9); + background-color: var(--el-fill-color-light); color: var(--el-color-primary); } .mode-name { + margin-left: 12px; font-size: 14px; white-space: nowrap; opacity: 1; @@ -232,16 +253,98 @@ onUnmounted(() => { } } -.mode-setting-btn { - position: absolute; - right: 8px; - top: 50%; - transform: translateY(-50%); - color: var(--el-text-color-secondary); +.mode-selector.collapsed { + .mode-header { + padding: 0; + display: flex; + align-items: center; + justify-content: center; + height: 60px; + + .mode-header-collapsed-logo { + display: flex; + align-items: center; + height: 100%; + } + + .mode-header-icon.collapsed { + height: 32px; + filter: drop-shadow(0 0 0.75em rgba(var(--el-color-primary-rgb), 0.6)); + vertical-align: middle; + } + } + .mode-menu { + padding: 8px 12px; + } + + :deep(.el-menu-item) { + width: 40px; + height: 40px; + padding: 0 !important; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto 4px auto; + + .el-icon { + margin-right: 0; + } + + .mode-name { + display: none; + } + } + + .settings-button { + width: 40px; + height: 40px; + .mode-name, + .button-text { + opacity: 0; + } + } +} + +.sidebar-footer { + height: 48px; + padding: 0 12px; + display: flex; + align-items: center; + justify-content: center; + margin-top: auto; + flex-shrink: 0; +} + +.settings-button { + display: flex; + align-items: center; + height: 40px; + width: 100%; + padding: 0 12px; + color: var(--el-text-color-regular); + border-radius: 8px; + cursor: pointer; + transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out; + + .el-icon { + margin: 0; + font-size: 18px; + width: 18px; + } + &:hover { + background-color: var(--el-fill-color-light); color: var(--el-color-primary); } + + .button-text { + margin-left: 12px; + font-size: 14px; + white-space: nowrap; + opacity: 1; + transition: opacity 0.3s ease-in-out; + } } /* 移动端样式 */ @@ -307,7 +410,7 @@ onUnmounted(() => { margin: 0 auto 4px auto; .el-icon { - margin-right: 0; + margin: 0; } .mode-name { @@ -325,95 +428,6 @@ onUnmounted(() => { } } -.sidebar-footer { - height: 48px; - padding: 0 12px; - display: flex; - align-items: center; - justify-content: center; -} - -.settings-button { - display: flex; - align-items: center; - height: 40px; - width: 100%; - padding: 0 12px; - color: var(--el-text-color-regular); - border-radius: 8px; - cursor: pointer; - transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out; - - .el-icon { - margin-right: 12px; - font-size: 18px; - width: 18px; - } - - &:hover { - background-color: var(--el-fill-color-light); - color: var(--el-color-primary); - } - - .button-text { - font-size: 14px; - white-space: nowrap; - opacity: 1; - transition: opacity 0.3s ease-in-out; - } -} - -.mode-selector.collapsed { - .sidebar-footer { - padding: 0; - } - - .settings-button { - justify-content: center; - width: 40px; - padding: 0; - - .el-icon { - margin-right: 0; - } - - .button-text { - opacity: 0; - pointer-events: none; - } - - &:hover { - background-color: var(--el-fill-color-light); - } - } -} - - - - - - - + + + + \ No newline at end of file