|
@@ -1,7 +1,7 @@
|
|
|
<script setup lang="ts">
|
|
|
import { ref, nextTick, onMounted } from 'vue'
|
|
|
import { Local } from '/@/utils/storage'
|
|
|
-import { User, ChatDotRound, Delete, Edit } from '@element-plus/icons-vue'
|
|
|
+import { User, ChatDotRound, Delete, Edit, Check, Close } from '@element-plus/icons-vue'
|
|
|
import { MarkdownPlugin } from '/@/components/markdown/type/markdown'
|
|
|
import EChartsPlugin from '/@/components/markdown/plugins/markdown-it-echarts'
|
|
|
import Markdown from '/@/components/markdown/Markdown.vue'
|
|
@@ -32,6 +32,10 @@ for (let i = 0; i < 100; i++) {
|
|
|
)
|
|
|
}
|
|
|
|
|
|
+// 编辑状态管理
|
|
|
+const editingConversationId = ref<number | null>(null)
|
|
|
+const editingTitle = ref('')
|
|
|
+
|
|
|
// 消息列表
|
|
|
const messages = ref<Message[]>([])
|
|
|
|
|
@@ -177,8 +181,38 @@ const deleteConversation = (id: number) => {
|
|
|
|
|
|
// 编辑摘要
|
|
|
const editSummary = (id: number) => {
|
|
|
- console.log('编辑摘要:', id)
|
|
|
- // TODO: 实现编辑摘要逻辑
|
|
|
+ const conversation = conversations.value.find(conv => conv.id === id)
|
|
|
+ if (conversation) {
|
|
|
+ // 设置当前编辑的会话ID
|
|
|
+ editingConversationId.value = id
|
|
|
+ editingTitle.value = conversation.title
|
|
|
+ // 下一帧聚焦到输入框
|
|
|
+ nextTick(() => {
|
|
|
+ const editInput = document.querySelector('.edit-input .el-input__inner') as HTMLInputElement
|
|
|
+ if (editInput) {
|
|
|
+ editInput.focus()
|
|
|
+ editInput.select()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 确认编辑
|
|
|
+const confirmEdit = (id: number) => {
|
|
|
+ const conversation = conversations.value.find(conv => conv.id === id)
|
|
|
+ if (conversation && editingTitle.value.trim()) {
|
|
|
+ conversation.title = editingTitle.value.trim()
|
|
|
+ // 清除编辑状态
|
|
|
+ editingConversationId.value = null
|
|
|
+ editingTitle.value = ''
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 取消编辑
|
|
|
+const cancelEdit = (id: number) => {
|
|
|
+ // 清除编辑状态
|
|
|
+ editingConversationId.value = null
|
|
|
+ editingTitle.value = ''
|
|
|
}
|
|
|
|
|
|
onMounted(() => {
|
|
@@ -198,29 +232,77 @@ onMounted(() => {
|
|
|
<div
|
|
|
v-for="conv in conversations"
|
|
|
:key="conv.id"
|
|
|
- :class="['conversation-item', { active: conv.active }]"
|
|
|
+ @click="selectConversation(conv.id)"
|
|
|
+ :class="['conversation-item', { active: conv.active, editing: editingConversationId === conv.id }]"
|
|
|
>
|
|
|
- <div class="conversation-content" @click="selectConversation(conv.id)">
|
|
|
+ <!-- 非编辑状态 -->
|
|
|
+ <div v-if="editingConversationId !== conv.id" class="conversation-content">
|
|
|
<span class="conversation-title">{{ conv.title }}</span>
|
|
|
</div>
|
|
|
- <div class="conversation-actions">
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
- size="small"
|
|
|
- :icon="Edit"
|
|
|
- @click.stop="editSummary(conv.id)"
|
|
|
- class="action-btn edit-btn"
|
|
|
- title="编辑摘要"
|
|
|
- />
|
|
|
- <el-button
|
|
|
- type="text"
|
|
|
+
|
|
|
+ <!-- 编辑状态 -->
|
|
|
+ <div v-else class="conversation-edit-content">
|
|
|
+ <el-input
|
|
|
+ v-model="editingTitle"
|
|
|
size="small"
|
|
|
- :icon="Delete"
|
|
|
- @click.stop="deleteConversation(conv.id)"
|
|
|
- class="action-btn delete-btn"
|
|
|
- title="删除对话"
|
|
|
+ @keydown.enter="confirmEdit(conv.id)"
|
|
|
+ @keydown.esc="cancelEdit(conv.id)"
|
|
|
+ class="edit-input"
|
|
|
/>
|
|
|
</div>
|
|
|
+
|
|
|
+ <!-- 操作按钮 -->
|
|
|
+ <div class="conversation-actions">
|
|
|
+ <!-- 非编辑状态的按钮 -->
|
|
|
+ <template v-if="editingConversationId !== conv.id">
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ :icon="Edit"
|
|
|
+ @click.stop="editSummary(conv.id)"
|
|
|
+ class="action-btn edit-btn"
|
|
|
+ title="编辑摘要"
|
|
|
+ plain
|
|
|
+ circle
|
|
|
+ />
|
|
|
+ <el-button
|
|
|
+ type="danger"
|
|
|
+ size="small"
|
|
|
+ :icon="Delete"
|
|
|
+ @click.stop="deleteConversation(conv.id)"
|
|
|
+ class="action-btn delete-btn"
|
|
|
+ title="删除对话"
|
|
|
+ plain
|
|
|
+ circle
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 编辑状态的按钮 -->
|
|
|
+ <template v-else>
|
|
|
+ <el-button
|
|
|
+ type="success"
|
|
|
+ size="small"
|
|
|
+ @click.stop="confirmEdit(conv.id)"
|
|
|
+ class="action-btn confirm-btn"
|
|
|
+ title="确认修改"
|
|
|
+ plain
|
|
|
+ circle
|
|
|
+ >
|
|
|
+ <el-icon><Check /></el-icon>
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ type="info"
|
|
|
+ size="small"
|
|
|
+ @click.stop="cancelEdit(conv.id)"
|
|
|
+ class="action-btn cancel-btn"
|
|
|
+ title="取消编辑"
|
|
|
+ plain
|
|
|
+ circle
|
|
|
+ >
|
|
|
+ <el-icon><Close /></el-icon>
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</el-scrollbar>
|
|
|
<el-button type="primary" size="large" class="create-conversation-btn">创建对话</el-button>
|
|
@@ -264,7 +346,7 @@ onMounted(() => {
|
|
|
|
|
|
<!-- 空状态页面 -->
|
|
|
|
|
|
- <div class="empty-content">
|
|
|
+ <div v-else class="empty-content">
|
|
|
<!-- 主图标 -->
|
|
|
<div class="empty-icon">
|
|
|
<el-icon :size="80" color="#d1d5db">
|
|
@@ -388,6 +470,7 @@ onMounted(() => {
|
|
|
type="primary"
|
|
|
size="small"
|
|
|
@click="sendMessage"
|
|
|
+ @keyup.ctrl.enter="sendMessage"
|
|
|
:disabled="!inputMessage.trim()"
|
|
|
>
|
|
|
发送
|
|
@@ -408,6 +491,10 @@ onMounted(() => {
|
|
|
</template>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
+:deep(.el-icon) {
|
|
|
+ margin-right: 0!important;
|
|
|
+}
|
|
|
+
|
|
|
.chat-container {
|
|
|
height: 100%;
|
|
|
background: var(--el-bg-color-page);
|
|
@@ -451,6 +538,7 @@ onMounted(() => {
|
|
|
color: var(--el-text-color-regular);
|
|
|
border: 1px solid transparent;
|
|
|
position: relative;
|
|
|
+ cursor: pointer;
|
|
|
|
|
|
&:hover {
|
|
|
background: var(--el-fill-color-light);
|
|
@@ -470,14 +558,39 @@ onMounted(() => {
|
|
|
opacity: 1;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ &.editing {
|
|
|
+ background: var(--el-color-warning-light-9);
|
|
|
+ border-color: var(--el-color-warning-light-7);
|
|
|
+
|
|
|
+ .conversation-actions {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.conversation-content {
|
|
|
flex: 1;
|
|
|
+ min-width: 0;
|
|
|
cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.conversation-edit-content {
|
|
|
+ flex: 1;
|
|
|
min-width: 0;
|
|
|
}
|
|
|
|
|
|
+.edit-input {
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ :deep(.el-input__inner) {
|
|
|
+ font-size: 14px;
|
|
|
+ padding: 4px 8px;
|
|
|
+ height: 28px;
|
|
|
+ line-height: 20px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
.conversation-title {
|
|
|
display: block;
|
|
|
overflow: hidden;
|
|
@@ -495,26 +608,10 @@ onMounted(() => {
|
|
|
}
|
|
|
|
|
|
.action-btn {
|
|
|
- padding: 4px !important;
|
|
|
- min-height: auto !important;
|
|
|
- width: 24px !important;
|
|
|
- height: 24px !important;
|
|
|
-
|
|
|
- &.edit-btn {
|
|
|
- color: var(--el-color-primary) !important;
|
|
|
-
|
|
|
- &:hover {
|
|
|
- background: var(--el-color-primary-light-9) !important;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &.delete-btn {
|
|
|
- color: var(--el-color-danger) !important;
|
|
|
-
|
|
|
- &:hover {
|
|
|
- background: var(--el-color-danger-light-9) !important;
|
|
|
- }
|
|
|
- }
|
|
|
+ width: 28px !important;
|
|
|
+ height: 28px !important;
|
|
|
+ padding: 0 !important;
|
|
|
+ margin: 0 2px;
|
|
|
}
|
|
|
|
|
|
/* 右侧聊天区域样式 */
|