diff --git a/build.gradle b/build.gradle index 0d6420f..107ddb1 100644 --- a/build.gradle +++ b/build.gradle @@ -46,6 +46,9 @@ dependencies { // https://mvnrepository.com/artifact/com.auth0/java-jwt implementation group: 'com.auth0', name: 'java-jwt', version: '4.3.0' + //Entity <-> DTO Converter + implementation group: 'org.modelmapper', name: 'modelmapper', version: '2.3.8' + implementation('org.springframework.boot:spring-boot-starter') diff --git a/src/main/java/com/example/rcp1/domain/recruitment/application/RecruitmentService.java b/src/main/java/com/example/rcp1/domain/recruitment/application/RecruitmentService.java index a6f3525..c3978aa 100644 --- a/src/main/java/com/example/rcp1/domain/recruitment/application/RecruitmentService.java +++ b/src/main/java/com/example/rcp1/domain/recruitment/application/RecruitmentService.java @@ -6,44 +6,38 @@ import com.example.rcp1.domain.recruitment.domain.repository.FieldRepository; import com.example.rcp1.domain.recruitment.domain.repository.PostRepository; import com.example.rcp1.domain.recruitment.dto.FieldDTO; -import com.example.rcp1.domain.recruitment.dto.PostDTO; +import com.example.rcp1.domain.recruitment.dto.PostReqDTO; +import com.example.rcp1.domain.recruitment.dto.PostResDTO; import com.example.rcp1.domain.user.domain.User; import com.example.rcp1.domain.user.domain.repository.UserRepository; import com.example.rcp1.global.config.security.util.JwtUtil; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; +import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; @Service +@RequiredArgsConstructor public class RecruitmentService { - - private final PostRepository postRepository; - @Value("${SECRET_KEY}") private String secretKey; private final UserRepository userRepository; + private final PostRepository postRepository; private final FieldRepository fieldRepository; - - @Autowired - public RecruitmentService(PostRepository postRepository, - UserRepository userRepository, FieldRepository fieldRepository) { - this.postRepository = postRepository; - this.userRepository = userRepository; - this.fieldRepository = fieldRepository; - } + private final ModelMapper modelMapper = new ModelMapper(); @Transactional - public Post createRecruitmentPost(String token, PostDTO postDTO) { - System.out.println("service called"); + public Post createRecruitmentPost(String token, PostReqDTO postDTO) { String email = JwtUtil.getUserEmail(token, secretKey); Optional user = userRepository.findByEmail(email); if (user.isPresent()) { - System.out.println("email searched"); System.out.println(postDTO.toString()); Post post = Post.builder() @@ -64,15 +58,50 @@ public Post createRecruitmentPost(String token, PostDTO postDTO) { field.setName(fieldDTO.getName()); post.addField(field); } - // Post 엔티티 저장 postRepository.save(post); - System.out.println("post saved. post = "+post.toString()); - return post; // Post 엔티티 반환 } + return null; + } + + public List retrieveAllRecruitmentPosts(){ + List posts = postRepository.findAll(); + if(posts!=null){ + List postDTOs = new ArrayList(); + for(Post post : posts){ + //ModelMapper.map : ENTITY -> DTO + postDTOs.add(modelMapper.map(post, PostResDTO.class)); + } + return postDTOs; + } + return null; + } + + public PostResDTO retrieveRecruitmentPostById(Long postId) { + Optional postOptional = postRepository.findById(postId); + PostResDTO postResDTO = null; + if(postOptional.isPresent()){ + Post post = postOptional.get(); + postResDTO = modelMapper.map(post, PostResDTO.class); + } + return postResDTO; + } + public List retrieveRecruitmentPostsOfCurrentCompany(String token) { + String email = JwtUtil.getUserEmail(token, secretKey); + Optional user = userRepository.findByEmail(email); + if (user.isPresent()) { + List posts = postRepository.findByUser_Id(user.get().getId()); + List postDTOs = new ArrayList(); + for(Post post : posts){ + //ModelMapper.map : ENTITY -> DTO + postDTOs.add(modelMapper.map(post, PostResDTO.class)); + } + return postDTOs; + } return null; } + } diff --git a/src/main/java/com/example/rcp1/domain/recruitment/domain/repository/PostRepository.java b/src/main/java/com/example/rcp1/domain/recruitment/domain/repository/PostRepository.java index a7bb1ca..b1c7b91 100644 --- a/src/main/java/com/example/rcp1/domain/recruitment/domain/repository/PostRepository.java +++ b/src/main/java/com/example/rcp1/domain/recruitment/domain/repository/PostRepository.java @@ -3,9 +3,14 @@ import com.example.rcp1.domain.recruitment.domain.Post; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Optional; + @Repository public interface PostRepository extends JpaRepository { - + List findByUser_Id(Long userId); } diff --git a/src/main/java/com/example/rcp1/domain/recruitment/dto/PostDTO.java b/src/main/java/com/example/rcp1/domain/recruitment/dto/PostReqDTO.java similarity index 85% rename from src/main/java/com/example/rcp1/domain/recruitment/dto/PostDTO.java rename to src/main/java/com/example/rcp1/domain/recruitment/dto/PostReqDTO.java index 60b997d..25fca26 100644 --- a/src/main/java/com/example/rcp1/domain/recruitment/dto/PostDTO.java +++ b/src/main/java/com/example/rcp1/domain/recruitment/dto/PostReqDTO.java @@ -1,17 +1,15 @@ package com.example.rcp1.domain.recruitment.dto; -import com.example.rcp1.domain.recruitment.domain.Field; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import lombok.Data; import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.HashSet; import java.util.Set; @Data -public class PostDTO { +public class PostReqDTO { @NotBlank private String title; diff --git a/src/main/java/com/example/rcp1/domain/recruitment/dto/PostResDTO.java b/src/main/java/com/example/rcp1/domain/recruitment/dto/PostResDTO.java new file mode 100644 index 0000000..b4c530c --- /dev/null +++ b/src/main/java/com/example/rcp1/domain/recruitment/dto/PostResDTO.java @@ -0,0 +1,43 @@ +package com.example.rcp1.domain.recruitment.dto; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; + +@Data +public class PostResDTO { //반환용 DTO + @NotBlank + private Long id; + + @NotBlank + private Long userId; + + @NotBlank + private String title; + + @NotBlank + private String company_photo_url; + + @Min(0) + private int compensation_recommender = 0; + + @Min(0) + private int compensation_applicant = 0; + + private LocalDate dueDate; + + @Min(0) + private int heart = 0; + + @NotBlank + private String content; + + @NotBlank + private String working_address; + + Set fields = new HashSet<>(); +} diff --git a/src/main/java/com/example/rcp1/domain/recruitment/presentation/RecruitmentController.java b/src/main/java/com/example/rcp1/domain/recruitment/presentation/RecruitmentController.java index 460bae4..958b8c3 100644 --- a/src/main/java/com/example/rcp1/domain/recruitment/presentation/RecruitmentController.java +++ b/src/main/java/com/example/rcp1/domain/recruitment/presentation/RecruitmentController.java @@ -3,26 +3,28 @@ import com.example.rcp1.domain.recruitment.application.RecruitmentService; import com.example.rcp1.domain.recruitment.domain.Post; -import com.example.rcp1.domain.recruitment.dto.PostDTO; +import com.example.rcp1.domain.recruitment.dto.PostReqDTO; +import com.example.rcp1.domain.recruitment.dto.PostResDTO; import com.example.rcp1.global.BaseResponse; import com.example.rcp1.global.ErrorCode; import com.example.rcp1.global.SuccessCode; import jakarta.validation.Valid; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.List; + @RequestMapping("/recruiting") @RestController +@RequiredArgsConstructor public class RecruitmentController { + private final RecruitmentService recruitmentService; - @Autowired - private RecruitmentService recruitmentService; - - + //채용공고 생성 @PostMapping("/posts") - public ResponseEntity> createRecruitmentPost(@RequestHeader("Authorization") String Authorization, @Valid @RequestBody PostDTO postDTO) { + public ResponseEntity> createRecruitmentPost(@RequestHeader("Authorization") String Authorization, @Valid @RequestBody PostReqDTO postDTO) { try { String token = Authorization.substring(7); Post post = recruitmentService.createRecruitmentPost(token, postDTO); @@ -32,4 +34,50 @@ public ResponseEntity> createRecruitmentPost(@RequestHeader(" .body(BaseResponse.error(ErrorCode.REQUEST_VALIDATION_EXCEPTION, "채용공고 게시에 실패했습니다.")); } } + + //전체 채용공고 리스트 조회 + @GetMapping("/posts") + public ResponseEntity>> retrieveAllRecruitmentPostList(){ + try { + List posts = recruitmentService.retrieveAllRecruitmentPosts(); + return ResponseEntity.ok(BaseResponse.success(SuccessCode.POST_RETRIEVAL_SUCCESS, posts)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(BaseResponse.error(ErrorCode.REQUEST_VALIDATION_EXCEPTION, "채용공고 조회에 실패했습니다.")); + } + } + + //특정 채용공고 조회 + @GetMapping("/posts/{postId}") + public ResponseEntity> retrieveRecruitmentPostById(@PathVariable Long postId){ + try { + PostResDTO post = recruitmentService.retrieveRecruitmentPostById(postId); + if (post != null) { + return ResponseEntity.ok(BaseResponse.success(SuccessCode.POST_RETRIEVAL_SUCCESS, post)); + } else { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(BaseResponse.error(ErrorCode.NOT_FOUND, "채용공고를 찾을 수 없습니다.")); + } + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(BaseResponse.error(ErrorCode.REQUEST_VALIDATION_EXCEPTION, "채용공고 조회에 실패했습니다.")); + } + } + + //현재 로그인한 기업 유저가 작성한 채용공고 리스트 조회 + @GetMapping("/posts/mine") + public ResponseEntity>> retrieveRecruitmentPostsOfCurrentCompany(@RequestHeader("Authorization") String Authorization){ + try { + String token = Authorization.substring(7); + List posts = recruitmentService.retrieveRecruitmentPostsOfCurrentCompany(token); + return ResponseEntity.ok(BaseResponse.success(SuccessCode.POST_RETRIEVAL_SUCCESS, posts)); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(BaseResponse.error(ErrorCode.REQUEST_VALIDATION_EXCEPTION, "채용공고 조회에 실패했습니다.")); + } + } + + + + } diff --git a/src/main/java/com/example/rcp1/global/ErrorCode.java b/src/main/java/com/example/rcp1/global/ErrorCode.java index 9d1adfa..769a73c 100644 --- a/src/main/java/com/example/rcp1/global/ErrorCode.java +++ b/src/main/java/com/example/rcp1/global/ErrorCode.java @@ -11,7 +11,8 @@ public enum ErrorCode { // api 만들고 수정하기 REQUEST_VALIDATION_EXCEPTION(BAD_REQUEST, "잘못된 요청입니니다."), - EXPIRED_TOKEN(UNAUTHORIZED, "만료된 토큰입니다."); + EXPIRED_TOKEN(UNAUTHORIZED, "만료된 토큰입니다."), + NOT_FOUND(HttpStatus.NOT_FOUND, "요청한 리소스를 찾을 수 없습니다."); private final HttpStatus httpStatus; private final String message; diff --git a/src/main/java/com/example/rcp1/global/SuccessCode.java b/src/main/java/com/example/rcp1/global/SuccessCode.java index 5b41eeb..32145f0 100644 --- a/src/main/java/com/example/rcp1/global/SuccessCode.java +++ b/src/main/java/com/example/rcp1/global/SuccessCode.java @@ -10,23 +10,20 @@ @Getter @AllArgsConstructor public enum SuccessCode { - // api 만들고 수정하기 -// CUSTOM_SUCCESS(OK, "~ 조회에 성공했습니다."), -// CUSTOM_CREATED_SUCCESS(CREATED, "~ 생성에 성공했습니다."); SIGNUP_SUCCESS(OK, "회원가입에 성공했습니다."), SIGNIN_SUCCESS(OK, "로그인에 성공했습니다."), UPDATE_PROFILE_SUCCESS(OK, "프로필이 성공적으로 수정되었습니다."), LOGICAL_DELETE_SUCCESS(OK, "논리적으로 삭제 되었습니다."), POST_CREATED_SUCCESS(CREATED, "채용공고 생성에 성공했습니다."), + POST_RETRIEVAL_SUCCESS(OK, "채용공고 조회에 성공했습니다."), CREATE_APPLY_SUCCESS(OK, "채용 공고에 지원서를 제출했습니다."), - DELETE_APPLY_SUCCESS(OK, "채용 공고에 대한 지원을 취소했습니다." ), + DELETE_APPLY_SUCCESS(OK, "채용 공고에 대한 지원을 취소했습니다."), GET_STATUS_SUCCESS(OK, "지원 현황 조회 성공"), STATUS_SETTING_SUCCESS(OK, "지원자의 상태가 변경되었습니다."); private final HttpStatus httpStatus; private final String message; - public int getHttpStatusCode() { return httpStatus.value(); }