import { useState, useEffect } from 'react' import { Users, Trash2, RefreshCw, ChevronLeft, ChevronRight, Key, CheckSquare, Square } from 'lucide-react' import { Card, CardHeader, CardTitle, CardContent, Button } from '../common' interface TeamOwner { id: number email: string account_id: string status: string created_at: string } const statusColors: Record = { valid: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400', registered: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400', pooled: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400', processing: 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400', invalid: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400', used: 'bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400', } const statusLabels: Record = { valid: '有效', registered: '已注册', pooled: '已入库', processing: '处理中', invalid: '无效', used: '已使用', } interface OwnerListProps { onStatsChange?: () => void } export default function OwnerList({ onStatsChange }: OwnerListProps) { const [owners, setOwners] = useState([]) const [total, setTotal] = useState(0) const [loading, setLoading] = useState(false) const [page, setPage] = useState(0) const [filter, setFilter] = useState('') const [selectedIds, setSelectedIds] = useState>(new Set()) const [deleting, setDeleting] = useState(false) const limit = 20 const loadOwners = async () => { setLoading(true) try { const params = new URLSearchParams({ limit: String(limit), offset: String(page * limit), }) if (filter) { params.set('status', filter) } const res = await fetch(`/api/db/owners?${params}`) const data = await res.json() if (data.code === 0) { setOwners(data.data.owners || []) setTotal(data.data.total || 0) } } catch (e) { console.error('Failed to load owners:', e) } finally { setLoading(false) } } useEffect(() => { loadOwners() // 清除选择 setSelectedIds(new Set()) }, [page, filter]) // 单个删除 const handleDelete = async (id: number) => { if (!confirm('确认删除此账号?')) return try { const res = await fetch(`/api/db/owners/delete/${id}`, { method: 'POST' }) const data = await res.json() if (data.code === 0) { loadOwners() onStatsChange?.() } else { alert(data.message || '删除失败') } } catch (e) { console.error('Failed to delete:', e) alert('删除失败') } } // 批量删除 const handleBatchDelete = async () => { if (selectedIds.size === 0) { alert('请先选择要删除的账号') return } if (!confirm(`确认删除选中的 ${selectedIds.size} 个账号?`)) return setDeleting(true) try { const res = await fetch('/api/db/owners/batch-delete', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ids: Array.from(selectedIds) }), }) const data = await res.json() if (data.code === 0) { alert(data.data.message) setSelectedIds(new Set()) loadOwners() onStatsChange?.() } else { alert(data.message || '删除失败') } } catch (e) { console.error('Failed to batch delete:', e) alert('删除失败') } finally { setDeleting(false) } } const handleClearAll = async () => { if (!confirm('确认清空所有账号?此操作不可恢复!')) return try { await fetch('/api/db/owners/clear', { method: 'POST' }) loadOwners() onStatsChange?.() } catch (e) { console.error('Failed to clear:', e) } } const handleClearUsed = async () => { if (!confirm('确认清理所有已使用的母号?')) return try { const res = await fetch('/api/db/owners/clear-used', { method: 'POST' }) const data = await res.json() if (data.code === 0) { alert(data.data.message) loadOwners() onStatsChange?.() } else { alert(data.message || '清理失败') } } catch (e) { console.error('Failed to clear used:', e) alert('清理失败') } } const [refetching, setRefetching] = useState(false) const handleRefetchAccountIds = async () => { if (refetching) return setRefetching(true) try { const res = await fetch('/api/db/owners/refetch-account-ids', { method: 'POST' }) const data = await res.json() if (data.code === 0) { const result = data.data alert(`重新获取完成\n总数: ${result.total}\n成功: ${result.success}\n失败: ${result.fail}`) loadOwners() onStatsChange?.() } else { alert(`操作失败: ${data.message}`) } } catch (e) { console.error('Failed to refetch account ids:', e) alert('操作失败,请查看控制台') } finally { setRefetching(false) } } // 选择逻辑 const toggleSelect = (id: number) => { const newSet = new Set(selectedIds) if (newSet.has(id)) { newSet.delete(id) } else { newSet.add(id) } setSelectedIds(newSet) } const toggleSelectAll = () => { if (selectedIds.size === owners.length) { setSelectedIds(new Set()) } else { setSelectedIds(new Set(owners.map(o => o.id))) } } const isAllSelected = owners.length > 0 && selectedIds.size === owners.length const totalPages = Math.ceil(total / limit) const formatTime = (ts: string) => { try { return new Date(ts).toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', }) } catch { return '' } } return (
母号列表 ({total})
{selectedIds.size > 0 && ( )}
{loading ? ( ) : owners.length === 0 ? ( ) : ( owners.map((owner) => ( )) )}
邮箱 Account ID 状态 创建时间 操作
加载中...
暂无数据
{owner.email} {owner.account_id ? `${owner.account_id.slice(0, 20)}...` : '-'} {statusLabels[owner.status] || owner.status} {formatTime(owner.created_at)}
{/* Pagination */} {totalPages > 1 && (
第 {page + 1} / {totalPages} 页
)}
) }