优化列表分页和数据加载
This commit is contained in:
@@ -8,6 +8,7 @@ import { DeleteOutlined, FilterOutlined, ImportOutlined, LoginOutlined, MobileOu
|
||||
import {
|
||||
huyaApi,
|
||||
type HuyaAccountItem,
|
||||
type HuyaAccountSummary,
|
||||
type HuyaPasswordLoginBatchItem,
|
||||
type SupportUserItem,
|
||||
} from '../api/modules';
|
||||
@@ -68,6 +69,16 @@ export default function HuyaAccountsPage() {
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
||||
const [batchTagInput, setBatchTagInput] = useState('');
|
||||
const [batchTagVisible, setBatchTagVisible] = useState(false);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [summary, setSummary] = useState<HuyaAccountSummary>({
|
||||
total: 0,
|
||||
assigned_count: 0,
|
||||
unassigned_count: 0,
|
||||
tag_count: 0,
|
||||
password_ready_count: 0,
|
||||
point_count: 0,
|
||||
bound_count: 0,
|
||||
});
|
||||
const [pageSize, setPageSize] = useState(() => {
|
||||
const v = localStorage.getItem('huya_account_page_size');
|
||||
return v ? Number(v) || 20 : 20;
|
||||
@@ -86,14 +97,30 @@ export default function HuyaAccountsPage() {
|
||||
try {
|
||||
const params: { tag?: string } = {};
|
||||
if (tagFilter) params.tag = tagFilter;
|
||||
const data = await huyaApi.listAccounts(params);
|
||||
setAccounts(data);
|
||||
const data = await huyaApi.listAccountsPaged({
|
||||
...params,
|
||||
page: currentPage,
|
||||
page_size: pageSize,
|
||||
search: searchText.trim() || undefined,
|
||||
include_cookie: false,
|
||||
});
|
||||
setAccounts(data.items);
|
||||
setTotal(data.total);
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [tagFilter]);
|
||||
}, [currentPage, pageSize, searchText, tagFilter]);
|
||||
|
||||
const loadSummary = useCallback(async () => {
|
||||
try {
|
||||
const data = await huyaApi.accountsSummary();
|
||||
setSummary(data);
|
||||
} catch {
|
||||
// 统计加载失败时不影响主列表操作。
|
||||
}
|
||||
}, []);
|
||||
|
||||
const loadUsers = useCallback(async () => {
|
||||
try {
|
||||
@@ -115,9 +142,13 @@ export default function HuyaAccountsPage() {
|
||||
|
||||
useEffect(() => {
|
||||
loadAccounts();
|
||||
}, [loadAccounts]);
|
||||
|
||||
useEffect(() => {
|
||||
if (canAssign) loadUsers();
|
||||
loadTags();
|
||||
}, [loadAccounts, canAssign, loadUsers, loadTags]);
|
||||
loadSummary();
|
||||
}, [canAssign, loadUsers, loadTags, loadSummary]);
|
||||
|
||||
const tagColorMap = useMemo(() => {
|
||||
const map: Record<string, string> = {};
|
||||
@@ -127,20 +158,6 @@ export default function HuyaAccountsPage() {
|
||||
return map;
|
||||
}, [tags]);
|
||||
|
||||
const filteredAccounts = useMemo(() => {
|
||||
const s = searchText.trim().toLowerCase();
|
||||
if (!s) return accounts;
|
||||
return accounts.filter((item) => (
|
||||
item.uid.toLowerCase().includes(s) ||
|
||||
item.yyuid.toLowerCase().includes(s) ||
|
||||
item.username.toLowerCase().includes(s) ||
|
||||
item.nickname.toLowerCase().includes(s) ||
|
||||
item.tag.toLowerCase().includes(s) ||
|
||||
item.game_name.toLowerCase().includes(s) ||
|
||||
item.game_phone.toLowerCase().includes(s)
|
||||
));
|
||||
}, [accounts, searchText]);
|
||||
|
||||
const handleImport = async () => {
|
||||
if (!importText.trim()) {
|
||||
message.warning('请先粘贴虎牙 CK');
|
||||
@@ -155,6 +172,7 @@ export default function HuyaAccountsPage() {
|
||||
setImportTag('');
|
||||
loadAccounts();
|
||||
loadTags();
|
||||
loadSummary();
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
} finally {
|
||||
@@ -223,6 +241,7 @@ export default function HuyaAccountsPage() {
|
||||
setSmsState('');
|
||||
loadAccounts();
|
||||
loadTags();
|
||||
loadSummary();
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
} finally {
|
||||
@@ -245,6 +264,7 @@ export default function HuyaAccountsPage() {
|
||||
setPasswordImportTag([]);
|
||||
loadAccounts();
|
||||
loadTags();
|
||||
loadSummary();
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
} finally {
|
||||
@@ -271,6 +291,7 @@ export default function HuyaAccountsPage() {
|
||||
}
|
||||
loadAccounts();
|
||||
loadTags();
|
||||
loadSummary();
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
} finally {
|
||||
@@ -285,6 +306,7 @@ export default function HuyaAccountsPage() {
|
||||
setSelectedRowKeys((prev) => prev.filter((key) => key !== id));
|
||||
loadAccounts();
|
||||
loadTags();
|
||||
loadSummary();
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
}
|
||||
@@ -301,6 +323,7 @@ export default function HuyaAccountsPage() {
|
||||
setSelectedRowKeys([]);
|
||||
loadAccounts();
|
||||
loadTags();
|
||||
loadSummary();
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e));
|
||||
}
|
||||
@@ -345,11 +368,6 @@ export default function HuyaAccountsPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const boundCount = accounts.filter((item) => item.game_name || item.game_channel || item.game_phone).length;
|
||||
const pointCount = accounts.filter((item) => item.points !== null && item.points !== undefined).length;
|
||||
const assignedCount = accounts.filter((item) => item.assigned_to).length;
|
||||
const passwordReadyCount = accounts.filter((item) => item.has_password).length;
|
||||
|
||||
const passwordLoginResultColumns: TableProps<HuyaPasswordLoginBatchItem>['columns'] = [
|
||||
{ title: '账号ID', dataIndex: 'line', width: 80, align: 'center' },
|
||||
{ title: '账号', dataIndex: 'username', width: 160, ellipsis: true },
|
||||
@@ -526,7 +544,10 @@ export default function HuyaAccountsPage() {
|
||||
placeholder="按标签筛选"
|
||||
style={{ width: 150 }}
|
||||
value={tagFilter || undefined}
|
||||
onChange={(value) => setTagFilter(value || '')}
|
||||
onChange={(value) => {
|
||||
setTagFilter(value || '');
|
||||
setCurrentPage(1);
|
||||
}}
|
||||
options={tags.map((tag) => ({ value: tag, label: tag }))}
|
||||
prefix={<FilterOutlined />}
|
||||
/>
|
||||
@@ -586,25 +607,25 @@ export default function HuyaAccountsPage() {
|
||||
|
||||
<Row gutter={12} style={{ marginBottom: 16 }}>
|
||||
<Col xs={24} sm={8}>
|
||||
<Card size="small"><Statistic title="账号总数" value={accounts.length} /></Card>
|
||||
<Card size="small"><Statistic title="账号总数" value={summary.total} /></Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={4}>
|
||||
<Card size="small"><Statistic title="标签数" value={tags.length} /></Card>
|
||||
<Card size="small"><Statistic title="标签数" value={summary.tag_count || tags.length} /></Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={4}>
|
||||
<Card size="small"><Statistic title="已导入密码" value={passwordReadyCount} /></Card>
|
||||
<Card size="small"><Statistic title="已导入密码" value={summary.password_ready_count} /></Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={4}>
|
||||
<Card size="small"><Statistic title="已查积分" value={pointCount} /></Card>
|
||||
<Card size="small"><Statistic title="已查积分" value={summary.point_count} /></Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={4}>
|
||||
<Card size="small"><Statistic title="已绑定信息" value={boundCount} /></Card>
|
||||
<Card size="small"><Statistic title="已绑定信息" value={summary.bound_count} /></Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={4}>
|
||||
<Card size="small"><Statistic title="已分配" value={assignedCount} /></Card>
|
||||
<Card size="small"><Statistic title="已分配" value={summary.assigned_count} /></Card>
|
||||
</Col>
|
||||
<Col xs={24} sm={4}>
|
||||
<Card size="small"><Statistic title="未分配" value={accounts.length - assignedCount} /></Card>
|
||||
<Card size="small"><Statistic title="未分配" value={summary.unassigned_count} /></Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -613,12 +634,23 @@ export default function HuyaAccountsPage() {
|
||||
placeholder="搜索 UID、昵称、标签、游戏名、手机号"
|
||||
allowClear
|
||||
value={searchText}
|
||||
onChange={(e) => setSearchText(e.target.value)}
|
||||
onChange={(e) => {
|
||||
setSearchText(e.target.value);
|
||||
setCurrentPage(1);
|
||||
}}
|
||||
style={{ width: 300 }}
|
||||
prefix={<SearchOutlined />}
|
||||
/>
|
||||
{tags.map((tag) => (
|
||||
<Tag key={tag} color="blue" onClick={() => setSearchText(tag)} style={{ cursor: 'pointer' }}>
|
||||
<Tag
|
||||
key={tag}
|
||||
color="blue"
|
||||
onClick={() => {
|
||||
setSearchText(tag);
|
||||
setCurrentPage(1);
|
||||
}}
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
{tag}
|
||||
</Tag>
|
||||
))}
|
||||
@@ -628,15 +660,17 @@ export default function HuyaAccountsPage() {
|
||||
rowSelection={(canImport || canDelete || canAssign) ? {
|
||||
selectedRowKeys,
|
||||
onChange: (keys) => setSelectedRowKeys(keys),
|
||||
preserveSelectedRowKeys: true,
|
||||
} : undefined}
|
||||
columns={columns}
|
||||
dataSource={filteredAccounts}
|
||||
dataSource={accounts}
|
||||
rowKey="id"
|
||||
loading={loading}
|
||||
size="small"
|
||||
pagination={{
|
||||
current: currentPage,
|
||||
pageSize,
|
||||
total,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
onChange: (page, size) => {
|
||||
|
||||
Reference in New Issue
Block a user