import { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { ArrowLeft, Database, Table2, Terminal, BarChart3, RefreshCw, Search, ChevronRight, FileJson } from 'lucide-react'; import { mongoApi } from '@/api/mongo'; type TabKey = 'collections' | 'documents' | 'cli' | 'stats'; export default function MongoDBDetailPage() { var params = useParams<{ id: string }>(); var navigate = useNavigate(); var instanceId = Number(params.id); var [activeTab, setActiveTab] = useState('collections'); var [databases, setDatabases] = useState([]); var [selectedDb, setSelectedDb] = useState(''); var [collections, setCollections] = useState([]); var [selectedCollection, setSelectedCollection] = useState(''); var [collectionStats, setCollectionStats] = useState(null); var [documents, setDocuments] = useState([]); var [docFilter, setDocFilter] = useState('{}'); var [docCount, setDocCount] = useState(0); var [docPage, setDocPage] = useState(0); var [pageSize] = useState(20); var [cmdInput, setCmdInput] = useState(''); var [cmdOutput, setCmdOutput] = useState([]); var [loading, setLoading] = useState(false); var [error, setError] = useState(''); var tabs: { key: TabKey; label: string; icon: React.ElementType }[] = [ { key: 'collections', label: '集合管理', icon: Database }, { key: 'documents', label: '文档浏览', icon: Table2 }, { key: 'cli', label: '查询控制台', icon: Terminal }, { key: 'stats', label: '统计信息', icon: BarChart3 }, ]; useEffect(function () { setLoading(true); mongoApi.getDatabases(instanceId).then(function (res: any) { var dbs = res.databases || res || []; setDatabases(Array.isArray(dbs) ? dbs : []); if (dbs.length > 0 && !selectedDb) { setSelectedDb(typeof dbs[0] === 'string' ? dbs[0] : (dbs[0].name || '')); } }).catch(function () { setDatabases([]); }).finally(function () { setLoading(false); }); }, [instanceId]); useEffect(function () { if (!selectedDb) { setCollections([]); return; } setLoading(true); mongoApi.getCollections(instanceId, selectedDb).then(function (res: any) { var cols = res.collections || res || []; setCollections(Array.isArray(cols) ? cols : []); }).catch(function () { setCollections([]); }).finally(function () { setLoading(false); }); }, [instanceId, selectedDb]); useEffect(function () { if (!selectedCollection || !selectedDb) { setCollectionStats(null); return; } mongoApi.getCollectionStats(instanceId, selectedCollection, selectedDb).then(function (res: any) { setCollectionStats(res || null); }).catch(function () { setCollectionStats(null); }); }, [instanceId, selectedDb, selectedCollection]); var fetchDocuments = function () { if (!selectedCollection || !selectedDb) return; setLoading(true); setError(''); try { var filterObj = JSON.parse(docFilter); mongoApi.query(instanceId, { database: selectedDb, collection: selectedCollection, operation: 'find', filter: filterObj, limit: pageSize, skip: docPage * pageSize, }).then(function (res: any) { var result = res.result || res; setDocuments(Array.isArray(result) ? result : []); setDocCount(Array.isArray(result) ? result.length : 0); }).catch(function (err: any) { setError(err.response ? err.response.data ? err.response.data.detail : '查询失败' : '查询失败'); setDocuments([]); }).finally(function () { setLoading(false); }); } catch (e) { setError('JSON 格式错误'); setLoading(false); } }; var handleCmdExecute = function () { if (!cmdInput.trim()) return; setCmdOutput(function (prev) { return [...prev, '> ' + cmdInput]; }); setLoading(true); try { var queryObj = JSON.parse(cmdInput); mongoApi.query(instanceId, queryObj).then(function (res: any) { var result = res.result || res; setCmdOutput(function (prev) { return [...prev, JSON.stringify(result, null, 2)]; }); }).catch(function (err: any) { setCmdOutput(function (prev) { return [...prev, '错误: ' + (err.response ? err.response.data ? err.response.data.detail : err.message : err.message)]; }); }).finally(function () { setLoading(false); }); } catch (e) { setCmdOutput(function (prev) { return [...prev, '错误: JSON 格式不正确']; }); setLoading(false); } setCmdInput(''); }; var handleSelectCollection = function (col: string) { setSelectedCollection(col); setActiveTab('documents'); setDocPage(0); setDocuments([]); }; var formatSize = function (bytes: number) { if (!bytes || bytes === 0) return '0 B'; var units = ['B', 'KB', 'MB', 'GB']; var i = 0; while (bytes >= 1024 && i < units.length - 1) { bytes /= 1024; i++; } return bytes.toFixed(1) + ' ' + units[i]; }; return (

MongoDB 实例 #{instanceId}

数据库管理
{tabs.map(function (tab) { var Icon = tab.icon; var isActive = activeTab === tab.key; return ( ); })}
数据库: {selectedDb && ( {collections.length} 个集合 )}
{activeTab === 'collections' && (
{databases.length === 0 && !loading && (

暂无数据库,请确认连接状态

)} {collections.length > 0 && (
{collections.map(function (col: any) { var name = typeof col === 'string' ? col : (col.name || col.collectionName || ''); var colType = typeof col === 'string' ? 'collection' : (col.type || 'collection'); return ( ); })}
集合名称 类型 操作
{name}
{colType}
)} {collections.length === 0 && selectedDb && !loading && (

该数据库中暂无集合

)}
)} {activeTab === 'documents' && (
{!selectedCollection ? (

请从集合管理中选择一个集合

) : (
筛选:
集合: {selectedCollection} {docCount > 0 && | 返回 {docCount} 条文档}
{error && (
{error}
)} {documents.length > 0 ? (
{Object.keys(documents[0] || {}).map(function (key) { return ; })} {documents.map(function (doc, idx) { return ( {Object.keys(documents[0] || {}).map(function (key) { var val = doc[key]; var display = typeof val === 'object' ? JSON.stringify(val) : String(val == null ? 'null' : val); return ; })} ); })}
{key}
{display}
) : ( !loading && !error && (
点击"查询"按钮加载文档
) )} {documents.length >= pageSize && (
第 {docPage + 1} 页
)}
)}
)} {activeTab === 'cli' && (
输入 JSON 格式的查询命令(需含 collection、operation 字段)
{cmdOutput.map(function (line, idx) { return
{line}
; })} {cmdOutput.length === 0 && 等待输入查询命令...}
)} {activeTab === 'stats' && (
{!selectedCollection ? (

请从集合管理中选择一个集合查看统计

) : collectionStats ? (

集合: {selectedCollection}

{[ { label: '命名空间', value: collectionStats.ns || '-' }, { label: '文档数量', value: (collectionStats.count || 0).toLocaleString() }, { label: '数据大小', value: formatSize(collectionStats.size || 0) }, { label: '平均文档大小', value: formatSize(collectionStats.avgObjSize || 0) }, { label: '索引大小', value: formatSize(collectionStats.totalIndexSize || 0) }, { label: '索引数量', value: collectionStats.nindexes || 0 }, { label: '存储大小', value: formatSize(collectionStats.storageSize || 0) }, { label: '是否固定集合', value: collectionStats.capped ? '是' : '否' }, ].map(function (item) { return (
{item.label} {item.value}
); })}
) : !loading ? (
无法获取统计信息
) : null}
)}
); }