Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
395 lines
10 KiB
Dart
395 lines
10 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:openim_common/openim_common.dart';
|
|
import 'package:sprintf/sprintf.dart';
|
|
|
|
import 'utils/api_service.dart';
|
|
|
|
class Apis {
|
|
static Options get imTokenOptions =>
|
|
Options(headers: {'token': DataSp.imToken});
|
|
|
|
static Options get chatTokenOptions =>
|
|
Options(headers: {'token': DataSp.chatToken});
|
|
|
|
static StreamController kickoffController = StreamController<int>.broadcast();
|
|
|
|
static void _kickoff(int? errCode) {
|
|
if (errCode == 1501 ||
|
|
errCode == 1503 ||
|
|
errCode == 1504 ||
|
|
errCode == 1505) {
|
|
kickoffController.sink.add(errCode);
|
|
}
|
|
}
|
|
|
|
static Future<LoginCertificate> login({
|
|
String? areaCode,
|
|
String? phoneNumber,
|
|
String? account,
|
|
String? email,
|
|
String? password,
|
|
String? verificationCode,
|
|
}) async {
|
|
try {
|
|
var data = await HttpUtil.post(Urls.login, data: {
|
|
"areaCode": areaCode,
|
|
'account': account,
|
|
'phoneNumber': phoneNumber,
|
|
'email': email,
|
|
'password': null != password ? IMUtils.generateMD5(password) : null,
|
|
'platform': IMUtils.getPlatform(),
|
|
'verifyCode': verificationCode,
|
|
});
|
|
final cert = LoginCertificate.fromJson(data!);
|
|
ApiService().setToken(cert.imToken);
|
|
|
|
return cert;
|
|
} catch (e, _) {
|
|
final t = e as (int, String?)?;
|
|
|
|
if (t == null) {
|
|
Logger.print('e:$e');
|
|
|
|
return Future.error(e);
|
|
}
|
|
final errCode = t.$1;
|
|
final errMsg = t.$2;
|
|
_kickoff(errCode);
|
|
Logger.print('e:$errCode s:$errMsg');
|
|
return Future.error(e);
|
|
}
|
|
}
|
|
|
|
static Future<LoginCertificate> register({
|
|
required String nickname,
|
|
required String password,
|
|
String? faceURL,
|
|
String? areaCode,
|
|
String? phoneNumber,
|
|
String? email,
|
|
String? account,
|
|
int birth = 0,
|
|
int gender = 1,
|
|
required String verificationCode,
|
|
String? invitationCode,
|
|
}) async {
|
|
try {
|
|
var data = await HttpUtil.post(Urls.register, data: {
|
|
'deviceID': DataSp.getDeviceID(),
|
|
'verifyCode': verificationCode,
|
|
'platform': IMUtils.getPlatform(),
|
|
'invitationCode': invitationCode,
|
|
'autoLogin': true,
|
|
'user': {
|
|
"nickname": nickname,
|
|
"faceURL": faceURL,
|
|
'birth': birth,
|
|
'gender': gender,
|
|
'email': email,
|
|
"areaCode": areaCode,
|
|
'phoneNumber': phoneNumber,
|
|
'account': account,
|
|
'password': IMUtils.generateMD5(password),
|
|
},
|
|
});
|
|
|
|
final cert = LoginCertificate.fromJson(data!);
|
|
ApiService().setToken(cert.imToken);
|
|
|
|
return cert;
|
|
} catch (e, s) {
|
|
final t = e as (int, String?);
|
|
final errCode = t.$1;
|
|
final errMsg = t.$2;
|
|
_kickoff(errCode);
|
|
Logger.print('e:$errCode s:$errMsg');
|
|
return Future.error(e);
|
|
}
|
|
}
|
|
|
|
static Future<dynamic> resetPassword({
|
|
String? areaCode,
|
|
String? phoneNumber,
|
|
String? email,
|
|
required String password,
|
|
required String verificationCode,
|
|
}) async {
|
|
try {
|
|
return HttpUtil.post(
|
|
Urls.resetPwd,
|
|
data: {
|
|
"areaCode": areaCode,
|
|
'phoneNumber': phoneNumber,
|
|
'email': email,
|
|
'password': IMUtils.generateMD5(password),
|
|
'verifyCode': verificationCode,
|
|
'platform': IMUtils.getPlatform(),
|
|
},
|
|
options: chatTokenOptions,
|
|
);
|
|
} catch (e, s) {
|
|
final t = e as (int, String?);
|
|
final errCode = t.$1;
|
|
final errMsg = t.$2;
|
|
_kickoff(errCode);
|
|
Logger.print('e:$errCode s:$errMsg');
|
|
}
|
|
}
|
|
|
|
static Future<bool> changePassword({
|
|
required String userID,
|
|
required String currentPassword,
|
|
required String newPassword,
|
|
}) async {
|
|
try {
|
|
await HttpUtil.post(
|
|
Urls.changePwd,
|
|
data: {
|
|
"userID": userID,
|
|
'currentPassword': IMUtils.generateMD5(currentPassword),
|
|
'newPassword': IMUtils.generateMD5(newPassword),
|
|
'platform': IMUtils.getPlatform(),
|
|
},
|
|
options: chatTokenOptions,
|
|
);
|
|
return true;
|
|
} catch (e, s) {
|
|
final t = e as (int, String?);
|
|
final errCode = t.$1;
|
|
final errMsg = t.$2;
|
|
_kickoff(errCode);
|
|
Logger.print('e:$errCode s:$errMsg');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static Future<bool> changePasswordOfB({
|
|
required String newPassword,
|
|
}) async {
|
|
try {
|
|
await HttpUtil.post(
|
|
Urls.resetPwd,
|
|
data: {
|
|
'password': IMUtils.generateMD5(newPassword),
|
|
'platform': IMUtils.getPlatform(),
|
|
},
|
|
options: chatTokenOptions,
|
|
);
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static Future<dynamic> updateUserInfo({
|
|
required String userID,
|
|
String? account,
|
|
String? phoneNumber,
|
|
String? areaCode,
|
|
String? email,
|
|
String? nickname,
|
|
String? faceURL,
|
|
int? gender,
|
|
int? birth,
|
|
int? level,
|
|
int? allowAddFriend,
|
|
int? allowBeep,
|
|
int? allowVibration,
|
|
}) async {
|
|
// 原 chat `/user/update` 已随 :10008 下线。OpenIM 只同步昵称/头像;
|
|
// 邮箱、性别、生日等业务字段由调用方更新本地状态,不打账号服务。
|
|
if (userID.isEmpty) return {};
|
|
if (nickname != null || faceURL != null) {
|
|
await OpenIM.iMManager.userManager.setSelfInfo(
|
|
nickname: nickname,
|
|
faceURL: faceURL,
|
|
);
|
|
}
|
|
return {};
|
|
}
|
|
|
|
static Future<List<FriendInfo>> searchFriendInfo(
|
|
String keyword, {
|
|
int pageNumber = 1,
|
|
int showNumber = 10,
|
|
}) async {
|
|
try {
|
|
final data = await HttpUtil.post(
|
|
Urls.searchFriendInfo,
|
|
data: {
|
|
'pagination': {'pageNumber': pageNumber, 'showNumber': showNumber},
|
|
'keyword': keyword,
|
|
},
|
|
options: chatTokenOptions,
|
|
);
|
|
if (data['users'] is List) {
|
|
return (data['users'] as List)
|
|
.map((e) => FriendInfo.fromJson(e))
|
|
.toList();
|
|
}
|
|
return [];
|
|
} catch (e, s) {
|
|
final t = e as (int, String?);
|
|
final errCode = t.$1;
|
|
final errMsg = t.$2;
|
|
_kickoff(errCode);
|
|
Logger.print('e:$errCode s:$errMsg');
|
|
return [];
|
|
}
|
|
}
|
|
|
|
static Future<List<UserFullInfo>?> getUserFullInfo({
|
|
int pageNumber = 0,
|
|
int showNumber = 10,
|
|
required List<String> userIDList,
|
|
}) async {
|
|
if (userIDList.isEmpty) return [];
|
|
try {
|
|
final users = await OpenIM.iMManager.userManager.getUsersInfo(
|
|
userIDList: userIDList,
|
|
);
|
|
return users
|
|
.map((e) => UserFullInfoMapper.fromImJson(e.toJson()))
|
|
.toList();
|
|
} catch (e, s) {
|
|
Logger.print('getUserFullInfo e:$e s:$s');
|
|
return [];
|
|
}
|
|
}
|
|
|
|
static Future<List<UserFullInfo>?> searchUserFullInfo({
|
|
required String content,
|
|
int pageNumber = 1,
|
|
int showNumber = 10,
|
|
}) async {
|
|
final keyword = content.trim();
|
|
if (keyword.isEmpty) return [];
|
|
if (pageNumber > 1) return [];
|
|
return getUserFullInfo(userIDList: [keyword], showNumber: showNumber);
|
|
}
|
|
|
|
static Future<UserFullInfo?> queryMyFullInfo() async {
|
|
try {
|
|
final user = await OpenIM.iMManager.userManager.getSelfUserInfo();
|
|
return UserFullInfoMapper.fromImJson(user.toJson());
|
|
} catch (e, s) {
|
|
Logger.print('queryMyFullInfo e:$e s:$s');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
static Future<bool> requestVerificationCode({
|
|
String? areaCode,
|
|
String? phoneNumber,
|
|
String? email,
|
|
required int usedFor,
|
|
String? invitationCode,
|
|
}) async {
|
|
return HttpUtil.post(
|
|
Urls.getVerificationCode,
|
|
data: {
|
|
"areaCode": areaCode,
|
|
"phoneNumber": phoneNumber,
|
|
"email": email,
|
|
'usedFor': usedFor,
|
|
'invitationCode': invitationCode
|
|
},
|
|
).then((value) {
|
|
IMViews.showToast(StrRes.sentSuccessfully);
|
|
return true;
|
|
}).catchError((e, s) {
|
|
Logger.print('e:$e s:$s');
|
|
return false;
|
|
});
|
|
}
|
|
|
|
static Future<SignalingCertificate> getTokenForRTC(
|
|
String roomID, String userID) async {
|
|
return HttpUtil.post(
|
|
Urls.getTokenForRTC,
|
|
data: {
|
|
"room": roomID,
|
|
"identity": userID,
|
|
},
|
|
options: chatTokenOptions,
|
|
).then((value) {
|
|
final signaling = SignalingCertificate.fromJson(value)..roomID = roomID;
|
|
return signaling;
|
|
}).catchError((e, s) {
|
|
Logger.print('e:$e s:$s');
|
|
});
|
|
}
|
|
|
|
static Future<dynamic> checkVerificationCode({
|
|
String? areaCode,
|
|
String? phoneNumber,
|
|
String? email,
|
|
required String verificationCode,
|
|
required int usedFor,
|
|
String? invitationCode,
|
|
}) {
|
|
return HttpUtil.post(
|
|
Urls.checkVerificationCode,
|
|
data: {
|
|
"phoneNumber": phoneNumber,
|
|
"areaCode": areaCode,
|
|
"email": email,
|
|
"verifyCode": verificationCode,
|
|
"usedFor": usedFor,
|
|
'invitationCode': invitationCode
|
|
},
|
|
);
|
|
}
|
|
|
|
static Future<UpgradeInfoV2> checkUpgradeV2() {
|
|
return dio.post<Map<String, dynamic>>(
|
|
'https://www.pgyer.com/apiv2/app/check',
|
|
options: Options(
|
|
contentType: 'application/x-www-form-urlencoded',
|
|
),
|
|
data: {
|
|
'_api_key': '',
|
|
'appKey': '',
|
|
},
|
|
).then((resp) {
|
|
Map<String, dynamic> map = resp.data!;
|
|
if (map['code'] == 0) {
|
|
return UpgradeInfoV2.fromJson(map['data']);
|
|
}
|
|
return Future.error(map);
|
|
});
|
|
}
|
|
|
|
static Future<Map<String, dynamic>> getClientConfig() async {
|
|
return {
|
|
'discoverPageURL': Config.discoverPageURL,
|
|
'allowSendMsgNotFriend': Config.allowSendMsgNotFriend
|
|
};
|
|
}
|
|
|
|
static void _catchError(Object e, StackTrace s, {bool forceBack = true}) {
|
|
if (e is ApiException) {
|
|
var msg = '${e.code}'.tr;
|
|
if (msg.isEmpty || e.code.toString() == msg) {
|
|
msg = e.message ?? 'Unkonw error';
|
|
} else if (e.code == 1004) {
|
|
msg = sprintf(msg, [StrRes.meeting]);
|
|
}
|
|
|
|
IMViews.showToast(msg);
|
|
|
|
if ((e.code == 10010 || e.code == 10002) && forceBack) {
|
|
DataSp.removeLoginCertificate();
|
|
Get.offAllNamed('/login');
|
|
}
|
|
} else {
|
|
IMViews.showToast(e.toString());
|
|
}
|
|
}
|
|
}
|