add
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import '../core/network/api_client.dart';
|
||||
import '../core/network/endpoints.dart';
|
||||
import '../models/user_model.dart';
|
||||
import '../models/user_profile.dart';
|
||||
import '../models/video_item.dart';
|
||||
|
||||
/// 用户服务(《03-接口文档》第 4 章 + 6.6/6.7)
|
||||
class UserService {
|
||||
UserService._();
|
||||
|
||||
/// 4.1 获取个人信息
|
||||
static Future<UserModel> fetchMe() async {
|
||||
final data = await ApiClient.get<Map<String, dynamic>>(Endpoints.me);
|
||||
return UserModel.fromJson(data);
|
||||
}
|
||||
|
||||
/// 4.2 修改资料(返回更新后的完整用户对象)
|
||||
static Future<UserModel> updateMe({
|
||||
String? nickname,
|
||||
String? bio,
|
||||
int? gender,
|
||||
}) async {
|
||||
final data = await ApiClient.put<Map<String, dynamic>>(
|
||||
Endpoints.me,
|
||||
data: {
|
||||
if (nickname != null) 'nickname': nickname,
|
||||
if (bio != null) 'bio': bio,
|
||||
if (gender != null) 'gender': gender,
|
||||
},
|
||||
);
|
||||
return UserModel.fromJson(data);
|
||||
}
|
||||
|
||||
/// 4.3 上传头像(multipart,字段名 file;仅支持 jpg/png,≤5MB)
|
||||
static Future<String> uploadAvatar({
|
||||
required String filePath,
|
||||
required String fileName,
|
||||
}) async {
|
||||
final data = await ApiClient.post<Map<String, dynamic>>(
|
||||
Endpoints.meAvatar,
|
||||
data: FormData.fromMap({
|
||||
'file': await MultipartFile.fromFile(filePath, filename: fileName),
|
||||
}),
|
||||
);
|
||||
return (data['avatar_url'] as String?) ?? '';
|
||||
}
|
||||
|
||||
/// 4.7 用户公开主页(游客可)
|
||||
static Future<UserPublicProfile> fetchPublicProfile(int userId) async {
|
||||
final data =
|
||||
await ApiClient.get<Map<String, dynamic>>(Endpoints.userDetail(userId));
|
||||
return UserPublicProfile.fromJson(data);
|
||||
}
|
||||
|
||||
/// 4.8 他人作品列表(仅已发布)
|
||||
static Future<PagedVideos> fetchUserVideos(
|
||||
int userId, {
|
||||
int page = 1,
|
||||
int pageSize = 50,
|
||||
}) =>
|
||||
_fetchVideos(Endpoints.userVideos(userId), page: page, pageSize: pageSize);
|
||||
|
||||
/// 我的作品(需登录,含各状态)
|
||||
static Future<PagedVideos> fetchMyVideos({
|
||||
int page = 1,
|
||||
int pageSize = 50,
|
||||
}) =>
|
||||
_fetchVideos(Endpoints.meVideos, page: page, pageSize: pageSize);
|
||||
|
||||
/// 6.6 我的收藏(需登录)
|
||||
static Future<PagedVideos> fetchMyFavorites({
|
||||
int page = 1,
|
||||
int pageSize = 50,
|
||||
}) =>
|
||||
_fetchVideos(Endpoints.meFavorites, page: page, pageSize: pageSize);
|
||||
|
||||
/// 6.7 观看历史(需登录):video + watched_at + cost_type
|
||||
static Future<List<HistoryItem>> fetchMyHistory({
|
||||
int page = 1,
|
||||
int pageSize = 50,
|
||||
}) async {
|
||||
final data = await ApiClient.get<Map<String, dynamic>>(
|
||||
Endpoints.meHistory,
|
||||
queryParameters: {'page': page, 'page_size': pageSize},
|
||||
);
|
||||
return ((data['list'] as List?) ?? const [])
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map(HistoryItem.fromJson)
|
||||
.toList();
|
||||
}
|
||||
|
||||
static Future<PagedVideos> _fetchVideos(
|
||||
String path, {
|
||||
required int page,
|
||||
required int pageSize,
|
||||
}) async {
|
||||
final data = await ApiClient.get<Map<String, dynamic>>(
|
||||
path,
|
||||
queryParameters: {'page': page, 'page_size': pageSize},
|
||||
);
|
||||
return PagedVideos(
|
||||
total: (data['total'] as num?)?.toInt() ?? 0,
|
||||
items: ((data['list'] as List?) ?? const [])
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map(VideoItem.fromJson)
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 视频分页结果(普通 page/page_size 分页)
|
||||
class PagedVideos {
|
||||
PagedVideos({required this.total, required this.items});
|
||||
|
||||
final int total;
|
||||
final List<VideoItem> items;
|
||||
}
|
||||
Reference in New Issue
Block a user