diff --git a/src/main/java/com/sajang/devracebackend/controller/RoomController.java b/src/main/java/com/sajang/devracebackend/controller/RoomController.java index f076444..d8c4aac 100644 --- a/src/main/java/com/sajang/devracebackend/controller/RoomController.java +++ b/src/main/java/com/sajang/devracebackend/controller/RoomController.java @@ -3,7 +3,6 @@ import com.sajang.devracebackend.config.RabbitConfig; import com.sajang.devracebackend.dto.problem.ProblemSaveRequestDto; import com.sajang.devracebackend.dto.room.RoomSaveResponseDto; -import com.sajang.devracebackend.dto.room.RoomEnterRequestDto; import com.sajang.devracebackend.dto.room.RoomWaitRequestDto; import com.sajang.devracebackend.dto.room.RoomWaitResponseDto; import com.sajang.devracebackend.dto.userroom.UserPassRequestDto; @@ -42,16 +41,6 @@ public ResponseEntity> createRoom(@RequestBody return ResponseData.toResponseEntity(ResponseCode.CREATED_ROOM, roomSaveResponseDto); } - @PostMapping("/rooms/{roomId}") - @Operation(summary = "방 입장 시작 [jwt O]", description = "userIdList : 방장을 제외한 나머지 입장자들 목록") - public ResponseEntity usersEnterRoom( - @PathVariable(value = "roomId") Long roomId, // value=""를 작성해주어야만, Swagger에서 api테스트할때 이름값이 뜸. - @RequestBody RoomEnterRequestDto roomEnterRequestDto) { - - userRoomService.usersEnterRoom(roomId, roomEnterRequestDto); - return ResponseData.toResponseEntity(ResponseCode.CREATED_USERROOM); - } - @GetMapping("/rooms/{roomId}") @Operation(summary = "문제풀이 페이지 정보 조회 [jwt O]") public ResponseEntity> loadSolvingPage(@PathVariable(value = "roomId") Long roomId) { // value=""를 작성해주어야만, Swagger에서 api테스트할때 이름값이 뜸. @@ -67,25 +56,32 @@ public ResponseEntity> checkAccess(@Pat } @GetMapping("/rooms/{roomId}/state-check") - @Operation(summary = "방 상태 검사 [jwt O]") + @Operation(summary = "방 상태 검사 [jwt O]", description = "dtoList index==0 : 방장 / dtoList index==others : 방장 외 대기자들 nickname & createdTime 기준 오름차순 정렬") public ResponseEntity> checkState(@PathVariable(value = "roomId") Long roomId) { RoomCheckStateResponseDto roomCheckStateResponseDto = roomService.checkState(roomId); return ResponseData.toResponseEntity(ResponseCode.READ_USERROOM, roomCheckStateResponseDto); } - @PutMapping("/room/{roomId}") + @PostMapping("/rooms/{roomId}") // 의미상 PUT보단 POST가 더 적합하다고 판단했음. @Operation(summary = "문제풀이 실패 및 성공 [jwt O]", description = "isRetry==0 : 첫풀이 경우 / isRetry==1 : 재풀이 경우") public ResponseEntity passSolvingProblem( @PathVariable(value = "roomId") Long roomId, @RequestBody UserPassRequestDto userPassRequestDto) { userRoomService.passSolvingProblem(roomId, userPassRequestDto); - return ResponseData.toResponseEntity(ResponseCode.UPDATE_USERROOM); + return ResponseData.toResponseEntity(ResponseCode.UPDATE_USERROOM); // 비록 POST이지만, 비즈니스 로직은 update임. + } + + @PutMapping("/rooms/{roomId}") + @Operation(summary = "방 입장 대기열 나가기 [jwt O]") + public ResponseEntity userStopWaitRoom(@PathVariable(value = "roomId") Long roomId) { + userRoomService.userStopWaitRoom(roomId); + return ResponseData.toResponseEntity(ResponseCode.UPDATE_ROOM); } @MessageMapping("wait.enter") // 웹소켓 메시지 처리 (백엔드로 '/pub/wait.enter'를 호출시 이 브로커에서 처리) public void userWaitRoom(@Payload RoomWaitRequestDto roomWaitRequestDto) { // '/exchange/wait.exchange/waitingroom.{roomId}' 구독되어있는 프론트엔드에게 메세지 전달. - RoomWaitResponseDto roomWaitResponseDto = roomService.userWaitRoom(roomWaitRequestDto); + RoomWaitResponseDto roomWaitResponseDto = userRoomService.userWaitRoom(roomWaitRequestDto); rabbitTemplate.convertAndSend(RabbitConfig.WAIT_EXCHANGE_NAME, "waitingroom." + roomWaitResponseDto.getRoomId(), roomWaitResponseDto); } diff --git a/src/main/java/com/sajang/devracebackend/domain/Room.java b/src/main/java/com/sajang/devracebackend/domain/Room.java index 8dc417b..579b9ee 100644 --- a/src/main/java/com/sajang/devracebackend/domain/Room.java +++ b/src/main/java/com/sajang/devracebackend/domain/Room.java @@ -3,6 +3,7 @@ import com.sajang.devracebackend.domain.common.BaseEntity; import com.sajang.devracebackend.domain.enums.RoomState; import com.sajang.devracebackend.domain.mapping.UserRoom; +import com.sajang.devracebackend.util.LongListConverter; import com.sajang.devracebackend.util.StringListConverter; import jakarta.persistence.*; import lombok.*; @@ -26,6 +27,9 @@ public class Room extends BaseEntity implements Serializable{ @Column(name = "link", unique = true) private String link; + @Convert(converter = LongListConverter.class) // DB에는 String으로 저장됨. + private List waiting = new ArrayList<>(); // 0인덱스에는 무조건 방장의 userId가 들어갈것. + @Convert(converter = StringListConverter.class) // DB에는 String으로 저장됨. private List ranking = new ArrayList<>(); @@ -45,13 +49,35 @@ public class Room extends BaseEntity implements Serializable{ public Room(String link, Problem problem) { // 이 빌더는 Room 생성때만 사용할 용도 this.link = link; + this.waiting = new ArrayList<>(); // 초기값 빈배열인 문자열 -> "__null__" this.ranking = new ArrayList<>(); // 초기값 빈배열인 문자열 -> "__null__" this.roomState = RoomState.WAIT; // 초기값 WAIT this.problem = problem; } - public void updateRanking(String nickname) { + public void addWaiting(Long userId, Boolean isManager) { + if(isManager == true) { // 방장인 경우, 리스트의 맨앞에 추가. + if(this.waiting.contains(userId)) { + this.waiting.remove(userId); + } + this.waiting.add(0, userId); + } + else if(!this.waiting.contains(userId)) { // 방장이 아니며, 리스트에 없는 일반 사용자인 경우 + this.waiting.add(userId); + } + } + + public void deleteWaiting(Long userId, Boolean isAllDelete) { + if(isAllDelete == true) { + this.waiting.clear(); + } + else { + this.waiting.remove(userId); + } + } + + public void addRanking(String nickname) { this.ranking.add(nickname); } diff --git a/src/main/java/com/sajang/devracebackend/dto/room/RoomCheckStateResponseDto.java b/src/main/java/com/sajang/devracebackend/dto/room/RoomCheckStateResponseDto.java index e478396..e7171f7 100644 --- a/src/main/java/com/sajang/devracebackend/dto/room/RoomCheckStateResponseDto.java +++ b/src/main/java/com/sajang/devracebackend/dto/room/RoomCheckStateResponseDto.java @@ -1,11 +1,14 @@ package com.sajang.devracebackend.dto.room; import com.sajang.devracebackend.domain.enums.RoomState; +import com.sajang.devracebackend.dto.user.UserResponseDto; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.List; + @Builder @Getter @NoArgsConstructor @@ -13,4 +16,6 @@ public class RoomCheckStateResponseDto { private RoomState roomState; + private String link; + private List userResponseDtoList; } diff --git a/src/main/java/com/sajang/devracebackend/dto/room/RoomWaitRequestDto.java b/src/main/java/com/sajang/devracebackend/dto/room/RoomWaitRequestDto.java index a1c513f..806b9d1 100644 --- a/src/main/java/com/sajang/devracebackend/dto/room/RoomWaitRequestDto.java +++ b/src/main/java/com/sajang/devracebackend/dto/room/RoomWaitRequestDto.java @@ -7,7 +7,13 @@ @NoArgsConstructor public class RoomWaitRequestDto { + // 방 private Long roomId; + + // 대기 private Long userId; // 대기자 userId private Boolean isManager; // 방장 여부 + + // 입장 + private Boolean isEnter; // 입장 여부 } diff --git a/src/main/java/com/sajang/devracebackend/dto/room/RoomWaitResponseDto.java b/src/main/java/com/sajang/devracebackend/dto/room/RoomWaitResponseDto.java index f46d558..b092aa0 100644 --- a/src/main/java/com/sajang/devracebackend/dto/room/RoomWaitResponseDto.java +++ b/src/main/java/com/sajang/devracebackend/dto/room/RoomWaitResponseDto.java @@ -13,9 +13,16 @@ @AllArgsConstructor public class RoomWaitResponseDto { + // 방 private Long roomId; + + // 대기 private Long userId; // 대기자 userId private String nickname; // 대기자 이름 + private String imageUrl; // 대기자 이미지url private Boolean isManager; // 방장 여부 + + // 입장 + private Boolean isEnter; // 입장 여부 private LocalDateTime createdTime; } diff --git a/src/main/java/com/sajang/devracebackend/response/ResponseCode.java b/src/main/java/com/sajang/devracebackend/response/ResponseCode.java index ae45344..1bca42b 100644 --- a/src/main/java/com/sajang/devracebackend/response/ResponseCode.java +++ b/src/main/java/com/sajang/devracebackend/response/ResponseCode.java @@ -31,6 +31,7 @@ public enum ResponseCode { // Room 성공 응답 CREATED_ROOM(StatusItem.CREATED, MessageItem.CREATED_ROOM), READ_ROOM(StatusItem.OK, MessageItem.READ_ROOM), + UPDATE_ROOM(StatusItem.NO_CONTENT, MessageItem.UPDATE_ROOM), // Room 실패 응답 NOT_FOUND_ROOM(StatusItem.NOT_FOUND, MessageItem.NOT_FOUND_ROOM), diff --git a/src/main/java/com/sajang/devracebackend/response/responseitem/MessageItem.java b/src/main/java/com/sajang/devracebackend/response/responseitem/MessageItem.java index 27a66b4..2f707bd 100644 --- a/src/main/java/com/sajang/devracebackend/response/responseitem/MessageItem.java +++ b/src/main/java/com/sajang/devracebackend/response/responseitem/MessageItem.java @@ -16,6 +16,7 @@ public class MessageItem { // < Room > public static final String CREATED_ROOM = "SUCCESS - 방 생성 성공"; public static final String READ_ROOM = "SUCCESS - 방 조회 성공"; + public static final String UPDATE_ROOM = "SUCCESS - 방 정보 수정 성공"; public static final String NOT_FOUND_ROOM = "ERROR - 존재하지 않는 방 조회 에러"; public static final String BAD_REQUEST_ROOM = "ERROR - 잘못된 방 요청 에러"; diff --git a/src/main/java/com/sajang/devracebackend/service/RoomService.java b/src/main/java/com/sajang/devracebackend/service/RoomService.java index 64af392..99b3ef5 100644 --- a/src/main/java/com/sajang/devracebackend/service/RoomService.java +++ b/src/main/java/com/sajang/devracebackend/service/RoomService.java @@ -4,14 +4,11 @@ import com.sajang.devracebackend.dto.problem.ProblemSaveRequestDto; import com.sajang.devracebackend.dto.room.RoomCheckStateResponseDto; import com.sajang.devracebackend.dto.room.RoomSaveResponseDto; -import com.sajang.devracebackend.dto.room.RoomWaitRequestDto; -import com.sajang.devracebackend.dto.room.RoomWaitResponseDto; import java.io.IOException; public interface RoomService { Room findRoom(Long roomId); RoomSaveResponseDto createRoom(ProblemSaveRequestDto problemSaveRequestDto) throws IOException; - RoomWaitResponseDto userWaitRoom(RoomWaitRequestDto roomWaitRequestDto); RoomCheckStateResponseDto checkState(Long roomId); } diff --git a/src/main/java/com/sajang/devracebackend/service/UserRoomService.java b/src/main/java/com/sajang/devracebackend/service/UserRoomService.java index 8f63016..3861239 100644 --- a/src/main/java/com/sajang/devracebackend/service/UserRoomService.java +++ b/src/main/java/com/sajang/devracebackend/service/UserRoomService.java @@ -2,14 +2,17 @@ import com.sajang.devracebackend.domain.Room; import com.sajang.devracebackend.domain.User; -import com.sajang.devracebackend.dto.room.RoomEnterRequestDto; +import com.sajang.devracebackend.dto.room.RoomWaitRequestDto; +import com.sajang.devracebackend.dto.room.RoomWaitResponseDto; import com.sajang.devracebackend.dto.userroom.UserPassRequestDto; import com.sajang.devracebackend.dto.userroom.RoomCheckAccessResponseDto; import com.sajang.devracebackend.dto.userroom.SolvingPageResponseDto; public interface UserRoomService { void createUserRoom(User user, Room room); - void usersEnterRoom(Long roomId, RoomEnterRequestDto roomEnterRequestDto); + RoomWaitResponseDto userWaitRoom(RoomWaitRequestDto roomWaitRequestDto); + void usersEnterRoom(Long roomId); + void userStopWaitRoom(Long roomId); SolvingPageResponseDto loadSolvingPage(Long roomId); RoomCheckAccessResponseDto checkAccess(Long roomId); void passSolvingProblem(Long roomId, UserPassRequestDto userPassRequestDto); diff --git a/src/main/java/com/sajang/devracebackend/service/impl/RoomServiceImpl.java b/src/main/java/com/sajang/devracebackend/service/impl/RoomServiceImpl.java index 8fc6010..2761702 100644 --- a/src/main/java/com/sajang/devracebackend/service/impl/RoomServiceImpl.java +++ b/src/main/java/com/sajang/devracebackend/service/impl/RoomServiceImpl.java @@ -6,31 +6,31 @@ import com.sajang.devracebackend.dto.problem.ProblemSaveRequestDto; import com.sajang.devracebackend.dto.room.RoomCheckStateResponseDto; import com.sajang.devracebackend.dto.room.RoomSaveResponseDto; -import com.sajang.devracebackend.dto.room.RoomWaitRequestDto; -import com.sajang.devracebackend.dto.room.RoomWaitResponseDto; -import com.sajang.devracebackend.repository.ProblemRepository; -import com.sajang.devracebackend.repository.RoomRepository; +import com.sajang.devracebackend.dto.user.UserResponseDto; +import com.sajang.devracebackend.repository.*; import com.sajang.devracebackend.response.exception.exception404.NoSuchRoomException; import com.sajang.devracebackend.service.ProblemService; import com.sajang.devracebackend.service.RoomService; -import com.sajang.devracebackend.service.UserService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.nio.ByteBuffer; -import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class RoomServiceImpl implements RoomService { - private final UserService userService; private final ProblemService problemService; - private final ProblemRepository problemRepository; + private final UserRepository userRepository; private final RoomRepository roomRepository; + private final ProblemRepository problemRepository; @Transactional(readOnly = true) @@ -69,27 +69,34 @@ public RoomSaveResponseDto createRoom(ProblemSaveRequestDto problemSaveRequestDt return roomSaveResponseDto; } - @Transactional - @Override - public RoomWaitResponseDto userWaitRoom(RoomWaitRequestDto roomWaitRequestDto) { - User user = userService.findUser(roomWaitRequestDto.getUserId()); - RoomWaitResponseDto roomWaitResponseDto = RoomWaitResponseDto.builder() - .roomId(roomWaitRequestDto.getRoomId()) - .userId(roomWaitRequestDto.getUserId()) - .nickname(user.getNickname()) - .isManager(roomWaitRequestDto.getIsManager()) - .createdTime(LocalDateTime.now()) // 시간을 수동으로 직접 넣어줌. - .build(); - - return roomWaitResponseDto; - } - @Transactional(readOnly = true) @Override public RoomCheckStateResponseDto checkState(Long roomId) { Room room = findRoom(roomId); + List waitUserIdList = room.getWaiting(); + List waitUserList = userRepository.findByIdIn(waitUserIdList); + List userResponseDtoList = waitUserList.stream() + .map(UserResponseDto::new) + .collect(Collectors.toList()); + + List sortedUserResponseDtoList = new ArrayList<>(); + if(userResponseDtoList.size() > 1) { + // 방장인 맨앞 인덱스를 제외하고 나머지 인덱스들을 정렬. + sortedUserResponseDtoList.addAll(userResponseDtoList.subList(1, userResponseDtoList.size()).stream() + .sorted(Comparator.comparing(UserResponseDto::getNickname) + .thenComparing(UserResponseDto::getCreatedTime)) // nickname으로 먼저 오름차순 정렬 후, createdTime으로 오름차순 정렬. + .collect(Collectors.toList())); + // 방장을 정렬된 리스트의 맨앞에 추가. + sortedUserResponseDtoList.add(0, userResponseDtoList.get(0)); + } + else { + sortedUserResponseDtoList = userResponseDtoList; + } + RoomCheckStateResponseDto roomCheckStateResponseDto = RoomCheckStateResponseDto.builder() .roomState(room.getRoomState()) + .link(room.getLink()) + .userResponseDtoList(sortedUserResponseDtoList) .build(); return roomCheckStateResponseDto; diff --git a/src/main/java/com/sajang/devracebackend/service/impl/UserRoomServiceImpl.java b/src/main/java/com/sajang/devracebackend/service/impl/UserRoomServiceImpl.java index 4112124..e5eb433 100644 --- a/src/main/java/com/sajang/devracebackend/service/impl/UserRoomServiceImpl.java +++ b/src/main/java/com/sajang/devracebackend/service/impl/UserRoomServiceImpl.java @@ -6,7 +6,8 @@ import com.sajang.devracebackend.domain.enums.MessageType; import com.sajang.devracebackend.domain.enums.RoomState; import com.sajang.devracebackend.domain.mapping.UserRoom; -import com.sajang.devracebackend.dto.room.RoomEnterRequestDto; +import com.sajang.devracebackend.dto.room.RoomWaitRequestDto; +import com.sajang.devracebackend.dto.room.RoomWaitResponseDto; import com.sajang.devracebackend.dto.userroom.UserPassRequestDto; import com.sajang.devracebackend.dto.userroom.RoomCheckAccessResponseDto; import com.sajang.devracebackend.dto.userroom.SolvingPageResponseDto; @@ -48,32 +49,55 @@ public void createUserRoom(User user, Room room) { @Transactional @Override - public void usersEnterRoom(Long roomId, RoomEnterRequestDto roomEnterRequestDto) { - User managerUser = userService.findLoginUser(); // 방장 = 로그인된 사용자 + public RoomWaitResponseDto userWaitRoom(RoomWaitRequestDto roomWaitRequestDto) { + User user = userService.findUser(roomWaitRequestDto.getUserId()); + Room room = roomService.findRoom(roomWaitRequestDto.getRoomId()); + + // 입장 + if(roomWaitRequestDto.getIsManager() == true && roomWaitRequestDto.getIsEnter() == true) { // 방 동시 입장 시작 (방장만 클릭 가능) + usersEnterRoom(roomWaitRequestDto.getRoomId()); + } + + // 대기 + room.addWaiting(roomWaitRequestDto.getRoomId(), roomWaitRequestDto.getIsManager()); + RoomWaitResponseDto roomWaitResponseDto = RoomWaitResponseDto.builder() + .roomId(roomWaitRequestDto.getRoomId()) + .userId(roomWaitRequestDto.getUserId()) + .nickname(user.getNickname()) + .imageUrl(user.getImageUrl()) + .isManager(roomWaitRequestDto.getIsManager()) + .isEnter(roomWaitRequestDto.getIsEnter()) + .createdTime(LocalDateTime.now()) // 시간을 수동으로 직접 넣어줌. + .build(); + + return roomWaitResponseDto; + } + + @Transactional + @Override + public void usersEnterRoom(Long roomId) { Room room = roomService.findRoom(roomId); - List userIdList = roomEnterRequestDto.getUserIdList(); + List waitUserIdList = room.getWaiting(); + List waitUserList = userRepository.findByIdIn(waitUserIdList); + User managerUser = waitUserList.get(0); // 방장 - List userList = userRepository.findByIdIn(userIdList); - List userRooms = userList.stream() + List userRooms = waitUserList.stream() .map(user -> UserRoom.UserRoomSaveBuilder() .user(user) .room(room) .build()) .collect(Collectors.toList()); - userRooms.add(UserRoom.UserRoomSaveBuilder() - .user(managerUser) - .room(room) - .build()); // UserRoom 한번에 저장 (여러번 DB에 접근하는것을 방지.) userRoomRepository.saveAll(userRooms); // Room RoomState=START로 수정 room.updateRoomState(RoomState.START); + room.deleteWaiting(null, true); // 대기자 목록 모두 비우기. String message = null; - if(userList.size() == 0) message = "'" + managerUser.getNickname() + "'님이 방에 참가하였습니다."; - else message = "'" + managerUser.getNickname() + "'님 외 " + userList.size() + "명이 방에 참가하였습니다."; + if(waitUserList.size() == 1) message = "'" + managerUser.getNickname() + "'님이 방에 참가하였습니다."; + else message = "'" + managerUser.getNickname() + "'님 외 " + (waitUserList.size()-1) + "명이 방에 참가하였습니다."; Chat chat = Chat.ChatSaveBuilder() .roomId(roomId) @@ -88,6 +112,15 @@ public void usersEnterRoom(Long roomId, RoomEnterRequestDto roomEnterRequestDto) chatRepository.save(chat); } + @Transactional + @Override + public void userStopWaitRoom(Long roomId) { + User loginUser = userService.findLoginUser(); + Room room = roomService.findRoom(roomId); + + room.deleteWaiting(loginUser.getId(), false); + } + @Transactional(readOnly = true) @Override public SolvingPageResponseDto loadSolvingPage(Long roomId) { @@ -138,12 +171,7 @@ public void passSolvingProblem(Long roomId, UserPassRequestDto userPassRequestDt userRoom.updateIsPass(userPassRequestDto.getIsPass()); } - // 밑의 랭킹 업데이트 파트는 STOMP 실시간 처리를 위하여, 주석처리 해두었음. -// if(userPassRequestDto.getIsPass() == 1) { -// room.updateRanking(user.getNickname()); // 성공시에만 닉네임 랭킹 등록. -// } - - boolean isLeaveAllUsers = userRoomRepository.findAllByRoom(room).stream() + Boolean isLeaveAllUsers = userRoomRepository.findAllByRoom(room).stream() .allMatch(users -> users.getIsLeave() == 1); // 모든 유저의 isLeave 값이 1인지 확인 if(isLeaveAllUsers == true) room.updateRoomState(RoomState.FINISH); } diff --git a/src/main/java/com/sajang/devracebackend/util/LongListConverter.java b/src/main/java/com/sajang/devracebackend/util/LongListConverter.java new file mode 100644 index 0000000..f3d519e --- /dev/null +++ b/src/main/java/com/sajang/devracebackend/util/LongListConverter.java @@ -0,0 +1,35 @@ +package com.sajang.devracebackend.util; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +@Converter +public class LongListConverter implements AttributeConverter, String> { + + private static final String SPLIT_CHAR = ","; // 구분자 설정 + + @Override + public String convertToDatabaseColumn(List attribute) { // 백엔드의 List를 String으로 변환하여 DB에 전달하는 메소드 (참고로 []괄호나 ""따옴표는 제외한채로.) + if (attribute == null || attribute.size() == 0) { + return "__null__"; // 빈 리스트를 "__null__"로 변환하여 명시. + } + return attribute.stream() + .map(String::valueOf) + .collect(Collectors.joining(SPLIT_CHAR)); // else 경우 + } + + @Override + public List convertToEntityAttribute(String dbData) { // DB의 String을 List로 변환하여 백엔드에 전달하는 메소드 + if (dbData == null || dbData.equals("__null__")) { + return new ArrayList<>(); + } + return Arrays.stream(dbData.split(SPLIT_CHAR)) + .map(Long::valueOf) + .collect(Collectors.toCollection(ArrayList::new)); // else 경우 + } +} diff --git a/submodule-backend b/submodule-backend index 006852c..5ac056d 160000 --- a/submodule-backend +++ b/submodule-backend @@ -1 +1 @@ -Subproject commit 006852ce3a20b91b964c4ec3f7379e882c820ec6 +Subproject commit 5ac056d7925d6476da4bb98fcfd8038355d0c4f3