|
|
|
@ -82,7 +82,9 @@ |
|
|
|
</template> |
|
|
|
<template #fileType="{ row }"><t-tag size="small" variant="light">{{ row.fileType }}</t-tag></template> |
|
|
|
<template #fileSize="{ row }"><span style="white-space:nowrap;">{{ formatSize(row.fileSize) }}</span></template> |
|
|
|
<template #categoryId="{ row }"><span>{{ categoryStore.getCategoryName(row.categoryId) }}</span></template> |
|
|
|
<template #categoryId="{ row }"> |
|
|
|
<span class="doc-pos" :title="docPath(row)">{{ docPath(row) }}</span> |
|
|
|
</template> |
|
|
|
<template #status="{ row }"> |
|
|
|
<t-tag size="small" :theme="row.status === 'READY' ? 'success' : row.status === 'PROCESSING' ? 'warning' : 'danger'" |
|
|
|
variant="light">{{ statusLabel(row.status) }}</t-tag> |
|
|
|
@ -189,6 +191,8 @@ const isResizing = ref(false) |
|
|
|
const MIN_TREE_WIDTH = 200 |
|
|
|
const MAX_TREE_WIDTH = 480 |
|
|
|
let resizeCleanup: (() => void) | null = null |
|
|
|
// 目录 id → { name, parentId },位置列据此沿 parentId 回溯拼目录路径 |
|
|
|
const folderMap = ref<Record<string, { name: string; parentId: string | number }>>({}) |
|
|
|
// 表格排序状态(服务端排序) |
|
|
|
const sortInfo = ref<{ sortBy: string; descending: boolean } | null>(null) |
|
|
|
|
|
|
|
@ -232,7 +236,7 @@ const columns = [ |
|
|
|
{ colKey: 'title', title: '标题', width: 220, sorter: true }, |
|
|
|
{ colKey: 'fileType', title: '类型', width: 70, sorter: true }, |
|
|
|
{ colKey: 'fileSize', title: '大小', width: 80, sorter: true }, |
|
|
|
{ colKey: 'categoryId', title: '分类', width: 100 }, |
|
|
|
{ colKey: 'categoryId', title: '位置', width: 200 }, |
|
|
|
{ colKey: 'status', title: '状态', width: 80 }, |
|
|
|
{ colKey: 'enabled', title: '启用', width: 60 }, |
|
|
|
{ colKey: 'chunkCount', title: '分块', width: 60, sorter: true }, |
|
|
|
@ -262,6 +266,20 @@ function getDocTags(doc: any): string[] { |
|
|
|
function statusLabel(s: string) { return s === 'READY' ? '已完成' : s === 'PROCESSING' ? '处理中' : s === 'FAILED' ? '失败' : s } |
|
|
|
function formatSize(b: number) { return b ? formatBytes(b) : '-' } |
|
|
|
|
|
|
|
/** 计算文档所在目录路径(不含分类名);直接挂分类根/无目录时返回「—」 */ |
|
|
|
function docPath(row: any): string { |
|
|
|
let fid = row.folderId != null ? String(row.folderId) : '0' |
|
|
|
const chain: string[] = [] |
|
|
|
let guard = 0 |
|
|
|
while (fid && fid !== '0' && guard++ < 20) { |
|
|
|
const f = folderMap.value[fid] |
|
|
|
if (!f) break |
|
|
|
chain.unshift(f.name) |
|
|
|
fid = String(f.parentId ?? '0') |
|
|
|
} |
|
|
|
return chain.length ? chain.join(' / ') : '—' |
|
|
|
} |
|
|
|
|
|
|
|
// ==================== 搜索防抖 ==================== |
|
|
|
const debouncedLoad = debounce(() => load(1)) |
|
|
|
|
|
|
|
@ -342,6 +360,9 @@ async function loadTreeData() { |
|
|
|
const cats = catRes.success ? (catRes.data || []) : [] |
|
|
|
const folders = folderRes.success ? (folderRes.data || []) : [] |
|
|
|
treeData.value = buildTree(cats, folders) |
|
|
|
// 目录映射:位置列只回溯目录链,无需分类链映射 |
|
|
|
folderMap.value = {} |
|
|
|
for (const f of folders || []) folderMap.value[String(f.id)] = { name: f.name, parentId: f.parentId } |
|
|
|
} catch (e: any) { |
|
|
|
toast('加载目录树失败:' + e.message, 'error') |
|
|
|
} finally { |
|
|
|
@ -626,10 +647,16 @@ loadData() |
|
|
|
|
|
|
|
<style scoped> |
|
|
|
.selected-count { font-size: 12px; font-weight: 600; color: var(--td-text-color-primary); } |
|
|
|
/* 位置列:长路径省略号截断,悬停 title 看全 */ |
|
|
|
.doc-pos { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; } |
|
|
|
|
|
|
|
/* 左右分栏布局 */ |
|
|
|
/* 卡片锁定一屏高度:左侧目录树独立滚动,右侧工具栏固定 + 表格内部滚动 */ |
|
|
|
.doc-list-card { height: 100%; display: flex; flex-direction: column; } |
|
|
|
.doc-list-card { height: 100%; min-height: 0; overflow: hidden; display: flex; flex-direction: column; } |
|
|
|
.doc-list-card :deep(.t-card__header) { flex-shrink: 0; } |
|
|
|
/* 关键修复:TDesign 在 header 与 body 之间有一层 .t-loading__parent,须让它参与 flex 高度链, |
|
|
|
否则 .t-card__body 的 flex:1 不生效,目录树无法在面板内滚动而撑高整页 */ |
|
|
|
.doc-list-card :deep(.t-loading__parent) { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; } |
|
|
|
.doc-list-card :deep(.t-card__body) { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; } |
|
|
|
|
|
|
|
.doc-layout { flex: 1; min-height: 0; display: flex; align-items: stretch; } |
|
|
|
@ -653,7 +680,7 @@ loadData() |
|
|
|
.tree-panel-body { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; } |
|
|
|
.doc-content { flex: 1; min-width: 0; overflow: hidden; padding-left: 16px; display: flex; flex-direction: column; } |
|
|
|
/* 表格宿主:撑满工具栏下方剩余高度,表格 max-height:100% 相对它解析,实现内部滚动与固定表头 */ |
|
|
|
.doc-table-wrap { flex: 1; min-height: 0; } |
|
|
|
.doc-table-wrap { flex: 1; min-height: 0; overflow: hidden; } |
|
|
|
|
|
|
|
.tree-panel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } |
|
|
|
.tree-panel-title { font-size: 13px; font-weight: 600; } |
|
|
|
|