1
This commit is contained in:
@@ -12,6 +12,10 @@ export function deleteDocument(id) {
|
||||
return request.post('/document/delete', { id })
|
||||
}
|
||||
|
||||
export function getDocumentDetail(id) {
|
||||
return request.get('/document/detail', { params: { id } })
|
||||
}
|
||||
|
||||
export function reembedDocument(id) {
|
||||
return request.post('/document/reembed', { id })
|
||||
}
|
||||
|
||||
@@ -39,25 +39,38 @@
|
||||
<el-pagination class="dd-page-bar" layout="total, prev, pager, next" :total="total"
|
||||
:page-size="pageSize" v-model:current-page="page" @current-change="load" />
|
||||
|
||||
<el-drawer v-model="chunkDrawer" :title="chunkDrawerTitle" size="55%">
|
||||
<div class="chunk-toolbar">
|
||||
<el-input v-model="chunkKeyword" placeholder="搜索分块内容" clearable style="width: 240px" @change="loadChunks" />
|
||||
<el-drawer v-model="chunkDrawer" :title="chunkDrawerTitle" size="70%" class="chunk-drawer">
|
||||
<div class="drawer-split">
|
||||
<div class="drawer-left">
|
||||
<div class="pane-title">原始内容({{ rawContent.length }} 字)</div>
|
||||
<div v-loading="rawLoading" class="raw-scroll">
|
||||
<pre v-if="rawContent" class="raw-content">{{ rawContent }}</pre>
|
||||
<div v-else-if="!rawLoading" class="raw-empty">{{ rawEmptyTip }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="drawer-right">
|
||||
<div class="chunk-toolbar">
|
||||
<el-input v-model="chunkKeyword" placeholder="搜索分块内容" clearable style="width: 240px" @change="loadChunks" />
|
||||
</div>
|
||||
<div class="chunk-table-scroll">
|
||||
<el-table :data="chunks" v-loading="chunkLoading" size="small">
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column label="内容" min-width="300">
|
||||
<template #default="{ row }">
|
||||
<div class="chunk-content">{{ row.content }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="110" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="editChunk(row)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-pagination class="dd-page-bar" layout="total, prev, pager, next" :total="chunkTotal"
|
||||
:page-size="chunkPageSize" v-model:current-page="chunkPage" @current-change="loadChunks" />
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="chunks" v-loading="chunkLoading" size="small">
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column label="内容" min-width="300">
|
||||
<template #default="{ row }">
|
||||
<div class="chunk-content">{{ row.content }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="110" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="editChunk(row)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination class="dd-page-bar" layout="total, prev, pager, next" :total="chunkTotal"
|
||||
:page-size="chunkPageSize" v-model:current-page="chunkPage" @current-change="loadChunks" />
|
||||
</el-drawer>
|
||||
|
||||
<el-dialog v-model="editDialog" title="编辑分块" width="640px">
|
||||
@@ -79,6 +92,7 @@ import { ArrowLeft, UploadFilled } from '@element-plus/icons-vue'
|
||||
import { listDatasets } from '../api/dataset.js'
|
||||
import { listDocuments, uploadDocument, deleteDocument, reembedDocument, retryParseTask } from '../api/document.js'
|
||||
import { listChunks, updateChunk } from '../api/chunk.js'
|
||||
import { getDocumentDetail } from '../api/document.js'
|
||||
|
||||
const route = useRoute()
|
||||
const datasetId = computed(() => Number(route.params.id))
|
||||
@@ -93,6 +107,9 @@ const uploading = ref(false)
|
||||
|
||||
const chunkDrawer = ref(false)
|
||||
const chunkDrawerTitle = ref('')
|
||||
const rawContent = ref('')
|
||||
const rawLoading = ref(false)
|
||||
const rawEmptyTip = ref('')
|
||||
const chunks = ref([])
|
||||
const chunkTotal = ref(0)
|
||||
const chunkPage = ref(1)
|
||||
@@ -199,8 +216,8 @@ async function reembed(row) {
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
await reembedDocument(row.id)
|
||||
ElMessage.success('重新向量化完成')
|
||||
const d = await reembedDocument(row.id)
|
||||
ElMessage.success(`已重新向量化 ${d.count} 个分块`)
|
||||
}
|
||||
|
||||
async function openChunks(row) {
|
||||
@@ -209,9 +226,27 @@ async function openChunks(row) {
|
||||
chunkDrawer.value = true
|
||||
chunkPage.value = 1
|
||||
chunkKeyword.value = ''
|
||||
rawContent.value = ''
|
||||
await loadRaw()
|
||||
await loadChunks()
|
||||
}
|
||||
|
||||
// 加载文档原始全文(存量文档后端会现场解析回填)
|
||||
async function loadRaw() {
|
||||
if (!currentDoc) return
|
||||
rawLoading.value = true
|
||||
rawEmptyTip.value = ''
|
||||
try {
|
||||
const d = await getDocumentDetail(currentDoc.id)
|
||||
rawContent.value = (d.document && d.document.content) || ''
|
||||
if (!rawContent.value) rawEmptyTip.value = '该文档无原始内容'
|
||||
} catch (e) {
|
||||
rawEmptyTip.value = '原始内容加载失败:' + (e.message || e)
|
||||
} finally {
|
||||
rawLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function loadChunks() {
|
||||
if (!currentDoc) return
|
||||
chunkLoading.value = true
|
||||
@@ -265,15 +300,70 @@ async function saveChunk() {
|
||||
margin-top: 10px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.chunk-drawer :deep(.el-drawer__body) {
|
||||
overflow: hidden;
|
||||
}
|
||||
.drawer-split {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
height: 100%;
|
||||
}
|
||||
.drawer-left,
|
||||
.drawer-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
.drawer-left {
|
||||
flex: 0 0 42%;
|
||||
border-right: 1px solid #ebeef5;
|
||||
padding-right: 16px;
|
||||
}
|
||||
.drawer-right {
|
||||
flex: 1;
|
||||
}
|
||||
.pane-title {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.raw-scroll {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
.raw-content {
|
||||
margin: 0;
|
||||
padding: 10px 12px;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
background: #f8f8f8;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
color: #303133;
|
||||
}
|
||||
.raw-empty {
|
||||
padding: 12px;
|
||||
font-size: 13px;
|
||||
color: #909399;
|
||||
}
|
||||
.chunk-toolbar {
|
||||
margin-bottom: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.chunk-table-scroll {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
.chunk-content {
|
||||
max-height: 60px;
|
||||
overflow: hidden;
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
.edit-tip {
|
||||
margin-top: 6px;
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
</el-select>
|
||||
<div class="ds-tip">标题分块保留标题与段落结构;递归字符分块按分隔符切分,通用文本;语义分块按语义相似度切分,质量更高但解析更慢,且需绑定向量模型</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="分块大小">
|
||||
<el-form-item :label="form.chunk_strategy === 'semantic' ? '上限大小' : '分块大小'">
|
||||
<el-input-number v-model="form.chunk_size" :min="50" :max="5000" :step="50" style="width: 100%" />
|
||||
<div class="ds-tip">{{ form.chunk_strategy === 'semantic' ? '语义分块按句子相似度切分,此值决定最小分块大小(低于该值的候选块会继续合并)' : '每块最大字数,超长段落自动按句号/换行切分' }}</div>
|
||||
<div class="ds-tip">{{ form.chunk_strategy === 'semantic' ? '语义分块按句子相似度切分,此值为安全上限(max_chunk_size),超过上限的块会再切分;语义分块不支持重叠' : '每块最大字数,超长段落自动按句号/换行切分' }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.chunk_strategy !== 'semantic'" label="重叠字数">
|
||||
<el-input-number v-model="form.chunk_overlap" :min="0" :max="500" :step="10" style="width: 100%" />
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
<el-table-column prop="name" label="名称" min-width="140" />
|
||||
<el-table-column prop="model_name" label="模型" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column prop="endpoint_url" label="接口地址" min-width="220" show-overflow-tooltip />
|
||||
<el-table-column prop="dimension" label="维度" width="80">
|
||||
<template #default="{ row }">{{ row.model_type === 'embedding' ? row.dimension : '-' }}</template>
|
||||
<el-table-column v-if="modelType === 'embedding'" prop="dimension" label="维度" width="80">
|
||||
<template #default="{ row }">{{ row.dimension }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="默认" width="110" align="center">
|
||||
<template #default="{ row }">
|
||||
|
||||
Reference in New Issue
Block a user