diff --git a/src/main/java/com/kusitms/website/domain/admin/AdminController.java b/src/main/java/com/kusitms/website/domain/admin/AdminController.java index 17e1a35..0c40706 100644 --- a/src/main/java/com/kusitms/website/domain/admin/AdminController.java +++ b/src/main/java/com/kusitms/website/domain/admin/AdminController.java @@ -2,6 +2,7 @@ import com.kusitms.website.domain.introduction.IntroService; import com.kusitms.website.domain.introduction.dto.request.IntroRequest; +import com.kusitms.website.domain.blog.dto.request.BlogReviewRequest; import com.kusitms.website.domain.project.dto.request.CorporateRequest; import com.kusitms.website.domain.project.dto.request.MeetupRequest; import com.kusitms.website.domain.review.dto.request.ReviewRequest; @@ -187,4 +188,57 @@ public ResponseEntity getMeetupProject(@PathVariable(name = "meetu public ResponseEntity getCorporateProjects() { return ResponseEntity.ok(new BaseResponse(adminService.getCorporateProjects())); } + + @GetMapping("/admin/corporate/{id}") + @Operation(summary = "기업 프로젝트 상세 조회(test db)", description = "기업 프로젝트의 상세 정보를 조회합니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "조회 성공"), + @ApiResponse(responseCode = "500", description = "INTER SERVER ERROR", content = @Content(schema = @Schema(implementation = BaseResponse.class))), + }) + public ResponseEntity getCorporateProject(@PathVariable("id") Long corporateId) { + return ResponseEntity.ok(new BaseResponse(adminService.getCorporateProject(corporateId))); + } + + @GetMapping("/admin/blog-review") + @Operation(summary = "블로그 후기 리스트(test db)", description = "블로그 후기의 모든 리스트를 조회합니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "조회 성공"), + @ApiResponse(responseCode = "500", description = "INTER SERVER ERROR", content = @Content(schema = @Schema(implementation = BaseResponse.class))), + }) + public ResponseEntity getBlogReviews() { + return ResponseEntity.ok(new BaseResponse(adminService.getBlogReviews())); + } + + @PostMapping(value = "/admin/blog-review", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @Operation(summary = "블로그 후기 등록(test db)", description = "블로그 후기를 등록합니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "등록 성공"), + @ApiResponse(responseCode = "500", description = "INTER SERVER ERROR", content = @Content(schema = @Schema(implementation = BaseResponse.class))), + }) + public ResponseEntity addBlogReview(@ModelAttribute BlogReviewRequest request) { + adminService.saveBlogReview(request); + return ResponseEntity.ok(new BaseResponse()); + } + + @PutMapping(value = "/admin/blog-review", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @Operation(summary = "블로그 후기 수정(test db)", description = "블로그 후기를 수정합니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "수정 성공"), + @ApiResponse(responseCode = "500", description = "INTER SERVER ERROR", content = @Content(schema = @Schema(implementation = BaseResponse.class))), + }) + public ResponseEntity updateBlogReview(@ModelAttribute BlogReviewRequest request) { + adminService.updateBlogReview(request); + return ResponseEntity.ok(new BaseResponse()); + } + + @DeleteMapping("/admin/blog-review/{id}") + @Operation(summary = "블로그 후기 삭제(test db)", description = "블로그 후기를 삭제합니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "삭제 성공"), + @ApiResponse(responseCode = "500", description = "INTER SERVER ERROR", content = @Content(schema = @Schema(implementation = BaseResponse.class))), + }) + public ResponseEntity deleteBlogReview(@PathVariable("id") Long blogReviewId) { + adminService.deleteBlogReview(blogReviewId); + return ResponseEntity.ok(new BaseResponse()); + } } diff --git a/src/main/java/com/kusitms/website/domain/admin/AdminService.java b/src/main/java/com/kusitms/website/domain/admin/AdminService.java index 6e34562..716196c 100644 --- a/src/main/java/com/kusitms/website/domain/admin/AdminService.java +++ b/src/main/java/com/kusitms/website/domain/admin/AdminService.java @@ -1,13 +1,18 @@ package com.kusitms.website.domain.admin; import com.kusitms.website.domain.admin.entity.TMPCorporateProject; +import com.kusitms.website.domain.admin.entity.TMPBlogReview; import com.kusitms.website.domain.admin.entity.TMPMeetupProject; import com.kusitms.website.domain.admin.entity.TMPMeetupTeam; import com.kusitms.website.domain.admin.entity.TMPReview; +import com.kusitms.website.domain.admin.repository.TMPBlogReviewRepository; import com.kusitms.website.domain.admin.repository.TMPCorporateRepository; import com.kusitms.website.domain.admin.repository.TMPMeetupRepository; import com.kusitms.website.domain.admin.repository.TMPMeetupTeamRepository; import com.kusitms.website.domain.admin.repository.TMPReviewRepository; +import com.kusitms.website.domain.blog.dto.response.BlogReviewDetailResponse; +import com.kusitms.website.domain.blog.dto.response.BlogReviewResponse; +import com.kusitms.website.domain.blog.dto.request.BlogReviewRequest; import com.kusitms.website.domain.file.S3Service; import com.kusitms.website.domain.project.dto.request.CorporateRequest; import com.kusitms.website.domain.project.dto.request.MeetupRequest; @@ -19,7 +24,6 @@ import com.kusitms.website.domain.review.dto.request.ReviewRequest; import com.kusitms.website.domain.review.dto.response.ReviewDetailResponse; import com.kusitms.website.domain.review.dto.response.ReviewResponse; -import com.kusitms.website.domain.review.entity.Review; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -38,13 +42,63 @@ public class AdminService { private final TMPMeetupRepository meetupRepository; private final TMPMeetupTeamRepository meetupTeamRepository; private final TMPReviewRepository reviewRepository; + private final TMPBlogReviewRepository blogReviewRepository; + + @Transactional(readOnly = true) + public BlogReviewResponse getBlogReviews() { + List findBlogReviews = blogReviewRepository.findAllByOrderByBlogReviewIdDesc(); + + List blogReviewDetails = findBlogReviews.stream() + .map(BlogReviewDetailResponse::new) + .collect(Collectors.toList()); + + return BlogReviewResponse.builder() + .blogReviewCount(blogReviewDetails.size()) + .blogReviewList(blogReviewDetails) + .build(); + } + + @Transactional + public void saveBlogReview(BlogReviewRequest request) { + String thumbnailUrl = null; + if (request.getThumbnailFile() != null && !request.getThumbnailFile().isEmpty()) { + thumbnailUrl = s3Service.uploadFile(request.getThumbnailFile(), "blog-review"); + } + + TMPBlogReview blogReview = BlogReviewRequest.from(request, thumbnailUrl); + blogReviewRepository.save(blogReview); + } + + @Transactional + public void updateBlogReview(BlogReviewRequest request) { + TMPBlogReview blogReview = blogReviewRepository.findById(request.getBlogReviewId()).orElseThrow(); + + String thumbnailUrl = blogReview.getThumbnailUrl(); + if (request.getThumbnailFile() != null && !request.getThumbnailFile().isEmpty()) { + thumbnailUrl = s3Service.uploadFile(request.getThumbnailFile(), "blog-review"); + } + + blogReview.update( + request.getCardinal(), + request.getPart(), + request.getActivity(), + thumbnailUrl, + request.getTitle(), + request.getPreviewText() + ); + } + + @Transactional + public void deleteBlogReview(Long blogReviewId) { + blogReviewRepository.deleteById(blogReviewId); + } @Transactional(readOnly = true) public ReviewResponse getReviews() { List findReviews = reviewRepository.findAll(); List reviewDetailResponses = findReviews.stream() - .map(r -> new ReviewDetailResponse(r.getReviewId(), r.getName(), r.getTeam(), r.getReview())) + .map(r -> new ReviewDetailResponse(r.getReviewId(), r.getName(), r.getCardinal(), r.getTeam(), r.getReview())) .collect(Collectors.toList()); return ReviewResponse.builder() @@ -215,6 +269,12 @@ public CorporateResponse getCorporateProjects() { .build(); } + @Transactional(readOnly = true) + public CorporateDetailResponse getCorporateProject(Long corporateId) { + TMPCorporateProject findProject = corporateRepository.findById(corporateId).orElseThrow(); + return new CorporateDetailResponse(findProject); + } + @Transactional public void saveCorporate(CorporateRequest request) { String logoUrl = s3Service.uploadFile(request.getLogoFile(), "corporate"); @@ -273,6 +333,7 @@ public void saveReview(ReviewRequest request) { public void updateReview(ReviewRequest request) { TMPReview review = reviewRepository.findById(request.getReviewId()).orElseThrow(); review.update(request.getName(), + request.getCardinal(), request.getTeam(), request.getReview()); } diff --git a/src/main/java/com/kusitms/website/domain/admin/entity/BlogReviewActivity.java b/src/main/java/com/kusitms/website/domain/admin/entity/BlogReviewActivity.java new file mode 100644 index 0000000..ae6e648 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/admin/entity/BlogReviewActivity.java @@ -0,0 +1,7 @@ +package com.kusitms.website.domain.admin.entity; + +public enum BlogReviewActivity { + DOCUMENT_REVIEW, + INTERVIEW_REVIEW, + COMPANY_PROJECT +} diff --git a/src/main/java/com/kusitms/website/domain/admin/entity/TMPBlogReview.java b/src/main/java/com/kusitms/website/domain/admin/entity/TMPBlogReview.java new file mode 100644 index 0000000..386a181 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/admin/entity/TMPBlogReview.java @@ -0,0 +1,56 @@ +package com.kusitms.website.domain.admin.entity; + +import com.kusitms.website.domain.project.entity.Team; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class TMPBlogReview { + @Id + @Column(name = "blog_review_id", nullable = false) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long blogReviewId; + + private Integer cardinal; + + @Enumerated(EnumType.STRING) + private Team part; + + @Enumerated(EnumType.STRING) + private BlogReviewActivity activity; + + @Column(name = "thumbnail_url") + private String thumbnailUrl; + + private String title; + + @Column(length = 500) + private String previewText; + + @Builder + public TMPBlogReview(Integer cardinal, Team part, BlogReviewActivity activity, + String thumbnailUrl, String title, String previewText) { + this.cardinal = cardinal; + this.part = part; + this.activity = activity; + this.thumbnailUrl = thumbnailUrl; + this.title = title; + this.previewText = previewText; + } + + public void update(Integer cardinal, Team part, BlogReviewActivity activity, + String thumbnailUrl, String title, String previewText) { + this.cardinal = cardinal; + this.part = part; + this.activity = activity; + this.thumbnailUrl = thumbnailUrl; + this.title = title; + this.previewText = previewText; + } +} diff --git a/src/main/java/com/kusitms/website/domain/admin/entity/TMPReview.java b/src/main/java/com/kusitms/website/domain/admin/entity/TMPReview.java index d3e17bb..ede09d0 100644 --- a/src/main/java/com/kusitms/website/domain/admin/entity/TMPReview.java +++ b/src/main/java/com/kusitms/website/domain/admin/entity/TMPReview.java @@ -20,6 +20,8 @@ public class TMPReview { @Column(nullable = false) private String name; + private Integer cardinal; + @Enumerated(EnumType.STRING) private Team team; @@ -27,14 +29,16 @@ public class TMPReview { private String review; @Builder - public TMPReview(String name, Team team, String review) { + public TMPReview(String name, Integer cardinal, Team team, String review) { this.name = name; + this.cardinal = cardinal; this.team = team; this.review = review; } - public void update(String name, Team team, String review) { + public void update(String name, Integer cardinal, Team team, String review) { this.name = name; + this.cardinal = cardinal; this.team = team; this.review = review; } diff --git a/src/main/java/com/kusitms/website/domain/admin/repository/TMPBlogReviewRepository.java b/src/main/java/com/kusitms/website/domain/admin/repository/TMPBlogReviewRepository.java new file mode 100644 index 0000000..d01a997 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/admin/repository/TMPBlogReviewRepository.java @@ -0,0 +1,10 @@ +package com.kusitms.website.domain.admin.repository; + +import com.kusitms.website.domain.admin.entity.TMPBlogReview; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface TMPBlogReviewRepository extends JpaRepository { + List findAllByOrderByBlogReviewIdDesc(); +} diff --git a/src/main/java/com/kusitms/website/domain/blog/dto/request/BlogReviewRequest.java b/src/main/java/com/kusitms/website/domain/blog/dto/request/BlogReviewRequest.java new file mode 100644 index 0000000..aabdc57 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/blog/dto/request/BlogReviewRequest.java @@ -0,0 +1,46 @@ +package com.kusitms.website.domain.blog.dto.request; + +import com.kusitms.website.domain.admin.entity.BlogReviewActivity; +import com.kusitms.website.domain.admin.entity.TMPBlogReview; +import com.kusitms.website.domain.project.entity.Team; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import org.springframework.web.multipart.MultipartFile; + +@Getter +@Setter +@Schema +public class BlogReviewRequest { + @Schema(description = "블로그 후기 ID (PUT API에서 사용)", example = "1") + private Long blogReviewId; + + @Schema(description = "기수", example = "33") + private Integer cardinal; + + @Schema(description = "파트", example = "PLANNER, DESIGNER, DEVELOPER") + private Team part; + + @Schema(description = "활동", example = "DOCUMENT_REVIEW, INTERVIEW_REVIEW, COMPANY_PROJECT") + private BlogReviewActivity activity; + + @Schema(description = "썸네일 이미지 파일") + private MultipartFile thumbnailFile; + + @Schema(description = "제목", example = "면접에서 이런 질문이 나왔어요") + private String title; + + @Schema(description = "미리보기 텍스트", example = "합격에 도움이 됐던 준비 과정을 공유합니다.") + private String previewText; + + public static TMPBlogReview from(BlogReviewRequest request, String thumbnailUrl) { + return TMPBlogReview.builder() + .cardinal(request.getCardinal()) + .part(request.getPart()) + .activity(request.getActivity()) + .thumbnailUrl(thumbnailUrl) + .title(request.getTitle()) + .previewText(request.getPreviewText()) + .build(); + } +} diff --git a/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogReviewDetailResponse.java b/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogReviewDetailResponse.java new file mode 100644 index 0000000..d863a63 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogReviewDetailResponse.java @@ -0,0 +1,44 @@ +package com.kusitms.website.domain.blog.dto.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.kusitms.website.domain.admin.entity.TMPBlogReview; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; + +import static com.kusitms.website.global.util.S3Util.s3Url; + +@Getter +@Schema +public class BlogReviewDetailResponse { + @JsonProperty("blog_review_id") + @Schema(description = "블로그 후기 아이디") + private Long blogReviewId; + + @Schema(description = "기수") + private Integer cardinal; + + @Schema(description = "파트") + private String part; + + @Schema(description = "활동") + private String activity; + + @Schema(description = "썸네일 URL") + private String thumbnailUrl; + + @Schema(description = "제목") + private String title; + + @Schema(description = "미리보기 텍스트") + private String previewText; + + public BlogReviewDetailResponse(TMPBlogReview blogReview) { + this.blogReviewId = blogReview.getBlogReviewId(); + this.cardinal = blogReview.getCardinal(); + this.part = blogReview.getPart() == null ? null : blogReview.getPart().name(); + this.activity = blogReview.getActivity() == null ? null : blogReview.getActivity().name(); + this.thumbnailUrl = blogReview.getThumbnailUrl() == null ? null : s3Url + blogReview.getThumbnailUrl(); + this.title = blogReview.getTitle(); + this.previewText = blogReview.getPreviewText(); + } +} diff --git a/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogReviewResponse.java b/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogReviewResponse.java new file mode 100644 index 0000000..77ef106 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/blog/dto/response/BlogReviewResponse.java @@ -0,0 +1,21 @@ +package com.kusitms.website.domain.blog.dto.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Getter; + +import java.util.List; + +@Getter +@Builder +@Schema +public class BlogReviewResponse { + @JsonProperty("blog_review_count") + @Schema(description = "블로그 후기 개수") + private int blogReviewCount; + + @JsonProperty("blog_review_list") + @Schema(description = "블로그 후기 리스트") + private List blogReviewList; +} diff --git a/src/main/java/com/kusitms/website/domain/review/dto/request/ReviewRequest.java b/src/main/java/com/kusitms/website/domain/review/dto/request/ReviewRequest.java index 42ca54b..4b45548 100644 --- a/src/main/java/com/kusitms/website/domain/review/dto/request/ReviewRequest.java +++ b/src/main/java/com/kusitms/website/domain/review/dto/request/ReviewRequest.java @@ -14,6 +14,9 @@ public class ReviewRequest { @Schema(description = "이름", example = "김큐시") private String name; + @Schema(description = "기수", example = "33") + private Integer cardinal; + @Schema(description = "소속팀", example = "PLANNER, DESIGNER, DEVELOPER") private Team team; @@ -23,6 +26,7 @@ public class ReviewRequest { public static TMPReview from(ReviewRequest request) { return TMPReview.builder() .name(request.getName()) + .cardinal(request.getCardinal()) .team(request.getTeam()) .review(request.getReview()) .build(); diff --git a/src/main/java/com/kusitms/website/domain/review/dto/response/ReviewDetailResponse.java b/src/main/java/com/kusitms/website/domain/review/dto/response/ReviewDetailResponse.java index f6717f2..3e87bc0 100644 --- a/src/main/java/com/kusitms/website/domain/review/dto/response/ReviewDetailResponse.java +++ b/src/main/java/com/kusitms/website/domain/review/dto/response/ReviewDetailResponse.java @@ -15,7 +15,7 @@ public class ReviewDetailResponse { @Schema(description = "이름") private String name; - @Schema(description = "기수") + @Schema(description = "기수", example = "33") private Integer cardinal; @Schema(description = "소속팀")