Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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<UserTodo> 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();
}

Expand All @@ -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<MyPotTodoResponseDTO> toListDtoWithRoles(
Pot pot,
List<UserTodo> todos,
Map<User, Role> roleMap,
User current) {

public List<MyPotTodoResponseDTO> toListDto(Pot pot, List<UserTodo> todos) {
Map<User, List<UserTodo>> 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());
}

}
}
112 changes: 76 additions & 36 deletions src/main/java/stackpot/stackpot/todo/service/UserTodoServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -43,69 +44,81 @@ public class UserTodoServiceImpl implements UserTodoService {
@Transactional
@Override
public Page<MyPotTodoResponseDTO> 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<PotMember> allMembers = potMemberRepository.findByPotId(pot.getPotId());

List<User> 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<PotMember> pageMembers = allMembers.subList(start, end);

if (startIndex >= totalUsers) {
return new PageImpl<>(List.of(), pageRequest, totalUsers);
}
// 쿼리용 사용자 리스트
List<User> pageUsers = pageMembers.stream()
.map(PotMember::getUser)
.collect(Collectors.toList());

List<User> pagedUsers = allPotMembers.subList(startIndex, endIndex);
// 사용자별 역할(Role) 매핑 (멤버 역할)
Map<User, Role> roleMap = pageMembers.stream()
.collect(Collectors.toMap(PotMember::getUser,
pm -> pm.getRoleName() != null ? pm.getRoleName() : Role.UNKNOWN));

List<UserTodo> todos = myPotRepository.findByPotAndUsers(pot, pagedUsers);
// Todo 조회
List<UserTodo> 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<UserTodo> filteredTodos = todos.stream()
.filter(todo -> todo.getCreatedAt().isAfter(yesterdayAt5AM))
List<UserTodo> filtered = todos.stream()
.filter(t -> t.getCreatedAt().isAfter(yesterdayAt5AM))
.collect(Collectors.toList());

Map<User, List<UserTodo>> groupedByUser = filteredTodos.stream()
Map<User, List<UserTodo>> grouped = filtered.stream()
.collect(Collectors.groupingBy(UserTodo::getUser));

List<MyPotTodoResponseDTO> responseList = pagedUsers.stream()
.map(member -> userTodoConverter.toDto(
member,
// Converter에 멤버 역할(Role) 전달
List<MyPotTodoResponseDTO> 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<MyPotTodoResponseDTO> updateTodos(Long potId, List<MyPotTodoUpdateRequestDTO> reqs) {
User user = authService.getCurrentUser();
User current = authService.getCurrentUser();

Pot pot = potRepository.findById(potId)
.orElseThrow(() -> new PotHandler(ErrorStatus.POT_NOT_FOUND));

List<UserTodo> existing = myPotRepository.findByPot_PotIdAndUser(potId, user);
List<UserTodo> existing = myPotRepository.findByPot_PotIdAndUser(potId, current);
Map<Long, UserTodo> existMap = existing.stream()
.collect(Collectors.toMap(UserTodo::getTodoId, t -> t));

Expand All @@ -122,7 +135,7 @@ public List<MyPotTodoResponseDTO> updateTodos(Long potId, List<MyPotTodoUpdateRe
toSave.add(e);
} else {
toSave.add(UserTodo.builder()
.user(user).pot(pot)
.user(current).pot(pot)
.content(r.getContent())
.status(r.getStatus() != null ? r.getStatus() : TodoStatus.NOT_STARTED)
.build());
Expand All @@ -135,27 +148,54 @@ public List<MyPotTodoResponseDTO> updateTodos(Long potId, List<MyPotTodoUpdateRe
myPotRepository.saveAll(toSave);
myPotRepository.deleteAll(toDelete);

return userTodoConverter.toListDto(pot, toSave);
// ✅ current 사용자의 멤버 역할(Role) 구해 전달
Role currentRole = potMemberRepository.findByPotId(potId).stream()
.filter(pm -> pm.getUser().equals(current))
.map(PotMember::getRoleName)
.filter(Objects::nonNull)
.findFirst()
.orElse(Role.UNKNOWN);

Map<User, List<UserTodo>> 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<MyPotTodoResponseDTO> 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<UserTodo> all = myPotRepository.findByPot_PotId(potId);
return userTodoConverter.toListDto(todo.getPot(), all);

// ✅ User → Role 매핑 (멤버 역할)
Map<User, Role> 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);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down