Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: exist portfolio 관련 api 구현 #223

Merged
merged 6 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gongjakso.server.domain.portfolio.controller;

import com.gongjakso.server.domain.portfolio.dto.request.PortfolioReq;
import com.gongjakso.server.domain.portfolio.dto.response.ExistPortfolioRes;
import com.gongjakso.server.domain.portfolio.dto.response.PortfolioRes;
import com.gongjakso.server.domain.portfolio.dto.response.SimplePortfolioRes;
import com.gongjakso.server.domain.portfolio.service.PortfolioService;
Expand All @@ -11,14 +12,8 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

Expand Down Expand Up @@ -66,4 +61,33 @@ public ApplicationResponse<Void> deletePortfolio(@AuthenticationPrincipal Princi
public ApplicationResponse<List<SimplePortfolioRes>> getMyPortfolios(@AuthenticationPrincipal PrincipalDetails principalDetails) {
return ApplicationResponse.ok(portfolioService.getMyPortfolios(principalDetails.getMember()));
}

@Operation(description = "포트폴리오 파일 및 링크 업로드 API")
@PostMapping("/exist-protfolio")
public ApplicationResponse<Void> updateExistPortfolio(@AuthenticationPrincipal PrincipalDetails principalDetails, @RequestPart(required = false,name = "file") MultipartFile file, @RequestPart(required = false,name = "notionUri") String notionUri){
portfolioService.saveExistPortfolio(principalDetails.getMember(),file,notionUri);
return ApplicationResponse.ok();
}

@Operation(description = "포트폴리오 파일 및 링크 업로드 삭제 API")
@DeleteMapping("/exist-protfolio/{portfolio_id}")
public ApplicationResponse<Void> deleteExistPortfolio(@AuthenticationPrincipal PrincipalDetails principalDetails,@PathVariable("portfolio_id") Long portfolioId){
portfolioService.deleteExistPortfolio(principalDetails.getMember(),portfolioId);
return ApplicationResponse.ok();
}

@Operation(description = "포트폴리오 파일 및 링크 업로드 업데이트 API")
@PatchMapping("/exist-protfolio/{portfolio_id}")
public ApplicationResponse<Void> updateExistPortfolio(@AuthenticationPrincipal PrincipalDetails principalDetails,@PathVariable("portfolio_id") Long portfolioId, @RequestPart(required = false,name = "file") MultipartFile file, @RequestPart(required = false,name = "notionUri") String notionUri){
portfolioService.updateExistPortfolio(principalDetails.getMember(),portfolioId,file,notionUri);
return ApplicationResponse.ok();
}

@Operation(description = "포트폴리오 파일 및 링크 업로드 가져오기 API")
@GetMapping("/exist-protfolio/{portfolio_id}")
public ApplicationResponse<ExistPortfolioRes> findExistPortfolio(@AuthenticationPrincipal PrincipalDetails principalDetails, @PathVariable("portfolio_id") Long portfolioId){
return ApplicationResponse.ok(portfolioService.findExistPorfolio(principalDetails.getMember(),portfolioId));
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.gongjakso.server.domain.portfolio.dto.response;

import com.gongjakso.server.domain.portfolio.entity.Portfolio;

public record ExistPortfolioRes(
String fileUri,
String notionUri
) {
public static ExistPortfolioRes of(Portfolio portfolio) {
return new ExistPortfolioRes(
portfolio.getFileUri(),
portfolio.getNotionUri()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.gongjakso.server.domain.portfolio.entity;

import com.gongjakso.server.domain.contest.dto.request.UpdateContestDto;
import com.gongjakso.server.domain.member.entity.Member;
import com.gongjakso.server.domain.portfolio.vo.PortfolioData;
import com.gongjakso.server.global.common.BaseTimeEntity;
Expand All @@ -12,6 +13,7 @@
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.type.SqlTypes;
import org.springframework.data.redis.connection.ReactiveGeoCommands;

@Getter
@Entity
Expand All @@ -36,13 +38,32 @@ public class Portfolio extends BaseTimeEntity {
@JdbcTypeCode(SqlTypes.JSON)
private PortfolioData portfolioData;

@Builder
@Column(name = "file_uri",columnDefinition = "text")
private String fileUri;

@Column(name = "notion_uri",columnDefinition = "text")
private String notionUri;

@Builder(builderMethodName = "portfolioBuilder")
public Portfolio(Member member, String portfolioName, PortfolioData portfolioData) {
this.member = member;
this.portfolioName = portfolioName;
this.portfolioData = portfolioData;
}

@Builder(builderMethodName = "existPortfolioBuilder")
public Portfolio(Member member, String portfolioName, String fileUri, String notionUri){
this.member = member;
this.portfolioName = portfolioName;
this.fileUri = fileUri;
this.notionUri = notionUri;
}
public void updatePortfolioUri(Portfolio portfolio, String fileUri, String notionUri) {
this.fileUri = (fileUri == null) ? this.fileUri : fileUri;
this.notionUri = (notionUri == null) ? this.notionUri : notionUri;
}


public void updateName(String updatedName) {
this.portfolioName = updatedName;
}
Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기의 JPQL은 QueryDSL로 작성할 수 없었던 이유가 있을까요?

Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package com.gongjakso.server.domain.portfolio.repository;

import com.gongjakso.server.domain.member.entity.Member;
import com.gongjakso.server.domain.portfolio.entity.Portfolio;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface PortfolioRepository extends JpaRepository<Portfolio, Long>, PortfolioRepositoryCustom{
Optional<Portfolio> findByIdAndDeletedAtIsNull(Long portfolioId);

long countByDeletedAtIsNull();
@Query("SELECT EXISTS (" +
"SELECT 1 FROM Portfolio po " +
"WHERE po.member = :member AND (po.fileUri IS NOT NULL OR po.notionUri IS NOT NULL) AND po.deletedAt IS NULL )")
Boolean existsExistPortfolioByMember(@Param("member") Member member);
Optional<Portfolio> findPortfolioById(Long portfolioId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.gongjakso.server.domain.member.entity.Member;
import com.gongjakso.server.domain.portfolio.dto.request.PortfolioReq;
import com.gongjakso.server.domain.portfolio.dto.response.ExistPortfolioRes;
import com.gongjakso.server.domain.portfolio.dto.response.PortfolioRes;
import com.gongjakso.server.domain.portfolio.dto.response.SimplePortfolioRes;
import com.gongjakso.server.domain.portfolio.entity.Portfolio;
Expand All @@ -10,16 +11,22 @@
import com.gongjakso.server.global.exception.ApplicationException;
import com.gongjakso.server.global.exception.ErrorCode;
import java.util.List;

import com.gongjakso.server.global.util.s3.S3Client;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class PortfolioService {

private final PortfolioRepository portfolioRepository;
private final S3Client s3Client;
private final String S3_PORTFOLIO_DIR_NAME = "portfolio";


// PortfolioName 생성 로직을 분리
private String generatePortfolioName(String portfolioName) {
Expand Down Expand Up @@ -104,11 +111,7 @@ public PortfolioRes registerPortfolio(Member member, PortfolioReq portfolioReq)
String portfolioName = generatePortfolioName(portfolioReq.portfolioName());
PortfolioData portfolioData = convertToPortfolioData(portfolioReq);

Portfolio portfolio = Portfolio.builder()
.member(member)
.portfolioName(portfolioName)
.portfolioData(portfolioData)
.build();
Portfolio portfolio = new Portfolio(member,portfolioName,portfolioData);

Portfolio savedPortfolio = portfolioRepository.save(portfolio);

Expand Down Expand Up @@ -165,4 +168,66 @@ public List<SimplePortfolioRes> getMyPortfolios(Member member) {
.map(SimplePortfolioRes::of)
.toList();
}

@Transactional
public void saveExistPortfolio(Member member, MultipartFile file, String notionUri){
//등록된 파일이나 노션 링크 있는지 확인
//Validation
Boolean isExist = portfolioRepository.existsExistPortfolioByMember(member);
if (isExist){
throw new ApplicationException(ErrorCode.ALREADY_EXIST_EXCEPTION);
}
if(file.isEmpty() && notionUri.isEmpty()){
throw new ApplicationException(ErrorCode.PORTFOLIO_SAVE_FAILED_EXCEPTION);
}
//Business
String s3Url = null;
if (file != null && !file.isEmpty()) {
s3Url = s3Client.upload(file, S3_PORTFOLIO_DIR_NAME);
}
Portfolio portfolio = new Portfolio(member,generatePortfolioName(null),s3Url,notionUri);
portfolioRepository.save(portfolio);
}

@Transactional
public void deleteExistPortfolio(Member member, Long id){
Portfolio portfolio = portfolioRepository.findById(id).orElseThrow(()-> new ApplicationException(ErrorCode.NOT_FOUND_EXCEPTION));
if(!member.getId().equals(portfolio.getMember().getId())){
throw new ApplicationException(ErrorCode.UNAUTHORIZED_EXCEPTION);
}
if(portfolio.getFileUri() != null&& !portfolio.getFileUri().isEmpty()){
s3Client.delete(portfolio.getFileUri());
}
portfolioRepository.delete(portfolio);
}

@Transactional
public void updateExistPortfolio(Member member, Long id, MultipartFile file, String notionUri){
//등록된 파일이나 노션 링크 있는지 확인
//Validation
Portfolio portfolio = portfolioRepository.findById(id).orElseThrow(()-> new ApplicationException(ErrorCode.PORTFOLIO_NOT_FOUND_EXCEPTION));
if(!member.getId().equals(portfolio.getMember().getId())){
throw new ApplicationException(ErrorCode.UNAUTHORIZED_EXCEPTION);
}
//Business
String s3Url = null;
if (file != null && !file.isEmpty()) {
if(portfolio.getFileUri()!=null && !portfolio.getFileUri().isEmpty()){
s3Client.delete(portfolio.getFileUri());
}
s3Url = s3Client.upload(file, S3_PORTFOLIO_DIR_NAME);
}
portfolio.updatePortfolioUri(portfolio,s3Url,notionUri);
portfolioRepository.save(portfolio);
}

public ExistPortfolioRes findExistPorfolio(Member member, Long id){
//Validation
Portfolio portfolio = portfolioRepository.findById(id).orElseThrow(()-> new ApplicationException(ErrorCode.NOT_FOUND_EXCEPTION));
if (!portfolio.getMember().getId().equals(member.getId())) {
throw new ApplicationException(ErrorCode.FORBIDDEN_EXCEPTION);
}
return new ExistPortfolioRes(portfolio.getFileUri(),portfolio.getNotionUri());
}

}
Loading