diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json index dcd2b587..aade2fd3 100644 --- a/web/src/i18n/locales/en.json +++ b/web/src/i18n/locales/en.json @@ -2470,6 +2470,19 @@ "自定义请求体模式": "Custom Request Body Mode", "自定义货币": "Custom currency", "自定义货币符号": "Custom currency symbol", + "自定义货币符号将显示在所有额度数值前,例如 €1.50": "Custom currency symbol will appear before all quota amounts, e.g. €1.50", + "额度展示类型": "Quota display type", + "站点所有额度将以美元 ($) 显示": "All site quotas will be displayed in USD ($)", + "站点所有额度将按汇率换算为人民币 (¥) 显示": "All site quotas will be converted to CNY (¥) using the exchange rate", + "站点所有额度将以原始 Token 数显示,不做货币换算": "All site quotas will be displayed as raw token counts without currency conversion", + "站点所有额度将按汇率换算为自定义货币显示": "All site quotas will be converted to custom currency using the exchange rate", + "汇率": "Exchange rate", + "每美元对应 Token 数": "Tokens per USD", + "预览效果": "Preview", + "请输入汇率": "Please enter the exchange rate", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为人民币,不影响内部计费": "The system uses USD as the base pricing unit. User balance, top-up amounts, model pricing, usage logs — all displayed amounts will be converted to CNY at this rate. Internal billing is not affected.", + "系统内部计费精度,默认 500000,修改可能导致计费异常,请谨慎操作": "Internal billing precision, default 500000. Changing this may cause billing anomalies — proceed with caution.", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为自定义货币,不影响内部计费": "The system uses USD as the base pricing unit. User balance, top-up amounts, model pricing, usage logs — all displayed amounts will be converted to custom currency at this rate. Internal billing is not affected.", "自定义错误响应": "Custom Error Response", "自定义镜像": "Custom Image", "自用模式": "Self-use mode", diff --git a/web/src/i18n/locales/fr.json b/web/src/i18n/locales/fr.json index 8d6d68dd..ec0689fe 100644 --- a/web/src/i18n/locales/fr.json +++ b/web/src/i18n/locales/fr.json @@ -2437,6 +2437,19 @@ "自定义请求体模式": "Mode de corps de requête personnalisé", "自定义货币": "Devise personnalisée", "自定义货币符号": "Symbole de devise personnalisé", + "自定义货币符号将显示在所有额度数值前,例如 €1.50": "Le symbole de devise personnalisé sera affiché avant tous les montants de quota, par ex. €1.50", + "额度展示类型": "Type d'affichage du quota", + "站点所有额度将以美元 ($) 显示": "Tous les quotas du site seront affichés en USD ($)", + "站点所有额度将按汇率换算为人民币 (¥) 显示": "Tous les quotas du site seront convertis en CNY (¥) selon le taux de change", + "站点所有额度将以原始 Token 数显示,不做货币换算": "Tous les quotas du site seront affichés en nombre brut de tokens sans conversion monétaire", + "站点所有额度将按汇率换算为自定义货币显示": "Tous les quotas du site seront convertis en devise personnalisée selon le taux de change", + "汇率": "Taux de change", + "每美元对应 Token 数": "Tokens par USD", + "预览效果": "Aperçu", + "请输入汇率": "Veuillez saisir le taux de change", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为人民币,不影响内部计费": "Le système utilise l'USD comme unité de tarification de base. Solde utilisateur, montants de recharge, tarification des modèles, journaux d'utilisation — tous les montants affichés seront convertis en CNY à ce taux. La facturation interne n'est pas affectée.", + "系统内部计费精度,默认 500000,修改可能导致计费异常,请谨慎操作": "Précision de facturation interne, par défaut 500000. Modifier cette valeur peut provoquer des anomalies de facturation — procédez avec prudence.", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为自定义货币,不影响内部计费": "Le système utilise l'USD comme unité de tarification de base. Solde utilisateur, montants de recharge, tarification des modèles, journaux d'utilisation — tous les montants affichés seront convertis en devise personnalisée à ce taux. La facturation interne n'est pas affectée.", "自定义错误响应": "Réponse d'erreur personnalisée", "自定义镜像": "Custom Image", "自用模式": "Mode auto-utilisation", diff --git a/web/src/i18n/locales/ja.json b/web/src/i18n/locales/ja.json index 48fd686d..73ba69e5 100644 --- a/web/src/i18n/locales/ja.json +++ b/web/src/i18n/locales/ja.json @@ -2418,6 +2418,19 @@ "自定义请求体模式": "カスタムリクエストボディモード", "自定义货币": "カスタム通貨", "自定义货币符号": "カスタム通貨記号", + "自定义货币符号将显示在所有额度数值前,例如 €1.50": "カスタム通貨記号はすべてのクォータ金額の前に表示されます(例:€1.50)", + "额度展示类型": "クォータ表示タイプ", + "站点所有额度将以美元 ($) 显示": "サイトのすべてのクォータは米ドル ($) で表示されます", + "站点所有额度将按汇率换算为人民币 (¥) 显示": "サイトのすべてのクォータは為替レートで人民元 (¥) に換算して表示されます", + "站点所有额度将以原始 Token 数显示,不做货币换算": "サイトのすべてのクォータは通貨換算なしで元のトークン数で表示されます", + "站点所有额度将按汇率换算为自定义货币显示": "サイトのすべてのクォータは為替レートでカスタム通貨に換算して表示されます", + "汇率": "為替レート", + "每美元对应 Token 数": "1米ドルあたりのトークン数", + "预览效果": "プレビュー", + "请输入汇率": "為替レートを入力してください", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为人民币,不影响内部计费": "システムは米ドル (USD) を基準通貨として使用しています。ユーザー残高、チャージ金額、モデル価格、使用ログなど、すべての金額表示がこのレートで人民元に換算されます。内部課金には影響しません。", + "系统内部计费精度,默认 500000,修改可能导致计费异常,请谨慎操作": "システム内部の課金精度、デフォルト500000。変更すると課金異常が発生する可能性があります — 慎重に操作してください。", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为自定义货币,不影响内部计费": "システムは米ドル (USD) を基準通貨として使用しています。ユーザー残高、チャージ金額、モデル価格、使用ログなど、すべての金額表示がこのレートでカスタム通貨に換算されます。内部課金には影響しません。", "自定义错误响应": "カスタムエラーレスポンス", "自定义镜像": "Custom Image", "自用模式": "個人モード", diff --git a/web/src/i18n/locales/ru.json b/web/src/i18n/locales/ru.json index 5c0b2889..f0590538 100644 --- a/web/src/i18n/locales/ru.json +++ b/web/src/i18n/locales/ru.json @@ -2451,6 +2451,19 @@ "自定义请求体模式": "Режим пользовательского тела запроса", "自定义货币": "Пользовательская валюта", "自定义货币符号": "Пользовательский символ валюты", + "自定义货币符号将显示在所有额度数值前,例如 €1.50": "Пользовательский символ валюты будет отображаться перед всеми суммами квот, например €1.50", + "额度展示类型": "Тип отображения квоты", + "站点所有额度将以美元 ($) 显示": "Все квоты сайта будут отображаться в долларах США ($)", + "站点所有额度将按汇率换算为人民币 (¥) 显示": "Все квоты сайта будут конвертированы в юани (¥) по курсу обмена", + "站点所有额度将以原始 Token 数显示,不做货币换算": "Все квоты сайта будут отображаться в виде необработанного количества токенов без валютной конвертации", + "站点所有额度将按汇率换算为自定义货币显示": "Все квоты сайта будут конвертированы в пользовательскую валюту по курсу обмена", + "汇率": "Обменный курс", + "每美元对应 Token 数": "Токенов за 1 доллар", + "预览效果": "Предпросмотр", + "请输入汇率": "Пожалуйста, введите обменный курс", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为人民币,不影响内部计费": "Система использует USD как базовую валюту ценообразования. Баланс пользователя, суммы пополнения, цены моделей, журналы использования — все отображаемые суммы конвертируются в юани по этому курсу. Внутренняя тарификация не затрагивается.", + "系统内部计费精度,默认 500000,修改可能导致计费异常,请谨慎操作": "Внутренняя точность тарификации, по умолчанию 500000. Изменение может привести к аномалиям тарификации — действуйте осторожно.", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为自定义货币,不影响内部计费": "Система использует USD как базовую валюту ценообразования. Баланс пользователя, суммы пополнения, цены моделей, журналы использования — все отображаемые суммы конвертируются в пользовательскую валюту по этому курсу. Внутренняя тарификация не затрагивается.", "自定义错误响应": "Пользовательский ответ об ошибке", "自定义镜像": "Custom Image", "自用模式": "Режим личного использования", diff --git a/web/src/i18n/locales/vi.json b/web/src/i18n/locales/vi.json index 76a88e65..936ebc8d 100644 --- a/web/src/i18n/locales/vi.json +++ b/web/src/i18n/locales/vi.json @@ -2751,6 +2751,18 @@ "自定义请求体模式": "Chế độ nội dung yêu cầu tùy chỉnh", "自定义货币": "Tiền tệ tùy chỉnh", "自定义货币符号": "Ký hiệu tiền tệ tùy chỉnh", + "自定义货币符号将显示在所有额度数值前,例如 €1.50": "Ký hiệu tiền tệ tùy chỉnh sẽ hiển thị trước tất cả số tiền hạn mức, ví dụ €1.50", + "额度展示类型": "Loại hiển thị hạn mức", + "站点所有额度将以美元 ($) 显示": "Tất cả hạn mức trang web sẽ được hiển thị bằng USD ($)", + "站点所有额度将按汇率换算为人民币 (¥) 显示": "Tất cả hạn mức trang web sẽ được chuyển đổi sang CNY (¥) theo tỷ giá hối đoái", + "站点所有额度将以原始 Token 数显示,不做货币换算": "Tất cả hạn mức trang web sẽ được hiển thị dưới dạng số token thô, không chuyển đổi tiền tệ", + "站点所有额度将按汇率换算为自定义货币显示": "Tất cả hạn mức trang web sẽ được chuyển đổi sang tiền tệ tùy chỉnh theo tỷ giá hối đoái", + "每美元对应 Token 数": "Số token trên mỗi USD", + "预览效果": "Xem trước", + "请输入汇率": "Vui lòng nhập tỷ giá hối đoái", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为人民币,不影响内部计费": "Hệ thống sử dụng USD làm đơn vị định giá cơ sở. Số dư người dùng, số tiền nạp, giá mô hình, nhật ký sử dụng — tất cả số tiền hiển thị được chuyển đổi sang CNY theo tỷ giá này. Thanh toán nội bộ không bị ảnh hưởng.", + "系统内部计费精度,默认 500000,修改可能导致计费异常,请谨慎操作": "Độ chính xác thanh toán nội bộ, mặc định 500000. Thay đổi có thể gây ra lỗi thanh toán — hãy thận trọng.", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为自定义货币,不影响内部计费": "Hệ thống sử dụng USD làm đơn vị định giá cơ sở. Số dư người dùng, số tiền nạp, giá mô hình, nhật ký sử dụng — tất cả số tiền hiển thị được chuyển đổi sang tiền tệ tùy chỉnh theo tỷ giá này. Thanh toán nội bộ không bị ảnh hưởng.", "自定义错误响应": "Phản hồi lỗi tùy chỉnh", "自定义镜像": "Custom Image", "自用模式": "Chế độ tự dùng", diff --git a/web/src/i18n/locales/zh-CN.json b/web/src/i18n/locales/zh-CN.json index b6f355fb..99a721ab 100644 --- a/web/src/i18n/locales/zh-CN.json +++ b/web/src/i18n/locales/zh-CN.json @@ -1985,6 +1985,19 @@ "自定义请求体模式": "自定义请求体模式", "自定义货币": "自定义货币", "自定义货币符号": "自定义货币符号", + "自定义货币符号将显示在所有额度数值前,例如 €1.50": "自定义货币符号将显示在所有额度数值前,例如 €1.50", + "额度展示类型": "额度展示类型", + "站点所有额度将以美元 ($) 显示": "站点所有额度将以美元 ($) 显示", + "站点所有额度将按汇率换算为人民币 (¥) 显示": "站点所有额度将按汇率换算为人民币 (¥) 显示", + "站点所有额度将以原始 Token 数显示,不做货币换算": "站点所有额度将以原始 Token 数显示,不做货币换算", + "站点所有额度将按汇率换算为自定义货币显示": "站点所有额度将按汇率换算为自定义货币显示", + "汇率": "汇率", + "每美元对应 Token 数": "每美元对应 Token 数", + "预览效果": "预览效果", + "请输入汇率": "请输入汇率", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为人民币,不影响内部计费": "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为人民币,不影响内部计费", + "系统内部计费精度,默认 500000,修改可能导致计费异常,请谨慎操作": "系统内部计费精度,默认 500000,修改可能导致计费异常,请谨慎操作", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为自定义货币,不影响内部计费": "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为自定义货币,不影响内部计费", "自定义镜像": "自定义镜像", "自用模式": "自用模式", "自适应列表": "自适应列表", diff --git a/web/src/i18n/locales/zh-TW.json b/web/src/i18n/locales/zh-TW.json index 584f3303..7fa77701 100644 --- a/web/src/i18n/locales/zh-TW.json +++ b/web/src/i18n/locales/zh-TW.json @@ -1995,6 +1995,19 @@ "自定义请求体模式": "自訂請求體模式", "自定义货币": "自訂貨幣", "自定义货币符号": "自訂貨幣符號", + "自定义货币符号将显示在所有额度数值前,例如 €1.50": "自訂貨幣符號將顯示在所有額度數值前,例如 €1.50", + "额度展示类型": "額度展示類型", + "站点所有额度将以美元 ($) 显示": "站點所有額度將以美元 ($) 顯示", + "站点所有额度将按汇率换算为人民币 (¥) 显示": "站點所有額度將按匯率換算為人民幣 (¥) 顯示", + "站点所有额度将以原始 Token 数显示,不做货币换算": "站點所有額度將以原始 Token 數顯示,不做貨幣換算", + "站点所有额度将按汇率换算为自定义货币显示": "站點所有額度將按匯率換算為自訂貨幣顯示", + "汇率": "匯率", + "每美元对应 Token 数": "每美元對應 Token 數", + "预览效果": "預覽效果", + "请输入汇率": "請輸入匯率", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为人民币,不影响内部计费": "系統內部以美元 (USD) 為基準計價。用戶餘額、充值金額、模型定價、用量日誌等所有金額顯示均按此匯率換算為人民幣,不影響內部計費", + "系统内部计费精度,默认 500000,修改可能导致计费异常,请谨慎操作": "系統內部計費精度,預設 500000,修改可能導致計費異常,請謹慎操作", + "系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为自定义货币,不影响内部计费": "系統內部以美元 (USD) 為基準計價。用戶餘額、充值金額、模型定價、用量日誌等所有金額顯示均按此匯率換算為自訂貨幣,不影響內部計費", "自定义镜像": "自訂鏡像", "自用模式": "自用模式", "自适应列表": "動態列表", diff --git a/web/src/pages/Setting/Operation/SettingsGeneral.jsx b/web/src/pages/Setting/Operation/SettingsGeneral.jsx index 8b9a621d..80810da0 100644 --- a/web/src/pages/Setting/Operation/SettingsGeneral.jsx +++ b/web/src/pages/Setting/Operation/SettingsGeneral.jsx @@ -26,9 +26,8 @@ import { Row, Spin, Modal, - Select, - InputGroup, Input, + Typography, } from '@douyinfe/semi-ui'; import { compareObjects, @@ -39,6 +38,8 @@ import { } from '../../../helpers'; import { useTranslation } from 'react-i18next'; +const { Text } = Typography; + export default function GeneralSettings(props) { const { t } = useTranslation(); const [loading, setLoading] = useState(false); @@ -126,6 +127,77 @@ export default function GeneralSettings(props) { } }; + const showTokensOption = useMemo(() => { + const initialType = props.options?.['general_setting.quota_display_type']; + const initialQuotaPerUnit = parseFloat(props.options?.QuotaPerUnit); + const legacyTokensMode = + initialType === undefined && + props.options?.DisplayInCurrencyEnabled !== undefined && + !props.options.DisplayInCurrencyEnabled; + return ( + initialType === 'TOKENS' || + legacyTokensMode || + (!isNaN(initialQuotaPerUnit) && initialQuotaPerUnit !== 500000) + ); + }, [props.options]); + + const quotaDisplayType = inputs['general_setting.quota_display_type']; + + const quotaDisplayTypeDesc = useMemo(() => { + const descMap = { + USD: t('站点所有额度将以美元 ($) 显示'), + CNY: t('站点所有额度将按汇率换算为人民币 (¥) 显示'), + TOKENS: t('站点所有额度将以原始 Token 数显示,不做货币换算'), + CUSTOM: t('站点所有额度将按汇率换算为自定义货币显示'), + }; + return descMap[quotaDisplayType] || ''; + }, [quotaDisplayType, t]); + + const rateLabel = useMemo(() => { + if (quotaDisplayType === 'CNY') return t('汇率'); + if (quotaDisplayType === 'TOKENS') return t('每美元对应 Token 数'); + if (quotaDisplayType === 'CUSTOM') return t('汇率'); + return ''; + }, [quotaDisplayType, t]); + + const rateSuffix = useMemo(() => { + if (quotaDisplayType === 'CNY') return 'CNY (¥)'; + if (quotaDisplayType === 'TOKENS') return 'Tokens'; + if (quotaDisplayType === 'CUSTOM') + return inputs['general_setting.custom_currency_symbol'] || '¤'; + return ''; + }, [quotaDisplayType, inputs]); + + const rateExtraText = useMemo(() => { + if (quotaDisplayType === 'CNY') + return t( + '系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为人民币,不影响内部计费', + ); + if (quotaDisplayType === 'TOKENS') + return t( + '系统内部计费精度,默认 500000,修改可能导致计费异常,请谨慎操作', + ); + if (quotaDisplayType === 'CUSTOM') + return t( + '系统内部以美元 (USD) 为基准计价。用户余额、充值金额、模型定价、用量日志等所有金额显示均按此汇率换算为自定义货币,不影响内部计费', + ); + return ''; + }, [quotaDisplayType, t]); + + const previewText = useMemo(() => { + if (quotaDisplayType === 'USD') return '$1.00'; + const rate = parseFloat(combinedRate); + if (!rate || isNaN(rate)) return t('请输入汇率'); + if (quotaDisplayType === 'CNY') return `$1.00 → ¥${rate.toFixed(2)}`; + if (quotaDisplayType === 'TOKENS') + return `$1.00 → ${Number(rate).toLocaleString()} Tokens`; + if (quotaDisplayType === 'CUSTOM') { + const symbol = inputs['general_setting.custom_currency_symbol'] || '¤'; + return `$1.00 → ${symbol}${rate.toFixed(2)}`; + } + return ''; + }, [quotaDisplayType, combinedRate, inputs, t]); + useEffect(() => { const currentInputs = {}; for (let key in props.options) { @@ -202,48 +274,79 @@ export default function GeneralSettings(props) { />