feat: KnowledgeSources 页面增加文件存在性校验列
All checks were successful
Deploy Admin Frontend / build-and-deploy (push) Successful in 13s

This commit is contained in:
wangdl 2026-07-04 12:15:05 +08:00
parent 64da1b1c0e
commit 12ca018ead
2 changed files with 20 additions and 1 deletions

View File

@ -13,4 +13,5 @@ export const knowledgeAPI = {
sourceReferences(sourceId: string) { return api.get<SourceReference[]>(`/admin-api/knowledge-bases/sources/${sourceId}/references`) }, sourceReferences(sourceId: string) { return api.get<SourceReference[]>(`/admin-api/knowledge-bases/sources/${sourceId}/references`) },
allSources(params: string) { return api.get<PaginatedResult<KnowledgeSource>>(`/admin-api/knowledge-bases/all-sources?${params}`) }, allSources(params: string) { return api.get<PaginatedResult<KnowledgeSource>>(`/admin-api/knowledge-bases/all-sources?${params}`) },
search(params: string) { return api.get<PaginatedResult<KnowledgeBase>>(`/admin-api/knowledge-bases?${params}`) }, search(params: string) { return api.get<PaginatedResult<KnowledgeBase>>(`/admin-api/knowledge-bases?${params}`) },
verifyFiles() { return api.get<{ total: number; missing: number; missingFiles: { sourceId: string; filename: string; objectKey: string; exists: boolean }[] }>('/admin-api/knowledge-bases/verify-files') },
} }

View File

@ -1,5 +1,5 @@
import { useState } from 'react' import { useState } from 'react'
import { Table, Tag, Space, Input, Select, Typography } from 'antd' import { Table, Tag, Space, Input, Select, Typography, Tooltip } from 'antd'
import { SearchOutlined } from '@ant-design/icons' import { SearchOutlined } from '@ant-design/icons'
import { useQuery } from '@tanstack/react-query' import { useQuery } from '@tanstack/react-query'
import { knowledgeAPI } from '@/api' import { knowledgeAPI } from '@/api'
@ -71,9 +71,27 @@ export default function KnowledgeSourcesPage() {
staleTime: 60_000, staleTime: 60_000,
}) })
const { data: fileCheck } = useQuery({
queryKey: ['admin', 'verify-files'],
queryFn: () => knowledgeAPI.verifyFiles(),
staleTime: 30_000,
refetchOnMount: true,
})
const missingMap = new Set((fileCheck?.missingFiles || []).map(f => f.sourceId))
const columns = [ const columns = [
{ title: '文件名', dataIndex: 'originalFilename', width: 220, ellipsis: true, render: (v: string, r: KnowledgeSourceItem) => v || r.title || '-' }, { title: '文件名', dataIndex: 'originalFilename', width: 220, ellipsis: true, render: (v: string, r: KnowledgeSourceItem) => v || r.title || '-' },
{ title: '知识库', dataIndex: 'kbName', width: 140, ellipsis: true, render: (v: string, r: KnowledgeSourceItem) => v || r.knowledgeBaseId }, { title: '知识库', dataIndex: 'kbName', width: 140, ellipsis: true, render: (v: string, r: KnowledgeSourceItem) => v || r.knowledgeBaseId },
{
title: '文件', dataIndex: 'id', width: 60,
render: (id: string) => {
if (!fileCheck) return null
return missingMap.has(id)
? <Tooltip title="文件丢失,需重新上传"><Tag color="red"></Tag></Tooltip>
: <Tag color="green"></Tag>
},
},
{ title: '类型', dataIndex: 'mimeType', width: 80, render: (v: string) => mimeLabels[v] || v?.split('/').pop() || '-' }, { title: '类型', dataIndex: 'mimeType', width: 80, render: (v: string) => mimeLabels[v] || v?.split('/').pop() || '-' },
{ title: '大小', dataIndex: 'sizeBytes', width: 80, render: (v: number) => v ? `${(v / 1024).toFixed(1)} KB` : '-' }, { title: '大小', dataIndex: 'sizeBytes', width: 80, render: (v: number) => v ? `${(v / 1024).toFixed(1)} KB` : '-' },
{ title: '字数', dataIndex: 'textLength', width: 70, render: (v: number | undefined) => v != null ? v : '-' }, { title: '字数', dataIndex: 'textLength', width: 70, render: (v: number | undefined) => v != null ? v : '-' },