Skip to content

fixed orgmembers with searchMemberName and searchGroupId #1772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,7 @@ public interface OrgApiService {
Mono<ConfigView> getOrganizationConfigs(String orgId);

Mono<Long> getApiUsageCount(String orgId, Boolean lastMonthOnly);

Mono<OrgMemberListView> getOrganizationMembersForSearch(String orgId, String searchMemberName, String searchGroupId, Integer pageNum, Integer pageSize);
}

Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
import org.springframework.http.codec.multipart.Part;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import reactor.core.publisher.Flux;
import org.lowcoder.domain.group.service.GroupMemberService;
import org.lowcoder.domain.group.model.GroupMember;

import java.util.*;
import java.util.stream.Collectors;
Expand All @@ -49,6 +52,8 @@
import static org.lowcoder.sdk.util.ExceptionUtils.deferredError;
import static org.lowcoder.sdk.util.ExceptionUtils.ofError;
import static org.lowcoder.sdk.util.StreamUtils.collectSet;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;

@Slf4j
@Service
Expand All @@ -72,9 +77,10 @@ public class OrgApiServiceImpl implements OrgApiService {
private GroupService groupService;
@Autowired
private AuthenticationService authenticationService;

@Autowired
private ServerLogService serverLogService;
@Autowired
private GroupMemberService groupMemberService;

@Override
public Mono<OrgMemberListView> getOrganizationMembers(String orgId, int page, int count) {
Expand All @@ -84,6 +90,78 @@ public Mono<OrgMemberListView> getOrganizationMembers(String orgId, int page, in
.then(getOrgMemberListView(orgId, page, count));
}

// Update getOrgMemberListViewForSearch to filter by group membership
private Mono<OrgMemberListView> getOrgMemberListViewForSearch(String orgId, String searchMemberName, String searchGroupId, Integer page, Integer pageSize) {
return orgMemberService.getOrganizationMembers(orgId)
.collectList()
.flatMap(orgMembers -> {
List<String> userIds = orgMembers.stream()
.map(OrgMember::getUserId)
.collect(Collectors.toList());
Mono<Map<String, User>> users = userService.getByIds(userIds);

// If searchGroupId is provided, fetch group members
Mono<Set<String>> groupUserIdsMono = StringUtils.isBlank(searchGroupId)
? Mono.just(Collections.emptySet())
: groupMemberService.getGroupMembers(searchGroupId)
.map(list -> list.stream()
.map(GroupMember::getUserId)
.collect(Collectors.toSet()));

return Mono.zip(users, groupUserIdsMono)
.map(tuple -> {
Map<String, User> userMap = tuple.getT1();
Set<String> groupUserIds = tuple.getT2();

var list = orgMembers.stream()
.map(orgMember -> {
User user = userMap.get(orgMember.getUserId());
if (user == null) {
log.warn("user {} not exist and will be removed from the result.", orgMember.getUserId());
return null;
}
return buildOrgMemberView(user, orgMember);
})
.filter(Objects::nonNull)
.filter(orgMemberView -> {
// Filter by name
boolean matchesName = StringUtils.isBlank(searchMemberName) ||
StringUtils.containsIgnoreCase(orgMemberView.getName(), searchMemberName);

// Filter by group
boolean matchesGroup = StringUtils.isBlank(searchGroupId) ||
groupUserIds.contains(orgMemberView.getUserId());

return matchesName && matchesGroup;
})
.collect(Collectors.toList());
var pageTotal = list.size();
list = list.subList((page - 1) * pageSize, pageSize == 0 ? pageTotal : Math.min(page * pageSize, pageTotal));
return Pair.of(list, pageTotal);
});
})
.zipWith(sessionUserService.getVisitorOrgMemberCache())
.map(tuple -> {
List<OrgMemberView> memberViews = tuple.getT1().getLeft();
var pageTotal = tuple.getT1().getRight();
OrgMember orgMember = tuple.getT2();
return OrgMemberListView.builder()
.members(memberViews)
.total(pageTotal)
.pageNum(page)
.pageSize(pageSize)
.visitorRole(orgMember.getRole().getValue())
.build();
});
}
@Override
public Mono<OrgMemberListView> getOrganizationMembersForSearch(String orgId, String searchMemberName, String searchGroupId, Integer page, Integer pageSize) {
return sessionUserService.getVisitorId()
.flatMap(visitorId -> orgMemberService.getOrgMember(orgId, visitorId))
.switchIfEmpty(deferredError(BizError.NOT_AUTHORIZED, "NOT_AUTHORIZED"))
.then(getOrgMemberListViewForSearch(orgId, searchMemberName, searchGroupId, page, pageSize));
}

private Mono<OrgMemberListView> getOrgMemberListView(String orgId, int page, int count) {
return orgMemberService.getOrganizationMembers(orgId)
.collectList()
Expand Down Expand Up @@ -136,6 +214,17 @@ protected OrgMemberView build(User user, OrgMember orgMember) {
.rawUserInfos(findRawUserInfos(user, orgId))
.build();
}
protected OrgMemberView buildOrgMemberView(User user, OrgMember orgMember) {
String orgId = orgMember.getOrgId();
return OrgMemberView.builder()
.name(user.getName())
.userId(user.getId())
.role(orgMember.getRole().getValue())
.avatarUrl(user.getAvatarUrl())
.joinTime(orgMember.getJoinTime())
.rawUserInfos(findRawUserInfos(user, orgId))
.build();
}

protected Map<String, Map<String, Object>> findRawUserInfos(User user, String orgId) {
return SetUtils.emptyIfNull(user.getConnections())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.lowcoder.api.usermanagement.view.UpdateRoleRequest;
import org.lowcoder.api.util.BusinessEventPublisher;
import org.lowcoder.api.util.GidService;
import org.lowcoder.domain.organization.model.OrgMember;
import org.lowcoder.domain.organization.model.Organization;
import org.lowcoder.domain.organization.model.Organization.OrganizationCommonSettings;
import org.lowcoder.domain.organization.service.OrgMemberService;
Expand Down Expand Up @@ -117,6 +118,16 @@ public Mono<ResponseView<OrgMemberListView>> getOrgMembers(@PathVariable String
orgApiService.getOrganizationMembers(id, pageNum, pageSize)
.map(ResponseView::success));
}
@Override
public Mono<ResponseView<OrgMemberListView>> getOrgMembersForSearch(@PathVariable String orgId,
@PathVariable String searchMemberName,
@PathVariable String searchGroupId,
@RequestParam(required = false, defaultValue = "1") int pageNum,
@RequestParam(required = false, defaultValue = "1000") int pageSize) {
return gidService.convertOrganizationIdToObjectId(orgId).flatMap(id ->
orgApiService.getOrganizationMembersForSearch(id, searchMemberName, searchGroupId, pageNum, pageSize)
.map(ResponseView::success));
}

@Override
public Mono<ResponseView<Boolean>> updateRoleForMember(@RequestBody UpdateRoleRequest updateRoleRequest,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ public Mono<ResponseView<OrgMemberListView>> getOrgMembers(@PathVariable String
@RequestParam(required = false, defaultValue = "1") int pageNum,
@RequestParam(required = false, defaultValue = "1000") int pageSize);

@GetMapping("/{orgId}/{searchMemberName}/{searchGroupId}/members")
public Mono<ResponseView<OrgMemberListView>> getOrgMembersForSearch(@PathVariable String orgId,
@PathVariable String searchMemberName,
@PathVariable String searchGroupId,
@RequestParam(required = false, defaultValue = "1") int pageNum,
@RequestParam(required = false, defaultValue = "1000") int pageSize);

@Operation(
tags = TAG_ORGANIZATION_MEMBERS,
operationId = "updateOrganizationMemberRole",
Expand Down
Loading