import React, { useState } from 'react'; import { createRoot } from 'react-dom/client'; import { Button, Space, Alert, Spin, Typography, Table } from 'antd'; import axios from 'axios'; import dayjs from 'dayjs'; import { QueryClient, QueryClientProvider, useQuery, } from '@tanstack/react-query'; const { Title } = Typography; // 创建QueryClient实例 const queryClient = new QueryClient(); interface MigrationResponse { success: boolean; error?: string; failedResult?: any; } interface MigrationHistory { id: string; name: string; status: string; timestamp: string; batch: string; } const MigrationsApp: React.FC = () => { const [loading, setLoading] = useState(false); const [migrationResult, setMigrationResult] = useState(null); const { data: historyData, isLoading: isHistoryLoading, error: historyError } = useQuery({ queryKey: ['migrations-history'], queryFn: async () => { const response = await axios.get('/api/migrations/history'); return response.data.history; } }); const runMigrations = async () => { try { setLoading(true); setMigrationResult(null); const response = await axios.get('/api/migrations'); setMigrationResult(response.data); if (response.data.success) { queryClient.invalidateQueries({ queryKey: ['migrations-history'] }); } } catch (error: any) { setMigrationResult({ success: false, error: error.response?.data?.error || '数据库迁移失败', failedResult: error.response?.data?.failedResult }); } finally { setLoading(false); } }; const rollbackMigrations = async (all: boolean) => { try { setLoading(true); setMigrationResult(null); const response = await axios.get(`/api/migrations/rollback?all=${all}`); setMigrationResult(response.data); if (response.data.success) { queryClient.invalidateQueries({ queryKey: ['migrations-history'] }); } } catch (error: any) { setMigrationResult({ success: false, error: error.response?.data?.error || '数据库回滚失败', failedResult: error.response?.data?.failedResult }); } finally { setLoading(false); } }; const columns = [ { title: '迁移名称', dataIndex: 'name', key: 'name', sorter: (a: MigrationHistory, b: MigrationHistory) => a.name.localeCompare(b.name), }, { title: '批次', dataIndex: 'batch', key: 'batch', }, { title: '状态', dataIndex: 'status', key: 'status', render: (status: string) => ( {status === 'completed' ? '已完成' : '失败'} ) }, { title: '时间', dataIndex: 'migration_time', key: 'migration_time', render: (migration_time: string) => dayjs(migration_time).format('YYYY-MM-DD HH:mm:ss') }, ]; return (
数据库迁移管理 {loading && } {migrationResult && ( migrationResult.success ? ( ) : (

{migrationResult.error}

{migrationResult.failedResult && (
                      {JSON.stringify(migrationResult.failedResult, null, 2)}
                    
)} } type="error" showIcon /> ) )} 迁移历史记录 {isHistoryLoading ? ( ) : historyError ? ( ) : ( `共 ${total} 条记录`, }} bordered className="migration-history-table" style={{ marginTop: 16 }} /> )} ); }; // 渲染应用 const root = createRoot(document.getElementById('root') as HTMLElement); root.render( );