diff --git a/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/controller/DraftController.java b/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/controller/DraftController.java index 504151b..5d0d1cd 100644 --- a/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/controller/DraftController.java +++ b/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/controller/DraftController.java @@ -50,6 +50,25 @@ public void selectPlayer(@Payload DraftRequest draftRequest, Principal principal } } + /* + * 선수 랜덤 드래프트 웹소켓 통신 + */ + @MessageMapping("/draft/selectRandomPlayer") + public void selectRandomPlayer(@Payload DraftRequest draftRequest, Principal principal) throws JsonProcessingException { + + try { + draftService.selectRandomPlayer(draftRequest, principal); + } catch (RuntimeException e) { + log.error(" 랜덤 드래프트 postgreSql 저장 실패 : {}", e.getMessage()); + + throw e; + } catch (JsonProcessingException e) { + log.error(" 랜덤 드래프트 postgreSql 저장 실패 : {}", e.getMessage()); + + throw e; + } + } + /* * 참여자(participant)클릭 시 해당 참여자가 선택한 선수 리스트 가져오기 * */ diff --git a/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/dto/DraftRequest.java b/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/dto/DraftRequest.java index 3c8c892..b90c746 100644 --- a/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/dto/DraftRequest.java +++ b/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/dto/DraftRequest.java @@ -1,6 +1,7 @@ package likelion.mlb.backendProject.domain.draft.dto; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @@ -10,6 +11,7 @@ @Data @NoArgsConstructor @AllArgsConstructor +@Builder public class DraftRequest { private UUID draftId; // 드래프트 방 pk값 diff --git a/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/service/DraftService.java b/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/service/DraftService.java index c67beaa..ab6267a 100644 --- a/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/service/DraftService.java +++ b/backendProject/src/main/java/likelion/mlb/backendProject/domain/draft/service/DraftService.java @@ -12,7 +12,9 @@ import likelion.mlb.backendProject.domain.draft.repository.ParticipantPlayerRepository; import likelion.mlb.backendProject.domain.match.entity.Participant; import likelion.mlb.backendProject.domain.match.repository.ParticipantRepository; +import likelion.mlb.backendProject.domain.player.entity.ElementType; import likelion.mlb.backendProject.domain.player.entity.Player; +import likelion.mlb.backendProject.domain.player.repository.ElementTypeRepository; import likelion.mlb.backendProject.domain.player.repository.PlayerRepository; import likelion.mlb.backendProject.domain.user.entity.User; import likelion.mlb.backendProject.domain.user.repository.UserRepository; @@ -28,6 +30,7 @@ import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -45,6 +48,7 @@ public class DraftService { private final ParticipantPlayerRepository participantPlayerRepository; private final UserRepository userRepository; private final DraftRepository draftRepository; + private final ElementTypeRepository elementTypeRepository; @Transactional @@ -86,6 +90,52 @@ public void selectPlayer(DraftRequest draftRequest redisPublisher.publish(channel, msg); } + @Transactional + public void selectRandomPlayer(DraftRequest draftRequest + , java.security.Principal principal + ) throws JsonProcessingException { + + // participant 객체 추출 + var auth = (org.springframework.security.core.Authentication) principal; + var cud = (likelion.mlb.backendProject.global.security.dto.CustomUserDetails) auth.getPrincipal(); + +// if (cud.getUser().getId() != null) { + User user = userRepository.findById(cud.getUser().getId()) + .orElseThrow(() -> new BaseException(ErrorCode.USER_NOT_FOUND)); +// } + Draft draft = draftRepository.findById(draftRequest.getDraftId()).orElseThrow(() -> new BaseException(ErrorCode.DRAFT_NOT_FOUND)); + Participant participant = participantRepository.findByUserAndDraft(user, draft).orElseThrow(() + -> new BaseException(ErrorCode.PARTICIPANT_NOT_FOUND)); + draftRequest.setParticipantId(participant.getId()); + + // 해당 참가자가 선택할 수 있는 선수 포지션 목록 + List elementTypes = elementTypeRepository.findAvailableElementTypesByParticipant(participant.getId()); + + List elementTypeIds = elementTypes.stream() + .map(ElementType::getId) + .collect(Collectors.toList()); + + Player player = playerRepository.findRandomAvailablePlayer(draft.getId(), elementTypeIds) + .orElseThrow(() -> new IllegalArgumentException("Random Player not found")); + + DraftRequest randomDraftRequest = Player.toDraftRequest(player); + randomDraftRequest.setDraftId(draftRequest.getDraftId()); + randomDraftRequest.setParticipantId(participant.getId()); + + String channel = null; + String msg = null; +// UUID participantId = ((StompPrincipal) principal).getParticipantId(); // 현 로그인 한 사용자 member pk + + // 일반 메시지 + channel = "draft."+randomDraftRequest.getDraftId(); + msg = objectMapper.writeValueAsString(randomDraftRequest); + + // DB에 참여자와 뽑은 선수 정보 저장 + saveDraft(randomDraftRequest, participant); + + redisPublisher.publish(channel, msg); + } + /* * DB에 참여자와 뽑은 선수 정보 저장 **/ diff --git a/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/entity/Player.java b/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/entity/Player.java index 457f766..22b1f39 100644 --- a/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/entity/Player.java +++ b/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/entity/Player.java @@ -1,6 +1,7 @@ package likelion.mlb.backendProject.domain.player.entity; import jakarta.persistence.*; +import likelion.mlb.backendProject.domain.draft.dto.DraftRequest; import likelion.mlb.backendProject.domain.player.cache.dto.PlayerDto; import likelion.mlb.backendProject.domain.team.entity.Team; import likelion.mlb.backendProject.global.jpa.entity.BaseTime; @@ -175,5 +176,26 @@ public static List toDtoList(List players) { ).collect(Collectors.toList()); } + /** + * Player 엔티티 → DraftRequest 변환 + */ + public static DraftRequest toDraftRequest(Player player) { + return DraftRequest.builder() + .playerId(player.getId()) + .playerWebName(player.getWebName()) + .playerKrName(player.getKrName()) + .playerPic(player.getPic()) + + // team관련 설정 + .teamName(player.getTeam().getName()) + .teamKrName(player.getTeam().getKrName()) + + // 포지션(elementType) 관련 설정 + .elementTypeId(player.getElementType().getId()) + .elementTypePluralName(player.getElementType().getPluralName()) + .elementTypeKrName(player.getElementType().getKrName()) + .build(); + } + } diff --git a/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/repository/ElementTypeRepository.java b/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/repository/ElementTypeRepository.java index 4c305eb..6eae557 100644 --- a/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/repository/ElementTypeRepository.java +++ b/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/repository/ElementTypeRepository.java @@ -2,10 +2,26 @@ import likelion.mlb.backendProject.domain.player.entity.ElementType; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.UUID; @Repository public interface ElementTypeRepository extends JpaRepository { + + /* + * 한 참가자(participant)가 선택할 수 있는 선수 포지션 가져오기 + * */ + @Query(""" + SELECT e + FROM ElementType e + LEFT JOIN Player p ON p.elementType = e + LEFT JOIN ParticipantPlayer pp ON pp.player = p AND pp.participant.id = :participantId + GROUP BY e.id, e.squadMaxPlay + HAVING COALESCE(COUNT(pp.id), 0) < e.squadMaxPlay + """) + List findAvailableElementTypesByParticipant(@Param("participantId") UUID participantId); } diff --git a/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/repository/PlayerRepository.java b/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/repository/PlayerRepository.java index 1323797..f12cb44 100644 --- a/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/repository/PlayerRepository.java +++ b/backendProject/src/main/java/likelion/mlb/backendProject/domain/player/repository/PlayerRepository.java @@ -61,4 +61,21 @@ default Map findAllByFplIdInAsMap(List ids) { @Query("SELECT p FROM Player p " +"JOIN FETCH p.team t " +"JOIN FETCH p.elementType et") List findAllWithTeamAndElementType(); + + + @Query(value = """ + SELECT * + FROM player p + WHERE p.id NOT IN ( + SELECT pp.player_id + FROM participant_player pp + JOIN participant pa ON pp.participant_id = pa.id + WHERE pa.draft_id = :draftId + ) + AND p.element_type_id IN (:elementTypeIds) + ORDER BY RANDOM() + LIMIT 1 + """, nativeQuery = true) + Optional findRandomAvailablePlayer(@Param("draftId") UUID draftId, + @Param("elementTypeIds") List elementTypeIds); }