diff --git a/src/main/java/stackpot/stackpot/todo/converter/UserTodoConverter.java b/src/main/java/stackpot/stackpot/todo/converter/UserTodoConverter.java index e52b2d76..bec224af 100644 --- a/src/main/java/stackpot/stackpot/todo/converter/UserTodoConverter.java +++ b/src/main/java/stackpot/stackpot/todo/converter/UserTodoConverter.java @@ -1,34 +1,36 @@ package stackpot.stackpot.todo.converter; +import org.springframework.stereotype.Component; import stackpot.stackpot.common.util.RoleNameMapper; import stackpot.stackpot.pot.entity.Pot; import stackpot.stackpot.todo.dto.MyPotTodoResponseDTO; - -import java.util.List; - -import org.springframework.stereotype.Component; +import stackpot.stackpot.todo.entity.enums.TodoStatus; import stackpot.stackpot.todo.entity.mapping.UserTodo; import stackpot.stackpot.user.entity.User; +import stackpot.stackpot.user.entity.enums.Role; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Component -public class UserTodoConverter{ +public class UserTodoConverter { + // ✅ 멤버 역할(Role)을 직접 받도록 변경 public MyPotTodoResponseDTO toDto( User member, + Role memberRole, // ← PotMember.roleName Pot pot, List todos, User current) { - String role = String.valueOf(member.getRole()); - String nicknameWithRole = member.getNickname() + " " + RoleNameMapper.mapRoleName(role); + String roleName = memberRole != null ? memberRole.name() : Role.UNKNOWN.name(); + String nicknameWithRole = member.getNickname() + " " + RoleNameMapper.mapRoleName(roleName); Integer notStartedCount = null; if (member.equals(current)) { notStartedCount = (int) todos.stream() - .filter(t -> t.getStatus()==stackpot.stackpot.todo.entity.enums.TodoStatus.NOT_STARTED) + .filter(t -> t.getStatus() == TodoStatus.NOT_STARTED) .count(); } @@ -42,21 +44,30 @@ public MyPotTodoResponseDTO toDto( return MyPotTodoResponseDTO.builder() .userNickname(nicknameWithRole) - .userRole(member.getRole().name()) + .userRole(roleName) // ← User.role이 아니라 PotMember.roleName 기반 .userId(member.getId()) .todoCount(notStartedCount) - .todos(details.isEmpty()? null : details) + .todos(details.isEmpty() ? null : details) .build(); } + // 필요 시: 리스트 변환에서 roleMap을 함께 받는 버전 + public List toListDtoWithRoles( + Pot pot, + List todos, + Map roleMap, + User current) { - public List toListDto(Pot pot, List todos) { Map> grouped = todos.stream() .collect(Collectors.groupingBy(UserTodo::getUser)); return grouped.entrySet().stream() - .map(e -> toDto(e.getKey(), pot, e.getValue(), e.getKey())) + .map(e -> toDto( + e.getKey(), + roleMap.getOrDefault(e.getKey(), Role.UNKNOWN), + pot, + e.getValue(), + current)) .collect(Collectors.toList()); } - -} +} \ No newline at end of file diff --git a/src/main/java/stackpot/stackpot/todo/service/UserTodoServiceImpl.java b/src/main/java/stackpot/stackpot/todo/service/UserTodoServiceImpl.java index d66a4887..da573fd2 100644 --- a/src/main/java/stackpot/stackpot/todo/service/UserTodoServiceImpl.java +++ b/src/main/java/stackpot/stackpot/todo/service/UserTodoServiceImpl.java @@ -23,6 +23,7 @@ import stackpot.stackpot.todo.repository.UserTodoRepository; import stackpot.stackpot.pot.repository.PotMemberRepository; import stackpot.stackpot.user.entity.User; +import stackpot.stackpot.user.entity.enums.Role; import java.time.LocalDateTime; import java.time.LocalTime; @@ -43,69 +44,81 @@ public class UserTodoServiceImpl implements UserTodoService { @Transactional @Override public Page getTodo(Long potId, PageRequest pageRequest) { - User user = authService.getCurrentUser(); + User current = authService.getCurrentUser(); Pot pot = potRepository.findById(potId) .orElseThrow(() -> new PotHandler(ErrorStatus.POT_NOT_FOUND)); - boolean isOwner = pot.getUser().equals(user); - boolean isMember = potMemberRepository.existsByPotAndUser(pot, user); + boolean isOwner = pot.getUser().equals(current); + boolean isMember = potMemberRepository.existsByPotAndUser(pot, current); + if (!isOwner && !isMember) throw new PotHandler(ErrorStatus.POT_FORBIDDEN); - if (!isOwner && !isMember) { - throw new PotHandler(ErrorStatus.POT_FORBIDDEN); - } + // PotMember 기준으로 전체 멤버 확보 + List allMembers = potMemberRepository.findByPotId(pot.getPotId()); - List allPotMembers = potMemberRepository.findByPotId(pot.getPotId()) - .stream() - .map(PotMember::getUser) - .collect(Collectors.toList()); + // 현재 사용자 우선 정렬 + allMembers.sort((m1, m2) -> { + boolean a = m1.getUser().equals(current); + boolean b = m2.getUser().equals(current); + return a == b ? 0 : (a ? -1 : 1); + }); - allPotMembers.sort((u1, u2) -> u1.equals(user) ? -1 : (u2.equals(user) ? 1 : 0)); + int total = allMembers.size(); + int start = (int) pageRequest.getOffset(); + int end = Math.min(start + pageRequest.getPageSize(), total); + if (start >= total) return new PageImpl<>(List.of(), pageRequest, total); - int totalUsers = allPotMembers.size(); - int startIndex = (int) pageRequest.getOffset(); - int endIndex = Math.min(startIndex + pageRequest.getPageSize(), totalUsers); + // 페이징된 PotMember + List pageMembers = allMembers.subList(start, end); - if (startIndex >= totalUsers) { - return new PageImpl<>(List.of(), pageRequest, totalUsers); - } + // 쿼리용 사용자 리스트 + List pageUsers = pageMembers.stream() + .map(PotMember::getUser) + .collect(Collectors.toList()); - List pagedUsers = allPotMembers.subList(startIndex, endIndex); + // 사용자별 역할(Role) 매핑 (멤버 역할) + Map roleMap = pageMembers.stream() + .collect(Collectors.toMap(PotMember::getUser, + pm -> pm.getRoleName() != null ? pm.getRoleName() : Role.UNKNOWN)); - List todos = myPotRepository.findByPotAndUsers(pot, pagedUsers); + // Todo 조회 + List todos = myPotRepository.findByPotAndUsers(pot, pageUsers); + // 5AM 컷 필터 LocalDateTime now = LocalDateTime.now(); LocalDateTime todayAt5AM = LocalDateTime.of(now.toLocalDate(), LocalTime.of(5, 0)); LocalDateTime yesterdayAt5AM = todayAt5AM.minusDays(1); - List filteredTodos = todos.stream() - .filter(todo -> todo.getCreatedAt().isAfter(yesterdayAt5AM)) + List filtered = todos.stream() + .filter(t -> t.getCreatedAt().isAfter(yesterdayAt5AM)) .collect(Collectors.toList()); - Map> groupedByUser = filteredTodos.stream() + Map> grouped = filtered.stream() .collect(Collectors.groupingBy(UserTodo::getUser)); - List responseList = pagedUsers.stream() - .map(member -> userTodoConverter.toDto( - member, + // Converter에 멤버 역할(Role) 전달 + List response = pageMembers.stream() + .map(pm -> userTodoConverter.toDto( + pm.getUser(), + roleMap.getOrDefault(pm.getUser(), Role.UNKNOWN), pot, - groupedByUser.getOrDefault(member, List.of()), - user)) + grouped.getOrDefault(pm.getUser(), List.of()), + current)) .collect(Collectors.toList()); - return new PageImpl<>(responseList, pageRequest, totalUsers); + return new PageImpl<>(response, pageRequest, total); } @Transactional @Override public List updateTodos(Long potId, List reqs) { - User user = authService.getCurrentUser(); + User current = authService.getCurrentUser(); Pot pot = potRepository.findById(potId) .orElseThrow(() -> new PotHandler(ErrorStatus.POT_NOT_FOUND)); - List existing = myPotRepository.findByPot_PotIdAndUser(potId, user); + List existing = myPotRepository.findByPot_PotIdAndUser(potId, current); Map existMap = existing.stream() .collect(Collectors.toMap(UserTodo::getTodoId, t -> t)); @@ -122,7 +135,7 @@ public List updateTodos(Long potId, List updateTodos(Long potId, List pm.getUser().equals(current)) + .map(PotMember::getRoleName) + .filter(Objects::nonNull) + .findFirst() + .orElse(Role.UNKNOWN); + + Map> grouped = toSave.stream() + .collect(Collectors.groupingBy(UserTodo::getUser)); + + return grouped.entrySet().stream() + .map(e -> userTodoConverter.toDto( + e.getKey(), + currentRole, // ← 멤버 역할 전달 + pot, + e.getValue(), + current)) + .collect(Collectors.toList()); } @Transactional @Override public List completeTodo(Long potId, Long todoId) { - User user = authService.getCurrentUser(); + User current = authService.getCurrentUser(); - potRepository.findById(potId) + Pot pot = potRepository.findById(potId) .orElseThrow(() -> new PotHandler(ErrorStatus.POT_NOT_FOUND)); UserTodo todo = myPotRepository.findByTodoIdAndPot_PotId(todoId, potId) .orElseThrow(() -> new PotHandler(ErrorStatus.USER_TODO_NOT_FOUND)); - if (!todo.getUser().equals(user)) throw new PotHandler(ErrorStatus.USER_TODO_UNAUTHORIZED); + + if (!todo.getUser().equals(current)) { + throw new PotHandler(ErrorStatus.USER_TODO_UNAUTHORIZED); + } todo.setStatus(todo.getStatus() == TodoStatus.COMPLETED ? TodoStatus.NOT_STARTED : TodoStatus.COMPLETED); myPotRepository.save(todo); List all = myPotRepository.findByPot_PotId(potId); - return userTodoConverter.toListDto(todo.getPot(), all); + + // ✅ User → Role 매핑 (멤버 역할) + Map roleMap = potMemberRepository.findByPotId(potId).stream() + .collect(Collectors.toMap(PotMember::getUser, + pm -> pm.getRoleName() != null ? pm.getRoleName() : Role.UNKNOWN)); + + return userTodoConverter.toListDtoWithRoles(pot, all, roleMap, current); } } diff --git a/src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java b/src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java index d68063ef..b53b5e18 100644 --- a/src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java +++ b/src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java @@ -270,7 +270,7 @@ public TokenServiceResponse saveNickname(String nickname) { .nickname(nickname) .userType(UserType.USER) .interests(tempUser.getInterest()) - .userIntroduction(tempUser.getRole() + "에 관심있는 " + nickname + " " + Role.toVegetable(String.valueOf(tempUser.getRole())) + "입니다.") + .userIntroduction(tempUser.getRole() + "에 관심있는 " + nickname + " " + "새싹입니다.") .userTemperature(33) .kakaoId(tempUser.getKakaoId()) .provider(tempUser.getProvider())