Files
video/app/lib/services/notification_service.dart
2026-10-15 20:36:59 +08:00

114 lines
3.2 KiB
Dart

import '../core/network/api_client.dart';
import '../core/network/endpoints.dart';
/// 消息通知(《03-接口文档》10.2)
class NotificationItem {
const NotificationItem({
required this.id,
required this.type,
required this.title,
this.content = '',
this.bizId = '',
this.isRead = false,
this.createdAt = '',
});
final int id;
/// 1审核结果 2提现进度 3系统公告 4评论回复
final int type;
final String title;
final String content;
/// 关联业务 ID(审核结果=视频ID、提现进度=提现单号等)
final String bizId;
final bool isRead;
final String createdAt;
static const Map<int, String> typeLabels = {
1: '审核',
2: '提现',
3: '公告',
4: '回复',
};
String get typeLabel => typeLabels[type] ?? '通知';
/// 审核结果:biz_id 为视频 ID
int? get videoId => type == 1 ? int.tryParse(bizId) : null;
NotificationItem copyWith({bool? isRead}) => NotificationItem(
id: id,
type: type,
title: title,
content: content,
bizId: bizId,
isRead: isRead ?? this.isRead,
createdAt: createdAt,
);
factory NotificationItem.fromJson(Map<String, dynamic> json) =>
NotificationItem(
id: (json['id'] as num).toInt(),
type: (json['type'] as num?)?.toInt() ?? 3,
title: (json['title'] as String?) ?? '',
content: (json['content'] as String?) ?? '',
bizId: (json['biz_id'] as String?) ?? '',
isRead: json['is_read'] as bool? ?? false,
createdAt: (json['created_at'] as String?) ?? '',
);
}
/// 通知分页
class NotificationsPage {
const NotificationsPage({required this.total, required this.items});
final int total;
final List<NotificationItem> items;
factory NotificationsPage.fromJson(Map<String, dynamic> json) =>
NotificationsPage(
total: (json['total'] as num?)?.toInt() ?? 0,
items: ((json['list'] as List?) ?? const [])
.whereType<Map<String, dynamic>>()
.map(NotificationItem.fromJson)
.toList(),
);
}
/// 消息通知服务(《03-接口文档》10.2~10.4,均需登录)
class NotificationService {
NotificationService._();
/// 10.2 通知列表(type 筛选 + 分页)
static Future<NotificationsPage> fetchNotifications({
int page = 1,
int pageSize = 20,
int? type,
}) async {
final query = <String, dynamic>{'page': page, 'page_size': pageSize};
if (type != null) query['type'] = type;
final data = await ApiClient.get<Map<String, dynamic>>(
Endpoints.notifications,
queryParameters: query,
);
return NotificationsPage.fromJson(data);
}
/// 10.3 未读数
static Future<int> fetchUnreadCount() async {
final data = await ApiClient.get<Map<String, dynamic>>(
Endpoints.notificationsUnread,
);
return (data['unread'] as num?)?.toInt() ?? 0;
}
/// 10.4 标记已读:ids 与 all 二选一
static Future<void> markRead({List<int>? ids, bool all = false}) async {
await ApiClient.post<Map<String, dynamic>>(
Endpoints.notificationsRead,
data: all ? {'all': true} : {'ids': ids},
);
}
}