feat: 增加组织架构、人员管理、角色管理、添加角色
This commit is contained in:
parent
abe49031ac
commit
9b4d112825
@ -1,6 +1,7 @@
|
|||||||
class ApiPath {
|
class ApiPath {
|
||||||
static const String sendValidationCode = "/v1/common/sendValidationCode";
|
static const String sendValidationCode = "/v1/common/sendValidationCode";
|
||||||
static const String validationCodeLogin = "/v1/user/codeLogin";
|
static const String validationCodeLogin = "/v1/user/codeLogin";
|
||||||
|
static const String userDetail = "/v1/user/detail";
|
||||||
static const String passwordLogin = "/v1/user/pwdLogin";
|
static const String passwordLogin = "/v1/user/pwdLogin";
|
||||||
static const String allTeamList = "/v1/team/teamListAll";
|
static const String allTeamList = "/v1/team/teamListAll";
|
||||||
static const String sceneList = "/v1/team/sceneList";
|
static const String sceneList = "/v1/team/sceneList";
|
||||||
@ -9,4 +10,10 @@ class ApiPath {
|
|||||||
static const String bindTeamStarCloudAccount = "/v1/team/bindStarCloudAccount";
|
static const String bindTeamStarCloudAccount = "/v1/team/bindStarCloudAccount";
|
||||||
static const String updateTeamInfo = "/v1/team/updateTeam";
|
static const String updateTeamInfo = "/v1/team/updateTeam";
|
||||||
static const String getInviteInfo = "/v1/team/getInviteInfo";
|
static const String getInviteInfo = "/v1/team/getInviteInfo";
|
||||||
|
static const String getTeamInviteConfig = "/v1/team/teamApplyConfig";
|
||||||
|
static const String updateTeamInviteConfig = "/v1/team/teamPersonConfigUpdate";
|
||||||
|
static const String departList = "/v1/team/departList";
|
||||||
|
static const String departCreate = "/v1/team/departCreate";
|
||||||
|
static const String roleList = "/v1/team/roleList";
|
||||||
|
static const String roleCreate = "/v1/team/roleCreate";
|
||||||
}
|
}
|
||||||
|
|||||||
32
lib/api/model/team/request/create_new_depart_request.dart
Normal file
32
lib/api/model/team/request/create_new_depart_request.dart
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
class CreateNewDepartRequest {
|
||||||
|
String departName;
|
||||||
|
String parentDepartNo;
|
||||||
|
List<String> leader;
|
||||||
|
|
||||||
|
CreateNewDepartRequest({
|
||||||
|
required this.departName,
|
||||||
|
required this.parentDepartNo,
|
||||||
|
required this.leader,
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
"departName": departName,
|
||||||
|
"parentDepartNo": parentDepartNo,
|
||||||
|
"leader": leader,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static CreateNewDepartRequest fromJson(Map<String, dynamic> json) {
|
||||||
|
return CreateNewDepartRequest(
|
||||||
|
departName: json["departName"],
|
||||||
|
parentDepartNo: json["parentDepartNo"],
|
||||||
|
leader: json["leader"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'CreateNewDepartRequest{departName: $departName, parentDepartNo: $parentDepartNo, leader: $leader}';
|
||||||
|
}
|
||||||
|
}
|
||||||
32
lib/api/model/team/request/create_new_role_request.dart
Normal file
32
lib/api/model/team/request/create_new_role_request.dart
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
class CreateNewRoleRequest {
|
||||||
|
String roleName; // 必填
|
||||||
|
String? roleDesc; // 可选
|
||||||
|
List<String>? personNos; // 可选
|
||||||
|
|
||||||
|
CreateNewRoleRequest({
|
||||||
|
required this.roleName, // 必填字段使用 required
|
||||||
|
this.roleDesc, // 可选字段不使用 required
|
||||||
|
this.personNos, // 可选字段不使用 required
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['roleName'] = roleName;
|
||||||
|
|
||||||
|
// 只有当字段不为 null 时才添加到 JSON 中
|
||||||
|
if (roleDesc != null) {
|
||||||
|
data['roleDesc'] = roleDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (personNos != null) {
|
||||||
|
data['personNos'] = personNos;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'CreateNewRoleRequest{roleName: $roleName, roleDesc: $roleDesc, personNos: $personNos}';
|
||||||
|
}
|
||||||
|
}
|
||||||
19
lib/api/model/team/request/get_depart_list_request.dart
Normal file
19
lib/api/model/team/request/get_depart_list_request.dart
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
class GetDepartListRequest {
|
||||||
|
String departNo;
|
||||||
|
|
||||||
|
GetDepartListRequest({
|
||||||
|
required this.departNo,
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
"departNo": departNo,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory GetDepartListRequest.fromJson(Map<String, dynamic> json) {
|
||||||
|
return GetDepartListRequest(
|
||||||
|
departNo: json['departNo'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
lib/api/model/team/request/role_list_request.dart
Normal file
18
lib/api/model/team/request/role_list_request.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
class RoleListRequest {
|
||||||
|
String teamNo;
|
||||||
|
|
||||||
|
RoleListRequest({
|
||||||
|
required this.teamNo,
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['teamNo'] = teamNo;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'RoleListRequest{teamNo: $teamNo}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
class UpdateInviteParameterConfigRequest {
|
||||||
|
final int joinTeamInputFace;
|
||||||
|
final int applyJoinTeamAudit;
|
||||||
|
final int teamInviteUserValidFalse;
|
||||||
|
|
||||||
|
UpdateInviteParameterConfigRequest({
|
||||||
|
required this.joinTeamInputFace,
|
||||||
|
required this.applyJoinTeamAudit,
|
||||||
|
required this.teamInviteUserValidFalse,
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
"joinTeamInputFace": joinTeamInputFace,
|
||||||
|
"applyJoinTeamAudit": applyJoinTeamAudit,
|
||||||
|
"teamInviteUserValidFalse": teamInviteUserValidFalse,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory UpdateInviteParameterConfigRequest.fromJson(Map<String, dynamic> json) {
|
||||||
|
return UpdateInviteParameterConfigRequest(
|
||||||
|
joinTeamInputFace: json['joinTeamInputFace'] as int,
|
||||||
|
applyJoinTeamAudit: json['applyJoinTeamAudit'] as int,
|
||||||
|
teamInviteUserValidFalse: json['teamInviteUserValidFalse'] as int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
170
lib/api/model/team/response/depart_list_reponse.dart
Normal file
170
lib/api/model/team/response/depart_list_reponse.dart
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
import 'package:starwork_flutter/api/model/team/response/role_list_response.dart';
|
||||||
|
|
||||||
|
class DepartListResponse {
|
||||||
|
final List<DepartItem>? departList;
|
||||||
|
|
||||||
|
DepartListResponse({this.departList});
|
||||||
|
|
||||||
|
factory DepartListResponse.fromJson(Map<String, dynamic> json) {
|
||||||
|
if (json['departList'] == null) {
|
||||||
|
return DepartListResponse(departList: []);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<dynamic> list = json['departList'];
|
||||||
|
return DepartListResponse(
|
||||||
|
departList: list.map((item) => DepartItem.fromJson(item as Map<String, dynamic>)).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'departList': departList?.map((item) => item.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'DepartListResponse{departList: $departList}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DepartItem {
|
||||||
|
final int? id;
|
||||||
|
final String? teamNo;
|
||||||
|
final String? departNo;
|
||||||
|
final String? departName;
|
||||||
|
final int? parentId;
|
||||||
|
final PersonItem? leader;
|
||||||
|
final int? level;
|
||||||
|
final int? sort;
|
||||||
|
final bool? hasLeaf;
|
||||||
|
final int? personNum;
|
||||||
|
final List<PersonItem>? persons; // 新增字段
|
||||||
|
|
||||||
|
DepartItem({
|
||||||
|
this.id,
|
||||||
|
this.teamNo,
|
||||||
|
this.departNo,
|
||||||
|
this.departName,
|
||||||
|
this.parentId,
|
||||||
|
this.leader,
|
||||||
|
this.level,
|
||||||
|
this.sort,
|
||||||
|
this.hasLeaf,
|
||||||
|
this.personNum,
|
||||||
|
this.persons,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory DepartItem.fromJson(Map<String, dynamic> json) {
|
||||||
|
List<PersonItem>? personsList;
|
||||||
|
if (json['persons'] != null && json['persons'] is List) {
|
||||||
|
personsList = (json['persons'] as List).map((item) => PersonItem.fromJson(item as Map<String, dynamic>)).toList();
|
||||||
|
}
|
||||||
|
// 处理 leader 字段(单个 PersonItem)
|
||||||
|
PersonItem? leaderItem;
|
||||||
|
if (json['leader'] != null && json['leader'] is Map) {
|
||||||
|
try {
|
||||||
|
leaderItem = PersonItem.fromJson(json['leader'] as Map<String, dynamic>);
|
||||||
|
} catch (e) {
|
||||||
|
// 如果转换失败,leaderItem 保持为 null
|
||||||
|
leaderItem = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DepartItem(
|
||||||
|
id: json['id'] as int?,
|
||||||
|
teamNo: json['teamNo'] as String?,
|
||||||
|
departNo: json['departNo'] as String?,
|
||||||
|
departName: json['departName'] as String?,
|
||||||
|
parentId: json['parentId'] as int?,
|
||||||
|
leader: leaderItem,
|
||||||
|
level: json['level'] as int?,
|
||||||
|
sort: json['sort'] as int?,
|
||||||
|
hasLeaf: json['hasLeaf'] as bool?,
|
||||||
|
personNum: json['personNum'] as int?,
|
||||||
|
persons: personsList,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'teamNo': teamNo,
|
||||||
|
'departNo': departNo,
|
||||||
|
'departName': departName,
|
||||||
|
'parentId': parentId,
|
||||||
|
'leader': leader?.toJson(), // 序列化单个 leader 对象
|
||||||
|
'level': level,
|
||||||
|
'sort': sort,
|
||||||
|
'hasLeaf': hasLeaf,
|
||||||
|
'personNum': personNum,
|
||||||
|
'persons': persons?.map((item) => item.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'DepartItem{id: $id, teamNo: $teamNo, departNo: $departNo, departName: $departName, parentId: $parentId, leader: $leader, level: $level, sort: $sort, hasLeaf: $hasLeaf, personNum: $personNum, persons: $persons}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增 PersonItem 类
|
||||||
|
class PersonItem {
|
||||||
|
final int? id;
|
||||||
|
final String? personName;
|
||||||
|
final int? userId;
|
||||||
|
final int? jobNumber;
|
||||||
|
final int? sex;
|
||||||
|
final String? personNo;
|
||||||
|
final String? phone;
|
||||||
|
final List<RoleListResponse>? roles;
|
||||||
|
|
||||||
|
PersonItem({
|
||||||
|
this.id,
|
||||||
|
this.personName,
|
||||||
|
this.userId,
|
||||||
|
this.jobNumber,
|
||||||
|
this.sex,
|
||||||
|
this.personNo,
|
||||||
|
this.phone,
|
||||||
|
this.roles,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PersonItem.fromJson(Map<String, dynamic> json) {
|
||||||
|
List<RoleListResponse>? rolesList;
|
||||||
|
if (json['roles'] != null && json['roles'] is List) {
|
||||||
|
rolesList = (json['roles'] as List)
|
||||||
|
.map((item) => RoleListResponse.fromJson(item as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return PersonItem(
|
||||||
|
id: json['id'] as int?,
|
||||||
|
personName: json['personName'] as String?,
|
||||||
|
userId: json['userId'] as int?,
|
||||||
|
jobNumber: json['jobNumber'] as int?,
|
||||||
|
sex: json['sex'] as int?,
|
||||||
|
personNo: json['personNo'] as String?,
|
||||||
|
phone: json['phone'] as String?,
|
||||||
|
roles: rolesList,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'personName': personName,
|
||||||
|
'userId': userId,
|
||||||
|
'jobNumber': jobNumber,
|
||||||
|
'sex': sex,
|
||||||
|
'personNo': personNo,
|
||||||
|
'phone': phone,
|
||||||
|
'roles': roles?.map((item) => item.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'PersonItem{id: $id, personName: $personName, userId: $userId, jobNumber: $jobNumber, sex: $sex, personNo: $personNo, phone: $phone, roles: $roles}';
|
||||||
|
}
|
||||||
|
}
|
||||||
79
lib/api/model/team/response/role_list_response.dart
Normal file
79
lib/api/model/team/response/role_list_response.dart
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/depart_list_reponse.dart';
|
||||||
|
|
||||||
|
class RoleListResponse {
|
||||||
|
int? id;
|
||||||
|
String? teamNo;
|
||||||
|
String? roleName;
|
||||||
|
String? roleDesc;
|
||||||
|
int? roleStatus;
|
||||||
|
String? roleStatusName;
|
||||||
|
int? isDefault;
|
||||||
|
int? isSuper;
|
||||||
|
int? isOperationRole;
|
||||||
|
List<PersonItem>? personList; // 添加 personList 属性
|
||||||
|
|
||||||
|
|
||||||
|
RoleListResponse({
|
||||||
|
this.id,
|
||||||
|
this.teamNo,
|
||||||
|
this.roleName,
|
||||||
|
this.roleDesc,
|
||||||
|
this.roleStatus,
|
||||||
|
this.roleStatusName,
|
||||||
|
this.isDefault,
|
||||||
|
this.isSuper,
|
||||||
|
this.isOperationRole,
|
||||||
|
});
|
||||||
|
|
||||||
|
RoleListResponse.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
teamNo = json['teamNo'];
|
||||||
|
roleName = json['roleName'];
|
||||||
|
roleDesc = json['roleDesc'];
|
||||||
|
roleStatus = json['roleStatus'];
|
||||||
|
roleStatusName = json['roleStatusName'];
|
||||||
|
isDefault = json['isDefault'];
|
||||||
|
isSuper = json['isSuper'];
|
||||||
|
isOperationRole = json['isOperationRole'];
|
||||||
|
// 处理 personList
|
||||||
|
if (json['personList'] != null && json['personList'] is List) {
|
||||||
|
personList = (json['personList'] as List)
|
||||||
|
.map((item) => PersonItem.fromJson(item as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['id'] = id;
|
||||||
|
data['teamNo'] = teamNo;
|
||||||
|
data['roleName'] = roleName;
|
||||||
|
data['roleDesc'] = roleDesc;
|
||||||
|
data['roleStatus'] = roleStatus;
|
||||||
|
data['roleStatusName'] = roleStatusName;
|
||||||
|
data['isDefault'] = isDefault;
|
||||||
|
data['isSuper'] = isSuper;
|
||||||
|
data['isOperationRole'] = isOperationRole;
|
||||||
|
// 序列化 personList
|
||||||
|
if (personList != null) {
|
||||||
|
data['personList'] = personList!.map((item) => item.toJson()).toList();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
// 添加序列化集合并返回 List<Map<String, dynamic>> 的静态方法
|
||||||
|
static List<Map<String, dynamic>> toJsonList(List<RoleListResponse> items) {
|
||||||
|
return items.map((item) => item.toJson()).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加从 List<dynamic> 反序列化集合并返回 List<RoleListResponse> 的静态方法
|
||||||
|
static List<RoleListResponse> fromJsonList(List<dynamic> jsonList) {
|
||||||
|
return jsonList.map((item) => RoleListResponse.fromJson(item as Map<String, dynamic>)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'RoleListResponse{id: $id, teamNo: $teamNo, roleName: $roleName, roleDesc: $roleDesc, roleStatus: $roleStatus, roleStatusName: $roleStatusName, isDefault: $isDefault, isSuper: $isSuper, isOperationRole: $isOperationRole}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
class TeamInviteParameterConfigResponse {
|
||||||
|
String? teamNo;
|
||||||
|
int? applyJoinTeamAudit;
|
||||||
|
int? joinTeamInputFace;
|
||||||
|
int? teamInviteUserValidFalse;
|
||||||
|
|
||||||
|
TeamInviteParameterConfigResponse({
|
||||||
|
this.teamNo,
|
||||||
|
this.applyJoinTeamAudit,
|
||||||
|
this.joinTeamInputFace,
|
||||||
|
this.teamInviteUserValidFalse,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory TeamInviteParameterConfigResponse.fromJson(Map<String, dynamic> json) {
|
||||||
|
return TeamInviteParameterConfigResponse(
|
||||||
|
teamNo: json['teamNo'] as String?,
|
||||||
|
applyJoinTeamAudit: json['applyJoinTeamAudit'] as int?,
|
||||||
|
joinTeamInputFace: json['joinTeamInputFace'] as int?,
|
||||||
|
teamInviteUserValidFalse: json['teamInviteUserValidFalse'] as int?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'teamNo': teamNo,
|
||||||
|
'applyJoinTeamAudit': applyJoinTeamAudit,
|
||||||
|
'joinTeamInputFace': joinTeamInputFace,
|
||||||
|
'teamInviteUserValidFalse': teamInviteUserValidFalse,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TeamInviteParameterConfigResponse{teamNo: $teamNo, applyJoinTeamAudit: $applyJoinTeamAudit, joinTeamInputFace: $joinTeamInputFace, teamInviteUserValidFalse: $teamInviteUserValidFalse}';
|
||||||
|
}
|
||||||
|
}
|
||||||
132
lib/api/model/user/response/user_info_response.dart
Normal file
132
lib/api/model/user/response/user_info_response.dart
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
class UserInfoResponse {
|
||||||
|
final int? id;
|
||||||
|
final String? accountNo;
|
||||||
|
final String? countryCode;
|
||||||
|
final String? phone;
|
||||||
|
final String? nickname;
|
||||||
|
final String? headUrl;
|
||||||
|
final String? createdAt;
|
||||||
|
final String? lastLoginTime;
|
||||||
|
final String? currentTeamNo;
|
||||||
|
final List<TeamInfo>? teamList;
|
||||||
|
|
||||||
|
UserInfoResponse({
|
||||||
|
this.id,
|
||||||
|
this.accountNo,
|
||||||
|
this.countryCode,
|
||||||
|
this.phone,
|
||||||
|
this.nickname,
|
||||||
|
this.headUrl,
|
||||||
|
this.createdAt,
|
||||||
|
this.lastLoginTime,
|
||||||
|
this.currentTeamNo,
|
||||||
|
this.teamList,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory UserInfoResponse.fromJson(Map<String, dynamic> json) {
|
||||||
|
List<TeamInfo>? teamList;
|
||||||
|
if (json['teamList'] != null && json['teamList'] is List) {
|
||||||
|
teamList = (json['teamList'] as List)
|
||||||
|
.map((item) => TeamInfo.fromJson(item as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return UserInfoResponse(
|
||||||
|
id: json['id'] as int?,
|
||||||
|
accountNo: json['accountNo'] as String?,
|
||||||
|
countryCode: json['countryCode'] as String?,
|
||||||
|
phone: json['phone'] as String?,
|
||||||
|
nickname: json['nickname'] as String?,
|
||||||
|
headUrl: json['headUrl'] as String?,
|
||||||
|
createdAt: json['createdAt'] as String?,
|
||||||
|
lastLoginTime: json['lastLoginTime'] as String?,
|
||||||
|
currentTeamNo: json['currentTeamNo'] as String?,
|
||||||
|
teamList: teamList,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'accountNo': accountNo,
|
||||||
|
'countryCode': countryCode,
|
||||||
|
'phone': phone,
|
||||||
|
'nickname': nickname,
|
||||||
|
'headUrl': headUrl,
|
||||||
|
'createdAt': createdAt,
|
||||||
|
'lastLoginTime': lastLoginTime,
|
||||||
|
'currentTeamNo': currentTeamNo,
|
||||||
|
'teamList': teamList?.map((item) => item.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'UserInfoResponse{id: $id, accountNo: $accountNo, countryCode: $countryCode, phone: $phone, nickname: $nickname, headUrl: $headUrl, createdAt: $createdAt, lastLoginTime: $lastLoginTime, currentTeamNo: $currentTeamNo, teamList: $teamList}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TeamInfo {
|
||||||
|
final int? id;
|
||||||
|
final String? teamNo;
|
||||||
|
final String? teamName;
|
||||||
|
final String? teamCode;
|
||||||
|
final String? owner;
|
||||||
|
final String? createdAt;
|
||||||
|
final int? scene;
|
||||||
|
final String? sceneCustomName;
|
||||||
|
final String? personNo;
|
||||||
|
final String? personName;
|
||||||
|
final bool? isOwner;
|
||||||
|
|
||||||
|
TeamInfo({
|
||||||
|
this.id,
|
||||||
|
this.teamNo,
|
||||||
|
this.teamName,
|
||||||
|
this.teamCode,
|
||||||
|
this.owner,
|
||||||
|
this.createdAt,
|
||||||
|
this.scene,
|
||||||
|
this.sceneCustomName,
|
||||||
|
this.personNo,
|
||||||
|
this.personName,
|
||||||
|
this.isOwner,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory TeamInfo.fromJson(Map<String, dynamic> json) {
|
||||||
|
return TeamInfo(
|
||||||
|
id: json['id'] as int?,
|
||||||
|
teamNo: json['teamNo'] as String?,
|
||||||
|
teamName: json['teamName'] as String?,
|
||||||
|
teamCode: json['teamCode'] as String?,
|
||||||
|
owner: json['owner'] as String?,
|
||||||
|
createdAt: json['createdAt'] as String?,
|
||||||
|
scene: json['scene'] as int?,
|
||||||
|
sceneCustomName: json['sceneCustomName'] as String?,
|
||||||
|
personNo: json['personNo'] as String?,
|
||||||
|
personName: json['personName'] as String?,
|
||||||
|
isOwner: json['isOwner'] as bool?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'teamNo': teamNo,
|
||||||
|
'teamName': teamName,
|
||||||
|
'teamCode': teamCode,
|
||||||
|
'owner': owner,
|
||||||
|
'createdAt': createdAt,
|
||||||
|
'scene': scene,
|
||||||
|
'sceneCustomName': sceneCustomName,
|
||||||
|
'personNo': personNo,
|
||||||
|
'personName': personName,
|
||||||
|
'isOwner': isOwner,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TeamInfo{id: $id, teamNo: $teamNo, teamName: $teamName, teamCode: $teamCode, owner: $owner, createdAt: $createdAt, scene: $scene, sceneCustomName: $sceneCustomName, personNo: $personNo, personName: $personName, isOwner: $isOwner}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,13 +4,21 @@ import 'package:starwork_flutter/api/api_response.dart';
|
|||||||
import 'package:starwork_flutter/api/base_api_service.dart';
|
import 'package:starwork_flutter/api/base_api_service.dart';
|
||||||
import 'package:starwork_flutter/api/model/team/request/bind_team_star_cloud_account_request.dart';
|
import 'package:starwork_flutter/api/model/team/request/bind_team_star_cloud_account_request.dart';
|
||||||
import 'package:starwork_flutter/api/model/team/request/change_current_team_request.dart';
|
import 'package:starwork_flutter/api/model/team/request/change_current_team_request.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/request/create_new_depart_request.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/request/create_new_role_request.dart';
|
||||||
import 'package:starwork_flutter/api/model/team/request/create_team_request.dart';
|
import 'package:starwork_flutter/api/model/team/request/create_team_request.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/request/get_depart_list_request.dart';
|
||||||
import 'package:starwork_flutter/api/model/team/request/invite_info_request.dart';
|
import 'package:starwork_flutter/api/model/team/request/invite_info_request.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/request/role_list_request.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/request/update_invite_parameter_config_request.dart';
|
||||||
import 'package:starwork_flutter/api/model/team/request/update_team_info_request.dart';
|
import 'package:starwork_flutter/api/model/team/request/update_team_info_request.dart';
|
||||||
import 'package:starwork_flutter/api/model/team/response/all_team_list_response.dart';
|
import 'package:starwork_flutter/api/model/team/response/all_team_list_response.dart';
|
||||||
import 'package:starwork_flutter/api/model/team/response/create_team_response.dart';
|
import 'package:starwork_flutter/api/model/team/response/create_team_response.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/depart_list_reponse.dart';
|
||||||
import 'package:starwork_flutter/api/model/team/response/invite_info_response.dart';
|
import 'package:starwork_flutter/api/model/team/response/invite_info_response.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/role_list_response.dart';
|
||||||
import 'package:starwork_flutter/api/model/team/response/scene_info_response.dart';
|
import 'package:starwork_flutter/api/model/team/response/scene_info_response.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/team_invite_parameter_config_response.dart';
|
||||||
import 'package:starwork_flutter/api/model/user/request/validation_code_login.dart';
|
import 'package:starwork_flutter/api/model/user/request/validation_code_login.dart';
|
||||||
import 'package:starwork_flutter/api/model/user/response/token_response.dart';
|
import 'package:starwork_flutter/api/model/user/response/token_response.dart';
|
||||||
import 'package:starwork_flutter/common/constant/http_constant.dart';
|
import 'package:starwork_flutter/common/constant/http_constant.dart';
|
||||||
@ -25,7 +33,6 @@ class TeamApiService {
|
|||||||
required CreateTeamRequest request,
|
required CreateTeamRequest request,
|
||||||
}) {
|
}) {
|
||||||
return _api.makeRequest(
|
return _api.makeRequest(
|
||||||
// 通过实例调用
|
|
||||||
path: ApiPath.createTeam,
|
path: ApiPath.createTeam,
|
||||||
method: HttpConstant.post,
|
method: HttpConstant.post,
|
||||||
data: request.toJson(),
|
data: request.toJson(),
|
||||||
@ -36,7 +43,6 @@ class TeamApiService {
|
|||||||
// 所有团队列表
|
// 所有团队列表
|
||||||
Future<ApiResponse<AllTeamListResponse>> requestAllTeamInfoList() {
|
Future<ApiResponse<AllTeamListResponse>> requestAllTeamInfoList() {
|
||||||
return _api.makeRequest(
|
return _api.makeRequest(
|
||||||
// 通过实例调用
|
|
||||||
path: ApiPath.allTeamList,
|
path: ApiPath.allTeamList,
|
||||||
method: HttpConstant.post,
|
method: HttpConstant.post,
|
||||||
fromJson: (data) => AllTeamListResponse.fromJson(data),
|
fromJson: (data) => AllTeamListResponse.fromJson(data),
|
||||||
@ -46,7 +52,6 @@ class TeamApiService {
|
|||||||
// 所有团队使用场景列表
|
// 所有团队使用场景列表
|
||||||
Future<ApiResponse<SceneInfoResponseList>> requestAllSceneInfoList() {
|
Future<ApiResponse<SceneInfoResponseList>> requestAllSceneInfoList() {
|
||||||
return _api.makeRequest(
|
return _api.makeRequest(
|
||||||
// 通过实例调用
|
|
||||||
path: ApiPath.sceneList,
|
path: ApiPath.sceneList,
|
||||||
method: HttpConstant.post,
|
method: HttpConstant.post,
|
||||||
fromJson: (data) => SceneInfoResponseList.fromJson(data),
|
fromJson: (data) => SceneInfoResponseList.fromJson(data),
|
||||||
@ -58,7 +63,6 @@ class TeamApiService {
|
|||||||
required ChangeCurrentTeamRequest request,
|
required ChangeCurrentTeamRequest request,
|
||||||
}) {
|
}) {
|
||||||
return _api.makeRequest(
|
return _api.makeRequest(
|
||||||
// 通过实例调用
|
|
||||||
path: ApiPath.changeTeam,
|
path: ApiPath.changeTeam,
|
||||||
method: HttpConstant.post,
|
method: HttpConstant.post,
|
||||||
data: request.toJson(),
|
data: request.toJson(),
|
||||||
@ -71,7 +75,6 @@ class TeamApiService {
|
|||||||
required BindTeamStarCloudAccountRequest request,
|
required BindTeamStarCloudAccountRequest request,
|
||||||
}) {
|
}) {
|
||||||
return _api.makeRequest(
|
return _api.makeRequest(
|
||||||
// 通过实例调用
|
|
||||||
path: ApiPath.bindTeamStarCloudAccount,
|
path: ApiPath.bindTeamStarCloudAccount,
|
||||||
method: HttpConstant.post,
|
method: HttpConstant.post,
|
||||||
data: request.toJson(),
|
data: request.toJson(),
|
||||||
@ -84,7 +87,6 @@ class TeamApiService {
|
|||||||
required UpdateTeamInfoRequest request,
|
required UpdateTeamInfoRequest request,
|
||||||
}) {
|
}) {
|
||||||
return _api.makeRequest(
|
return _api.makeRequest(
|
||||||
// 通过实例调用
|
|
||||||
path: ApiPath.updateTeamInfo,
|
path: ApiPath.updateTeamInfo,
|
||||||
method: HttpConstant.post,
|
method: HttpConstant.post,
|
||||||
data: request.toJson(),
|
data: request.toJson(),
|
||||||
@ -97,11 +99,76 @@ class TeamApiService {
|
|||||||
required InviteInfoRequest request,
|
required InviteInfoRequest request,
|
||||||
}) {
|
}) {
|
||||||
return _api.makeRequest(
|
return _api.makeRequest(
|
||||||
// 通过实例调用
|
|
||||||
path: ApiPath.getInviteInfo,
|
path: ApiPath.getInviteInfo,
|
||||||
method: HttpConstant.post,
|
method: HttpConstant.post,
|
||||||
data: request.toJson(),
|
data: request.toJson(),
|
||||||
fromJson: (data) => InviteInfoResponse.fromJson(data),
|
fromJson: (data) => InviteInfoResponse.fromJson(data),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 请求邀请参数信息配置
|
||||||
|
Future<ApiResponse<TeamInviteParameterConfigResponse>> requestInviteParameterConfig() {
|
||||||
|
return _api.makeRequest(
|
||||||
|
path: ApiPath.getTeamInviteConfig,
|
||||||
|
method: HttpConstant.post,
|
||||||
|
fromJson: (data) => TeamInviteParameterConfigResponse.fromJson(data),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 请求邀请参数信息修改
|
||||||
|
Future<ApiResponse<void>> requestUpdateInviteParameterConfig({
|
||||||
|
required UpdateInviteParameterConfigRequest request,
|
||||||
|
}) {
|
||||||
|
return _api.makeRequest(
|
||||||
|
path: ApiPath.updateTeamInviteConfig,
|
||||||
|
method: HttpConstant.post,
|
||||||
|
data: request.toJson(),
|
||||||
|
fromJson: (data) {},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取组织列表
|
||||||
|
Future<ApiResponse<DepartListResponse>> requestDepartList({
|
||||||
|
required GetDepartListRequest request,
|
||||||
|
}) {
|
||||||
|
return _api.makeRequest(
|
||||||
|
path: ApiPath.departList,
|
||||||
|
method: HttpConstant.post,
|
||||||
|
data: request.toJson(),
|
||||||
|
fromJson: (data) => DepartListResponse.fromJson(data),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取组织列表
|
||||||
|
Future<ApiResponse<void>> requestCreateDepart({
|
||||||
|
required CreateNewDepartRequest request,
|
||||||
|
}) {
|
||||||
|
return _api.makeRequest(
|
||||||
|
path: ApiPath.departCreate,
|
||||||
|
method: HttpConstant.post,
|
||||||
|
data: request.toJson(),
|
||||||
|
fromJson: (data) {},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取团队角色列表
|
||||||
|
Future<ApiResponse<List<RoleListResponse>>> requestTeamRoleList() {
|
||||||
|
return _api.makeRequest(
|
||||||
|
path: ApiPath.roleList,
|
||||||
|
method: HttpConstant.post,
|
||||||
|
fromJson: (data) => RoleListResponse.fromJsonList(data),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新的角色
|
||||||
|
Future<ApiResponse<void>> requestCreateTeamRole({
|
||||||
|
required CreateNewRoleRequest request,
|
||||||
|
}) {
|
||||||
|
return _api.makeRequest(
|
||||||
|
path: ApiPath.roleCreate,
|
||||||
|
method: HttpConstant.post,
|
||||||
|
data: request.toJson(),
|
||||||
|
fromJson: (data) {},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import 'package:starwork_flutter/api/api_response.dart';
|
|||||||
import 'package:starwork_flutter/api/base_api_service.dart';
|
import 'package:starwork_flutter/api/base_api_service.dart';
|
||||||
import 'package:starwork_flutter/api/model/user/request/validation_code_login.dart';
|
import 'package:starwork_flutter/api/model/user/request/validation_code_login.dart';
|
||||||
import 'package:starwork_flutter/api/model/user/response/token_response.dart';
|
import 'package:starwork_flutter/api/model/user/response/token_response.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/user/response/user_info_response.dart';
|
||||||
import 'package:starwork_flutter/common/constant/http_constant.dart';
|
import 'package:starwork_flutter/common/constant/http_constant.dart';
|
||||||
|
|
||||||
class UserApiService {
|
class UserApiService {
|
||||||
@ -23,4 +24,14 @@ class UserApiService {
|
|||||||
fromJson: (data) => LoginResponse.fromJson(data),
|
fromJson: (data) => LoginResponse.fromJson(data),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 用户信息
|
||||||
|
Future<ApiResponse<UserInfoResponse>> requestUserInfo() {
|
||||||
|
return _api.makeRequest(
|
||||||
|
// 通过实例调用
|
||||||
|
path: ApiPath.userDetail,
|
||||||
|
method: HttpConstant.post,
|
||||||
|
fromJson: (data) => UserInfoResponse.fromJson(data),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,14 +40,14 @@ class _AppState extends State<App> {
|
|||||||
checkboxTheme: CheckboxThemeData(
|
checkboxTheme: CheckboxThemeData(
|
||||||
side: const BorderSide(
|
side: const BorderSide(
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
width: 1, // 设置边框粗细
|
width: 0.5, // 设置边框粗细
|
||||||
),
|
),
|
||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(8.r),
|
borderRadius: BorderRadius.circular(10.r),
|
||||||
),
|
),
|
||||||
checkColor: MaterialStateProperty.all(Colors.white),
|
checkColor: MaterialStateProperty.all(Colors.white),
|
||||||
fillColor: MaterialStateProperty.all(Colors.blue),
|
fillColor: MaterialStateProperty.all(Colors.white),
|
||||||
),
|
),
|
||||||
appBarTheme: AppBarTheme(
|
appBarTheme: AppBarTheme(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
|
|||||||
@ -3,5 +3,6 @@ class AppViewParameterKeys {
|
|||||||
static const String lockInfo = "lockInfo";
|
static const String lockInfo = "lockInfo";
|
||||||
static const String networkInfo = "networkInfo";
|
static const String networkInfo = "networkInfo";
|
||||||
static const String teamInfo = "teamInfo";
|
static const String teamInfo = "teamInfo";
|
||||||
|
static const String departItem = "departItem";
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -8,5 +8,6 @@ class CacheKeys {
|
|||||||
static const String starCloudPassword = 'starCloudPassword';
|
static const String starCloudPassword = 'starCloudPassword';
|
||||||
static const String starCloudUid = 'starCloudUid';
|
static const String starCloudUid = 'starCloudUid';
|
||||||
static const String starCloudUserLoginInfo = 'starCloudUserLoginInfo';
|
static const String starCloudUserLoginInfo = 'starCloudUserLoginInfo';
|
||||||
|
static const String userAccountInfo = 'userAccountInfo';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ class F {
|
|||||||
// Release环境的API地址
|
// Release环境的API地址
|
||||||
switch (appFlavor) {
|
switch (appFlavor) {
|
||||||
case Flavor.sky:
|
case Flavor.sky:
|
||||||
return 'https://192.168.1.138:8112/api'; // 生产环境API
|
return 'https://192.168.1.137:8112/api'; // 生产环境API
|
||||||
case Flavor.xhj:
|
case Flavor.xhj:
|
||||||
return 'https://api.xhjcn.ltd/api'; // 生产环境API
|
return 'https://api.xhjcn.ltd/api'; // 生产环境API
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ class F {
|
|||||||
// Debug/Profile环境的API地址(开发环境)
|
// Debug/Profile环境的API地址(开发环境)
|
||||||
switch (appFlavor) {
|
switch (appFlavor) {
|
||||||
case Flavor.sky:
|
case Flavor.sky:
|
||||||
return 'http://192.168.1.138:8112/api';
|
return 'http://192.168.1.137:8112/api';
|
||||||
case Flavor.xhj:
|
case Flavor.xhj:
|
||||||
return 'https://loacl.work.star-lock.cn/api';
|
return 'https://loacl.work.star-lock.cn/api';
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ class F {
|
|||||||
// Debug/Profile环境的StarCloud地址(开发环境)
|
// Debug/Profile环境的StarCloud地址(开发环境)
|
||||||
switch (appFlavor) {
|
switch (appFlavor) {
|
||||||
case Flavor.sky:
|
case Flavor.sky:
|
||||||
return 'http://192.168.1.138:8111/sdk';
|
return 'http://192.168.1.137:8111/sdk';
|
||||||
case Flavor.xhj:
|
case Flavor.xhj:
|
||||||
return 'http://local.cloud.star-lock.cn';
|
return 'http://local.cloud.star-lock.cn';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,12 +36,22 @@ import 'package:starwork_flutter/views/main/main_binding.dart';
|
|||||||
import 'package:starwork_flutter/views/main/main_view.dart';
|
import 'package:starwork_flutter/views/main/main_view.dart';
|
||||||
import 'package:starwork_flutter/views/team/addPerson/add_person_binding.dart';
|
import 'package:starwork_flutter/views/team/addPerson/add_person_binding.dart';
|
||||||
import 'package:starwork_flutter/views/team/addPerson/add_person_view.dart';
|
import 'package:starwork_flutter/views/team/addPerson/add_person_view.dart';
|
||||||
|
import 'package:starwork_flutter/views/team/addPerson/selectRole/select_role_binding.dart';
|
||||||
|
import 'package:starwork_flutter/views/team/addPerson/selectRole/select_role_view.dart';
|
||||||
|
import 'package:starwork_flutter/views/team/addRole/add_role_binding.dart';
|
||||||
|
import 'package:starwork_flutter/views/team/addRole/add_role_view.dart';
|
||||||
import 'package:starwork_flutter/views/team/inviteTeamMember/invitationSettings/invitation_settings_binding.dart';
|
import 'package:starwork_flutter/views/team/inviteTeamMember/invitationSettings/invitation_settings_binding.dart';
|
||||||
import 'package:starwork_flutter/views/team/inviteTeamMember/invitationSettings/invitation_settings_view.dart';
|
import 'package:starwork_flutter/views/team/inviteTeamMember/invitationSettings/invitation_settings_view.dart';
|
||||||
import 'package:starwork_flutter/views/team/inviteTeamMember/invite_team_member_binding.dart';
|
import 'package:starwork_flutter/views/team/inviteTeamMember/invite_team_member_binding.dart';
|
||||||
import 'package:starwork_flutter/views/team/inviteTeamMember/invite_team_member_view.dart';
|
import 'package:starwork_flutter/views/team/inviteTeamMember/invite_team_member_view.dart';
|
||||||
import 'package:starwork_flutter/views/team/joinTeam/join_team_binding.dart';
|
import 'package:starwork_flutter/views/team/joinTeam/join_team_binding.dart';
|
||||||
import 'package:starwork_flutter/views/team/joinTeam/join_team_view.dart';
|
import 'package:starwork_flutter/views/team/joinTeam/join_team_view.dart';
|
||||||
|
import 'package:starwork_flutter/views/team/personnelManage/personnel_manage_binding.dart';
|
||||||
|
import 'package:starwork_flutter/views/team/personnelManage/personnel_manage_view.dart';
|
||||||
|
import 'package:starwork_flutter/views/team/roleManage/role_manage_binding.dart';
|
||||||
|
import 'package:starwork_flutter/views/team/roleManage/role_manage_view.dart';
|
||||||
|
import 'package:starwork_flutter/views/team/selectOrganization/select_organization_binding.dart';
|
||||||
|
import 'package:starwork_flutter/views/team/selectOrganization/select_organization_view.dart';
|
||||||
import 'package:starwork_flutter/views/team/teamManage/teamInfo/team_info_binding.dart';
|
import 'package:starwork_flutter/views/team/teamManage/teamInfo/team_info_binding.dart';
|
||||||
import 'package:starwork_flutter/views/team/teamManage/teamInfo/team_info_view.dart';
|
import 'package:starwork_flutter/views/team/teamManage/teamInfo/team_info_view.dart';
|
||||||
import 'package:starwork_flutter/views/team/teamManage/team_manage_binding.dart';
|
import 'package:starwork_flutter/views/team/teamManage/team_manage_binding.dart';
|
||||||
@ -207,5 +217,30 @@ class AppPages {
|
|||||||
page: () => AddPersonView(),
|
page: () => AddPersonView(),
|
||||||
binding: AddPersonBinding(),
|
binding: AddPersonBinding(),
|
||||||
),
|
),
|
||||||
|
GetPage(
|
||||||
|
name: AppRoutes.teamRoleManage,
|
||||||
|
page: () => RoleManageView(),
|
||||||
|
binding: RoleManageBinding(),
|
||||||
|
),
|
||||||
|
GetPage(
|
||||||
|
name: AppRoutes.teamPersonnelManage,
|
||||||
|
page: () => PersonnelManageView(),
|
||||||
|
binding: PersonnelManageBinding(),
|
||||||
|
),
|
||||||
|
GetPage(
|
||||||
|
name: AppRoutes.teamSelectOrganization,
|
||||||
|
page: () => SelectOrganizationView(),
|
||||||
|
binding: SelectOrganizationBinding(),
|
||||||
|
),
|
||||||
|
GetPage(
|
||||||
|
name: AppRoutes.teamAddRole,
|
||||||
|
page: () => AddRoleView(),
|
||||||
|
binding: AddRoleBinding(),
|
||||||
|
),
|
||||||
|
GetPage(
|
||||||
|
name: AppRoutes.teamSelectRole,
|
||||||
|
page: () => SelectRoleView(),
|
||||||
|
binding: SelectRoleBinding(),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,11 @@ class AppRoutes{
|
|||||||
static const String teamInviteTeamMember = '/team/inviteTeamMember';
|
static const String teamInviteTeamMember = '/team/inviteTeamMember';
|
||||||
static const String teamInvitationSettings = '/team/invitationSettings';
|
static const String teamInvitationSettings = '/team/invitationSettings';
|
||||||
static const String teamAddPerson = '/team/addPerson';
|
static const String teamAddPerson = '/team/addPerson';
|
||||||
|
static const String teamRoleManage = '/team/roleManage';
|
||||||
|
static const String teamSelectOrganization = '/team/selectOrganization';
|
||||||
|
static const String teamPersonnelManage = '/team/personnelManage';
|
||||||
|
static const String teamAddRole = '/team/addRole';
|
||||||
|
static const String teamSelectRole = '/team/selectRole';
|
||||||
static const String deviceManage = '/device/deviceManage';
|
static const String deviceManage = '/device/deviceManage';
|
||||||
static const String searchDevice = '/device/searchDevice';
|
static const String searchDevice = '/device/searchDevice';
|
||||||
static const String confirmPairDevice = '/device/confirmPairDevice';
|
static const String confirmPairDevice = '/device/confirmPairDevice';
|
||||||
|
|||||||
@ -24,6 +24,9 @@ class HomeStatisticsRowWidget extends StatelessWidget {
|
|||||||
backgroundColor: const Color(0xFFCEF2F5),
|
backgroundColor: const Color(0xFFCEF2F5),
|
||||||
textColor: const Color(0xFF134347),
|
textColor: const Color(0xFF134347),
|
||||||
buttonText: '人员管理',
|
buttonText: '人员管理',
|
||||||
|
onTap: () {
|
||||||
|
Get.toNamed(AppRoutes.teamPersonnelManage);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
SizedBox(width: 8.w), // 卡片之间的间距
|
SizedBox(width: 8.w), // 卡片之间的间距
|
||||||
_buildStatisticsCard(
|
_buildStatisticsCard(
|
||||||
@ -33,6 +36,9 @@ class HomeStatisticsRowWidget extends StatelessWidget {
|
|||||||
backgroundColor: const Color(0xFFD4E0FF),
|
backgroundColor: const Color(0xFFD4E0FF),
|
||||||
textColor: const Color(0xFF172A5B),
|
textColor: const Color(0xFF172A5B),
|
||||||
buttonText: '设备管理',
|
buttonText: '设备管理',
|
||||||
|
onTap: () {
|
||||||
|
Get.toNamed(AppRoutes.deviceManage);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -45,13 +51,12 @@ class HomeStatisticsRowWidget extends StatelessWidget {
|
|||||||
required Color backgroundColor,
|
required Color backgroundColor,
|
||||||
required Color textColor,
|
required Color textColor,
|
||||||
required String buttonText,
|
required String buttonText,
|
||||||
|
required GestureTapCallback onTap,
|
||||||
}) {
|
}) {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
// 使用Expanded让卡片自适应宽度
|
// 使用Expanded让卡片自适应宽度
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: (){
|
onTap: onTap,
|
||||||
Get.toNamed(AppRoutes.deviceManage);
|
|
||||||
},
|
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 62.h,
|
height: 62.h,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
|
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
@ -11,12 +12,16 @@ import 'package:starcloud/sdk/starcloud.dart';
|
|||||||
import 'package:starwork_flutter/api/model/team/request/bind_team_star_cloud_account_request.dart';
|
import 'package:starwork_flutter/api/model/team/request/bind_team_star_cloud_account_request.dart';
|
||||||
import 'package:starwork_flutter/api/model/team/request/change_current_team_request.dart';
|
import 'package:starwork_flutter/api/model/team/request/change_current_team_request.dart';
|
||||||
import 'package:starwork_flutter/api/model/team/response/team_info_response.dart';
|
import 'package:starwork_flutter/api/model/team/response/team_info_response.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/user/response/user_info_response.dart';
|
||||||
import 'package:starwork_flutter/api/service/team_api_service.dart';
|
import 'package:starwork_flutter/api/service/team_api_service.dart';
|
||||||
|
import 'package:starwork_flutter/api/service/user_api_service.dart';
|
||||||
import 'package:starwork_flutter/base/app_logger.dart';
|
import 'package:starwork_flutter/base/app_logger.dart';
|
||||||
import 'package:starwork_flutter/base/base_controller.dart';
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
import 'package:starwork_flutter/common/constant/app_images.dart';
|
import 'package:starwork_flutter/common/constant/app_images.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/cache_keys.dart';
|
||||||
import 'package:starwork_flutter/common/events/refresh_device_list_event.dart';
|
import 'package:starwork_flutter/common/events/refresh_device_list_event.dart';
|
||||||
import 'package:starwork_flutter/common/utils/event_bus_util.dart';
|
import 'package:starwork_flutter/common/utils/event_bus_util.dart';
|
||||||
|
import 'package:starwork_flutter/common/utils/shared_preferences_utils.dart';
|
||||||
import 'package:starwork_flutter/routes/app_routes.dart';
|
import 'package:starwork_flutter/routes/app_routes.dart';
|
||||||
import 'package:starwork_flutter/views/home/home_controller.dart';
|
import 'package:starwork_flutter/views/home/home_controller.dart';
|
||||||
import 'package:starwork_flutter/views/home/home_view.dart';
|
import 'package:starwork_flutter/views/home/home_view.dart';
|
||||||
@ -25,6 +30,7 @@ import 'package:starwork_flutter/views/mine/mine_view.dart';
|
|||||||
|
|
||||||
class MainController extends BaseController {
|
class MainController extends BaseController {
|
||||||
final teamApi = Get.find<TeamApiService>();
|
final teamApi = Get.find<TeamApiService>();
|
||||||
|
final userApi = Get.find<UserApiService>();
|
||||||
|
|
||||||
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
@ -62,6 +68,9 @@ class MainController extends BaseController {
|
|||||||
|
|
||||||
/// 请求设备列表
|
/// 请求设备列表
|
||||||
_requestTeamDeviceList();
|
_requestTeamDeviceList();
|
||||||
|
|
||||||
|
/// 请求账户信息
|
||||||
|
requestUserAccountInfo();
|
||||||
// 监听刷新设备列表事件
|
// 监听刷新设备列表事件
|
||||||
_refreshDeviceListSubscription = EventBusUtil().instance.on<RefreshDeviceListEvent>().listen((event) {
|
_refreshDeviceListSubscription = EventBusUtil().instance.on<RefreshDeviceListEvent>().listen((event) {
|
||||||
_requestTeamDeviceList();
|
_requestTeamDeviceList();
|
||||||
@ -232,4 +241,23 @@ class MainController extends BaseController {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void requestUserAccountInfo() async {
|
||||||
|
var userInfo = await userApi.requestUserInfo();
|
||||||
|
if (userInfo.isSuccess) {
|
||||||
|
// 保存到缓存
|
||||||
|
// 方式1: 直接存储 JSON 字符串(推荐)
|
||||||
|
await SharedPreferencesUtils.setString(CacheKeys.userAccountInfo, jsonEncode(userInfo.data!.toJson()));
|
||||||
|
// 从缓存中读取
|
||||||
|
// String? cachedJson = await SharedPreferencesUtils.getString(CacheKeys.userAccountInfo);
|
||||||
|
// if (cachedJson != null) {
|
||||||
|
// try {
|
||||||
|
// Map<String, dynamic> jsonMap = jsonDecode(cachedJson);
|
||||||
|
// UserInfoResponse userInfoResponse = UserInfoResponse.fromJson(jsonMap);
|
||||||
|
// } catch (e) {
|
||||||
|
// AppLogger.error('JSON 解析错误: $e');
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,44 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get/get_rx/get_rx.dart';
|
import 'package:get/get_rx/get_rx.dart';
|
||||||
import 'package:get/get_rx/src/rx_types/rx_types.dart';
|
import 'package:get/get_rx/src/rx_types/rx_types.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/depart_list_reponse.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/role_list_response.dart';
|
||||||
import 'package:starwork_flutter/base/base_controller.dart';
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/app_view_parameter_keys.dart';
|
||||||
|
|
||||||
class AddPersonController extends BaseController {
|
class AddPersonController extends BaseController {
|
||||||
RxString selectedGender = 'male'.obs;
|
RxString selectedGender = 'male'.obs;
|
||||||
|
|
||||||
|
var selectedDepartItem = DepartItem().obs; // 当前选中的组织
|
||||||
|
|
||||||
|
TextEditingController nameInputController = TextEditingController();
|
||||||
|
TextEditingController jobNoInputController = TextEditingController(); // 工号
|
||||||
|
TextEditingController postInputController = TextEditingController(); // 职务
|
||||||
|
TextEditingController idCardInputController = TextEditingController(); // 身份证号码
|
||||||
|
var isOpeningAccount = false.obs; // 是否开通账户
|
||||||
|
var selectedRoles = <RoleListResponse>[].obs;
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
super.onReady();
|
||||||
|
// 读取参数
|
||||||
|
final args = Get.arguments;
|
||||||
|
if (args != null && args.containsKey(AppViewParameterKeys.departItem)) {
|
||||||
|
final json = args[AppViewParameterKeys.departItem];
|
||||||
|
selectedDepartItem.value = DepartItem.fromJson(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取选中角色的显示文本
|
||||||
|
String getSelectedRoleDisplayText() {
|
||||||
|
if (selectedRoles.isEmpty) {
|
||||||
|
return '请选择'; // 如果没有选中角色,显示"请选择"
|
||||||
|
} else {
|
||||||
|
// 将所有选中角色的名称用逗号连接
|
||||||
|
return selectedRoles
|
||||||
|
.map((role) => role.roleName ?? '')
|
||||||
|
.join('、'); // 使用顿号或逗号分隔
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,460 +2,501 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/depart_list_reponse.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/role_list_response.dart';
|
||||||
|
import 'package:starwork_flutter/base/app_logger.dart';
|
||||||
import 'package:starwork_flutter/common/constant/app_colors.dart';
|
import 'package:starwork_flutter/common/constant/app_colors.dart';
|
||||||
import 'package:starwork_flutter/common/widgets/custom_cell_list_widget.dart';
|
import 'package:starwork_flutter/common/widgets/custom_cell_list_widget.dart';
|
||||||
import 'package:starwork_flutter/common/widgets/custom_cell_widget.dart';
|
import 'package:starwork_flutter/common/widgets/custom_cell_widget.dart';
|
||||||
import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart';
|
import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart';
|
||||||
import 'package:starwork_flutter/extension/function_extension.dart';
|
import 'package:starwork_flutter/extension/function_extension.dart';
|
||||||
|
import 'package:starwork_flutter/routes/app_routes.dart';
|
||||||
import 'add_person_controller.dart';
|
import 'add_person_controller.dart';
|
||||||
|
|
||||||
class AddPersonView extends GetView<AddPersonController> {
|
class AddPersonView extends GetView<AddPersonController> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return GestureDetector(
|
||||||
backgroundColor: AppColors.scaffoldBackgroundColor,
|
onTap: () {
|
||||||
appBar: CustomAppBarWidget(
|
FocusScope.of(context).requestFocus(FocusNode());
|
||||||
title: '添加人员'.tr,
|
},
|
||||||
|
child: Scaffold(
|
||||||
backgroundColor: AppColors.scaffoldBackgroundColor,
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
),
|
appBar: CustomAppBarWidget(
|
||||||
body: SafeArea(
|
title: '添加人员'.tr,
|
||||||
child: SingleChildScrollView(
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
child: Padding(
|
),
|
||||||
padding: EdgeInsets.only(
|
body: SafeArea(
|
||||||
left: 10.w,
|
child: SingleChildScrollView(
|
||||||
right: 10.w,
|
child: Padding(
|
||||||
bottom: 10.h,
|
padding: EdgeInsets.only(
|
||||||
),
|
left: 10.w,
|
||||||
child: Column(
|
right: 10.w,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
bottom: 10.h,
|
||||||
children: [
|
),
|
||||||
Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Column(
|
||||||
'基本信息'.tr,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
style: TextStyle(
|
children: [
|
||||||
fontSize: 12.sp,
|
Text(
|
||||||
color: Colors.black54,
|
'基本信息'.tr,
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 6.h,
|
|
||||||
),
|
|
||||||
CustomCellListWidget(
|
|
||||||
children: [
|
|
||||||
CustomCellWidget(
|
|
||||||
onTap: () {},
|
|
||||||
leftText: '组织'.tr,
|
|
||||||
leftIcon: Icon(
|
|
||||||
Icons.circle,
|
|
||||||
size: 4.w,
|
|
||||||
color: Colors.red,
|
|
||||||
),
|
|
||||||
rightWidget: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'请选择',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
color: Colors.black54,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 4.w,
|
|
||||||
),
|
|
||||||
Icon(
|
|
||||||
Icons.arrow_forward_ios_rounded,
|
|
||||||
size: 16.sp,
|
|
||||||
color: Colors.grey[300],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
CustomCellWidget(
|
|
||||||
onTap: () {},
|
|
||||||
leftText: '姓名'.tr,
|
|
||||||
leftIcon: Icon(
|
|
||||||
Icons.circle,
|
|
||||||
size: 4.w,
|
|
||||||
color: Colors.red,
|
|
||||||
),
|
|
||||||
rightWidget: Expanded(
|
|
||||||
flex: 3,
|
|
||||||
child: TextField(
|
|
||||||
keyboardType: TextInputType.text,
|
|
||||||
textInputAction: TextInputAction.next,
|
|
||||||
textAlign: TextAlign.end,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
isCollapsed: true,
|
|
||||||
hintText: '请输入姓名'.tr,
|
|
||||||
hintStyle: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
color: Colors.black54,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
// 设置无边框
|
|
||||||
border: InputBorder.none,
|
|
||||||
contentPadding: EdgeInsets.zero,
|
|
||||||
// 获取焦点时的边框
|
|
||||||
focusedBorder: InputBorder.none,
|
|
||||||
enabledBorder: InputBorder.none,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
CustomCellWidget(
|
|
||||||
onTap: () {},
|
|
||||||
leftText: '开通账号'.tr,
|
|
||||||
leftSubText: '可登录并使用应用或管理功能',
|
|
||||||
leftIcon: Icon(
|
|
||||||
Icons.circle,
|
|
||||||
size: 4.w,
|
|
||||||
color: Colors.red,
|
|
||||||
),
|
|
||||||
rightWidget: CupertinoSwitch(
|
|
||||||
value: false,
|
|
||||||
onChanged: (bool value) {},
|
|
||||||
activeColor: Colors.blue, // 可选:打开时的颜色(iOS 默认为系统蓝色,可自定义)
|
|
||||||
trackColor: Colors.grey, // 可选:关闭时的背景轨道颜色
|
|
||||||
),
|
|
||||||
),
|
|
||||||
CustomCellWidget(
|
|
||||||
onTap: () {},
|
|
||||||
leftText: '分配权限'.tr,
|
|
||||||
leftIcon: Icon(
|
|
||||||
Icons.circle,
|
|
||||||
size: 4.w,
|
|
||||||
color: Colors.red,
|
|
||||||
),
|
|
||||||
rightWidget: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'企业员工',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
color: Colors.black54,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 4.w,
|
|
||||||
),
|
|
||||||
Icon(
|
|
||||||
Icons.arrow_forward_ios_rounded,
|
|
||||||
size: 16.sp,
|
|
||||||
color: Colors.grey[300],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 10.h,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'扩展信息'.tr,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12.sp,
|
|
||||||
color: Colors.black54,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 10.h,
|
|
||||||
),
|
|
||||||
CustomCellListWidget(
|
|
||||||
children: [
|
|
||||||
CustomCellWidget(
|
|
||||||
onTap: () {},
|
|
||||||
leftText: '工号'.tr,
|
|
||||||
rightWidget: Expanded(
|
|
||||||
flex: 3,
|
|
||||||
child: TextField(
|
|
||||||
keyboardType: TextInputType.text,
|
|
||||||
textInputAction: TextInputAction.next,
|
|
||||||
textAlign: TextAlign.end,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
isCollapsed: true,
|
|
||||||
hintText: '选填'.tr,
|
|
||||||
hintStyle: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
color: Colors.black54,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
// 设置无边框
|
|
||||||
border: InputBorder.none,
|
|
||||||
contentPadding: EdgeInsets.zero,
|
|
||||||
// 获取焦点时的边框
|
|
||||||
focusedBorder: InputBorder.none,
|
|
||||||
enabledBorder: InputBorder.none,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
CustomCellWidget(
|
|
||||||
onTap: () {},
|
|
||||||
leftText: '性别'.tr,
|
|
||||||
rightWidget: Obx(
|
|
||||||
() => Row(
|
|
||||||
children: [
|
|
||||||
Radio<String>(
|
|
||||||
value: 'male',
|
|
||||||
activeColor: Colors.blue,
|
|
||||||
groupValue: controller.selectedGender.value,
|
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
onChanged: (value) {
|
|
||||||
controller.selectedGender.value = value!;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Text('男'),
|
|
||||||
Radio<String>(
|
|
||||||
value: 'female',
|
|
||||||
activeColor: Colors.blue,
|
|
||||||
groupValue: controller.selectedGender.value,
|
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
onChanged: (value) {
|
|
||||||
controller.selectedGender.value = value!;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Text('女'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
CustomCellWidget(
|
|
||||||
onTap: () {},
|
|
||||||
leftText: '有效期'.tr,
|
|
||||||
rightWidget: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'请选择',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
color: Colors.black54,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 4.w,
|
|
||||||
),
|
|
||||||
Icon(
|
|
||||||
Icons.arrow_forward_ios_rounded,
|
|
||||||
size: 16.sp,
|
|
||||||
color: Colors.grey[300],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
CustomCellWidget(
|
|
||||||
onTap: () {},
|
|
||||||
leftText: '职务'.tr,
|
|
||||||
rightWidget: Expanded(
|
|
||||||
flex: 3,
|
|
||||||
child: TextField(
|
|
||||||
keyboardType: TextInputType.text,
|
|
||||||
textInputAction: TextInputAction.next,
|
|
||||||
textAlign: TextAlign.end,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
isCollapsed: true,
|
|
||||||
hintText: '选填'.tr,
|
|
||||||
hintStyle: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
color: Colors.black54,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
// 设置无边框
|
|
||||||
border: InputBorder.none,
|
|
||||||
contentPadding: EdgeInsets.zero,
|
|
||||||
// 获取焦点时的边框
|
|
||||||
focusedBorder: InputBorder.none,
|
|
||||||
enabledBorder: InputBorder.none,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
CustomCellWidget(
|
|
||||||
onTap: () {},
|
|
||||||
leftText: '备注'.tr,
|
|
||||||
rightWidget: Expanded(
|
|
||||||
flex: 3,
|
|
||||||
child: TextField(
|
|
||||||
keyboardType: TextInputType.text,
|
|
||||||
textInputAction: TextInputAction.next,
|
|
||||||
textAlign: TextAlign.end,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
isCollapsed: true,
|
|
||||||
hintText: '选填'.tr,
|
|
||||||
hintStyle: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
color: Colors.black54,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
// 设置无边框
|
|
||||||
border: InputBorder.none,
|
|
||||||
contentPadding: EdgeInsets.zero,
|
|
||||||
// 获取焦点时的边框
|
|
||||||
focusedBorder: InputBorder.none,
|
|
||||||
enabledBorder: InputBorder.none,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
CustomCellWidget(
|
|
||||||
onTap: () {},
|
|
||||||
leftText: '身份证号码'.tr,
|
|
||||||
rightWidget: Expanded(
|
|
||||||
flex: 3,
|
|
||||||
child: TextField(
|
|
||||||
keyboardType: TextInputType.text,
|
|
||||||
textInputAction: TextInputAction.next,
|
|
||||||
textAlign: TextAlign.end,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
isCollapsed: true,
|
|
||||||
hintText: '选填'.tr,
|
|
||||||
hintStyle: TextStyle(
|
|
||||||
fontSize: 14.sp,
|
|
||||||
color: Colors.black54,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
// 设置无边框
|
|
||||||
border: InputBorder.none,
|
|
||||||
contentPadding: EdgeInsets.zero,
|
|
||||||
// 获取焦点时的边框
|
|
||||||
focusedBorder: InputBorder.none,
|
|
||||||
enabledBorder: InputBorder.none,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 10.h,
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: double.infinity,
|
|
||||||
child: Text(
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
'温馨提示:人脸/指纹/卡片信息需先保存后录入',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12.sp,
|
fontSize: 12.sp,
|
||||||
color: Colors.grey,
|
color: Colors.black54,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(
|
||||||
SizedBox(
|
height: 6.h,
|
||||||
height: 10.h,
|
),
|
||||||
),
|
CustomCellListWidget(
|
||||||
CustomCellListWidget(
|
|
||||||
children: [
|
|
||||||
CustomCellWidget(
|
|
||||||
onTap: () {
|
|
||||||
controller.showFunctionNotOpen();
|
|
||||||
},
|
|
||||||
leftText: '其他添加方式'.tr,
|
|
||||||
rightWidget: Icon(
|
|
||||||
Icons.arrow_forward_ios_rounded,
|
|
||||||
size: 16.sp,
|
|
||||||
color: Colors.grey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Checkbox(
|
|
||||||
value: true,
|
|
||||||
// 转换为 bool
|
|
||||||
onChanged: (bool? value) {},
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'向用户发送短信邀请通知',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12.sp,
|
|
||||||
color: Colors.grey,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: double.infinity,
|
|
||||||
child: Row(
|
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
CustomCellWidget(
|
||||||
child: ElevatedButton(
|
onTap: () async {
|
||||||
onPressed: () {}.debounce(),
|
final result = await Get.toNamed(AppRoutes.teamSelectOrganization);
|
||||||
style: ElevatedButton.styleFrom(
|
if (result != null) {
|
||||||
backgroundColor: Colors.grey[100],
|
AppLogger.highlight('result:${result}');
|
||||||
padding: EdgeInsets.symmetric(vertical: 12.h),
|
if (result is DepartItem) {
|
||||||
shape: RoundedRectangleBorder(
|
controller.selectedDepartItem.value = result;
|
||||||
borderRadius: BorderRadius.circular(8.r),
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
leftText: '组织'.tr,
|
||||||
|
leftIcon: Icon(
|
||||||
|
Icons.circle,
|
||||||
|
size: 4.w,
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
|
rightWidget: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Obx(
|
||||||
|
() => Text(
|
||||||
|
controller.selectedDepartItem.value.departName ?? '请选择',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.black54,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(
|
||||||
child: Text(
|
width: 4.w,
|
||||||
'保存'.tr,
|
),
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_ios_rounded,
|
||||||
|
size: 16.sp,
|
||||||
|
color: Colors.grey[300],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CustomCellWidget(
|
||||||
|
onTap: () {},
|
||||||
|
leftText: '姓名'.tr,
|
||||||
|
leftIcon: Icon(
|
||||||
|
Icons.circle,
|
||||||
|
size: 4.w,
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
|
rightWidget: Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: TextField(
|
||||||
|
controller: controller.nameInputController,
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
textAlign: TextAlign.end,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16.sp,
|
fontSize: 14.sp,
|
||||||
color: Colors.blue,
|
),
|
||||||
fontWeight: FontWeight.w500,
|
decoration: InputDecoration(
|
||||||
|
isCollapsed: true,
|
||||||
|
hintText: '请输入姓名'.tr,
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.black54,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
// 设置无边框
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
// 获取焦点时的边框
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
CustomCellWidget(
|
||||||
width: 10.w,
|
onTap: () {},
|
||||||
|
leftText: '开通账号'.tr,
|
||||||
|
leftSubText: '可登录并使用应用或管理功能',
|
||||||
|
leftIcon: Icon(
|
||||||
|
Icons.circle,
|
||||||
|
size: 4.w,
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
|
rightWidget: CupertinoSwitch(
|
||||||
|
value: true,
|
||||||
|
onChanged: (bool value) {},
|
||||||
|
activeColor: Colors.blue, // 可选:打开时的颜色(iOS 默认为系统蓝色,可自定义)
|
||||||
|
trackColor: Colors.grey, // 可选:关闭时的背景轨道颜色
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
CustomCellWidget(
|
||||||
child: ElevatedButton(
|
onTap: () async {
|
||||||
onPressed: () {}.debounce(),
|
var result =
|
||||||
style: ElevatedButton.styleFrom(
|
await Get.toNamed(AppRoutes.teamSelectRole, arguments: controller.selectedRoles);
|
||||||
backgroundColor: Colors.blue,
|
if (result != null) {
|
||||||
padding: EdgeInsets.symmetric(vertical: 12.h),
|
// 处理返回的角色数据
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.r)),
|
if (result is List<RoleListResponse>) {
|
||||||
|
controller.selectedRoles.value = result;
|
||||||
|
controller.selectedRoles.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
leftText: '分配权限'.tr,
|
||||||
|
leftIcon: Icon(
|
||||||
|
Icons.circle,
|
||||||
|
size: 4.w,
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
|
rightWidget: Container(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
maxWidth: 200.w,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Row(
|
||||||
'保存并继续添加'.tr,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Obx(
|
||||||
|
() => Expanded(
|
||||||
|
child: Text(
|
||||||
|
controller.getSelectedRoleDisplayText(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.black54,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 4.w,
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_ios_rounded,
|
||||||
|
size: 16.sp,
|
||||||
|
color: Colors.grey[300],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'扩展信息'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Colors.black54,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
CustomCellListWidget(
|
||||||
|
children: [
|
||||||
|
CustomCellWidget(
|
||||||
|
onTap: () {},
|
||||||
|
leftText: '工号'.tr,
|
||||||
|
rightWidget: Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: TextField(
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
textAlign: TextAlign.end,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16.sp,
|
fontSize: 14.sp,
|
||||||
color: Colors.white,
|
),
|
||||||
fontWeight: FontWeight.w500,
|
decoration: InputDecoration(
|
||||||
|
isCollapsed: true,
|
||||||
|
hintText: '选填'.tr,
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.black54,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
// 设置无边框
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
// 获取焦点时的边框
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CustomCellWidget(
|
||||||
|
onTap: () {},
|
||||||
|
leftText: '性别'.tr,
|
||||||
|
rightWidget: Obx(
|
||||||
|
() => Row(
|
||||||
|
children: [
|
||||||
|
Radio<String>(
|
||||||
|
value: 'male',
|
||||||
|
activeColor: Colors.blue,
|
||||||
|
groupValue: controller.selectedGender.value,
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
onChanged: (value) {
|
||||||
|
controller.selectedGender.value = value!;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Text('男'),
|
||||||
|
Radio<String>(
|
||||||
|
value: 'female',
|
||||||
|
activeColor: Colors.blue,
|
||||||
|
groupValue: controller.selectedGender.value,
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
onChanged: (value) {
|
||||||
|
controller.selectedGender.value = value!;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Text('女'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CustomCellWidget(
|
||||||
|
onTap: () {},
|
||||||
|
leftText: '有效期'.tr,
|
||||||
|
rightWidget: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'请选择',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.black54,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 4.w,
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_ios_rounded,
|
||||||
|
size: 16.sp,
|
||||||
|
color: Colors.grey[300],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CustomCellWidget(
|
||||||
|
onTap: () {},
|
||||||
|
leftText: '职务'.tr,
|
||||||
|
rightWidget: Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: TextField(
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
textAlign: TextAlign.end,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isCollapsed: true,
|
||||||
|
hintText: '选填'.tr,
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.black54,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
// 设置无边框
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
// 获取焦点时的边框
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CustomCellWidget(
|
||||||
|
onTap: () {},
|
||||||
|
leftText: '备注'.tr,
|
||||||
|
rightWidget: Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: TextField(
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
textAlign: TextAlign.end,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isCollapsed: true,
|
||||||
|
hintText: '选填'.tr,
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.black54,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
// 设置无边框
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
// 获取焦点时的边框
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CustomCellWidget(
|
||||||
|
onTap: () {},
|
||||||
|
leftText: '身份证号码'.tr,
|
||||||
|
rightWidget: Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: TextField(
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
textAlign: TextAlign.end,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isCollapsed: true,
|
||||||
|
hintText: '选填'.tr,
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.black54,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
// 设置无边框
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
// 获取焦点时的边框
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
SizedBox(
|
||||||
],
|
height: 10.h,
|
||||||
)
|
),
|
||||||
],
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: Text(
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
'温馨提示:人脸/指纹/卡片信息需先保存后录入',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Colors.grey,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
CustomCellListWidget(
|
||||||
|
children: [
|
||||||
|
CustomCellWidget(
|
||||||
|
onTap: () {
|
||||||
|
controller.showFunctionNotOpen();
|
||||||
|
},
|
||||||
|
leftText: '其他添加方式'.tr,
|
||||||
|
rightWidget: Icon(
|
||||||
|
Icons.arrow_forward_ios_rounded,
|
||||||
|
size: 16.sp,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Checkbox(
|
||||||
|
value: true,
|
||||||
|
// 转换为 bool
|
||||||
|
onChanged: (bool? value) {},
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'向用户发送短信邀请通知',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Colors.grey,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {}.debounce(),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.grey[100],
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 12.h),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'保存'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.blue,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10.w,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {}.debounce(),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 12.h),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.r)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'保存并继续添加'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
10
lib/views/team/addPerson/selectRole/select_role_binding.dart
Normal file
10
lib/views/team/addPerson/selectRole/select_role_binding.dart
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'select_role_controller.dart';
|
||||||
|
|
||||||
|
class SelectRoleBinding extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut(() => SelectRoleController());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/role_list_response.dart';
|
||||||
|
import 'package:starwork_flutter/api/service/team_api_service.dart';
|
||||||
|
import 'package:starwork_flutter/base/app_logger.dart';
|
||||||
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
|
|
||||||
|
class SelectRoleController extends BaseController {
|
||||||
|
final teamApi = Get.find<TeamApiService>();
|
||||||
|
var roleList = <RoleListResponse>[].obs;
|
||||||
|
|
||||||
|
var selectRoleIndexList = <int>[].obs;
|
||||||
|
|
||||||
|
// 存储从参数传递过来的已选角色
|
||||||
|
List<RoleListResponse>? initialSelectedRoles;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
super.onInit();
|
||||||
|
// 获取传递的参数
|
||||||
|
var arguments = Get.arguments;
|
||||||
|
if (arguments != null && arguments is List<RoleListResponse>) {
|
||||||
|
initialSelectedRoles = arguments;
|
||||||
|
}
|
||||||
|
requestRoleList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
super.onReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
void requestRoleList() async {
|
||||||
|
var response = await teamApi.requestTeamRoleList();
|
||||||
|
if (response.isSuccess) {
|
||||||
|
roleList.value = response.data ?? [];
|
||||||
|
roleList.refresh();
|
||||||
|
_setInitialSelectedIndexes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据初始选中的角色设置对应的索引
|
||||||
|
void _setInitialSelectedIndexes() {
|
||||||
|
if (initialSelectedRoles != null && initialSelectedRoles!.isNotEmpty) {
|
||||||
|
for (var selectedRole in initialSelectedRoles!) {
|
||||||
|
// 在角色列表中查找对应的角色并设置选中状态
|
||||||
|
for (int i = 0; i < roleList.length; i++) {
|
||||||
|
if (roleList[i].id == selectedRole.id) {
|
||||||
|
if (!selectRoleIndexList.contains(i)) {
|
||||||
|
selectRoleIndexList.add(i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selectRoleIndexList.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
236
lib/views/team/addPerson/selectRole/select_role_view.dart
Normal file
236
lib/views/team/addPerson/selectRole/select_role_view.dart
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/role_list_response.dart';
|
||||||
|
import 'package:starwork_flutter/base/app_logger.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/app_colors.dart';
|
||||||
|
import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart';
|
||||||
|
import 'package:starwork_flutter/extension/function_extension.dart';
|
||||||
|
import 'package:starwork_flutter/routes/app_routes.dart';
|
||||||
|
import 'select_role_controller.dart';
|
||||||
|
|
||||||
|
class SelectRoleView extends GetView<SelectRoleController> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: CustomAppBarWidget(
|
||||||
|
title: '按照角色分配权限'.tr,
|
||||||
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
),
|
||||||
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
body: SafeArea(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
var result = await Get.toNamed(AppRoutes.teamAddRole);
|
||||||
|
if (result != null && result == true) {
|
||||||
|
controller.requestRoleList();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'新建角色并分配'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'按新角色的权限分配'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_ios_rounded,
|
||||||
|
size: 20.w,
|
||||||
|
color: Colors.grey,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'按以下已有角色的权限分配'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Obx(
|
||||||
|
() => Flexible(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
child: ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
RoleListResponse roleList = controller.roleList[index];
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
// 避免重复添加
|
||||||
|
if (!controller.selectRoleIndexList.contains(index)) {
|
||||||
|
controller.selectRoleIndexList.add(index);
|
||||||
|
} else {
|
||||||
|
controller.selectRoleIndexList.remove(index);
|
||||||
|
}
|
||||||
|
controller.selectRoleIndexList.refresh();
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: 10.h,
|
||||||
|
horizontal: 10.w,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Obx(
|
||||||
|
() => Checkbox(
|
||||||
|
value: controller.selectRoleIndexList.contains(index),
|
||||||
|
activeColor: Colors.blue,
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value == true) {
|
||||||
|
// 避免重复添加
|
||||||
|
if (!controller.selectRoleIndexList.contains(index)) {
|
||||||
|
controller.selectRoleIndexList.add(index);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
controller.selectRoleIndexList.remove(index);
|
||||||
|
}
|
||||||
|
controller.selectRoleIndexList.refresh();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.blue[50],
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
width: 36.w,
|
||||||
|
height: 36.w,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.group_rounded,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10.w,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
roleList.roleName ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
roleList.roleDesc ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
maxLines: 3,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
),
|
||||||
|
child: Divider(
|
||||||
|
height: 0.5.h,
|
||||||
|
thickness: 0.5.h,
|
||||||
|
color: Colors.grey[100],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: controller.roleList.length,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Obx(
|
||||||
|
() => Text(
|
||||||
|
'已选中:${controller.selectRoleIndexList.length}个',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Get.back(
|
||||||
|
result: controller.selectRoleIndexList.map((e) => controller.roleList[e]).toList(),
|
||||||
|
);
|
||||||
|
}.debounce(),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'确认'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
lib/views/team/addRole/add_role_binding.dart
Normal file
10
lib/views/team/addRole/add_role_binding.dart
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'add_role_controller.dart';
|
||||||
|
|
||||||
|
class AddRoleBinding extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut(() => AddRoleController());
|
||||||
|
}
|
||||||
|
}
|
||||||
27
lib/views/team/addRole/add_role_controller.dart
Normal file
27
lib/views/team/addRole/add_role_controller.dart
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/request/create_new_role_request.dart';
|
||||||
|
import 'package:starwork_flutter/api/service/team_api_service.dart';
|
||||||
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
|
|
||||||
|
class AddRoleController extends BaseController {
|
||||||
|
final teamApi = Get.find<TeamApiService>();
|
||||||
|
|
||||||
|
TextEditingController roleNameInputController = TextEditingController();
|
||||||
|
TextEditingController roleDescribeInputController = TextEditingController();
|
||||||
|
|
||||||
|
void createTeamRole() async {
|
||||||
|
var response = await teamApi.requestCreateTeamRole(
|
||||||
|
request: CreateNewRoleRequest(
|
||||||
|
roleName: roleNameInputController.text.trim(),
|
||||||
|
roleDesc: roleDescribeInputController.text.trim(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (response.isSuccess) {
|
||||||
|
showSuccess(message: '创建成功');
|
||||||
|
Get.back(result: true);
|
||||||
|
} else {
|
||||||
|
showError(message: response.errorMsg!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
157
lib/views/team/addRole/add_role_view.dart
Normal file
157
lib/views/team/addRole/add_role_view.dart
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/app_colors.dart';
|
||||||
|
import 'package:starwork_flutter/common/widgets/custom_cell_list_widget.dart';
|
||||||
|
import 'package:starwork_flutter/common/widgets/custom_cell_widget.dart';
|
||||||
|
import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart';
|
||||||
|
import 'package:starwork_flutter/extension/function_extension.dart';
|
||||||
|
import 'add_role_controller.dart';
|
||||||
|
|
||||||
|
class AddRoleView extends GetView<AddRoleController> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// 即使不使用,只是引用一下 controller 就能触发初始化
|
||||||
|
final _ = controller; // 添加这一行
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
FocusScope.of(context).requestFocus(FocusNode());
|
||||||
|
},
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: CustomAppBarWidget(
|
||||||
|
title: '新建角色'.tr,
|
||||||
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
),
|
||||||
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
body: SafeArea(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
vertical: 10.h,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
CustomCellListWidget(
|
||||||
|
children: [
|
||||||
|
CustomCellWidget(
|
||||||
|
onTap: () {},
|
||||||
|
leftText: '角色名称'.tr,
|
||||||
|
leftIcon: Icon(
|
||||||
|
Icons.circle,
|
||||||
|
size: 4.w,
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
|
rightWidget: Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: TextField(
|
||||||
|
controller: controller.roleNameInputController,
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
textAlign: TextAlign.end,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isCollapsed: true,
|
||||||
|
hintText: '请输入角色名称'.tr,
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.black54,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
// 设置无边框
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
// 获取焦点时的边框
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
CustomCellListWidget(
|
||||||
|
children: [
|
||||||
|
CustomCellWidget(
|
||||||
|
onTap: () {},
|
||||||
|
leftText: '角色描述'.tr,
|
||||||
|
leftIcon: Icon(
|
||||||
|
Icons.circle,
|
||||||
|
size: 4.w,
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
|
rightWidget: Expanded(
|
||||||
|
flex: 3,
|
||||||
|
child: TextField(
|
||||||
|
controller: controller.roleDescribeInputController,
|
||||||
|
keyboardType: TextInputType.text,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
textAlign: TextAlign.end,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isCollapsed: true,
|
||||||
|
hintText: '请输入角色描述'.tr,
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.black54,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
// 设置无边框
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
// 获取焦点时的边框
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Spacer(),
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (controller.roleNameInputController.text.isEmpty) {
|
||||||
|
controller.showToast('请先输入角色名称');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (controller.roleDescribeInputController.text.isEmpty) {
|
||||||
|
controller.showToast('请先输入角色描述');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
controller.createTeamRole();
|
||||||
|
}.debounce(),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 12.h),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.r)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'保存'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,6 +25,8 @@ class CreateTeamController extends BaseController {
|
|||||||
requestAllSceneInfoList();
|
requestAllSceneInfoList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// 请求团队使用场景信息
|
/// 请求团队使用场景信息
|
||||||
void requestAllSceneInfoList() async {
|
void requestAllSceneInfoList() async {
|
||||||
showLoading();
|
showLoading();
|
||||||
|
|||||||
@ -1,6 +1,40 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/request/update_invite_parameter_config_request.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/team_invite_parameter_config_response.dart';
|
||||||
|
import 'package:starwork_flutter/api/service/team_api_service.dart';
|
||||||
import 'package:starwork_flutter/base/base_controller.dart';
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
|
import 'package:starwork_flutter/views/main/main_controller.dart';
|
||||||
|
|
||||||
class InvitationSettingsController extends BaseController {
|
class InvitationSettingsController extends BaseController {
|
||||||
// TODO: 在这里添加业务逻辑
|
final teamApi = Get.find<TeamApiService>();
|
||||||
}
|
final mainController = Get.find<MainController>();
|
||||||
|
var inviteConfig = TeamInviteParameterConfigResponse().obs;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
super.onReady();
|
||||||
|
requestInvitationSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
requestInvitationSettings() async {
|
||||||
|
var response = await teamApi.requestInviteParameterConfig();
|
||||||
|
if (response.isSuccess) {
|
||||||
|
inviteConfig.value = response.data!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requestUpdateInvitationSettings() async {
|
||||||
|
var response = await teamApi.requestUpdateInviteParameterConfig(
|
||||||
|
request: UpdateInviteParameterConfigRequest(
|
||||||
|
joinTeamInputFace: inviteConfig.value.joinTeamInputFace!,
|
||||||
|
applyJoinTeamAudit: inviteConfig.value.applyJoinTeamAudit!,
|
||||||
|
teamInviteUserValidFalse: inviteConfig.value.teamInviteUserValidFalse!,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (response.isSuccess) {
|
||||||
|
inviteConfig.refresh();
|
||||||
|
} else {
|
||||||
|
showError(message: response.errorMsg!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -11,6 +11,9 @@ import 'invitation_settings_controller.dart';
|
|||||||
class InvitationSettingsView extends GetView<InvitationSettingsController> {
|
class InvitationSettingsView extends GetView<InvitationSettingsController> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
// 即使不使用,只是引用一下 controller 就能触发初始化
|
||||||
|
final _ = controller; // 添加这一行
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColors.scaffoldBackgroundColor,
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
appBar: CustomAppBarWidget(
|
appBar: CustomAppBarWidget(
|
||||||
@ -31,31 +34,58 @@ class InvitationSettingsView extends GetView<InvitationSettingsController> {
|
|||||||
onTap: () {},
|
onTap: () {},
|
||||||
leftText: '人员配置'.tr,
|
leftText: '人员配置'.tr,
|
||||||
leftSubText: '关闭审核后,新申请的用户无需审核即可加入成功',
|
leftSubText: '关闭审核后,新申请的用户无需审核即可加入成功',
|
||||||
rightWidget: CupertinoSwitch(
|
rightWidget: Obx(
|
||||||
value: false,
|
() => CupertinoSwitch(
|
||||||
onChanged: (bool value) {},
|
value: controller.inviteConfig.value.applyJoinTeamAudit == 1,
|
||||||
activeColor: Colors.blue, // 可选:打开时的颜色(iOS 默认为系统蓝色,可自定义)
|
onChanged: (bool value) {
|
||||||
trackColor: Colors.grey, // 可选:关闭时的背景轨道颜色
|
if (value) {
|
||||||
|
controller.inviteConfig.value.applyJoinTeamAudit = 1;
|
||||||
|
} else {
|
||||||
|
controller.inviteConfig.value.applyJoinTeamAudit = 2;
|
||||||
|
}
|
||||||
|
controller.requestUpdateInvitationSettings();
|
||||||
|
},
|
||||||
|
activeColor: Colors.blue,
|
||||||
|
trackColor: Colors.grey,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CustomCellWidget(
|
CustomCellWidget(
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
leftText: '申请加入时可录入人脸'.tr,
|
leftText: '申请加入时可录入人脸'.tr,
|
||||||
rightWidget: CupertinoSwitch(
|
rightWidget: Obx(
|
||||||
value: false,
|
() => CupertinoSwitch(
|
||||||
onChanged: (bool value) {},
|
value: controller.inviteConfig.value.joinTeamInputFace == 1,
|
||||||
activeColor: Colors.blue, // 可选:打开时的颜色(iOS 默认为系统蓝色,可自定义)
|
onChanged: (bool value) {
|
||||||
trackColor: Colors.grey, // 可选:关闭时的背景轨道颜色
|
if (value) {
|
||||||
|
controller.inviteConfig.value.joinTeamInputFace = 1;
|
||||||
|
} else {
|
||||||
|
controller.inviteConfig.value.joinTeamInputFace = 2;
|
||||||
|
}
|
||||||
|
controller.requestUpdateInvitationSettings();
|
||||||
|
},
|
||||||
|
activeColor: Colors.blue,
|
||||||
|
trackColor: Colors.grey,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
CustomCellWidget(
|
CustomCellWidget(
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
leftText: '邀请信息30天后自动失效'.tr,
|
leftText: '邀请信息30天后自动失效'.tr,
|
||||||
rightWidget: CupertinoSwitch(
|
rightWidget: Obx(
|
||||||
value: false,
|
() => CupertinoSwitch(
|
||||||
onChanged: (bool value) {},
|
value: controller.inviteConfig.value.teamInviteUserValidFalse == 1,
|
||||||
activeColor: Colors.blue, // 可选:打开时的颜色(iOS 默认为系统蓝色,可自定义)
|
onChanged: (bool value) {
|
||||||
trackColor: Colors.grey, // 可选:关闭时的背景轨道颜色
|
if (value) {
|
||||||
|
controller.inviteConfig.value.teamInviteUserValidFalse = 1;
|
||||||
|
} else {
|
||||||
|
controller.inviteConfig.value.teamInviteUserValidFalse = 2;
|
||||||
|
}
|
||||||
|
controller.requestUpdateInvitationSettings();
|
||||||
|
},
|
||||||
|
activeColor: Colors.blue, // 可选:打开时的颜色(iOS 默认为系统蓝色,可自定义)
|
||||||
|
trackColor: Colors.grey, // 可选:关闭时的背景轨道颜色
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -82,22 +82,25 @@ class InviteTeamMemberView extends GetView<InviteTeamMemberController> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 10.h),
|
SizedBox(height: 10.h),
|
||||||
Container(
|
Obx(
|
||||||
padding: EdgeInsets.all(10.r), // 添加边距
|
() => Visibility(
|
||||||
decoration: BoxDecoration(
|
visible: controller.inviteInfo.value.inviteInfo != null,
|
||||||
borderRadius: BorderRadius.circular(8.r), // 为 Container 添加圆角
|
child: Container(
|
||||||
color: Colors.white, // 添加背景色以突出圆角效果
|
padding: EdgeInsets.all(10.r), // 添加边距
|
||||||
),
|
decoration: BoxDecoration(
|
||||||
child: ClipRRect(
|
borderRadius: BorderRadius.circular(8.r), // 为 Container 添加圆角
|
||||||
borderRadius: BorderRadius.circular(8.r),
|
color: Colors.white, // 添加背景色以突出圆角效果
|
||||||
child: Obx(
|
),
|
||||||
() => Image(
|
child: ClipRRect(
|
||||||
width: 200.w, // 调整为 200 以适应 padding
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
height: 200.w,
|
child: Image(
|
||||||
image: NetworkImage(
|
width: 200.w, // 调整为 200 以适应 padding
|
||||||
controller.inviteInfo.value.inviteInfo ?? '',
|
height: 200.w,
|
||||||
|
image: NetworkImage(
|
||||||
|
controller.inviteInfo.value.inviteInfo ?? '',
|
||||||
|
),
|
||||||
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
10
lib/views/team/personnelManage/personnel_manage_binding.dart
Normal file
10
lib/views/team/personnelManage/personnel_manage_binding.dart
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'personnel_manage_controller.dart';
|
||||||
|
|
||||||
|
class PersonnelManageBinding extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut(() => PersonnelManageController());
|
||||||
|
}
|
||||||
|
}
|
||||||
137
lib/views/team/personnelManage/personnel_manage_controller.dart
Normal file
137
lib/views/team/personnelManage/personnel_manage_controller.dart
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:animated_tree_view/animated_tree_view.dart';
|
||||||
|
import 'package:animated_tree_view/tree_view/tree_node.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/request/create_new_depart_request.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/request/get_depart_list_request.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/depart_list_reponse.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/user/response/user_info_response.dart';
|
||||||
|
import 'package:starwork_flutter/api/service/team_api_service.dart';
|
||||||
|
import 'package:starwork_flutter/base/app_logger.dart';
|
||||||
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/cache_keys.dart';
|
||||||
|
import 'package:starwork_flutter/common/utils/shared_preferences_utils.dart';
|
||||||
|
|
||||||
|
class PersonnelManageController extends BaseController {
|
||||||
|
final teamApi = Get.find<TeamApiService>();
|
||||||
|
final Rx<TreeNode?> treeData = Rx<TreeNode?>(null);
|
||||||
|
TreeViewController? treeViewController;
|
||||||
|
var selectedDepartItem = DepartItem().obs; // 当前选中的组织
|
||||||
|
var cacheUserInfo = UserInfoResponse().obs; // 缓存的登录用户信息
|
||||||
|
final RxInt totalPersonCount = 0.obs;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
super.onReady();
|
||||||
|
requestDepartList();
|
||||||
|
getCacheUserInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
requestDepartList() async {
|
||||||
|
var response = await teamApi.requestDepartList(
|
||||||
|
request: GetDepartListRequest(departNo: ''),
|
||||||
|
);
|
||||||
|
if (response.isSuccess) {
|
||||||
|
// 转换数据为树形结构
|
||||||
|
final tree = _convertToTree(response.data!.departList ?? []);
|
||||||
|
treeData.value = tree;
|
||||||
|
// 统计总人数
|
||||||
|
totalPersonCount.value = _calculateTotalPersonCount(response.data!.departList ?? []);
|
||||||
|
|
||||||
|
treeViewController?.expandAllChildren(treeData.value ?? TreeNode.root());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算总人数
|
||||||
|
int _calculateTotalPersonCount(List<DepartItem> departList) {
|
||||||
|
int total = 0;
|
||||||
|
for (final depart in departList) {
|
||||||
|
total += depart.personNum ?? 0;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode _convertToTree(List<DepartItem> departList) {
|
||||||
|
// 创建根节点
|
||||||
|
final root = TreeNode.root();
|
||||||
|
|
||||||
|
// 如果列表为空,直接返回根节点
|
||||||
|
if (departList.isEmpty) {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个映射来存储所有部门节点,方便查找
|
||||||
|
final Map<int, TreeNode> departNodeMap = {};
|
||||||
|
|
||||||
|
// 先创建所有部门节点
|
||||||
|
for (final depart in departList) {
|
||||||
|
final node = TreeNode(
|
||||||
|
key: depart.id.toString(),
|
||||||
|
data: depart,
|
||||||
|
);
|
||||||
|
departNodeMap[depart.id!] = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 建立部门间的父子关系
|
||||||
|
for (final depart in departList) {
|
||||||
|
final currentNode = departNodeMap[depart.id];
|
||||||
|
if (currentNode == null) continue;
|
||||||
|
|
||||||
|
// 建立部门间的父子关系
|
||||||
|
if (depart.parentId == -1) {
|
||||||
|
// 顶级部门添加到根节点下
|
||||||
|
root.add(currentNode);
|
||||||
|
} else {
|
||||||
|
// 子部门添加到对应父部门下
|
||||||
|
final parentNode = departNodeMap[depart.parentId];
|
||||||
|
parentNode?.add(currentNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将人员节点添加到对应的部门节点下(在所有部门结构建立完成后再添加)
|
||||||
|
for (final depart in departList) {
|
||||||
|
final currentNode = departNodeMap[depart.id];
|
||||||
|
if (currentNode == null) continue;
|
||||||
|
|
||||||
|
// 将该部门下的所有人员作为子节点添加
|
||||||
|
if (depart.persons != null && depart.persons!.isNotEmpty) {
|
||||||
|
// 对人员按某种规则排序(例如按姓名或ID)
|
||||||
|
final sortedPersons = List<PersonItem>.from(depart.persons!);
|
||||||
|
// 这里可以根据需要添加排序逻辑,例如按姓名排序:
|
||||||
|
// sortedPersons.sort((a, b) => (a.personName ?? '').compareTo(b.personName ?? ''));
|
||||||
|
|
||||||
|
for (final person in sortedPersons) {
|
||||||
|
final personNode = TreeNode(
|
||||||
|
key: 'person_${person.id}',
|
||||||
|
data: person,
|
||||||
|
);
|
||||||
|
currentNode.add(personNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
requestCreateDepart() async {
|
||||||
|
var response = await teamApi.requestCreateDepart(
|
||||||
|
request: CreateNewDepartRequest(departName: '测试2', parentDepartNo: '-1', leader: ['CY93685899']),
|
||||||
|
);
|
||||||
|
if (response.isSuccess) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void getCacheUserInfo() async {
|
||||||
|
String? cachedJson = await SharedPreferencesUtils.getString(CacheKeys.userAccountInfo);
|
||||||
|
if (cachedJson != null) {
|
||||||
|
try {
|
||||||
|
Map<String, dynamic> jsonMap = jsonDecode(cachedJson);
|
||||||
|
UserInfoResponse userInfoResponse = UserInfoResponse.fromJson(jsonMap);
|
||||||
|
cacheUserInfo.value = userInfoResponse;
|
||||||
|
cacheUserInfo.refresh();
|
||||||
|
} catch (e) {
|
||||||
|
AppLogger.error('JSON 解析错误: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
428
lib/views/team/personnelManage/personnel_manage_view.dart
Normal file
428
lib/views/team/personnelManage/personnel_manage_view.dart
Normal file
@ -0,0 +1,428 @@
|
|||||||
|
import 'package:animated_tree_view/animated_tree_view.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/painting.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/depart_list_reponse.dart';
|
||||||
|
import 'package:starwork_flutter/base/app_logger.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/app_colors.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/app_images.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/app_view_parameter_keys.dart';
|
||||||
|
import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart';
|
||||||
|
import 'package:starwork_flutter/extension/function_extension.dart';
|
||||||
|
import 'package:starwork_flutter/routes/app_routes.dart';
|
||||||
|
import 'personnel_manage_controller.dart';
|
||||||
|
|
||||||
|
class PersonnelManageView extends GetView<PersonnelManageController> {
|
||||||
|
PersonnelManageView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// 即使不使用,只是引用一下 controller 就能触发初始化
|
||||||
|
final _ = controller; // 添加这一行
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
appBar: CustomAppBarWidget(
|
||||||
|
title: '人员管理'.tr,
|
||||||
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
),
|
||||||
|
body: SafeArea(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
vertical: 10.h,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
vertical: 10.h,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.person,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 4.h,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'人脸信息'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Get.toNamed(AppRoutes.teamRoleManage);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.person,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 4.h,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'角色管理'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.person,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 4.h,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'新用户审核'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
),
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text(
|
||||||
|
'组织架构',
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Obx(
|
||||||
|
() => Container(
|
||||||
|
margin: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(8.0)),
|
||||||
|
),
|
||||||
|
child: TreeView.simple(
|
||||||
|
tree: controller.treeData.value ?? TreeNode.root(),
|
||||||
|
showRootNode: false,
|
||||||
|
expansionIndicatorBuilder: noExpansionIndicatorBuilder,
|
||||||
|
indentation: const Indentation(style: IndentStyle.roundJoint),
|
||||||
|
onItemTap: (item) {},
|
||||||
|
onTreeReady: (c) {
|
||||||
|
controller.treeViewController = c;
|
||||||
|
},
|
||||||
|
builder: (context, node) {
|
||||||
|
String title = "";
|
||||||
|
DepartItem departInfo = DepartItem();
|
||||||
|
int personNum = 0;
|
||||||
|
bool hasChildren = node.childrenAsList.isNotEmpty; // 判断是否有子节点
|
||||||
|
bool isPersonItem = node.data is PersonItem; // 判断当前节点是否是人员节点
|
||||||
|
bool isOneself = false;
|
||||||
|
bool isRootNode = false;
|
||||||
|
bool isSuper = false;
|
||||||
|
|
||||||
|
if (node.data is DepartItem) {
|
||||||
|
final depart = node.data as DepartItem;
|
||||||
|
title = depart.departName ?? "未命名部门";
|
||||||
|
personNum = depart.personNum ?? 0;
|
||||||
|
departInfo = depart;
|
||||||
|
if (hasChildren) {
|
||||||
|
title = title + "($personNum)";
|
||||||
|
} else {
|
||||||
|
title = title + "(0)";
|
||||||
|
}
|
||||||
|
if (depart.parentId == -1) {
|
||||||
|
isRootNode = true;
|
||||||
|
}
|
||||||
|
} else if (node.data is PersonItem) {
|
||||||
|
// 处理人员节点
|
||||||
|
final person = node.data as PersonItem;
|
||||||
|
title = person.personName ?? "未命名人员";
|
||||||
|
var personUserId = person.userId;
|
||||||
|
person.roles?.forEach((role) {
|
||||||
|
if (role.isSuper == 1) {
|
||||||
|
isSuper = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (personUserId != null && personUserId == controller.cacheUserInfo.value.id) {
|
||||||
|
isOneself = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 6.h),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
!isPersonItem
|
||||||
|
? Container(
|
||||||
|
width: 34.w,
|
||||||
|
height: 34.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[300],
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
child: Icon(
|
||||||
|
Icons.folder,
|
||||||
|
size: 22.w,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Container(
|
||||||
|
width: 34.w,
|
||||||
|
height: 34.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[200],
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
child: Image(
|
||||||
|
image: const AssetImage(AppImages.defaultAvatar),
|
||||||
|
width: 22.w,
|
||||||
|
height: 22.w,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
gaplessPlayback: true,
|
||||||
|
filterQuality: FilterQuality.medium,
|
||||||
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
return Icon(
|
||||||
|
Icons.person,
|
||||||
|
size: 30.sp,
|
||||||
|
color: Colors.grey[400],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10.w,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: isOneself,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 2.h),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.blue[50],
|
||||||
|
borderRadius: BorderRadius.circular(4.r),
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.blue,
|
||||||
|
width: 1.w,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'自己',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: isSuper && isOneself,
|
||||||
|
child: SizedBox(
|
||||||
|
width: 4.w,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: isSuper,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 2.h),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.blue[50],
|
||||||
|
borderRadius: BorderRadius.circular(4.r),
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.blue,
|
||||||
|
width: 1.w,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'超管',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: !isPersonItem,
|
||||||
|
child: Obx(
|
||||||
|
() => Radio<DepartItem>(
|
||||||
|
value: departInfo,
|
||||||
|
groupValue: controller.selectedDepartItem.value,
|
||||||
|
activeColor: Colors.blue,
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
onChanged: (value) {
|
||||||
|
controller.selectedDepartItem.value = value as DepartItem;
|
||||||
|
controller.selectedDepartItem.refresh();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Obx(
|
||||||
|
() => Text(
|
||||||
|
'共${controller.totalPersonCount.value}人',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (controller.selectedDepartItem.value.departNo == null) {
|
||||||
|
controller.showToast('请先选择一个组织');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Get.toNamed(AppRoutes.teamAddPerson, arguments: {
|
||||||
|
AppViewParameterKeys.departItem: controller.selectedDepartItem.value.toJson(),
|
||||||
|
});
|
||||||
|
}.debounce(),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.h),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.r)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'添加人员'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 10.w),
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (controller.selectedDepartItem.value.departNo == null) {
|
||||||
|
controller.showToast('请先选择一个组织');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}.debounce(),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.grey[50],
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.h),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.r)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'添加子组织'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.blue,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 10.w),
|
||||||
|
Expanded(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {}.debounce(),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.grey[50],
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.h),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.r)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'更多管理'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.blue,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
lib/views/team/roleManage/role_manage_binding.dart
Normal file
10
lib/views/team/roleManage/role_manage_binding.dart
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'role_manage_controller.dart';
|
||||||
|
|
||||||
|
class RoleManageBinding extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut(() => RoleManageController());
|
||||||
|
}
|
||||||
|
}
|
||||||
42
lib/views/team/roleManage/role_manage_controller.dart
Normal file
42
lib/views/team/roleManage/role_manage_controller.dart
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/request/role_list_request.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/role_list_response.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/user/response/user_info_response.dart';
|
||||||
|
import 'package:starwork_flutter/api/service/team_api_service.dart';
|
||||||
|
import 'package:starwork_flutter/base/app_logger.dart';
|
||||||
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/cache_keys.dart';
|
||||||
|
import 'package:starwork_flutter/common/utils/shared_preferences_utils.dart';
|
||||||
|
|
||||||
|
class RoleManageController extends BaseController {
|
||||||
|
final teamApi = Get.find<TeamApiService>();
|
||||||
|
var roleList = <RoleListResponse>[].obs;
|
||||||
|
var cacheUserInfo = UserInfoResponse().obs; // 缓存的登录用户信息
|
||||||
|
@override
|
||||||
|
void onReady() async {
|
||||||
|
super.onReady();
|
||||||
|
requestRoleList();
|
||||||
|
|
||||||
|
String? cachedJson = await SharedPreferencesUtils.getString(CacheKeys.userAccountInfo);
|
||||||
|
if (cachedJson != null) {
|
||||||
|
try {
|
||||||
|
Map<String, dynamic> jsonMap = jsonDecode(cachedJson);
|
||||||
|
UserInfoResponse userInfoResponse = UserInfoResponse.fromJson(jsonMap);
|
||||||
|
cacheUserInfo.value = userInfoResponse;
|
||||||
|
cacheUserInfo.refresh();
|
||||||
|
} catch (e) {
|
||||||
|
AppLogger.error('JSON 解析错误: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void requestRoleList() async {
|
||||||
|
var response = await teamApi.requestTeamRoleList();
|
||||||
|
if (response.isSuccess) {
|
||||||
|
roleList.value = response.data ?? [];
|
||||||
|
roleList.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
345
lib/views/team/roleManage/role_manage_view.dart
Normal file
345
lib/views/team/roleManage/role_manage_view.dart
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/role_list_response.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/app_colors.dart';
|
||||||
|
import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart';
|
||||||
|
import 'package:starwork_flutter/extension/function_extension.dart';
|
||||||
|
import 'package:starwork_flutter/routes/app_routes.dart';
|
||||||
|
import 'role_manage_controller.dart';
|
||||||
|
|
||||||
|
class RoleManageView extends GetView<RoleManageController> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// 即使不使用,只是引用一下 controller 就能触发初始化
|
||||||
|
final _ = controller; // 添加这一行
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
appBar: CustomAppBarWidget(
|
||||||
|
title: '角色分配'.tr,
|
||||||
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
),
|
||||||
|
body: SafeArea(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: '超级管理员'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const TextSpan(
|
||||||
|
text: ' ',
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: '具有团队全部管理权限'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
vertical: 10.h,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Obx(
|
||||||
|
() => Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
controller.cacheUserInfo.value.nickname ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
controller.cacheUserInfo.value.accountNo ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
controller.showFunctionNotOpen();
|
||||||
|
}.debounce(),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.r)),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'转让'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
RichText(
|
||||||
|
text: TextSpan(
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: '角色'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const TextSpan(
|
||||||
|
text: ' ',
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: '用于给其他用户快捷分配权限'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () async {
|
||||||
|
var result = await Get.toNamed(AppRoutes.teamAddRole);
|
||||||
|
if (result != null && result == true) {
|
||||||
|
controller.requestRoleList();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'新建角色',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
_buildRoleList(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_buildRoleList() {
|
||||||
|
return Obx(
|
||||||
|
() => Flexible(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
child: ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: controller.roleList.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
RoleListResponse role = controller.roleList[index];
|
||||||
|
return _buildRoleItem(role);
|
||||||
|
},
|
||||||
|
separatorBuilder: (context, index) {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
),
|
||||||
|
child: Divider(
|
||||||
|
height: 0.5.h,
|
||||||
|
thickness: 0.5.h,
|
||||||
|
color: Colors.grey[100],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_buildRoleItem(RoleListResponse role) {
|
||||||
|
// 假设 role 对象中有 personList 字段,且每个 person 有 personName 属性
|
||||||
|
// 如果数据结构不同,请根据实际情况调整
|
||||||
|
String personNames = '';
|
||||||
|
|
||||||
|
// 示例:如果 role.personList 存在且不为空
|
||||||
|
if (role.personList != null && role.personList!.isNotEmpty) {
|
||||||
|
// 提取所有 personName 并用逗号连接
|
||||||
|
personNames = role.personList!.map((person) => person.personName ?? '').join(','); // 使用顿号或逗号分隔
|
||||||
|
} else {
|
||||||
|
// 默认值或空值处理
|
||||||
|
personNames = '暂无用户';
|
||||||
|
}
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
vertical: 10.h,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.group_rounded,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 6.w,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
role.roleName ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_ios_rounded,
|
||||||
|
color: Colors.grey,
|
||||||
|
size: 16.sp,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
RichText(
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
text: TextSpan(
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: '角色用户:'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: personNames,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
RichText(
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
text: TextSpan(
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: '分配权限:'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: '全部权限'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
RichText(
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
text: TextSpan(
|
||||||
|
children: [
|
||||||
|
TextSpan(
|
||||||
|
text: '角色描述:'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.grey[500],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: role.roleDesc ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'select_organization_controller.dart';
|
||||||
|
|
||||||
|
class SelectOrganizationBinding extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut(() => SelectOrganizationController());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
import 'package:animated_tree_view/animated_tree_view.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/request/get_depart_list_request.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/depart_list_reponse.dart';
|
||||||
|
import 'package:starwork_flutter/api/service/team_api_service.dart';
|
||||||
|
import 'package:starwork_flutter/base/base_controller.dart';
|
||||||
|
|
||||||
|
class SelectOrganizationController extends BaseController {
|
||||||
|
final teamApi = Get.find<TeamApiService>();
|
||||||
|
final Rx<TreeNode?> treeData = Rx<TreeNode?>(null);
|
||||||
|
TreeViewController? treeViewController;
|
||||||
|
// 搜索输入框
|
||||||
|
TextEditingController searchInputController = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onReady() {
|
||||||
|
super.onReady();
|
||||||
|
requestDepartList();
|
||||||
|
}
|
||||||
|
|
||||||
|
requestDepartList() async {
|
||||||
|
var response = await teamApi.requestDepartList(
|
||||||
|
request: GetDepartListRequest(departNo: ''),
|
||||||
|
);
|
||||||
|
if (response.isSuccess) {
|
||||||
|
// 转换数据为树形结构
|
||||||
|
final tree = _convertToTree(response.data!.departList ?? []);
|
||||||
|
treeData.value = tree;
|
||||||
|
|
||||||
|
treeViewController?.expandAllChildren(treeData.value ?? TreeNode.root());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode _convertToTree(List<DepartItem> departList) {
|
||||||
|
// 创建根节点
|
||||||
|
final root = TreeNode.root();
|
||||||
|
|
||||||
|
// 如果列表为空,直接返回根节点
|
||||||
|
if (departList.isEmpty) {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个映射来存储所有部门节点,方便查找
|
||||||
|
final Map<int, TreeNode> departNodeMap = {};
|
||||||
|
|
||||||
|
// 先创建所有部门节点
|
||||||
|
for (final depart in departList) {
|
||||||
|
final node = TreeNode(
|
||||||
|
key: depart.id.toString(),
|
||||||
|
data: depart,
|
||||||
|
);
|
||||||
|
departNodeMap[depart.id!] = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 建立部门间的父子关系
|
||||||
|
for (final depart in departList) {
|
||||||
|
final currentNode = departNodeMap[depart.id];
|
||||||
|
if (currentNode == null) continue;
|
||||||
|
|
||||||
|
// 建立部门间的父子关系
|
||||||
|
if (depart.parentId == -1) {
|
||||||
|
// 顶级部门添加到根节点下
|
||||||
|
root.add(currentNode);
|
||||||
|
} else {
|
||||||
|
// 子部门添加到对应父部门下
|
||||||
|
final parentNode = departNodeMap[depart.parentId];
|
||||||
|
parentNode?.add(currentNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
}
|
||||||
204
lib/views/team/selectOrganization/select_organization_view.dart
Normal file
204
lib/views/team/selectOrganization/select_organization_view.dart
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
import 'package:animated_tree_view/animated_tree_view.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:starwork_flutter/api/model/team/response/depart_list_reponse.dart';
|
||||||
|
import 'package:starwork_flutter/base/app_logger.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/app_colors.dart';
|
||||||
|
import 'package:starwork_flutter/common/constant/app_images.dart';
|
||||||
|
import 'package:starwork_flutter/common/widgets/custome_app_bar_wdiget.dart';
|
||||||
|
import 'select_organization_controller.dart';
|
||||||
|
|
||||||
|
class SelectOrganizationView extends GetView<SelectOrganizationController> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
appBar: CustomAppBarWidget(
|
||||||
|
title: '选择组织'.tr,
|
||||||
|
backgroundColor: AppColors.scaffoldBackgroundColor,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.clear_rounded,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: SafeArea(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10.w,
|
||||||
|
vertical: 10.h,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_buildSearchBar(),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text(
|
||||||
|
'组织架构',
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10.h,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Obx(
|
||||||
|
() => Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(8.0)),
|
||||||
|
),
|
||||||
|
child: TreeView.simple(
|
||||||
|
tree: controller.treeData.value ?? TreeNode.root(),
|
||||||
|
showRootNode: false,
|
||||||
|
expansionIndicatorBuilder: noExpansionIndicatorBuilder,
|
||||||
|
indentation: const Indentation(style: IndentStyle.roundJoint),
|
||||||
|
onItemTap: (item) {
|
||||||
|
AppLogger.highlight('message:${item.data}');
|
||||||
|
if (item.data is DepartItem) {
|
||||||
|
Get.back(result: item.data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onTreeReady: (c) {
|
||||||
|
controller.treeViewController = c;
|
||||||
|
},
|
||||||
|
builder: (context, node) {
|
||||||
|
String title = "";
|
||||||
|
DepartItem departInfo = DepartItem();
|
||||||
|
bool isPersonItem = node.data is PersonItem; // 判断当前节点是否是人员节点
|
||||||
|
|
||||||
|
if (node.data is DepartItem) {
|
||||||
|
final depart = node.data as DepartItem;
|
||||||
|
title = depart.departName ?? "未命名部门";
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 6.h),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
!isPersonItem
|
||||||
|
? Container(
|
||||||
|
width: 34.w,
|
||||||
|
height: 34.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[300],
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
child: Icon(
|
||||||
|
Icons.folder,
|
||||||
|
size: 22.w,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Container(
|
||||||
|
width: 34.w,
|
||||||
|
height: 34.w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[200],
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
|
child: Image(
|
||||||
|
image: const AssetImage(AppImages.defaultAvatar),
|
||||||
|
width: 22.w,
|
||||||
|
height: 22.w,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
gaplessPlayback: true,
|
||||||
|
filterQuality: FilterQuality.medium,
|
||||||
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
return Icon(
|
||||||
|
Icons.person,
|
||||||
|
size: 30.sp,
|
||||||
|
color: Colors.grey[400],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 10.w,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_buildSearchBar() {
|
||||||
|
return TextField(
|
||||||
|
controller: controller.searchInputController,
|
||||||
|
textInputAction: TextInputAction.search,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: '请输入设备名称'.tr,
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
fontSize: 14.sp,
|
||||||
|
color: const Color(0xFF999999),
|
||||||
|
),
|
||||||
|
prefixIcon: const Icon(
|
||||||
|
Icons.search,
|
||||||
|
color: Color(0xFF999999),
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
// 启用背景填充
|
||||||
|
fillColor: const Color(0xFFf0f0f0),
|
||||||
|
// 灰色背景(可调整色值)
|
||||||
|
border: InputBorder.none,
|
||||||
|
// 设置内边距
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Colors.blue,
|
||||||
|
width: 1.5,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(8.0.r),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(color: Colors.transparent),
|
||||||
|
borderRadius: BorderRadius.circular(8.0.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
40
pubspec.lock
40
pubspec.lock
@ -1,6 +1,14 @@
|
|||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
animated_tree_view:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: animated_tree_view
|
||||||
|
sha256: ed982be7fa2cf51b62bb76e95b6a0f423cde12f1da8745a1da938e82a7baacf2
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.0"
|
||||||
archive:
|
archive:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -105,6 +113,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.11"
|
version: "0.7.11"
|
||||||
|
diffutil_dart:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: diffutil_dart
|
||||||
|
sha256: "5e74883aedf87f3b703cb85e815bdc1ed9208b33501556e4a8a5572af9845c81"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.1"
|
||||||
dio:
|
dio:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -153,6 +169,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
|
fixnum:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fixnum
|
||||||
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -509,6 +533,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.28.0"
|
version: "0.28.0"
|
||||||
|
scroll_to_index:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: scroll_to_index
|
||||||
|
sha256: b707546e7500d9f070d63e5acf74fd437ec7eeeb68d3412ef7b0afada0b4f176
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -657,6 +689,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
uuid:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: uuid
|
||||||
|
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.5.1"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -43,7 +43,8 @@ dependencies:
|
|||||||
# 星云sdk
|
# 星云sdk
|
||||||
starcloud:
|
starcloud:
|
||||||
path: ../starcloud-sdk-flutter
|
path: ../starcloud-sdk-flutter
|
||||||
|
# 树形结构
|
||||||
|
animated_tree_view: ^2.3.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user