XuqmGroup-Server/im-service/src/main/java/com/xuqm/im/controller/FriendController.java

186 行
7.8 KiB
Java

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.PutMapping;
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<ApiResponse<List<String>>> listFriends(
@AuthenticationPrincipal String userId,
@RequestParam String appId) {
List<String> friendIds = friendRepository.findByAppIdAndUserId(appId, userId)
.stream()
.map(ImFriendEntity::getFriendId)
.toList();
return ResponseEntity.ok(ApiResponse.success(friendIds));
}
@PostMapping
public ResponseEntity<ApiResponse<ImFriendEntity>> addFriend(
@AuthenticationPrincipal String userId,
@RequestParam String appId,
@RequestParam String friendId) {
return ResponseEntity.ok(ApiResponse.success(addFriendLink(appId, userId, friendId)));
}
@PostMapping("/batch")
public ResponseEntity<ApiResponse<List<ImFriendEntity>>> addFriends(
@AuthenticationPrincipal String userId,
@RequestParam String appId,
@RequestBody FriendBatchRequest req) {
List<ImFriendEntity> 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<ApiResponse<Void>> 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));
}
@DeleteMapping
public ResponseEntity<ApiResponse<Void>> removeAllFriends(
@AuthenticationPrincipal String userId,
@RequestParam String appId) {
friendRepository.deleteByAppIdAndUserId(appId, userId);
friendRepository.deleteByAppIdAndFriendId(appId, userId);
return ResponseEntity.ok(ApiResponse.ok());
}
@PostMapping("/batch/remove")
public ResponseEntity<ApiResponse<Void>> 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));
}
@PutMapping("/{friendId}/group")
public ResponseEntity<ApiResponse<ImFriendEntity>> setFriendGroup(
@AuthenticationPrincipal String userId,
@PathVariable String friendId,
@RequestParam String appId,
@RequestParam(required = false) String groupName) {
ImFriendEntity link = friendRepository.findByAppIdAndUserIdAndFriendId(appId, userId, friendId)
.orElseGet(() -> addFriendLink(appId, userId, friendId));
link.setFriendGroup(normalizeGroup(groupName));
return ResponseEntity.ok(ApiResponse.success(friendRepository.save(link)));
}
@GetMapping("/groups")
public ResponseEntity<ApiResponse<List<String>>> listFriendGroups(
@AuthenticationPrincipal String userId,
@RequestParam String appId) {
List<String> groups = friendRepository.findByAppIdAndUserId(appId, userId).stream()
.map(ImFriendEntity::getFriendGroup)
.filter(group -> group != null && !group.isBlank())
.distinct()
.sorted()
.toList();
return ResponseEntity.ok(ApiResponse.success(groups));
}
@GetMapping("/groups/{groupName}")
public ResponseEntity<ApiResponse<List<String>>> listFriendsByGroup(
@AuthenticationPrincipal String userId,
@RequestParam String appId,
@PathVariable String groupName) {
List<String> friendIds = friendRepository
.findByAppIdAndUserIdAndFriendGroup(appId, userId, normalizeGroup(groupName))
.stream()
.map(ImFriendEntity::getFriendId)
.toList();
return ResponseEntity.ok(ApiResponse.success(friendIds));
}
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<String> unique(List<String> friendIds) {
return friendIds == null ? List.of() : new ArrayList<>(new LinkedHashSet<>(friendIds));
}
private String normalizeGroup(String groupName) {
return groupName == null || groupName.isBlank() ? null : groupName.trim();
}
@PostMapping("/check")
public ResponseEntity<ApiResponse<List<FriendCheckResult>>> checkFriends(
@AuthenticationPrincipal String userId,
@RequestParam String appId,
@RequestBody FriendCheckRequest req) {
List<FriendCheckResult> results = new ArrayList<>();
for (String friendId : req.friendIds() == null ? List.<String>of() : req.friendIds()) {
boolean isFriend = friendRepository.existsByAppIdAndUserIdAndFriendId(appId, userId, friendId)
|| friendRepository.existsByAppIdAndUserIdAndFriendId(appId, friendId, userId);
results.add(new FriendCheckResult(friendId, isFriend));
}
return ResponseEntity.ok(ApiResponse.success(results));
}
public record FriendBatchRequest(List<String> friendIds) {}
public record FriendCheckRequest(List<String> friendIds) {}
public record FriendCheckResult(String userId, boolean isFriend) {}
}