feat: 订单列表支持分页查询,分页大小可选 20/50/100
- /api/orders/my 新增 page/page_size 参数,返回分页信息和全局状态统计 - 用户订单页:分页控件(首/上/下/末页)+ 分页大小选择,摘要卡片改为全局统计 - 管理员订单页:分页大小选择器(20/50/100)+ 首尾页跳转按钮
This commit is contained in:
@@ -43,6 +43,7 @@ function AdminContent() {
|
||||
const [orders, setOrders] = useState<AdminOrder[]>([]);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [page, setPage] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(20);
|
||||
const [totalPages, setTotalPages] = useState(1);
|
||||
const [statusFilter, setStatusFilter] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -54,7 +55,7 @@ function AdminContent() {
|
||||
if (!token) return;
|
||||
setLoading(true);
|
||||
try {
|
||||
const params = new URLSearchParams({ token, page: String(page), page_size: '20' });
|
||||
const params = new URLSearchParams({ token, page: String(page), page_size: String(pageSize) });
|
||||
if (statusFilter) params.set('status', statusFilter);
|
||||
|
||||
const res = await fetch(`/api/admin/orders?${params}`);
|
||||
@@ -75,7 +76,7 @@ function AdminContent() {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [token, page, statusFilter]);
|
||||
}, [token, page, pageSize, statusFilter]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchOrders();
|
||||
@@ -198,14 +199,36 @@ function AdminContent() {
|
||||
</div>
|
||||
|
||||
{/* Pagination */}
|
||||
{totalPages > 1 && (
|
||||
<div className="mt-4 flex items-center justify-between text-sm text-gray-500">
|
||||
<span>共 {total} 条记录</span>
|
||||
<div className="flex gap-2">
|
||||
<div className="mt-4 flex flex-wrap items-center justify-between gap-3 text-sm text-gray-500">
|
||||
<div className="flex items-center gap-2">
|
||||
<span>共 {total} 条,每页</span>
|
||||
{[20, 50, 100].map((s) => (
|
||||
<button
|
||||
key={s}
|
||||
onClick={() => { setPageSize(s); setPage(1); }}
|
||||
className={`rounded border px-2.5 py-1 text-xs font-medium transition-colors ${
|
||||
pageSize === s
|
||||
? 'border-blue-500 bg-blue-50 text-blue-700'
|
||||
: 'border-gray-300 text-gray-600 hover:bg-gray-100'
|
||||
}`}
|
||||
>
|
||||
{s}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
{totalPages > 1 && (
|
||||
<div className="flex items-center gap-1.5">
|
||||
<button
|
||||
onClick={() => setPage(1)}
|
||||
disabled={page <= 1}
|
||||
className="rounded border px-2.5 py-1 disabled:opacity-40 hover:bg-gray-100"
|
||||
>
|
||||
««
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setPage((p) => Math.max(1, p - 1))}
|
||||
disabled={page <= 1}
|
||||
className="rounded border px-3 py-1 disabled:opacity-50"
|
||||
className="rounded border px-3 py-1 disabled:opacity-40 hover:bg-gray-100"
|
||||
>
|
||||
上一页
|
||||
</button>
|
||||
@@ -215,13 +238,20 @@ function AdminContent() {
|
||||
<button
|
||||
onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
|
||||
disabled={page >= totalPages}
|
||||
className="rounded border px-3 py-1 disabled:opacity-50"
|
||||
className="rounded border px-3 py-1 disabled:opacity-40 hover:bg-gray-100"
|
||||
>
|
||||
下一页
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setPage(totalPages)}
|
||||
disabled={page >= totalPages}
|
||||
className="rounded border px-2.5 py-1 disabled:opacity-40 hover:bg-gray-100"
|
||||
>
|
||||
»»
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Order Detail */}
|
||||
{detailOrder && <OrderDetail order={detailOrder} onClose={() => setDetailOrder(null)} />}
|
||||
|
||||
Reference in New Issue
Block a user