1111
1212 <!-- 文档列表 -->
1313 <v-card variant =" outlined" >
14- <v-data-table :headers =" headers" :items =" documents" :loading =" loading" :search =" searchQuery" :items-per-page =" 10" >
14+ <v-data-table-server :headers =" headers" :items =" documents" :loading =" loading"
15+ :items-per-page =" pageSize" :page =" page" :items-length =" total"
16+ @update:page =" onPageChange" @update:items-per-page =" onItemsPerPageChange" >
1517 <template #item .doc_name =" { item } " >
1618 <div class =" d-flex align-center gap-2" >
1719 <v-icon :color =" getFileColor(item.file_type)" class =" mr-2" >
5355 <p class =" mt-4 text-medium-emphasis" >{{ t('documents.empty') }}</p >
5456 </div >
5557 </template >
56- </v-data-table >
58+ </v-data-table-server >
5759 </v-card >
5860
5961 <!-- 上传对话框 -->
236238
237239<script setup lang="ts">
238240import TavilyKeyDialog from ' ./TavilyKeyDialog.vue'
239- import { ref , onMounted , onUnmounted , computed } from ' vue'
241+ import { ref , watch , onMounted , onUnmounted , computed } from ' vue'
240242import { useRouter } from ' vue-router'
241243import { configProfileApi , knowledgeApi , providerApi } from ' @/api/v1'
242244import { useModuleI18n } from ' @/i18n/composables'
@@ -256,6 +258,9 @@ const loading = ref(false)
256258const uploading = ref (false )
257259const deleting = ref (false )
258260const documents = ref <any []>([])
261+ const page = ref (1 )
262+ const pageSize = ref (10 )
263+ const total = ref (0 )
259264const searchQuery = ref (' ' )
260265const showUploadDialog = ref (false )
261266const showDeleteDialog = ref (false )
@@ -340,9 +345,15 @@ const headers = [
340345const loadDocuments = async () => {
341346 loading .value = true
342347 try {
343- const response = await knowledgeApi .documents (props .kbId )
348+ const response = await knowledgeApi .documents (props .kbId , {
349+ page: page .value ,
350+ page_size: pageSize .value ,
351+ search: searchQuery .value .trim () || undefined ,
352+ })
344353 if (response .data .status === ' ok' ) {
345- documents .value = response .data .data .items || []
354+ const data = response .data .data
355+ documents .value = data .items || []
356+ total .value = data .total || 0
346357 }
347358 } catch (error ) {
348359 console .error (' Failed to load documents:' , error )
@@ -352,6 +363,18 @@ const loadDocuments = async () => {
352363 }
353364}
354365
366+ // Handle pagination
367+ const onPageChange = (newPage : number ) => {
368+ page .value = newPage
369+ loadDocuments ()
370+ }
371+
372+ const onItemsPerPageChange = (newSize : number ) => {
373+ pageSize .value = newSize
374+ page .value = 1
375+ loadDocuments ()
376+ }
377+
355378// 文件选择
356379const handleFileSelect = (event : Event ) => {
357380 const target = event .target as HTMLInputElement
@@ -591,7 +614,7 @@ const startProgressPolling = (taskId: string) => {
591614 // 移除上传中的占位文档
592615 documents .value = documents .value .filter (doc => doc .taskId !== taskId )
593616
594- // 重新加载文档列表
617+ // Reload current page
595618 await loadDocuments ()
596619 emit (' refresh' )
597620
@@ -684,6 +707,10 @@ const deleteDocument = async () => {
684707 if (response .data .status === ' ok' ) {
685708 showSnackbar (t (' documents.deleteSuccess' ))
686709 showDeleteDialog .value = false
710+ // If current page becomes empty after delete and is not the first page, go back one page
711+ if (documents .value .length === 1 && page .value > 1 ) {
712+ page .value -= 1
713+ }
687714 await loadDocuments ()
688715 emit (' refresh' )
689716 } else {
@@ -782,6 +809,12 @@ const onTavilyKeySet = () => {
782809 checkTavilyConfig ()
783810}
784811
812+ // Reset to page 1 and reload when search text changes
813+ watch (searchQuery , () => {
814+ page .value = 1
815+ loadDocuments ()
816+ })
817+
785818onMounted (() => {
786819 loadDocuments ()
787820 loadLlmProviders ()
0 commit comments