diff --git a/controller/pricing.go b/controller/pricing.go
index e1719cf3..898c9f9f 100644
--- a/controller/pricing.go
+++ b/controller/pricing.go
@@ -42,9 +42,10 @@ func GetPricing(c *gin.Context) {
"success": true,
"data": pricing,
"vendors": model.GetVendors(),
- "group_ratio": groupRatio,
+ "group_ratio": groupRatio,
"usable_group": usableGroup,
"supported_endpoint": model.GetSupportedEndpointMap(),
+ "auto_groups": setting.AutoGroups,
})
}
diff --git a/web/src/components/table/model-pricing/layout/PricingPage.jsx b/web/src/components/table/model-pricing/layout/PricingPage.jsx
index 69ac2336..a2c34435 100644
--- a/web/src/components/table/model-pricing/layout/PricingPage.jsx
+++ b/web/src/components/table/model-pricing/layout/PricingPage.jsx
@@ -72,7 +72,6 @@ const PricingPage = () => {
visible={pricingData.showModelDetail}
onClose={pricingData.closeModelDetail}
modelData={pricingData.selectedModel}
- selectedGroup={pricingData.selectedGroup}
groupRatio={pricingData.groupRatio}
usableGroup={pricingData.usableGroup}
currency={pricingData.currency}
@@ -81,6 +80,7 @@ const PricingPage = () => {
showRatio={allProps.showRatio}
vendorsMap={pricingData.vendorsMap}
endpointMap={pricingData.endpointMap}
+ autoGroups={pricingData.autoGroups}
t={pricingData.t}
/>
diff --git a/web/src/components/table/model-pricing/modal/ModelDetailSideSheet.jsx b/web/src/components/table/model-pricing/modal/ModelDetailSideSheet.jsx
index 44a3607c..66a1bfe6 100644
--- a/web/src/components/table/model-pricing/modal/ModelDetailSideSheet.jsx
+++ b/web/src/components/table/model-pricing/modal/ModelDetailSideSheet.jsx
@@ -39,7 +39,6 @@ const ModelDetailSideSheet = ({
visible,
onClose,
modelData,
- selectedGroup,
groupRatio,
currency,
tokenUnit,
@@ -48,6 +47,7 @@ const ModelDetailSideSheet = ({
usableGroup,
vendorsMap,
endpointMap,
+ autoGroups,
t,
}) => {
const isMobile = useIsMobile();
@@ -86,13 +86,13 @@ const ModelDetailSideSheet = ({
>
diff --git a/web/src/components/table/model-pricing/modal/components/ModelPricingTable.jsx b/web/src/components/table/model-pricing/modal/components/ModelPricingTable.jsx
index 3d8d84be..de52eae6 100644
--- a/web/src/components/table/model-pricing/modal/components/ModelPricingTable.jsx
+++ b/web/src/components/table/model-pricing/modal/components/ModelPricingTable.jsx
@@ -18,7 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
import React from 'react';
-import { Card, Avatar, Typography, Table, Tag, Tooltip } from '@douyinfe/semi-ui';
+import { Card, Avatar, Typography, Table, Tag } from '@douyinfe/semi-ui';
import { IconCoinMoneyStroked } from '@douyinfe/semi-icons';
import { calculateModelPrice } from '../../../../../helpers';
@@ -26,34 +26,24 @@ const { Text } = Typography;
const ModelPricingTable = ({
modelData,
- selectedGroup,
groupRatio,
currency,
tokenUnit,
displayPrice,
showRatio,
usableGroup,
+ autoGroups = [],
t,
}) => {
- // 获取分组介绍
- const getGroupDescription = (groupName) => {
- const descriptions = {
- 'default': t('默认分组,适用于普通用户'),
- 'ssvip': t('超级VIP分组,享受最优惠价格'),
- 'openai官-优质': t('OpenAI官方优质分组,最快最稳,支持o1、realtime等'),
- 'origin': t('企业分组,OpenAI&Claude官方原价,不升价本分组稳定性可用性'),
- 'vip': t('VIP分组,享受优惠价格'),
- 'premium': t('高级分组,稳定可靠'),
- 'enterprise': t('企业级分组,专业服务'),
- };
- return descriptions[groupName] || t('用户分组');
- };
-
const renderGroupPriceTable = () => {
- const availableGroups = Object.keys(usableGroup || {}).filter(g => g !== '');
- if (availableGroups.length === 0) {
- availableGroups.push('default');
- }
+ // 仅展示模型可用的分组:模型 enable_groups 与用户可用分组的交集
+ const modelEnableGroups = Array.isArray(modelData?.enable_groups)
+ ? modelData.enable_groups
+ : [];
+ const availableGroups = Object.keys(usableGroup || {})
+ .filter(g => g !== '')
+ .filter(g => g !== 'auto')
+ .filter(g => modelEnableGroups.includes(g));
// 准备表格数据
const tableData = availableGroups.map(group => {
@@ -72,7 +62,6 @@ const ModelPricingTable = ({
return {
key: group,
group: group,
- description: getGroupDescription(group),
ratio: groupRatioValue,
billingType: modelData?.quota_type === 0 ? t('按量计费') : t('按次计费'),
inputPrice: modelData?.quota_type === 0 ? priceData.inputPrice : '-',
@@ -86,12 +75,10 @@ const ModelPricingTable = ({
{
title: t('分组'),
dataIndex: 'group',
- render: (text, record) => (
-
-
- {text}{t('分组')}
-
-
+ render: (text) => (
+
+ {text}{t('分组')}
+
),
},
];
@@ -182,6 +169,18 @@ const ModelPricingTable = ({
{t('不同用户分组的价格信息')}
+ {autoGroups && autoGroups.length > 0 && (
+
+ {t('auto分组调用链路')}
+ →
+ {autoGroups.map((g, idx) => (
+
+ {g}{t('分组')}
+ {idx < autoGroups.length - 1 && →}
+
+ ))}
+
+ )}
{renderGroupPriceTable()}
);
diff --git a/web/src/hooks/model-pricing/useModelPricingData.js b/web/src/hooks/model-pricing/useModelPricingData.js
index 966e346b..71c29a41 100644
--- a/web/src/hooks/model-pricing/useModelPricingData.js
+++ b/web/src/hooks/model-pricing/useModelPricingData.js
@@ -49,6 +49,7 @@ export const useModelPricingData = () => {
const [groupRatio, setGroupRatio] = useState({});
const [usableGroup, setUsableGroup] = useState({});
const [endpointMap, setEndpointMap] = useState({});
+ const [autoGroups, setAutoGroups] = useState([]);
const [statusState] = useContext(StatusContext);
const [userState] = useContext(UserContext);
@@ -160,7 +161,7 @@ export const useModelPricingData = () => {
setLoading(true);
let url = '/api/pricing';
const res = await API.get(url);
- const { success, message, data, vendors, group_ratio, usable_group, supported_endpoint } = res.data;
+ const { success, message, data, vendors, group_ratio, usable_group, supported_endpoint, auto_groups } = res.data;
if (success) {
setGroupRatio(group_ratio);
setUsableGroup(usable_group);
@@ -174,6 +175,7 @@ export const useModelPricingData = () => {
}
setVendorsMap(vendorMap);
setEndpointMap(supported_endpoint || {});
+ setAutoGroups(auto_groups || []);
setModelsFormat(data, group_ratio, vendorMap);
} else {
showError(message);
@@ -282,6 +284,7 @@ export const useModelPricingData = () => {
groupRatio,
usableGroup,
endpointMap,
+ autoGroups,
// 计算属性
priceRate,