Skip to content

Commit

Permalink
Merge pull request #22 from Leets-Official/feat]-#21-프로젝트-소개-로직-개발
Browse files Browse the repository at this point in the history
[feat] #22 프로젝트 소개 로직 개발
  • Loading branch information
taeseokyang authored Feb 23, 2024
2 parents da9443d + 6488f6c commit 3741327
Show file tree
Hide file tree
Showing 27 changed files with 637 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package land.leets.domain.contributor.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import land.leets.domain.portfolio.domain.Portfolio;
import land.leets.domain.portfolio.domain.ProjectType;
import land.leets.domain.shared.BaseTimeEntity;
import lombok.*;

import java.time.LocalDate;

@Entity(name = "contributors")
@Builder
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Contributor {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonIgnore
private Long id;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "portfolioId")
@JsonIgnore
private Portfolio portfolio;

@Column(nullable = false)
private String name;

@Column(nullable = false)
private Position position;

@Column(nullable = false)
private String githubUrl;
}

14 changes: 14 additions & 0 deletions src/main/java/land/leets/domain/contributor/domain/Position.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package land.leets.domain.contributor.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum Position {
BACK_END("BackEnd"),
FRONT_END("FrontEnd"),
DESIGN("Design");

private final String position;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package land.leets.domain.contributor.domain.repository;

import land.leets.domain.comment.domain.Comment;
import land.leets.domain.contributor.domain.Contributor;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
public interface ContributorRepository extends JpaRepository<Contributor, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package land.leets.domain.contributor.usecase;

import land.leets.domain.contributor.domain.Contributor;
import land.leets.domain.portfolio.domain.Portfolio;

import java.util.List;

public interface CreateContributor {
void execute(List<Contributor> request, Portfolio portfolio) ;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package land.leets.domain.contributor.usecase;

import land.leets.domain.contributor.domain.Contributor;
import land.leets.domain.contributor.domain.repository.ContributorRepository;
import land.leets.domain.portfolio.domain.Portfolio;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class CreateContributorImpl implements CreateContributor{
private final ContributorRepository contributorRepository;
@Override
public void execute(List<Contributor> request, Portfolio portfolio) {
for (Contributor contributor : request) {
contributor.setPortfolio(portfolio);
contributorRepository.save(contributor);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package land.leets.domain.image.exception;


import land.leets.global.error.ErrorCode;
import land.leets.global.error.exception.ServiceException;

public class ImageSaveFailException extends ServiceException {
public ImageSaveFailException() {
super(ErrorCode.IMAGE_SAVE_FAIL);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package land.leets.domain.image.presentation;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;

import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.core.io.FileSystemResource;

@RestController
@RequiredArgsConstructor
@RequestMapping("/images")
public class ImageController {
@Value("${image.path}")
private String imageStoragePath;
@GetMapping("/{imageName}")
public ResponseEntity<?> getImage(@PathVariable String imageName) {
Resource resource = new FileSystemResource(imageStoragePath + imageName);
return new ResponseEntity<>(resource, HttpStatus.OK);
}
}
7 changes: 7 additions & 0 deletions src/main/java/land/leets/domain/image/usecase/SaveImage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package land.leets.domain.image.usecase;

import org.springframework.web.multipart.MultipartFile;

public interface SaveImage {
String save(MultipartFile pic) ;
}
40 changes: 40 additions & 0 deletions src/main/java/land/leets/domain/image/usecase/SaveImageImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package land.leets.domain.image.usecase;


import land.leets.domain.image.exception.ImageSaveFailException;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

@RequiredArgsConstructor
@Service
@Transactional
public class SaveImageImpl implements SaveImage{

@Value("${image.path}")
private String imageStoragePath;

@Override
public String save(MultipartFile pic){
if (pic == null){
return "no_image";
}
try {
UUID uuid = UUID.randomUUID();
String imageFileName = uuid + "_" + pic.getOriginalFilename();
Path imagePath = Paths.get(imageStoragePath + imageFileName);
Files.write(imagePath, pic.getBytes());
return imageFileName;
} catch (IOException e) {
throw new ImageSaveFailException();
}
}
}
64 changes: 64 additions & 0 deletions src/main/java/land/leets/domain/portfolio/domain/Portfolio.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package land.leets.domain.portfolio.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import land.leets.domain.admin.domain.Admin;
import land.leets.domain.contributor.domain.Contributor;
import land.leets.domain.shared.BaseTimeEntity;
import lombok.*;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@Entity(name = "portfolios")
@Builder
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Portfolio extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long portfolioId;

@Column(nullable = false)
private Long generation;

@Column(nullable = false)
private String name;

@Column(nullable = false)
private String summary;

@Column(nullable = false)
private String description;

@Column(nullable = false)
private ProjectType type;

@Column(nullable = false)
private ProjectScope scope;

@Column(nullable = false)
private LocalDate startDate;

@Column(nullable = false)
private LocalDate endDate;

@OneToMany(mappedBy = "portfolio", fetch = FetchType.EAGER)
@JsonIgnore
private List<Contributor> contributors = new ArrayList<>();

@Column
private String logoImgUrl;

@Column
private String coverImgUrl;

@Column
private String mainImgUrl;

}

13 changes: 13 additions & 0 deletions src/main/java/land/leets/domain/portfolio/domain/ProjectScope.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package land.leets.domain.portfolio.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum ProjectScope {
TOY("Toy"),
FINAL("Final");

private final String projectScope;
}
12 changes: 12 additions & 0 deletions src/main/java/land/leets/domain/portfolio/domain/ProjectType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package land.leets.domain.portfolio.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum ProjectType {
WEB("WEB");

private final String projectType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package land.leets.domain.portfolio.domain.repository;

import land.leets.domain.comment.domain.Comment;
import land.leets.domain.portfolio.domain.Portfolio;
import land.leets.domain.portfolio.domain.ProjectScope;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface PortfolioRepository extends JpaRepository<Portfolio, Long> {
List<Portfolio> findAllByGenerationAndScope(Long generation, ProjectScope scope);
List<Portfolio> findAllByScope(ProjectScope scope);
Portfolio findByPortfolioId(Long portfolioId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package land.leets.domain.portfolio.exception;

import land.leets.global.error.ErrorCode;
import land.leets.global.error.exception.ServiceException;

public class PortfolioNotFoundException extends ServiceException {
public PortfolioNotFoundException() {
super(ErrorCode.PORTFOLIO_NOT_FOUND);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package land.leets.domain.portfolio.presentation;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import land.leets.domain.portfolio.domain.ProjectScope;
import land.leets.domain.portfolio.presentation.dto.PortfolioRequest;
import land.leets.domain.portfolio.presentation.dto.PortfolioResponse;
import land.leets.domain.portfolio.presentation.dto.PortfoliosResponse;
import land.leets.domain.portfolio.usecase.CreatePortfolio;
import land.leets.domain.portfolio.usecase.GetPortfolios;
import land.leets.global.error.ErrorResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;

@RestController
@RequiredArgsConstructor
@RequestMapping("/portfolios")
public class PortfolioController {

private final CreatePortfolio createPortfolio;
private final GetPortfolios getPortfolios;

@Operation(summary = "(관리자) 포트폴리오 추가", description = "포트폴리오를 추가합니다.")
@ApiResponses({
@ApiResponse(responseCode = "200"),
@ApiResponse(responseCode = "400", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "403", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "404", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "500", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@PostMapping
public PortfolioResponse create(@RequestPart PortfolioRequest request,
@RequestPart(required = false) MultipartFile logoImg,
@RequestPart(required = false) MultipartFile coverImg,
@RequestPart(required = false) MultipartFile mainImg) {
return createPortfolio.execute(request, logoImg, coverImg, mainImg);
}

@Operation(summary = "(비로그인) 포트폴리오 조회", description = "포트폴리오를 조회합니다.")
@ApiResponses({
@ApiResponse(responseCode = "200"),
@ApiResponse(responseCode = "400", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "403", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "404", content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "500", content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
@GetMapping
public List<List<PortfoliosResponse>> getAll(@RequestParam(required = false) String generation) {
return getPortfolios.all(generation);
}

@GetMapping("/{portfolioId}")
public PortfolioResponse get(@PathVariable Long portfolioId) {
return getPortfolios.one(portfolioId);
}
}
Loading

0 comments on commit 3741327

Please sign in to comment.