feat(notification): 通知标题和正文支持多语言
- 通知静态配置支持 title/body i18n - 前端通知列表和详情页展示本地化内容 - 新增数据库迁移脚本 - 更新通知协议文档
This commit is contained in:
@@ -27,6 +27,7 @@ List notifications for the current user.
|
||||
|
||||
- `limit` (optional, integer, default 20, max 50): number of items per page
|
||||
- `cursor` (optional, string): pagination cursor (ISO 8601 timestamp of last item's `created_at`)
|
||||
- `locale` (optional, string): requested locale for title/body resolution. Supported values: `zh` (default), `zh_Hant`, `en`. If the requested locale is not available in the notification's i18n dict, falls back to `zh`.
|
||||
|
||||
**Response (200)**:
|
||||
|
||||
@@ -61,6 +62,7 @@ Field rules:
|
||||
- `payload`: discriminated union (see Payload section below)
|
||||
- `isRead`: boolean
|
||||
- `readAt`: ISO 8601 timestamp or `null`
|
||||
- `title` and `body`: resolved plain strings based on the `locale` parameter. The database stores these as i18n JSONB objects (`{"zh": "...", "zh_Hant": "...", "en": "..."}`); the API resolves the best match before returning.
|
||||
- Results are filtered: `notifications.status = 'published'` and `notifications.deleted_at IS NULL`
|
||||
|
||||
### GET /api/v1/notifications/unread-count
|
||||
@@ -92,6 +94,10 @@ Mark a single notification as read. Idempotent.
|
||||
|
||||
- `notification_id`: UUID of the `user_notifications` record
|
||||
|
||||
**Query parameters**:
|
||||
|
||||
- `locale` (optional, string): requested locale for title/body resolution (same rules as list endpoint)
|
||||
|
||||
**Response (200)**:
|
||||
|
||||
```json
|
||||
|
||||
@@ -41,8 +41,14 @@ notification:
|
||||
type: system
|
||||
status: published
|
||||
published_at: 2026-04-10T08:00:00Z
|
||||
title: 新用户欢迎通知
|
||||
body: 你已获得注册奖励,可前往积分中心查看。
|
||||
title:
|
||||
zh: 新用户欢迎通知
|
||||
zh_Hant: 新用戶歡迎通知
|
||||
en: Welcome
|
||||
body:
|
||||
zh: 你已获得注册奖励,可前往积分中心查看。
|
||||
zh_Hant: 你已獲得註冊獎勵,可前往積分中心查看。
|
||||
en: You have received a registration reward. Check your points.
|
||||
payload:
|
||||
action: open_route
|
||||
route: /points
|
||||
@@ -60,8 +66,8 @@ targets:
|
||||
- `status`: required, one of `draft`, `published`, `revoked`
|
||||
- `deleted`: optional, boolean, default `false`, soft-delete this notification
|
||||
- `published_at`: optional ISO 8601 timestamp
|
||||
- `title`: required, non-empty string
|
||||
- `body`: required, non-empty string
|
||||
- `title`: required, non-empty dict mapping locale codes to translated strings. Must include at least `zh`. Supported keys: `zh`, `zh_Hant`, `en`.
|
||||
- `body`: required, non-empty dict mapping locale codes to translated strings. Must include at least `zh`. Supported keys: `zh`, `zh_Hant`, `en`.
|
||||
- `payload`: required, must follow the notification payload protocol
|
||||
|
||||
### targets
|
||||
|
||||
Reference in New Issue
Block a user