// 认证令牌模型 — 匹配后端 LoginResp // // 管理访问令牌和刷新令牌,支持自动计算过期时间。 // 令牌通过 flutter_secure_storage 安全持久化(PIPL 合规要求)。 /// 认证令牌 — 包含访问令牌、刷新令牌和过期信息 class AuthToken { final String accessToken; final String refreshToken; final int expiresIn; final DateTime expiresAt; const AuthToken({ required this.accessToken, required this.refreshToken, required this.expiresIn, required this.expiresAt, }); /// 令牌是否已过期 bool get isExpired => DateTime.now().isAfter(expiresAt); /// 令牌是否即将过期(5 分钟内) bool get isExpiringSoon => DateTime.now().isAfter(expiresAt.subtract(const Duration(minutes: 5))); /// 从后端 LoginResp JSON 创建 factory AuthToken.fromJson(Map json) { final expiresIn = (json['expires_in'] as int?) ?? 3600; return AuthToken( accessToken: json['access_token'] as String, refreshToken: json['refresh_token'] as String, expiresIn: expiresIn, expiresAt: DateTime.now().add(Duration(seconds: expiresIn)), ); } Map toJson() => { 'access_token': accessToken, 'refresh_token': refreshToken, 'expires_in': expiresIn, 'expires_at': expiresAt.toIso8601String(), }; /// 从持久化存储恢复(使用保存的过期时间) factory AuthToken.fromStorage(Map json) => AuthToken( accessToken: json['access_token'] as String, refreshToken: json['refresh_token'] as String, expiresIn: (json['expires_in'] as int?) ?? 3600, expiresAt: json['expires_at'] != null ? DateTime.parse(json['expires_at'] as String) : DateTime.now().add(const Duration(hours: 1)), ); }