feat: 实现站内通知系统
- 后端: 新增 notifications/user_notifications 表迁移及 ORM 模型
- 后端: 实现 schema/repository/service/router 全套通知 API
- GET /api/v1/notifications (列表+游标分页)
- GET /api/v1/notifications/unread-count
- PATCH /api/v1/notifications/{id}/read (幂等)
- PATCH /api/v1/notifications/mark-all-read (幂等)
- 后端: payload 使用 Pydantic discriminated union (none/open_route/open_url)
- 后端: 19 个单元测试全部通过
- Flutter: 通知 feature 完整实现 (models/apis/repositories/bloc/UI)
- Flutter: Home 页通知按钮接入真实页面,显示未读 badge
- Flutter: 14 个测试全部通过
- 协议文档: notification-inbox-protocol.md 及错误码注册
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
sealed class NotificationPayload {
|
||||
const NotificationPayload();
|
||||
}
|
||||
|
||||
final class NotificationPayloadNone extends NotificationPayload {
|
||||
const NotificationPayloadNone();
|
||||
}
|
||||
|
||||
final class NotificationPayloadRoute extends NotificationPayload {
|
||||
const NotificationPayloadRoute({
|
||||
required this.route,
|
||||
this.entityId,
|
||||
this.tab,
|
||||
});
|
||||
|
||||
final String route;
|
||||
final String? entityId;
|
||||
final String? tab;
|
||||
}
|
||||
|
||||
final class NotificationPayloadUrl extends NotificationPayload {
|
||||
const NotificationPayloadUrl({required this.url});
|
||||
|
||||
final String url;
|
||||
}
|
||||
|
||||
NotificationPayload parseNotificationPayload(Map<String, dynamic> json) {
|
||||
final action = json['action'];
|
||||
switch (action) {
|
||||
case 'open_route':
|
||||
return NotificationPayloadRoute(
|
||||
route: json['route'] as String? ?? '',
|
||||
entityId: json['entityId'] as String?,
|
||||
tab: json['tab'] as String?,
|
||||
);
|
||||
case 'open_url':
|
||||
return NotificationPayloadUrl(url: json['url'] as String? ?? '');
|
||||
case 'none':
|
||||
return const NotificationPayloadNone();
|
||||
default:
|
||||
return const NotificationPayloadNone();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user