import { useState, useEffect } from 'react'; import { Account, ListAccountsBody, ListAccountsResponse, StatsOverview, BusinessCode, BatchUpdateBody, BatchDeleteBody, ScriptUploadItem } from '@/lib/types'; import { apiClient } from '@/lib/api'; import { toast } from 'sonner'; export interface UseAccountsReturn { // 数据状态 accounts: Account[]; stats: StatsOverview | null; loading: boolean; selectedIds: number[]; // 分页和筛选 pagination: { page: number; pageSize: number; total: number; totalPages: number; }; filters: { platform: string; status: string[]; ownerId: string; search: string; }; sort: { field: keyof Account; order: 'asc' | 'desc'; }; // 操作方法 fetchAccounts: () => Promise; fetchStats: () => Promise; handleFilterChange: (key: string, value: any) => void; handlePageChange: (page: number) => void; handlePageSizeChange: (pageSize: number) => void; handleSortChange: (field: keyof Account, order: 'asc' | 'desc') => void; handleSelectAll: (checked: boolean) => void; handleSelectOne: (id: number, checked: boolean) => void; handleBatchDelete: () => Promise; handleBatchUpdate: (payload: Partial>, targetIds?: number[]) => Promise; handleUploadAccounts: (accounts: ScriptUploadItem[], ownerId: string) => Promise; setSelectedIds: (ids: number[]) => void; } export function useAccounts(): UseAccountsReturn { const [accounts, setAccounts] = useState([]); const [stats, setStats] = useState(null); const [loading, setLoading] = useState(false); const [selectedIds, setSelectedIds] = useState([]); const [pagination, setPagination] = useState({ page: 1, pageSize: 20, total: 0, totalPages: 0 }); const [filters, setFilters] = useState({ platform: '', status: [] as string[], ownerId: '', search: '' }); const [sort, setSort] = useState({ field: 'id' as keyof Account, order: 'desc' as 'asc' | 'desc' }); // 获取统计数据 const fetchStats = async () => { try { const response = await apiClient.getStatsOverview(); if (response.code === BusinessCode.Success && response.data) { setStats(response.data); } } catch (error) { console.error('Failed to fetch stats:', error); toast.error('获取统计数据失败'); } }; // 获取账户列表 const fetchAccounts = async () => { setLoading(true); try { const body: ListAccountsBody = { filters, pagination: { page: pagination.page, pageSize: pagination.pageSize }, sort }; const response = await apiClient.getAccountsList(body); if (response.code === BusinessCode.Success && response.data) { setAccounts(response.data.list); setPagination(prev => ({ ...prev, total: response.data!.pagination.total, totalPages: response.data!.pagination.totalPages })); } } catch (error) { console.error('Failed to fetch accounts:', error); toast.error('获取账户列表失败'); } finally { setLoading(false); } }; // 处理筛选变化 const handleFilterChange = (key: string, value: any) => { setFilters({ ...filters, [key]: value }); setPagination({ ...pagination, page: 1 }); }; // 处理分页 const handlePageChange = (page: number) => { setPagination({ ...pagination, page }); }; // 处理每页大小变化 const handlePageSizeChange = (pageSize: number) => { setPagination({ ...pagination, pageSize, page: 1 }); }; // 处理排序 const handleSortChange = (field: keyof Account, order: 'asc' | 'desc') => { setSort({ field, order }); }; // 处理全选 const handleSelectAll = (checked: boolean) => { if (checked) { setSelectedIds(accounts.map(account => account.id)); } else { setSelectedIds([]); } }; // 处理单选 const handleSelectOne = (id: number, checked: boolean) => { if (checked) { setSelectedIds([...selectedIds, id]); } else { setSelectedIds(selectedIds.filter(selectedId => selectedId !== id)); } }; // 批量删除 const handleBatchDelete = async () => { if (selectedIds.length === 0) return; if (!confirm(`确认删除 ${selectedIds.length} 个账户?`)) return; try { const response = await apiClient.batchDeleteAccounts({ ids: selectedIds }); if (response.code === BusinessCode.Success) { setSelectedIds([]); await fetchAccounts(); await fetchStats(); toast.success(`成功删除 ${response.data?.deletedCount || 0} 个账户`); } } catch (error) { console.error('Failed to delete accounts:', error); toast.error('删除失败,请检查网络连接后重试'); } }; // 批量更新 const handleBatchUpdate = async (payload: Partial>, targetIds?: number[]) => { const idsToUpdate = targetIds || selectedIds; console.log('handleBatchUpdate 被调用, idsToUpdate:', idsToUpdate); console.log('payload:', payload); if (idsToUpdate.length === 0) { console.log('idsToUpdate为空,直接返回'); return; } if (Object.keys(payload).length === 0) { toast.warning('请至少选择一个字段进行更新'); return; } try { console.log('发送批量更新请求...'); const response = await apiClient.batchUpdateAccounts({ ids: idsToUpdate, payload }); console.log('批量更新响应:', response); if (response.code === BusinessCode.Success) { if (!targetIds) { // 只有在没有指定目标ID时才清空选中状态(批量操作时) setSelectedIds([]); } await fetchAccounts(); await fetchStats(); toast.success(`成功更新 ${response.data?.updatedCount || 0} 个账户`); } } catch (error) { console.error('Failed to update accounts:', error); toast.error('更新失败,请检查网络连接后重试'); } }; // 上传账户 const handleUploadAccounts = async (uploadAccounts: ScriptUploadItem[], ownerId: string) => { try { const response = await apiClient.uploadAccounts(uploadAccounts, ownerId); if (response.code === BusinessCode.Success) { await fetchAccounts(); await fetchStats(); toast.success(`成功处理 ${response.data?.processedCount || 0} 个账户 (${response.data?.createdCount || 0} 个新建, ${response.data?.updatedCount || 0} 个更新)`); return; } } catch (error) { console.error('Failed to upload accounts:', error); toast.error('上传失败,请检查网络连接后重试'); } }; // 初始化数据 useEffect(() => { fetchAccounts(); }, [filters, pagination.page, pagination.pageSize, sort]); // 只在开始时获取统计数据 useEffect(() => { fetchStats(); }, []); return { accounts, stats, loading, selectedIds, pagination, filters, sort, fetchAccounts, fetchStats, handleFilterChange, handlePageChange, handlePageSizeChange, handleSortChange, handleSelectAll, handleSelectOne, handleBatchDelete, handleBatchUpdate, handleUploadAccounts, setSelectedIds }; }