Files
video/app/lib/services/auth_service.dart
T
2026-10-15 20:36:59 +08:00

88 lines
2.8 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 '../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;
}