Skip to content

Commit

Permalink
Feat : Career 카테고리, 연도별 활동 조회 API 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
hyeonda02 committed Jul 23, 2024
1 parent 3f73775 commit 4d3a059
Show file tree
Hide file tree
Showing 15 changed files with 148 additions and 55 deletions.
Binary file removed .DS_Store
Binary file not shown.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,4 @@ out/
### VS Code ###
.vscode/


.DS_Store
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import umc.kkijuk.server.career.controller.response.CareerGroupedByResponse;
import umc.kkijuk.server.career.controller.response.CareerResponse;
import umc.kkijuk.server.career.controller.response.CareerResponseMessage;
import umc.kkijuk.server.career.controller.response.CareerStatusCode;
import umc.kkijuk.server.career.domain.Career;
import umc.kkijuk.server.career.dto.CareerRequestDto;
import umc.kkijuk.server.career.dto.CareerResponseDto;
Expand All @@ -23,23 +24,26 @@
@RequiredArgsConstructor
@RequestMapping("/career")
public class CareerController {

private final CareerService careerService;

@PostMapping("")
@Operation(summary = "활동 추가 API", description = "내 커리어 - 활동을 추가하는 API")
public CareerResponse<CareerResponseDto.CareerResultDto> create(@RequestBody @Valid CareerRequestDto.CareerDto request){
LoginUser loginUser = LoginUser.get();
Career career = careerService.createCareer(request);
return CareerResponse.success(CareerStatusCode.CREATED,
return CareerResponse.success(HttpStatus.CREATED,
CareerResponseMessage.CAREER_CREATE_SUCCESS,
CareerConverter.tocareerResultDto(career));
}

@DeleteMapping("/{careerId}")
@Operation(summary = "활동 삭제 API", description = "내 커리어 - 활동을 삭제하는 API")
@Parameter(name="careerId", description = "활동 Id, path variable 입니다.",example = "1")
public CareerResponse<Object> delete(@PathVariable Long careerId){
LoginUser loginUser = LoginUser.get();
careerService.deleteCareer(careerId);
return CareerResponse.success(CareerStatusCode.OK,
return CareerResponse.success(HttpStatus.OK,
CareerResponseMessage.CAREER_DELETE_SUCCESS,null);
}

Expand All @@ -50,20 +54,22 @@ public CareerResponse<Object> update(@RequestBody @Valid CareerRequestDto.Update
@PathVariable Long careerId) {
LoginUser loginUser = LoginUser.get();
Career updateCareer = careerService.updateCareer(careerId, request);
return CareerResponse.success(CareerStatusCode.OK,
return CareerResponse.success(HttpStatus.OK,
CareerResponseMessage.CAREER_UPDATE_SUCCESS,
CareerConverter.toUpdateCareerResultDto(updateCareer));
CareerConverter.toCareerDto(updateCareer));
}

// @GetMapping("")
// @Operation(
// summary = "활동 조회 API - 카테고리 기준(cateogry), 연도 기준(year) ",
// description = "내 커리어 - 활동을 카테고리 별로 조회하는 API. query 값으로 category 나 year 값을 주세요. " )
// public CareerResponse<Object> read(@RequestParam(name="status") String value){
//
// List<CareerDto> careeList = careerService.getCareersGroupBy(value);
// return null;
// }
@GetMapping("")
@Operation(
summary = "활동 조회 API - category(카테고리 기준) , year(연도 기준) ",
description = "내 커리어 - 활동을 카테고리 별로 조회하는 API입니다. query 값으로 category 나 year 값을 주세요. " )
public CareerResponse<List<? extends CareerGroupedByResponse>> read(@RequestParam(name="status") String value){
List<? extends CareerGroupedByResponse> groupedCareers = careerService.getCareerGroupedBy(value);
if (!groupedCareers.isEmpty()) {
return CareerResponse.success(HttpStatus.OK, "success", groupedCareers);
}
return CareerResponse.success(HttpStatus.OK, "success", groupedCareers);
}



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ public ResponseEntity<CareerResponse<?>> handleInvalidFormatExceptions(InvalidFo
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CareerResponse.createError(CareerResponseMessage.CAREER_FOTMAT_INVALID));
}

@ExceptionHandler(CareerNotFoundException.class)
public ResponseEntity<CareerResponse<?>> handleCareerNotFoundException(CareerNotFoundException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CareerResponse.createError(e.getMessage()));
}

@ExceptionHandler(CareerValidationException.class)
public ResponseEntity<CareerResponse<?>> handleCareerValidationException(CareerValidationException e){
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CareerResponse.createError(e.getMessage()));
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package umc.kkijuk.server.career.controller.response;

public abstract class CareerGroupedByResponse {
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ public static CareerResponse<?> createFail (BindingResult bindingResult){
errors.put(error.getObjectName(),error.getDefaultMessage());
}
}
return new CareerResponse<>(CareerStatusCode.FAIL,CareerResponseMessage.CAREER_CREATE_FAIL,errors);
return new CareerResponse<>(HttpStatus.BAD_REQUEST.value(), CareerResponseMessage.CAREER_CREATE_FAIL,errors);
}
public static CareerResponse<?> createError(String message){
return new CareerResponse<>(CareerStatusCode.FAIL, message, null);
return new CareerResponse<>(HttpStatus.BAD_REQUEST.value(), message, null);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ public class CareerResponseMessage {
public static final String CAREER_CREATE_SUCCESS = "활동 추가가 정상적으로 이루어졌습니다.";
public static final String CAREER_UPDATE_SUCCESS = "활동 수정이 정상적으로 이루어졌습니다.";
public static final String CAREER_NOT_FOUND ="존재하는 활동 Id가 아닙니다.";

public static final String CAREER_CREATE_FAIL = "활동 추가를 실패했습니다.";
public static final String CAREER_FOTMAT_INVALID = "올바른 날짜 형식이 아닙니다. YYYY-MM-DD 형식으로 입력해야 합니다.";
public static final String CAREER_ENDDATE = "현재 진행중이 아니라면, 활동 종료 날짜를 입력해야 합니다.";
public static final String CAREER_PERIOD_FAIL = "시작 날짜는 종료 날짜보다 앞에 있어야 합니다.";
public static final String CATEGORY_NOT_FOUND = "존재하는 카테고리 Id가 아닙니다.";
public static final String CAREER_DELETE_SUCCESS = "활동 삭제가 정상적으로 이루어졌습니다.";
public static final String CAREER_FINDALL_FAIL = "올바른 요청이 아닙니다. category, year 요청을 주세요";



Expand Down

This file was deleted.

36 changes: 34 additions & 2 deletions src/main/java/umc/kkijuk/server/career/dto/CareerResponseDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import umc.kkijuk.server.career.controller.response.CareerGroupedByResponse;

import java.time.LocalDate;
import java.util.List;

public class CareerResponseDto {

Expand All @@ -23,14 +25,44 @@ public static class CareerResultDto{
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class UpdateCareerResultDto{
public static class CareerDto{
Long id;
String careerName;
String alias;
String summary;
Boolean isCurrent;
LocalDate startDate;
LocalDate endDate;
int category;
int year;
String categoryName;
Long categoryId;
}

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class CareerGroupedByCategoryDto extends CareerGroupedByResponse {
@Schema(description = "카테고리명",example = "동아리",type = "String")
private String category;
@Schema(description = "카테고리 내 활동 개수",example = "2",type="int")
private int count;
@Schema(description = "해당 카테고리 내 활동 목록")
private List<CareerDto> careers;

}

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class CareerGroupedByYearDto extends CareerGroupedByResponse{
@Schema(description = "연도", example = "2024", type = "int")
private int year;
@Schema(description = "연도 내 활동 개수", example = "2", type = "int")
private int count;
@Schema(description = "해당 연도 내 활동 목록")
private List<CareerDto> careers;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import umc.kkijuk.server.career.dto.CareerRequestDto;
import umc.kkijuk.server.career.dto.CareerResponseDto;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class CareerConverter {

public static Career toCareer(CareerRequestDto.CareerDto request){
Expand All @@ -22,16 +26,66 @@ public static CareerResponseDto.CareerResultDto tocareerResultDto(Career career)
.careerId(career.getId())
.build();
}
public static CareerResponseDto.UpdateCareerResultDto toUpdateCareerResultDto(Career career) {
return CareerResponseDto.UpdateCareerResultDto.builder()
public static CareerResponseDto.CareerDto toCareerDto(Career career) {
return CareerResponseDto.CareerDto.builder()
.id(career.getId())
.careerName(career.getName())
.alias(career.getAlias())
.summary(career.getSummary())
.isCurrent(career.getCurrent())
.startDate(career.getStartdate())
.endDate(career.getEnddate())
.category(Math.toIntExact(career.getCategory().getId()))
.year(career.getYear())
.categoryId(career.getCategory().getId())
.categoryName(career.getCategory().getName())
.build();
}

public static List<CareerResponseDto.CareerGroupedByCategoryDto> toCareerGroupedByCategoryDto( Map<String, List<Career>> groupedCareers ) {
return groupedCareers.entrySet().stream()
.map(entry -> CareerResponseDto.CareerGroupedByCategoryDto.builder()
.category(entry.getKey())
.count(entry.getValue().size())
.careers(entry.getValue().stream()
.map(career -> CareerResponseDto.CareerDto.builder()
.id(career.getId())
.careerName(career.getName())
.alias(career.getAlias())
.summary(career.getSummary())
.year(career.getYear())
.startDate(career.getStartdate())
.endDate(career.getEnddate())
.isCurrent(career.getCurrent())
.categoryId(career.getCategory().getId())
.categoryName(career.getCategory().getName())
.build())
.collect(Collectors.toList()))
.build())
.collect(Collectors.toList());
}

public static List<CareerResponseDto.CareerGroupedByYearDto> toCareerGroupedByYearDto(Map<String, List<Career>> groupedCareers) {
return groupedCareers.entrySet().stream()
.map(entry -> CareerResponseDto.CareerGroupedByYearDto.builder()
.year(Integer.parseInt(entry.getKey()))
.count(entry.getValue().size())
.careers(entry.getValue().stream()
.map(career -> CareerResponseDto.CareerDto.builder()
.id(career.getId())
.careerName(career.getName())
.alias(career.getAlias())
.summary(career.getSummary())
.year(career.getYear())
.startDate(career.getStartdate())
.endDate(career.getEnddate())
.isCurrent(career.getCurrent())
.categoryId(career.getCategory().getId())
.categoryName(career.getCategory().getName())
.build())
.collect(Collectors.toList()))
.build())
.collect(Collectors.toList());
}


}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package umc.kkijuk.server.career.service;

import umc.kkijuk.server.career.controller.response.CareerGroupedByResponse;
import umc.kkijuk.server.career.domain.Career;
import umc.kkijuk.server.career.dto.CareerRequestDto;
import umc.kkijuk.server.career.dto.CareerResponseDto;

import java.util.List;
import java.util.Optional;
Expand All @@ -12,4 +14,5 @@ public interface CareerService {
Optional<Career> findCareer(Long value);
Career updateCareer(Long careerId, CareerRequestDto.UpdateCareerDto request);

List<? extends CareerGroupedByResponse> getCareerGroupedBy(String value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import umc.kkijuk.server.career.controller.exception.CareerNotFoundException;
import umc.kkijuk.server.career.controller.exception.CareerValidationException;
import umc.kkijuk.server.career.controller.response.CareerGroupedByResponse;
import umc.kkijuk.server.career.controller.response.CareerResponseMessage;
import umc.kkijuk.server.career.domain.Career;
import umc.kkijuk.server.career.dto.CareerRequestDto;
import umc.kkijuk.server.career.dto.converter.CareerConverter;
import umc.kkijuk.server.career.repository.CareerRepository;
import umc.kkijuk.server.career.repository.CategoryRepository;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
Expand All @@ -39,6 +42,7 @@ public void deleteCareer(Long careerId) {
Optional<Career> career = findCareer(careerId);
careerRepository.delete(career.get());
}

@Override
@Transactional
public Career updateCareer(Long careerId, CareerRequestDto.UpdateCareerDto request) {
Expand Down Expand Up @@ -66,20 +70,32 @@ public Career updateCareer(Long careerId, CareerRequestDto.UpdateCareerDto reque
return careerRepository.save(career);
}

@Override
public List<? extends CareerGroupedByResponse> getCareerGroupedBy(String status) {
List<Career> careers = careerRepository.findAll();
Map<String,List<Career>> groupedCareers;

if(status.equalsIgnoreCase("category")){
groupedCareers = careers.stream().collect(Collectors.groupingBy(value -> value.getCategory().getName()));
return CareerConverter.toCareerGroupedByCategoryDto(groupedCareers);
} else if (status.equalsIgnoreCase("year")) {
groupedCareers = careers.stream().collect(Collectors.groupingBy(value -> String.valueOf(value.getYear())));
return CareerConverter.toCareerGroupedByYearDto(groupedCareers);
} else {
throw new IllegalArgumentException(CareerResponseMessage.CAREER_FINDALL_FAIL);
}
}

@Override
public Optional<Career> findCareer(Long careerId) {
return Optional.ofNullable(careerRepository.findById(careerId).orElseThrow(
() -> new CareerNotFoundException(CareerResponseMessage.CAREER_NOT_FOUND.toString())));
() -> new CareerValidationException(CareerResponseMessage.CAREER_NOT_FOUND.toString(),"careerId")));
}








private void updateEndDateAndCurrentStatus(Career career, Boolean isCurrent, LocalDate endDate) {
if (isCurrent != null) {
career.setCurrent(isCurrent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.transaction.annotation.Transactional;
import umc.kkijuk.server.career.controller.exception.CareerExceptionControllerAdvice;
import umc.kkijuk.server.career.controller.exception.CareerNotFoundException;
import umc.kkijuk.server.career.controller.exception.CareerValidationException;
import umc.kkijuk.server.career.controller.response.CareerResponse;
import umc.kkijuk.server.career.controller.response.CareerResponseMessage;
Expand Down Expand Up @@ -177,7 +175,7 @@ void init() {
.build();
//when
//then
assertThrows(CareerNotFoundException.class, () -> careerService.updateCareer(999L,updateCareerDto));
assertThrows(CareerValidationException.class, () -> careerService.updateCareer(999L,updateCareerDto));
}
@Test
void update_수정시_날짜_형식이_잘못된_경우_에러() {
Expand Down Expand Up @@ -230,7 +228,7 @@ void init() {
//given
//when
//then
assertThrows(CareerNotFoundException.class, () -> careerService.deleteCareer(999L));
assertThrows(CareerValidationException.class, () -> careerService.deleteCareer(999L));
}
@Test
void CareerExceptionControllerAdvice가_올바른_예외_응답을_반환하는지_검증() {
Expand Down
Loading

0 comments on commit 4d3a059

Please sign in to comment.