diff --git a/web/src/components/layout/PageLayout.jsx b/web/src/components/layout/PageLayout.jsx index 0799838eb..51666b5ef 100644 --- a/web/src/components/layout/PageLayout.jsx +++ b/web/src/components/layout/PageLayout.jsx @@ -41,7 +41,7 @@ import { normalizeLanguage } from '../../i18n/language'; const { Sider, Content, Header } = Layout; const PageLayout = () => { - const [, userDispatch] = useContext(UserContext); + const [userState, userDispatch] = useContext(UserContext); const [, statusDispatch] = useContext(StatusContext); const isMobile = useIsMobile(); const [collapsed, , setCollapsed] = useSidebarCollapsed(); @@ -114,15 +114,34 @@ const PageLayout = () => { linkElement.href = logo; } } - const savedLang = localStorage.getItem('i18nextLng'); - if (savedLang) { - const normalizedLang = normalizeLanguage(savedLang); - if (normalizedLang !== savedLang) { - localStorage.setItem('i18nextLng', normalizedLang); + }, []); + + useEffect(() => { + let preferredLang; + + if (userState?.user?.setting) { + try { + const settings = JSON.parse(userState.user.setting); + preferredLang = normalizeLanguage(settings.language); + } catch (e) { + // Ignore parse errors } - i18n.changeLanguage(normalizedLang); } - }, [i18n]); + + if (!preferredLang) { + const savedLang = localStorage.getItem('i18nextLng'); + if (savedLang) { + preferredLang = normalizeLanguage(savedLang); + } + } + + if (preferredLang) { + localStorage.setItem('i18nextLng', preferredLang); + if (preferredLang !== i18n.language) { + i18n.changeLanguage(preferredLang); + } + } + }, [i18n, userState?.user?.setting]); return ( { // Update language immediately for responsive UX setCurrentLanguage(lang); i18n.changeLanguage(lang); + localStorage.setItem('i18nextLng', lang); // Save to backend const res = await API.put("/api/user/self", { @@ -81,33 +82,38 @@ const PreferencesSettings = ({ t }) => { if (res.data.success) { showSuccess(t("语言偏好已保存")); - // Update user context with new setting + // Keep backend preference, context state, and local cache aligned. + let settings = {}; if (userState?.user?.setting) { try { - const settings = JSON.parse(userState.user.setting); - settings.language = lang; - userDispatch({ - type: "login", - payload: { - ...userState.user, - setting: JSON.stringify(settings), - }, - }); + settings = JSON.parse(userState.user.setting) || {}; } catch (e) { - // Ignore + settings = {}; } } + settings.language = lang; + const nextUser = { + ...userState.user, + setting: JSON.stringify(settings), + }; + userDispatch({ + type: "login", + payload: nextUser, + }); + localStorage.setItem("user", JSON.stringify(nextUser)); } else { showError(res.data.message || t("保存失败")); // Revert on error setCurrentLanguage(previousLang); i18n.changeLanguage(previousLang); + localStorage.setItem("i18nextLng", previousLang); } } catch (error) { showError(t("保存失败,请重试")); // Revert on error setCurrentLanguage(previousLang); i18n.changeLanguage(previousLang); + localStorage.setItem("i18nextLng", previousLang); } finally { setLoading(false); } diff --git a/web/src/components/table/model-pricing/filter/PricingDisplaySettings.jsx b/web/src/components/table/model-pricing/filter/PricingDisplaySettings.jsx index 71dbd2000..7c4bdbc52 100644 --- a/web/src/components/table/model-pricing/filter/PricingDisplaySettings.jsx +++ b/web/src/components/table/model-pricing/filter/PricingDisplaySettings.jsx @@ -25,6 +25,7 @@ const PricingDisplaySettings = ({ setShowWithRecharge, currency, setCurrency, + siteDisplayType, showRatio, setShowRatio, viewMode, @@ -34,11 +35,17 @@ const PricingDisplaySettings = ({ loading = false, t, }) => { + const supportsCurrencyDisplay = siteDisplayType !== 'TOKENS'; + const items = [ - { - value: 'recharge', - label: t('充值价格显示'), - }, + ...(supportsCurrencyDisplay + ? [ + { + value: 'recharge', + label: t('充值价格显示'), + }, + ] + : []), { value: 'ratio', label: t('显示倍率'), @@ -78,7 +85,7 @@ const PricingDisplaySettings = ({ const getActiveValues = () => { const activeValues = []; - if (showWithRecharge) activeValues.push('recharge'); + if (supportsCurrencyDisplay && showWithRecharge) activeValues.push('recharge'); if (showRatio) activeValues.push('ratio'); if (viewMode === 'table') activeValues.push('tableView'); if (tokenUnit === 'K') activeValues.push('tokenUnit'); @@ -98,7 +105,7 @@ const PricingDisplaySettings = ({ t={t} /> - {showWithRecharge && ( + {supportsCurrencyDisplay && showWithRecharge && ( { groupRatio={pricingData.groupRatio} usableGroup={pricingData.usableGroup} currency={pricingData.currency} + siteDisplayType={pricingData.siteDisplayType} tokenUnit={pricingData.tokenUnit} displayPrice={pricingData.displayPrice} showRatio={allProps.showRatio} diff --git a/web/src/components/table/model-pricing/layout/header/PricingTopSection.jsx b/web/src/components/table/model-pricing/layout/header/PricingTopSection.jsx index 5ce5f5cb3..fe04e4cc3 100644 --- a/web/src/components/table/model-pricing/layout/header/PricingTopSection.jsx +++ b/web/src/components/table/model-pricing/layout/header/PricingTopSection.jsx @@ -40,6 +40,7 @@ const PricingTopSection = memo( setShowWithRecharge, currency, setCurrency, + siteDisplayType, showRatio, setShowRatio, viewMode, @@ -68,6 +69,7 @@ const PricingTopSection = memo( setShowWithRecharge={setShowWithRecharge} currency={currency} setCurrency={setCurrency} + siteDisplayType={siteDisplayType} showRatio={showRatio} setShowRatio={setShowRatio} viewMode={viewMode} @@ -103,6 +105,7 @@ const PricingTopSection = memo( setShowWithRecharge={setShowWithRecharge} currency={currency} setCurrency={setCurrency} + siteDisplayType={siteDisplayType} showRatio={showRatio} setShowRatio={setShowRatio} viewMode={viewMode} diff --git a/web/src/components/table/model-pricing/layout/header/SearchActions.jsx b/web/src/components/table/model-pricing/layout/header/SearchActions.jsx index c961b8dc1..e285d3fba 100644 --- a/web/src/components/table/model-pricing/layout/header/SearchActions.jsx +++ b/web/src/components/table/model-pricing/layout/header/SearchActions.jsx @@ -35,6 +35,7 @@ const SearchActions = memo( setShowWithRecharge, currency, setCurrency, + siteDisplayType, showRatio, setShowRatio, viewMode, @@ -43,6 +44,8 @@ const SearchActions = memo( setTokenUnit, t, }) => { + const supportsCurrencyDisplay = siteDisplayType !== 'TOKENS'; + const handleCopyClick = useCallback(() => { if (copyText && selectedRowKeys.length > 0) { copyText(selectedRowKeys); @@ -91,16 +94,18 @@ const SearchActions = memo( {/* 充值价格显示开关 */} -
- {t('充值价格显示')} - -
+ {supportsCurrencyDisplay && ( +
+ {t('充值价格显示')} + +
+ )} {/* 货币单位选择 */} - {showWithRecharge && ( + {supportsCurrencyDisplay && showWithRecharge && (