feat(agent-panel): 添加附件删除功能
- 新增附件删除按钮和 deleteAttachment 方法 - 优化文件树操作按钮样式,支持多按钮布局 - 附件列表添加独立边框样式,提升视觉区分度
This commit is contained in:
parent
cab244227f
commit
e0f1c21ceb
@ -98,7 +98,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="data.isLeaf" class="node-actions" @click.stop>
|
<div v-if="data.isLeaf" class="node-actions" @click.stop>
|
||||||
<button
|
<button
|
||||||
class="tree-download-btn"
|
class="tree-action-btn tree-download-btn"
|
||||||
@click.stop="downloadFile(data.fileData)"
|
@click.stop="downloadFile(data.fileData)"
|
||||||
title="下载文件"
|
title="下载文件"
|
||||||
>
|
>
|
||||||
@ -129,7 +129,7 @@
|
|||||||
<p>暂无附件</p>
|
<p>暂无附件</p>
|
||||||
<a-button type="primary" @click="triggerUpload" :loading="isUploading">上传附件</a-button>
|
<a-button type="primary" @click="triggerUpload" :loading="isUploading">上传附件</a-button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="file-tree-container">
|
<div v-else class="file-tree-container attachment-tree">
|
||||||
<a-tree
|
<a-tree
|
||||||
v-model:expandedKeys="expandedKeys"
|
v-model:expandedKeys="expandedKeys"
|
||||||
:tree-data="attachmentTreeData"
|
:tree-data="attachmentTreeData"
|
||||||
@ -166,12 +166,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="data.isLeaf" class="node-actions" @click.stop>
|
<div v-if="data.isLeaf" class="node-actions" @click.stop>
|
||||||
<button
|
<button
|
||||||
class="tree-download-btn"
|
class="tree-action-btn tree-download-btn"
|
||||||
@click.stop="downloadFile(data.fileData)"
|
@click.stop="downloadFile(data.fileData)"
|
||||||
title="下载文件"
|
title="下载文件"
|
||||||
>
|
>
|
||||||
<Download :size="14" />
|
<Download :size="14" />
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
class="tree-action-btn tree-delete-btn"
|
||||||
|
@click.stop="deleteAttachment(data.fileData)"
|
||||||
|
title="删除附件"
|
||||||
|
>
|
||||||
|
<Trash2 :size="14" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -243,7 +250,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref, onMounted, onUpdated, nextTick } from 'vue'
|
import { computed, ref, onMounted, onUpdated, nextTick } from 'vue'
|
||||||
import { Download, X, Plus, Info, FolderCode, RefreshCw, Folder, FolderOpen } from 'lucide-vue-next'
|
import { Download, X, Plus, Info, FolderCode, RefreshCw, Folder, FolderOpen, Trash2 } from 'lucide-vue-next'
|
||||||
import {
|
import {
|
||||||
CheckCircleOutlined,
|
CheckCircleOutlined,
|
||||||
SyncOutlined,
|
SyncOutlined,
|
||||||
@ -600,6 +607,19 @@ const emitRefresh = () => {
|
|||||||
emit('refresh')
|
emit('refresh')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deleteAttachment = async (fileItem) => {
|
||||||
|
if (!props.threadId || !fileItem?.file_id) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
await threadApi.deleteThreadAttachment(props.threadId, fileItem.file_id)
|
||||||
|
message.success('附件已删除')
|
||||||
|
emitRefresh()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除附件失败:', error)
|
||||||
|
message.error('删除附件失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 拖拽调整宽度相关
|
// 拖拽调整宽度相关
|
||||||
const isResizing = ref(false)
|
const isResizing = ref(false)
|
||||||
const startX = ref(0)
|
const startX = ref(0)
|
||||||
@ -1046,15 +1066,15 @@ const stopResize = () => {
|
|||||||
|
|
||||||
/* File Tree Styles - VS Code Style Refined */
|
/* File Tree Styles - VS Code Style Refined */
|
||||||
.file-tree-container {
|
.file-tree-container {
|
||||||
padding: 0;
|
padding: 4px;
|
||||||
margin: 0 -6px; /* Slight negative margin */
|
margin: 0 -4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-node-wrapper {
|
.tree-node-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 28px; /* Increased height for spacing */
|
height: 28px;
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@ -1063,7 +1083,7 @@ const stopResize = () => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0; /* Important for flex child truncation */
|
min-width: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: var(--gray-800);
|
color: var(--gray-800);
|
||||||
@ -1096,23 +1116,28 @@ const stopResize = () => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
|
gap: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-download-btn {
|
.tree-action-btn {
|
||||||
display: none;
|
display: none;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border: none;
|
border: none;
|
||||||
background: transparent !important;
|
background: transparent;
|
||||||
color: var(--gray-500);
|
color: var(--gray-500);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
.tree-download-btn:hover {
|
||||||
color: var(--main-600);
|
color: var(--main-600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tree-delete-btn:hover {
|
||||||
|
color: var(--color-error-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Specific Ant Design Tree Overrides */
|
/* Specific Ant Design Tree Overrides */
|
||||||
@ -1142,13 +1167,13 @@ const stopResize = () => {
|
|||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--gray-50);
|
background-color: var(--gray-50);
|
||||||
|
|
||||||
.tree-download-btn {
|
.tree-action-btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.ant-tree-node-selected {
|
&.ant-tree-node-selected {
|
||||||
background-color: var(--gray-100); /* Gray selection background */
|
background-color: var(--gray-100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1166,7 +1191,7 @@ const stopResize = () => {
|
|||||||
.ant-tree-title {
|
.ant-tree-title {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
min-width: 0; /* Crucial for flex truncation */
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Switcher (Arrow) */
|
/* Switcher (Arrow) */
|
||||||
@ -1185,7 +1210,7 @@ const stopResize = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ant-tree-indent-unit {
|
.ant-tree-indent-unit {
|
||||||
width: 18px; /* Slightly wider indent */
|
width: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 隐藏文件夹展开/折叠箭头 */
|
/* 隐藏文件夹展开/折叠箭头 */
|
||||||
@ -1193,4 +1218,21 @@ const stopResize = () => {
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 附件列表专用样式 */
|
||||||
|
.attachment-tree :deep(.ant-tree-node-content-wrapper) {
|
||||||
|
border: 1px solid var(--gray-200);
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--gray-50);
|
||||||
|
border-color: var(--gray-300);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ant-tree-node-selected {
|
||||||
|
background-color: var(--gray-100);
|
||||||
|
border-color: var(--main-300);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user