Browse Source

Merge remote-tracking branch 'origin/alpha' into alpha

CaIon 5 months ago
parent
commit
969953039f
2 changed files with 59 additions and 30 deletions
  1. 57 29
      web/src/components/table/ModelPricing.js
  2. 2 1
      web/src/i18n/locales/en.json

+ 57 - 29
web/src/components/table/ModelPricing.js

@@ -17,7 +17,8 @@ import {
   Tabs,
   TabPane,
   Empty,
-  Switch
+  Switch,
+  Select
 } from '@douyinfe/semi-ui';
 import {
   IllustrationNoResult,
@@ -47,11 +48,12 @@ const ModelPricing = () => {
   const [pageSize, setPageSize] = useState(10);
 
   const [currency, setCurrency] = useState('USD');
+  const [showWithRecharge, setShowWithRecharge] = useState(false);
   const [tokenUnit, setTokenUnit] = useState('M');
   const [statusState] = useContext(StatusContext);
-  const priceRate = useMemo(() => {
-    return statusState?.status?.price || 1;
-  }, [statusState]);
+  // 充值汇率(price)与美元兑人民币汇率(usd_exchange_rate)
+  const priceRate = useMemo(() => statusState?.status?.price ?? 1, [statusState]);
+  const usdExchangeRate = useMemo(() => statusState?.status?.usd_exchange_rate ?? priceRate, [statusState, priceRate]);
 
   const rowSelection = useMemo(
     () => ({
@@ -134,6 +136,18 @@ const ModelPricing = () => {
     );
   }
 
+  const displayPrice = (usdPrice) => {
+    let priceInUSD = usdPrice;
+    if (showWithRecharge) {
+      priceInUSD = usdPrice * priceRate / usdExchangeRate;
+    }
+
+    if (currency === 'CNY') {
+      return `¥${(priceInUSD * usdExchangeRate).toFixed(3)}`;
+    }
+    return `$${priceInUSD.toFixed(3)}`;
+  };
+
   const columns = [
     {
       title: t('可用性'),
@@ -257,13 +271,6 @@ const ModelPricing = () => {
       title: (
         <div className="flex items-center space-x-2">
           <span>{t('模型价格')}</span>
-          {/* 货币切换 */}
-          <Switch
-            checked={currency === 'RMB'}
-            onChange={(checked) => setCurrency(checked ? 'RMB' : 'USD')}
-            checkedText="¥"
-            uncheckedText="$"
-          />
           {/* 计费单位切换 */}
           <Switch
             checked={tokenUnit === 'K'}
@@ -277,38 +284,38 @@ const ModelPricing = () => {
       render: (text, record, index) => {
         let content = text;
         if (record.quota_type === 0) {
-          let inputRatioPrice = record.model_ratio * 2 * groupRatio[selectedGroup];
-          let completionRatioPrice =
+          let inputRatioPriceUSD = record.model_ratio * 2 * groupRatio[selectedGroup];
+          let completionRatioPriceUSD =
             record.model_ratio * record.completion_ratio * 2 * groupRatio[selectedGroup];
 
-          if (currency === 'RMB') {
-            inputRatioPrice = inputRatioPrice * priceRate;
-            completionRatioPrice = completionRatioPrice * priceRate;
-          }
-
           const unitDivisor = tokenUnit === 'K' ? 1000 : 1;
           const unitLabel = tokenUnit === 'K' ? 'K' : 'M';
-          inputRatioPrice = inputRatioPrice / unitDivisor;
-          completionRatioPrice = completionRatioPrice / unitDivisor;
+
+          let displayInput = displayPrice(inputRatioPriceUSD);
+          let displayCompletion = displayPrice(completionRatioPriceUSD);
+
+          const divisor = unitDivisor;
+          const numInput = parseFloat(displayInput.replace(/[^0-9.]/g, '')) / divisor;
+          const numCompletion = parseFloat(displayCompletion.replace(/[^0-9.]/g, '')) / divisor;
+
+          displayInput = `${currency === 'CNY' ? '¥' : '$'}${numInput.toFixed(3)}`;
+          displayCompletion = `${currency === 'CNY' ? '¥' : '$'}${numCompletion.toFixed(3)}`;
           content = (
             <div className="space-y-1">
               <div className="text-gray-700">
-                {t('提示')} {currency === 'USD' ? '$' : '¥'}{inputRatioPrice.toFixed(3)} / 1{unitLabel} tokens
+                {t('提示')} {displayInput} / 1{unitLabel} tokens
               </div>
               <div className="text-gray-700">
-                {t('补全')} {currency === 'USD' ? '$' : '¥'}{completionRatioPrice.toFixed(3)} / 1{unitLabel} tokens
+                {t('补全')} {displayCompletion} / 1{unitLabel} tokens
               </div>
             </div>
           );
         } else {
-          let price = parseFloat(text) * groupRatio[selectedGroup];
-
-          if (currency === 'RMB') {
-            price = price * priceRate;
-          }
+          let priceUSD = parseFloat(text) * groupRatio[selectedGroup];
+          let displayVal = displayPrice(priceUSD);
           content = (
             <div className="text-gray-700">
-              {t('模型价格')}:{currency === 'USD' ? '$' : '¥'}{price.toFixed(3)}
+              {t('模型价格')}:{displayVal}
             </div>
           );
         }
@@ -482,9 +489,30 @@ const ModelPricing = () => {
         >
           {t('复制选中模型')}
         </Button>
+
+        {/* 充值价格显示开关 */}
+        <Space align="center">
+          <span>{t('以充值价格显示')}</span>
+          <Switch
+            checked={showWithRecharge}
+            onChange={setShowWithRecharge}
+            size="small"
+          />
+          {showWithRecharge && (
+            <Select
+              value={currency}
+              onChange={setCurrency}
+              size="small"
+              style={{ width: 100 }}
+            >
+              <Select.Option value="USD">USD ($)</Select.Option>
+              <Select.Option value="CNY">CNY (¥)</Select.Option>
+            </Select>
+          )}
+        </Space>
       </div>
     </Card>
-  ), [selectedRowKeys, t]);
+  ), [selectedRowKeys, t, showWithRecharge, currency]);
 
   const ModelTable = useMemo(() => (
     <Card className="!rounded-xl overflow-hidden" bordered={false}>

+ 2 - 1
web/src/i18n/locales/en.json

@@ -1778,5 +1778,6 @@
   "切换为单密钥模式": "Switch to single key mode",
   "将仅保留第一个密钥文件,其余文件将被移除,是否继续?": "Only the first key file will be retained, and the remaining files will be removed. Continue?",
   "自定义模型名称": "Custom model name",
-  "启用全部密钥": "Enable all keys"
+  "启用全部密钥": "Enable all keys",
+  "以充值价格显示": "Show with recharge price"
 }