From 5e45314f440ee8582fed14a8ff71d0f5ee00dc36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B0=80=EC=98=81?= Date: Thu, 1 Aug 2024 22:45:06 +0900 Subject: [PATCH] feat: load portfolio --- .../auth/controller/AuthController.java | 11 ++--- .../domain/member/entity/MemberEntity.java | 5 ++ .../controller/MemberController.java | 12 ++--- .../controller/MemberProfileController.java | 6 +++ .../member/service/MemberProfileService.java | 5 ++ .../domain/member/service/MemberService.java | 12 ----- .../portfolio/entity/PortfolioEntity.java | 48 +++++++++++++++++++ .../domain/portfolio/entity/TagEntity.java | 33 +++++++++++++ .../portfolio/enums/PortfolioState.java | 5 ++ .../controller/PortfolioController.java | 28 +++++++++++ .../dto/res/LoadPortfolioRes.java | 15 ++++++ .../repository/PortfolioRepository.java | 18 +++++++ .../portfolio/service/PortfolioService.java | 32 +++++++++++++ .../config/security/SecurityConfig.java | 1 + 14 files changed, 204 insertions(+), 27 deletions(-) create mode 100644 src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/entity/PortfolioEntity.java create mode 100644 src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/entity/TagEntity.java create mode 100644 src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/enums/PortfolioState.java create mode 100644 src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/presentation/controller/PortfolioController.java create mode 100644 src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/presentation/dto/res/LoadPortfolioRes.java create mode 100644 src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/repository/PortfolioRepository.java create mode 100644 src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/service/PortfolioService.java diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/auth/controller/AuthController.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/auth/controller/AuthController.java index fcd7d20..712922b 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/auth/controller/AuthController.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/auth/controller/AuthController.java @@ -3,20 +3,17 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; -import kr.hs.dgsw.SOPO_server_v2.domain.auth.dto.req.ReProvideTokenReq; import kr.hs.dgsw.SOPO_server_v2.domain.auth.dto.req.SignInReq; import kr.hs.dgsw.SOPO_server_v2.domain.auth.dto.req.SignUpReq; -import kr.hs.dgsw.SOPO_server_v2.domain.auth.dto.res.ReProvideTokenRes; import kr.hs.dgsw.SOPO_server_v2.domain.auth.dto.res.TokenRes; -import kr.hs.dgsw.SOPO_server_v2.domain.auth.service.AuthEmailService; import kr.hs.dgsw.SOPO_server_v2.domain.auth.service.AuthService; -import kr.hs.dgsw.SOPO_server_v2.domain.auth.service.AuthTokenService; -import kr.hs.dgsw.SOPO_server_v2.global.common.dto.res.JsonWebTokenResponse; import kr.hs.dgsw.SOPO_server_v2.global.response.Response; import kr.hs.dgsw.SOPO_server_v2.global.response.ResponseData; import lombok.RequiredArgsConstructor; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; @Tag(name = "Auth", description = "Auth Api") @RestController diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/entity/MemberEntity.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/entity/MemberEntity.java index 3edb3d4..97a51f8 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/entity/MemberEntity.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/entity/MemberEntity.java @@ -5,6 +5,7 @@ import kr.hs.dgsw.SOPO_server_v2.domain.file.entity.FileEntity; import kr.hs.dgsw.SOPO_server_v2.domain.member.enums.MemberCategory; import kr.hs.dgsw.SOPO_server_v2.domain.member.enums.MemberState; +import kr.hs.dgsw.SOPO_server_v2.domain.portfolio.entity.PortfolioEntity; import kr.hs.dgsw.SOPO_server_v2.global.common.entity.BaseTimeEntity; import lombok.*; import lombok.experimental.SuperBuilder; @@ -56,4 +57,8 @@ public class MemberEntity extends BaseTimeEntity { @OneToOne(fetch = FetchType.LAZY, orphanRemoval = true) @JoinColumn(name = "member_file") private FileEntity memberProfile; + + @OneToOne(fetch = FetchType.LAZY, orphanRemoval = true) + @JoinColumn(name = "member_portfolio") + private PortfolioEntity portfolioEntity; } diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/presentation/controller/MemberController.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/presentation/controller/MemberController.java index da63192..76b80be 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/presentation/controller/MemberController.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/presentation/controller/MemberController.java @@ -2,14 +2,15 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import kr.hs.dgsw.SOPO_server_v2.domain.member.presentation.dto.req.MemberModifyReq; import kr.hs.dgsw.SOPO_server_v2.domain.member.presentation.dto.res.ReadProfileRes; -import kr.hs.dgsw.SOPO_server_v2.domain.member.service.MemberProfileService; import kr.hs.dgsw.SOPO_server_v2.domain.member.service.MemberService; import kr.hs.dgsw.SOPO_server_v2.global.response.Response; import kr.hs.dgsw.SOPO_server_v2.global.response.ResponseData; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; @Tag(name = "Member", description = "Member Api") @RestController @@ -22,9 +23,4 @@ public class MemberController { public Response deleteMember(){ return memberService.deleteMember(); } - @Operation(description = "나의 프로필 보기") - @GetMapping - public ResponseData readProfile(){ - return memberService.readProfile(); - } } diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/presentation/controller/MemberProfileController.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/presentation/controller/MemberProfileController.java index 5dc63a4..a0f764c 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/presentation/controller/MemberProfileController.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/presentation/controller/MemberProfileController.java @@ -24,5 +24,11 @@ public Response modifyMember( @RequestBody MemberModifyReq memberModifyReq) { return memberProfileService.memberModify(memberModifyReq); } + + @Operation(description = "나의 프로필 보기") + @GetMapping + public ResponseData readProfile(){ + return memberProfileService.readProfile(); + } } diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/service/MemberProfileService.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/service/MemberProfileService.java index ebd3840..69186c8 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/service/MemberProfileService.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/service/MemberProfileService.java @@ -55,5 +55,10 @@ public Response memberModify(MemberModifyReq memberModifyReq) { return Response.of(HttpStatus.OK, "성공"); } + @Transactional(rollbackFor = Exception.class) + public ResponseData readProfile(){ + MemberEntity member = getCurrentMember.current(); + return ResponseData.of(HttpStatus.OK, "조회 성공", ReadProfileRes.of(memberRepository.findByMemberId(member.getMemberId()))); + } } diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/service/MemberService.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/service/MemberService.java index 72bac15..897c7a5 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/service/MemberService.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/member/service/MemberService.java @@ -2,12 +2,9 @@ import kr.hs.dgsw.SOPO_server_v2.domain.member.entity.MemberEntity; import kr.hs.dgsw.SOPO_server_v2.domain.member.enums.MemberState; -import kr.hs.dgsw.SOPO_server_v2.domain.member.presentation.dto.res.ReadProfileRes; import kr.hs.dgsw.SOPO_server_v2.domain.member.repository.MemberRepository; -import kr.hs.dgsw.SOPO_server_v2.global.error.custom.member.MemberNotCoincideException; import kr.hs.dgsw.SOPO_server_v2.global.infra.security.GetCurrentMember; import kr.hs.dgsw.SOPO_server_v2.global.response.Response; -import kr.hs.dgsw.SOPO_server_v2.global.response.ResponseData; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; @@ -16,22 +13,13 @@ @Component @RequiredArgsConstructor public class MemberService { - private final MemberRepository memberRepository; private final GetCurrentMember getCurrentMember; - @Transactional(rollbackFor = Exception.class) public Response deleteMember(){ MemberEntity member = getCurrentMember.current(); member.setMemberState(MemberState.DELETED); return Response.of(HttpStatus.OK, "성공"); } - - @Transactional(rollbackFor = Exception.class) - public ResponseData readProfile(){ - MemberEntity member = getCurrentMember.current(); - - return ResponseData.of(HttpStatus.OK, "조회 성공", ReadProfileRes.of(memberRepository.findByMemberId(member.getMemberId()))); - } } diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/entity/PortfolioEntity.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/entity/PortfolioEntity.java new file mode 100644 index 0000000..2427535 --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/entity/PortfolioEntity.java @@ -0,0 +1,48 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.portfolio.entity; + +import jakarta.persistence.*; +import jakarta.validation.constraints.Size; +import kr.hs.dgsw.SOPO_server_v2.domain.member.entity.MemberEntity; +import kr.hs.dgsw.SOPO_server_v2.domain.portfolio.enums.PortfolioState; +import kr.hs.dgsw.SOPO_server_v2.global.common.entity.BaseTimeEntity; +import lombok.*; +import lombok.experimental.SuperBuilder; +import org.hibernate.annotations.DynamicUpdate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.util.List; + +@Entity +@Getter +@Setter +@SuperBuilder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@EntityListeners(AuditingEntityListener.class) +@Table(name = "tb_portfolio") +@DynamicUpdate +@AllArgsConstructor +public class PortfolioEntity extends BaseTimeEntity { + @Id + @Column(name = "portfolio_id") + private Long portfolioId; + + + @Column(name = "portfolio_title") + private String portfolioTitle; + + @Builder.Default + @Enumerated(EnumType.STRING) + private PortfolioState portfolioState = PortfolioState.PENDING; + + + @Column(name = "portfolio_content") + private String portfolioContent; + + @OneToOne(fetch = FetchType.LAZY, orphanRemoval = true) + @JoinColumn(name = "portfolio_tag") + private TagEntity tagEntity; + + @ManyToOne + @JoinColumn(name = "member_id") + private MemberEntity member; +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/entity/TagEntity.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/entity/TagEntity.java new file mode 100644 index 0000000..3ee4064 --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/entity/TagEntity.java @@ -0,0 +1,33 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.portfolio.entity; + +import jakarta.persistence.*; +import kr.hs.dgsw.SOPO_server_v2.domain.member.entity.MemberEntity; +import kr.hs.dgsw.SOPO_server_v2.global.common.entity.BaseTimeEntity; +import lombok.*; +import lombok.experimental.SuperBuilder; +import org.hibernate.annotations.DynamicUpdate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +@Entity +@Getter +@SuperBuilder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@EntityListeners(AuditingEntityListener.class) +@Table(name = "tb_tag") +@DynamicUpdate +@AllArgsConstructor +public class TagEntity extends BaseTimeEntity { + @Id + @Column(name = "tag_id") + private Long tagId; + + private String tagName; + + @ManyToOne + @JoinColumn(name = "portfolio_id") + private PortfolioEntity portfolioEntity; + + @ManyToOne + @JoinColumn(name = "member_id") + private MemberEntity memberEntity; +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/enums/PortfolioState.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/enums/PortfolioState.java new file mode 100644 index 0000000..5aad682 --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/enums/PortfolioState.java @@ -0,0 +1,5 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.portfolio.enums; + +public enum PortfolioState { + PENDING, ACTIVE +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/presentation/controller/PortfolioController.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/presentation/controller/PortfolioController.java new file mode 100644 index 0000000..896bfc2 --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/presentation/controller/PortfolioController.java @@ -0,0 +1,28 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.portfolio.presentation.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import kr.hs.dgsw.SOPO_server_v2.domain.portfolio.presentation.dto.res.LoadPortfolioRes; +import kr.hs.dgsw.SOPO_server_v2.domain.portfolio.service.PortfolioService; +import kr.hs.dgsw.SOPO_server_v2.global.page.PageRequest; +import kr.hs.dgsw.SOPO_server_v2.global.response.ResponseData; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Tag(name = "Portfolio", description = "Portfolio Api") +@RestController +@RequestMapping(value = "/portfolio") +@RequiredArgsConstructor +public class PortfolioController { + private final PortfolioService portfolioService; + + @Operation(description = "최신 포트폴리오 불러오기") + @GetMapping + public ResponseData> loadPortfolio( + @ModelAttribute PageRequest pageRequest + ){ + return portfolioService.pagingPortfolio(pageRequest); + } +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/presentation/dto/res/LoadPortfolioRes.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/presentation/dto/res/LoadPortfolioRes.java new file mode 100644 index 0000000..b0060de --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/presentation/dto/res/LoadPortfolioRes.java @@ -0,0 +1,15 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.portfolio.presentation.dto.res; + +import kr.hs.dgsw.SOPO_server_v2.domain.portfolio.entity.PortfolioEntity; + +public record LoadPortfolioRes( + String portfolioTitle, + String memberName +) { + public static LoadPortfolioRes of(PortfolioEntity portfolioEntity) { + return new LoadPortfolioRes( + portfolioEntity.getPortfolioTitle(), + portfolioEntity.getMember().getMemberName() + ); + } +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/repository/PortfolioRepository.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/repository/PortfolioRepository.java new file mode 100644 index 0000000..261e76f --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/repository/PortfolioRepository.java @@ -0,0 +1,18 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.portfolio.repository; + +import kr.hs.dgsw.SOPO_server_v2.domain.portfolio.entity.PortfolioEntity; +import kr.hs.dgsw.SOPO_server_v2.domain.portfolio.enums.PortfolioState; +import kr.hs.dgsw.SOPO_server_v2.global.page.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; + +public interface PortfolioRepository extends JpaRepository { + + @Query("SELECT p FROM PortfolioEntity p WHERE p.portfolioState = :state ORDER BY p.createdAt DESC") + List findPortfoliosByState(@Param("state") PortfolioState state); +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/service/PortfolioService.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/service/PortfolioService.java new file mode 100644 index 0000000..194550a --- /dev/null +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/domain/portfolio/service/PortfolioService.java @@ -0,0 +1,32 @@ +package kr.hs.dgsw.SOPO_server_v2.domain.portfolio.service; + +import kr.hs.dgsw.SOPO_server_v2.domain.portfolio.entity.PortfolioEntity; +import kr.hs.dgsw.SOPO_server_v2.domain.portfolio.enums.PortfolioState; +import kr.hs.dgsw.SOPO_server_v2.domain.portfolio.presentation.dto.res.LoadPortfolioRes; +import kr.hs.dgsw.SOPO_server_v2.domain.portfolio.repository.PortfolioRepository; +import kr.hs.dgsw.SOPO_server_v2.global.page.PageRequest; +import kr.hs.dgsw.SOPO_server_v2.global.response.ResponseData; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +@Component +@RequiredArgsConstructor +public class PortfolioService { + private final PortfolioRepository portfolioRepository; + + public ResponseData> pagingPortfolio(PageRequest pageRequest){ + List portfolioEntities = portfolioRepository.findPortfoliosByState(PortfolioState.ACTIVE); + + List loadPortfolioReqList = portfolioEntities.stream() + .map(LoadPortfolioRes::of) + .skip((pageRequest.page() - 1) * pageRequest.size()) + .limit(pageRequest.size()) + .collect(Collectors.toList()); + + return ResponseData.of(HttpStatus.OK, "성공", loadPortfolioReqList); + } +} diff --git a/src/main/java/kr/hs/dgsw/SOPO_server_v2/global/config/security/SecurityConfig.java b/src/main/java/kr/hs/dgsw/SOPO_server_v2/global/config/security/SecurityConfig.java index 3c2b7e5..d3003e0 100644 --- a/src/main/java/kr/hs/dgsw/SOPO_server_v2/global/config/security/SecurityConfig.java +++ b/src/main/java/kr/hs/dgsw/SOPO_server_v2/global/config/security/SecurityConfig.java @@ -51,6 +51,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers("/member/**").hasAuthority("ROLE_ACTIVE") .requestMatchers("/contest/**").hasAuthority("ROLE_ACTIVE") .requestMatchers("/like/**").hasAuthority("ROLE_ACTIVE") + .requestMatchers("/profile/**").hasAuthority("ROLE_ACTIVE") .anyRequest().authenticated() .and() .formLogin().disable()