🚀 feat(pagination): unify backend-driven pagination & improve channel tag aggregation
SUMMARY • Migrated Token, Task, Midjourney, Channel, Redemption tables to true server-side pagination. • Added total / page / page_size metadata in API responses; switched all affected React tables to consume new structure. • Implemented counting helpers: – model/token.go CountUserTokens – model/task.go TaskCountAllTasks / TaskCountAllUserTask – model/midjourney.go CountAllTasks / CountAllUserTask – model/channel.go CountAllChannels / CountAllTags • Refactored controllers (token, task, midjourney, channel) for 1-based paging & aggregated returns. • Redesigned `ChannelsTable.js`: – `loadChannels`, `syncPageData`, `enrichChannels` for tag-mode grouping without recursion. – Fixed runtime white-screen (maximum call-stack) by removing child duplication. – Pagination, search, tag-mode, idSort all hot-reload correctly. • Removed unused `log` import in controller/midjourney.go. BREAKING CHANGES Front-end consumers must now expect data.items / total / page / page_size from list endpoints (`/api/channel`, `/api/task`, `/api/mj`, `/api/token`, etc.).
This commit is contained in:
@@ -865,32 +865,22 @@ const ChannelsTable = () => {
|
||||
tagChannelDates.response_time = tagChannelDates.response_time / 2;
|
||||
}
|
||||
}
|
||||
// data.key = '' + data.id
|
||||
setChannels(channelDates);
|
||||
if (channelDates.length >= pageSize) {
|
||||
setChannelCount(channelDates.length + pageSize);
|
||||
} else {
|
||||
setChannelCount(channelDates.length);
|
||||
}
|
||||
};
|
||||
|
||||
const loadChannels = async (startIdx, pageSize, idSort, enableTagMode) => {
|
||||
const loadChannels = async (page, pageSize, idSort, enableTagMode) => {
|
||||
setLoading(true);
|
||||
const res = await API.get(
|
||||
`/api/channel/?p=${startIdx}&page_size=${pageSize}&id_sort=${idSort}&tag_mode=${enableTagMode}`,
|
||||
`/api/channel/?p=${page}&page_size=${pageSize}&id_sort=${idSort}&tag_mode=${enableTagMode}`,
|
||||
);
|
||||
if (res === undefined) {
|
||||
return;
|
||||
}
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
if (startIdx === 0) {
|
||||
setChannelFormat(data, enableTagMode);
|
||||
} else {
|
||||
let newChannels = [...channels];
|
||||
newChannels.splice(startIdx * pageSize, data.length, ...data);
|
||||
setChannelFormat(newChannels, enableTagMode);
|
||||
}
|
||||
const { items, total } = data;
|
||||
setChannelFormat(items, enableTagMode);
|
||||
setChannelCount(total);
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
@@ -903,7 +893,6 @@ const ChannelsTable = () => {
|
||||
channelToCopy.created_time = null;
|
||||
channelToCopy.balance = 0;
|
||||
channelToCopy.used_quota = 0;
|
||||
// 删除可能导致类型不匹配的字段
|
||||
delete channelToCopy.test_time;
|
||||
delete channelToCopy.response_time;
|
||||
if (!channelToCopy) {
|
||||
@@ -927,7 +916,7 @@ const ChannelsTable = () => {
|
||||
const refresh = async () => {
|
||||
const { searchKeyword, searchGroup, searchModel } = getFormValues();
|
||||
if (searchKeyword === '' && searchGroup === '' && searchModel === '') {
|
||||
await loadChannels(activePage - 1, pageSize, idSort, enableTagMode);
|
||||
await loadChannels(activePage, pageSize, idSort, enableTagMode);
|
||||
} else {
|
||||
await searchChannels(enableTagMode);
|
||||
}
|
||||
@@ -944,7 +933,7 @@ const ChannelsTable = () => {
|
||||
setPageSize(localPageSize);
|
||||
setEnableTagMode(localEnableTagMode);
|
||||
setEnableBatchDelete(localEnableBatchDelete);
|
||||
loadChannels(0, localPageSize, localIdSort, localEnableTagMode)
|
||||
loadChannels(1, localPageSize, localIdSort, localEnableTagMode)
|
||||
.then()
|
||||
.catch((reason) => {
|
||||
showError(reason);
|
||||
@@ -1052,7 +1041,6 @@ const ChannelsTable = () => {
|
||||
try {
|
||||
if (searchKeyword === '' && searchGroup === '' && searchModel === '') {
|
||||
await loadChannels(activePage - 1, pageSize, idSort, enableTagMode);
|
||||
// setActivePage(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1191,24 +1179,18 @@ const ChannelsTable = () => {
|
||||
}
|
||||
};
|
||||
|
||||
let pageData = channels.slice(
|
||||
(activePage - 1) * pageSize,
|
||||
activePage * pageSize,
|
||||
);
|
||||
let pageData = channels;
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
setActivePage(page);
|
||||
if (page === Math.ceil(channels.length / pageSize) + 1) {
|
||||
// In this case we have to load more data and then append them.
|
||||
loadChannels(page - 1, pageSize, idSort, enableTagMode).then((r) => { });
|
||||
}
|
||||
loadChannels(page, pageSize, idSort, enableTagMode).then(() => { });
|
||||
};
|
||||
|
||||
const handlePageSizeChange = async (size) => {
|
||||
localStorage.setItem('page-size', size + '');
|
||||
setPageSize(size);
|
||||
setActivePage(1);
|
||||
loadChannels(0, size, idSort, enableTagMode)
|
||||
loadChannels(1, size, idSort, enableTagMode)
|
||||
.then()
|
||||
.catch((reason) => {
|
||||
showError(reason);
|
||||
@@ -1218,8 +1200,6 @@ const ChannelsTable = () => {
|
||||
const fetchGroups = async () => {
|
||||
try {
|
||||
let res = await API.get(`/api/group/`);
|
||||
// add 'all' option
|
||||
// res.data.data.unshift('all');
|
||||
if (res === undefined) {
|
||||
return;
|
||||
}
|
||||
@@ -1514,7 +1494,7 @@ const ChannelsTable = () => {
|
||||
onChange={(v) => {
|
||||
localStorage.setItem('id-sort', v + '');
|
||||
setIdSort(v);
|
||||
loadChannels(0, pageSize, v, enableTagMode);
|
||||
loadChannels(activePage, pageSize, v, enableTagMode);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -1541,7 +1521,8 @@ const ChannelsTable = () => {
|
||||
onChange={(v) => {
|
||||
localStorage.setItem('enable-tag-mode', v + '');
|
||||
setEnableTagMode(v);
|
||||
loadChannels(0, pageSize, idSort, v);
|
||||
setActivePage(1);
|
||||
loadChannels(1, pageSize, idSort, v);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -1703,7 +1684,7 @@ const ChannelsTable = () => {
|
||||
formatPageText: (page) => t('第 {{start}} - {{end}} 条,共 {{total}} 条', {
|
||||
start: page.currentStart,
|
||||
end: page.currentEnd,
|
||||
total: channels.length,
|
||||
total: channelCount,
|
||||
}),
|
||||
onPageSizeChange: (size) => {
|
||||
handlePageSizeChange(size);
|
||||
|
||||
@@ -601,7 +601,7 @@ const LogsTable = () => {
|
||||
const [logs, setLogs] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [activePage, setActivePage] = useState(1);
|
||||
const [logCount, setLogCount] = useState(ITEMS_PER_PAGE);
|
||||
const [logCount, setLogCount] = useState(0);
|
||||
const [pageSize, setPageSize] = useState(ITEMS_PER_PAGE);
|
||||
const [isModalOpenurl, setIsModalOpenurl] = useState(false);
|
||||
const [showBanner, setShowBanner] = useState(false);
|
||||
@@ -649,69 +649,53 @@ const LogsTable = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const setLogsFormat = (logs) => {
|
||||
for (let i = 0; i < logs.length; i++) {
|
||||
logs[i].timestamp2string = timestamp2string(logs[i].created_at);
|
||||
logs[i].key = '' + logs[i].id;
|
||||
}
|
||||
// data.key = '' + data.id
|
||||
setLogs(logs);
|
||||
setLogCount(logs.length + pageSize);
|
||||
// console.log(logCount);
|
||||
const enrichLogs = (items) => {
|
||||
return items.map((log) => ({
|
||||
...log,
|
||||
timestamp2string: timestamp2string(log.created_at),
|
||||
key: '' + log.id,
|
||||
}));
|
||||
};
|
||||
|
||||
const loadLogs = async (startIdx, pageSize = ITEMS_PER_PAGE) => {
|
||||
setLoading(true);
|
||||
const syncPageData = (payload) => {
|
||||
const items = enrichLogs(payload.items || []);
|
||||
setLogs(items);
|
||||
setLogCount(payload.total || 0);
|
||||
setActivePage(payload.page || 1);
|
||||
setPageSize(payload.page_size || pageSize);
|
||||
};
|
||||
|
||||
let url = '';
|
||||
const loadLogs = async (page = 1, size = pageSize) => {
|
||||
setLoading(true);
|
||||
const { channel_id, mj_id, start_timestamp, end_timestamp } = getFormValues();
|
||||
let localStartTimestamp = Date.parse(start_timestamp);
|
||||
let localEndTimestamp = Date.parse(end_timestamp);
|
||||
if (isAdminUser) {
|
||||
url = `/api/mj/?p=${startIdx}&page_size=${pageSize}&channel_id=${channel_id}&mj_id=${mj_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
||||
} else {
|
||||
url = `/api/mj/self/?p=${startIdx}&page_size=${pageSize}&mj_id=${mj_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
||||
}
|
||||
const url = isAdminUser
|
||||
? `/api/mj/?p=${page}&page_size=${size}&channel_id=${channel_id}&mj_id=${mj_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`
|
||||
: `/api/mj/self/?p=${page}&page_size=${size}&mj_id=${mj_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
||||
const res = await API.get(url);
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
if (startIdx === 0) {
|
||||
setLogsFormat(data);
|
||||
} else {
|
||||
let newLogs = [...logs];
|
||||
newLogs.splice(startIdx * pageSize, data.length, ...data);
|
||||
setLogsFormat(newLogs);
|
||||
}
|
||||
syncPageData(data);
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
const pageData = logs.slice(
|
||||
(activePage - 1) * pageSize,
|
||||
activePage * pageSize,
|
||||
);
|
||||
const pageData = logs;
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
setActivePage(page);
|
||||
if (page === Math.ceil(logs.length / pageSize) + 1) {
|
||||
// In this case we have to load more data and then append them.
|
||||
loadLogs(page - 1, pageSize).then((r) => { });
|
||||
}
|
||||
loadLogs(page, pageSize).then();
|
||||
};
|
||||
|
||||
const handlePageSizeChange = async (size) => {
|
||||
localStorage.setItem('mj-page-size', size + '');
|
||||
setPageSize(size);
|
||||
setActivePage(1);
|
||||
await loadLogs(0, size);
|
||||
await loadLogs(1, size);
|
||||
};
|
||||
|
||||
const refresh = async () => {
|
||||
// setLoading(true);
|
||||
setActivePage(1);
|
||||
await loadLogs(0, pageSize);
|
||||
await loadLogs(1, pageSize);
|
||||
};
|
||||
|
||||
const copyText = async (text) => {
|
||||
@@ -726,7 +710,7 @@ const LogsTable = () => {
|
||||
useEffect(() => {
|
||||
const localPageSize = parseInt(localStorage.getItem('mj-page-size')) || ITEMS_PER_PAGE;
|
||||
setPageSize(localPageSize);
|
||||
loadLogs(0, localPageSize).then();
|
||||
loadLogs(1, localPageSize).then();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -936,7 +920,7 @@ const LogsTable = () => {
|
||||
>
|
||||
<Table
|
||||
columns={getVisibleColumns()}
|
||||
dataSource={pageData}
|
||||
dataSource={logs}
|
||||
rowKey='key'
|
||||
loading={loading}
|
||||
scroll={{ x: 'max-content' }}
|
||||
@@ -962,9 +946,7 @@ const LogsTable = () => {
|
||||
total: logCount,
|
||||
pageSizeOptions: [10, 20, 50, 100],
|
||||
showSizeChanger: true,
|
||||
onPageSizeChange: (size) => {
|
||||
handlePageSizeChange(size);
|
||||
},
|
||||
onPageSizeChange: handlePageSizeChange,
|
||||
onPageChange: handlePageChange,
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -451,10 +451,16 @@ const LogsTable = () => {
|
||||
return allColumns.filter((column) => visibleColumns[column.key]);
|
||||
};
|
||||
|
||||
const [logs, setLogs] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [activePage, setActivePage] = useState(1);
|
||||
const [logCount, setLogCount] = useState(ITEMS_PER_PAGE);
|
||||
const [logCount, setLogCount] = useState(0);
|
||||
const [logs, setLogs] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const localPageSize = parseInt(localStorage.getItem('task-page-size')) || ITEMS_PER_PAGE;
|
||||
setPageSize(localPageSize);
|
||||
loadLogs(1, localPageSize).then();
|
||||
}, []);
|
||||
|
||||
let now = new Date();
|
||||
// 初始化start_timestamp为前一天
|
||||
@@ -494,67 +500,53 @@ const LogsTable = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const setLogsFormat = (logs) => {
|
||||
for (let i = 0; i < logs.length; i++) {
|
||||
logs[i].timestamp2string = timestamp2string(logs[i].created_at);
|
||||
logs[i].key = '' + logs[i].id;
|
||||
}
|
||||
// data.key = '' + data.id
|
||||
setLogs(logs);
|
||||
setLogCount(logs.length + ITEMS_PER_PAGE);
|
||||
// console.log(logCount);
|
||||
const enrichLogs = (items) => {
|
||||
return items.map((log) => ({
|
||||
...log,
|
||||
timestamp2string: timestamp2string(log.created_at),
|
||||
key: '' + log.id,
|
||||
}));
|
||||
};
|
||||
|
||||
const loadLogs = async (startIdx, pageSize = ITEMS_PER_PAGE) => {
|
||||
setLoading(true);
|
||||
const syncPageData = (payload) => {
|
||||
const items = enrichLogs(payload.items || []);
|
||||
setLogs(items);
|
||||
setLogCount(payload.total || 0);
|
||||
setActivePage(payload.page || 1);
|
||||
setPageSize(payload.page_size || pageSize);
|
||||
};
|
||||
|
||||
let url = '';
|
||||
const loadLogs = async (page = 1, size = pageSize) => {
|
||||
setLoading(true);
|
||||
const { channel_id, task_id, start_timestamp, end_timestamp } = getFormValues();
|
||||
let localStartTimestamp = parseInt(Date.parse(start_timestamp) / 1000);
|
||||
let localEndTimestamp = parseInt(Date.parse(end_timestamp) / 1000);
|
||||
if (isAdminUser) {
|
||||
url = `/api/task/?p=${startIdx}&page_size=${pageSize}&channel_id=${channel_id}&task_id=${task_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
||||
} else {
|
||||
url = `/api/task/self?p=${startIdx}&page_size=${pageSize}&task_id=${task_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
||||
}
|
||||
let url = isAdminUser
|
||||
? `/api/task/?p=${page}&page_size=${size}&channel_id=${channel_id}&task_id=${task_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`
|
||||
: `/api/task/self?p=${page}&page_size=${size}&task_id=${task_id}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
||||
const res = await API.get(url);
|
||||
let { success, message, data } = res.data;
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
if (startIdx === 0) {
|
||||
setLogsFormat(data);
|
||||
} else {
|
||||
let newLogs = [...logs];
|
||||
newLogs.splice(startIdx * pageSize, data.length, ...data);
|
||||
setLogsFormat(newLogs);
|
||||
}
|
||||
syncPageData(data);
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
const pageData = logs.slice(
|
||||
(activePage - 1) * pageSize,
|
||||
activePage * pageSize,
|
||||
);
|
||||
const pageData = logs;
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
setActivePage(page);
|
||||
if (page === Math.ceil(logs.length / pageSize) + 1) {
|
||||
loadLogs(page - 1, pageSize).then((r) => { });
|
||||
}
|
||||
loadLogs(page, pageSize).then();
|
||||
};
|
||||
|
||||
const handlePageSizeChange = async (size) => {
|
||||
localStorage.setItem('task-page-size', size + '');
|
||||
setPageSize(size);
|
||||
setActivePage(1);
|
||||
await loadLogs(0, size);
|
||||
await loadLogs(1, size);
|
||||
};
|
||||
|
||||
const refresh = async () => {
|
||||
setActivePage(1);
|
||||
await loadLogs(0, pageSize);
|
||||
await loadLogs(1, pageSize);
|
||||
};
|
||||
|
||||
const copyText = async (text) => {
|
||||
@@ -565,12 +557,6 @@ const LogsTable = () => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const localPageSize = parseInt(localStorage.getItem('task-page-size')) || ITEMS_PER_PAGE;
|
||||
setPageSize(localPageSize);
|
||||
loadLogs(0, localPageSize).then();
|
||||
}, []);
|
||||
|
||||
// 列选择器模态框
|
||||
const renderColumnSelector = () => {
|
||||
return (
|
||||
@@ -763,7 +749,7 @@ const LogsTable = () => {
|
||||
>
|
||||
<Table
|
||||
columns={getVisibleColumns()}
|
||||
dataSource={pageData}
|
||||
dataSource={logs}
|
||||
rowKey='key'
|
||||
loading={loading}
|
||||
scroll={{ x: 'max-content' }}
|
||||
@@ -789,9 +775,7 @@ const LogsTable = () => {
|
||||
total: logCount,
|
||||
pageSizeOptions: [10, 20, 50, 100],
|
||||
showSizeChanger: true,
|
||||
onPageSizeChange: (size) => {
|
||||
handlePageSizeChange(size);
|
||||
},
|
||||
onPageSizeChange: handlePageSizeChange,
|
||||
onPageChange: handlePageChange,
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -408,31 +408,20 @@ const TokensTable = () => {
|
||||
}, 500);
|
||||
};
|
||||
|
||||
const setTokensFormat = (tokens) => {
|
||||
setTokens(tokens);
|
||||
if (tokens.length >= pageSize) {
|
||||
setTokenCount(tokens.length + pageSize);
|
||||
} else {
|
||||
setTokenCount(tokens.length);
|
||||
}
|
||||
// 将后端返回的数据写入状态
|
||||
const syncPageData = (payload) => {
|
||||
setTokens(payload.items || []);
|
||||
setTokenCount(payload.total || 0);
|
||||
setActivePage(payload.page || 1);
|
||||
setPageSize(payload.page_size || pageSize);
|
||||
};
|
||||
|
||||
let pageData = tokens.slice(
|
||||
(activePage - 1) * pageSize,
|
||||
activePage * pageSize,
|
||||
);
|
||||
const loadTokens = async (startIdx) => {
|
||||
const loadTokens = async (page = 1, size = pageSize) => {
|
||||
setLoading(true);
|
||||
const res = await API.get(`/api/token/?p=${startIdx}&size=${pageSize}`);
|
||||
const res = await API.get(`/api/token/?p=${page}&size=${size}`);
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
if (startIdx === 0) {
|
||||
setTokensFormat(data);
|
||||
} else {
|
||||
let newTokens = [...tokens];
|
||||
newTokens.splice(startIdx * pageSize, data.length, ...data);
|
||||
setTokensFormat(newTokens);
|
||||
}
|
||||
syncPageData(data);
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
@@ -440,7 +429,7 @@ const TokensTable = () => {
|
||||
};
|
||||
|
||||
const refresh = async () => {
|
||||
await loadTokens(activePage - 1);
|
||||
await loadTokens(1);
|
||||
};
|
||||
|
||||
const copyText = async (text) => {
|
||||
@@ -473,7 +462,7 @@ const TokensTable = () => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadTokens(0)
|
||||
loadTokens(1)
|
||||
.then()
|
||||
.catch((reason) => {
|
||||
showError(reason);
|
||||
@@ -487,7 +476,7 @@ const TokensTable = () => {
|
||||
|
||||
if (idx > -1) {
|
||||
newDataSource.splice(idx, 1);
|
||||
setTokensFormat(newDataSource);
|
||||
setTokens(newDataSource);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -518,7 +507,7 @@ const TokensTable = () => {
|
||||
} else {
|
||||
record.status = token.status;
|
||||
}
|
||||
setTokensFormat(newTokens);
|
||||
setTokens(newTokens);
|
||||
} else {
|
||||
showError(message);
|
||||
}
|
||||
@@ -528,8 +517,7 @@ const TokensTable = () => {
|
||||
const searchTokens = async () => {
|
||||
const { searchKeyword, searchToken } = getFormValues();
|
||||
if (searchKeyword === '' && searchToken === '') {
|
||||
await loadTokens(0);
|
||||
setActivePage(1);
|
||||
await loadTokens(1);
|
||||
return;
|
||||
}
|
||||
setSearching(true);
|
||||
@@ -538,7 +526,8 @@ const TokensTable = () => {
|
||||
);
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
setTokensFormat(data);
|
||||
setTokens(data);
|
||||
setTokenCount(data.length);
|
||||
setActivePage(1);
|
||||
} else {
|
||||
showError(message);
|
||||
@@ -561,10 +550,12 @@ const TokensTable = () => {
|
||||
};
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
setActivePage(page);
|
||||
if (page === Math.ceil(tokens.length / pageSize) + 1) {
|
||||
loadTokens(page - 1).then((r) => { });
|
||||
}
|
||||
loadTokens(page, pageSize).then();
|
||||
};
|
||||
|
||||
const handlePageSizeChange = async (size) => {
|
||||
setPageSize(size);
|
||||
await loadTokens(1, size);
|
||||
};
|
||||
|
||||
const rowSelection = {
|
||||
@@ -707,7 +698,7 @@ const TokensTable = () => {
|
||||
>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={pageData}
|
||||
dataSource={tokens}
|
||||
scroll={{ x: 'max-content' }}
|
||||
pagination={{
|
||||
currentPage: activePage,
|
||||
@@ -719,12 +710,9 @@ const TokensTable = () => {
|
||||
t('第 {{start}} - {{end}} 条,共 {{total}} 条', {
|
||||
start: page.currentStart,
|
||||
end: page.currentEnd,
|
||||
total: tokens.length,
|
||||
total: tokenCount,
|
||||
}),
|
||||
onPageSizeChange: (size) => {
|
||||
setPageSize(size);
|
||||
setActivePage(1);
|
||||
},
|
||||
onPageSizeChange: handlePageSizeChange,
|
||||
onPageChange: handlePageChange,
|
||||
}}
|
||||
loading={loading}
|
||||
|
||||
Reference in New Issue
Block a user