fix: paginate operational list pages

This commit is contained in:
hectorzhao
2026-07-28 23:20:13 +08:00
parent 87c5b1eccc
commit b8560372cc
40 changed files with 1208 additions and 422 deletions
+23 -17
View File
@@ -1,7 +1,7 @@
import { useEffect, useMemo, useState } from 'react';
import { useEffect, useState } from 'react';
import { Eye, Search } from 'lucide-react';
import { adminApi, fileDownloadUrl, type ReportTask } from '@/api/adminApi';
import { Breadcrumb, Button, DateRangeInput, Input, Modal, Select, Table, Tag, Textarea, type DateRangeValue, type TableColumn } from '@/components/ui';
import { Breadcrumb, Button, DateRangeInput, Input, Modal, Pagination, Select, Table, Tag, Textarea, type DateRangeValue, type TableColumn } from '@/components/ui';
import { formatDateTime } from '@/utils/dateTime';
const statusMeta: Record<string, { label: string; tone: 'neutral' | 'info' | 'success' | 'warning' | 'danger' }> = {
@@ -74,25 +74,30 @@ export function AdminReportTasksPage() {
const [statusReason, setStatusReason] = useState('');
const [error, setError] = useState('');
const [busy, setBusy] = useState(false);
const [page, setPage] = useState(1);
const [total, setTotal] = useState(0);
const pageSize = 10;
function loadData() {
adminApi.listReportTasks({ reportType: reportType === 'all' ? undefined : reportType as 'signature' | 'drainage' })
.then((items) => {
setTasks(items);
function loadData(targetPage = page) {
adminApi.listReportTasksPage({
reportType: reportType === 'all' ? undefined : reportType as 'signature' | 'drainage',
keyword: keyword || undefined,
createdAtFrom: dateRange.start || undefined,
createdAtTo: dateRange.end || undefined,
page: targetPage,
pageSize,
})
.then((result) => {
setTasks(result.items);
setTotal(result.total);
setError('');
})
.catch((failure: Error) => setError(failure.message || '报备明细加载失败'));
}
useEffect(loadData, [reportType]);
const filteredTasks = useMemo(() => tasks.filter((task) => {
const text = `${task.id}${task.channel?.name ?? task.channelId}${task.signature?.name ?? task.signatureId}${task.drainageInfo?.siteName ?? ''}${task.drainageInfo?.url ?? ''}${task.signature?.tenant?.name ?? ''}${task.signature?.application?.name ?? ''}`;
const date = task.createdAt?.slice(0, 10) ?? '';
return (!keyword || text.includes(keyword))
&& (!dateRange.start || date >= dateRange.start)
&& (!dateRange.end || date <= dateRange.end);
}), [dateRange.end, dateRange.start, keyword, tasks]);
useEffect(() => {
loadData(page);
}, [page]);
async function saveTaskStatus() {
if (!statusTask) return;
@@ -143,13 +148,14 @@ export function AdminReportTasksPage() {
<Input label="企业/应用/通道/报备对象" onChange={(event) => setKeyword(event.target.value)} placeholder="搜索报备明细" value={keyword} />
<Select label="报备类型" onChange={(event) => setReportType(event.target.value)} options={[{ label: '全部类型', value: 'all' }, { label: '签名报备', value: 'signature' }, { label: '引流信息报备', value: 'drainage' }]} value={reportType} />
<DateRangeInput label="创建时间" onChange={setDateRange} value={dateRange} />
<div className="admin-task-filter__actions"><Button icon={<Search size={16} />} onClick={loadData}></Button><Button onClick={() => {
<div className="admin-task-filter__actions"><Button icon={<Search size={16} />} onClick={() => { if (page !== 1) setPage(1); else loadData(1); }}></Button><Button onClick={() => {
setKeyword('');
setDateRange({});
setReportType('all');
}} variant="ghost"></Button></div>
</div>
<div className="surface report-task-table-card"><Table columns={columns} data={filteredTasks} emptyText="暂无报备明细" rowKey="id" /></div>
<div className="surface report-task-table-card"><Table columns={columns} data={tasks} emptyText="暂无报备明细" pagination={false} rowKey="id" /></div>
<Pagination nextDisabled={page * pageSize >= total} onNext={() => setPage((current) => current + 1)} onPageChange={setPage} onPrevious={() => setPage((current) => Math.max(1, current - 1))} page={page} previousDisabled={page <= 1} total={total} totalPages={Math.max(1, Math.ceil(total / pageSize))} />
{detailTask ? <TaskDetailModal onClose={() => setDetailTask(null)} task={detailTask} /> : null}
<Modal footer={<><Button disabled={busy} onClick={() => setStatusTask(null)} variant="ghost"></Button><Button disabled={busy} onClick={() => void saveTaskStatus()}>{busy ? '保存中…' : '保存'}</Button></>} onClose={() => setStatusTask(null)} open={Boolean(statusTask)} title="修改报备状态">
{statusTask ? <div className="page-stack">