feat(notification): 通知标题和正文支持多语言
- 通知静态配置支持 title/body i18n - 前端通知列表和详情页展示本地化内容 - 新增数据库迁移脚本 - 更新通知协议文档
This commit is contained in:
@@ -13,6 +13,35 @@ from v1.notifications.schemas import (
|
||||
NotificationPayload,
|
||||
)
|
||||
|
||||
DEFAULT_LOCALE = "zh"
|
||||
SUPPORTED_LOCALES = frozenset({"zh", "zh_Hant", "en"})
|
||||
|
||||
|
||||
def resolve_i18n_text(i18n_dict: dict[str, str], locale: str) -> str:
|
||||
if not i18n_dict:
|
||||
return ""
|
||||
if locale in i18n_dict:
|
||||
return i18n_dict[locale]
|
||||
if DEFAULT_LOCALE in i18n_dict:
|
||||
return i18n_dict[DEFAULT_LOCALE]
|
||||
return ""
|
||||
|
||||
|
||||
def normalize_locale(raw: str | None) -> str:
|
||||
if raw is None:
|
||||
return DEFAULT_LOCALE
|
||||
locale = raw.strip()
|
||||
if locale in SUPPORTED_LOCALES:
|
||||
return locale
|
||||
lower = locale.lower().replace("-", "_")
|
||||
if lower in ("zh_cn", "zh_hans", "zh"):
|
||||
return "zh"
|
||||
if lower in ("zh_tw", "zh_hant", "zh_hk"):
|
||||
return "zh_Hant"
|
||||
if lower.startswith("en"):
|
||||
return "en"
|
||||
return DEFAULT_LOCALE
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class NotificationListItem:
|
||||
@@ -44,6 +73,7 @@ class NotificationService:
|
||||
user_id: UUID,
|
||||
limit: int = 20,
|
||||
cursor: datetime | None = None,
|
||||
locale: str = DEFAULT_LOCALE,
|
||||
) -> NotificationListResult:
|
||||
actual_limit = min(limit, 50)
|
||||
rows = await self._repository.list_notifications(
|
||||
@@ -65,8 +95,8 @@ class NotificationService:
|
||||
id=un.id,
|
||||
notification_id=n.id,
|
||||
type=n.type,
|
||||
title=n.title,
|
||||
body=n.body,
|
||||
title=resolve_i18n_text(n.title, locale),
|
||||
body=resolve_i18n_text(n.body, locale),
|
||||
payload=payload,
|
||||
is_read=un.is_read,
|
||||
read_at=un.read_at,
|
||||
@@ -83,7 +113,11 @@ class NotificationService:
|
||||
return await self._repository.get_unread_count(user_id=user_id)
|
||||
|
||||
async def mark_read(
|
||||
self, *, user_notification_id: UUID, user_id: UUID
|
||||
self,
|
||||
*,
|
||||
user_notification_id: UUID,
|
||||
user_id: UUID,
|
||||
locale: str = DEFAULT_LOCALE,
|
||||
) -> NotificationListItem:
|
||||
result = await self._repository.get_user_notification(
|
||||
user_notification_id=user_notification_id,
|
||||
@@ -109,8 +143,8 @@ class NotificationService:
|
||||
id=un.id,
|
||||
notification_id=n.id,
|
||||
type=n.type,
|
||||
title=n.title,
|
||||
body=n.body,
|
||||
title=resolve_i18n_text(n.title, locale),
|
||||
body=resolve_i18n_text(n.body, locale),
|
||||
payload=payload,
|
||||
is_read=True,
|
||||
read_at=un.read_at or datetime.now(timezone.utc),
|
||||
|
||||
Reference in New Issue
Block a user