feat: A3-A6 数据层(内容/播放/记录收藏/互动的 HTTP 对接)
- AppCatalog 模型(feed/section/card/detail/episode/banner/category) - HttpCatalogRepository 对接首页/发现/分类/详情 - PlaybackRepository 播放票据、WatchRepository 记录收藏 - InteractionRepository 评论点赞举报、WalletRepository 钱包解锁
This commit is contained in:
1 parent
a7ac3b7fc7
commit
88a401512d
6 files changed
+382
No files matched your search
@@ -0,0 +1,33 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import '../models/app_catalog.dart';
|
||||
import '../services/api_client.dart';
|
||||
|
||||
/// 对接后端 `/app/**` 内容接口(A3)。
|
||||
class HttpCatalogRepository {
|
||||
HttpCatalogRepository(this._client);
|
||||
|
||||
final ApiClient _client;
|
||||
|
||||
Future<AppFeed> fetchHomeFeed() async {
|
||||
final data = await _client.get('/app/home/feed');
|
||||
return AppFeed.fromJson(data as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Future<AppFeed> fetchDiscoverFeed() async {
|
||||
final data = await _client.get('/app/discover/feed');
|
||||
return AppFeed.fromJson(data as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Future<List<AppCategory>> fetchCategories() async {
|
||||
final data = await _client.get('/app/categories');
|
||||
return (data as List)
|
||||
.map((e) => AppCategory.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<AppDramaDetail> fetchDramaDetail(int id) async {
|
||||
final data = await _client.get('/app/dramas/$id');
|
||||
return AppDramaDetail.fromJson(data as Map<String, dynamic>);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import '../services/api_client.dart';
|
||||
|
||||
/// 评论、点赞、举报(A6)。
|
||||
class InteractionRepository {
|
||||
InteractionRepository(this._client);
|
||||
|
||||
final ApiClient _client;
|
||||
|
||||
Future<void> postComment({
|
||||
required int dramaId,
|
||||
required String content,
|
||||
int? rootId,
|
||||
}) async {
|
||||
await _client.post('/app/comments', data: {
|
||||
'dramaId': dramaId,
|
||||
'content': content,
|
||||
if (rootId != null) 'rootId': rootId,
|
||||
});
|
||||
}
|
||||
|
||||
Future<List<dynamic>> fetchComments({
|
||||
required int dramaId,
|
||||
int? cursor,
|
||||
int size = 20,
|
||||
}) async {
|
||||
final data = await _client.get('/app/comments', query: {
|
||||
'dramaId': dramaId,
|
||||
if (cursor != null) 'cursor': cursor,
|
||||
'size': size,
|
||||
});
|
||||
return data as List;
|
||||
}
|
||||
|
||||
Future<void> deleteComment(int id) async {
|
||||
await _client.delete('/app/comments/$id');
|
||||
}
|
||||
|
||||
Future<void> toggleLike({
|
||||
required String targetType,
|
||||
required int targetId,
|
||||
}) async {
|
||||
await _client.post('/app/likes/toggle', data: {
|
||||
'targetType': targetType,
|
||||
'targetId': targetId,
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> report({
|
||||
required String targetType,
|
||||
required int targetId,
|
||||
required String reason,
|
||||
}) async {
|
||||
await _client.post('/app/reports', data: {
|
||||
'targetType': targetType,
|
||||
'targetId': targetId,
|
||||
'reason': reason,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import '../services/api_client.dart';
|
||||
|
||||
/// 播放票据(A4)。
|
||||
class PlaybackRepository {
|
||||
PlaybackRepository(this._client);
|
||||
|
||||
final ApiClient _client;
|
||||
|
||||
/// 签发播放票据与签名地址,客户端原样使用 playUrl。
|
||||
Future<Map<String, dynamic>> fetchPlayTicket(int episodeId) async {
|
||||
final data = await _client.get('/app/episodes/$episodeId/play');
|
||||
return data as Map<String, dynamic>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import '../services/api_client.dart';
|
||||
|
||||
/// 钱包、金币解锁(09 收费支付)。
|
||||
class WalletRepository {
|
||||
WalletRepository(this._client);
|
||||
|
||||
final ApiClient _client;
|
||||
|
||||
Future<Map<String, dynamic>> fetchWallet() async {
|
||||
final data = await _client.get('/app/wallet');
|
||||
return data as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> unlockEpisode(int episodeId) async {
|
||||
final data = await _client.post('/app/episodes/$episodeId/unlock');
|
||||
return data as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
Future<List<dynamic>> fetchOrders() async {
|
||||
final data = await _client.get('/app/orders');
|
||||
return data as List;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import '../services/api_client.dart';
|
||||
|
||||
/// 观看记录与收藏(A5)。
|
||||
class WatchRepository {
|
||||
WatchRepository(this._client);
|
||||
|
||||
final ApiClient _client;
|
||||
|
||||
Future<void> reportProgress({
|
||||
required int episodeId,
|
||||
required int positionSec,
|
||||
required int durationSec,
|
||||
}) async {
|
||||
await _client.post('/app/watch/progress', data: {
|
||||
'episodeId': episodeId,
|
||||
'positionSec': positionSec,
|
||||
'durationSec': durationSec,
|
||||
});
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> fetchProgress(int dramaId) async {
|
||||
final data = await _client.get('/app/watch/progress', query: {
|
||||
'dramaId': dramaId,
|
||||
});
|
||||
return data as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
Future<List<dynamic>> fetchRecent({int limit = 20}) async {
|
||||
final data = await _client.get('/app/watch/recent', query: {'limit': limit});
|
||||
return data as List;
|
||||
}
|
||||
|
||||
Future<void> deleteProgress(int dramaId) async {
|
||||
await _client.delete('/app/watch/progress/$dramaId');
|
||||
}
|
||||
|
||||
Future<void> clearProgress() async {
|
||||
await _client.delete('/app/watch/progress');
|
||||
}
|
||||
|
||||
Future<bool> toggleFavorite(int dramaId) async {
|
||||
final data = await _client.post('/app/favorites/toggle', data: {
|
||||
'dramaId': dramaId,
|
||||
});
|
||||
final map = data as Map<String, dynamic>;
|
||||
return map['favorited'] as bool? ?? false;
|
||||
}
|
||||
|
||||
Future<List<dynamic>> fetchFavorites() async {
|
||||
final data = await _client.get('/app/favorites');
|
||||
return data as List;
|
||||
}
|
||||
|
||||
Future<void> deleteFavorite(int dramaId) async {
|
||||
await _client.delete('/app/favorites/$dramaId');
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user