diff --git a/src/main/java/org/sopt/sopkerton/common/exception/ProgramError.java b/src/main/java/org/sopt/sopkerton/common/exception/ProgramError.java deleted file mode 100644 index 14e335b..0000000 --- a/src/main/java/org/sopt/sopkerton/common/exception/ProgramError.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.sopt.sopkerton.common.exception; - -public enum ProgramError { -} diff --git a/src/main/java/org/sopt/sopkerton/program/controller/ProgramController.java b/src/main/java/org/sopt/sopkerton/program/controller/ProgramController.java index 449c87f..5ab3b87 100644 --- a/src/main/java/org/sopt/sopkerton/program/controller/ProgramController.java +++ b/src/main/java/org/sopt/sopkerton/program/controller/ProgramController.java @@ -2,14 +2,12 @@ import java.util.List; import lombok.RequiredArgsConstructor; -import org.sopt.sopkerton.common.exception.ProgramSuccess; +import org.sopt.sopkerton.program.domain.exception.ProgramSuccess; import org.sopt.sopkerton.common.response.ApiResponse; -import org.sopt.sopkerton.program.dto.request.ProgramListRequest; import org.sopt.sopkerton.program.dto.response.ProgramListResponse; import org.sopt.sopkerton.program.service.ProgramService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -29,4 +27,16 @@ public ResponseEntity>> programListView(@R ApiResponse.success(ProgramSuccess.PROGRAM_LIST_VIEW_SUCCESS, programListByProgramType) ); } + + @GetMapping("/detail") + public ResponseEntity orderProgramDetail( + @RequestParam("programId") Long programId + ) { + Object programDetail = programService.getProgramDetail(1L, programId); + return ResponseEntity + .status(ProgramSuccess.PROGRAM_DETAIL_VIEW_SUCCESS.getHttpStatus()) + .body( + ApiResponse.success(ProgramSuccess.PROGRAM_DETAIL_VIEW_SUCCESS, programDetail) + ); + } } diff --git a/src/main/java/org/sopt/sopkerton/program/domain/exception/ProgramError.java b/src/main/java/org/sopt/sopkerton/program/domain/exception/ProgramError.java new file mode 100644 index 0000000..56241d1 --- /dev/null +++ b/src/main/java/org/sopt/sopkerton/program/domain/exception/ProgramError.java @@ -0,0 +1,29 @@ +package org.sopt.sopkerton.program.domain.exception; + +import lombok.AllArgsConstructor; +import org.sopt.sopkerton.common.exception.base.ErrorBase; +import org.springframework.http.HttpStatus; + +@AllArgsConstructor +public enum ProgramError implements ErrorBase { + PROGRAM_NOT_FOUND(HttpStatus.NOT_FOUND, "Can not found Program."), + + ; + + private final HttpStatus status; + private final String errorMessage; + @Override + public int getHttpStatusCode() { + return this.status.value(); + } + + @Override + public HttpStatus getHttpStatus() { + return this.status; + } + + @Override + public String getErrorMessage() { + return this.errorMessage; + } +} diff --git a/src/main/java/org/sopt/sopkerton/program/domain/exception/ProgramException.java b/src/main/java/org/sopt/sopkerton/program/domain/exception/ProgramException.java new file mode 100644 index 0000000..768c8e7 --- /dev/null +++ b/src/main/java/org/sopt/sopkerton/program/domain/exception/ProgramException.java @@ -0,0 +1,9 @@ +package org.sopt.sopkerton.program.domain.exception; + +import org.sopt.sopkerton.common.exception.base.ExceptionBase; + +public class ProgramException extends ExceptionBase { + public ProgramException(ProgramError errorBase) { + super(errorBase); + } +} diff --git a/src/main/java/org/sopt/sopkerton/common/exception/ProgramSuccess.java b/src/main/java/org/sopt/sopkerton/program/domain/exception/ProgramSuccess.java similarity index 79% rename from src/main/java/org/sopt/sopkerton/common/exception/ProgramSuccess.java rename to src/main/java/org/sopt/sopkerton/program/domain/exception/ProgramSuccess.java index 893ec06..c95967e 100644 --- a/src/main/java/org/sopt/sopkerton/common/exception/ProgramSuccess.java +++ b/src/main/java/org/sopt/sopkerton/program/domain/exception/ProgramSuccess.java @@ -1,4 +1,4 @@ -package org.sopt.sopkerton.common.exception; +package org.sopt.sopkerton.program.domain.exception; import lombok.AllArgsConstructor; import org.sopt.sopkerton.common.exception.base.SuccessBase; @@ -6,7 +6,8 @@ @AllArgsConstructor public enum ProgramSuccess implements SuccessBase { - PROGRAM_LIST_VIEW_SUCCESS(HttpStatus.OK, "Get Program List View Data Successful.") + PROGRAM_LIST_VIEW_SUCCESS(HttpStatus.OK, "Get Program List View Data Successful."), + PROGRAM_DETAIL_VIEW_SUCCESS(HttpStatus.OK, "Get Program Detail View Data Successful.") ; private final HttpStatus status; diff --git a/src/main/java/org/sopt/sopkerton/program/dto/response/ProgramDetailResponse.java b/src/main/java/org/sopt/sopkerton/program/dto/response/ProgramDetailResponse.java new file mode 100644 index 0000000..d4bdf3f --- /dev/null +++ b/src/main/java/org/sopt/sopkerton/program/dto/response/ProgramDetailResponse.java @@ -0,0 +1,38 @@ +package org.sopt.sopkerton.program.dto.response; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public abstract class ProgramDetailResponse { + + public record VolunteerDetail( + @JsonProperty("imageUrl") + String imageUrl, + @JsonProperty("content") + String content, + @JsonProperty("organizationName") + String organizationName, + @JsonProperty("registerAt") + String registerAt, + @JsonProperty("hour") + int hour, + @JsonProperty("isApply") + boolean isApply + ) { + } + + public record EmploymentDetail( + @JsonProperty("imageUrl") + String imageUrl, + @JsonProperty("content") + String content, + @JsonProperty("organizationName") + String organizationName, + @JsonProperty("registerAt") + String registerAt, + @JsonProperty("salary") + int salary, + @JsonProperty("isApply") + boolean isApply + ) { + } +} diff --git a/src/main/java/org/sopt/sopkerton/program/infrastructure/ProgramRepository.java b/src/main/java/org/sopt/sopkerton/program/infrastructure/ProgramRepository.java index 158051d..686b782 100644 --- a/src/main/java/org/sopt/sopkerton/program/infrastructure/ProgramRepository.java +++ b/src/main/java/org/sopt/sopkerton/program/infrastructure/ProgramRepository.java @@ -1,6 +1,7 @@ package org.sopt.sopkerton.program.infrastructure; import java.util.List; + import org.sopt.sopkerton.program.domain.Program; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -10,4 +11,5 @@ public interface ProgramRepository extends JpaRepository { @Query("select p from Program p where p.type = :type order by p.registerAt") List findAllByProgramType(@Param("type")String programType); + } diff --git a/src/main/java/org/sopt/sopkerton/program/service/ProgramService.java b/src/main/java/org/sopt/sopkerton/program/service/ProgramService.java index 9aca4db..caa8769 100644 --- a/src/main/java/org/sopt/sopkerton/program/service/ProgramService.java +++ b/src/main/java/org/sopt/sopkerton/program/service/ProgramService.java @@ -6,14 +6,24 @@ import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.sopt.sopkerton.program.domain.Program; +import org.sopt.sopkerton.program.domain.exception.ProgramError; +import org.sopt.sopkerton.program.domain.exception.ProgramException; +import org.sopt.sopkerton.program.dto.response.ProgramDetailResponse; import org.sopt.sopkerton.program.dto.response.ProgramListResponse; import org.sopt.sopkerton.program.infrastructure.ProgramRepository; +import org.sopt.sopkerton.user.domain.Apply; +import org.sopt.sopkerton.user.domain.enums.ApplyStatus; +import org.sopt.sopkerton.user.infrastructure.ApplyRepository; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class ProgramService { + private static final String VOLUNTEER_TYPE = "VOLUNTEERING"; + private static final String EMPLOYMENT_TYPE = "EMPLOYMENT"; + private final ProgramRepository programRepository; + private final ApplyRepository applyRepository; public List getProgramListByProgramType(String programType) { List programs = programRepository.findAllByProgramType(programType); @@ -31,10 +41,40 @@ public List getProgramListByProgramType(String programType) return programListResponses; } + public Object getProgramDetail(Long userId, Long programId) { + Program program = programRepository.findById(programId) + .orElseThrow(() -> new ProgramException(ProgramError.PROGRAM_NOT_FOUND)); + Apply apply = applyRepository.findByUserIdAndProgramId(userId, programId).get(); + boolean isApply = convertToIsApply(apply.getIsApply()); + if (program.getType().equals(VOLUNTEER_TYPE)) { + return new ProgramDetailResponse.VolunteerDetail( + program.getImageUrl(), + program.getContent(), + program.getOrganizationName(), + formatToLocalDate(program.getRegisterAt()), + program.getVolunteerHours(), + isApply + ); + } + if (program.getType().equals(EMPLOYMENT_TYPE)){ + return new ProgramDetailResponse.EmploymentDetail( + program.getImageUrl(), + program.getContent(), + program.getOrganizationName(), + formatToLocalDate(program.getRegisterAt()), + program.getSalary(), + isApply + ); + } + return null; + } + private String formatToLocalDate(LocalDateTime localDateTime) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM월 dd일"); return localDateTime.format(formatter); } - + private boolean convertToIsApply(ApplyStatus status) { + return status.equals(ApplyStatus.APPLY); + } } diff --git a/src/main/java/org/sopt/sopkerton/user/domain/Apply.java b/src/main/java/org/sopt/sopkerton/user/domain/Apply.java new file mode 100644 index 0000000..fa5700d --- /dev/null +++ b/src/main/java/org/sopt/sopkerton/user/domain/Apply.java @@ -0,0 +1,29 @@ +package org.sopt.sopkerton.user.domain; + +import jakarta.persistence.*; +import lombok.*; +import org.sopt.sopkerton.common.domain.BaseEntity; +import org.sopt.sopkerton.user.domain.enums.ApplyStatus; + +@Getter +@Entity +@Table(schema = "skt-t1-app", name = "applies") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Builder +public class Apply extends BaseEntity { + @Id + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; + + @Column(name = "user_id", nullable = false) + Long userId; + + @Column(name = "program_id", nullable = false) + Long programId; + + @Column(name = "is_apply", nullable = false) + @Enumerated(value = EnumType.STRING) + ApplyStatus isApply; +} diff --git a/src/main/java/org/sopt/sopkerton/user/domain/enums/ApplyStatus.java b/src/main/java/org/sopt/sopkerton/user/domain/enums/ApplyStatus.java new file mode 100644 index 0000000..b467276 --- /dev/null +++ b/src/main/java/org/sopt/sopkerton/user/domain/enums/ApplyStatus.java @@ -0,0 +1,7 @@ +package org.sopt.sopkerton.user.domain.enums; + +public enum ApplyStatus { + + APPLY, UNAPPLY + +} diff --git a/src/main/java/org/sopt/sopkerton/user/infrastructure/ApplyRepository.java b/src/main/java/org/sopt/sopkerton/user/infrastructure/ApplyRepository.java new file mode 100644 index 0000000..2ecd2e9 --- /dev/null +++ b/src/main/java/org/sopt/sopkerton/user/infrastructure/ApplyRepository.java @@ -0,0 +1,11 @@ +package org.sopt.sopkerton.user.infrastructure; + +import org.sopt.sopkerton.user.domain.Apply; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface ApplyRepository extends JpaRepository { + + Optional findByUserIdAndProgramId(Long userId, Long programId); +}