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 ca38963..9ec627b 100644
--- a/web/src/components/table/model-pricing/modal/components/ModelPricingTable.jsx
+++ b/web/src/components/table/model-pricing/modal/components/ModelPricingTable.jsx
@@ -22,9 +22,12 @@ import { Card, Avatar, Typography, Table, Tag } from '@douyinfe/semi-ui';
import { IconCoinMoneyStroked } from '@douyinfe/semi-icons';
import {
calculateModelPrice,
+ formatDisplayPricingItem,
formatMatrixPrice,
getMatrixPricingUnit,
+ hasDisplayPricing,
hasMatrixPricing,
+ normalizeDisplayPricingItems,
} from '../../../../../helpers';
const { Text } = Typography;
@@ -44,6 +47,62 @@ const ModelPricingTable = ({
? modelData.enable_groups
: [];
const autoChain = autoGroups.filter((g) => modelEnableGroups.includes(g));
+ const renderDisplayPricingTable = () => {
+ const items = normalizeDisplayPricingItems(modelData).map((item) =>
+ formatDisplayPricingItem({ item, displayPrice, t }),
+ );
+ const columns = [
+ {
+ title: t('规格'),
+ dataIndex: 'specification',
+ render: (text) => {text},
+ },
+ {
+ title: t('供应商说明'),
+ dataIndex: 'official_supplier_tip',
+ render: (text) => {text || '-'},
+ },
+ {
+ title: t('价格'),
+ dataIndex: 'formattedPrice',
+ render: (text, record) => (
+
+
{text}
+ {record.originalPrice && (
+
+ {t('原价')} {record.originalPrice}
+
+ )}
+
+ ),
+ },
+ {
+ title: t('折扣'),
+ dataIndex: 'discountText',
+ render: (text) => text || '-',
+ },
+ ];
+
+ return (
+ <>
+
+ {t('展示价格仅用于估算,实际消耗以任务完成后的积分扣减为准。')}
+
+ ({
+ ...item,
+ key: `${item.specification}-${index}`,
+ }))}
+ columns={columns}
+ pagination={false}
+ size='small'
+ bordered={false}
+ className='!rounded-lg'
+ />
+ >
+ );
+ };
+
const renderMatrixPriceTable = () => {
const cfg = modelData?.pricing_config;
const dimensions = cfg?.dimensions || [];
@@ -124,6 +183,9 @@ const ModelPricingTable = ({
};
const renderGroupPriceTable = () => {
+ if (hasDisplayPricing(modelData)) {
+ return renderDisplayPricingTable();
+ }
if (hasMatrixPricing(modelData)) {
return renderMatrixPriceTable();
}
@@ -144,6 +206,7 @@ const ModelPricingTable = ({
tokenUnit,
displayPrice,
currency,
+ t,
})
: { inputPrice: '-', outputPrice: '-', price: '-' };
@@ -322,9 +385,13 @@ const ModelPricingTable = ({
-
{t('分组价格')}
+
+ {hasDisplayPricing(modelData) ? t('展示价格') : t('分组价格')}
+
- {t('不同用户分组的价格信息')}
+ {hasDisplayPricing(modelData)
+ ? t('展示价格,仅用于估算')
+ : t('不同用户分组的价格信息')}
diff --git a/web/src/components/table/model-pricing/modal/components/UserPriceComparison.jsx b/web/src/components/table/model-pricing/modal/components/UserPriceComparison.jsx
index a103a89..ff35788 100644
--- a/web/src/components/table/model-pricing/modal/components/UserPriceComparison.jsx
+++ b/web/src/components/table/model-pricing/modal/components/UserPriceComparison.jsx
@@ -7,17 +7,22 @@ const { Text } = Typography;
const UserPriceComparison = ({
modelName,
+ modelData,
currency,
tokenUnit,
displayPrice,
t,
}) => {
+ const hasDisplayPricing =
+ Array.isArray(modelData?.display_pricing) &&
+ modelData.display_pricing.length > 0;
+
const [loading, setLoading] = useState(false);
const [priceData, setPriceData] = useState(null);
useEffect(() => {
const fetchUserPrice = async () => {
- if (!modelName) return;
+ if (!modelName || hasDisplayPricing) return;
setLoading(true);
try {
const res = await API.get(
@@ -37,7 +42,7 @@ const UserPriceComparison = ({
}
};
fetchUserPrice();
- }, [modelName]);
+ }, [modelName, hasDisplayPricing]);
const currencySymbol = useMemo(() => {
if (currency === 'CNY') return '¥';
@@ -74,6 +79,8 @@ const UserPriceComparison = ({
return `${currencySymbol}${num.toFixed(4)}`;
};
+ if (hasDisplayPricing) return null;
+
if (loading) {
return (
diff --git a/web/src/components/table/model-pricing/view/card/PricingCardView.jsx b/web/src/components/table/model-pricing/view/card/PricingCardView.jsx
index 0418390..5e16842 100644
--- a/web/src/components/table/model-pricing/view/card/PricingCardView.jsx
+++ b/web/src/components/table/model-pricing/view/card/PricingCardView.jsx
@@ -38,6 +38,7 @@ import {
import {
stringToColor,
getLobeHubIcon,
+ hasDisplayPricing,
hasMatrixPricing,
calculateModelPrice,
} from '../../../../../helpers';
@@ -163,8 +164,41 @@ const PricingCardView = ({
tokenUnit,
displayPrice,
currency,
+ t,
});
+ if (priceData?.isDisplayPricing) {
+ return (
+
+ {String(priceData.price || '')
+ .split('\n')
+ .map((line) => (
+
+ {line}
+
+ ))}
+
{t('展示价格')}
+ {(priceData.details || []).map((detail, detailIndex) => (
+
+ {detail.specification}
+
+ {detail.formattedPrice}
+
+
+ ))}
+ {priceData.hiddenDetailCount > 0 && (
+
+ + {priceData.hiddenDetailCount}
+
+ )}
+
+ );
+ }
+
if (!priceData?.isMatrix) {
return null;
}
@@ -206,7 +240,13 @@ const PricingCardView = ({
-
);
- if (hasMatrixPricing(record)) {
+ if (hasDisplayPricing(record)) {
+ billingTag = (
+
+ {t('展示价格')}
+
+ );
+ } else if (hasMatrixPricing(record)) {
billingTag = (
{t('矩阵计费')}
diff --git a/web/src/components/table/model-pricing/view/table/PricingTableColumns.jsx b/web/src/components/table/model-pricing/view/table/PricingTableColumns.jsx
index 2c34870..e9cff94 100644
--- a/web/src/components/table/model-pricing/view/table/PricingTableColumns.jsx
+++ b/web/src/components/table/model-pricing/view/table/PricingTableColumns.jsx
@@ -24,6 +24,7 @@ import {
renderModelTag,
stringToColor,
calculateModelPrice,
+ hasDisplayPricing,
hasMatrixPricing,
getLobeHubIcon,
} from '../../../../../helpers';
@@ -53,6 +54,13 @@ function renderQuotaType(type, t) {
}
function renderBillingType(record, t) {
+ if (hasDisplayPricing(record)) {
+ return (
+
+ {t('展示价格')}
+
+ );
+ }
if (hasMatrixPricing(record)) {
return (
@@ -137,6 +145,7 @@ export const getPricingTableColumns = ({
tokenUnit,
displayPrice,
currency,
+ t,
});
priceDataCache.set(record, cache);
}
@@ -244,6 +253,23 @@ export const getPricingTableColumns = ({
render: (text, record, index) => {
const priceData = getPriceData(record);
+ if (priceData.isDisplayPricing) {
+ return (
+
+ {String(priceData.price || '')
+ .split('\n')
+ .map((line) => (
+
+ {line}
+
+ ))}
+
+ {t('展示价格,仅用于估算')}
+
+
+ );
+ }
+
if (priceData.isMatrix) {
return (
diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json
index ed3b03e..cbc0e49 100644
--- a/web/src/i18n/locales/en.json
+++ b/web/src/i18n/locales/en.json
@@ -3295,5 +3295,14 @@
"重试启动失败": "Failed to start retry",
"重试已启动": "Retry started",
"验证完成": "Verification complete",
- "暂无数据": "No data"
+ "暂无数据": "No data",
+ "展示价格,仅用于估算": "Display price, estimate only",
+ "展示价格仅用于估算,实际消耗以任务完成后的积分扣减为准。": "Display price is only an estimate. Actual consumption is based on the final quota deduction after the task completes.",
+ "规格": "Specification",
+ "供应商说明": "Supplier tip",
+ "折扣": "Discount",
+ "second": "second",
+ "call": "call",
+ "image": "image",
+ "video": "video"
}
diff --git a/web/src/i18n/locales/zh-CN.json b/web/src/i18n/locales/zh-CN.json
index f082d8e..1c8848c 100644
--- a/web/src/i18n/locales/zh-CN.json
+++ b/web/src/i18n/locales/zh-CN.json
@@ -3249,5 +3249,14 @@
"重试启动失败": "重试启动失败",
"重试已启动": "重试已启动",
"验证完成": "验证完成",
- "暂无数据": "暂无数据"
+ "暂无数据": "暂无数据",
+ "展示价格,仅用于估算": "展示价格,仅用于估算",
+ "展示价格仅用于估算,实际消耗以任务完成后的积分扣减为准。": "展示价格仅用于估算,实际消耗以任务完成后的积分扣减为准。",
+ "规格": "规格",
+ "供应商说明": "供应商说明",
+ "折扣": "折扣",
+ "second": "秒",
+ "call": "次",
+ "image": "张图片",
+ "video": "个视频"
}