🔠 refactor: refine group label formatting in price info
Summary:
• Updated `helpers/utils.js` to display the “group” label without a colon, ensuring consistent typography with other price elements.
Details:
1. `formatPriceInfo`
– Changed `{t('分组')}:` to `{t('分组')}` for a cleaner look.
– Keeps spacing intact between label and selected group name.
2. No functional impact; purely visual polish.
This commit is contained in:
@@ -136,7 +136,7 @@ const PricingCardView = ({
|
|||||||
groupRatio,
|
groupRatio,
|
||||||
tokenUnit,
|
tokenUnit,
|
||||||
displayPrice,
|
displayPrice,
|
||||||
currency
|
currency,
|
||||||
});
|
});
|
||||||
return formatPriceInfo(priceData, t);
|
return formatPriceInfo(priceData, t);
|
||||||
};
|
};
|
||||||
@@ -302,7 +302,7 @@ const PricingCardView = ({
|
|||||||
{t('补全')}: {model.quota_type === 0 ? parseFloat(model.completion_ratio.toFixed(3)) : t('无')}
|
{t('补全')}: {model.quota_type === 0 ? parseFloat(model.completion_ratio.toFixed(3)) : t('无')}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{t('分组')}: {groupRatio[selectedGroup]}
|
{t('分组')}: {priceData.usedGroupRatio}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -581,13 +581,37 @@ export const calculateModelPrice = ({
|
|||||||
tokenUnit,
|
tokenUnit,
|
||||||
displayPrice,
|
displayPrice,
|
||||||
currency,
|
currency,
|
||||||
precision = 4
|
precision = 4,
|
||||||
}) => {
|
}) => {
|
||||||
|
// 1. 选择实际使用的分组
|
||||||
|
let usedGroup = selectedGroup;
|
||||||
|
let usedGroupRatio = groupRatio[selectedGroup];
|
||||||
|
|
||||||
|
if (selectedGroup === 'all' || usedGroupRatio === undefined) {
|
||||||
|
// 在模型可用分组中选择倍率最小的分组,若无则使用 1
|
||||||
|
let minRatio = Number.POSITIVE_INFINITY;
|
||||||
|
if (Array.isArray(record.enable_groups) && record.enable_groups.length > 0) {
|
||||||
|
record.enable_groups.forEach((g) => {
|
||||||
|
const r = groupRatio[g];
|
||||||
|
if (r !== undefined && r < minRatio) {
|
||||||
|
minRatio = r;
|
||||||
|
usedGroup = g;
|
||||||
|
usedGroupRatio = r;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果找不到合适分组倍率,回退为 1
|
||||||
|
if (usedGroupRatio === undefined) {
|
||||||
|
usedGroupRatio = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据计费类型计算价格
|
||||||
if (record.quota_type === 0) {
|
if (record.quota_type === 0) {
|
||||||
// 按量计费
|
// 按量计费
|
||||||
const inputRatioPriceUSD = record.model_ratio * 2 * groupRatio[selectedGroup];
|
const inputRatioPriceUSD = record.model_ratio * 2 * usedGroupRatio;
|
||||||
const completionRatioPriceUSD =
|
const completionRatioPriceUSD = record.model_ratio * record.completion_ratio * 2 * usedGroupRatio;
|
||||||
record.model_ratio * record.completion_ratio * 2 * groupRatio[selectedGroup];
|
|
||||||
|
|
||||||
const unitDivisor = tokenUnit === 'K' ? 1000 : 1;
|
const unitDivisor = tokenUnit === 'K' ? 1000 : 1;
|
||||||
const unitLabel = tokenUnit === 'K' ? 'K' : 'M';
|
const unitLabel = tokenUnit === 'K' ? 'K' : 'M';
|
||||||
@@ -602,22 +626,32 @@ export const calculateModelPrice = ({
|
|||||||
inputPrice: `${currency === 'CNY' ? '¥' : '$'}${numInput.toFixed(precision)}`,
|
inputPrice: `${currency === 'CNY' ? '¥' : '$'}${numInput.toFixed(precision)}`,
|
||||||
completionPrice: `${currency === 'CNY' ? '¥' : '$'}${numCompletion.toFixed(precision)}`,
|
completionPrice: `${currency === 'CNY' ? '¥' : '$'}${numCompletion.toFixed(precision)}`,
|
||||||
unitLabel,
|
unitLabel,
|
||||||
isPerToken: true
|
isPerToken: true,
|
||||||
};
|
usedGroup,
|
||||||
} else {
|
usedGroupRatio,
|
||||||
// 按次计费
|
|
||||||
const priceUSD = parseFloat(record.model_price) * groupRatio[selectedGroup];
|
|
||||||
const displayVal = displayPrice(priceUSD);
|
|
||||||
|
|
||||||
return {
|
|
||||||
price: displayVal,
|
|
||||||
isPerToken: false
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 按次计费
|
||||||
|
const priceUSD = parseFloat(record.model_price) * usedGroupRatio;
|
||||||
|
const displayVal = displayPrice(priceUSD);
|
||||||
|
|
||||||
|
return {
|
||||||
|
price: displayVal,
|
||||||
|
isPerToken: false,
|
||||||
|
usedGroup,
|
||||||
|
usedGroupRatio,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 格式化价格信息(用于卡片视图)
|
// 格式化价格信息(用于卡片视图)
|
||||||
export const formatPriceInfo = (priceData, t) => {
|
export const formatPriceInfo = (priceData, t) => {
|
||||||
|
const groupTag = priceData.usedGroup ? (
|
||||||
|
<span style={{ color: 'var(--semi-color-text-1)' }} className="ml-1 text-xs">
|
||||||
|
{t('分组')} {priceData.usedGroup}
|
||||||
|
</span>
|
||||||
|
) : null;
|
||||||
|
|
||||||
if (priceData.isPerToken) {
|
if (priceData.isPerToken) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -627,15 +661,19 @@ export const formatPriceInfo = (priceData, t) => {
|
|||||||
<span style={{ color: 'var(--semi-color-text-1)' }}>
|
<span style={{ color: 'var(--semi-color-text-1)' }}>
|
||||||
{t('补全')} {priceData.completionPrice}/{priceData.unitLabel}
|
{t('补全')} {priceData.completionPrice}/{priceData.unitLabel}
|
||||||
</span>
|
</span>
|
||||||
|
{groupTag}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
return (
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
<span style={{ color: 'var(--semi-color-text-1)' }}>
|
<span style={{ color: 'var(--semi-color-text-1)' }}>
|
||||||
{t('模型价格')} {priceData.price}
|
{t('模型价格')} {priceData.price}
|
||||||
</span>
|
</span>
|
||||||
);
|
{groupTag}
|
||||||
}
|
</>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const useModelPricingData = () => {
|
|||||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||||
const [modalImageUrl, setModalImageUrl] = useState('');
|
const [modalImageUrl, setModalImageUrl] = useState('');
|
||||||
const [isModalOpenurl, setIsModalOpenurl] = useState(false);
|
const [isModalOpenurl, setIsModalOpenurl] = useState(false);
|
||||||
const [selectedGroup, setSelectedGroup] = useState('default');
|
const [selectedGroup, setSelectedGroup] = useState('all');
|
||||||
const [showModelDetail, setShowModelDetail] = useState(false);
|
const [showModelDetail, setShowModelDetail] = useState(false);
|
||||||
const [selectedModel, setSelectedModel] = useState(null);
|
const [selectedModel, setSelectedModel] = useState(null);
|
||||||
const [filterGroup, setFilterGroup] = useState('all'); // 用于 Table 的可用分组筛选,"all" 表示不过滤
|
const [filterGroup, setFilterGroup] = useState('all'); // 用于 Table 的可用分组筛选,"all" 表示不过滤
|
||||||
@@ -180,7 +180,7 @@ export const useModelPricingData = () => {
|
|||||||
if (success) {
|
if (success) {
|
||||||
setGroupRatio(group_ratio);
|
setGroupRatio(group_ratio);
|
||||||
setUsableGroup(usable_group);
|
setUsableGroup(usable_group);
|
||||||
setSelectedGroup(userState.user ? userState.user.group : 'default');
|
setSelectedGroup('all');
|
||||||
// 构建供应商 Map 方便查找
|
// 构建供应商 Map 方便查找
|
||||||
const vendorMap = {};
|
const vendorMap = {};
|
||||||
if (Array.isArray(vendors)) {
|
if (Array.isArray(vendors)) {
|
||||||
@@ -233,12 +233,17 @@ export const useModelPricingData = () => {
|
|||||||
setSelectedGroup(group);
|
setSelectedGroup(group);
|
||||||
// 同时将分组过滤设置为该分组
|
// 同时将分组过滤设置为该分组
|
||||||
setFilterGroup(group);
|
setFilterGroup(group);
|
||||||
showInfo(
|
|
||||||
t('当前查看的分组为:{{group}},倍率为:{{ratio}}', {
|
if (group === 'all') {
|
||||||
group: group,
|
showInfo(t('已切换至最优倍率视图,每个模型使用其最低倍率分组'));
|
||||||
ratio: groupRatio[group],
|
} else {
|
||||||
}),
|
showInfo(
|
||||||
);
|
t('当前查看的分组为:{{group}},倍率为:{{ratio}}', {
|
||||||
|
group: group,
|
||||||
|
ratio: groupRatio[group] ?? 1,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const openModelDetail = (model) => {
|
const openModelDetail = (model) => {
|
||||||
|
|||||||
@@ -1916,5 +1916,6 @@
|
|||||||
"前缀名称匹配": "Prefix name matching",
|
"前缀名称匹配": "Prefix name matching",
|
||||||
"后缀名称匹配": "Suffix name matching",
|
"后缀名称匹配": "Suffix name matching",
|
||||||
"包含名称匹配": "Contains name matching",
|
"包含名称匹配": "Contains name matching",
|
||||||
"展开更多": "Expand more"
|
"展开更多": "Expand more",
|
||||||
|
"已切换至最优倍率视图,每个模型使用其最低倍率分组": "Switched to the optimal ratio view, each model uses its lowest ratio group"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user