> getJoinRequests(@PathVariable String groupId) {
+ return Result.success(groupService.getJoinRequests(groupId));
+ }
+
+ /**
+ * 邀请用户入群(原「添加群成员」)。
+ *
+ * ⚠️ 行为变更:已建群拉人不再直接入群,改为**发群邀请**,等对方点「允许」后才成为成员。
+ * 建群时带人({@code POST /api/groups} 的 memberIds)不受影响,仍是直接入群。
+ * 响应体由 {@code List} 改为 {@link GroupInviteResult}(invited / failed)。
+ */
+ @PostMapping("/{groupId}/members")
+ public Result addMembers(@PathVariable String groupId,
+ @Valid @RequestBody AddGroupMembersRequest request) {
+ return Result.success(groupInvitationService.invite(groupId, request.getUserIds(), null));
+ }
+
+ // ===================== 群邀请 =====================
+
+ /** 发起群邀请(与 /members 等价,语义更明确的新路径)。 */
+ @PostMapping("/{groupId}/invitations")
+ public Result inviteMembers(@PathVariable String groupId,
+ @Valid @RequestBody CreateGroupInvitationRequest request) {
+ return Result.success(groupInvitationService.invite(groupId, request.getUserIds(), request.getMessage()));
+ }
+
+ /** 群主/管理员查看本群已发出的邀请(谁还没点允许)。 */
+ @GetMapping("/{groupId}/invitations")
+ public Result> listGroupInvitations(
+ @PathVariable String groupId,
+ @RequestParam(required = false) String status,
+ @RequestParam(defaultValue = "1") Integer page,
+ @RequestParam(defaultValue = "20") Integer size) {
+ return Result.success(groupInvitationService.listByGroup(groupId, status, page, size));
+ }
+
+ @DeleteMapping("/{groupId}/members/{userId}")
+ public Result removeMember(@PathVariable String groupId, @PathVariable String userId) {
+ groupService.removeMember(groupId, userId);
+ return Result.success();
+ }
+
+ @PutMapping("/{groupId}/members/{userId}/mute")
+ public Result setMemberMute(@PathVariable String groupId, @PathVariable String userId,
+ @RequestParam boolean isMuted) {
+ groupService.setMemberMute(groupId, userId, isMuted);
+ return Result.success();
+ }
+
+ @PutMapping("/{groupId}/members/me/nickname")
+ public Result updateMyGroupNickname(@PathVariable String groupId,
+ @RequestBody UpdateGroupNicknameRequest request) {
+ return Result.success(groupService.updateMyGroupNickname(groupId, request.getNickname()));
+ }
+
+ // ===================== 群组查询 =====================
+
+ @GetMapping("/my")
+ public Result> getMyGroups() {
+ return Result.success(groupService.getMyGroups());
+ }
+
+ @GetMapping("/search")
+ public Result> searchGroups(
+ @RequestParam(required = false) String keyword,
+ @RequestParam(defaultValue = "1") Integer page,
+ @RequestParam(defaultValue = "20") Integer size) {
+ return Result.success(groupService.searchGroups(keyword, page, size));
+ }
+
+ @GetMapping("/{groupId}")
+ public Result getGroupInfo(@PathVariable String groupId) {
+ return Result.success(groupService.getGroupInfo(groupId));
+ }
+
+ @GetMapping("/{groupId}/members")
+ public Result