Skip to content

Commit

Permalink
Merge pull request #63 from LIKELION-TEAM4-HACKATHON/feature/culture-…
Browse files Browse the repository at this point in the history
…detail
  • Loading branch information
oosedus authored Jul 28, 2024
2 parents f1c743b + ea9cac4 commit b23c83c
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package likelion.MZConnent.api.culture;

import likelion.MZConnent.dto.culture.response.CultureCategoryResponse;
import likelion.MZConnent.dto.culture.response.CultureDetailResponse;
import likelion.MZConnent.dto.culture.response.CulturesSimpleResponse;
import likelion.MZConnent.dto.paging.response.PageContentResponse;
import likelion.MZConnent.dto.review.response.ReviewsSimpleResponse;
import likelion.MZConnent.jwt.principle.UserPrinciple;
import likelion.MZConnent.service.culture.CultureCategoryService;
import likelion.MZConnent.service.culture.CultureService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

Expand All @@ -31,9 +35,27 @@ public ResponseEntity<CultureCategoryResponse> getAllCultureCategories() {

// 전체 문화 간단 조회
@GetMapping("/api/cultures")
ResponseEntity<PageContentResponse> getReviewSimpleList(@RequestParam(required = false, defaultValue = "0", value = "category") Long category, @RequestParam(required = false, defaultValue = "0", value = "page") int page ) {
public ResponseEntity<PageContentResponse> getCulturesSimpleList(@RequestParam(required = false, defaultValue = "0", value = "category") Long category, @RequestParam(required = false, defaultValue = "0", value = "page") int page) {

PageContentResponse<CulturesSimpleResponse> response = cultureService.getCulturesSimpleList(category, page);
return ResponseEntity.ok(response);
}


// 나의 관심 문화 간단 조회
@GetMapping("/api/cultures/interest")
public ResponseEntity<PageContentResponse> getMyInterestCulturesSimpleList(@RequestParam(required = false, defaultValue = "0", value = "category") Long category, @RequestParam(required = false, defaultValue = "0", value = "page") int page, @AuthenticationPrincipal UserPrinciple userPrinciple) {

PageContentResponse<CulturesSimpleResponse> response = cultureService.getMyIntersetCulturesSimpleList(userPrinciple.getEmail(), category, page);
return ResponseEntity.ok(response);
}

@GetMapping("/api/cultures/{cultureId}")
public ResponseEntity<CultureDetailResponse> getCultureDetailInfo(@PathVariable("cultureId") Long cultureId) {
CultureDetailResponse response = cultureService.getCultureDetailInfo(cultureId);

log.info("문화 정보 조회 성공: {}", response.getCultureId());

return ResponseEntity.ok(response);
}
}
23 changes: 17 additions & 6 deletions src/main/java/likelion/MZConnent/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package likelion.MZConnent.config;

import jakarta.servlet.http.HttpServletRequest;
import likelion.MZConnent.jwt.JwtAccessDeniedHandler;
import likelion.MZConnent.jwt.JwtAuthenticationEntryPoint;
import likelion.MZConnent.jwt.JwtFilter;
Expand Down Expand Up @@ -31,19 +30,30 @@ public class SecurityConfig {
private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
private final JwtFilter jwtFilter;

//권한별 url
/**
* 권한별 URI
*/

// 관리자 권한
private final String[] adminUrl = {"/admin/**"};
// 아무나 접속 가능한 것

// 인증된 사용자만 접근 가능한 URI (permitAllUrl과 겹치는 경우에만 추가 -> 미인증 사용자가 접근하는 URI는 모두 인가가 필요하게 설정되어 있어 추가할 필요 없음)
private final String[] authenticatedUrl = {
"/api/cultures/interest"
};

// 아무나 접근 가능한 URI
private final String[] permitAllUrl = {"/error",
"/api/auth/login", // 회원
"/api/categories/culture", "/api/cultures", "/api/cultures/*", // 문화
"/api/categories/culture", "/api/cultures", "/api/cultures/**", // 문화
"/api/reviews", // 후기
"/api/categories/region", "/api/clubs/list",
"/api/main",
"/swagger", "/swagger-ui.html", "/swagger-ui/**", "/api-docs", "/api-docs/**", "/v3/api-docs/**", //swagger
"/api/test"
};
// 로그인 안한 사용자만 접속 가능한 것

// 인증되지 않은 사용자만 접근 가능한 URI
private final String[] anonymousUrl = {
"/api/auth/signup"
};
Expand All @@ -63,8 +73,9 @@ public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws
.accessDeniedHandler(jwtAccessDeniedHandler)
)
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.authorizeHttpRequests(auth -> auth // 접근 url 권한 관리
.authorizeHttpRequests(auth -> auth // 접근 uri 권한 관리
.requestMatchers(adminUrl).hasAnyRole("ADMIN")
.requestMatchers(authenticatedUrl).authenticated()
.requestMatchers(permitAllUrl).permitAll()
.requestMatchers(anonymousUrl).anonymous()
.anyRequest().authenticated() // 이 외의 url은 인증받은 사용자만 접근 가능
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/likelion/MZConnent/domain/club/ClubRole.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package likelion.MZConnent.domain.club;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

Expand All @@ -11,10 +13,12 @@ public enum ClubRole {

private final String clubRole;

@JsonValue
public String getClubRole() {
return clubRole;
}

@JsonProperty
public static ClubRole fromRole(String role) {
for (ClubRole cR : ClubRole.values()) {
if (cR.getClubRole().equals(role)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package likelion.MZConnent.dto.culture.response;

import likelion.MZConnent.domain.club.AgeRestriction;
import likelion.MZConnent.domain.club.Club;
import likelion.MZConnent.domain.club.ClubRole;
import likelion.MZConnent.domain.club.GenderRestriction;
import likelion.MZConnent.domain.culture.Culture;
import likelion.MZConnent.dto.review.response.ReviewsSimpleResponse;
import lombok.*;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Getter
@Slf4j
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class CultureDetailResponse {
private Long cultureId;
private String name;
private String cultureImageUrl;
private String regionName;
private int interestCount;
private String recommendedMember;
private String content;
private List<ClubsSimpleResponse> clubs;
private List<ReviewsSimpleResponse> reviews;

@Builder
public CultureDetailResponse(Culture culture) {
this.cultureId = culture.getCultureId();
this.name = culture.getName();
this.cultureImageUrl = culture.getCultureImageUrl();
this.regionName = culture.getRegion().getName();
this.interestCount = culture.getInterestCount();
this.recommendedMember = culture.getRecommendedMember();
this.content = culture.getContent();
this.clubs = culture.getClubs().stream().filter(club ->
(club.getStatus().equals("OPEN")
)).map(club ->
ClubsSimpleResponse.builder()
.club(club).build()).collect(Collectors.toList());
this.reviews = culture.getReviews().stream().map(
review -> ReviewsSimpleResponse.builder()
.review(review).build()
).collect(Collectors.toList());
}


@Getter
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
static private class ClubsSimpleResponse {
private Long clubId;
private String title;
private String regionName;
private String cultureName;
private String leaderProfileImage;
private LocalDate meetingDate;
private LocalDateTime createdDate;
private GenderRestriction genderRestriction;
private AgeRestriction ageRestriction;
private int currentParticipant;
private int maxParticipant;

@Builder
public ClubsSimpleResponse(Club club) {
this.clubId = club.getClubId();
this.title = club.getTitle();
this.regionName = club.getRegion().getName();
this.cultureName = club.getCulture().getName();
this.leaderProfileImage = club.getClubMembers().stream().filter((member) ->
member.getClubRole() == ClubRole.LEADER
).findFirst().orElseThrow(() -> {
log.info("모임장이 존재하지 않음.");
return new IllegalArgumentException("모임장이 존재하지 않습니다.");
}).getMember().getProfileImageUrl();
this.meetingDate = club.getMeetingDate();
this.createdDate = club.getCreatedDate();
this.genderRestriction = club.getGenderRestriction();
this.ageRestriction = club.getAgeRestriction();
this.currentParticipant = club.getCurrentParticipant();
this.maxParticipant = club.getMaxParticipant();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

@Getter
@NoArgsConstructor
@ToString
public class ReviewsSimpleResponse {
private Long reviewId;
private MemberProfileDto reviewer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@
public interface CultureRepository extends JpaRepository<Culture, Long> {
@Query("SELECT c FROM Culture c WHERE :category = 0 OR c.cultureCategory.id = :category")
Page<Culture> findAllByCultureCategory(@Param("category") Long category, Pageable pageable);

@Query("SELECT c FROM Culture c JOIN c.cultureInterests ci JOIN ci.member m WHERE (:category = 0 OR c.cultureCategory.id = :category) AND m.email = :email")
Page<Culture> findByMemberAndCategory(@Param("email") String email, @Param("category") Long category, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import likelion.MZConnent.domain.culture.Culture;
import likelion.MZConnent.domain.review.Review;
import likelion.MZConnent.dto.culture.response.CultureDetailResponse;
import likelion.MZConnent.dto.culture.response.CulturesSimpleResponse;
import likelion.MZConnent.dto.paging.response.PageContentResponse;
import likelion.MZConnent.dto.review.response.ReviewsSimpleResponse;
Expand All @@ -14,12 +15,14 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
@RequiredArgsConstructor
public class CultureService {
private final CultureRepository cultureRepository;
Expand All @@ -42,4 +45,31 @@ public PageContentResponse<CulturesSimpleResponse> getCulturesSimpleList(Long cu
.build();

}

public PageContentResponse<CulturesSimpleResponse> getMyIntersetCulturesSimpleList(String email, Long cultureCategoryId, int page) {
Pageable pageable = PageRequest.of(page, PAGE_SIZE);

Page<Culture> cultures = cultureRepository.findByMemberAndCategory(email, cultureCategoryId, pageable);

List<CulturesSimpleResponse> cultureResponse = cultures.stream().map(culture -> CulturesSimpleResponse.builder()
.culture(culture).build()
).collect(Collectors.toList());

return PageContentResponse.<CulturesSimpleResponse>builder()
.content(cultureResponse)
.totalPages(cultures.getTotalPages())
.totalElements(cultures.getTotalElements())
.size(pageable.getPageSize())
.build();

}

public CultureDetailResponse getCultureDetailInfo(Long cultureId) {
Culture culture = cultureRepository.findById(cultureId).orElseThrow(() -> {
log.info("해당 문화가 존재하지 않습니다.");
return new IllegalArgumentException("해당 문화가 존재하지 않습니다.");
});
return CultureDetailResponse.builder()
.culture(culture).build();
}
}

0 comments on commit b23c83c

Please sign in to comment.