diff --git a/web/src/components/common/ui/CardPro.js b/web/src/components/common/ui/CardPro.js
index 3325381c..4488661c 100644
--- a/web/src/components/common/ui/CardPro.js
+++ b/web/src/components/common/ui/CardPro.js
@@ -28,12 +28,13 @@ const { Text } = Typography;
/**
* CardPro 高级卡片组件
*
- * 布局分为5个区域:
+ * 布局分为6个区域:
* 1. 统计信息区域 (statsArea)
* 2. 描述信息区域 (descriptionArea)
* 3. 类型切换/标签区域 (tabsArea)
* 4. 操作按钮区域 (actionsArea)
* 5. 搜索表单区域 (searchArea)
+ * 6. 分页区域 (paginationArea) - 固定在卡片底部
*
* 支持三种布局类型:
* - type1: 操作型 (如TokensTable) - 描述信息 + 操作按钮 + 搜索表单
@@ -50,6 +51,7 @@ const CardPro = ({
tabsArea,
actionsArea,
searchArea,
+ paginationArea, // 新增分页区域
// 卡片属性
shadows = 'always',
bordered = false,
@@ -159,10 +161,24 @@ const CardPro = ({
const headerContent = renderHeader();
+ // 渲染分页区域
+ const renderFooter = () => {
+ if (!paginationArea) return null;
+
+ return (
+
+ {paginationArea}
+
+ );
+ };
+
+ const footerContent = renderFooter();
+
return (
{
+const CardTable = ({
+ columns = [],
+ dataSource = [],
+ loading = false,
+ rowKey = 'key',
+ hidePagination = false, // 新增参数,控制是否隐藏内部分页
+ ...tableProps
+}) => {
const isMobile = useIsMobile();
const { t } = useTranslation();
@@ -62,13 +69,18 @@ const CardTable = ({ columns = [], dataSource = [], loading = false, rowKey = 'k
// 如果不是移动端,直接渲染原 Table
if (!isMobile) {
+ // 如果要隐藏分页,则从tableProps中移除pagination
+ const finalTableProps = hidePagination
+ ? { ...tableProps, pagination: false }
+ : tableProps;
+
return (
);
}
@@ -215,8 +227,8 @@ const CardTable = ({ columns = [], dataSource = [], loading = false, rowKey = 'k
{dataSource.map((record, index) => (
))}
- {/* 分页组件 */}
- {tableProps.pagination && dataSource.length > 0 && (
+ {/* 分页组件 - 只在不隐藏分页且有pagination配置时显示 */}
+ {!hidePagination && tableProps.pagination && dataSource.length > 0 && (
@@ -230,6 +242,7 @@ CardTable.propTypes = {
dataSource: PropTypes.array,
loading: PropTypes.bool,
rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
+ hidePagination: PropTypes.bool, // 控制是否隐藏内部分页
};
export default CardTable;
\ No newline at end of file
diff --git a/web/src/components/table/channels/ChannelsTable.jsx b/web/src/components/table/channels/ChannelsTable.jsx
index e0270558..bf4d24de 100644
--- a/web/src/components/table/channels/ChannelsTable.jsx
+++ b/web/src/components/table/channels/ChannelsTable.jsx
@@ -129,6 +129,7 @@ const ChannelsTable = (channelsData) => {
onPageSizeChange: handlePageSizeChange,
onPageChange: handlePageChange,
}}
+ hidePagination={true}
expandAllRows={false}
onRow={handleRow}
rowSelection={
diff --git a/web/src/components/table/channels/index.jsx b/web/src/components/table/channels/index.jsx
index 91dd3200..b29be9fe 100644
--- a/web/src/components/table/channels/index.jsx
+++ b/web/src/components/table/channels/index.jsx
@@ -29,6 +29,7 @@ import ModelTestModal from './modals/ModelTestModal.jsx';
import ColumnSelectorModal from './modals/ColumnSelectorModal.jsx';
import EditChannelModal from './modals/EditChannelModal.jsx';
import EditTagModal from './modals/EditTagModal.jsx';
+import { createCardProPagination } from '../../../helpers/utils';
const ChannelsPage = () => {
const channelsData = useChannelsData();
@@ -58,6 +59,13 @@ const ChannelsPage = () => {
tabsArea={}
actionsArea={}
searchArea={}
+ paginationArea={createCardProPagination({
+ currentPage: channelsData.activePage,
+ pageSize: channelsData.pageSize,
+ total: channelsData.channelCount,
+ onPageChange: channelsData.handlePageChange,
+ onPageSizeChange: channelsData.handlePageSizeChange,
+ })}
t={channelsData.t}
>
diff --git a/web/src/components/table/mj-logs/MjLogsTable.jsx b/web/src/components/table/mj-logs/MjLogsTable.jsx
index 5b1cfa92..31a2d10e 100644
--- a/web/src/components/table/mj-logs/MjLogsTable.jsx
+++ b/web/src/components/table/mj-logs/MjLogsTable.jsx
@@ -109,6 +109,7 @@ const MjLogsTable = (mjLogsData) => {
onPageSizeChange: handlePageSizeChange,
onPageChange: handlePageChange,
}}
+ hidePagination={true}
/>
);
};
diff --git a/web/src/components/table/mj-logs/index.jsx b/web/src/components/table/mj-logs/index.jsx
index 3b0560b8..3d352706 100644
--- a/web/src/components/table/mj-logs/index.jsx
+++ b/web/src/components/table/mj-logs/index.jsx
@@ -26,6 +26,7 @@ import MjLogsFilters from './MjLogsFilters.jsx';
import ColumnSelectorModal from './modals/ColumnSelectorModal.jsx';
import ContentModal from './modals/ContentModal.jsx';
import { useMjLogsData } from '../../../hooks/mj-logs/useMjLogsData.js';
+import { createCardProPagination } from '../../../helpers/utils';
const MjLogsPage = () => {
const mjLogsData = useMjLogsData();
@@ -41,6 +42,13 @@ const MjLogsPage = () => {
type="type2"
statsArea={}
searchArea={}
+ paginationArea={createCardProPagination({
+ currentPage: mjLogsData.activePage,
+ pageSize: mjLogsData.pageSize,
+ total: mjLogsData.logCount,
+ onPageChange: mjLogsData.handlePageChange,
+ onPageSizeChange: mjLogsData.handlePageSizeChange,
+ })}
t={mjLogsData.t}
>
diff --git a/web/src/components/table/redemptions/RedemptionsTable.jsx b/web/src/components/table/redemptions/RedemptionsTable.jsx
index 58fc5444..76e50532 100644
--- a/web/src/components/table/redemptions/RedemptionsTable.jsx
+++ b/web/src/components/table/redemptions/RedemptionsTable.jsx
@@ -107,6 +107,7 @@ const RedemptionsTable = (redemptionsData) => {
onPageSizeChange: redemptionsData.handlePageSizeChange,
onPageChange: handlePageChange,
}}
+ hidePagination={true}
loading={loading}
rowSelection={rowSelection}
onRow={handleRow}
diff --git a/web/src/components/table/redemptions/index.jsx b/web/src/components/table/redemptions/index.jsx
index 1886c59f..cde9c00f 100644
--- a/web/src/components/table/redemptions/index.jsx
+++ b/web/src/components/table/redemptions/index.jsx
@@ -25,6 +25,7 @@ import RedemptionsFilters from './RedemptionsFilters.jsx';
import RedemptionsDescription from './RedemptionsDescription.jsx';
import EditRedemptionModal from './modals/EditRedemptionModal';
import { useRedemptionsData } from '../../../hooks/redemptions/useRedemptionsData';
+import { createCardProPagination } from '../../../helpers/utils';
const RedemptionsPage = () => {
const redemptionsData = useRedemptionsData();
@@ -99,6 +100,13 @@ const RedemptionsPage = () => {
}
+ paginationArea={createCardProPagination({
+ currentPage: redemptionsData.activePage,
+ pageSize: redemptionsData.pageSize,
+ total: redemptionsData.tokenCount,
+ onPageChange: redemptionsData.handlePageChange,
+ onPageSizeChange: redemptionsData.handlePageSizeChange,
+ })}
t={t}
>
diff --git a/web/src/components/table/task-logs/TaskLogsTable.jsx b/web/src/components/table/task-logs/TaskLogsTable.jsx
index c148709c..cacb12dd 100644
--- a/web/src/components/table/task-logs/TaskLogsTable.jsx
+++ b/web/src/components/table/task-logs/TaskLogsTable.jsx
@@ -106,6 +106,7 @@ const TaskLogsTable = (taskLogsData) => {
onPageSizeChange: handlePageSizeChange,
onPageChange: handlePageChange,
}}
+ hidePagination={true}
/>
);
};
diff --git a/web/src/components/table/task-logs/index.jsx b/web/src/components/table/task-logs/index.jsx
index 944f49df..997f3164 100644
--- a/web/src/components/table/task-logs/index.jsx
+++ b/web/src/components/table/task-logs/index.jsx
@@ -26,6 +26,7 @@ import TaskLogsFilters from './TaskLogsFilters.jsx';
import ColumnSelectorModal from './modals/ColumnSelectorModal.jsx';
import ContentModal from './modals/ContentModal.jsx';
import { useTaskLogsData } from '../../../hooks/task-logs/useTaskLogsData.js';
+import { createCardProPagination } from '../../../helpers/utils';
const TaskLogsPage = () => {
const taskLogsData = useTaskLogsData();
@@ -41,6 +42,13 @@ const TaskLogsPage = () => {
type="type2"
statsArea={}
searchArea={}
+ paginationArea={createCardProPagination({
+ currentPage: taskLogsData.activePage,
+ pageSize: taskLogsData.pageSize,
+ total: taskLogsData.logCount,
+ onPageChange: taskLogsData.handlePageChange,
+ onPageSizeChange: taskLogsData.handlePageSizeChange,
+ })}
t={taskLogsData.t}
>
diff --git a/web/src/components/table/tokens/TokensTable.jsx b/web/src/components/table/tokens/TokensTable.jsx
index 237d05ae..15be1c63 100644
--- a/web/src/components/table/tokens/TokensTable.jsx
+++ b/web/src/components/table/tokens/TokensTable.jsx
@@ -99,6 +99,7 @@ const TokensTable = (tokensData) => {
onPageSizeChange: handlePageSizeChange,
onPageChange: handlePageChange,
}}
+ hidePagination={true}
loading={loading}
rowSelection={rowSelection}
onRow={handleRow}
diff --git a/web/src/components/table/tokens/index.jsx b/web/src/components/table/tokens/index.jsx
index 35ff6102..7011eb7c 100644
--- a/web/src/components/table/tokens/index.jsx
+++ b/web/src/components/table/tokens/index.jsx
@@ -25,6 +25,7 @@ import TokensFilters from './TokensFilters.jsx';
import TokensDescription from './TokensDescription.jsx';
import EditTokenModal from './modals/EditTokenModal';
import { useTokensData } from '../../../hooks/tokens/useTokensData';
+import { createCardProPagination } from '../../../helpers/utils';
const TokensPage = () => {
const tokensData = useTokensData();
@@ -101,6 +102,13 @@ const TokensPage = () => {
}
+ paginationArea={createCardProPagination({
+ currentPage: tokensData.activePage,
+ pageSize: tokensData.pageSize,
+ total: tokensData.tokenCount,
+ onPageChange: tokensData.handlePageChange,
+ onPageSizeChange: tokensData.handlePageSizeChange,
+ })}
t={t}
>
diff --git a/web/src/components/table/usage-logs/UsageLogsTable.jsx b/web/src/components/table/usage-logs/UsageLogsTable.jsx
index b089f5cb..2739d3c4 100644
--- a/web/src/components/table/usage-logs/UsageLogsTable.jsx
+++ b/web/src/components/table/usage-logs/UsageLogsTable.jsx
@@ -120,6 +120,7 @@ const LogsTable = (logsData) => {
},
onPageChange: handlePageChange,
}}
+ hidePagination={true}
/>
);
};
diff --git a/web/src/components/table/usage-logs/index.jsx b/web/src/components/table/usage-logs/index.jsx
index d14a2d65..51336bbf 100644
--- a/web/src/components/table/usage-logs/index.jsx
+++ b/web/src/components/table/usage-logs/index.jsx
@@ -25,6 +25,7 @@ import LogsFilters from './UsageLogsFilters.jsx';
import ColumnSelectorModal from './modals/ColumnSelectorModal.jsx';
import UserInfoModal from './modals/UserInfoModal.jsx';
import { useLogsData } from '../../../hooks/usage-logs/useUsageLogsData.js';
+import { createCardProPagination } from '../../../helpers/utils';
const LogsPage = () => {
const logsData = useLogsData();
@@ -40,6 +41,13 @@ const LogsPage = () => {
type="type2"
statsArea={}
searchArea={}
+ paginationArea={createCardProPagination({
+ currentPage: logsData.activePage,
+ pageSize: logsData.pageSize,
+ total: logsData.logCount,
+ onPageChange: logsData.handlePageChange,
+ onPageSizeChange: logsData.handlePageSizeChange,
+ })}
t={logsData.t}
>
diff --git a/web/src/components/table/users/UsersTable.jsx b/web/src/components/table/users/UsersTable.jsx
index 53ca747e..cd93bf95 100644
--- a/web/src/components/table/users/UsersTable.jsx
+++ b/web/src/components/table/users/UsersTable.jsx
@@ -137,6 +137,7 @@ const UsersTable = (usersData) => {
onPageSizeChange: handlePageSizeChange,
onPageChange: handlePageChange,
}}
+ hidePagination={true}
loading={loading}
onRow={handleRow}
empty={
diff --git a/web/src/components/table/users/index.jsx b/web/src/components/table/users/index.jsx
index ce282aaf..cc477154 100644
--- a/web/src/components/table/users/index.jsx
+++ b/web/src/components/table/users/index.jsx
@@ -26,6 +26,7 @@ import UsersDescription from './UsersDescription.jsx';
import AddUserModal from './modals/AddUserModal.jsx';
import EditUserModal from './modals/EditUserModal.jsx';
import { useUsersData } from '../../../hooks/users/useUsersData';
+import { createCardProPagination } from '../../../helpers/utils';
const UsersPage = () => {
const usersData = useUsersData();
@@ -104,6 +105,13 @@ const UsersPage = () => {
/>
}
+ paginationArea={createCardProPagination({
+ currentPage: usersData.activePage,
+ pageSize: usersData.pageSize,
+ total: usersData.userCount,
+ onPageChange: usersData.handlePageChange,
+ onPageSizeChange: usersData.handlePageSizeChange,
+ })}
t={t}
>
diff --git a/web/src/helpers/utils.js b/web/src/helpers/utils.js
index dffb04d7..244b6058 100644
--- a/web/src/helpers/utils.js
+++ b/web/src/helpers/utils.js
@@ -17,13 +17,14 @@ along with this program. If not, see .
For commercial licensing, please contact support@quantumnous.com
*/
-import { Toast } from '@douyinfe/semi-ui';
+import { Toast, Pagination } from '@douyinfe/semi-ui';
import { toastConstants } from '../constants';
import React from 'react';
import { toast } from 'react-toastify';
import { THINK_TAG_REGEX, MESSAGE_ROLES } from '../constants/playground.constants';
import { TABLE_COMPACT_MODES_KEY } from '../constants';
import { MOBILE_BREAKPOINT } from '../hooks/common/useIsMobile.js';
+import { useIsMobile } from '../hooks/common/useIsMobile.js';
const HTMLToastContent = ({ htmlContent }) => {
return ;
@@ -567,3 +568,35 @@ export const modelSelectFilter = (input, option) => {
const val = (option?.value || '').toString().toLowerCase();
return val.includes(input.trim().toLowerCase());
};
+
+// -------------------------------
+// CardPro 分页配置组件
+// 用于创建 CardPro 的 paginationArea 配置
+export const createCardProPagination = ({
+ currentPage,
+ pageSize,
+ total,
+ onPageChange,
+ onPageSizeChange,
+ pageSizeOpts = [10, 20, 50, 100],
+ showSizeChanger = true,
+}) => {
+ const isMobile = useIsMobile();
+
+ if (!total || total <= 0) return null;
+
+ return (
+
+ );
+};