|
@@ -2,7 +2,7 @@
|
2
|
2
|
* @Author: wrh
|
3
|
3
|
* @Date: 2025-01-01 00:00:00
|
4
|
4
|
* @LastEditors: Please set LastEditors
|
5
|
|
- * @LastEditTime: 2025-07-30 14:54:24
|
|
5
|
+ * @LastEditTime: 2025-07-30 16:06:36
|
6
|
6
|
-->
|
7
|
7
|
<template>
|
8
|
8
|
<div class="agent-detail-container" v-loading="loading">
|
|
@@ -32,11 +32,22 @@
|
32
|
32
|
</div>
|
33
|
33
|
<div class="topic-content">
|
34
|
34
|
<div v-for="topic in topicList" :key="topic.topicId" class="topic-item"
|
35
|
|
- :class="{ 'active': currentTopicId === topic.topicId }" @click="selectTopic(topic)">
|
36
|
|
- <div class="topic-info">
|
|
35
|
+ :class="{ 'active': currentTopicId === topic.topicId }">
|
|
36
|
+ <div class="topic-info" @click="selectTopic(topic)">
|
37
|
37
|
<div class="topic-name">{{ topic.topic }}</div>
|
38
|
38
|
<div class="topic-time">{{ topic.createTime }}</div>
|
39
|
39
|
</div>
|
|
40
|
+ <div class="topic-actions">
|
|
41
|
+ <el-button
|
|
42
|
+ type="danger"
|
|
43
|
+ size="small"
|
|
44
|
+ :icon="Delete"
|
|
45
|
+ circle
|
|
46
|
+ @click.stop="handleDeleteTopic(topic)"
|
|
47
|
+ class="delete-btn"
|
|
48
|
+ title="删除对话"
|
|
49
|
+ />
|
|
50
|
+ </div>
|
40
|
51
|
</div>
|
41
|
52
|
</div>
|
42
|
53
|
</div>
|
|
@@ -160,7 +171,8 @@
|
160
|
171
|
|
161
|
172
|
<script setup>
|
162
|
173
|
import { ref, reactive, watch, nextTick, computed, getCurrentInstance } from 'vue';
|
163
|
|
-import { ElMessage } from 'element-plus';
|
|
174
|
+import { ElMessage, ElMessageBox } from 'element-plus';
|
|
175
|
+import { Delete } from '@element-plus/icons-vue';
|
164
|
176
|
import { getAgent, opening, uploadFile } from '@/api/llm/agent';
|
165
|
177
|
import { answer } from '@/api/llm/mcp';
|
166
|
178
|
import { listTopic, getTopic, delTopic, addTopic, updateTopic } from "@/api/llm/topic";
|
|
@@ -331,6 +343,42 @@ const selectTopic = async (topic) => {
|
331
|
343
|
}
|
332
|
344
|
}
|
333
|
345
|
|
|
346
|
+// 删除话题
|
|
347
|
+const handleDeleteTopic = async (topic) => {
|
|
348
|
+ try {
|
|
349
|
+ await ElMessageBox.confirm(
|
|
350
|
+ `确定要删除话题"${topic.topic}"吗?删除后无法恢复。`,
|
|
351
|
+ '删除确认',
|
|
352
|
+ {
|
|
353
|
+ confirmButtonText: '确定删除',
|
|
354
|
+ cancelButtonText: '取消',
|
|
355
|
+ type: 'warning',
|
|
356
|
+ confirmButtonClass: 'el-button--danger'
|
|
357
|
+ }
|
|
358
|
+ )
|
|
359
|
+
|
|
360
|
+ // 调用删除API
|
|
361
|
+ await delTopic(topic.topicId)
|
|
362
|
+
|
|
363
|
+ // 如果删除的是当前选中的话题,则重置对话状态
|
|
364
|
+ if (currentTopicId.value === topic.topicId) {
|
|
365
|
+ currentTopicId.value = null
|
|
366
|
+ chatMessages.value = []
|
|
367
|
+ chatTitle.value = '智能体新对话'
|
|
368
|
+ }
|
|
369
|
+
|
|
370
|
+ // 重新加载话题列表
|
|
371
|
+ await loadTopic()
|
|
372
|
+
|
|
373
|
+ ElMessage.success('话题删除成功')
|
|
374
|
+ } catch (error) {
|
|
375
|
+ if (error !== 'cancel') {
|
|
376
|
+ console.error('删除话题失败:', error)
|
|
377
|
+ ElMessage.error('删除话题失败')
|
|
378
|
+ }
|
|
379
|
+ }
|
|
380
|
+}
|
|
381
|
+
|
334
|
382
|
// 发送消息
|
335
|
383
|
const sendMessage = async () => {
|
336
|
384
|
const message = inputMessage.value.trim()
|
|
@@ -483,11 +531,6 @@ const submitChatUpload = async () => {
|
483
|
531
|
}
|
484
|
532
|
}
|
485
|
533
|
|
486
|
|
-// 清空聊天内文件列表
|
487
|
|
-const clearChatFiles = () => {
|
488
|
|
- chatFileList.value = []
|
489
|
|
-}
|
490
|
|
-
|
491
|
534
|
// 开始新对话
|
492
|
535
|
const startNewChat = () => {
|
493
|
536
|
currentTopicId.value = null
|
|
@@ -655,17 +698,23 @@ const formatContentLinks = (content) => {
|
655
|
698
|
.topic-item {
|
656
|
699
|
padding: 12px 16px;
|
657
|
700
|
border-bottom: 1px solid #e9ecef;
|
658
|
|
- cursor: pointer;
|
659
|
701
|
transition: all 0.3s ease;
|
660
|
702
|
background: white;
|
661
|
703
|
margin: 4px 8px;
|
662
|
704
|
border-radius: 6px;
|
663
|
705
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
706
|
+ display: flex;
|
|
707
|
+ justify-content: space-between;
|
|
708
|
+ align-items: center;
|
664
|
709
|
|
665
|
710
|
&:hover {
|
666
|
711
|
background: #e3f2fd;
|
667
|
712
|
transform: translateX(2px);
|
668
|
713
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
714
|
+
|
|
715
|
+ .topic-actions {
|
|
716
|
+ opacity: 1;
|
|
717
|
+ }
|
669
|
718
|
}
|
670
|
719
|
|
671
|
720
|
&.active {
|
|
@@ -697,6 +746,11 @@ const formatContentLinks = (content) => {
|
697
|
746
|
}
|
698
|
747
|
|
699
|
748
|
.topic-info {
|
|
749
|
+ flex: 1;
|
|
750
|
+ cursor: pointer;
|
|
751
|
+ min-width: 0; // 允许flex项目缩小到内容以下
|
|
752
|
+ max-width: calc(100% - 40px); // 为删除按钮预留40px空间
|
|
753
|
+
|
700
|
754
|
.topic-name {
|
701
|
755
|
font-size: 13px;
|
702
|
756
|
font-weight: 500;
|
|
@@ -705,6 +759,7 @@ const formatContentLinks = (content) => {
|
705
|
759
|
overflow: hidden;
|
706
|
760
|
text-overflow: ellipsis;
|
707
|
761
|
white-space: nowrap;
|
|
762
|
+ max-width: 100%;
|
708
|
763
|
|
709
|
764
|
&::before {
|
710
|
765
|
content: "💬";
|
|
@@ -717,6 +772,36 @@ const formatContentLinks = (content) => {
|
717
|
772
|
font-size: 11px;
|
718
|
773
|
color: #6c757d;
|
719
|
774
|
font-style: italic;
|
|
775
|
+ overflow: hidden;
|
|
776
|
+ text-overflow: ellipsis;
|
|
777
|
+ white-space: nowrap;
|
|
778
|
+ max-width: 100%;
|
|
779
|
+ }
|
|
780
|
+ }
|
|
781
|
+
|
|
782
|
+ .topic-actions {
|
|
783
|
+ flex-shrink: 0; // 防止删除按钮被压缩
|
|
784
|
+ width: 32px; // 固定宽度
|
|
785
|
+ display: flex;
|
|
786
|
+ justify-content: center;
|
|
787
|
+ opacity: 0;
|
|
788
|
+ transition: opacity 0.3s ease;
|
|
789
|
+
|
|
790
|
+ .delete-btn {
|
|
791
|
+ width: 24px;
|
|
792
|
+ height: 24px;
|
|
793
|
+ padding: 0;
|
|
794
|
+ border: none;
|
|
795
|
+ background: #ff4757;
|
|
796
|
+
|
|
797
|
+ &:hover {
|
|
798
|
+ background: #ff3742;
|
|
799
|
+ transform: scale(1.1);
|
|
800
|
+ }
|
|
801
|
+
|
|
802
|
+ .el-icon {
|
|
803
|
+ font-size: 12px;
|
|
804
|
+ }
|
720
|
805
|
}
|
721
|
806
|
}
|
722
|
807
|
}
|