From 08adf0f20dae498b3a8be799907fa3989f842535 Mon Sep 17 00:00:00 2001 From: richarjiang Date: Thu, 27 Nov 2025 11:17:21 +0800 Subject: [PATCH] =?UTF-8?q?feat(i18n):=20=E5=AE=9E=E7=8E=B0=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=AF=AD=E8=A8=80=E5=81=8F=E5=A5=BD=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=99=A8=E5=90=8C=E6=AD=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 UserLanguage 类型定义 ('zh-CN' | 'en-US') - 在 UpdateUserDto 中新增 language 字段 - 实现语言切换时自动同步到服务器 - 为已登录用户保存语言偏好设置 - 服务器同步失败时降级处理,不影响本地语言切换 --- app/(tabs)/personal.tsx | 23 ++++++++++++++++++++++- services/users.ts | 4 ++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/app/(tabs)/personal.tsx b/app/(tabs)/personal.tsx index a0f94f4..8d9227e 100644 --- a/app/(tabs)/personal.tsx +++ b/app/(tabs)/personal.tsx @@ -9,6 +9,7 @@ import { useAppDispatch, useAppSelector } from '@/hooks/redux'; import { useAuthGuard } from '@/hooks/useAuthGuard'; import type { BadgeDto } from '@/services/badges'; import { reportBadgeShowcaseDisplayed } from '@/services/badges'; +import { updateUser, type UserLanguage } from '@/services/users'; import { fetchAvailableBadges, selectBadgeCounts, selectBadgePreview, selectSortedBadges } from '@/store/badgesSlice'; import { selectActiveMembershipPlanName } from '@/store/membershipSlice'; import { DEFAULT_MEMBER_NAME, fetchActivityHistory, fetchMyProfile } from '@/store/userSlice'; @@ -89,13 +90,33 @@ export default function PersonalScreen() { } try { setIsSwitchingLanguage(true); + + // 将 AppLanguage ('zh' | 'en') 映射到 UserLanguage ('zh-CN' | 'en-US') + const languageMap: Record = { + 'zh': 'zh-CN', + 'en': 'en-US', + }; + const userLanguage = languageMap[language]; + + // 先切换本地语言 await changeAppLanguage(language); + + // 如果用户已登录,同步更新服务器语言设置 + if (isLoggedIn) { + try { + await updateUser({ language: userLanguage }); + log.info('语言设置已同步到服务器', { language: userLanguage }); + } catch (error) { + log.warn('同步语言设置到服务器失败', error); + // 服务器更新失败不影响本地语言切换,静默处理 + } + } } catch (error) { log.warn('语言切换失败', error); } finally { setIsSwitchingLanguage(false); } - }, [activeLanguageCode, isSwitchingLanguage]); + }, [activeLanguageCode, isSwitchingLanguage, isLoggedIn]); // 推送通知设置仅在独立页面管理 diff --git a/services/users.ts b/services/users.ts index 6df0890..af98d22 100644 --- a/services/users.ts +++ b/services/users.ts @@ -2,6 +2,9 @@ import { api } from '@/services/api'; export type Gender = 'male' | 'female'; +// 用户语言设置 +export type UserLanguage = 'zh-CN' | 'en-US'; + export type UpdateUserDto = { name?: string; avatar?: string; // base64 字符串 @@ -21,6 +24,7 @@ export type UpdateUserDto = { armCircumference?: number; // 臂围 thighCircumference?: number; // 大腿围 calfCircumference?: number; // 小腿围 + language?: UserLanguage; // 用户语言偏好 }; export async function updateUser(dto: UpdateUserDto): Promise> {