feat: 完成 Flutter 版智能电网 IoT 管理应用初始化搭建
This commit is contained in:
commit
f61b7bf90b
120 files changed
+15229
No files matched your search
@@ -0,0 +1,27 @@
|
||||
import '../../../core/network/api_client.dart';
|
||||
import '../../../core/network/api_response.dart';
|
||||
import 'auth_models.dart';
|
||||
|
||||
/// 认证相关接口,对应 uni-app 版 `api/auth.ts`。
|
||||
class AuthApi {
|
||||
AuthApi(this._client);
|
||||
|
||||
final ApiClient _client;
|
||||
|
||||
Future<ApiResponse<LoginResult>> login({
|
||||
required String username,
|
||||
required String password,
|
||||
}) => _client.post<LoginResult>(
|
||||
'/auth/login',
|
||||
body: {'username': username, 'password': password},
|
||||
parse: (d) => LoginResult.fromJson((d as Map).cast<String, dynamic>()),
|
||||
needAuth: false,
|
||||
);
|
||||
|
||||
Future<ApiResponse<UserInfo>> currentUser() => _client.get<UserInfo>(
|
||||
'/auth/currentUser',
|
||||
parse: (d) => UserInfo.fromJson((d as Map).cast<String, dynamic>()),
|
||||
);
|
||||
|
||||
Future<ApiResponse<void>> logout() => _client.post<void>('/auth/logout');
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import '../../../core/utils/id_util.dart';
|
||||
|
||||
/// 登录态用户信息,对应 `types/auth.ts` 的 `UserInfo`。
|
||||
class UserInfo {
|
||||
const UserInfo({
|
||||
required this.id,
|
||||
required this.username,
|
||||
required this.realName,
|
||||
required this.roles,
|
||||
});
|
||||
|
||||
final int id;
|
||||
final String username;
|
||||
final String realName;
|
||||
final List<String> roles;
|
||||
|
||||
String get displayName => realName.isNotEmpty ? realName : username;
|
||||
|
||||
/// 头像占位文字:取显示名首个字符(按 Unicode 码点截取,兼容中文)。
|
||||
String get avatarText {
|
||||
if (displayName.isEmpty) return '?';
|
||||
return String.fromCharCode(displayName.runes.first);
|
||||
}
|
||||
|
||||
bool get isAdmin => roles.contains('ADMIN');
|
||||
|
||||
factory UserInfo.fromJson(Map<String, dynamic> json) => UserInfo(
|
||||
id: toIntOr(json['id'], 0),
|
||||
username: json['username'] as String? ?? '',
|
||||
realName: json['realName'] as String? ?? '',
|
||||
roles: (json['roles'] as List?)?.map((e) => e.toString()).toList() ?? const [],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'username': username,
|
||||
'realName': realName,
|
||||
'roles': roles,
|
||||
};
|
||||
}
|
||||
|
||||
/// 登录接口返回体,对应 `types/auth.ts` 的 `LoginResponse`。
|
||||
class LoginResult {
|
||||
const LoginResult({
|
||||
required this.accessToken,
|
||||
required this.refreshToken,
|
||||
required this.userInfo,
|
||||
required this.roles,
|
||||
});
|
||||
|
||||
final String accessToken;
|
||||
final String refreshToken;
|
||||
final UserInfo userInfo;
|
||||
final List<String> roles;
|
||||
|
||||
factory LoginResult.fromJson(Map<String, dynamic> json) => LoginResult(
|
||||
accessToken: json['accessToken'] as String? ?? '',
|
||||
refreshToken: json['refreshToken'] as String? ?? '',
|
||||
userInfo: UserInfo.fromJson(
|
||||
(json['userInfo'] as Map?)?.cast<String, dynamic>() ?? const {},
|
||||
),
|
||||
roles: (json['roles'] as List?)?.map((e) => e.toString()).toList() ?? const [],
|
||||
);
|
||||
}
|
||||
|
||||
/// 后端角色编码 → 中文名称映射。
|
||||
const roleLabelMap = <String, String>{
|
||||
'ADMIN': '运营管理员',
|
||||
'SALESMAN': '业务员',
|
||||
'WORKER': '共享电工',
|
||||
'CUSTOMER': '客户',
|
||||
};
|
||||
|
||||
/// 将角色编码数组映射为可读文本(多个角色以 / 分隔)。
|
||||
String roleLabel(List<String>? roles) {
|
||||
if (roles != null && roles.isNotEmpty) {
|
||||
return roles.map((r) => roleLabelMap[r] ?? r).join(' / ');
|
||||
}
|
||||
return '运营管理员';
|
||||
}
|
||||
Reference in new issue
Block a user