实现了入门测/出门测报告的完整链路: 1. 新增UserInfo模型的出门测报告标记字段与相关接口 2. 新增全局报告路由拦截器,自动在登录后/应用回前台时检查报告状态 3. 新增报告相关API、页面与路由配置,包含欢迎页、H5壳子、AI计算页 4. 适配登录成功后的报告跳转逻辑,更新用户状态管理方法
90 lines
2.9 KiB
Dart
90 lines
2.9 KiB
Dart
/// ============================================================
|
||
/// 【auth 模块模型】登录相关实体 —— 对照 Vue 项目 src/api/login.ts
|
||
///
|
||
/// LoginRequest → 登录请求体(toJson 提交给服务器)
|
||
/// LoginResponse → 登录响应(token + 用户信息)
|
||
/// UserInfo → 用户信息子模型(info 字段)
|
||
///
|
||
/// 高频坑:
|
||
/// 1. fromJson 全部用 ?? 兜底,字段缺失/类型漂移不会闪崩;
|
||
/// 2. 数字用 (json['x'] as num?)?.toInt() 防 int/double 不一致;
|
||
/// 3. 兼容业务响应壳 {code, msg, data: {token, info}}。
|
||
/// ============================================================
|
||
library;
|
||
|
||
class LoginRequest {
|
||
const LoginRequest({required this.account, required this.password});
|
||
|
||
final String account;
|
||
final String password;
|
||
|
||
Map<String, dynamic> toJson() {
|
||
return {
|
||
'account': account,
|
||
'password': password,
|
||
};
|
||
}
|
||
}
|
||
|
||
class LoginResponse {
|
||
const LoginResponse({required this.token, required this.info});
|
||
|
||
final String token;
|
||
final UserInfo info;
|
||
|
||
factory LoginResponse.fromJson(Map<String, dynamic> json) {
|
||
// 兼容常见包装结构:后端可能直接返回 {token, info},
|
||
// 也可能包一层 {code, msg, data: {token, info}}(业务响应通用壳)。
|
||
// data 存在就取 data,否则直接用 json,两种都能解析到。
|
||
final payload = (json['data'] as Map<String, dynamic>?) ?? json;
|
||
return LoginResponse(
|
||
token: payload['token'] as String? ?? '',
|
||
info: UserInfo.fromJson(
|
||
(payload['info'] as Map<String, dynamic>?) ?? const {},
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
/// 用户信息(对齐 Vue 端 getUserInfo 的字段,未知的用 ?? 兜底)
|
||
class UserInfo {
|
||
const UserInfo({
|
||
this.userId = 0,
|
||
this.userName = '',
|
||
this.account = '',
|
||
this.avatar = '',
|
||
this.phone = '',
|
||
this.isShowReport = false,
|
||
this.isShowAfterReport = false,
|
||
});
|
||
|
||
final int userId;
|
||
final String userName;
|
||
final String account;
|
||
final String avatar;
|
||
final String phone;
|
||
final bool isShowReport;
|
||
|
||
/// 登录响应里的出门测试报告标记(对齐 Vue api/login/type.ts 的 UserInfo)
|
||
final bool isShowAfterReport;
|
||
|
||
factory UserInfo.fromJson(Map<String, dynamic> json) {
|
||
return UserInfo(
|
||
// userId 可能是字符串(后端统一风格),不能直接 as num
|
||
userId: _toInt(json['userId']),
|
||
userName: json['userName'] as String? ?? '',
|
||
account: json['account'] as String? ?? '',
|
||
avatar: json['avatar'] as String? ?? '',
|
||
phone: json['phone'] as String? ?? '',
|
||
isShowReport: json['isShowReport'] as bool? ?? false,
|
||
isShowAfterReport: json['isShowAfterReport'] as bool? ?? false,
|
||
);
|
||
}
|
||
}
|
||
|
||
/// 兼容"字符串数字"(后端 userId 返回 "820466383020136")
|
||
int _toInt(dynamic v) {
|
||
if (v is num) return v.toInt();
|
||
if (v is String) return int.tryParse(v) ?? 0;
|
||
return 0;
|
||
} |