Files
CloudHome-Ops/lib/models/sys_user.dart

219 lines
6.2 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.

/// 系统用户模型。
///
/// 对应后端 /sys/user/* 接口的用户实体。
class SysUser {
const SysUser({
required this.id,
required this.username,
required this.realName,
required this.email,
required this.mobile,
required this.status,
required this.roleId,
required this.roleName,
required this.roleNames,
required this.orgId,
required this.orgName,
required this.createTime,
});
/// 用户 ID。
final String id;
/// 登录账号。
final String username;
/// 真实姓名。
final String realName;
/// 邮箱。
final String email;
/// 手机号。
final String mobile;
/// 状态(0=正常 1=禁用)。
final int status;
/// 角色 ID。
final String roleId;
/// 角色名称。
final String roleName;
/// 角色名称列表(后端部分接口返回 roleNames 数组)。
final List<String> roleNames;
/// 所属组织 ID。
final String orgId;
/// 所属组织名称(门店 / 渠道商 / 代理商名称)。
final String orgName;
/// 创建时间。
final DateTime? createTime;
factory SysUser.fromJson(Map<String, dynamic> json) {
final roleList = _parseStringList(json['roleIdList'] ?? json['roleIds']);
final roleNameFromObj = _extractNestedName(
json['roles'] ?? json['role'] ?? json['sysRoles'] ?? json['sysRole'],
const ['roleName', 'name', 'role'],
);
final roleIdFromObj = _extractNestedName(
json['roles'] ?? json['role'] ?? json['sysRoles'] ?? json['sysRole'],
const ['roleId', 'id'],
);
final roleNames = _parseStringList(
json['roleNames'] ?? json['roleName'] ?? roleNameFromObj,
);
final roleId = json['roleId']?.toString() ??
roleIdFromObj ??
(roleList.isNotEmpty ? roleList.first : '');
final orgNameFromObj = _extractNestedName(
json['org'] ??
json['dept'] ??
json['sysOrg'] ??
json['sysDept'] ??
json['organization'],
const ['orgName', 'name', 'deptName', 'org'],
);
final orgIdFromObj = _extractNestedName(
json['org'] ??
json['dept'] ??
json['sysOrg'] ??
json['sysDept'] ??
json['organization'],
const ['orgId', 'id', 'deptId'],
);
return SysUser(
id: json['id']?.toString() ?? json['userId']?.toString() ?? '',
username: json['username']?.toString() ?? '',
realName: json['realName']?.toString() ?? '',
email: json['email']?.toString() ?? '',
mobile: json['mobile']?.toString() ?? '',
status: _parseStatus(json['status']),
roleId: roleId,
roleName: json['roleName']?.toString() ??
(roleNames.isNotEmpty ? roleNames.first : ''),
roleNames: roleNames.isNotEmpty ? roleNames : roleList,
orgId: json['orgId']?.toString() ?? orgIdFromObj ?? '',
orgName: json['orgName']?.toString() ??
json['storeName']?.toString() ??
json['deptName']?.toString() ??
orgNameFromObj ??
'',
createTime: _parseDateTime(json['createTime']),
);
}
/// 从嵌套对象或对象列表中提取名称/ID 字段。
/// 用于兼容后端把角色/组织以对象/对象数组返回的情况。
static String? _extractNestedName(dynamic value, List<String> keys) {
if (value is Map) {
final map = value as Map<String, dynamic>;
for (final key in keys) {
final v = map[key]?.toString();
if (v != null && v.isNotEmpty) return v;
}
}
if (value is List && value.isNotEmpty) {
return _extractNestedName(value.first, keys);
}
return null;
}
/// 兼容 int / String / bool 三种状态表示:
/// - int: 1=正常, 0=禁用(新后台 /sys/user/list 返回 status=1 为启用)
/// - String: '0'/'正常'/'启用'/'true'=正常, 其他=禁用
/// - bool: true=正常, false=禁用
static int _parseStatus(dynamic value) {
if (value == null) return 0;
if (value is bool) return value ? 0 : 1;
if (value is int) {
// 新后台:1=启用/正常,0=禁用/停用。
return value == 1 ? 0 : 1;
}
final text = value.toString().trim().toLowerCase();
if (text.isEmpty ||
text == '0' ||
text == '正常' ||
text == '启用' ||
text == 'true' ||
text == 'ok' ||
text == 'enabled' ||
text == '1') {
return 0;
}
return 1;
}
static List<String> _parseStringList(dynamic value) {
if (value is List) {
return value.map((e) => e?.toString() ?? '').where((e) => e.isNotEmpty).toList();
}
if (value is String && value.isNotEmpty) {
return [value];
}
return const <String>[];
}
/// 兼容 `yyyy-MM-dd HH:mm:ss` 与 ISO 8601 两种时间格式。
static DateTime? _parseDateTime(dynamic value) {
if (value == null) return null;
final text = value.toString().trim();
if (text.isEmpty) return null;
return DateTime.tryParse(text) ??
DateTime.tryParse(text.replaceFirst(' ', 'T'));
}
Map<String, dynamic> toJson() {
return {
'id': id,
'username': username,
'realName': realName,
'email': email,
'mobile': mobile,
'status': status,
'roleId': roleId,
'roleName': roleName,
'roleNames': roleNames,
'orgId': orgId,
'orgName': orgName,
'createTime': createTime?.toIso8601String(),
};
}
/// 复制并覆盖指定字段,用于列表层批量补全角色信息(/_enrichRoles)。
SysUser copyWith({
String? id,
String? username,
String? realName,
String? email,
String? mobile,
int? status,
String? roleId,
String? roleName,
List<String>? roleNames,
String? orgId,
String? orgName,
DateTime? createTime,
}) {
return SysUser(
id: id ?? this.id,
username: username ?? this.username,
realName: realName ?? this.realName,
email: email ?? this.email,
mobile: mobile ?? this.mobile,
status: status ?? this.status,
roleId: roleId ?? this.roleId,
roleName: roleName ?? this.roleName,
roleNames: roleNames ?? this.roleNames,
orgId: orgId ?? this.orgId,
orgName: orgName ?? this.orgName,
createTime: createTime ?? this.createTime,
);
}
}