This commit is contained in:
macbook_max
2026-10-15 20:36:59 +08:00
commit 6bf949949c
7923 changed files with 1369582 additions and 0 deletions
+119
View File
@@ -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;
}