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
+87
View File
@@ -0,0 +1,87 @@
import '../core/network/api_client.dart';
import '../core/network/api_exception.dart';
import '../core/network/endpoints.dart';
import '../models/user_model.dart';
/// 认证服务(《03-接口文档》第 3 章)
class AuthService {
AuthService._();
/// 3.1 发送短信验证码 scene: register/login/reset
static Future<void> sendSmsCode(String phone, String scene) async {
await ApiClient.I.post(Endpoints.smsSend, data: {'phone': phone, 'scene': scene});
}
/// 3.2 发送邮箱验证码
static Future<void> sendEmailCode(String email, String scene) async {
await ApiClient.I.post(Endpoints.emailSend, data: {'email': email, 'scene': scene});
}
/// 3.3 注册(type: phone/email,可带邀请码),返回 Token 对与用户信息
static Future<LoginResult> register({
required String type,
required String account,
required String code,
required String password,
String? nickname,
String? inviteCode,
}) async {
final data = await ApiClient.post<Map<String, dynamic>>(Endpoints.register, data: {
'type': type,
if (type == 'phone') 'phone': account else 'email': account,
'code': code,
'password': password,
if (nickname != null && nickname.isNotEmpty) 'nickname': nickname,
if (inviteCode != null && inviteCode.isNotEmpty) 'invite_code': inviteCode,
});
return _fromTokenData(data);
}
/// 3.4 登录(type: phone_password/phone_code/email_password)
static Future<LoginResult> login({
required String type,
String? phone,
String? email,
String? password,
String? code,
}) async {
final data = await ApiClient.post<Map<String, dynamic>>(Endpoints.login, data: {
'type': type,
if (phone != null) 'phone': phone,
if (email != null) 'email': email,
if (password != null) 'password': password,
if (code != null) 'code': code,
});
return _fromTokenData(data);
}
/// 3.6 退出登录
static Future<void> logout() async {
try {
await ApiClient.I.post(Endpoints.logout);
} on ApiException catch (e) {
// Token 已失效等情况忽略,本地照常清理
if (!e.isUnauthorized) rethrow;
}
}
/// 统一解析 Token 响应:access/refresh 入安全存储,user 转模型
static LoginResult _fromTokenData(Map<String, dynamic> data) {
final user = UserModel.fromJson((data['user'] as Map<String, dynamic>?) ?? const {});
final trial = data['trial_granted'] as Map<String, dynamic>?;
return LoginResult(
user: user,
trialPlanName: trial?['plan_name'] as String?,
);
}
}
/// 登录/注册结果
class LoginResult {
LoginResult({required this.user, this.trialPlanName});
final UserModel user;
/// 注册赠送的体验会员名称(关闭赠送开关时为 null)
final String? trialPlanName;
}