import { useState, useEffect, useCallback } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Badge } from '@/components/ui/badge'; import { Checkbox } from '@/components/ui/checkbox'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Plus, Search, Trash2, Pencil, MapPin, CheckCircle2, XCircle, Loader2, } from 'lucide-react'; import { regionApi } from '@/services/api'; import { useConfirm } from '@/components/ui/confirm-dialog'; import { toast } from 'sonner'; const providerNames: Record = { aws: 'AWS', aliyun: '阿里云', tencent: '腾讯云', huawei: '华为云', azure: 'Azure', }; const providerColors: Record = { aws: 'text-orange-400', aliyun: 'text-orange-400', tencent: 'text-blue-400', huawei: 'text-red-400', azure: 'text-blue-400', }; export function RegionManager() { const confirm = useConfirm(); const [regions, setRegions] = useState([]); const [loading, setLoading] = useState(true); const [searchQuery, setSearchQuery] = useState(''); const [selectedProvider, setSelectedProvider] = useState('all'); const [selectedIds, setSelectedIds] = useState([]); const [dialogOpen, setDialogOpen] = useState(false); const [editingItem, setEditingItem] = useState(null); const [submitting, setSubmitting] = useState(false); const [formData, setFormData] = useState({ name: '', code: '', provider: 'aliyun', location: '', status: 'active', endpoint: '', }); const loadData = useCallback(async () => { setLoading(true); try { const res = await regionApi.list(); const items = (res as any)?.list || []; setRegions(items); } catch { setRegions([]); } finally { setLoading(false); } }, []); useEffect(() => { loadData(); }, [loadData]); const filtered = regions.filter(r => { const matchSearch = r.name?.toLowerCase().includes(searchQuery.toLowerCase()) || r.code?.toLowerCase().includes(searchQuery.toLowerCase()); const matchProvider = selectedProvider === 'all' || r.provider === selectedProvider; return matchSearch && matchProvider; }); // 全选 / 单选 // Logan.Li const allSelected = filtered.length > 0 && filtered.every(r => selectedIds.includes(r.id)); const toggleSelectAll = () => { if (allSelected) { setSelectedIds([]); } else { setSelectedIds(filtered.map(r => r.id)); } }; const toggleSelect = (id: number) => { setSelectedIds(prev => prev.includes(id) ? prev.filter(i => i !== id) : [...prev, id]); }; const openCreate = () => { setEditingItem(null); setFormData({ name: '', code: '', provider: 'aliyun', location: '', status: 'active', endpoint: '' }); setDialogOpen(true); }; const openEdit = (item: any) => { setEditingItem(item); setFormData({ name: item.name || '', code: item.code || '', provider: item.provider || 'aliyun', location: item.location || '', status: item.status || 'active', endpoint: item.endpoint || '', }); setDialogOpen(true); }; const handleSubmit = async () => { if (!formData.name.trim() || !formData.code.trim()) return; setSubmitting(true); try { if (editingItem) { await regionApi.update(editingItem.id, formData); } else { await regionApi.create(formData); } setDialogOpen(false); loadData(); } catch { } finally { setSubmitting(false); } }; // 单条删除 // Logan.Li const handleDelete = async (id: number) => { const region = regions.find(r => r.id === id); const ok = await confirm({ title: '删除区域', description: `确定删除「${region?.name || id}」吗?此操作不可撤销。`, confirmText: '删除', variant: 'destructive', }); if (!ok) return; try { await regionApi.delete(id); toast.success('区域已删除'); setSelectedIds(prev => prev.filter(i => i !== id)); loadData(); } catch (e) { console.error('删除区域失败:', e); toast.error('删除失败'); } }; // 批量删除 // Logan.Li const handleBatchDelete = async () => { if (selectedIds.length === 0) return; const ok = await confirm({ title: '批量删除区域', description: `确定删除选中的 ${selectedIds.length} 个区域吗?此操作不可撤销。`, confirmText: '批量删除', variant: 'destructive', }); if (!ok) return; try { await regionApi.batchDelete(selectedIds); toast.success(`已删除 ${selectedIds.length} 个区域`); setSelectedIds([]); loadData(); } catch (e) { console.error('批量删除失败:', e); toast.error('批量删除失败'); } }; return (
{/* Toolbar */}
setSearchQuery(e.target.value)} className="pl-9 h-9 bg-slate-800/50 border-slate-700" />
{/* 批量操作栏 // Logan.Li */} {selectedIds.length > 0 && (
已选择 {selectedIds.length} 个区域
)} {/* Table */} {loading ? (
) : filtered.length === 0 ? (

暂无区域数据

) : (
区域名称 编码 云商 位置 接入端点 状态 操作 {filtered.map((r) => ( toggleSelect(r.id)} className="border-slate-600" /> {r.name} {r.code} {providerNames[r.provider] || r.provider} {r.location || '-'} {r.endpoint || '-'} {r.status === 'active' ? ( 启用 ) : ( 禁用 )}
))}
)} {/* Dialog */} {editingItem ? '编辑区域' : '添加区域'}
setFormData({ ...formData, name: e.target.value })} placeholder="如:华北-北京" className="bg-slate-800/50 border-slate-700" />
setFormData({ ...formData, code: e.target.value })} placeholder="如:cn-north-1" className="bg-slate-800/50 border-slate-700 font-mono" disabled={!!editingItem} />
setFormData({ ...formData, location: e.target.value })} placeholder="如:中国北京" className="bg-slate-800/50 border-slate-700" />
setFormData({ ...formData, endpoint: e.target.value })} placeholder="如:ecs.cn-north-1.aliyuncs.com" className="bg-slate-800/50 border-slate-700 font-mono text-sm" />
); }