package com.xuqm.im.controller; import com.xuqm.common.model.ApiResponse; import com.xuqm.im.entity.ImFriendEntity; import com.xuqm.im.repository.ImFriendRepository; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; @RestController @RequestMapping("/api/im/friends") public class FriendController { private final ImFriendRepository friendRepository; public FriendController(ImFriendRepository friendRepository) { this.friendRepository = friendRepository; } @GetMapping public ResponseEntity>> listFriends( @AuthenticationPrincipal String userId, @RequestParam String appId) { List friendIds = friendRepository.findByAppIdAndUserId(appId, userId) .stream() .map(ImFriendEntity::getFriendId) .toList(); return ResponseEntity.ok(ApiResponse.success(friendIds)); } @PostMapping public ResponseEntity> addFriend( @AuthenticationPrincipal String userId, @RequestParam String appId, @RequestParam String friendId) { return ResponseEntity.ok(ApiResponse.success(addFriendLink(appId, userId, friendId))); } @PostMapping("/batch") public ResponseEntity>> addFriends( @AuthenticationPrincipal String userId, @RequestParam String appId, @RequestBody FriendBatchRequest req) { List links = new ArrayList<>(); for (String friendId : unique(req.friendIds())) { if (friendId == null || friendId.isBlank() || userId.equals(friendId)) { continue; } links.add(addFriendLink(appId, userId, friendId)); } return ResponseEntity.ok(ApiResponse.success(links)); } @DeleteMapping("/{friendId}") public ResponseEntity> removeFriend( @AuthenticationPrincipal String userId, @PathVariable String friendId, @RequestParam String appId) { friendRepository.deleteByAppIdAndUserIdAndFriendId(appId, userId, friendId); friendRepository.deleteByAppIdAndUserIdAndFriendId(appId, friendId, userId); return ResponseEntity.ok(ApiResponse.success(null)); } @PostMapping("/batch/remove") public ResponseEntity> removeFriends( @AuthenticationPrincipal String userId, @RequestParam String appId, @RequestBody FriendBatchRequest req) { for (String friendId : unique(req.friendIds())) { if (friendId == null || friendId.isBlank() || userId.equals(friendId)) { continue; } friendRepository.deleteByAppIdAndUserIdAndFriendId(appId, userId, friendId); friendRepository.deleteByAppIdAndUserIdAndFriendId(appId, friendId, userId); } return ResponseEntity.ok(ApiResponse.success(null)); } private ImFriendEntity addFriendLink(String appId, String userId, String friendId) { ImFriendEntity forward = friendRepository .findByAppIdAndUserIdAndFriendId(appId, userId, friendId) .orElseGet(() -> { ImFriendEntity e = new ImFriendEntity(); e.setAppId(appId); e.setUserId(userId); e.setFriendId(friendId); return friendRepository.save(e); }); friendRepository.findByAppIdAndUserIdAndFriendId(appId, friendId, userId) .orElseGet(() -> { ImFriendEntity e = new ImFriendEntity(); e.setAppId(appId); e.setUserId(friendId); e.setFriendId(userId); return friendRepository.save(e); }); return forward; } private List unique(List friendIds) { return friendIds == null ? List.of() : new ArrayList<>(new LinkedHashSet<>(friendIds)); } public record FriendBatchRequest(List friendIds) {} }