public Mono<GroupJoinRequestsWithVersion> authAndQueryGroupJoinRequestsWithVersion(
            @NotNull Long requesterId,
            @Nullable Long groupId,
            @Nullable Date lastUpdatedDate) {
        try {
            Validator.notNull(requesterId, "requesterId");
        } catch (ResponseException e) {
            return Mono.error(e);
        }
        boolean searchRequestsByGroupId = groupId != null;
        Mono<Date> versionMono = searchRequestsByGroupId
                ? groupMemberService.isOwnerOrManager(requesterId, groupId, false)
                        .flatMap(authenticated -> {
                            if (!authenticated) {
                                return Mono.error(ResponseException.get(
                                        ResponseStatusCode.NOT_GROUP_OWNER_OR_MANAGER_TO_QUERY_GROUP_JOIN_REQUEST));
                            }
                            return groupVersionService.queryGroupJoinRequestsVersion(groupId);
                        })
                : userVersionService.queryGroupJoinRequestsVersion(requesterId);
        return versionMono.flatMap(version -> {
            if (DateTimeUtil.isAfterOrSame(lastUpdatedDate, version)) {
                return ResponseExceptionPublisherPool.alreadyUpToUpdate();
            }
            Flux<GroupJoinRequest> requestFlux = searchRequestsByGroupId
                    ? queryGroupJoinRequestsByGroupId(groupId)
                    : queryGroupJoinRequestsByRequesterId(requesterId);
            return requestFlux.collect(CollectorUtil.toChunkedList())
                    .map(groupJoinRequests -> {
                        if (groupJoinRequests.isEmpty()) {
                            throw ResponseException.get(ResponseStatusCode.NO_CONTENT);
                        }
                        GroupJoinRequestsWithVersion.Builder builder =
                                ClientMessagePool.getGroupJoinRequestsWithVersionBuilder();
                        int expireAfterSeconds =
                                groupJoinRequestRepository.getEntityExpireAfterSeconds();
                        for (GroupJoinRequest groupJoinRequest : groupJoinRequests) {
                            builder.addGroupJoinRequests(ProtoModelConvertor
                                    .groupJoinRequest2proto(groupJoinRequest, expireAfterSeconds)
                                    .build());
                        }
                        return builder.setLastUpdatedDate(version.getTime())
                                .build();
                    });
        })
                .switchIfEmpty(ResponseExceptionPublisherPool.alreadyUpToUpdate());
    }
@return requester ID, group ID, and status
turms-service/src/main/java/im/turms/service/domain/group/service/GroupJoinRequestService.java