+ );
+ }
+ return content;
+ },
+ },
+ ];
+};
\ No newline at end of file
diff --git a/web/src/components/table/model-pricing/ModelPricingFilters.jsx b/web/src/components/table/model-pricing/ModelPricingFilters.jsx
new file mode 100644
index 00000000..57b5e7e1
--- /dev/null
+++ b/web/src/components/table/model-pricing/ModelPricingFilters.jsx
@@ -0,0 +1,87 @@
+/*
+Copyright (C) 2025 QuantumNous
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+
+For commercial licensing, please contact support@quantumnous.com
+*/
+
+import React, { useMemo } from 'react';
+import { Card, Input, Button, Space, Switch, Select } from '@douyinfe/semi-ui';
+import { IconSearch, IconCopy } from '@douyinfe/semi-icons';
+
+const ModelPricingFilters = ({
+ selectedRowKeys,
+ copyText,
+ showWithRecharge,
+ setShowWithRecharge,
+ currency,
+ setCurrency,
+ handleChange,
+ handleCompositionStart,
+ handleCompositionEnd,
+ t
+}) => {
+ const SearchAndActions = useMemo(() => (
+
+
+
+ ), [selectedRowKeys, t, showWithRecharge, currency, handleCompositionStart, handleCompositionEnd, handleChange, copyText, setShowWithRecharge, setCurrency]);
+
+ return SearchAndActions;
+};
+
+export default ModelPricingFilters;
\ No newline at end of file
diff --git a/web/src/components/table/model-pricing/ModelPricingHeader.jsx b/web/src/components/table/model-pricing/ModelPricingHeader.jsx
new file mode 100644
index 00000000..40075f3a
--- /dev/null
+++ b/web/src/components/table/model-pricing/ModelPricingHeader.jsx
@@ -0,0 +1,123 @@
+/*
+Copyright (C) 2025 QuantumNous
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+
+For commercial licensing, please contact support@quantumnous.com
+*/
+
+import React from 'react';
+import { Card } from '@douyinfe/semi-ui';
+import { IconVerify, IconLayers, IconInfoCircle } from '@douyinfe/semi-icons';
+import { AlertCircle } from 'lucide-react';
+
+const ModelPricingHeader = ({
+ userState,
+ groupRatio,
+ selectedGroup,
+ models,
+ t
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default ModelPricingHeader;
\ No newline at end of file
diff --git a/web/src/components/table/model-pricing/ModelPricingTable.jsx b/web/src/components/table/model-pricing/ModelPricingTable.jsx
new file mode 100644
index 00000000..22d94f29
--- /dev/null
+++ b/web/src/components/table/model-pricing/ModelPricingTable.jsx
@@ -0,0 +1,124 @@
+/*
+Copyright (C) 2025 QuantumNous
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+
+For commercial licensing, please contact support@quantumnous.com
+*/
+
+import React, { useMemo } from 'react';
+import { Card, Table, Empty } from '@douyinfe/semi-ui';
+import {
+ IllustrationNoResult,
+ IllustrationNoResultDark
+} from '@douyinfe/semi-illustrations';
+import { getModelPricingColumns } from './ModelPricingColumnDefs.js';
+
+const ModelPricingTable = ({
+ filteredModels,
+ loading,
+ rowSelection,
+ pageSize,
+ setPageSize,
+ selectedGroup,
+ usableGroup,
+ groupRatio,
+ copyText,
+ setModalImageUrl,
+ setIsModalOpenurl,
+ currency,
+ showWithRecharge,
+ tokenUnit,
+ setTokenUnit,
+ displayPrice,
+ filteredValue,
+ handleGroupClick,
+ t
+}) => {
+ const columns = useMemo(() => {
+ return getModelPricingColumns({
+ t,
+ selectedGroup,
+ usableGroup,
+ groupRatio,
+ copyText,
+ setModalImageUrl,
+ setIsModalOpenurl,
+ currency,
+ showWithRecharge,
+ tokenUnit,
+ setTokenUnit,
+ displayPrice,
+ handleGroupClick,
+ });
+ }, [
+ t,
+ selectedGroup,
+ usableGroup,
+ groupRatio,
+ copyText,
+ setModalImageUrl,
+ setIsModalOpenurl,
+ currency,
+ showWithRecharge,
+ tokenUnit,
+ setTokenUnit,
+ displayPrice,
+ handleGroupClick,
+ ]);
+
+ // 更新列定义中的 filteredValue
+ const tableColumns = useMemo(() => {
+ return columns.map(column => {
+ if (column.dataIndex === 'model_name') {
+ return {
+ ...column,
+ filteredValue
+ };
+ }
+ return column;
+ });
+ }, [columns, filteredValue]);
+
+ const ModelTable = useMemo(() => (
+
+
}
+ darkModeImage={}
+ description={t('搜索无结果')}
+ style={{ padding: 30 }}
+ />
+ }
+ pagination={{
+ defaultPageSize: 10,
+ pageSize: pageSize,
+ showSizeChanger: true,
+ pageSizeOptions: [10, 20, 50, 100],
+ onPageSizeChange: (size) => setPageSize(size),
+ }}
+ />
+
+ ), [filteredModels, loading, tableColumns, rowSelection, pageSize, setPageSize, t]);
+
+ return ModelTable;
+};
+
+export default ModelPricingTable;
\ No newline at end of file
diff --git a/web/src/components/table/model-pricing/ModelPricingTabs.jsx b/web/src/components/table/model-pricing/ModelPricingTabs.jsx
new file mode 100644
index 00000000..11a58b79
--- /dev/null
+++ b/web/src/components/table/model-pricing/ModelPricingTabs.jsx
@@ -0,0 +1,67 @@
+/*
+Copyright (C) 2025 QuantumNous
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+
+For commercial licensing, please contact support@quantumnous.com
+*/
+
+import React from 'react';
+import { Tabs, TabPane, Tag } from '@douyinfe/semi-ui';
+
+const ModelPricingTabs = ({
+ activeKey,
+ setActiveKey,
+ modelCategories,
+ categoryCounts,
+ availableCategories,
+ t
+}) => {
+ return (
+ setActiveKey(key)}
+ className="mt-2"
+ >
+ {Object.entries(modelCategories)
+ .filter(([key]) => availableCategories.includes(key))
+ .map(([key, category]) => {
+ const modelCount = categoryCounts[key] || 0;
+
+ return (
+
+ {category.icon && {category.icon}}
+ {category.label}
+
+ {modelCount}
+
+
+ }
+ itemKey={key}
+ key={key}
+ />
+ );
+ })}
+
+ );
+};
+
+export default ModelPricingTabs;
\ No newline at end of file
diff --git a/web/src/components/table/model-pricing/index.jsx b/web/src/components/table/model-pricing/index.jsx
new file mode 100644
index 00000000..a8641ce5
--- /dev/null
+++ b/web/src/components/table/model-pricing/index.jsx
@@ -0,0 +1,66 @@
+/*
+Copyright (C) 2025 QuantumNous
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see .
+
+For commercial licensing, please contact support@quantumnous.com
+*/
+
+import React from 'react';
+import { Layout, Card, ImagePreview } from '@douyinfe/semi-ui';
+import ModelPricingTabs from './ModelPricingTabs.jsx';
+import ModelPricingFilters from './ModelPricingFilters.jsx';
+import ModelPricingTable from './ModelPricingTable.jsx';
+import ModelPricingHeader from './ModelPricingHeader.jsx';
+import { useModelPricingData } from '../../../hooks/model-pricing/useModelPricingData.js';
+
+const ModelPricingPage = () => {
+ const modelPricingData = useModelPricingData();
+
+ return (
+