refactor: 完成全站国际化改造,统一多语言支持

此提交完成了全项目的国际化适配:
1. 新增多语言翻译文件与基础配置
2. 替换所有硬编码文本为i18n调用
3. 优化语言切换与文档语言同步逻辑
4. 重构部分业务逻辑以支持动态翻译
5. 移除过时代码与硬编码配置
This commit is contained in:
2026-05-15 10:41:14 +08:00
parent ac612cb32c
commit f2c7f5e4f1
53 changed files with 2179 additions and 767 deletions

View File

@@ -2,6 +2,7 @@
import { useState, useEffect } from "react";
import { RefreshCw, AlertCircle } from "lucide-react";
import { useTranslation } from "react-i18next";
import { useTokenRefresh } from "@/hooks/use-token-refresh";
import { Button } from "@/components/ui/button";
@@ -16,6 +17,7 @@ import { cn } from "@/lib/utils";
export function TokenRefreshIndicator(): React.ReactElement | null {
const { isTokenExpiringSoon, getTokenRemainingTime, refreshToken } =
useTokenRefresh();
const { t } = useTranslation("player");
const [isRefreshing, setIsRefreshing] = useState(false);
const [showWarning, setShowWarning] = useState(false);
const [remainingSeconds, setRemainingSeconds] = useState<number | null>(null);
@@ -24,7 +26,6 @@ export function TokenRefreshIndicator(): React.ReactElement | null {
useEffect(() => {
const checkToken = (): void => {
const remaining = getTokenRemainingTime();
const expiringSoon = isTokenExpiringSoon();
if (remaining > 0 && remaining < 120000) {
// 2 分钟内显示
@@ -85,16 +86,19 @@ export function TokenRefreshIndicator(): React.ReactElement | null {
color: isCritical ? ERROR_COLORS.error : ERROR_COLORS.warning,
}}
>
{isCritical ? "登录即将失效" : "登录即将过期"}
{isCritical ? t("token.critical") : t("token.warning")}
</span>
<span className="text-xs text-muted-foreground">
{remainingSeconds !== null && (
<>
{Math.floor(remainingSeconds / 60)}:
{String(remainingSeconds % 60).padStart(2, "0")} {" "}
{t("token.remaining", {
time: `${Math.floor(remainingSeconds / 60)}:${String(
remainingSeconds % 60,
).padStart(2, "0")}`,
})}{" "}
</>
)}
...
{t("token.autoRenewing")}
</span>
</div>
@@ -112,7 +116,7 @@ export function TokenRefreshIndicator(): React.ReactElement | null {
<RefreshCw
className={cn("size-3.5", isRefreshing && "animate-spin")}
/>
{t("token.renewNow")}
</Button>
</div>
);