feat(flutter): 接入互动评论点赞举报

This commit is contained in:
Zhou Weidong committed 2026-10-17 15:26:42 +08:00
1 parent 45f5f25640
commit d361034226
39 files changed
+3298 -462

No files matched your search

+59
View File
@@ -0,0 +1,59 @@
// Author: fruit.com.cn
import '../models/comment.dart';
import 'api_client.dart';
/// 评论接口,对应契约 §1.7 的 `/app/comments*`。
class CommentApi {
const CommentApi(this._client);
final ApiClient _client;
/// 拉取游标分页;`rootId` 用于加载某一楼层的回复。
Future<CommentPage> page({
required String dramaId,
String? rootId,
String? cursor,
int size = commentPageSize,
}) async {
final data = await _client.get(
'/app/comments',
query: {
'dramaId': dramaId,
'rootId': ?rootId,
'cursor': ?cursor,
'size': '$size',
},
);
if (data is! Map<String, dynamic>) return const CommentPage();
return CommentPage.fromJson(data);
}
/// 发表评论或回复;回复只提交 `parentId`,不自行拼层级。
Future<DramaComment> publish({
required String dramaId,
String? episodeId,
required String content,
String? parentId,
}) async {
final data = await _client.post(
'/app/comments',
body: {
'dramaId': dramaId,
if (episodeId != null && episodeId.isNotEmpty)
'episodeId': episodeId,
'content': content,
if (parentId != null && parentId.isNotEmpty) 'parentId': parentId,
},
);
if (data is! Map<String, dynamic>) {
throw const ApiException(500, '评论响应格式错误');
}
return DramaComment.fromJson(data);
}
/// 删除自己的评论。
Future<void> delete(String commentId) async {
await _client.delete('/app/comments/$commentId');
}
}
+44
View File
@@ -0,0 +1,44 @@
// Author: fruit.com.cn
import '../models/interaction.dart';
import 'api_client.dart';
/// 点赞与举报接口,对应契约 §1.7。
class InteractionApi {
const InteractionApi(this._client);
final ApiClient _client;
/// 切换点赞,服务端返回的状态与计数为最终真相。
Future<LikeToggleResult> toggleLike({
required InteractionTargetType targetType,
required String targetId,
}) async {
final data = await _client.post(
'/app/likes/toggle',
body: {
'targetType': targetType.apiValue,
'targetId': targetId,
},
);
if (data is! Map<String, dynamic>) {
throw const ApiException(500, '点赞响应格式错误');
}
return LikeToggleResult.fromJson(data);
}
/// 提交举报,返回工单 ID。
Future<String> report(ReportRequest request) async {
final data = await _client.post(
'/app/reports',
body: {
'targetType': request.targetType.apiValue,
'targetId': request.targetId,
'reasonCode': request.reasonCode,
if (request.description.isNotEmpty)
'description': request.description,
},
);
return data?.toString() ?? '';
}
}