fix: replace all any types with proper interfaces
All checks were successful
Deploy Admin Frontend / build-and-deploy (push) Successful in 8s

This commit is contained in:
wangdl 2026-06-19 15:36:55 +08:00
parent d07bca4897
commit 9e36c10d31

View File

@ -8,6 +8,43 @@ import dayjs from 'dayjs'
const { Title } = Typography const { Title } = Typography
// ── Types ──
interface KnowledgeSourceItem {
id: string
userId?: string
knowledgeBaseId?: string
originalFilename?: string
title?: string
mimeType?: string
sizeBytes?: number
textLength?: number
parseStatus?: string
indexStatus?: string
createdAt?: string
userName?: string
kbName?: string
}
interface PaginatedSources {
items: KnowledgeSourceItem[]
total: number
page: number
limit: number
}
interface KnowledgeBaseItem {
id: string
title?: string
name?: string
}
interface PaginatedKnowledgeBases {
items: KnowledgeBaseItem[]
}
// ── Labels ──
const mimeLabels: Record<string, string> = { const mimeLabels: Record<string, string> = {
'text/plain': '文本', 'text/markdown': 'Markdown', 'text/plain': '文本', 'text/markdown': 'Markdown',
'application/pdf': 'PDF', 'application/epub+zip': 'EPUB', 'application/pdf': 'PDF', 'application/epub+zip': 'EPUB',
@ -25,6 +62,8 @@ const indexStatusColors: Record<string, string> = {
pending: 'default', indexing: 'processing', completed: 'green', failed: 'red', pending: 'default', indexing: 'processing', completed: 'green', failed: 'red',
} }
// ── Component ──
export default function KnowledgeSourcesPage() { export default function KnowledgeSourcesPage() {
const [page, setPage] = useState(1) const [page, setPage] = useState(1)
const [kbFilter, setKbFilter] = useState<string>() const [kbFilter, setKbFilter] = useState<string>()
@ -38,24 +77,23 @@ export default function KnowledgeSourcesPage() {
if (kbFilter) p.set('knowledgeBaseId', kbFilter) if (kbFilter) p.set('knowledgeBaseId', kbFilter)
if (statusFilter) p.set('parseStatus', statusFilter) if (statusFilter) p.set('parseStatus', statusFilter)
if (search) p.set('search', search) if (search) p.set('search', search)
return api.get<any>(`/admin-api/knowledge-bases/all-sources?${p.toString()}`) return api.get<PaginatedSources>(`/admin-api/knowledge-bases/all-sources?${p.toString()}`)
}, },
staleTime: 10_000, staleTime: 10_000,
}) })
// KB list for filter dropdown
const { data: kbList } = useQuery({ const { data: kbList } = useQuery({
queryKey: ['admin', 'kb-list'], queryKey: ['admin', 'kb-list'],
queryFn: () => api.get<{ items: any[] }>('/admin-api/knowledge-bases?limit=200').then(d => d?.items || []), queryFn: () => api.get<PaginatedKnowledgeBases>('/admin-api/knowledge-bases?limit=200').then(d => d.items),
staleTime: 60_000, staleTime: 60_000,
}) })
const columns = [ const columns = [
{ title: '文件名', dataIndex: 'originalFilename', width: 220, ellipsis: true, render: (v: string, r: any) => 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: any) => v || r.knowledgeBaseId }, { title: '知识库', dataIndex: 'kbName', width: 140, ellipsis: true, render: (v: string, r: KnowledgeSourceItem) => v || r.knowledgeBaseId },
{ 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) => v || '-' }, { title: '字数', dataIndex: 'textLength', width: 70, render: (v: number | undefined) => v != null ? v : '-' },
{ {
title: '解析', dataIndex: 'parseStatus', width: 90, title: '解析', dataIndex: 'parseStatus', width: 90,
render: (v: string) => <Tag color={parseStatusColors[v] || 'default'}>{parseStatusLabels[v] || v}</Tag>, render: (v: string) => <Tag color={parseStatusColors[v] || 'default'}>{parseStatusLabels[v] || v}</Tag>,
@ -75,12 +113,12 @@ export default function KnowledgeSourcesPage() {
onChange={e => { setSearch(e.target.value); setPage(1) }} style={{ width: 200 }} /> onChange={e => { setSearch(e.target.value); setPage(1) }} style={{ width: 200 }} />
<Select placeholder="知识库筛选" allowClear value={kbFilter} <Select placeholder="知识库筛选" allowClear value={kbFilter}
onChange={v => { setKbFilter(v); setPage(1) }} style={{ width: 160 }} onChange={v => { setKbFilter(v); setPage(1) }} style={{ width: 160 }}
options={(kbList || []).map((kb: any) => ({ value: kb.id, label: kb.title || kb.name || kb.id }))} /> options={(kbList || []).map(kb => ({ value: kb.id, label: kb.title || kb.name || kb.id }))} />
<Select placeholder="解析状态" allowClear value={statusFilter} <Select placeholder="解析状态" allowClear value={statusFilter}
onChange={v => { setStatusFilter(v); setPage(1) }} style={{ width: 130 }} onChange={v => { setStatusFilter(v); setPage(1) }} style={{ width: 130 }}
options={Object.entries(parseStatusLabels).map(([v, l]) => ({ value: v, label: l }))} /> options={Object.entries(parseStatusLabels).map(([v, l]) => ({ value: v, label: l }))} />
</Space> </Space>
<Table dataSource={data?.items || []} columns={columns} rowKey="id" loading={isLoading} <Table<KnowledgeSourceItem> dataSource={data?.items || []} columns={columns} rowKey="id" loading={isLoading}
pagination={{ current: page, defaultPageSize: 20, total: data?.total || 0, onChange: setPage }} pagination={{ current: page, defaultPageSize: 20, total: data?.total || 0, onChange: setPage }}
size="small" scroll={{ x: 1000 }} /> size="small" scroll={{ x: 1000 }} />
</div> </div>