Commit f69ceb69 by QuentinHsu Committed by GitHub

fix: 修复新 UI 语言与文案显示问题 (#4876)

* chore(dev): add local setup state reset target

- add a reset-setup make target to clear setup records, root users, and related options.
- support both docker dev PostgreSQL and local SQLite development databases.
- restart the docker dev backend so setup status is recalculated after reset.

* fix(chat): prevent preset menu text overflow

- add truncation layout for chat preset names to keep long labels inside the sidebar menu.
- prevent loading and external-link icons from shrinking in constrained menu rows.

* fix(i18n): translate dashboard granularity options

- call t() for granularity option labels in dashboard system settings.
- keep localized text consistent between the select trigger and dropdown items.

* chore(dev): add backend dev service rebuild target

- add a dev-api-rebuild make target to rebuild and start the docker backend service.
- reuse DEV_COMPOSE_FILE and DEV_BACKEND_SERVICE variables to avoid repeated compose config literals.

* fix(i18n): align interface language option labels

- add shared interface language options to keep display names consistent.
- reuse the shared options in the header switcher and profile preferences.
- normalize language codes so zh-CN and zh_CN resolve to Simplified Chinese.

* fix(i18n): add missing frontend translation keys

- route channel key prompts, form validation messages, and channel fallback text through i18n.
- add missing translations across six locales for channels, rankings, billing, and logs.
- update i18n sync reports so literal t() keys are present in the base locale.
parent 68830e60
FRONTEND_DIR = ./web/default
FRONTEND_CLASSIC_DIR = ./web/classic
BACKEND_DIR = .
DEV_COMPOSE_FILE = docker-compose.dev.yml
DEV_POSTGRES_SERVICE = postgres
DEV_BACKEND_SERVICE = new-api
DEV_POSTGRES_DB = new-api
DEV_POSTGRES_USER = root
DEV_SQLITE_PATH ?= one-api.db
.PHONY: all build-frontend build-frontend-classic build-all-frontends start-backend dev dev-api dev-web dev-web-classic
.PHONY: all build-frontend build-frontend-classic build-all-frontends start-backend dev dev-api dev-api-rebuild dev-web dev-web-classic reset-setup
all: build-all-frontends start-backend
......@@ -22,7 +28,11 @@ start-backend:
dev-api:
@echo "Starting backend services (docker)..."
@docker compose -f docker-compose.dev.yml up -d
@docker compose -f $(DEV_COMPOSE_FILE) up -d
dev-api-rebuild:
@echo "Rebuilding and starting backend service (docker)..."
@docker compose -f $(DEV_COMPOSE_FILE) up -d --build $(DEV_BACKEND_SERVICE)
dev-web:
@echo "Starting frontend dev server..."
......@@ -33,3 +43,27 @@ dev-web-classic:
@cd $(FRONTEND_CLASSIC_DIR) && bun install && bun run dev
dev: dev-api dev-web
reset-setup:
@echo "Resetting local setup wizard state..."
@if docker compose -f $(DEV_COMPOSE_FILE) ps --services --status running | grep -qx "$(DEV_POSTGRES_SERVICE)"; then \
echo "Detected running docker dev PostgreSQL. Removing setup record and root users..."; \
docker compose -f $(DEV_COMPOSE_FILE) exec -T $(DEV_POSTGRES_SERVICE) \
psql -U $(DEV_POSTGRES_USER) -d $(DEV_POSTGRES_DB) \
-c 'DELETE FROM setups;' \
-c 'DELETE FROM users WHERE role = 100;' \
-c "DELETE FROM options WHERE key IN ('SelfUseModeEnabled', 'DemoSiteEnabled');"; \
echo "Restarting docker dev backend so setup status is recalculated..."; \
docker compose -f $(DEV_COMPOSE_FILE) restart $(DEV_BACKEND_SERVICE); \
elif db_path="$${SQLITE_PATH:-$(DEV_SQLITE_PATH)}"; db_path="$${db_path%%\?*}"; [ -f "$$db_path" ]; then \
db_path="$${SQLITE_PATH:-$(DEV_SQLITE_PATH)}"; \
db_path="$${db_path%%\?*}"; \
echo "Detected local SQLite database: $$db_path"; \
sqlite3 "$$db_path" \
"DELETE FROM setups; DELETE FROM users WHERE role = 100; DELETE FROM options WHERE key IN ('SelfUseModeEnabled', 'DemoSiteEnabled');"; \
echo "SQLite setup state reset. Restart the local backend process before testing the setup wizard."; \
else \
echo "No running docker dev PostgreSQL or local SQLite database found."; \
echo "Start the dev stack with 'make dev-api', or set SQLITE_PATH/DEV_SQLITE_PATH to your local SQLite database."; \
exit 1; \
fi
......@@ -17,6 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useCallback } from 'react'
import {
INTERFACE_LANGUAGE_OPTIONS,
normalizeInterfaceLanguage,
} from '@/i18n/languages'
import { Languages, Check } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { useAuthStore } from '@/stores/auth-store'
......@@ -30,18 +34,10 @@ import {
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
const languages = [
{ code: 'en', label: 'English' },
{ code: 'zh', label: '中文' },
{ code: 'fr', label: 'Français' },
{ code: 'ru', label: 'Русский' },
{ code: 'ja', label: '日本語' },
{ code: 'vi', label: 'Tiếng Việt' },
]
export function LanguageSwitcher() {
const { i18n, t } = useTranslation()
const user = useAuthStore((s) => s.auth.user)
const currentLanguage = normalizeInterfaceLanguage(i18n.language)
const handleChangeLanguage = useCallback(
async (code: string) => {
......@@ -66,7 +62,7 @@ export function LanguageSwitcher() {
<span className='sr-only'>{t('Change language')}</span>
</DropdownMenuTrigger>
<DropdownMenuContent align='end'>
{languages.map((lang) => (
{INTERFACE_LANGUAGE_OPTIONS.map((lang) => (
<DropdownMenuItem
key={lang.code}
onClick={() => handleChangeLanguage(lang.code)}
......@@ -74,7 +70,10 @@ export function LanguageSwitcher() {
{lang.label}
<Check
size={14}
className={cn('ms-auto', i18n.language !== lang.code && 'hidden')}
className={cn(
'ms-auto',
currentLanguage !== lang.code && 'hidden'
)}
/>
</DropdownMenuItem>
))}
......
......@@ -79,7 +79,9 @@ function ChatMenuItem({
/>
}
>
<span>{preset.name}</span>
<span className='min-w-0 flex-1 truncate whitespace-nowrap'>
{preset.name}
</span>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
)
......@@ -95,11 +97,13 @@ function ChatMenuItem({
isActive={false}
className='justify-between'
>
<span>{preset.name}</span>
<span className='min-w-0 flex-1 truncate whitespace-nowrap'>
{preset.name}
</span>
{loading ? (
<Loader2 className='h-4 w-4 animate-spin' />
<Loader2 className='h-4 w-4 shrink-0 animate-spin' />
) : (
<ExternalLink className='h-4 w-4' />
<ExternalLink className='h-4 w-4 shrink-0' />
)}
</SidebarMenuSubButton>
</SidebarMenuSubItem>
......
......@@ -27,6 +27,7 @@ import {
type FieldValues,
} from 'react-hook-form'
import { useRender } from '@base-ui/react/use-render'
import { useTranslation } from 'react-i18next'
import { cn } from '@/lib/utils'
import { Label } from '@/components/ui/label'
......@@ -153,12 +154,15 @@ function FormDescription({ className, ...props }: React.ComponentProps<'p'>) {
function FormMessage({ className, ...props }: React.ComponentProps<'p'>) {
const { error, formMessageId } = useFormField()
const { t } = useTranslation()
const body = error ? String(error?.message ?? '') : props.children
if (!body) {
return null
}
const translatedBody = typeof body === 'string' ? t(body) : body
return (
<p
data-slot='form-message'
......@@ -166,7 +170,7 @@ function FormMessage({ className, ...props }: React.ComponentProps<'p'>) {
className={cn('text-destructive text-sm', className)}
{...props}
>
{body}
{translatedBody}
</p>
)
}
......
......@@ -232,13 +232,20 @@ export function ChannelTestDialog({
} catch (error: unknown) {
updateTestResult(model, {
status: 'error',
error: error instanceof Error ? error.message : 'Test failed',
error: error instanceof Error ? error.message : t('Test failed'),
})
} finally {
markModelTesting(model, false)
}
},
[currentRow, endpointType, isStreamTest, markModelTesting, updateTestResult]
[
currentRow,
endpointType,
isStreamTest,
markModelTesting,
t,
updateTestResult,
]
)
const handleBatchTest = useCallback(
......
......@@ -138,7 +138,7 @@ export function MultiKeyManageDialog({
}
} catch (error: unknown) {
toast.error(
error instanceof Error ? error.message : 'Failed to load key status'
error instanceof Error ? error.message : t('Failed to load key status')
)
} finally {
setIsLoading(false)
......@@ -181,7 +181,7 @@ export function MultiKeyManageDialog({
}
if (response?.success) {
toast.success(response.message || 'Operation successful')
toast.success(response.message || t('Operation successful'))
queryClient.invalidateQueries({ queryKey: channelsQueryKeys.lists() })
// Reload data - reset to page 1 for bulk actions
......@@ -193,10 +193,12 @@ export function MultiKeyManageDialog({
loadKeyStatus(currentPage, pageSize)
}
} else {
toast.error(response?.message || 'Operation failed')
toast.error(response?.message || t('Operation failed'))
}
} catch (error: unknown) {
toast.error(error instanceof Error ? error.message : 'Operation failed')
toast.error(
error instanceof Error ? error.message : t('Operation failed')
)
} finally {
setIsPerformingAction(false)
setConfirmAction(null)
......
......@@ -697,7 +697,7 @@ export function ChannelMutateDrawer({
try {
const res = await getChannelKey(channelId)
if (!res.success) {
throw new Error(res.message || 'Failed to fetch channel key')
throw new Error(res.message || t('Failed to fetch channel key'))
}
const keyValue = res.data?.key ?? ''
......@@ -732,7 +732,7 @@ export function ChannelMutateDrawer({
try {
const res = await refreshCodexCredential(channelId)
if (!res.success) {
throw new Error(res.message || 'Failed to refresh credential')
throw new Error(res.message || t('Failed to refresh credential'))
}
toast.success(t('Credential refreshed'))
queryClient.invalidateQueries({
......
......@@ -17,6 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useEffect, useMemo, useState } from 'react'
import {
INTERFACE_LANGUAGE_OPTIONS,
normalizeInterfaceLanguage,
} from '@/i18n/languages'
import { Languages, Loader2 } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
......@@ -34,24 +38,6 @@ import { updateUserLanguage } from '../api'
import { parseUserSettings } from '../lib'
import type { UserProfile } from '../types'
const LANGUAGE_OPTIONS = [
{ value: 'zh', label: '简体中文' },
{ value: 'en', label: 'English' },
{ value: 'fr', label: 'Français' },
{ value: 'ru', label: 'Русский' },
{ value: 'ja', label: '日本語' },
{ value: 'vi', label: 'Tiếng Việt' },
] as const
function normalizeLanguage(value?: string | null): string {
if (!value) return 'en'
const normalized = value.trim().replace(/_/g, '-').toLowerCase()
if (normalized.startsWith('zh')) return 'zh'
return LANGUAGE_OPTIONS.some((lang) => lang.value === normalized)
? normalized
: 'en'
}
type LanguagePreferencesCardProps = {
profile: UserProfile | null
onProfileUpdate: () => void
......@@ -64,7 +50,7 @@ export function LanguagePreferencesCard(props: LanguagePreferencesCardProps) {
const savedLanguage = useMemo(() => {
const settings = parseUserSettings(props.profile?.setting)
return normalizeLanguage(settings.language || i18n.language)
return normalizeInterfaceLanguage(settings.language || i18n.language)
}, [props.profile?.setting, i18n.language])
const [currentLanguage, setCurrentLanguage] = useState(savedLanguage)
......@@ -75,7 +61,7 @@ export function LanguagePreferencesCard(props: LanguagePreferencesCardProps) {
const handleLanguageChange = async (language: string | null) => {
if (!language) return
const nextLanguage = normalizeLanguage(language)
const nextLanguage = normalizeInterfaceLanguage(language)
if (nextLanguage === currentLanguage) return
const previousLanguage = currentLanguage
......@@ -132,8 +118,8 @@ export function LanguagePreferencesCard(props: LanguagePreferencesCardProps) {
<div className='flex items-center gap-2 sm:min-w-48'>
<Select
items={[
...LANGUAGE_OPTIONS.map((language) => ({
value: language.value,
...INTERFACE_LANGUAGE_OPTIONS.map((language) => ({
value: language.code,
label: language.label,
})),
]}
......@@ -146,8 +132,8 @@ export function LanguagePreferencesCard(props: LanguagePreferencesCardProps) {
</SelectTrigger>
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
{LANGUAGE_OPTIONS.map((language) => (
<SelectItem key={language.value} value={language.value}>
{INTERFACE_LANGUAGE_OPTIONS.map((language) => (
<SelectItem key={language.code} value={language.code}>
{language.label}
</SelectItem>
))}
......
......@@ -151,7 +151,7 @@ export function DashboardSection({ defaultValues }: DashboardSectionProps) {
items={[
...granularityOptions.map((option) => ({
value: option.value,
label: option.label,
label: t(option.label),
})),
]}
onValueChange={field.onChange}
......@@ -167,7 +167,7 @@ export function DashboardSection({ defaultValues }: DashboardSectionProps) {
<SelectGroup>
{granularityOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
{t(option.label)}
</SelectItem>
))}
</SelectGroup>
......
/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
export const INTERFACE_LANGUAGE_OPTIONS = [
{ code: 'zh', label: '简体中文' },
{ code: 'en', label: 'English' },
{ code: 'fr', label: 'Français' },
{ code: 'ru', label: 'Русский' },
{ code: 'ja', label: '日本語' },
{ code: 'vi', label: 'Tiếng Việt' },
] as const
export type InterfaceLanguageCode =
(typeof INTERFACE_LANGUAGE_OPTIONS)[number]['code']
export function normalizeInterfaceLanguage(value?: string | null): string {
if (!value) return 'en'
const normalized = value.trim().replace(/_/g, '-').toLowerCase()
if (normalized.startsWith('zh')) return 'zh'
return INTERFACE_LANGUAGE_OPTIONS.some((lang) => lang.code === normalized)
? normalized
: 'en'
}
......@@ -11,25 +11,25 @@
"file": "fr.json",
"missingCount": 0,
"extrasCount": 0,
"untranslatedCount": 1
"untranslatedCount": 21
},
"ja": {
"file": "ja.json",
"missingCount": 0,
"extrasCount": 0,
"untranslatedCount": 92
"untranslatedCount": 120
},
"ru": {
"file": "ru.json",
"missingCount": 0,
"extrasCount": 0,
"untranslatedCount": 107
"untranslatedCount": 135
},
"vi": {
"file": "vi.json",
"missingCount": 0,
"extrasCount": 0,
"untranslatedCount": 3
"untranslatedCount": 23
},
"zh": {
"file": "zh.json",
......
{
"Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback."
"acknowledge the related legal risks": "acknowledge the related legal risks",
"Confirm and enable": "Confirm and enable",
"Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
"Failed to confirm compliance": "Failed to confirm compliance",
"I have read and understood the above compliance reminder": "I have read and understood the above compliance reminder",
"I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.": "I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.",
"If you provide generative AI services to the public in mainland China, you will fulfill legal obligations including filing, security assessment, content safety, complaint handling, generated content labeling, log retention, and personal information protection.": "If you provide generative AI services to the public in mainland China, you will fulfill legal obligations including filing, security assessment, content safety, complaint handling, generated content labeling, log retention, and personal information protection.",
"operation and charging behavior": "operation and charging behavior",
"Payment, redemption codes, subscription plans, and invitation rewards are locked until the root administrator confirms the compliance terms.": "Payment, redemption codes, subscription plans, and invitation rewards are locked until the root administrator confirms the compliance terms.",
"Please type the following text to confirm:": "Please type the following text to confirm:",
"Redemption codes are disabled until the administrator confirms compliance terms.": "Redemption codes are disabled until the administrator confirms compliance terms.",
"Referral reward transfer is disabled until the administrator confirms compliance terms.": "Referral reward transfer is disabled until the administrator confirms compliance terms.",
"Subscription plan creation and changes are locked until the administrator confirms compliance terms in Payment Gateway settings.": "Subscription plan creation and changes are locked until the administrator confirms compliance terms in Payment Gateway settings.",
"The entered text does not match the required text.": "The entered text does not match the required text.",
"This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read the statements carefully.": "This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read the statements carefully.",
"Type the confirmation text here": "Type the confirmation text here",
"You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.": "You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.",
"You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.": "You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.",
"You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.": "You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.",
"You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.": "You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.",
"You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario.": "You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario."
}
......@@ -3,6 +3,7 @@
"[{\"name\":\"支付宝\",\"type\":\"alipay\",\"color\":\"#1677FF\"}]": "[{\"name\":\"Alipay\",\"type\":\"alipay\",\"color\":\"#1677FF\"}]",
"/status/": "/status/",
"/your/endpoint": "/your/endpoint",
"acknowledge the related legal risks": "acknowledge the related legal risks",
"AIGC2D": "AIGC2D",
"Alipay": "Alipay",
"Anthropic": "Anthropic",
......@@ -14,11 +15,20 @@
"Claude": "Claude",
"Cloudflare": "Cloudflare",
"Cohere": "Cohere",
"Compliance confirmation required": "Compliance confirmation required",
"Compliance confirmed": "Compliance confirmed",
"Compliance confirmed successfully": "Compliance confirmed successfully",
"Confirm and enable": "Confirm and enable",
"Confirm compliance": "Confirm compliance",
"Confirm compliance terms": "Confirm compliance terms",
"confirm that I bear legal responsibility arising from deployment": "confirm that I bear legal responsibility arising from deployment",
"Confirmed at {{time}} by user #{{userId}}": "Confirmed at {{time}} by user #{{userId}}",
"DeepSeek": "DeepSeek",
"Discord": "Discord",
"DoubaoVideo": "DoubaoVideo",
"Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
"edit_this": "edit_this",
"Failed to confirm compliance": "Failed to confirm compliance",
"FastGPT": "FastGPT",
"footer.columns.related.links.midjourney": "Midjourney-Proxy",
"footer.columns.related.links.newApiKeyTool": "new-api-key-tool",
......@@ -47,6 +57,9 @@
"https://wechat-server.example.com": "https://wechat-server.example.com",
"https://worker.example.workers.dev": "https://worker.example.workers.dev",
"https://your-server.example.com": "https://your-server.example.com",
"I have read and understood the above compliance reminder": "I have read and understood the above compliance reminder",
"I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.": "I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.",
"If you provide generative AI services to the public in mainland China, you will fulfill legal obligations including filing, security assessment, content safety, complaint handling, generated content labeling, log retention, and personal information protection.": "If you provide generative AI services to the public in mainland China, you will fulfill legal obligations including filing, security assessment, content safety, complaint handling, generated content labeling, log retention, and personal information protection.",
"Jimeng": "Jimeng",
"JustSong": "JustSong",
"LingYiWanWu": "LingYiWanWu",
......@@ -60,29 +73,39 @@
"my-status": "my-status",
"name@example.com": "name@example.com",
"NewAPI": "NewAPI",
"Non-zero invitation rewards require compliance confirmation in Payment Gateway settings.": "Non-zero invitation rewards require compliance confirmation in Payment Gateway settings.",
"noreply@example.com": "noreply@example.com",
"OhMyGPT": "OhMyGPT",
"Ollama": "Ollama",
"OpenAI": "OpenAI",
"OpenAIMax": "OpenAIMax",
"OpenRouter": "OpenRouter",
"operation and charging behavior": "operation and charging behavior",
"org-...": "org-...",
"Passkey": "Passkey",
"Payment, redemption codes, subscription plans, and invitation rewards are locked until the root administrator confirms the compliance terms.": "Payment, redemption codes, subscription plans, and invitation rewards are locked until the root administrator confirms the compliance terms.",
"Perplexity": "Perplexity",
"Please type the following text to confirm:": "Please type the following text to confirm:",
"price_xxx": "price_xxx",
"QuantumNous": "QuantumNous",
"Redemption codes are disabled until the administrator confirms compliance terms.": "Redemption codes are disabled until the administrator confirms compliance terms.",
"Referral reward transfer is disabled until the administrator confirms compliance terms.": "Referral reward transfer is disabled until the administrator confirms compliance terms.",
"Replicate": "Replicate",
"SiliconFlow": "SiliconFlow",
"smtp.example.com": "smtp.example.com",
"socks5://user:pass@host:port": "socks5://user:pass@host:port",
"Stripe": "Stripe",
"Submodel": "Submodel",
"Subscription plan creation and changes are locked until the administrator confirms compliance terms in Payment Gateway settings.": "Subscription plan creation and changes are locked until the administrator confirms compliance terms in Payment Gateway settings.",
"SunoAPI": "SunoAPI",
"Telegram": "Telegram",
"The entered text does not match the required text.": "The entered text does not match the required text.",
"This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read the statements carefully.": "This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read the statements carefully.",
"Token prices": "Token prices",
"TTFT P50": "TTFT P50",
"TTFT P95": "TTFT P95",
"TTFT P99": "TTFT P99",
"Type the confirmation text here": "Type the confirmation text here",
"Vertex AI": "Vertex AI",
"VolcEngine": "VolcEngine",
"Webhook URL": "Webhook URL",
......@@ -90,5 +113,10 @@
"WeChat Pay": "WeChat Pay",
"whsec_xxx": "whsec_xxx",
"Xinference": "Xinference",
"Xunfei": "Xunfei"
"Xunfei": "Xunfei",
"You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.": "You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.",
"You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.": "You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.",
"You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.": "You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.",
"You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.": "You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.",
"You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario.": "You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario."
}
......@@ -6,6 +6,7 @@
"/status/": "/status/",
"/your/endpoint": "/your/endpoint",
"AccessKey / SecretAccessKey": "AccessKey / SecretAccessKey",
"acknowledge the related legal risks": "acknowledge the related legal risks",
"AI Proxy": "AI Proxy",
"AIGC2D": "AIGC2D",
"Alipay": "Alipay",
......@@ -20,6 +21,14 @@
"checkout.session.expired": "checkout.session.expired",
"Cloudflare": "Cloudflare",
"Cohere": "Cohere",
"Compliance confirmation required": "Compliance confirmation required",
"Compliance confirmed": "Compliance confirmed",
"Compliance confirmed successfully": "Compliance confirmed successfully",
"Confirm and enable": "Confirm and enable",
"Confirm compliance": "Confirm compliance",
"Confirm compliance terms": "Confirm compliance terms",
"confirm that I bear legal responsibility arising from deployment": "confirm that I bear legal responsibility arising from deployment",
"Confirmed at {{time}} by user #{{userId}}": "Confirmed at {{time}} by user #{{userId}}",
"Core pricing": "Core pricing",
"DeepSeek": "DeepSeek",
"Discord": "Discord",
......@@ -27,6 +36,7 @@
"Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
"example.com&#10;blocked-site.com": "example.com&#10;blocked-site.com",
"example.com&#10;company.com": "example.com&#10;company.com",
"Failed to confirm compliance": "Failed to confirm compliance",
"Fallback tier": "Fallback tier",
"FastGPT": "FastGPT",
"footer.columns.related.links.midjourney": "Midjourney-Proxy",
......@@ -56,6 +66,9 @@
"https://wechat-server.example.com": "https://wechat-server.example.com",
"https://worker.example.workers.dev": "https://worker.example.workers.dev",
"https://your-server.example.com": "https://your-server.example.com",
"I have read and understood the above compliance reminder": "I have read and understood the above compliance reminder",
"I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.": "I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.",
"If you provide generative AI services to the public in mainland China, you will fulfill legal obligations including filing, security assessment, content safety, complaint handling, generated content labeling, log retention, and personal information protection.": "If you provide generative AI services to the public in mainland China, you will fulfill legal obligations including filing, security assessment, content safety, complaint handling, generated content labeling, log retention, and personal information protection.",
"Jimeng": "Jimeng",
"JustSong": "JustSong",
"LingYiWanWu": "LingYiWanWu",
......@@ -70,6 +83,7 @@
"name@example.com": "name@example.com",
"NewAPI": "NewAPI",
"No separate media pricing configured.": "No separate media pricing configured.",
"Non-zero invitation rewards require compliance confirmation in Payment Gateway settings.": "Non-zero invitation rewards require compliance confirmation in Payment Gateway settings.",
"noreply@example.com": "noreply@example.com",
"OAuth Client Secret": "OAuth Client Secret",
"OhMyGPT": "OhMyGPT",
......@@ -77,10 +91,15 @@
"OpenAI": "OpenAI",
"OpenAIMax": "OpenAIMax",
"OpenRouter": "OpenRouter",
"operation and charging behavior": "operation and charging behavior",
"Passkey": "Passkey",
"Payment, redemption codes, subscription plans, and invitation rewards are locked until the root administrator confirms the compliance terms.": "Payment, redemption codes, subscription plans, and invitation rewards are locked until the root administrator confirms the compliance terms.",
"Perplexity": "Perplexity",
"Please type the following text to confirm:": "Please type the following text to confirm:",
"price_xxx": "price_xxx",
"QuantumNous": "QuantumNous",
"Redemption codes are disabled until the administrator confirms compliance terms.": "Redemption codes are disabled until the administrator confirms compliance terms.",
"Referral reward transfer is disabled until the administrator confirms compliance terms.": "Referral reward transfer is disabled until the administrator confirms compliance terms.",
"Replicate": "Replicate",
"Separate image/audio prices are enabled.": "Separate image/audio prices are enabled.",
"Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes.",
......@@ -89,15 +108,19 @@
"socks5://user:pass@host:port": "socks5://user:pass@host:port",
"Stripe": "Stripe",
"Submodel": "Submodel",
"Subscription plan creation and changes are locked until the administrator confirms compliance terms in Payment Gateway settings.": "Subscription plan creation and changes are locked until the administrator confirms compliance terms in Payment Gateway settings.",
"SunoAPI": "SunoAPI",
"Telegram": "Telegram",
"Tencent": "Tencent",
"The entered text does not match the required text.": "The entered text does not match the required text.",
"This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read the statements carefully.": "This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read the statements carefully.",
"This tier catches any request that did not match earlier tiers.": "This tier catches any request that did not match earlier tiers.",
"Tier conditions": "Tier conditions",
"Token prices": "Token prices",
"TTFT P50": "TTFT P50",
"TTFT P95": "TTFT P95",
"TTFT P99": "TTFT P99",
"Type the confirmation text here": "Type the confirmation text here",
"Vertex AI": "Vertex AI",
"VolcEngine": "VolcEngine",
"WeChat": "WeChat",
......@@ -105,5 +128,10 @@
"whsec_xxx": "whsec_xxx",
"Xinference": "Xinference",
"Xunfei": "Xunfei",
"You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.": "You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.",
"You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.": "You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.",
"You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.": "You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.",
"You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.": "You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.",
"You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario.": "You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario.",
"Zhipu V4": "Zhipu V4"
}
{
"acknowledge the related legal risks": "acknowledge the related legal risks",
"Base input and output token prices for this tier.": "Base input and output token prices for this tier.",
"Confirm and enable": "Confirm and enable",
"Each tier supports up to 2 conditions. The last tier without conditions is the fallback.": "Each tier supports up to 2 conditions. The last tier without conditions is the fallback.",
"Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes."
"Failed to confirm compliance": "Failed to confirm compliance",
"I have read and understood the above compliance reminder": "I have read and understood the above compliance reminder",
"I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.": "I have read and understood the above compliance reminder, acknowledge the related legal risks, and confirm that I bear legal responsibility arising from deployment, operation, and charging behavior.",
"If you provide generative AI services to the public in mainland China, you will fulfill legal obligations including filing, security assessment, content safety, complaint handling, generated content labeling, log retention, and personal information protection.": "If you provide generative AI services to the public in mainland China, you will fulfill legal obligations including filing, security assessment, content safety, complaint handling, generated content labeling, log retention, and personal information protection.",
"operation and charging behavior": "operation and charging behavior",
"Payment, redemption codes, subscription plans, and invitation rewards are locked until the root administrator confirms the compliance terms.": "Payment, redemption codes, subscription plans, and invitation rewards are locked until the root administrator confirms the compliance terms.",
"Please type the following text to confirm:": "Please type the following text to confirm:",
"Redemption codes are disabled until the administrator confirms compliance terms.": "Redemption codes are disabled until the administrator confirms compliance terms.",
"Referral reward transfer is disabled until the administrator confirms compliance terms.": "Referral reward transfer is disabled until the administrator confirms compliance terms.",
"Set separate prices for cache reads and writes.": "Set separate prices for cache reads and writes.",
"Subscription plan creation and changes are locked until the administrator confirms compliance terms in Payment Gateway settings.": "Subscription plan creation and changes are locked until the administrator confirms compliance terms in Payment Gateway settings.",
"The entered text does not match the required text.": "The entered text does not match the required text.",
"This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read the statements carefully.": "This confirmation unlocks payment, redemption code, subscription plan, and invitation reward features. Please read the statements carefully.",
"Type the confirmation text here": "Type the confirmation text here",
"You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.": "You commit not to use this system to implement, assist with, or indirectly implement acts that violate applicable laws and regulations, regulatory requirements, platform rules, public interests, or the lawful rights and interests of third parties.",
"You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.": "You commit to using upstream APIs, accounts, keys, quotas, and service capabilities only within the scope of lawful authorization obtained from upstream service providers, model service providers, or relevant rights holders, and will not conduct unauthorized resale, trafficking, distribution, or other non-compliant commercialization.",
"You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.": "You have legally obtained authorization for the connected model APIs, accounts, keys, and quotas.",
"You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.": "You understand and independently bear legal responsibility arising from deployment, operation, and charging behavior.",
"You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario.": "You understand this compliance reminder is only for risk notice and does not constitute legal advice, a compliance review conclusion, or a guarantee of the legality of your use of this system; you should consult professional legal or compliance advisors based on your actual business scenario."
}
......@@ -90,6 +90,7 @@ export const STATIC_I18N_KEYS = [
'Failed to update API key status',
'Successfully created {{count}} API Key(s)',
'Successfully deleted {{count}} API key(s)',
'Enter API key for this channel',
// Users
'Root',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment