Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4278242

Browse files
dragonpooludomikula
authored andcommitted
Fix: group members filtering and sorting
1 parent 1daf513 commit 4278242

File tree

7 files changed

+122
-11
lines changed

7 files changed

+122
-11
lines changed

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/group/service/GroupMemberService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,6 @@ public interface GroupMemberService {
4141

4242
Mono<Boolean> bulkRemoveMember(String groupId, Collection<String> userIds);
4343

44+
Mono<List<GroupMember>> getGroupMembersByIdAndRole(String groupId, String role);
45+
4446
}

‎server/api-service/lowcoder-domain/src/main/java/org/lowcoder/domain/group/service/GroupMemberServiceImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ public Mono<List<GroupMember>> getGroupMembers(String groupId) {
3535
.collectList();
3636
}
3737

38+
@Override
39+
public Mono<List<GroupMember>> getGroupMembersByIdAndRole(String groupId, String role) {
40+
return biRelationService.getBySourceIdAndRelation(GROUP_MEMBER, groupId, role)
41+
.map(GroupMember::from)
42+
.collectList();
43+
}
44+
3845
@Override
3946
public Mono<Boolean> addMember(String orgId, String groupId, String userId, MemberRole memberRole) {
4047
return biRelationService.addBiRelation(GROUP_MEMBER, groupId,

‎server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/birelation/BiRelationServiceImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ public Mono<Boolean> updateState(BiRelationBizType bizType, String sourceId, Str
185185

186186
@Override
187187
public Flux<BiRelation> getBySourceIdAndRelation(BiRelationBizType bizType, String sourceId, String relation) {
188+
if (relation == null || relation.isBlank()) {
189+
return biRelationRepository.findByBizTypeAndSourceId(bizType, sourceId);
190+
}
188191
Query query = new Query();
189192
query.addCriteria(where(BIZ_TYPE).is(bizType));
190193
query.addCriteria(where(SOURCE_ID).is(sourceId));

‎server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/GroupApiService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
public interface GroupApiService {
1111
Mono<GroupMemberAggregateView> getGroupMembers(String groupId, int page, int count);
1212

13+
Mono<GroupMemberAggregateView> getGroupMembersForSearch(String groupId, String search, String role, String sort, String order, Integer pageNum, Integer pageSize);
14+
1315
Mono<Boolean> addGroupMember(String groupId, String newUserId, String roleName);
1416

1517
Mono<Boolean> updateRoleForMember(String groupId, UpdateRoleRequest updateRoleRequest);

‎server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/GroupApiServiceImpl.java

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,91 @@ public Mono<GroupMemberAggregateView> getGroupMembers(String groupId, int page,
111111
});
112112
}
113113

114+
@Override
115+
public Mono<GroupMemberAggregateView> getGroupMembersForSearch(String groupId, String search, String role, String sort, String order, Integer pageNum, Integer pageSize) {
116+
Mono<Tuple2<GroupMember, OrgMember>> groupAndOrgMemberInfo = getGroupAndOrgMemberInfo(groupId).cache();
117+
118+
Mono<MemberRole> visitorRoleMono = groupAndOrgMemberInfo.flatMap(tuple -> {
119+
GroupMember groupMember = tuple.getT1();
120+
OrgMember orgMember = tuple.getT2();
121+
if (groupMember.isSuperAdmin() || orgMember.isSuperAdmin()) {
122+
return Mono.just(MemberRole.SUPER_ADMIN);
123+
}
124+
if (groupMember.isAdmin() || orgMember.isAdmin()) {
125+
return Mono.just(MemberRole.ADMIN);
126+
}
127+
if (groupMember.isValid()) {
128+
return Mono.just(MemberRole.MEMBER);
129+
}
130+
return ofError(BizError.NOT_AUTHORIZED, NOT_AUTHORIZED);
131+
});
132+
133+
return groupAndOrgMemberInfo
134+
.filter(this::hasReadPermission)
135+
.switchIfEmpty(deferredError(BizError.NOT_AUTHORIZED, NOT_AUTHORIZED))
136+
.flatMap(groupMember -> groupMemberService.getGroupMembersByIdAndRole(groupId, role))
137+
.<Pair<List<GroupMemberView>, Integer>> flatMap(members -> {
138+
if (members.isEmpty()) {
139+
return Mono.just(Pair.of(emptyList(), 0));
140+
}
141+
142+
List<String> userIds = collectList(members, GroupMember::getUserId);
143+
Mono<Map<String, User>> userMapMono = userService.getByIds(userIds);
144+
return userMapMono.map(map -> {
145+
var list = members.stream()
146+
.map(orgMember -> {
147+
User user = map.get(orgMember.getUserId());
148+
if (user == null) {
149+
return null;
150+
}
151+
return new GroupMemberView(orgMember, user);
152+
})
153+
.filter(Objects::nonNull)
154+
.filter(view -> {
155+
if (search == null || search.isBlank()) return true;
156+
return view.getUserName() != null &&
157+
view.getUserName().toLowerCase().contains(search.toLowerCase());
158+
})
159+
.toList();
160+
List<GroupMemberView> mutableList = new ArrayList<>(list);
161+
if (sort != null && !sort.isBlank()) {
162+
Comparator<GroupMemberView> comparator = null;
163+
if ("userName".equalsIgnoreCase(sort)) {
164+
comparator = Comparator.comparing(GroupMemberView::getUserName, Comparator.nullsLast(String::compareToIgnoreCase));
165+
} else if ("role".equalsIgnoreCase(sort)) {
166+
comparator = Comparator.comparing(GroupMemberView::getRole, Comparator.nullsLast(String::compareToIgnoreCase));
167+
} else if ("joinTime".equalsIgnoreCase(sort)) {
168+
comparator = Comparator.comparing(GroupMemberView::getJoinTime, Comparator.nullsLast(Long::compareTo));
169+
}
170+
if (comparator != null && "desc".equalsIgnoreCase(order)) {
171+
comparator = comparator.reversed();
172+
}
173+
if (comparator != null) {
174+
mutableList.sort(comparator);
175+
}
176+
}
177+
178+
int pageTotal = mutableList.size();
179+
int fromIndex = Math.max(0, (pageNum - 1) * pageSize);
180+
int toIndex = pageSize == 0 ? pageTotal : Math.min(pageNum * pageSize, pageTotal);
181+
List<GroupMemberView> pagedList = fromIndex < toIndex ? mutableList.subList(fromIndex, toIndex) : emptyList();
182+
183+
return Pair.of(pagedList, pageTotal);
184+
});
185+
})
186+
.zipWith(visitorRoleMono)
187+
.map(tuple -> {
188+
Pair<List<GroupMemberView>, Integer> t1 = tuple.getT1();
189+
return GroupMemberAggregateView.builder()
190+
.members(t1.getLeft())
191+
.total(t1.getRight())
192+
.pageNum(pageNum)
193+
.pageSize(pageSize)
194+
.visitorRole(tuple.getT2().getValue())
195+
.build();
196+
});
197+
}
198+
114199
private boolean hasReadPermission(Tuple2<GroupMember, OrgMember> tuple) {
115200
GroupMember groupMember = tuple.getT1();
116201
OrgMember orgMember = tuple.getT2();
@@ -366,4 +451,5 @@ public Mono<OrgMemberListView> getPotentialGroupMembers(String groupId, String s
366451
});
367452
});
368453
}
454+
369455
}

