feat(locale): 实现 App 启动时语言和时区自动设置

- 新增系统语言/时区读取工具函数
- SessionStore 扩展支持时区存储
- 启动流程自动检测并保存系统语言/时区
- 注册时传递语言/时区到后端
- 登录后从服务器同步语言/时区
This commit is contained in:
ZL-Q
2026-04-28 17:18:16 +08:00
parent 14752cdcfa
commit a83001de0d
11 changed files with 402 additions and 14 deletions
+19 -2
View File
@@ -22,6 +22,7 @@ from v1.auth.schemas import (
from v1.auth.service import AuthService
from v1.points.repository import PointsRepository
from v1.points.service import PointsService
from v1.users.repository import SQLAlchemyUserRepository
router = APIRouter(prefix="/auth", tags=["auth"])
@@ -72,14 +73,30 @@ async def create_email_session(
window_seconds=300,
)
result = await service.create_email_session(payload)
user_id = UUID(result.user.id)
if payload.language is not None or payload.timezone is not None:
user_repository = SQLAlchemyUserRepository(session)
profile = await user_repository.get_profile_by_user_id(user_id=user_id)
if profile is not None:
settings: dict[str, object] = dict(profile.settings or {})
prefs_raw = settings.get("preferences", {})
preferences: dict[str, object] = dict(prefs_raw) if isinstance(prefs_raw, dict) else {}
if payload.language is not None:
preferences["language"] = payload.language
if payload.timezone is not None:
preferences["timezone"] = payload.timezone
settings["preferences"] = preferences
profile.settings = settings
points_service = PointsService(repository=PointsRepository(session))
bonus_result = await points_service.grant_register_bonus_if_eligible(
user_id=UUID(result.user.id),
user_id=user_id,
user_email=result.user.email,
)
notification_service = NotificationService(NotificationRepository(session))
linked_count = await notification_service.link_notifications_for_registered_user(
user_id=UUID(result.user.id),
user_id=user_id,
is_first_registration=bonus_result.is_first_registration,
)
await session.commit()
+2
View File
@@ -17,6 +17,8 @@ class EmailSessionCreateRequest(BaseModel):
email: str = Field(pattern=SUPABASE_EMAIL_PATTERN)
token: str = Field(min_length=6, max_length=6)
language: str | None = Field(default=None, max_length=20)
timezone: str | None = Field(default=None, max_length=50)
class SessionRefreshRequest(BaseModel):