admin-projects/src/pages/VectorAdmin.tsx
WangDL f6917d63d3
Some checks failed
Deploy Admin Frontend / build-and-deploy (push) Failing after 7s
feat: M1-01~03 admin pages — AI Gateway, Vector, Events deepening
M1-01 AI Gateway:
- Tab-based layout: Overview, Routes CRUD, Provider toggle, Fallback logs

M1-02 Vector:
- New VectorAdmin page: collection stats, info panel, reindex trigger
- Route /vector + menu entry under 系统运维

M1-03 Events:
- Tab-based layout: Queue overview (with batch retry), Task statistics
- Worker status panel, 16 task type configs table

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 10:18:22 +08:00

83 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useQuery, useQueryClient } from '@tanstack/react-query'
import { Card, Row, Col, Statistic, Button, Typography, Descriptions, App } from 'antd'
import { ReloadOutlined, DatabaseOutlined, NodeIndexOutlined } from '@ant-design/icons'
import { api } from '@/services/http-client'
const { Title } = Typography
export default function VectorAdminPage() {
const qc = useQueryClient()
const { message } = App.useApp()
const { data: coll, isLoading: collLoading } = useQuery({
queryKey: ['vector', 'collection'],
queryFn: (): Promise<any> => api.get('/admin-api/vector/collection'),
staleTime: 30_000,
})
const { data: count } = useQuery({
queryKey: ['vector', 'count'],
queryFn: (): Promise<any> => api.get('/admin-api/vector/count'),
staleTime: 30_000,
})
const handleReindex = async () => {
try {
await api.post('/admin-api/vector/reindex')
message.success('索引重建已提交')
qc.invalidateQueries({ queryKey: ['vector'] })
} catch {
message.error('操作失败')
}
}
return (
<div>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>
<Title level={5} style={{ margin: 0 }}><DatabaseOutlined /> </Title>
<Button icon={<ReloadOutlined />} onClick={() => qc.invalidateQueries({ queryKey: ['vector'] })}></Button>
</div>
<Row gutter={[16, 16]} style={{ marginBottom: 16 }}>
<Col span={6}>
<Card size="small"><Statistic title="向量总数" value={count?.count ?? 0} loading={collLoading} suffix="条" /></Card>
</Col>
<Col span={6}>
<Card size="small"><Statistic title="向量维度" value={coll?.vectorSize || 1024} /></Card>
</Col>
<Col span={6}>
<Card size="small"><Statistic title="距离度量" value={coll?.distance || 'Cosine'} /></Card>
</Col>
<Col span={6}>
<Card size="small"><Statistic title="状态" value={coll?.status || '-'} valueStyle={{ color: coll?.status === 'green' ? '#52c41a' : '#faad14' }} /></Card>
</Col>
</Row>
<Row gutter={[16, 16]}>
<Col span={16}>
<Card size="small" title="Collection 信息">
<Descriptions column={2} size="small" bordered>
<Descriptions.Item label="名称">{coll?.name || 'zhixi_chunks'}</Descriptions.Item>
<Descriptions.Item label="向量维度">{coll?.vectorSize || 1024}</Descriptions.Item>
<Descriptions.Item label="距离度量">{coll?.distance || 'Cosine'}</Descriptions.Item>
<Descriptions.Item label="向量总数">{count?.count ?? 0}</Descriptions.Item>
<Descriptions.Item label="索引算法">HNSW (m=16, ef_construct=100)</Descriptions.Item>
<Descriptions.Item label="Payload 索引">userId (keyword), knowledgeBaseId (keyword), deleted (bool)</Descriptions.Item>
</Descriptions>
</Card>
</Col>
<Col span={8}>
<Card size="small" title="索引操作">
<Button icon={<NodeIndexOutlined />} block onClick={handleReindex} style={{ marginBottom: 8 }}>
</Button>
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
线
</Typography.Text>
</Card>
</Col>
</Row>
</div>
)
}