feat: KOC资源列表分页展示(每页15个)

This commit is contained in:
ABAPPLO
2026-08-27 19:17:53 +08:00
parent dfc7dc217d
commit 8e4e3de974
2 changed files with 121 additions and 7 deletions

View File

@@ -3171,6 +3171,22 @@ function ScreenshotTaskTable({ distributions }: { distributions: Distribution[]
);
}
const RESOURCE_PAGE_SIZE = 15;
function pageList(current: number, total: number): Array<number | "gap"> {
if (total <= 7) {
return Array.from({ length: total }, (_, index) => index + 1);
}
const items: Array<number | "gap"> = [1];
const start = Math.max(2, current - 1);
const end = Math.min(total - 1, current + 1);
if (start > 2) items.push("gap");
for (let page = start; page <= end; page += 1) items.push(page);
if (end < total - 1) items.push("gap");
items.push(total);
return items;
}
function ResourcesPage({
accounts,
distributions,
@@ -3188,6 +3204,7 @@ function ResourcesPage({
const [platformFilter, setPlatformFilter] = useState("全部平台");
const [ipFilter, setIpFilter] = useState("");
const [sourceFilter, setSourceFilter] = useState("");
const [page, setPage] = useState(1);
const [importOpen, setImportOpen] = useState(false);
const [importMode, setImportMode] = useState<"bulk" | "single">("bulk");
const [importFile, setImportFile] = useState<File | null>(null);
@@ -3307,11 +3324,21 @@ function ResourcesPage({
platformFilter !== "全部平台" ||
Boolean(ipFilter.trim()) ||
Boolean(sourceFilter.trim());
const totalPages = Math.max(
1,
Math.ceil(filteredAccounts.length / RESOURCE_PAGE_SIZE),
);
const currentPage = Math.min(page, totalPages);
const pagedAccounts = filteredAccounts.slice(
(currentPage - 1) * RESOURCE_PAGE_SIZE,
currentPage * RESOURCE_PAGE_SIZE,
);
const clearFilters = () => {
setQuery("");
setPlatformFilter("全部平台");
setIpFilter("");
setSourceFilter("");
setPage(1);
};
const closeImport = () => {
if (importWorking || singleWorking) return;
@@ -3569,7 +3596,10 @@ function ResourcesPage({
<div className="filter-chips">
<button
className={platformFilter === "全部平台" ? "active" : ""}
onClick={() => setPlatformFilter("全部平台")}
onClick={() => {
setPlatformFilter("全部平台");
setPage(1);
}}
>
全部平台
</button>
@@ -3577,7 +3607,10 @@ function ResourcesPage({
<button
className={platformFilter === platform ? "active" : ""}
key={platform}
onClick={() => setPlatformFilter(platform)}
onClick={() => {
setPlatformFilter(platform);
setPage(1);
}}
>
<PlatformBadge platform={platform} compact />
</button>
@@ -3590,7 +3623,10 @@ function ResourcesPage({
<span aria-hidden="true">⌕</span>
<input
aria-label="搜索账号名称、账号ID或当前联系人"
onChange={(event) => setQuery(event.target.value)}
onChange={(event) => {
setQuery(event.target.value);
setPage(1);
}}
placeholder="搜索账号名称 / 账号ID / 当前联系人 / 标签"
type="search"
value={query}
@@ -3601,7 +3637,10 @@ function ResourcesPage({
<input
aria-label="模糊搜索IP地区"
list="resource-ip-options"
onChange={(event) => setIpFilter(event.target.value)}
onChange={(event) => {
setIpFilter(event.target.value);
setPage(1);
}}
placeholder="搜索IP地区"
type="search"
value={ipFilter}
@@ -3615,7 +3654,10 @@ function ResourcesPage({
<input
aria-label="模糊搜索合作来源"
list="resource-source-options"
onChange={(event) => setSourceFilter(event.target.value)}
onChange={(event) => {
setSourceFilter(event.target.value);
setPage(1);
}}
placeholder="搜索合作来源"
type="search"
value={sourceFilter}
@@ -3634,7 +3676,7 @@ function ResourcesPage({
清空筛选
</button>
<div className="resource-toolbar-summary">
<span>共 <b>{filteredAccounts.length}</b> 个结果</span>
<span>共 <b>{filteredAccounts.length}</b> 个结果{totalPages > 1 ? ` · 第 ${currentPage}/${totalPages} 页` : ""}</span>
<button
className="export-data-button"
disabled={runningIdRefresh || idRefreshStarting}
@@ -3660,7 +3702,7 @@ function ResourcesPage({
{idRefreshError && <div className="form-error">{idRefreshError}</div>}
</div>
<div className="resource-grid">
{filteredAccounts.map(({ account, sources, partnerManagedOnly }) => {
{pagedAccounts.map(({ account, sources, partnerManagedOnly }) => {
const profileLink = resourceProfileLink(account);
const accountTags = (account.tags || "")
.split(/[,,、;;|]/)
@@ -3762,6 +3804,35 @@ function ResourcesPage({
</button>
</div>
)}
{totalPages > 1 && (
<div className="resource-pagination">
<button
disabled={currentPage === 1}
onClick={() => setPage(currentPage - 1)}
>
上一页
</button>
{pageList(currentPage, totalPages).map((item, index) =>
item === "gap" ? (
<span className="gap" key={`gap-${index}`}>…</span>
) : (
<button
className={item === currentPage ? "active" : ""}
key={item}
onClick={() => setPage(item)}
>
{item}
</button>
),
)}
<button
disabled={currentPage === totalPages}
onClick={() => setPage(currentPage + 1)}
>
下一页
</button>
</div>
)}
</section>
{editAccount && (
<div className="modal-backdrop" role="presentation" onMouseDown={closeAccountEdit}>