286 lines
7.7 KiB
Dart
286 lines
7.7 KiB
Dart
import 'dart:convert';
|
||
import 'package:dio/dio.dart';
|
||
import '../model/user_model.dart';
|
||
import '../tool/encryption_util.dart';
|
||
|
||
class UserService {
|
||
static final Dio _dio = Dio();
|
||
static const String baseUrl = "https://union.godserver.cn";
|
||
|
||
// 注册
|
||
static Future<void> register(String username, String password, String inviter) async {
|
||
try {
|
||
await _dio.post(
|
||
'$baseUrl/user/register',
|
||
data: {
|
||
"username": username,
|
||
"password": password,
|
||
"inviter": inviter,
|
||
},
|
||
);
|
||
} on DioException catch (e) {
|
||
throw _getErrorMessage(e);
|
||
}
|
||
}
|
||
|
||
// 登录
|
||
static Future<String> login(String username, String twoKeyCode) async {
|
||
try {
|
||
final raw = jsonEncode({
|
||
"username": username,
|
||
"twoKeyCode": twoKeyCode,
|
||
});
|
||
final encrypted = EncryptionUtil.encrypt(raw);
|
||
|
||
final res = await _dio.post(
|
||
'$baseUrl/api/user/user',
|
||
data: {
|
||
"code": 200,
|
||
"timestamp": DateTime.now().millisecondsSinceEpoch,
|
||
"msg": "login",
|
||
"data": encrypted,
|
||
},
|
||
);
|
||
|
||
return EncryptionUtil.decrypt(res.data["data"]?.toString() ?? '');
|
||
} on DioException catch (e) {
|
||
throw _getErrorMessage(e);
|
||
}
|
||
}
|
||
|
||
// 获取用户信息
|
||
static Future<UserModel> getUserInfo(String token) async {
|
||
try {
|
||
final res = await _dio.post(
|
||
'$baseUrl/api/user/data',
|
||
data: {
|
||
"msg": "getUser",
|
||
"timestamp": DateTime.now().millisecondsSinceEpoch,
|
||
"data": token,
|
||
},
|
||
options: Options(headers: {"Authorization": token}),
|
||
);
|
||
|
||
final decrypted = EncryptionUtil.decrypt(res.data["data"]?.toString() ?? '');
|
||
return UserModel.fromJson(jsonDecode(decrypted));
|
||
} on DioException catch (e) {
|
||
throw _getErrorMessage(e);
|
||
}
|
||
}
|
||
|
||
// 保存/修改用户信息(updateUser)
|
||
static Future<String> updateUser(String token, String encryptedData) async {
|
||
try {
|
||
final res = await _dio.put(
|
||
'$baseUrl/api/user/data',
|
||
data: {
|
||
"msg": "updateUser",
|
||
"timestamp": DateTime.now().millisecondsSinceEpoch,
|
||
"data": encryptedData,
|
||
},
|
||
options: Options(headers: {"Authorization": token}),
|
||
);
|
||
return res.data.toString();
|
||
} on DioException catch (e) {
|
||
throw _getErrorMessage(e);
|
||
}
|
||
return "";
|
||
}
|
||
|
||
// 检查登录状态
|
||
static Future<bool> isLogin(String token) async {
|
||
try {
|
||
final res = await _dio.get(
|
||
'$baseUrl/api/user/isLogin',
|
||
options: Options(headers: {"Authorization": token}),
|
||
);
|
||
return res.data["code"] == 200;
|
||
} on DioException {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 刷新Token(接口通用逻辑)
|
||
static Future<String?> refreshToken(String oldToken) async {
|
||
try {
|
||
final res = await _dio.post(
|
||
'$baseUrl/api/user/refreshToken',
|
||
options: Options(headers: {"Authorization": oldToken}),
|
||
);
|
||
if (res.data["code"] == 200) {
|
||
return res.data["data"]?.toString();
|
||
}
|
||
return null;
|
||
} on DioException {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 获取角色
|
||
static Future<String?> getUserRole(String token) async {
|
||
try {
|
||
final res = await _dio.get(
|
||
'$baseUrl/api/user/role',
|
||
options: Options(headers: {"Authorization": token}),
|
||
);
|
||
if (res.data["code"] == 200) {
|
||
return res.data["data"]?.toString();
|
||
}
|
||
return null;
|
||
} on DioException {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 获取性别标签
|
||
static Future<List<String>> fetchSexTags() async {
|
||
try {
|
||
final res = await _dio.get('$baseUrl/api/union/sextag');
|
||
if (res.data is List) {
|
||
return List<String>.from(res.data);
|
||
}
|
||
return [];
|
||
} on DioException {
|
||
return [];
|
||
}
|
||
}
|
||
|
||
// 获取好友列表
|
||
static Future<List<dynamic>> fetchFriends(String token) async {
|
||
try {
|
||
final res = await _dio.get(
|
||
'$baseUrl/api/user/friend',
|
||
options: Options(headers: {"Authorization": token}),
|
||
);
|
||
if (res.data is List) {
|
||
return res.data;
|
||
}
|
||
return [];
|
||
} on DioException {
|
||
return [];
|
||
}
|
||
}
|
||
|
||
// 更新API Key
|
||
static Future<void> updateApiKey(String token) async {
|
||
try {
|
||
await _dio.post(
|
||
'$baseUrl/api/user/updateKey',
|
||
data: {
|
||
"msg": "updateApiKey",
|
||
"timestamp": DateTime.now().millisecondsSinceEpoch,
|
||
},
|
||
options: Options(headers: {"Authorization": token}),
|
||
);
|
||
} on DioException catch (e) {
|
||
throw _getErrorMessage(e);
|
||
}
|
||
}
|
||
|
||
// 绑定GitHub - 获取跳转链接
|
||
static Future<String> bindGithub(String token) async {
|
||
try {
|
||
final res = await _dio.get(
|
||
'$baseUrl/api/user/bind/github',
|
||
options: Options(headers: {"Authorization": token}),
|
||
);
|
||
return res.realUri.toString();
|
||
} on DioException catch (e) {
|
||
throw _getErrorMessage(e);
|
||
}
|
||
}
|
||
|
||
// 确认绑定GitHub
|
||
static Future<void> confirmBindGithub(String token, String uuid) async {
|
||
try {
|
||
await _dio.post(
|
||
'$baseUrl/api/user/bind/github',
|
||
options: Options(headers: {
|
||
"Authorization": token,
|
||
"uuid": uuid,
|
||
}),
|
||
);
|
||
} on DioException catch (e) {
|
||
throw _getErrorMessage(e);
|
||
}
|
||
}
|
||
|
||
// 验证SegaId
|
||
static Future<Map<String, dynamic>> verifySegaId(String token, String segaId) async {
|
||
try {
|
||
final res = await _dio.post(
|
||
'$baseUrl/api/user/verifySegaId',
|
||
queryParameters: {"useSegaId": segaId},
|
||
options: Options(headers: {"Authorization": token}),
|
||
);
|
||
return res.data;
|
||
} on DioException catch (e) {
|
||
throw _getErrorMessage(e);
|
||
}
|
||
}
|
||
// 获取雷达图数据
|
||
static Future<Map<String, dynamic>> getRadarData(String token, String id) async {
|
||
try {
|
||
final res = await _dio.get(
|
||
'$baseUrl/api/union/radar',
|
||
queryParameters: {"id": id},
|
||
options: Options(headers: {"Authorization": token}),
|
||
);
|
||
// 返回雷达图原始数据
|
||
return Map<String, dynamic>.from(res.data);
|
||
} on DioException catch (e) {
|
||
throw _getErrorMessage(e);
|
||
}
|
||
}
|
||
// 统一错误处理
|
||
static String _getErrorMessage(DioException e) {
|
||
if (e.response?.data != null) {
|
||
final data = e.response!.data;
|
||
if (data is Map && data["msg"] != null) {
|
||
return data["msg"].toString();
|
||
}
|
||
}
|
||
switch (e.type) {
|
||
case DioExceptionType.connectionTimeout:
|
||
case DioExceptionType.receiveTimeout:
|
||
case DioExceptionType.sendTimeout:
|
||
return "网络超时";
|
||
case DioExceptionType.connectionError:
|
||
return "网络异常";
|
||
default:
|
||
return "请求失败";
|
||
}
|
||
}
|
||
static Future<Map<String, dynamic>> getUserAllScores(String token, {String? name}) async {
|
||
try {
|
||
// 构建查询参数
|
||
final queryParameters = <String, dynamic>{};
|
||
if (name != null && name.isNotEmpty) {
|
||
queryParameters['name'] = name;
|
||
}
|
||
final res = await _dio.get(
|
||
'$baseUrl/api/union/reisaRating',
|
||
queryParameters: queryParameters,
|
||
options: Options(headers: {"Authorization": token}),
|
||
);
|
||
if (res.data is Map) {
|
||
return Map<String, dynamic>.from(res.data);
|
||
}
|
||
return {};
|
||
} on DioException catch (e) {
|
||
throw _getErrorMessage(e);
|
||
}
|
||
}
|
||
static Future<Map<String, dynamic>> getSegaRatingData(String token, String segaId) async {
|
||
try {
|
||
final res = await _dio.get(
|
||
'$baseUrl/api/union/segaReisaRating',
|
||
queryParameters: {"segaId": segaId},
|
||
options: Options(headers: {"Authorization": token}),
|
||
);
|
||
return Map<String, dynamic>.from(res.data);
|
||
} on DioException catch (e) {
|
||
throw _getErrorMessage(e);
|
||
}
|
||
}
|
||
} |