feat(huya): 精英宝典账号表格补充浏览器分页状态

This commit is contained in:
yml2213
2026-11-09 11:19:12 +08:00
parent 070a7954e7
commit 84883015b4
+14 -1
View File
@@ -22,6 +22,7 @@ const SCOPE = 'elite' as const;
const ACT_ID = 25135;
const DEFAULT_SID = '2203';
const LAYOUT_KEY = 'huya_elite_layout_mode';
const PAGE_SIZE_KEY = 'huya_elite_page_size';
// 开通/充值:记住上次选的商品与数量(浏览器本地,换台机器不影响)
const RECHARGE_SPU_KEY = 'huya_elite_recharge_spu';
const RECHARGE_COUNT_KEY = 'huya_elite_recharge_count';
@@ -63,6 +64,12 @@ function savedInterval(): number {
return Number.isInteger(value) && value >= 5 && value <= 60 ? value : 15;
}
/** 账号表格每页条数:用户改过一次后就记住,默认与账号管理页一致为 20。 */
function savedPageSize(): number {
const value = Number(localStorage.getItem(PAGE_SIZE_KEY));
return Number.isInteger(value) && value > 0 && value <= 200 ? value : 20;
}
/** 上次选的开通商品(列表里已不存在时会自动回落到第一个)。 */
function savedRechargeSpu(): string {
return localStorage.getItem(RECHARGE_SPU_KEY) || '';
@@ -178,6 +185,8 @@ export default function HuyaElitePage() {
// 开通/充值数量:一个账号按这个份数下单(后端 payload.count,1~10000),记住上次填的值
const [rechargeCount, setRechargeCount] = useState(savedRechargeCount);
const [search, setSearch] = useState('');
const [pageSize, setPageSize] = useState(savedPageSize);
const [currentPage, setCurrentPage] = useState(1);
const [loading, setLoading] = useState(false);
const [starting, setStarting] = useState(false);
const [concurrency, setConcurrency] = useState(3);
@@ -390,6 +399,10 @@ export default function HuyaElitePage() {
const value = search.trim().toLowerCase();
return accounts.filter((item) => !value || [item.uid, item.nickname, item.username, item.tag, item.game_name, item.game_phone].some((v) => String(v || '').toLowerCase().includes(value)));
}, [accounts, search]);
useEffect(() => {
const totalPages = Math.max(1, Math.ceil(filteredAccounts.length / pageSize));
if (currentPage > totalPages) setCurrentPage(totalPages);
}, [currentPage, filteredAccounts.length, pageSize]);
const filteredGoods = useMemo(() => goods.map((item) => ({ ...item, label: `${item.name} / ${item.price ?? '-'}分 / ${item.remain_text || '动态库存'}` })), [goods]);
// 精英宝典:通常只有一个商品;换过 SKU 或已下线时回落到当前的第一个(并记住回落结果)
useEffect(() => {
@@ -465,7 +478,7 @@ export default function HuyaElitePage() {
</Space>
);
const accountsBody = <><Space style={{ marginBottom: 8, width: '100%', justifyContent: 'space-between' }} wrap><Input size="small" allowClear prefix={<SearchOutlined />} placeholder="搜索账号/昵称/游戏名/手机号" value={search} onChange={(event) => setSearch(event.target.value)} style={{ width: 240 }} /><Space><Button size="small" icon={<ImportOutlined />} onClick={() => setImportOpen(true)}>导入账号</Button>{canImport && <Button size="small" icon={<ImportOutlined />} onClick={() => setCkImportOpen(true)}>导入外部 CK</Button>}{selectedIds.length > 0 && <Button size="small" danger onClick={() => void saveAccounts(accounts.map((item) => item.id).filter((id) => !selectedIds.includes(id)))}>移出选中</Button>}</Space></Space><div className="huya-account-table"><Table rowKey="id" size="small" loading={loading} tableLayout="fixed" rowSelection={{ selectedRowKeys: selectedIds, onChange: (keys) => setSelectedIds(keys.map(Number)) }} columns={accountColumns} dataSource={filteredAccounts} locale={{ emptyText: '工作台暂无账号,点击右上角「导入账号」添加' }} pagination={{ pageSize: 20, showSizeChanger: true, showTotal: (total) => `共 ${total} 条` }} scroll={{ y: 'calc(100vh - 300px)' }} onRow={(row) => ({ onClick: () => { const task = latestTask(tasks, row.id); if (!task?.result) return; if (task.task_type === 'get_bind_qr') void openQrTask(task); else if (task.task_type === 'create_recharge_order') openPayTasks(task.batch_id); }, onContextMenu: (event) => handleRowContextMenu(row, event), style: { cursor: 'context-menu' }, title: '右键打开账号动作' })} /></div></>;
const accountsBody = <><Space style={{ marginBottom: 8, width: '100%', justifyContent: 'space-between' }} wrap><Input size="small" allowClear prefix={<SearchOutlined />} placeholder="搜索账号/昵称/游戏名/手机号" value={search} onChange={(event) => { setSearch(event.target.value); setCurrentPage(1); }} style={{ width: 240 }} /><Space><Button size="small" icon={<ImportOutlined />} onClick={() => setImportOpen(true)}>导入账号</Button>{canImport && <Button size="small" icon={<ImportOutlined />} onClick={() => setCkImportOpen(true)}>导入外部 CK</Button>}{selectedIds.length > 0 && <Button size="small" danger onClick={() => void saveAccounts(accounts.map((item) => item.id).filter((id) => !selectedIds.includes(id)))}>移出选中</Button>}</Space></Space><div className="huya-account-table"><Table rowKey="id" size="small" loading={loading} tableLayout="fixed" rowSelection={{ selectedRowKeys: selectedIds, onChange: (keys) => setSelectedIds(keys.map(Number)), preserveSelectedRowKeys: true }} columns={accountColumns} dataSource={filteredAccounts} locale={{ emptyText: '工作台暂无账号,点击右上角「导入账号」添加' }} pagination={{ current: currentPage, pageSize, total: filteredAccounts.length, showSizeChanger: true, showTotal: (total) => `共 ${total} 条`, onChange: (page, size) => { setCurrentPage(page); if (size !== pageSize) { setPageSize(size); localStorage.setItem(PAGE_SIZE_KEY, String(size)); setCurrentPage(1); } } }} scroll={{ y: 'calc(100vh - 300px)' }} onRow={(row) => ({ onClick: () => { const task = latestTask(tasks, row.id); if (!task?.result) return; if (task.task_type === 'get_bind_qr') void openQrTask(task); else if (task.task_type === 'create_recharge_order') openPayTasks(task.batch_id); }, onContextMenu: (event) => handleRowContextMenu(row, event), style: { cursor: 'context-menu' }, title: '右键打开账号动作' })} /></div></>;
const configField = (key: Exclude<keyof HuyaConfig, 'updated_at'>, label: string) => configDraft && <Space key={key} style={{ width: '100%', justifyContent: 'space-between' }}><Text>{label}</Text><Input value={configDraft[key] || ''} onChange={(event) => setConfigDraft({ ...configDraft, [key]: event.target.value })} style={{ width: 300 }} /></Space>;
const contextMenuStyle = contextMenu ? {