‎server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/GroupController.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,16 @@ public Mono<GroupListResponseView<List<GroupView>>> getOrgGroups(@RequestParam(r
116116

117117

118118
@Override
119-
public Mono<ResponseView<GroupMemberAggregateView>> getGroupMembers(@PathVariable String groupId,
120-
@RequestParam(required = false, defaultValue = "1") int pageNum,
121-
@RequestParam(required = false, defaultValue = "100") int pageSize) {
119+
public Mono<ResponseView<GroupMemberAggregateView>> getGroupMembers(
120+
@PathVariable String groupId,
121+
@RequestParam(required = false) String search,
122+
@RequestParam(required = false) String role,
123+
@RequestParam(required = false) String sort,
124+
@RequestParam(required = false) String order,
125+
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
126+
@RequestParam(required = false, defaultValue = "100") Integer pageSize) {
122127
return gidService.convertGroupIdToObjectId(groupId).flatMap(objectId ->
123-
groupApiService.getGroupMembers(objectId, pageNum, pageSize)
128+
groupApiService.getGroupMembersForSearch(objectId, search, role, sort, order, pageNum, pageSize)
124129
.map(ResponseView::success));
125130
}
126131

‎server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/usermanagement/GroupEndpoints.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,20 @@ public Mono<GroupListResponseView<List<GroupView>>> getOrgGroups(@RequestParam(r
6868

6969
@Operation(
7070
tags = TAG_GROUP_MEMBERS,
71-
operationId = "listGroupMembers",
72-
summary = "List User Group Members",
73-
description = "Retrieve a list of Users / Members within a specific User Group in Lowcoder, showing the group's composition."
71+
operationId = "listGroupMembersWithSearchAndSort",
72+
summary = "List User Group Members with Search and Sort",
73+
description = "Retrieve a paginated, searchable, and sortable list of Users / Members within a specific User Group in Lowcoder."
7474
)
75-
@GetMapping("/{groupId}/members")
76-
public Mono<ResponseView<GroupMemberAggregateView>> getGroupMembers(@PathVariable String groupId,
77-
@RequestParam(required = false, defaultValue = "1") int pageNum,
78-
@RequestParam(required = false, defaultValue = "100") int pageSize);
75+
@GetMapping("/{groupId}/members")
76+
public Mono<ResponseView<GroupMemberAggregateView>> getGroupMembers(
77+
@PathVariable String groupId,
78+
@RequestParam(required = false) String search,
79+
@RequestParam(required = false) String role,
80+
@RequestParam(required = false) String sort,
81+
@RequestParam(required = false) String order,
82+
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
83+
@RequestParam(required = false, defaultValue = "100") Integer pageSize
84+
);
7985

8086
@Operation(
8187
tags = TAG_GROUP_MEMBERS,

0 commit comments

Comments
 (0)