Skip to content

Commit

Permalink
Merge pull request #46 from MAKAR-iOS/feat/#45
Browse files Browse the repository at this point in the history
[Feat/#45] 로그아웃 & 최근 경로 기능 구현
  • Loading branch information
chaeyeon0130 authored Jul 30, 2024
2 parents 75c8c31 + 0a4a139 commit a43fb7d
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/main/java/makar/dev/common/status/SuccessStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public enum SuccessStatus {
_FAVORITE_ROUTE_LIST_GET(HttpStatus.OK, 200, "즐겨찾는 경로 리스트 조회가 완료되었습니다."),
_FAVORITE_ROUTE_POST(HttpStatus.OK, 200, "즐겨찾는 경로 추가가 완료되었습니다."),
_FAVORITE_ROUTE_DELETE(HttpStatus.OK, 200, "즐겨찾는 경로 삭제가 완료되었습니다."),
_RECENT_ROUTE_LIST_GET(HttpStatus.OK, 200, "최근 경로 리스트 조회가 완료되었습니다."),
_RECENT_ROUTE_DELETE(HttpStatus.OK, 200, "최근 경로 리스트에서 특정 경로가 삭제 완료되었습니다."),
_All_RECENT_ROUTE_DELETE(HttpStatus.OK, 200, "최근 경로 리스트에서 모든 경로가 삭제 완료되었습니다."),


// NotiController
_MAKAR_NOTI_POST(HttpStatus.OK, 200, "막차 알림 추가가 완료되었습니다."),
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/makar/dev/controller/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import makar.dev.common.response.ApiResponse;
import makar.dev.common.security.dto.TokenDto;
import makar.dev.common.status.SuccessStatus;
import makar.dev.dto.request.AuthRequest;
import makar.dev.dto.response.AuthResponse;
import makar.dev.service.AuthService;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -39,4 +41,14 @@ public ApiResponse<AuthResponse.SignDto> signIn(@RequestBody AuthRequest.SignInR

return ApiResponse.SuccessResponse(SuccessStatus._OK, response);
}

@Operation(
summary = "로그아웃",
description = "로그아웃 후 DB에 저장하고 있는 리프레쉬 토큰을 삭제합니다."
)
@PostMapping("/sign-out")
public ApiResponse<String> signOut(@AuthenticationPrincipal TokenDto tokenDto) {
authService.signOut(tokenDto.getUserId());
return ApiResponse.SuccessResponse(SuccessStatus._OK);
}
}
30 changes: 30 additions & 0 deletions src/main/java/makar/dev/controller/RouteController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import makar.dev.common.response.ApiResponse;
import makar.dev.common.security.dto.TokenDto;
import makar.dev.common.status.SuccessStatus;
import makar.dev.dto.response.RouteResponse;
import makar.dev.service.RouteService;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
Expand Down Expand Up @@ -81,4 +82,33 @@ public ApiResponse addFavoriteRoute(@AuthenticationPrincipal TokenDto tokenDto,
public ApiResponse deleteFavoriteRoute(@AuthenticationPrincipal TokenDto tokenDto, @PathVariable(name = "routeId") Long routeId) {
return ApiResponse.SuccessResponse(SuccessStatus._FAVORITE_ROUTE_DELETE, routeService.deleteFavoriteRoute(tokenDto, routeId));
}

@Operation(
summary = "최근 경로 리스트 조회",
description = "최근에 설정된 경로 최대 5개를 조회합니다."
)
@GetMapping("/recent")
public ApiResponse<RouteResponse.RecentRouteListDto> getAllRecentRoute(@AuthenticationPrincipal TokenDto tokenDto) {
return ApiResponse.SuccessResponse(SuccessStatus._RECENT_ROUTE_LIST_GET, routeService.getAllRecentRoute(tokenDto.getUserId()));
}

@Operation(
summary = "특정 최근 경로 삭제",
description = "최근 경로 리스트에서 특정 경로가 삭제됩니다."
)
@DeleteMapping("/recent/{route-id}")
public ApiResponse deleteRecentRoute(@AuthenticationPrincipal TokenDto tokenDto, @PathVariable("route-id") Long routeId) {
routeService.deleteRecentRoute(tokenDto.getUserId(), routeId);
return ApiResponse.SuccessResponse(SuccessStatus._RECENT_ROUTE_DELETE);
}

@Operation(
summary = "모든 최근 경로 삭제",
description = "최근 경로 리스트에서 모든 경로가 삭제됩니다."
)
@DeleteMapping("/recent/all")
public ApiResponse deleteAllRecentRoute(@AuthenticationPrincipal TokenDto tokenDto) {
routeService.deleteAllRecentRoute(tokenDto.getUserId());
return ApiResponse.SuccessResponse(SuccessStatus._All_RECENT_ROUTE_DELETE);
}
}
18 changes: 18 additions & 0 deletions src/main/java/makar/dev/converter/RouteConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import makar.dev.dto.response.RouteResponse;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class RouteConverter {

Expand Down Expand Up @@ -67,6 +69,22 @@ public static RouteResponse.BriefRouteDto toBriefRouteDto(Route route){
.build();
}

public static List<RouteResponse.BriefRouteDtoWithRouteId> toBriefRouteDtoList(List<Route> routes){
routes.sort(Comparator.comparingInt(Route::getRecentOrder).reversed());

return routes.stream()
.map(route ->
RouteResponse.BriefRouteDtoWithRouteId.builder()
.routeId(route.getRouteId())
.sourceStationName(route.getSourceStation().getStationName())
.sourceLineNum(route.getSourceStation().getLineNum())
.destinationStationName(route.getDestinationStation().getStationName())
.destinationLineNum(route.getDestinationStation().getLineNum())
.build()
)
.collect(Collectors.toList());
}

public static SubRoute toSubRoute(RouteSearchResponse.SubPath subPath) {
RouteSearchResponse.Lane lane = subPath.getLane().get(0);

Expand Down
7 changes: 7 additions & 0 deletions src/main/java/makar/dev/domain/Route.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,15 @@ public class Route {
@Column(nullable = false)
private List<SubRoute> subRouteList;

// 최근 경로 리스트 내 순서
@Column(name = "recent_order")
private int recentOrder;

public void updateSchedule(Schedule schedule){
this.schedule = schedule;
}

public void setRecentOrder(int recentOrder) {
this.recentOrder = recentOrder;
}
}
35 changes: 34 additions & 1 deletion src/main/java/makar/dev/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,40 @@ public User(String userName){
public boolean isFavoriteSchoolStationExist(){return this.favoriteSchoolStation != null;}
public void addNotiList(Noti noti){this.notiList.add(noti);}
public void addFavoriteRoute(Route route){this.favoriteRouteList.add(favoriteRouteList.size(), route);}

public void addRecentRouteList(Route route) {
int maxOrder = -1;
Route existingRoute = null;

// 동일한 routeId를 가진 Route가 이미 최근 경로 리스트에 존재하는지 확인
for (Route r : this.recentRouteList) {
if (r.getRouteId().equals(route.getRouteId())) {
existingRoute = r;
}
if (r.getRecentOrder() > maxOrder) {
maxOrder = r.getRecentOrder();
}
}

if (existingRoute != null) {
// 이미 리스트에 존재하는 경우 recentOrder만 수정
existingRoute.setRecentOrder(maxOrder + 1);
} else {
// 최근 경로 리스트 사이즈 최대 5개 유지
if (this.recentRouteList.size() >= 5) {
this.recentRouteList.remove(0);
}

// 새로운 Route일 경우 리스트의 마지막에 추가
route.setRecentOrder(maxOrder + 1);
this.recentRouteList.add(route);
}
}
public void removeRecentRouteList(Route route) {
this.recentRouteList.remove(route);
}
public void clearRecentRouteList() {
this.recentRouteList.clear();
}

@Builder
public User(String id, String password, String email, String username) {
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/makar/dev/dto/response/RouteResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ public static class BriefRouteDto {
private String destinationLineNum;
}

@Data @Builder
@NoArgsConstructor
@AllArgsConstructor
public static class BriefRouteDtoWithRouteId {
private Long routeId;
private String sourceStationName;
private String sourceLineNum;
private String destinationStationName;
private String destinationLineNum;
}

@Data
@Builder
@NoArgsConstructor
Expand Down Expand Up @@ -84,4 +95,11 @@ public static class SubRouteDetailDto {
public static class SearchRouteDto {
private List<RouteDto> routeDtoList;
}

@Data @Builder
@NoArgsConstructor
@AllArgsConstructor
public static class RecentRouteListDto {
private List<BriefRouteDtoWithRouteId> recentRouteList;
}
}
6 changes: 6 additions & 0 deletions src/main/java/makar/dev/service/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,10 @@ public AuthResponse.SignDto signIn(String id, String password) {

return AuthConverter.toSignDto(accessToken, refreshToken);
}

@Transactional
public void signOut(Long userId) {
User user = userService.findUserById(userId);
user.setRefreshToken(null);
}
}
26 changes: 26 additions & 0 deletions src/main/java/makar/dev/service/RouteService.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ public RouteResponse.RouteDto setRoute(Long userId, Long routeId){

user.addNotiList(makarNoti);
user.addNotiList(getOffNoti);

// 해당 경로, 유저의 최근 경로 리스트에 저장
user.addRecentRouteList(route);
return RouteConverter.toRouteDto(route);
}

Expand Down Expand Up @@ -311,4 +314,27 @@ private String getDestinationTime(String sourceTime, int totalTime) {
}
return sdf.format(calendar.getTime());
}

// 최근 경로 리스트 조회하기
public RouteResponse.RecentRouteListDto getAllRecentRoute(Long userId) {
User user = findUserById(userId);
return RouteResponse.RecentRouteListDto.builder()
.recentRouteList(RouteConverter.toBriefRouteDtoList(user.getRecentRouteList()))
.build();
}

// 특정 최근 경로 삭제
@Transactional
public void deleteRecentRoute(Long userId, Long routeId) {
User user = findUserById(userId);
Route route = findRouteById(routeId);
user.removeRecentRouteList(route);
}

// 모든 최근 경로 삭제
@Transactional
public void deleteAllRecentRoute(Long userId) {
User user = findUserById(userId);
user.clearRecentRouteList();
}
}
2 changes: 1 addition & 1 deletion src/main/java/makar/dev/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public UserResponse.HomeDto getHome(TokenDto tokenDto) {
return UserConverter.toHomeDto(isRouteSet, user.getNotiList());
}

private User findUserById(Long userId){
public User findUserById(Long userId){
return userRepository.findById(userId)
.orElseThrow(() -> new GeneralException(ErrorStatus.NOT_FOUND_USER));
}
Expand Down

0 comments on commit a43fb7d

Please sign in to comment.