Skip to content

Commit 2ccb13c

Browse files
authored
Merge pull request #81 from prgrms-be-devcourse/dev/refactor/jobpost/#64
JobPost 추가 기능 구현 및 Apply 기능 수정
2 parents 9b581a3 + e653162 commit 2ccb13c

24 files changed

+833
-311
lines changed

Diff for: src/main/java/com/prgrms2/java/bitta/apply/controller/ApplyController.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
import io.swagger.v3.oas.annotations.media.Schema;
1010
import io.swagger.v3.oas.annotations.responses.ApiResponse;
1111
import io.swagger.v3.oas.annotations.tags.Tag;
12+
import jakarta.validation.Valid;
1213
import lombok.RequiredArgsConstructor;
1314
import org.springframework.http.ResponseEntity;
15+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
1416
import org.springframework.web.bind.annotation.*;
1517

1618
import java.util.List;
@@ -66,8 +68,9 @@ public ResponseEntity<List<ApplyDTO>> findAll(Member member) {
6668
)
6769
}
6870
)
71+
6972
@PostMapping
70-
public ResponseEntity<ApplyDTO> registerApply(@RequestBody ApplyDTO applyDTO) {
73+
public ResponseEntity<Map<String, Object>> registerApply(@Valid @RequestBody ApplyDTO applyDTO) {
7174
return ResponseEntity.ok(applyService.register(applyDTO));
7275
}
7376

@@ -101,8 +104,9 @@ public ResponseEntity<ApplyDTO> registerApply(@RequestBody ApplyDTO applyDTO) {
101104
schema = @Schema(type = "integer")
102105
)
103106
@GetMapping("/{id}")
104-
public ResponseEntity<ApplyDTO> readApply(@PathVariable("id") Long id) {
105-
return ResponseEntity.ok(applyService.read(id));
107+
public ResponseEntity<ApplyDTO> readApply(@PathVariable("id") Long id, @AuthenticationPrincipal Member member) {
108+
ApplyDTO applyDTO = applyService.readByIdAndMember(id, member);
109+
return ResponseEntity.ok(applyDTO);
106110
}
107111

108112
@Operation(
@@ -143,8 +147,8 @@ public ResponseEntity<ApplyDTO> readApply(@PathVariable("id") Long id) {
143147
schema = @Schema(type = "integer")
144148
)
145149
@DeleteMapping("/{id}")
146-
public ResponseEntity<Map<String, String>> deleteApply(@PathVariable("id") Long id) {
150+
public ResponseEntity<Map<String, String>> deleteApply(@Valid @PathVariable("id") Long id) {
147151
applyService.delete(id);
148-
return ResponseEntity.ok(Map.of("message", "delete complete"));
152+
return ResponseEntity.ok(Map.of("message", "삭제가 완료되었습니다"));
149153
}
150154
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.prgrms2.java.bitta.apply.controller.advice;
2+
3+
import com.prgrms2.java.bitta.apply.exception.ApplyTaskException;
4+
import org.springframework.http.ResponseEntity;
5+
import org.springframework.web.bind.annotation.ExceptionHandler;
6+
import org.springframework.web.bind.annotation.RestControllerAdvice;
7+
8+
import java.util.Map;
9+
10+
@RestControllerAdvice
11+
public class ApplyControllerAdvice {
12+
13+
@ExceptionHandler(ApplyTaskException.class)
14+
public ResponseEntity<Map<String, String>> handleApplyTaskException(ApplyTaskException e) {
15+
return ResponseEntity.status(e.getCode())
16+
.body(Map.of("error", e.getMessage()));
17+
}
18+
}
19+

Diff for: src/main/java/com/prgrms2/java/bitta/apply/dto/ApplyDTO.java

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.prgrms2.java.bitta.apply.dto;
22

33
import io.swagger.v3.oas.annotations.media.Schema;
4+
import jakarta.validation.constraints.Min;
5+
import jakarta.validation.constraints.NotNull;
46
import lombok.AllArgsConstructor;
57
import lombok.Builder;
68
import lombok.Data;
@@ -15,14 +17,20 @@
1517
@Schema(title = "지원서 DTO", description = "지원서 요청 및 응답에 사용하는 DTO입니다.")
1618
public class ApplyDTO {
1719
@Schema(title = "지원서 ID (PK)", description = "지원서의 고유 ID 입니다.", example = "1", minimum = "1")
20+
@Min(value = 1, message = "ID는 음수가 될 수 없습니다")
1821
private Long id;
1922

2023
@Schema(title = "일거리 ID (FK)", description = "일거리의 고유 ID 입니다.", example = "1", minimum = "1")
24+
@Min(value = 1, message = "ID는 음수가 될 수 없습니다")
25+
@NotNull(message = "게시글의 ID가 필요합니다")
2126
private Long jobPostId;
2227

2328
@Schema(title = "회원 ID (FK)", description = "회원의 고유 ID 입니다.", example = "1", minimum = "1")
29+
@Min(value = 1, message = "ID는 음수가 될 수 없습니다")
30+
@NotNull(message = "회원의 ID가 필요합니다")
2431
private Long memberId;
2532

2633
@Schema(title = "지원서 생성일시", description = "지원서가 생성된 날짜 및 시간입니다.", example = "2023-09-24T14:45:00")
2734
private LocalDateTime appliedAt;
35+
2836
}

Diff for: src/main/java/com/prgrms2/java/bitta/apply/exception/ApplyException.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.prgrms2.java.bitta.apply.exception;
22

33
public enum ApplyException {
4-
NOT_FOUND("NOT_FOUND", 404),
5-
NOT_REGISTERED("NOT_REGISTERED", 400),
6-
NOT_MODIFIED("NOT_MODIFIED", 400),
7-
NOT_REMOVED("NOT_REMOVED", 400),
8-
NOT_FETCHED("NOT_FETCHED", 400);
4+
NOT_FOUND("지원서를 찾을 수 없습니다", 404),
5+
NOT_REGISTERED("지원서가 등록되지 않았습니다", 400),
6+
NOT_MODIFIED("지원서가 수정되지 않았습니다", 400),
7+
NOT_REMOVED("지원서가 삭제되지 않았습니다", 400),
8+
NOT_FETCHED("지원서 조회에 실패하였습니다", 400);
99

1010
private ApplyTaskException applyTaskException;
1111

Diff for: src/main/java/com/prgrms2/java/bitta/apply/repository/ApplyRepository.java

+5
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,9 @@ public interface ApplyRepository extends JpaRepository<Apply, Long> {
2121

2222
@Query("SELECT a FROM Apply a WHERE a.id = :id")
2323
Optional<ApplyDTO> getApplyDTO(@Param("id") Long id);
24+
25+
@Query("DELETE FROM Apply a WHERE a.id = :id")
26+
int deleteByIdAndReturnCount(Long id);
27+
28+
Optional<Apply> findByIdAndMember(Long id, Member member);
2429
}

Diff for: src/main/java/com/prgrms2/java/bitta/apply/service/ApplyService.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@
22

33
import com.prgrms2.java.bitta.apply.dto.ApplyDTO;
44
import com.prgrms2.java.bitta.member.entity.Member;
5+
import org.springframework.http.ResponseEntity;
56

67
import java.util.List;
8+
import java.util.Map;
79

810
public interface ApplyService {
911
List<ApplyDTO> readAll(Member member);
1012

11-
ApplyDTO register(ApplyDTO applyDTO);
13+
Map<String, Object> register(ApplyDTO applyDTO);
1214

1315
void delete(Long id);
1416

1517
ApplyDTO read(Long id);
18+
19+
ApplyDTO readByIdAndMember(Long id, Member member);
1620
}

Diff for: src/main/java/com/prgrms2/java/bitta/apply/service/ApplyServiceImpl.java

+17-11
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
import lombok.extern.slf4j.Slf4j;
1212
import org.springframework.stereotype.Service;
1313

14-
import java.util.List;
15-
import java.util.Optional;
14+
import java.util.*;
1615

1716
@Slf4j
1817
@Service
@@ -34,11 +33,16 @@ public List<ApplyDTO> readAll(Member member) {
3433
}
3534

3635
@Override
37-
public ApplyDTO register(ApplyDTO applyDTO) {
36+
public Map<String, Object> register(ApplyDTO applyDTO) {
3837
try {
3938
Apply apply = dtoToEntity(applyDTO);
4039
apply = applyRepository.save(apply);
41-
return entityToDto(apply);
40+
41+
Map<String, Object> response = new HashMap<>();
42+
response.put("message", apply.getMember().getNickname() + "님 지원 완료");
43+
response.put("data", entityToDto(apply));
44+
45+
return response;
4246
} catch (Exception e) {
4347
log.error(e.getMessage());
4448
throw ApplyException.NOT_REGISTERED.get();
@@ -47,13 +51,7 @@ public ApplyDTO register(ApplyDTO applyDTO) {
4751

4852
@Override
4953
public void delete(Long id) {
50-
Optional<Apply> deleteApply = applyRepository.findById(id);
51-
Apply apply = deleteApply.orElseThrow(ApplyException.NOT_FOUND::get);
52-
53-
try {
54-
applyRepository.delete(apply);
55-
} catch (Exception e) {
56-
log.error(e.getMessage());
54+
if (applyRepository.deleteByIdAndReturnCount(id) == 0) {
5755
throw ApplyException.NOT_REMOVED.get();
5856
}
5957
}
@@ -64,6 +62,14 @@ public ApplyDTO read(Long id) {
6462
return applyDTO.orElseThrow(ApplyException.NOT_FOUND::get);
6563
}
6664

65+
@Override
66+
public ApplyDTO readByIdAndMember(Long id, Member member) {
67+
Apply apply = applyRepository.findByIdAndMember(id, member)
68+
.orElseThrow(ApplyException.NOT_FOUND::get);
69+
return entityToDto(apply);
70+
}
71+
72+
6773
private Apply dtoToEntity(ApplyDTO applyDTO) {
6874
return Apply.builder()
6975
.id(applyDTO.getId())

Diff for: src/main/java/com/prgrms2/java/bitta/apply/util/ApplyProvider.java

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.prgrms2.java.bitta.apply.util;
22

3+
import com.prgrms2.java.bitta.apply.dto.ApplyDTO;
34
import com.prgrms2.java.bitta.apply.entity.Apply;
45
import com.prgrms2.java.bitta.apply.repository.ApplyRepository;
56
import lombok.RequiredArgsConstructor;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.prgrms2.java.bitta.global.dto;
2+
3+
import jakarta.validation.constraints.Max;
4+
import jakarta.validation.constraints.Min;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Builder;
7+
import lombok.Data;
8+
import lombok.NoArgsConstructor;
9+
import org.springframework.data.domain.PageRequest;
10+
import org.springframework.data.domain.Pageable;
11+
import org.springframework.data.domain.Sort;
12+
13+
@Data
14+
@NoArgsConstructor
15+
@AllArgsConstructor
16+
@Builder
17+
public class PageRequestDTO {
18+
19+
@Builder.Default
20+
@Min(1)
21+
private int page = 1;
22+
23+
@Builder.Default
24+
@Min(10)
25+
@Max(100)
26+
private int size = 10;
27+
28+
public Pageable getPageable(Sort sort) {
29+
int pageNum = page < 0 ? 1 : page - 1;
30+
int sizeNum = size <= 10 ? 10 : size;
31+
32+
return PageRequest.of(pageNum, sizeNum, sort);
33+
}
34+
}

Diff for: src/main/java/com/prgrms2/java/bitta/jobpost/controller/JobPostController.java

+13-9
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
11
package com.prgrms2.java.bitta.jobpost.controller;
22

33
import com.prgrms2.java.bitta.jobpost.dto.JobPostDTO;
4+
import com.prgrms2.java.bitta.global.dto.PageRequestDTO;
45
import com.prgrms2.java.bitta.jobpost.service.JobPostService;
56
import io.swagger.v3.oas.annotations.Operation;
67
import io.swagger.v3.oas.annotations.Parameter;
78
import io.swagger.v3.oas.annotations.media.Content;
89
import io.swagger.v3.oas.annotations.media.Schema;
910
import io.swagger.v3.oas.annotations.responses.ApiResponse;
1011
import io.swagger.v3.oas.annotations.tags.Tag;
12+
import jakarta.validation.Valid;
1113
import lombok.RequiredArgsConstructor;
1214
import lombok.extern.log4j.Log4j2;
15+
import org.springframework.data.domain.Page;
1316
import org.springframework.http.ResponseEntity;
17+
import org.springframework.validation.annotation.Validated;
1418
import org.springframework.web.bind.annotation.*;
1519

16-
import java.util.List;
1720
import java.util.Map;
1821

1922
import static com.prgrms2.java.bitta.global.constants.ApiResponses.*;
2023

2124
@Tag(name = "일거리 API 컨트롤러", description = "일거리와 관련된 REST API를 제공하는 컨틀롤러입니다.")
2225
@RestController
2326
@RequiredArgsConstructor
24-
@RequestMapping("/api/v1/jobpost")
27+
@RequestMapping("/api/v1/job-post")
2528
@Log4j2
2629
public class JobPostController {
2730
private final JobPostService jobPostService;
@@ -48,9 +51,10 @@ public class JobPostController {
4851
)
4952
}
5053
)
54+
5155
@GetMapping
52-
public ResponseEntity<List<JobPostDTO>> findAll() {
53-
return ResponseEntity.ok(jobPostService.getList());
56+
public ResponseEntity<Page<JobPostDTO>> getList(@Valid PageRequestDTO pageRequestDTO) {
57+
return ResponseEntity.ok(jobPostService.getList(pageRequestDTO));
5458
}
5559

5660
@Operation(
@@ -76,7 +80,7 @@ public ResponseEntity<List<JobPostDTO>> findAll() {
7680
}
7781
)
7882
@PostMapping
79-
public ResponseEntity<JobPostDTO> registerJobPost(@RequestBody JobPostDTO jobPostDTO) {
83+
public ResponseEntity<JobPostDTO> registerJobPost(@Valid @RequestBody JobPostDTO jobPostDTO) {
8084
return ResponseEntity.ok(jobPostService.register(jobPostDTO));
8185
}
8286

@@ -110,7 +114,7 @@ public ResponseEntity<JobPostDTO> registerJobPost(@RequestBody JobPostDTO jobPos
110114
schema = @Schema(type = "integer")
111115
)
112116
@GetMapping("/{id}")
113-
public ResponseEntity<JobPostDTO> readJobPost(@PathVariable("id") Long id) {
117+
public ResponseEntity<JobPostDTO> readJobPost(@PathVariable("id") @Valid Long id) {
114118
return ResponseEntity.ok(jobPostService.read(id));
115119
}
116120

@@ -152,7 +156,7 @@ public ResponseEntity<JobPostDTO> readJobPost(@PathVariable("id") Long id) {
152156
schema = @Schema(type = "integer")
153157
)
154158
@PutMapping("/{id}")
155-
public ResponseEntity<JobPostDTO> modifyJobPost(@RequestBody JobPostDTO jobPostDTO, @PathVariable("id") Long id) {
159+
public ResponseEntity<JobPostDTO> modifyJobPost(@RequestBody JobPostDTO jobPostDTO, @Valid @PathVariable("id") Long id) {
156160
return ResponseEntity.ok(jobPostService.modify(jobPostDTO));
157161
}
158162

@@ -194,8 +198,8 @@ public ResponseEntity<JobPostDTO> modifyJobPost(@RequestBody JobPostDTO jobPostD
194198
schema = @Schema(type = "integer")
195199
)
196200
@DeleteMapping("/{id}")
197-
public ResponseEntity<Map<String, String>> deleteJobPost(@PathVariable("id") Long id) {
201+
public ResponseEntity<Map<String, String>> deleteJobPost(@Valid @PathVariable("id") Long id) {
198202
jobPostService.remove(id);
199-
return ResponseEntity.ok(Map.of("message", "success"));
203+
return ResponseEntity.ok(Map.of("message", "삭제가 완료되었습니다"));
200204
}
201205
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.prgrms2.java.bitta.jobpost.controller.advice;
2+
3+
import com.prgrms2.java.bitta.jobpost.exception.JobPostTaskException;
4+
import org.springframework.http.ResponseEntity;
5+
import org.springframework.web.bind.annotation.ExceptionHandler;
6+
import org.springframework.web.bind.annotation.RestControllerAdvice;
7+
8+
import java.util.Map;
9+
10+
@RestControllerAdvice
11+
public class JobPostControllerAdvice {
12+
@ExceptionHandler(JobPostTaskException.class)
13+
public ResponseEntity<Map<String, String>> handleArgsException(JobPostTaskException e) {
14+
return ResponseEntity.status(e.getCode())
15+
.body(Map.of("error", e.getMessage()));
16+
}
17+
}

Diff for: src/main/java/com/prgrms2/java/bitta/jobpost/dto/JobPostDTO.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.prgrms2.java.bitta.jobpost.entity.PayStatus;
77
import com.prgrms2.java.bitta.member.entity.Member;
88
import io.swagger.v3.oas.annotations.media.Schema;
9+
import jakarta.validation.constraints.*;
910
import lombok.AllArgsConstructor;
1011
import lombok.Builder;
1112
import lombok.Data;
@@ -20,21 +21,28 @@
2021
@Schema(title = "일거리 DTO", description = "일거리의 요청 및 응답에 사용하는 DTO입니다.")
2122
public class JobPostDTO {
2223
@Schema(title = "일거리 ID (PK)", description = "일거리의 고유 ID 입니다.", example = "1")
24+
@Min(1)
2325
private Long id;
2426

2527
@Schema(title = "회원 ID (FK)", description = "회원의 고유 ID 입니다.", example = "1")
26-
private Long userId;
28+
@Min(1)
29+
@NotNull(message = "회원 ID가 필요합니다")
30+
private Long memberId;
2731

2832
@Schema(title = "일거리 제목", description = "일거리 제목입니다.", example = "Job Title")
33+
@NotBlank(message = "제목 입력은 필수적 입니다")
2934
private String title;
3035

3136
@Schema(title = "일거리 내용", description = "일거리 내용입니다.", example = "Job Content")
37+
@NotBlank(message = "설명 입력은 필수적 입니다")
3238
private String description;
3339

3440
@Schema(title = "출근지", description = "출근 지역입니다.", example = "SEOUL")
41+
@NotNull(message = "지역명은 필수적으로 입력해야 합니다")
3542
private Location location;
3643

3744
@Schema(title = "지불 유형", description = "지불 유형입니다.", example = "FREE")
45+
@NotNull(message = "급여 여부는 필수적으로 입력해야 합니다")
3846
private PayStatus payStatus;
3947

4048
@Schema(title = "일거리 수정일시", description = "일거리가 수정된 날짜 및 시간입니다.", example = "2023-09-24T14:45:00")
@@ -49,4 +57,5 @@ public class JobPostDTO {
4957
@Schema(title = "종료여부", description = "일이 종료되었는지 여부입니다.", example = "true")
5058
@JsonProperty("isClosed")
5159
private boolean isClosed;
60+
5261
}

Diff for: src/main/java/com/prgrms2/java/bitta/jobpost/entity/JobPost.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public boolean isClosed() {
6262
return LocalDate.now().isAfter(this.endDate);
6363
}
6464

65-
// 해당 게시글에 대한 신청 목록 가져야함 (임시로 application 엔티티 만듦)
65+
// 해당 게시글에 대한 신청 목록 가져야함
6666
@OneToMany(mappedBy = "jobPost", cascade = CascadeType.ALL, orphanRemoval = true)
6767
private List<Apply> apply = new ArrayList<>();
6868
}

0 commit comments

Comments
 (0)