Просмотр исходного кода

🐛 fix: group-ratio display & deduplicate price logic in model-pricing views

Summary
• Ensure “Group Ratio” shows correctly when “All” groups are selected.
• Eliminate redundant price calculations in both card and table views.

Details
1. PricingCardView.jsx
   • Removed obsolete renderPriceInfo function.
   • Calculate priceData once per model and reuse for header price string and footer ratio block.
   • Display priceData.usedGroupRatio as the group ratio fallback.

2. PricingTableColumns.js
   • Introduced WeakMap-based cache (getPriceData) to compute priceData only once per row.
   • Updated ratioColumn & priceColumn to reuse cached priceData.
   • Now displays priceData.usedGroupRatio, preventing empty cells for “All” group.

Benefits
• Correct visual output for group ratio across all views.
• Reduced duplicate calculations, improving render performance.
• Removed dead code, keeping components clean and maintainable.
t0ng7u 6 месяцев назад
Родитель
Сommit
936b1f8d09

+ 11 - 15
web/src/components/table/model-pricing/view/card/PricingCardView.jsx

@@ -128,19 +128,6 @@ const PricingCardView = ({
     return record.description || '';
     return record.description || '';
   };
   };
 
 
-  // 渲染价格信息
-  const renderPriceInfo = (record) => {
-    const priceData = calculateModelPrice({
-      record,
-      selectedGroup,
-      groupRatio,
-      tokenUnit,
-      displayPrice,
-      currency,
-    });
-    return formatPriceInfo(priceData, t);
-  };
-
   // 渲染标签
   // 渲染标签
   const renderTags = (record) => {
   const renderTags = (record) => {
     // 计费类型标签(左边)
     // 计费类型标签(左边)
@@ -221,6 +208,15 @@ const PricingCardView = ({
           const modelKey = getModelKey(model);
           const modelKey = getModelKey(model);
           const isSelected = selectedRowKeys.includes(modelKey);
           const isSelected = selectedRowKeys.includes(modelKey);
 
 
+          const priceData = calculateModelPrice({
+            record: model,
+            selectedGroup,
+            groupRatio,
+            tokenUnit,
+            displayPrice,
+            currency,
+          });
+
           return (
           return (
             <Card
             <Card
               key={modelKey || index}
               key={modelKey || index}
@@ -238,7 +234,7 @@ const PricingCardView = ({
                         {model.model_name}
                         {model.model_name}
                       </h3>
                       </h3>
                       <div className="flex items-center gap-3 text-xs mt-1">
                       <div className="flex items-center gap-3 text-xs mt-1">
-                        {renderPriceInfo(model)}
+                        {formatPriceInfo(priceData, t)}
                       </div>
                       </div>
                     </div>
                     </div>
                   </div>
                   </div>
@@ -313,7 +309,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('分组')}: {priceData.usedGroupRatio}
+                          {t('分组')}: {priceData?.usedGroupRatio ?? '-'}
                         </div>
                         </div>
                       </div>
                       </div>
                     </div>
                     </div>

+ 25 - 13
web/src/components/table/model-pricing/view/table/PricingTableColumns.js

@@ -98,6 +98,25 @@ export const getPricingTableColumns = ({
   displayPrice,
   displayPrice,
   showRatio,
   showRatio,
 }) => {
 }) => {
+
+  const priceDataCache = new WeakMap();
+
+  const getPriceData = (record) => {
+    let cache = priceDataCache.get(record);
+    if (!cache) {
+      cache = calculateModelPrice({
+        record,
+        selectedGroup,
+        groupRatio,
+        tokenUnit,
+        displayPrice,
+        currency,
+      });
+      priceDataCache.set(record, cache);
+    }
+    return cache;
+  };
+
   const endpointColumn = {
   const endpointColumn = {
     title: t('可用端点类型'),
     title: t('可用端点类型'),
     dataIndex: 'supported_endpoint_types',
     dataIndex: 'supported_endpoint_types',
@@ -167,21 +186,21 @@ export const getPricingTableColumns = ({
     dataIndex: 'model_ratio',
     dataIndex: 'model_ratio',
     render: (text, record, index) => {
     render: (text, record, index) => {
       const completionRatio = parseFloat(record.completion_ratio.toFixed(3));
       const completionRatio = parseFloat(record.completion_ratio.toFixed(3));
-      const content = (
+      const priceData = getPriceData(record);
+
+      return (
         <div className="space-y-1">
         <div className="space-y-1">
           <div className="text-gray-700">
           <div className="text-gray-700">
             {t('模型倍率')}:{record.quota_type === 0 ? text : t('无')}
             {t('模型倍率')}:{record.quota_type === 0 ? text : t('无')}
           </div>
           </div>
           <div className="text-gray-700">
           <div className="text-gray-700">
-            {t('补全倍率')}:
-            {record.quota_type === 0 ? completionRatio : t('无')}
+            {t('补全倍率')}:{record.quota_type === 0 ? completionRatio : t('无')}
           </div>
           </div>
           <div className="text-gray-700">
           <div className="text-gray-700">
-            {t('分组倍率')}:{groupRatio[selectedGroup]}
+            {t('分组倍率')}:{priceData?.usedGroupRatio ?? '-'}
           </div>
           </div>
         </div>
         </div>
       );
       );
-      return content;
     },
     },
   };
   };
 
 
@@ -190,14 +209,7 @@ export const getPricingTableColumns = ({
     dataIndex: 'model_price',
     dataIndex: 'model_price',
     fixed: 'right',
     fixed: 'right',
     render: (text, record, index) => {
     render: (text, record, index) => {
-      const priceData = calculateModelPrice({
-        record,
-        selectedGroup,
-        groupRatio,
-        tokenUnit,
-        displayPrice,
-        currency
-      });
+      const priceData = getPriceData(record);
 
 
       if (priceData.isPerToken) {
       if (priceData.isPerToken) {
         return (
         return (