-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
39 changed files
with
1,482 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
...-api/src/main/java/com/heachi/housework/api/controller/housework/todo/TodoController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.heachi.housework.api.controller.housework.todo; | ||
|
||
import com.heachi.admin.common.response.JsonResult; | ||
import com.heachi.external.clients.auth.response.UserInfoResponse; | ||
import com.heachi.housework.api.service.auth.AuthExternalService; | ||
import com.heachi.housework.api.service.housework.todo.TodoService; | ||
import com.heachi.housework.api.service.housework.todo.request.TodoSelectRequest; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.time.LocalDate; | ||
|
||
@Slf4j | ||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/housework/todo") | ||
public class TodoController { | ||
|
||
private final AuthExternalService authExternalService; | ||
private final TodoService todoService; | ||
|
||
// Todo List 가져오기 | ||
@GetMapping("/{groupId}") | ||
public JsonResult<?> selectTodo(@RequestHeader(name = "Authorization") String authorization, | ||
@PathVariable(name = "groupId") Long groupId, | ||
@RequestParam(value = "date") LocalDate date) { | ||
UserInfoResponse userInfo = authExternalService.userAuthenticateAndGroupMatch(authorization, groupId); | ||
|
||
return JsonResult.successOf(todoService.cachedSelectTodo( | ||
TodoSelectRequest.builder().groupId(groupId).date(date).build())); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
...ousework-api/src/main/java/com/heachi/housework/api/service/auth/AuthExternalService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.heachi.housework.api.service.auth; | ||
|
||
import com.heachi.admin.common.exception.ExceptionMessage; | ||
import com.heachi.admin.common.exception.auth.AuthException; | ||
import com.heachi.admin.common.exception.group.member.GroupMemberException; | ||
import com.heachi.admin.common.response.JsonResult; | ||
import com.heachi.external.clients.auth.AuthClients; | ||
import com.heachi.external.clients.auth.response.UserInfoResponse; | ||
import com.heachi.mysql.define.group.member.repository.GroupMemberRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Slf4j | ||
@Service | ||
@RequiredArgsConstructor | ||
public class AuthExternalService { | ||
|
||
private final AuthClients authClients; | ||
private final GroupMemberRepository groupMemberRepository; | ||
|
||
// Auth 서버에 인증 요청을 보낸다. | ||
public UserInfoResponse userAuthenticate(String authorization) { | ||
JsonResult<UserInfoResponse> jsonResult = authClients.getUserInfo(authorization).block(); // Mono 객체이므로 Block | ||
|
||
if (jsonResult.getResCode() != 200) { | ||
log.warn(">>>> 유저 인증에 실패했습니다."); | ||
|
||
throw new AuthException(ExceptionMessage.AUTH_SERVER_NOT_RESPOND); | ||
} | ||
|
||
return jsonResult.getResObj(); | ||
} | ||
|
||
// Auth 서버에 인증 요청을 보낸 후 가져온 정보로 해당 그룹원인지 판별한다. | ||
public UserInfoResponse userAuthenticateAndGroupMatch(String authorization, Long groupId) { | ||
JsonResult<UserInfoResponse> jsonResult = authClients.getUserInfo(authorization).block(); // Mono 객체이므로 Block | ||
|
||
if (jsonResult.getResCode() != 200) { | ||
log.warn(">>>> 유저 인증에 실패했습니다."); | ||
|
||
throw new AuthException(ExceptionMessage.AUTH_SERVER_NOT_RESPOND); | ||
} | ||
|
||
if (!groupMemberRepository.existsGroupMemberByUserEmailAndGroupInfoId( | ||
jsonResult.getResObj().getEmail(), groupId)) { | ||
log.warn(">>>> 해당 유저[{}]는 해당 그룹[{}]의 소속이 아닙니다.", jsonResult.getResObj().getEmail(), groupId); | ||
|
||
throw new GroupMemberException(ExceptionMessage.GROUP_MEMBER_NOT_FOUND); | ||
} | ||
|
||
return jsonResult.getResObj(); | ||
} | ||
} |
114 changes: 114 additions & 0 deletions
114
...sework-api/src/main/java/com/heachi/housework/api/service/housework/todo/TodoService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package com.heachi.housework.api.service.housework.todo; | ||
|
||
import com.heachi.admin.common.utils.CachingStrategy; | ||
import com.heachi.admin.common.utils.DayOfWeekUtils; | ||
import com.heachi.housework.api.service.housework.todo.request.TodoSelectRequest; | ||
import com.heachi.housework.api.service.housework.todo.response.TodoResponse; | ||
import com.heachi.mysql.define.group.member.repository.GroupMemberRepository; | ||
import com.heachi.mysql.define.housework.info.repository.HouseworkInfoRepository; | ||
import com.heachi.mysql.define.housework.todo.HouseworkTodo; | ||
import com.heachi.mysql.define.housework.todo.repository.HouseworkTodoRepository; | ||
import com.heachi.mysql.define.user.User; | ||
import com.heachi.redis.define.housework.todo.Todo; | ||
import com.heachi.redis.define.housework.todo.TodoList; | ||
import com.heachi.redis.define.housework.todo.TodoUser; | ||
import com.heachi.redis.define.housework.todo.repository.TodoListRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.time.LocalDate; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
@Slf4j | ||
@Service | ||
@RequiredArgsConstructor | ||
@Transactional(readOnly = true) | ||
public class TodoService { | ||
|
||
private final TodoListRepository todoListRepository; | ||
|
||
private final GroupMemberRepository groupMemberRepository; | ||
private final HouseworkTodoRepository houseworkTodoRepository; | ||
private final HouseworkInfoRepository houseworkInfoRepository; | ||
|
||
public TodoList cachedSelectTodo(TodoSelectRequest request) { | ||
|
||
return CachingStrategy.cachingIfEmpty(request, | ||
(req) -> todoListRepository.findById(TodoList.makeId(req.getGroupId(), req.getDate())).orElse(null), | ||
(req) -> { | ||
List<TodoResponse> todoResponseList = selectTodo(req); | ||
|
||
TodoList todoList = caching(req, todoResponseList); | ||
log.info(">>>> [{}]의 캐싱이 완료 되었습니다.", todoList.getId()); | ||
|
||
return todoList; | ||
}, | ||
(todo) -> todo.isDirtyBit() == false); // dirtyBit가 false가 아니면 캐시 업데이트 | ||
} | ||
|
||
// GroupInfoId와 Date를 통해 Todo List 가져오기 | ||
public List<TodoResponse> selectTodo(TodoSelectRequest request) { | ||
Long groupId = request.getGroupId(); | ||
LocalDate date = request.getDate(); | ||
|
||
// Map<HOUSEWORK_INFO_ID, HOUSEWORK_TODO> | ||
Map<Long, HouseworkTodo> todoMap = houseworkTodoRepository.findByGroupInfoAndDate(groupId, date).stream() | ||
.collect(Collectors.toMap(todo -> todo.getHouseworkInfo().getId(), todo -> todo)); | ||
|
||
// 그룹의 HouseworkInfo 조회 후 필터링해서 추가해야하는 TodoList를 만든다. | ||
List<HouseworkTodo> insertTodoList = houseworkInfoRepository.findHouseworkInfoByGroupInfoId(groupId).stream() | ||
.filter(info -> !todoMap.containsKey(info.getId())) // HouseworkTodo에 이미 있는 INFO는 제외 | ||
.filter(info -> // PERIOD에 맞는 INFO 선별 | ||
switch (info.getType()) { | ||
case HOUSEWORK_PERIOD_EVERYDAY -> true; | ||
case HOUSEWORK_PERIOD_WEEK -> DayOfWeekUtils.equals(info.getWeekDate(), date); | ||
case HOUSEWORK_PERIOD_MONTH -> Arrays.asList(info.getMonthDate().split(",")).stream() | ||
.filter(d -> Integer.parseInt(d) == date.getDayOfMonth()) | ||
.findFirst().isPresent(); | ||
default -> false; | ||
}) | ||
.map(info -> HouseworkTodo.makeTodoReferInfo(info, info.getGroupInfo(), date)) | ||
.collect(Collectors.toList()); | ||
|
||
houseworkTodoRepository.saveAll(insertTodoList); // Todo 저장 | ||
|
||
// Map<GROUP_MEMBER_ID, USER> | ||
Map<Long, User> userMap = groupMemberRepository.findGroupMemberByGroupId(groupId).stream() | ||
.collect(Collectors.toMap(gm -> gm.getId(), gm -> gm.getUser())); | ||
|
||
return houseworkTodoRepository.findByGroupInfoAndDate(groupId, date).stream() // 최신 Todo 불러와 리턴 | ||
.map(todo -> TodoResponse.of(todo, userMap)) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private TodoList caching(TodoSelectRequest req, List<TodoResponse> todoResponseList) { | ||
|
||
return todoListRepository.save(TodoList.builder() // List<TodoResponse> => TodoList 후 save | ||
.groupInfoId(req.getGroupId()) | ||
.date(req.getDate()) | ||
.todoList(todoResponseList.stream() | ||
.map(todo -> Todo.builder() | ||
.id(todo.getId()) | ||
.houseworkMembers(todo.getHouseworkMembers().stream() | ||
.map(u -> TodoUser.builder() | ||
.name(u.getName()) | ||
.email(u.getEmail()) | ||
.profileImageUrl(u.getProfileImageUrl()) | ||
.build()) | ||
.collect(Collectors.toList())) | ||
.category(todo.getCategory()) | ||
.title(todo.getTitle()) | ||
.detail(todo.getDetail()) | ||
.status(todo.getStatus().name()) | ||
.date(todo.getDate()) | ||
.endTime(todo.getEndTime()) | ||
.build()) | ||
.collect(Collectors.toList())) | ||
.build()); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
.../main/java/com/heachi/housework/api/service/housework/todo/request/TodoSelectRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.heachi.housework.api.service.housework.todo.request; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
import java.time.LocalDate; | ||
|
||
@Getter | ||
public class TodoSelectRequest { | ||
|
||
Long groupId; | ||
LocalDate date; | ||
|
||
@Builder | ||
private TodoSelectRequest(Long groupId, LocalDate date) { | ||
this.groupId = groupId; | ||
this.date = date; | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
.../src/main/java/com/heachi/housework/api/service/housework/todo/response/TodoResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package com.heachi.housework.api.service.housework.todo.response; | ||
|
||
import com.heachi.mysql.define.housework.todo.HouseworkTodo; | ||
import com.heachi.mysql.define.housework.todo.constant.HouseworkTodoStatus; | ||
import com.heachi.mysql.define.user.User; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.ToString; | ||
|
||
import java.time.LocalDate; | ||
import java.time.LocalDateTime; | ||
import java.time.LocalTime; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
|
||
@Getter | ||
@ToString | ||
public class TodoResponse { | ||
|
||
private Long id; | ||
private List<TodoUser> houseworkMembers; | ||
private String category; | ||
private String title; | ||
private String detail; | ||
private Integer idx; | ||
private HouseworkTodoStatus status; | ||
private LocalDate date; | ||
private LocalTime endTime; | ||
private String verificationPhotoURL; | ||
private String verifierId; | ||
private LocalDateTime verificationTime; | ||
|
||
@Builder | ||
private TodoResponse(Long id, List<TodoUser> houseworkMembers, String category, String title, String detail, | ||
Integer idx, HouseworkTodoStatus status, LocalDate date, LocalTime endTime, | ||
String verificationPhotoURL, String verifierId, LocalDateTime verificationTime) { | ||
this.id = id; | ||
this.houseworkMembers = houseworkMembers; | ||
this.category = category; | ||
this.title = title; | ||
this.detail = detail; | ||
this.idx = idx; | ||
this.status = status; | ||
this.date = date; | ||
this.endTime = endTime; | ||
this.verificationPhotoURL = verificationPhotoURL; | ||
this.verifierId = verifierId; | ||
this.verificationTime = verificationTime; | ||
} | ||
|
||
public static TodoResponse of(HouseworkTodo todo, Map<Long, User> userMap) { | ||
|
||
return TodoResponse.builder() | ||
.id(todo.getId()) | ||
.houseworkMembers(!todo.getHouseworkMember().equals("") ? Arrays.asList(todo.getHouseworkMember().split(",")).stream() | ||
.map(Long::parseLong) | ||
.map(i -> TodoUser.of(userMap.get(i))) | ||
.collect(Collectors.toList()) : new ArrayList<>()) | ||
.category(todo.getCategory()) | ||
.title(todo.getTitle()) | ||
.detail(todo.getDetail()) | ||
.idx(todo.getIdx()) | ||
.status(todo.getStatus()) | ||
.date(todo.getDate()) | ||
.endTime(todo.getEndTime()) | ||
.verificationPhotoURL(todo.getVerificationPhotoURL()) | ||
.verifierId(todo.getVerifierId()) | ||
.verificationTime(todo.getVerificationTime()) | ||
.build(); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...-api/src/main/java/com/heachi/housework/api/service/housework/todo/response/TodoUser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.heachi.housework.api.service.housework.todo.response; | ||
|
||
import com.heachi.mysql.define.user.User; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.ToString; | ||
|
||
@Getter | ||
@ToString | ||
public class TodoUser { | ||
|
||
private String name; | ||
private String email; | ||
private String profileImageUrl; | ||
|
||
@Builder | ||
private TodoUser(String name, String email, String profileImageUrl) { | ||
this.name = name; | ||
this.email = email; | ||
this.profileImageUrl = profileImageUrl; | ||
} | ||
|
||
public static TodoUser of(User user) { | ||
|
||
return TodoUser.builder() | ||
.name(user.getName()) | ||
.email(user.getEmail()) | ||
.profileImageUrl(user.getProfileImageUrl()) | ||
.build(); | ||
} | ||
} |
Oops, something went wrong.