diff --git a/src/main/java/inu/codin/codin/common/dto/Department.java b/src/main/java/inu/codin/codin/common/dto/Department.java index f49f8966..2ad60cc4 100644 --- a/src/main/java/inu/codin/codin/common/dto/Department.java +++ b/src/main/java/inu/codin/codin/common/dto/Department.java @@ -1,10 +1,14 @@ package inu.codin.codin.common.dto; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; @Getter @RequiredArgsConstructor +@Slf4j public enum Department { IT_COLLEGE("정보기술대학"), @@ -17,13 +21,20 @@ public enum Department { private final String description; + @JsonCreator public static Department fromDescription(String description) { for (Department department : Department.values()) { - if (department.getDescription().equals(description)) { + if (department.name().equals(description) || department.getDescription().equals(description)) { return department; } } + + log.warn("정보대 내의 학과가 아닙니다. description : " + description); return OTHERS; } + @JsonValue + public String toValue(){ + return this.name(); + } } diff --git a/src/main/java/inu/codin/codin/common/exception/GlobalExceptionHandler.java b/src/main/java/inu/codin/codin/common/exception/GlobalExceptionHandler.java index 2fb9dca9..ae643bc1 100644 --- a/src/main/java/inu/codin/codin/common/exception/GlobalExceptionHandler.java +++ b/src/main/java/inu/codin/codin/common/exception/GlobalExceptionHandler.java @@ -2,7 +2,10 @@ import inu.codin.codin.common.response.ExceptionResponse; import inu.codin.codin.common.security.exception.JwtException; +import inu.codin.codin.domain.chat.chatroom.exception.ChatRoomExistedException; import inu.codin.codin.domain.chat.exception.*; +import inu.codin.codin.domain.info.exception.InfoErrorCode; +import inu.codin.codin.domain.info.exception.InfoException; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.RedisSystemException; import org.springframework.http.HttpStatus; @@ -33,8 +36,8 @@ protected ResponseEntity handleGlobalException(GlobalExceptio protected ResponseEntity handleChatRoomException(ChatRoomException e) { ChatRoomErrorCode code = e.getErrorCode(); String message = code.message(); - if (e instanceof ChatRoomExistedException existedException) //client 측에서 303 상태 코드 확인 후 message의 chatRoomId로 리다이렉션 - message = message + "/" + existedException.getChatRoomId(); +// if (e instanceof ChatRoomExistedException existedException) //client 측에서 303 상태 코드 확인 후 message의 chatRoomId로 리다이렉션 +// message = message + "/" + existedException.getChatRoomId(); return ResponseEntity.status(code.httpStatus()) .body(new ExceptionResponse(message, code.httpStatus().value())); } @@ -46,6 +49,13 @@ protected ResponseEntity handleChattingException(ChattingExce .body(new ExceptionResponse(code.message(), code.httpStatus().value())); } + @ExceptionHandler(InfoException.class) + protected ResponseEntity handleInfoException(InfoException e) { + InfoErrorCode code = e.getErrorCode(); + return ResponseEntity.status(code.httpStatus()) + .body(new ExceptionResponse(code.message(), code.httpStatus().value())); + } + @ExceptionHandler(NotFoundException.class) protected ResponseEntity handleNotFoundException(NotFoundException e) { return ResponseEntity.status(HttpStatus.NOT_FOUND) diff --git a/src/main/java/inu/codin/codin/domain/info/domain/lab/controller/LabController.java b/src/main/java/inu/codin/codin/domain/info/controller/LabController.java similarity index 88% rename from src/main/java/inu/codin/codin/domain/info/domain/lab/controller/LabController.java rename to src/main/java/inu/codin/codin/domain/info/controller/LabController.java index 0f96274f..8875a931 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/lab/controller/LabController.java +++ b/src/main/java/inu/codin/codin/domain/info/controller/LabController.java @@ -1,11 +1,11 @@ -package inu.codin.codin.domain.info.domain.lab.controller; +package inu.codin.codin.domain.info.controller; import inu.codin.codin.common.response.ListResponse; import inu.codin.codin.common.response.SingleResponse; -import inu.codin.codin.domain.info.domain.lab.dto.request.LabCreateUpdateRequestDto; -import inu.codin.codin.domain.info.domain.lab.dto.response.LabListResponseDto; -import inu.codin.codin.domain.info.domain.lab.dto.response.LabThumbnailResponseDto; -import inu.codin.codin.domain.info.domain.lab.service.LabService; +import inu.codin.codin.domain.info.dto.request.LabCreateUpdateRequestDto; +import inu.codin.codin.domain.info.dto.response.LabListResponseDto; +import inu.codin.codin.domain.info.dto.response.LabThumbnailResponseDto; +import inu.codin.codin.domain.info.service.LabService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; diff --git a/src/main/java/inu/codin/codin/domain/info/domain/office/controller/OfficeController.java b/src/main/java/inu/codin/codin/domain/info/controller/OfficeController.java similarity index 92% rename from src/main/java/inu/codin/codin/domain/info/domain/office/controller/OfficeController.java rename to src/main/java/inu/codin/codin/domain/info/controller/OfficeController.java index 05a7a6d4..952eb0cc 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/office/controller/OfficeController.java +++ b/src/main/java/inu/codin/codin/domain/info/controller/OfficeController.java @@ -1,10 +1,10 @@ -package inu.codin.codin.domain.info.domain.office.controller; +package inu.codin.codin.domain.info.controller; import inu.codin.codin.common.dto.Department; import inu.codin.codin.common.response.SingleResponse; -import inu.codin.codin.domain.info.domain.office.dto.request.OfficeMemberCreateUpdateRequestDto; -import inu.codin.codin.domain.info.domain.office.dto.request.OfficeUpdateRequestDto; -import inu.codin.codin.domain.info.domain.office.service.OfficeService; +import inu.codin.codin.domain.info.dto.request.OfficeMemberCreateUpdateRequestDto; +import inu.codin.codin.domain.info.dto.request.OfficeUpdateRequestDto; +import inu.codin.codin.domain.info.service.OfficeService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; diff --git a/src/main/java/inu/codin/codin/domain/info/controller/PartnerController.java b/src/main/java/inu/codin/codin/domain/info/controller/PartnerController.java new file mode 100644 index 00000000..c25a2ba8 --- /dev/null +++ b/src/main/java/inu/codin/codin/domain/info/controller/PartnerController.java @@ -0,0 +1,75 @@ +package inu.codin.codin.domain.info.controller; + +import inu.codin.codin.common.response.ListResponse; +import inu.codin.codin.common.response.SingleResponse; +import inu.codin.codin.domain.info.dto.request.PartnerCreateRequestDto; +import inu.codin.codin.domain.info.dto.response.PartnerDetailsResponseDto; +import inu.codin.codin.domain.info.dto.response.PartnerListResponseDto; +import inu.codin.codin.domain.info.service.PartnerService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/info/partner") +@Tag(name = "Partner API", description = "Partner CRUD") +public class PartnerController { + + private final PartnerService partnerService; + + @Operation( + summary = "Partner 썸네일 리스트 반환" + ) + @GetMapping + public ResponseEntity> getPartnerList() { + return ResponseEntity.ok() + .body(new ListResponse<>(200, "Partner 썸네일 리스트 반환 성공", partnerService.getPartnerList())); + } + + @Operation( + summary = "Partner 상세 내역 반환" + ) + @GetMapping("/{id}") + public ResponseEntity> getPartnerDetails(@PathVariable("id") String partnerId) { + return ResponseEntity.ok() + .body(new SingleResponse<>(200, "Partner 상세 내열 반환 성공", partnerService.getPartnerDetails(partnerId))); + } + + @PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_MANAGER')") + @Operation( + summary = "[ADMIN, MANAGER] Partner 추가" + ) + @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public ResponseEntity createPartner(@RequestPart("partnerInfo") @Valid PartnerCreateRequestDto partnerCreateRequestDto, + @RequestPart(value = "mainImage", required = false) MultipartFile mainImage, + @RequestPart(value = "subImages", required = false) List subImages ) { + partnerService.createPartner(partnerCreateRequestDto, mainImage, subImages); + return ResponseEntity.status(HttpStatus.CREATED) + .body(new SingleResponse<>(201, "Partner 생성 완료", null)); + } + + @PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_MANAGER')") + @Operation( + summary = "[ADMIN, MANAGER] Partner 삭제" + ) + @DeleteMapping("/{id}") + public ResponseEntity deletePartner(@PathVariable("id") String partnerId) { + partnerService.deletePartner(partnerId); + return ResponseEntity.ok() + .body(new SingleResponse<>(200, "Partner 삭제 완료", null)); + } + + /* + 제휴업체 내용 수정 + */ +} diff --git a/src/main/java/inu/codin/codin/domain/info/domain/professor/controller/ProfessorController.java b/src/main/java/inu/codin/codin/domain/info/controller/ProfessorController.java similarity index 87% rename from src/main/java/inu/codin/codin/domain/info/domain/professor/controller/ProfessorController.java rename to src/main/java/inu/codin/codin/domain/info/controller/ProfessorController.java index 072c30de..b5910248 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/professor/controller/ProfessorController.java +++ b/src/main/java/inu/codin/codin/domain/info/controller/ProfessorController.java @@ -1,12 +1,12 @@ -package inu.codin.codin.domain.info.domain.professor.controller; +package inu.codin.codin.domain.info.controller; import inu.codin.codin.common.dto.Department; import inu.codin.codin.common.response.ListResponse; import inu.codin.codin.common.response.SingleResponse; -import inu.codin.codin.domain.info.domain.professor.dto.request.ProfessorCreateUpdateRequestDto; -import inu.codin.codin.domain.info.domain.professor.dto.response.ProfessorListResponseDto; -import inu.codin.codin.domain.info.domain.professor.dto.response.ProfessorThumbnailResponseDto; -import inu.codin.codin.domain.info.domain.professor.service.ProfessorService; +import inu.codin.codin.domain.info.dto.request.ProfessorCreateUpdateRequestDto; +import inu.codin.codin.domain.info.dto.response.ProfessorListResponseDto; +import inu.codin.codin.domain.info.dto.response.ProfessorThumbnailResponseDto; +import inu.codin.codin.domain.info.service.ProfessorService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; diff --git a/src/main/java/inu/codin/codin/domain/info/domain/lab/exception/LabNotFoundException.java b/src/main/java/inu/codin/codin/domain/info/domain/lab/exception/LabNotFoundException.java deleted file mode 100644 index a3003257..00000000 --- a/src/main/java/inu/codin/codin/domain/info/domain/lab/exception/LabNotFoundException.java +++ /dev/null @@ -1,8 +0,0 @@ -package inu.codin.codin.domain.info.domain.lab.exception; - -public class LabNotFoundException extends RuntimeException{ - - public LabNotFoundException(String message){ - super(message); - } -} diff --git a/src/main/java/inu/codin/codin/domain/info/domain/professor/exception/ProfessorDuplicatedException.java b/src/main/java/inu/codin/codin/domain/info/domain/professor/exception/ProfessorDuplicatedException.java deleted file mode 100644 index d78c76a3..00000000 --- a/src/main/java/inu/codin/codin/domain/info/domain/professor/exception/ProfessorDuplicatedException.java +++ /dev/null @@ -1,7 +0,0 @@ -package inu.codin.codin.domain.info.domain.professor.exception; - -public class ProfessorDuplicatedException extends RuntimeException{ - public ProfessorDuplicatedException(String message){ - super(message); - } -} diff --git a/src/main/java/inu/codin/codin/domain/info/domain/professor/exception/ProfessorNotFoundException.java b/src/main/java/inu/codin/codin/domain/info/domain/professor/exception/ProfessorNotFoundException.java deleted file mode 100644 index 39f3cc7d..00000000 --- a/src/main/java/inu/codin/codin/domain/info/domain/professor/exception/ProfessorNotFoundException.java +++ /dev/null @@ -1,7 +0,0 @@ -package inu.codin.codin.domain.info.domain.professor.exception; - -public class ProfessorNotFoundException extends RuntimeException{ - public ProfessorNotFoundException(String message){ - super(message); - } -} diff --git a/src/main/java/inu/codin/codin/domain/info/domain/lab/dto/request/LabCreateUpdateRequestDto.java b/src/main/java/inu/codin/codin/domain/info/dto/request/LabCreateUpdateRequestDto.java similarity index 95% rename from src/main/java/inu/codin/codin/domain/info/domain/lab/dto/request/LabCreateUpdateRequestDto.java rename to src/main/java/inu/codin/codin/domain/info/dto/request/LabCreateUpdateRequestDto.java index 9b75e7f3..8ca41081 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/lab/dto/request/LabCreateUpdateRequestDto.java +++ b/src/main/java/inu/codin/codin/domain/info/dto/request/LabCreateUpdateRequestDto.java @@ -1,4 +1,4 @@ -package inu.codin.codin.domain.info.domain.lab.dto.request; +package inu.codin.codin.domain.info.dto.request; import inu.codin.codin.common.dto.Department; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/src/main/java/inu/codin/codin/domain/info/domain/office/dto/request/OfficeMemberCreateUpdateRequestDto.java b/src/main/java/inu/codin/codin/domain/info/dto/request/OfficeMemberCreateUpdateRequestDto.java similarity index 91% rename from src/main/java/inu/codin/codin/domain/info/domain/office/dto/request/OfficeMemberCreateUpdateRequestDto.java rename to src/main/java/inu/codin/codin/domain/info/dto/request/OfficeMemberCreateUpdateRequestDto.java index 13bd04bb..0b3288d0 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/office/dto/request/OfficeMemberCreateUpdateRequestDto.java +++ b/src/main/java/inu/codin/codin/domain/info/dto/request/OfficeMemberCreateUpdateRequestDto.java @@ -1,4 +1,4 @@ -package inu.codin.codin.domain.info.domain.office.dto.request; +package inu.codin.codin.domain.info.dto.request; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; diff --git a/src/main/java/inu/codin/codin/domain/info/domain/office/dto/request/OfficeUpdateRequestDto.java b/src/main/java/inu/codin/codin/domain/info/dto/request/OfficeUpdateRequestDto.java similarity index 91% rename from src/main/java/inu/codin/codin/domain/info/domain/office/dto/request/OfficeUpdateRequestDto.java rename to src/main/java/inu/codin/codin/domain/info/dto/request/OfficeUpdateRequestDto.java index a6a4bb3c..1bf5d980 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/office/dto/request/OfficeUpdateRequestDto.java +++ b/src/main/java/inu/codin/codin/domain/info/dto/request/OfficeUpdateRequestDto.java @@ -1,6 +1,6 @@ -package inu.codin.codin.domain.info.domain.office.dto.request; +package inu.codin.codin.domain.info.dto.request; -import inu.codin.codin.domain.info.domain.office.entity.Office; +import inu.codin.codin.domain.info.entity.Office; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Builder; diff --git a/src/main/java/inu/codin/codin/domain/info/dto/request/PartnerCreateRequestDto.java b/src/main/java/inu/codin/codin/domain/info/dto/request/PartnerCreateRequestDto.java new file mode 100644 index 00000000..5b006f94 --- /dev/null +++ b/src/main/java/inu/codin/codin/domain/info/dto/request/PartnerCreateRequestDto.java @@ -0,0 +1,38 @@ +package inu.codin.codin.domain.info.dto.request; + +import inu.codin.codin.common.dto.Department; +import inu.codin.codin.domain.info.entity.PartnerImg; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import lombok.Builder; +import lombok.Getter; + +import java.time.LocalDate; +import java.util.List; + +@Getter +@Builder +public class PartnerCreateRequestDto { + + @NotBlank + @Schema(description = "제휴업체 가게 이름", example = "홍콩반점 송도점") + private String name; + + @NotEmpty + @Schema(description = "제휴 학과", example = "[\"COMPUTER_SCI\", \"INFO_COMM\", \"EMBEDDED\"]") + private List tags; + + @NotEmpty + @Schema(description = "제휴 혜택", example = "[\"탕수육 주문 시, 탕수육 공짜!\", \"평일 언제나 80% 대박 할인!\"]") + private List benefits; + + @Schema(description = "제휴 시작 날짜", example = "2025-03-01") + private LocalDate startDate; + + @Schema(description = "제휴 종료 날짜", example = "2026-03-01") + private LocalDate endDate; + + @Schema(description = "제휴업체 가게 위치", example = "인천 연수구 송도동 3-2") + private String location; +} diff --git a/src/main/java/inu/codin/codin/domain/info/domain/professor/dto/request/ProfessorCreateUpdateRequestDto.java b/src/main/java/inu/codin/codin/domain/info/dto/request/ProfessorCreateUpdateRequestDto.java similarity index 96% rename from src/main/java/inu/codin/codin/domain/info/domain/professor/dto/request/ProfessorCreateUpdateRequestDto.java rename to src/main/java/inu/codin/codin/domain/info/dto/request/ProfessorCreateUpdateRequestDto.java index 56103dd6..3cfd3de4 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/professor/dto/request/ProfessorCreateUpdateRequestDto.java +++ b/src/main/java/inu/codin/codin/domain/info/dto/request/ProfessorCreateUpdateRequestDto.java @@ -1,4 +1,4 @@ -package inu.codin.codin.domain.info.domain.professor.dto.request; +package inu.codin.codin.domain.info.dto.request; import inu.codin.codin.common.dto.Department; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/src/main/java/inu/codin/codin/domain/info/domain/lab/dto/response/LabListResponseDto.java b/src/main/java/inu/codin/codin/domain/info/dto/response/LabListResponseDto.java similarity index 89% rename from src/main/java/inu/codin/codin/domain/info/domain/lab/dto/response/LabListResponseDto.java rename to src/main/java/inu/codin/codin/domain/info/dto/response/LabListResponseDto.java index 9c76d96c..6e4e51c6 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/lab/dto/response/LabListResponseDto.java +++ b/src/main/java/inu/codin/codin/domain/info/dto/response/LabListResponseDto.java @@ -1,12 +1,11 @@ -package inu.codin.codin.domain.info.domain.lab.dto.response; +package inu.codin.codin.domain.info.dto.response; -import inu.codin.codin.domain.info.domain.lab.entity.Lab; +import inu.codin.codin.domain.info.entity.Lab; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Builder; import lombok.Getter; import lombok.Setter; -import org.bson.types.ObjectId; /* 연구실 리스트 반환 DTO diff --git a/src/main/java/inu/codin/codin/domain/info/domain/lab/dto/response/LabThumbnailResponseDto.java b/src/main/java/inu/codin/codin/domain/info/dto/response/LabThumbnailResponseDto.java similarity index 95% rename from src/main/java/inu/codin/codin/domain/info/domain/lab/dto/response/LabThumbnailResponseDto.java rename to src/main/java/inu/codin/codin/domain/info/dto/response/LabThumbnailResponseDto.java index 606b57c8..fcd0e387 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/lab/dto/response/LabThumbnailResponseDto.java +++ b/src/main/java/inu/codin/codin/domain/info/dto/response/LabThumbnailResponseDto.java @@ -1,7 +1,7 @@ -package inu.codin.codin.domain.info.domain.lab.dto.response; +package inu.codin.codin.domain.info.dto.response; import inu.codin.codin.common.dto.Department; -import inu.codin.codin.domain.info.domain.lab.entity.Lab; +import inu.codin.codin.domain.info.entity.Lab; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Builder; diff --git a/src/main/java/inu/codin/codin/domain/info/domain/office/dto/response/OfficeDetailsResponseDto.java b/src/main/java/inu/codin/codin/domain/info/dto/response/OfficeDetailsResponseDto.java similarity index 94% rename from src/main/java/inu/codin/codin/domain/info/domain/office/dto/response/OfficeDetailsResponseDto.java rename to src/main/java/inu/codin/codin/domain/info/dto/response/OfficeDetailsResponseDto.java index 9e22e6c3..88516715 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/office/dto/response/OfficeDetailsResponseDto.java +++ b/src/main/java/inu/codin/codin/domain/info/dto/response/OfficeDetailsResponseDto.java @@ -1,7 +1,7 @@ -package inu.codin.codin.domain.info.domain.office.dto.response; +package inu.codin.codin.domain.info.dto.response; import inu.codin.codin.common.dto.Department; -import inu.codin.codin.domain.info.domain.office.entity.Office; +import inu.codin.codin.domain.info.entity.Office; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Builder; diff --git a/src/main/java/inu/codin/codin/domain/info/domain/office/dto/response/OfficeMemberResponseDto.java b/src/main/java/inu/codin/codin/domain/info/dto/response/OfficeMemberResponseDto.java similarity index 91% rename from src/main/java/inu/codin/codin/domain/info/domain/office/dto/response/OfficeMemberResponseDto.java rename to src/main/java/inu/codin/codin/domain/info/dto/response/OfficeMemberResponseDto.java index bf7d0dbf..ee052ea2 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/office/dto/response/OfficeMemberResponseDto.java +++ b/src/main/java/inu/codin/codin/domain/info/dto/response/OfficeMemberResponseDto.java @@ -1,6 +1,6 @@ -package inu.codin.codin.domain.info.domain.office.dto.response; +package inu.codin.codin.domain.info.dto.response; -import inu.codin.codin.domain.info.domain.office.entity.OfficeMember; +import inu.codin.codin.domain.info.entity.OfficeMember; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Builder; diff --git a/src/main/java/inu/codin/codin/domain/info/dto/response/PartnerDetailsResponseDto.java b/src/main/java/inu/codin/codin/domain/info/dto/response/PartnerDetailsResponseDto.java new file mode 100644 index 00000000..f9b901b1 --- /dev/null +++ b/src/main/java/inu/codin/codin/domain/info/dto/response/PartnerDetailsResponseDto.java @@ -0,0 +1,52 @@ +package inu.codin.codin.domain.info.dto.response; + +import com.fasterxml.jackson.annotation.JsonFormat; +import inu.codin.codin.common.dto.Department; +import inu.codin.codin.domain.info.entity.Partner; +import inu.codin.codin.domain.info.entity.PartnerImg; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Getter; + +import java.time.LocalDate; +import java.util.List; + +@Builder +@Getter +public class PartnerDetailsResponseDto { + + @Schema(description = "제휴업체 가게 이름", example = "홍콩반점 송도점") + private String name; + + @Schema(description = "제휴 학과", example = "[\"COMPUTER_SCI\", \"INFO_COMM\", \"EMBEDDED\"]") + private List tags; + + @Schema(description = "제휴 혜택", example = "[\"탕수육 주문 시, 탕수육 공짜!\", \"평일 언제나 80% 대박 할인!\"]") + private List benefits; + + @Schema(description = "제휴 시작 날짜", example = "2025-03-01") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") + private LocalDate startDate; + + @Schema(description = "제휴 종료 날짜", example = "2026-03-01") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") + private LocalDate endDate; + + @Schema(description = "제휴업체 가게 위치", example = "인천 연수구 송도동 3-2") + private String location; + + @Schema(description = "제휴업체 가게 이미지") + private PartnerImg img; + + public static PartnerDetailsResponseDto from(Partner partner){ + return PartnerDetailsResponseDto.builder() + .name(partner.getName()) + .tags(partner.getTags()) + .benefits(partner.getBenefits()) + .startDate(partner.getStartDate()) + .endDate(partner.getEndDate()) + .location(partner.getLocation()) + .img(partner.getImg()) + .build(); + } +} diff --git a/src/main/java/inu/codin/codin/domain/info/dto/response/PartnerListResponseDto.java b/src/main/java/inu/codin/codin/domain/info/dto/response/PartnerListResponseDto.java new file mode 100644 index 00000000..4596cff6 --- /dev/null +++ b/src/main/java/inu/codin/codin/domain/info/dto/response/PartnerListResponseDto.java @@ -0,0 +1,37 @@ +package inu.codin.codin.domain.info.dto.response; + +import inu.codin.codin.common.dto.Department; +import inu.codin.codin.domain.info.entity.Partner; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; +import lombok.Getter; + +import java.util.List; + +@Builder +@Getter +public class PartnerListResponseDto { + + @Schema(description = "제휴업체 pk", example = "6862c1128d0ca733396ecd5b") + @NotBlank + private String id; + + @Schema(description = "제휴업체 가게 이름", example = "홍콩반점 송도점") + private String name; + + @Schema(description = "제휴업체 가게 이미지", example = "https://example.com") + private String mainImg; + + @Schema(description = "제휴 학과", example = "[\"COMPUTER_SCI\", \"INFO_COMM\", \"EMBEDDED\"]") + private List tags; + + public static PartnerListResponseDto from(Partner partner) { + return PartnerListResponseDto.builder() + .id(partner.get_id().toString()) + .name(partner.getName()) + .mainImg(partner.getImg().getMain()) + .tags(partner.getTags()) + .build(); + } +} diff --git a/src/main/java/inu/codin/codin/domain/info/domain/professor/dto/response/ProfessorListResponseDto.java b/src/main/java/inu/codin/codin/domain/info/dto/response/ProfessorListResponseDto.java similarity index 89% rename from src/main/java/inu/codin/codin/domain/info/domain/professor/dto/response/ProfessorListResponseDto.java rename to src/main/java/inu/codin/codin/domain/info/dto/response/ProfessorListResponseDto.java index ad0e58d5..62bff212 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/professor/dto/response/ProfessorListResponseDto.java +++ b/src/main/java/inu/codin/codin/domain/info/dto/response/ProfessorListResponseDto.java @@ -1,7 +1,7 @@ -package inu.codin.codin.domain.info.domain.professor.dto.response; +package inu.codin.codin.domain.info.dto.response; import inu.codin.codin.common.dto.Department; -import inu.codin.codin.domain.info.domain.professor.entity.Professor; +import inu.codin.codin.domain.info.entity.Professor; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Builder; diff --git a/src/main/java/inu/codin/codin/domain/info/domain/professor/dto/response/ProfessorThumbnailResponseDto.java b/src/main/java/inu/codin/codin/domain/info/dto/response/ProfessorThumbnailResponseDto.java similarity index 94% rename from src/main/java/inu/codin/codin/domain/info/domain/professor/dto/response/ProfessorThumbnailResponseDto.java rename to src/main/java/inu/codin/codin/domain/info/dto/response/ProfessorThumbnailResponseDto.java index 4095f694..cf2e5eb0 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/professor/dto/response/ProfessorThumbnailResponseDto.java +++ b/src/main/java/inu/codin/codin/domain/info/dto/response/ProfessorThumbnailResponseDto.java @@ -1,7 +1,7 @@ -package inu.codin.codin.domain.info.domain.professor.dto.response; +package inu.codin.codin.domain.info.dto.response; import inu.codin.codin.common.dto.Department; -import inu.codin.codin.domain.info.domain.professor.entity.Professor; +import inu.codin.codin.domain.info.entity.Professor; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Builder; diff --git a/src/main/java/inu/codin/codin/domain/info/domain/lab/entity/Lab.java b/src/main/java/inu/codin/codin/domain/info/entity/Lab.java similarity index 91% rename from src/main/java/inu/codin/codin/domain/info/domain/lab/entity/Lab.java rename to src/main/java/inu/codin/codin/domain/info/entity/Lab.java index ca0fc14c..0bd63eda 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/lab/entity/Lab.java +++ b/src/main/java/inu/codin/codin/domain/info/entity/Lab.java @@ -1,9 +1,7 @@ -package inu.codin.codin.domain.info.domain.lab.entity; +package inu.codin.codin.domain.info.entity; -import inu.codin.codin.domain.info.domain.lab.dto.request.LabCreateUpdateRequestDto; -import inu.codin.codin.domain.info.entity.Info; +import inu.codin.codin.domain.info.dto.request.LabCreateUpdateRequestDto; import inu.codin.codin.common.dto.Department; -import inu.codin.codin.domain.info.entity.InfoType; import jakarta.validation.constraints.NotBlank; import lombok.AccessLevel; import lombok.Builder; diff --git a/src/main/java/inu/codin/codin/domain/info/domain/office/entity/Office.java b/src/main/java/inu/codin/codin/domain/info/entity/Office.java similarity index 85% rename from src/main/java/inu/codin/codin/domain/info/domain/office/entity/Office.java rename to src/main/java/inu/codin/codin/domain/info/entity/Office.java index bb998af1..b5eac1fa 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/office/entity/Office.java +++ b/src/main/java/inu/codin/codin/domain/info/entity/Office.java @@ -1,7 +1,6 @@ -package inu.codin.codin.domain.info.domain.office.entity; +package inu.codin.codin.domain.info.entity; -import inu.codin.codin.domain.info.domain.office.dto.request.OfficeUpdateRequestDto; -import inu.codin.codin.domain.info.entity.Info; +import inu.codin.codin.domain.info.dto.request.OfficeUpdateRequestDto; import jakarta.validation.constraints.NotBlank; import lombok.AccessLevel; import lombok.Getter; diff --git a/src/main/java/inu/codin/codin/domain/info/domain/office/entity/OfficeMember.java b/src/main/java/inu/codin/codin/domain/info/entity/OfficeMember.java similarity index 92% rename from src/main/java/inu/codin/codin/domain/info/domain/office/entity/OfficeMember.java rename to src/main/java/inu/codin/codin/domain/info/entity/OfficeMember.java index 16ce3e1d..19a7120c 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/office/entity/OfficeMember.java +++ b/src/main/java/inu/codin/codin/domain/info/entity/OfficeMember.java @@ -1,7 +1,7 @@ -package inu.codin.codin.domain.info.domain.office.entity; +package inu.codin.codin.domain.info.entity; import inu.codin.codin.common.dto.BaseTimeEntity; -import inu.codin.codin.domain.info.domain.office.dto.request.OfficeMemberCreateUpdateRequestDto; +import inu.codin.codin.domain.info.dto.request.OfficeMemberCreateUpdateRequestDto; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import lombok.Builder; diff --git a/src/main/java/inu/codin/codin/domain/info/entity/Partner.java b/src/main/java/inu/codin/codin/domain/info/entity/Partner.java new file mode 100644 index 00000000..e55fbbed --- /dev/null +++ b/src/main/java/inu/codin/codin/domain/info/entity/Partner.java @@ -0,0 +1,54 @@ +package inu.codin.codin.domain.info.entity; + +import inu.codin.codin.common.dto.Department; +import inu.codin.codin.domain.info.dto.request.PartnerCreateRequestDto; +import jakarta.validation.constraints.NotBlank; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.bson.types.ObjectId; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.time.LocalDate; +import java.util.List; + +@Document(collection = "partner") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class Partner { + + @Id @NotBlank + private ObjectId _id; + private String name; + private List tags; + private List benefits; + private LocalDate startDate; + private LocalDate endDate; + private String location; + private PartnerImg img; + + @Builder + public Partner(String name, List tags, List benefits, LocalDate startDate, LocalDate endDate, String location, PartnerImg img) { + this.name = name; + this.tags = tags; + this.benefits = benefits; + this.startDate = startDate; + this.endDate = endDate; + this.location = location; + this.img = img; + } + + public static Partner of(PartnerCreateRequestDto partnerCreateRequestDto, PartnerImg partnerImg){ + return Partner.builder() + .name(partnerCreateRequestDto.getName()) + .tags(partnerCreateRequestDto.getTags()) + .benefits(partnerCreateRequestDto.getBenefits()) + .startDate(partnerCreateRequestDto.getStartDate()) + .endDate(partnerCreateRequestDto.getEndDate()) + .location(partnerCreateRequestDto.getLocation()) + .img(partnerImg) + .build(); + } +} diff --git a/src/main/java/inu/codin/codin/domain/info/entity/PartnerImg.java b/src/main/java/inu/codin/codin/domain/info/entity/PartnerImg.java new file mode 100644 index 00000000..465b10eb --- /dev/null +++ b/src/main/java/inu/codin/codin/domain/info/entity/PartnerImg.java @@ -0,0 +1,18 @@ +package inu.codin.codin.domain.info.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; + +@Getter +@AllArgsConstructor +public class PartnerImg { + + @Schema(description = "제휴업체 메인 이미지", example = "https://example.com") + private String main; + + @Schema(description = "제휴업체 서브 이미지", example = "[\"https://example.com\", \"https://example.com\"]") + private List sub; +} diff --git a/src/main/java/inu/codin/codin/domain/info/domain/professor/entity/Professor.java b/src/main/java/inu/codin/codin/domain/info/entity/Professor.java similarity index 91% rename from src/main/java/inu/codin/codin/domain/info/domain/professor/entity/Professor.java rename to src/main/java/inu/codin/codin/domain/info/entity/Professor.java index 54c5ae04..da280ae3 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/professor/entity/Professor.java +++ b/src/main/java/inu/codin/codin/domain/info/entity/Professor.java @@ -1,9 +1,7 @@ -package inu.codin.codin.domain.info.domain.professor.entity; +package inu.codin.codin.domain.info.entity; import inu.codin.codin.common.dto.Department; -import inu.codin.codin.domain.info.domain.professor.dto.request.ProfessorCreateUpdateRequestDto; -import inu.codin.codin.domain.info.entity.Info; -import inu.codin.codin.domain.info.entity.InfoType; +import inu.codin.codin.domain.info.dto.request.ProfessorCreateUpdateRequestDto; import jakarta.validation.constraints.NotBlank; import lombok.AccessLevel; import lombok.Builder; diff --git a/src/main/java/inu/codin/codin/domain/info/exception/InfoErrorCode.java b/src/main/java/inu/codin/codin/domain/info/exception/InfoErrorCode.java new file mode 100644 index 00000000..743d7b77 --- /dev/null +++ b/src/main/java/inu/codin/codin/domain/info/exception/InfoErrorCode.java @@ -0,0 +1,29 @@ +package inu.codin.codin.domain.info.exception; + +import inu.codin.codin.common.exception.GlobalErrorCode; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +@RequiredArgsConstructor +public enum InfoErrorCode implements GlobalErrorCode { + + LAB_NOT_FOUND(HttpStatus.NOT_FOUND, "LAB 정보를 찾을 수 없습니다."), + + PROFESSOR_NOT_FOUND(HttpStatus.NOT_FOUND, "PROFESSOR 정보를 찾을 수 없습니다."), + PROFESSOR_DUPLICATED(HttpStatus.CONFLICT, "이미 존재하는 PROFESSOR 정보 입니다."), + + PARTNER_NOT_FOUND(HttpStatus.NOT_FOUND, "PARTNER 정보를 찾을 수 없습니다."); + + private final HttpStatus httpStatus; + private final String message; + + @Override + public HttpStatus httpStatus() { + return httpStatus; + } + + @Override + public String message() { + return message; + } +} diff --git a/src/main/java/inu/codin/codin/domain/info/exception/InfoException.java b/src/main/java/inu/codin/codin/domain/info/exception/InfoException.java new file mode 100644 index 00000000..85a383ad --- /dev/null +++ b/src/main/java/inu/codin/codin/domain/info/exception/InfoException.java @@ -0,0 +1,14 @@ +package inu.codin.codin.domain.info.exception; + +import inu.codin.codin.common.exception.GlobalException; +import lombok.Getter; + +@Getter +public class InfoException extends GlobalException { + + private final InfoErrorCode errorCode; + public InfoException(InfoErrorCode errorCode) { + super(errorCode); + this.errorCode = errorCode; + } +} diff --git a/src/main/java/inu/codin/codin/domain/info/repository/InfoRepository.java b/src/main/java/inu/codin/codin/domain/info/repository/InfoRepository.java index 416fa37e..51efec33 100644 --- a/src/main/java/inu/codin/codin/domain/info/repository/InfoRepository.java +++ b/src/main/java/inu/codin/codin/domain/info/repository/InfoRepository.java @@ -1,9 +1,9 @@ package inu.codin.codin.domain.info.repository; import inu.codin.codin.common.dto.Department; -import inu.codin.codin.domain.info.domain.lab.entity.Lab; -import inu.codin.codin.domain.info.domain.office.entity.Office; -import inu.codin.codin.domain.info.domain.professor.entity.Professor; +import inu.codin.codin.domain.info.entity.Lab; +import inu.codin.codin.domain.info.entity.Office; +import inu.codin.codin.domain.info.entity.Professor; import inu.codin.codin.domain.info.entity.Info; import org.bson.types.ObjectId; import org.springframework.data.mongodb.repository.MongoRepository; diff --git a/src/main/java/inu/codin/codin/domain/info/repository/PartnerRepository.java b/src/main/java/inu/codin/codin/domain/info/repository/PartnerRepository.java new file mode 100644 index 00000000..152c36f3 --- /dev/null +++ b/src/main/java/inu/codin/codin/domain/info/repository/PartnerRepository.java @@ -0,0 +1,9 @@ +package inu.codin.codin.domain.info.repository; + +import inu.codin.codin.domain.info.entity.Partner; +import org.bson.types.ObjectId; +import org.springframework.data.mongodb.repository.MongoRepository; + +public interface PartnerRepository extends MongoRepository { + +} diff --git a/src/main/java/inu/codin/codin/domain/info/domain/lab/service/LabService.java b/src/main/java/inu/codin/codin/domain/info/service/LabService.java similarity index 73% rename from src/main/java/inu/codin/codin/domain/info/domain/lab/service/LabService.java rename to src/main/java/inu/codin/codin/domain/info/service/LabService.java index 723711d3..6906241c 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/lab/service/LabService.java +++ b/src/main/java/inu/codin/codin/domain/info/service/LabService.java @@ -1,10 +1,11 @@ -package inu.codin.codin.domain.info.domain.lab.service; +package inu.codin.codin.domain.info.service; -import inu.codin.codin.domain.info.domain.lab.dto.request.LabCreateUpdateRequestDto; -import inu.codin.codin.domain.info.domain.lab.dto.response.LabListResponseDto; -import inu.codin.codin.domain.info.domain.lab.dto.response.LabThumbnailResponseDto; -import inu.codin.codin.domain.info.domain.lab.entity.Lab; -import inu.codin.codin.domain.info.domain.lab.exception.LabNotFoundException; +import inu.codin.codin.domain.info.dto.request.LabCreateUpdateRequestDto; +import inu.codin.codin.domain.info.dto.response.LabListResponseDto; +import inu.codin.codin.domain.info.dto.response.LabThumbnailResponseDto; +import inu.codin.codin.domain.info.entity.Lab; +import inu.codin.codin.domain.info.exception.InfoErrorCode; +import inu.codin.codin.domain.info.exception.InfoException; import inu.codin.codin.domain.info.repository.InfoRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -24,7 +25,7 @@ public LabThumbnailResponseDto getLabThumbnail(String id) { Lab lab = infoRepository.findLabById(new ObjectId(id)) .orElseThrow(() -> { log.warn("[getLabThumbnail] 연구실 정보 조회 실패, 연구실 ID: {}", id); - return new LabNotFoundException("연구실 정보를 찾을 수 없습니다."); + return new InfoException(InfoErrorCode.LAB_NOT_FOUND); }); log.info("[getLabThumbnail] {}의 연구실 정보 열람", id); return LabThumbnailResponseDto.of(lab); @@ -47,7 +48,7 @@ public void updateLab(LabCreateUpdateRequestDto labCreateUpdateRequestDto, Strin Lab lab = infoRepository.findLabById(new ObjectId(id)) .orElseThrow(() -> { log.warn("[updateLab] 연구실 정보 업데이트 실패, 연구실 ID: {}", id); - return new LabNotFoundException("연구실 정보를 찾을 수 없습니다."); + return new InfoException(InfoErrorCode.LAB_NOT_FOUND); }); lab.update(labCreateUpdateRequestDto); infoRepository.save(lab); @@ -56,7 +57,7 @@ public void updateLab(LabCreateUpdateRequestDto labCreateUpdateRequestDto, Strin public void deleteLab(String id) { Lab lab = infoRepository.findLabById(new ObjectId(id)) - .orElseThrow(() -> new LabNotFoundException("연구실 정보를 찾을 수 없습니다.")); + .orElseThrow(() -> new InfoException(InfoErrorCode.LAB_NOT_FOUND)); lab.delete(); infoRepository.save(lab); log.info("[deleteLab] {}의 연구실 정보 삭제", lab.get_id().toString()); diff --git a/src/main/java/inu/codin/codin/domain/info/domain/office/service/OfficeService.java b/src/main/java/inu/codin/codin/domain/info/service/OfficeService.java similarity index 85% rename from src/main/java/inu/codin/codin/domain/info/domain/office/service/OfficeService.java rename to src/main/java/inu/codin/codin/domain/info/service/OfficeService.java index 760b0eb0..42f21447 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/office/service/OfficeService.java +++ b/src/main/java/inu/codin/codin/domain/info/service/OfficeService.java @@ -1,11 +1,11 @@ -package inu.codin.codin.domain.info.domain.office.service; +package inu.codin.codin.domain.info.service; -import inu.codin.codin.domain.info.domain.office.dto.request.OfficeMemberCreateUpdateRequestDto; -import inu.codin.codin.domain.info.domain.office.dto.request.OfficeUpdateRequestDto; -import inu.codin.codin.domain.info.domain.office.dto.response.OfficeDetailsResponseDto; -import inu.codin.codin.domain.info.domain.office.entity.Office; +import inu.codin.codin.domain.info.dto.request.OfficeMemberCreateUpdateRequestDto; +import inu.codin.codin.domain.info.dto.request.OfficeUpdateRequestDto; +import inu.codin.codin.domain.info.dto.response.OfficeDetailsResponseDto; +import inu.codin.codin.domain.info.entity.Office; import inu.codin.codin.common.dto.Department; -import inu.codin.codin.domain.info.domain.office.entity.OfficeMember; +import inu.codin.codin.domain.info.entity.OfficeMember; import inu.codin.codin.domain.info.repository.InfoRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/inu/codin/codin/domain/info/service/PartnerService.java b/src/main/java/inu/codin/codin/domain/info/service/PartnerService.java new file mode 100644 index 00000000..506390b3 --- /dev/null +++ b/src/main/java/inu/codin/codin/domain/info/service/PartnerService.java @@ -0,0 +1,58 @@ +package inu.codin.codin.domain.info.service; + +import inu.codin.codin.domain.info.dto.request.PartnerCreateRequestDto; +import inu.codin.codin.domain.info.dto.response.PartnerDetailsResponseDto; +import inu.codin.codin.domain.info.dto.response.PartnerListResponseDto; +import inu.codin.codin.domain.info.entity.Partner; +import inu.codin.codin.domain.info.entity.PartnerImg; +import inu.codin.codin.domain.info.exception.InfoErrorCode; +import inu.codin.codin.domain.info.exception.InfoException; +import inu.codin.codin.domain.info.repository.PartnerRepository; +import inu.codin.codin.infra.s3.S3Service; +import lombok.RequiredArgsConstructor; +import org.bson.types.ObjectId; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class PartnerService { + + private final PartnerRepository partnerRepository; + private final S3Service s3Service; + + public List getPartnerList() { + return partnerRepository.findAll() + .stream() + .map(PartnerListResponseDto::from) + .toList(); + } + + public PartnerDetailsResponseDto getPartnerDetails(String partnerId) { + Partner partner = partnerRepository.findById(new ObjectId(partnerId)) + .orElseThrow(() -> new InfoException(InfoErrorCode.PARTNER_NOT_FOUND)); + return PartnerDetailsResponseDto.from(partner); + } + + public void createPartner(PartnerCreateRequestDto partnerCreateRequestDto, MultipartFile mainImage, List subImages) { + PartnerImg partnerImg = getPartnerImg(mainImage, subImages); + Partner partner = Partner.of(partnerCreateRequestDto, partnerImg); + partnerRepository.save(partner); + } + + private PartnerImg getPartnerImg(MultipartFile mainImage, List subImages) { + String main = Optional.ofNullable(mainImage) + .map(img -> s3Service.handleImageUpload(List.of(img)).get(0)) + .orElse(null); + List subs = s3Service.handleImageUpload(subImages); + return new PartnerImg(main, subs); + } + + public void deletePartner(String partnerId) { + partnerRepository.deleteById(new ObjectId(partnerId)); + } +} diff --git a/src/main/java/inu/codin/codin/domain/info/domain/professor/service/ProfessorService.java b/src/main/java/inu/codin/codin/domain/info/service/ProfessorService.java similarity index 75% rename from src/main/java/inu/codin/codin/domain/info/domain/professor/service/ProfessorService.java rename to src/main/java/inu/codin/codin/domain/info/service/ProfessorService.java index 0f6b70ef..b03bd4fe 100644 --- a/src/main/java/inu/codin/codin/domain/info/domain/professor/service/ProfessorService.java +++ b/src/main/java/inu/codin/codin/domain/info/service/ProfessorService.java @@ -1,12 +1,12 @@ -package inu.codin.codin.domain.info.domain.professor.service; +package inu.codin.codin.domain.info.service; import inu.codin.codin.common.dto.Department; -import inu.codin.codin.domain.info.domain.professor.dto.response.ProfessorListResponseDto; -import inu.codin.codin.domain.info.domain.professor.dto.response.ProfessorThumbnailResponseDto; -import inu.codin.codin.domain.info.domain.professor.dto.request.ProfessorCreateUpdateRequestDto; -import inu.codin.codin.domain.info.domain.professor.entity.Professor; -import inu.codin.codin.domain.info.domain.professor.exception.ProfessorDuplicatedException; -import inu.codin.codin.domain.info.domain.professor.exception.ProfessorNotFoundException; +import inu.codin.codin.domain.info.dto.response.ProfessorListResponseDto; +import inu.codin.codin.domain.info.dto.response.ProfessorThumbnailResponseDto; +import inu.codin.codin.domain.info.dto.request.ProfessorCreateUpdateRequestDto; +import inu.codin.codin.domain.info.entity.Professor; +import inu.codin.codin.domain.info.exception.InfoErrorCode; +import inu.codin.codin.domain.info.exception.InfoException; import inu.codin.codin.domain.info.repository.InfoRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -32,7 +32,7 @@ public List getProfessorByDepartment(Department depart public ProfessorThumbnailResponseDto getProfessorThumbnail(String id) { log.info("[getProfessorThumbnail] 교수 ID '{}'로 정보 조회 시도", id); Professor professor = infoRepository.findProfessorById(new ObjectId(id)) - .orElseThrow(() -> new ProfessorNotFoundException("교수 정보를 찾을 수 없습니다.")); + .orElseThrow(() -> new InfoException(InfoErrorCode.PROFESSOR_NOT_FOUND)); log.info("[getProfessorThumbnail] {} 교수님의 정보 열람", professor.get_id().toString()); return ProfessorThumbnailResponseDto.of(professor); } @@ -41,7 +41,7 @@ public void createProfessor(ProfessorCreateUpdateRequestDto professorCreateUpdat log.info("[createProfessor] 교수 이메일 '{}'로 정보 생성 시도", professorCreateUpdateRequestDto.getEmail()); if (infoRepository.findProfessorByEmail(professorCreateUpdateRequestDto.getEmail()).isPresent()){ log.warn("[createProfessor] 교수 이메일 '{}' 이미 존재", professorCreateUpdateRequestDto.getEmail()); - throw new ProfessorDuplicatedException("이미 존재하는 Professor 정보 입니다."); + throw new InfoException(InfoErrorCode.PROFESSOR_DUPLICATED); } Professor professor = Professor.of(professorCreateUpdateRequestDto); infoRepository.save(professor); @@ -52,7 +52,7 @@ public void updateProfessor(String id, ProfessorCreateUpdateRequestDto professor Professor professor = infoRepository.findProfessorById(new ObjectId(id)) .orElseThrow(() -> { log.warn("[updateProfessor] 교수 ID '{}' 정보가 존재하지 않음", id); - return new ProfessorNotFoundException("교수 정보를 찾을 수 없습니다."); + return new InfoException(InfoErrorCode.PROFESSOR_NOT_FOUND); }); professor.update(professorCreateUpdateRequestDto); infoRepository.save(professor); @@ -66,7 +66,7 @@ public void deleteProfessor(String id) { Professor professor = infoRepository.findProfessorById(new ObjectId(id)) .orElseThrow(() -> { log.warn("[deleteProfessor] 교수 ID '{}' 정보가 존재하지 않음", id); - return new ProfessorNotFoundException("교수 정보를 찾을 수 없습니다."); + return new InfoException(InfoErrorCode.PROFESSOR_NOT_FOUND); });professor.delete(); infoRepository.save(professor); log.info("[deleteProfessor] {} 교수님의 정보 삭제", professor.get_id().toString()); diff --git a/src/main/resources b/src/main/resources index 51c30539..50cfe48f 160000 --- a/src/main/resources +++ b/src/main/resources @@ -1 +1 @@ -Subproject commit 51c30539c96620229babf5d98ac909a989a214e6 +Subproject commit 50cfe48f2b60416ef75f21fc3cc58c570bc84f4b diff --git a/src/test/java/inu/codin/codin/domain/info/service/PartnerServiceTest.java b/src/test/java/inu/codin/codin/domain/info/service/PartnerServiceTest.java new file mode 100644 index 00000000..efc5f3a2 --- /dev/null +++ b/src/test/java/inu/codin/codin/domain/info/service/PartnerServiceTest.java @@ -0,0 +1,139 @@ +package inu.codin.codin.domain.info.service; + +import inu.codin.codin.domain.info.dto.request.PartnerCreateRequestDto; +import inu.codin.codin.domain.info.dto.response.PartnerDetailsResponseDto; +import inu.codin.codin.domain.info.dto.response.PartnerListResponseDto; +import inu.codin.codin.domain.info.entity.Partner; +import inu.codin.codin.domain.info.entity.PartnerImg; +import inu.codin.codin.domain.info.exception.InfoErrorCode; +import inu.codin.codin.domain.info.exception.InfoException; +import inu.codin.codin.domain.info.repository.PartnerRepository; +import inu.codin.codin.infra.s3.S3Service; +import org.bson.types.ObjectId; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class PartnerServiceTest { + + @InjectMocks + PartnerService partnerService; + + @Mock + PartnerRepository partnerRepository; + + @Mock + S3Service s3Service; + + @Test + @DisplayName("제휴업체 목록 조회") + void 제휴업체_목록_반환() { + //given + Partner partner = mock(Partner.class); + given(partner.get_id()).willReturn(new ObjectId()); + given(partner.getImg()).willReturn(new PartnerImg("img1", List.of("img2"))); + + given(partnerRepository.findAll()).willReturn(List.of(partner)); + + //when + List responseDtos = partnerService.getPartnerList(); + + //then + assertThat(responseDtos).hasSize(1); + } + + @Test + @DisplayName("제휴업체 상세 조회 - 성공") + void 제휴업체_상세_조회_성공() { + //given + String partnerId = new ObjectId().toString(); + Partner partner = mock(Partner.class); + given(partnerRepository.findById(new ObjectId(partnerId))).willReturn(Optional.ofNullable(partner)); + + //when + PartnerDetailsResponseDto responseDto = partnerService.getPartnerDetails(partnerId); + + //then + assertNotNull(responseDto); + } + + @Test + @DisplayName("제휴업체 상세 조회 - 성공") + void 제휴업체_상세_조회_실패() { + //given + String partnerId = new ObjectId().toString(); + given(partnerRepository.findById(new ObjectId(partnerId))).willReturn(Optional.empty()); + + //when & then + assertThatThrownBy(() -> partnerService.getPartnerDetails(partnerId)) + .isInstanceOf(InfoException.class) + .hasMessageContaining(InfoErrorCode.PARTNER_NOT_FOUND.message()); + } + + @Test + @DisplayName("제휴업체 생성") + void 제휴업체_생성() { + //given + PartnerCreateRequestDto requestDto = mock(PartnerCreateRequestDto.class); + MultipartFile mainImage = mock(MultipartFile.class); + List subImage = List.of(mock(MultipartFile.class)); + + given(s3Service.handleImageUpload(List.of(mainImage))).willReturn(List.of("mainImage")); + given(s3Service.handleImageUpload(subImage)).willReturn(List.of("subImage1", "subImage2")); + + //when + partnerService.createPartner(requestDto, mainImage, subImage); + + //then + ArgumentCaptor captor = ArgumentCaptor.forClass(Partner.class); + verify(partnerRepository, times(1)).save(captor.capture()); + + Partner savedPartner = captor.getValue(); + assertNotNull(savedPartner); + } + + @Test + @DisplayName("이미지 없이 제휴업체 생성 성공") + void 이미지_없이_제휴업체_생성_성공(){ + //given + PartnerCreateRequestDto requestDto = mock(PartnerCreateRequestDto.class); + + //when + partnerService.createPartner(requestDto, null, null); + + //then + ArgumentCaptor captor = ArgumentCaptor.forClass(Partner.class); + verify(partnerRepository, times(1)).save(captor.capture()); + + Partner savedPartner = captor.getValue(); + assertNotNull(savedPartner); + } + + @Test + @DisplayName("제휴업체 삭제") + void 제휴업체_삭제() { + //given + String partnerId = new ObjectId().toString(); + + //when + partnerService.deletePartner(partnerId); + + //then + verify(partnerRepository, times(1)).deleteById(new ObjectId(partnerId)); + } +} \ No newline at end of file