Files
PiliPlus/lib/http/user.dart
2026-04-05 12:11:22 +08:00

575 lines
15 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:PiliPlus/http/api.dart';
import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/user/info.dart';
import 'package:PiliPlus/models/user/stat.dart';
import 'package:PiliPlus/models_new/coin_log/data.dart';
import 'package:PiliPlus/models_new/follow/data.dart';
import 'package:PiliPlus/models_new/history/data.dart';
import 'package:PiliPlus/models_new/later/data.dart';
import 'package:PiliPlus/models_new/login_log/data.dart';
import 'package:PiliPlus/models_new/media_list/data.dart';
import 'package:PiliPlus/models_new/relation/data.dart';
import 'package:PiliPlus/models_new/space_setting/data.dart';
import 'package:PiliPlus/models_new/sub/sub/data.dart';
import 'package:PiliPlus/models_new/user_real_name/data.dart';
import 'package:PiliPlus/models_new/video/video_tag/data.dart';
import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/accounts/account.dart';
import 'package:PiliPlus/utils/app_sign.dart';
import 'package:PiliPlus/utils/global_data.dart';
import 'package:PiliPlus/utils/wbi_sign.dart';
import 'package:dio/dio.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
abstract final class UserHttp {
// static Future<dynamic> userStat({required int mid}) async {
// final res = await Request().get(
// Api.userStat,
// queryParameters: {'vmid': mid},
// );
// if (res.data['code'] == 0) {
// return {'status': true, 'data': res.data['data']};
// } else {
// return {'status': false};
// }
// }
static Future<LoadingState<UserInfoData>> userInfo() async {
final res = await Request().get(Api.userInfo);
if (res.data['code'] == 0) {
UserInfoData data = UserInfoData.fromJson(res.data['data']);
GlobalData().coins = data.money;
return Success(data);
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<UserStat>> userStatOwner() async {
final res = await Request().get(Api.userStatOwner);
if (res.data['code'] == 0) {
return Success(UserStat.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
// 稍后再看
static Future<LoadingState<LaterData>> seeYouLater({
required int page,
int viewed = 0,
String keyword = '',
bool asc = false,
}) async {
final res = await Request().get(
Api.seeYouLater,
queryParameters: await WbiSign.makSign({
'pn': page,
'ps': 20,
'viewed': viewed,
'key': keyword,
'asc': asc,
'need_split': true,
'web_location': 333.881,
}),
);
if (res.data['code'] == 0) {
return Success(LaterData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
// 观看历史
static Future<LoadingState<HistoryData>> historyList({
required String type,
int? max,
int? viewAt,
Account? account,
}) async {
final res = await Request().get(
Api.historyList,
queryParameters: {
'type': type,
'ps': 20,
'max': max ?? 0,
'view_at': viewAt ?? 0,
},
options: Options(extra: {'account': account ?? Accounts.history}),
);
if (res.data['code'] == 0) {
return Success(HistoryData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
// 暂停观看历史
static Future<LoadingState<void>> pauseHistory(
bool switchStatus, {
Account? account,
}) async {
// 暂停switchStatus传true 否则false
account ??= Accounts.history;
final res = await Request().post(
Api.pauseHistory,
data: {
'switch': switchStatus,
'jsonp': 'jsonp',
'csrf': account.csrf,
},
options: Options(
extra: {'account': account},
contentType: Headers.formUrlEncodedContentType,
),
);
if (res.data['code'] == 0) {
return const Success(null);
} else {
return Error(res.data['message']);
}
}
// 观看历史暂停状态
static Future<LoadingState<bool>> historyStatus({Account? account}) async {
final res = await Request().get(
Api.historyStatus,
options: Options(extra: {'account': account ?? Accounts.history}),
);
if (res.data['code'] == 0) {
return Success(res.data['data']);
} else {
return Error(res.data['message']);
}
}
// 清空历史记录
static Future<LoadingState<void>> clearHistory({Account? account}) async {
account ??= Accounts.history;
final res = await Request().post(
Api.clearHistory,
data: {
'jsonp': 'jsonp',
'csrf': account.csrf,
},
options: Options(
extra: {'account': account},
contentType: Headers.formUrlEncodedContentType,
),
);
if (res.data['code'] == 0) {
return const Success(null);
} else {
return Error(res.data['message']);
}
}
// 稍后再看
static Future<LoadingState<void>> toViewLater({
String? bvid,
Object? aid,
}) async {
assert(aid != null || bvid != null);
final res = await Request().post(
Api.toViewLater,
data: {
'aid': ?aid,
'bvid': ?bvid,
'csrf': Accounts.main.csrf,
},
options: Options(contentType: Headers.formUrlEncodedContentType),
);
if (res.data['code'] == 0) {
SmartDialog.showToast('yeah稍后再看');
return const Success(null);
} else {
SmartDialog.showToast(res.data['message'].toString());
return const Error(null);
}
}
// 移除已观看
static Future<LoadingState<void>> toViewDel({required String aids}) async {
final Map<String, dynamic> params = {
'csrf': Accounts.main.csrf,
'resources': aids,
};
final res = await Request().post(
Api.toViewDel,
data: params,
options: Options(contentType: Headers.formUrlEncodedContentType),
);
if (res.data['code'] == 0) {
SmartDialog.showToast('yeah成功移除');
return const Success(null);
} else {
SmartDialog.showToast(res.data['message'].toString());
return const Error(null);
}
}
// 获取用户凭证 失效
// static Future thirdLogin() async {
// final res = await Request().get(
// 'https://passport.bilibili.com/login/app/third',
// queryParameters: {
// 'appkey': Constants.appKey,
// 'api': Constants.thirdApi,
// 'sign': Constants.thirdSign,
// },
// );
// try {
// if (res.data['code'] == 0 && res.data['data']['has_login'] == 1) {
// Request().get(res.data['data']['confirm_uri']);
// }
// } catch (err) {
// SmartDialog.showNotify(msg: '获取用户凭证: $err', notifyType: NotifyType.error);
// }
// }
// 清空稍后再看 // clean_type: null->all, 1->invalid, 2->viewed
static Future<LoadingState<void>> toViewClear([int? cleanType]) async {
final res = await Request().post(
Api.toViewClear,
data: {
'clean_type': ?cleanType,
'csrf': Accounts.main.csrf,
},
options: Options(contentType: Headers.formUrlEncodedContentType),
);
if (res.data['code'] == 0) {
return const Success(null);
} else {
return Error(res.data['message']);
}
}
// 删除历史记录
static Future<LoadingState<void>> delHistory(
String kid, {
Account? account,
}) async {
account ??= Accounts.history;
final res = await Request().post(
Api.delHistory,
data: {
'kid': kid,
'jsonp': 'jsonp',
'csrf': account.csrf,
},
options: Options(
extra: {'account': account},
contentType: Headers.formUrlEncodedContentType,
),
);
if (res.data['code'] == 0) {
return const Success(null);
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<RelationData>> userRelation(int mid) async {
final res = await Request().get(
Api.relation,
queryParameters: {
'fid': mid,
},
);
if (res.data['code'] == 0) {
return Success(RelationData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
// 搜索历史记录
static Future<LoadingState<HistoryData>> searchHistory({
required int pn,
required String keyword,
Account? account,
}) async {
final res = await Request().get(
Api.searchHistory,
queryParameters: {
'pn': pn,
'keyword': keyword,
'business': 'all',
},
options: Options(extra: {'account': account ?? Accounts.history}),
);
if (res.data['code'] == 0) {
return Success(HistoryData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
// 我的订阅
static Future<LoadingState<SubData>> userSubFolder({
required int mid,
required int pn,
required int ps,
}) async {
final res = await Request().get(
Api.userSubFolder,
queryParameters: {
'up_mid': mid,
'ps': ps,
'pn': pn,
'platform': 'web',
},
);
if (res.data['code'] == 0 && res.data['data'] is Map) {
return Success(SubData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<List<VideoTagItem>?>> videoTags({
required String bvid,
Object? cid,
}) async {
final res = await Request().get(
Api.videoTags,
queryParameters: {'bvid': bvid, 'cid': ?cid},
);
if (res.data['code'] == 0) {
return Success(
(res.data['data'] as List?)
?.map((e) => VideoTagItem.fromJson(e))
.toList(),
);
} else {
return const Error(null);
}
}
// 稍后再看列表
static Future<LoadingState<MediaListData>> getMediaList({
required Object type,
required Object bizId,
required int ps,
dynamic oid,
int? otype,
bool withCurrent = false,
bool desc = true,
dynamic sortField = 1,
bool direction = false,
}) async {
final res = await Request().get(
Api.mediaList,
queryParameters: {
'mobi_app': 'web',
'type': type,
'biz_id': bizId,
'oid': ?oid,
'otype': ?otype, // ugc:2 // pgc: 24
'ps': ps,
'direction': direction,
'desc': desc,
'sort_field': sortField,
'tid': 0,
'with_current': withCurrent,
},
);
if (res.data['code'] == 0) {
return Success(MediaListData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<num?>> getCoin() async {
final res = await Request().get(Api.getCoin);
if (res.data['code'] == 0) {
return Success(res.data['data']?['money']);
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<void>> dynamicReport({
required Object mid,
required Object dynId,
required int reasonType,
String? reasonDesc,
}) async {
final res = await Request().post(
Api.dynamicReport,
queryParameters: {
'csrf': Accounts.main.csrf,
},
data: {
"accused_uid": mid,
"dynamic_id": dynId,
"reason_type": reasonType,
"reason_desc": reasonType == 0 ? reasonDesc : null,
},
options: Options(contentType: Headers.formUrlEncodedContentType),
);
if (res.data['code'] == 0) {
return const Success(null);
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<SpaceSettingData>> spaceSetting() async {
final res = await Request().get(
Api.spaceSetting,
queryParameters: {
'mid': Accounts.main.mid,
},
);
if (res.data['code'] == 0) {
return Success(SpaceSettingData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<void>> spaceSettingMod(
Map<String, dynamic> data,
) async {
final res = await Request().post(
Api.spaceSettingMod,
queryParameters: {
'csrf': Accounts.main.csrf,
},
data: data,
options: Options(contentType: Headers.formUrlEncodedContentType),
);
if (res.data['code'] == 0) {
return const Success(null);
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<void>> vipExpAdd() async {
final res = await Request().post(
Api.vipExpAdd,
queryParameters: {
'mid': Accounts.main.mid,
'csrf': Accounts.main.csrf,
},
);
if (res.data['code'] == 0) {
return const Success(null);
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<CoinLogData>> coinLog() async {
final res = await Request().get(
Api.coinLog,
queryParameters: {
'jsonp': 'jsonp',
'web_location': '333.33',
},
);
if (res.data['code'] == 0) {
return Success(CoinLogData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<LoginLogData>> loginLog() async {
final res = await Request().get(
Api.loginLog,
queryParameters: {
'jsonp': 'jsonp',
'web_location': '333.33',
},
);
if (res.data['code'] == 0) {
return Success(LoginLogData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<CoinLogData>> expLog() async {
final res = await Request().get(
Api.expLog,
queryParameters: {
'jsonp': 'jsonp',
'web_location': '333.33',
},
);
if (res.data['code'] == 0) {
return Success(CoinLogData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<UserRealNameData>> getUserRealName(
Object mid,
) async {
final params = {
'access_key': Accounts.main.accessKey,
'up_mid': mid,
};
AppSign.appSign(params);
final res = await Request().get(
Api.userRealName,
queryParameters: params,
);
if (res.data['code'] == 0) {
return Success(UserRealNameData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<FollowData>> followedUp({
required Object mid,
required int pn,
}) async {
final res = await Request().get(
Api.followedUp,
queryParameters: {
'csrf': Accounts.main.csrf,
'pn': pn,
'vmid': mid,
'web_location': 333.789,
'x-bili-device-req-json':
'{"platform":"web","device":"pc","spmid":"333.789"}',
},
);
if (res.data['code'] == 0) {
return Success(FollowData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
static Future<LoadingState<FollowData>> sameFollowing({
required Object mid,
int? pn,
}) async {
final res = await Request().get(
Api.sameFollowing,
queryParameters: {
'csrf': Accounts.main.csrf,
'pn': ?pn,
'vmid': mid,
'web_location': 333.789,
'x-bili-device-req-json':
'{"platform":"web","device":"pc","spmid":"333.789"}',
},
);
if (res.data['code'] == 0) {
return Success(FollowData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
}