From 1d7414dec3566bdfaa3b2c9c6d7b957897ca9043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?toni=20=28=EC=9D=B4=EC=86=8C=EC=9D=80=29?= <144209738+saokiritoni@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:49:36 +0900 Subject: [PATCH] =?UTF-8?q?Feat:=20=EC=95=84=EC=BD=94=ED=8F=B4=EB=A6=AC?= =?UTF-8?q?=EC=98=A4=20CRUD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dongguk/osori/config/RedisConfig.java | 8 +- .../dongguk/osori/config/SecurityConfig.java | 2 +- .../domain/follow/service/FollowService.java | 3 +- .../goal/service/GoalCommentService.java | 3 +- .../domain/goal/service/GoalService.java | 3 +- .../controller/PortfolioController.java | 57 +++++++ .../domain/portfolio/dto/ExperienceDto.java | 15 ++ .../osori/domain/portfolio/dto/PmiDto.java | 14 ++ .../portfolio/dto/PortfolioBaseDto.java | 21 +++ .../portfolio/dto/PortfolioDetailDto.java | 15 ++ .../portfolio/dto/PortfolioRequestDto.java | 19 +++ .../domain/portfolio/entity/Experience.java | 44 ++++++ .../osori/domain/portfolio/entity/Pmi.java | 39 +++++ .../domain/portfolio/entity/Portfolio.java | 67 +++++++++ .../osori/domain/portfolio/entity/Tag.java | 8 + .../repository/ExperienceRepository.java | 9 ++ .../portfolio/repository/PmiRepository.java | 9 ++ .../repository/PortfolioRepository.java | 23 +++ .../portfolio/service/PortfolioService.java | 141 ++++++++++++++++++ .../user/{ => controller}/UserController.java | 2 +- .../osori/domain/user/entity/User.java | 7 +- .../user/{ => repository}/UserRepository.java | 2 +- .../domain/user/service/UserService.java | 2 +- 23 files changed, 498 insertions(+), 15 deletions(-) create mode 100644 src/main/java/dongguk/osori/domain/portfolio/controller/PortfolioController.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/dto/ExperienceDto.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/dto/PmiDto.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioBaseDto.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioDetailDto.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioRequestDto.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/entity/Experience.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/entity/Pmi.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/entity/Portfolio.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/entity/Tag.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/repository/ExperienceRepository.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/repository/PmiRepository.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/repository/PortfolioRepository.java create mode 100644 src/main/java/dongguk/osori/domain/portfolio/service/PortfolioService.java rename src/main/java/dongguk/osori/domain/user/{ => controller}/UserController.java (99%) rename src/main/java/dongguk/osori/domain/user/{ => repository}/UserRepository.java (91%) diff --git a/src/main/java/dongguk/osori/config/RedisConfig.java b/src/main/java/dongguk/osori/config/RedisConfig.java index e3d8ec1..9f06619 100644 --- a/src/main/java/dongguk/osori/config/RedisConfig.java +++ b/src/main/java/dongguk/osori/config/RedisConfig.java @@ -10,7 +10,6 @@ import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; -import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; @Configuration @EnableRedisRepositories @@ -35,12 +34,13 @@ public RedisConnectionFactory redisConnectionFactory() { } @Bean - public RedisTemplate redisTemplate() { - RedisTemplate redisTemplate = new RedisTemplate<>(); + public RedisTemplate redisTemplate() { + RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setKeySerializer(new StringRedisSerializer()); - redisTemplate.setValueSerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.setConnectionFactory(redisConnectionFactory()); return redisTemplate; } + } diff --git a/src/main/java/dongguk/osori/config/SecurityConfig.java b/src/main/java/dongguk/osori/config/SecurityConfig.java index 254d1c8..51803d9 100644 --- a/src/main/java/dongguk/osori/config/SecurityConfig.java +++ b/src/main/java/dongguk/osori/config/SecurityConfig.java @@ -69,7 +69,7 @@ public PasswordEncoder passwordEncoder() { public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(List.of("http://localhost:3000")); // 정확한 오리진 설정 - configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 허용할 HTTP 메서드 + configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")); // 허용할 HTTP 메서드 configuration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type")); // 허용할 HTTP 헤더 configuration.setAllowCredentials(true); // 자격 증명 허용 diff --git a/src/main/java/dongguk/osori/domain/follow/service/FollowService.java b/src/main/java/dongguk/osori/domain/follow/service/FollowService.java index 9a659f7..b82049d 100644 --- a/src/main/java/dongguk/osori/domain/follow/service/FollowService.java +++ b/src/main/java/dongguk/osori/domain/follow/service/FollowService.java @@ -3,12 +3,11 @@ import dongguk.osori.domain.follow.FollowRepository; import dongguk.osori.domain.follow.dto.FollowDto; import dongguk.osori.domain.follow.entity.Follow; -import dongguk.osori.domain.user.UserRepository; +import dongguk.osori.domain.user.repository.UserRepository; import dongguk.osori.domain.user.entity.User; import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/dongguk/osori/domain/goal/service/GoalCommentService.java b/src/main/java/dongguk/osori/domain/goal/service/GoalCommentService.java index a724d9a..c578af3 100644 --- a/src/main/java/dongguk/osori/domain/goal/service/GoalCommentService.java +++ b/src/main/java/dongguk/osori/domain/goal/service/GoalCommentService.java @@ -8,13 +8,12 @@ import dongguk.osori.domain.goal.repository.GoalCommentRepository; import dongguk.osori.domain.goal.repository.GoalRepository; import dongguk.osori.domain.user.entity.User; -import dongguk.osori.domain.user.UserRepository; +import dongguk.osori.domain.user.repository.UserRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; diff --git a/src/main/java/dongguk/osori/domain/goal/service/GoalService.java b/src/main/java/dongguk/osori/domain/goal/service/GoalService.java index f829df4..ff60f60 100644 --- a/src/main/java/dongguk/osori/domain/goal/service/GoalService.java +++ b/src/main/java/dongguk/osori/domain/goal/service/GoalService.java @@ -1,12 +1,11 @@ package dongguk.osori.domain.goal.service; import dongguk.osori.domain.goal.dto.*; -import dongguk.osori.domain.goal.entity.GoalComment; import dongguk.osori.domain.goal.repository.GoalCommentRepository; import dongguk.osori.domain.goal.repository.GoalRepository; import dongguk.osori.domain.goal.entity.Goal; import dongguk.osori.domain.user.entity.User; -import dongguk.osori.domain.user.UserRepository; +import dongguk.osori.domain.user.repository.UserRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/dongguk/osori/domain/portfolio/controller/PortfolioController.java b/src/main/java/dongguk/osori/domain/portfolio/controller/PortfolioController.java new file mode 100644 index 0000000..5b99c3a --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/controller/PortfolioController.java @@ -0,0 +1,57 @@ +package dongguk.osori.domain.portfolio.controller; + +import dongguk.osori.domain.portfolio.dto.PortfolioBaseDto; +import dongguk.osori.domain.portfolio.dto.PortfolioDetailDto; +import dongguk.osori.domain.portfolio.dto.PortfolioRequestDto; +import dongguk.osori.domain.portfolio.service.PortfolioService; +import jakarta.servlet.http.HttpSession; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/portfolios") +@RequiredArgsConstructor +public class PortfolioController { + + private final PortfolioService portfolioService; + private final HttpSession httpSession; + + @PostMapping + public ResponseEntity createPortfolio(@RequestBody PortfolioRequestDto requestDto) { + Long userId = (Long) httpSession.getAttribute("userId"); + return ResponseEntity.ok(portfolioService.createPortfolio(userId, requestDto)); + } + + @GetMapping + public ResponseEntity> getPortfolioList() { + Long userId = (Long) httpSession.getAttribute("userId"); + return ResponseEntity.ok(portfolioService.getPortfolioList(userId)); + } + + @GetMapping("/{portfolioId}") + public ResponseEntity getPortfolioDetail(@PathVariable("portfolioId") Long portfolioId) { + Long userId = (Long) httpSession.getAttribute("userId"); + return ResponseEntity.ok(portfolioService.getPortfolioDetail(userId, portfolioId)); + } + + + @PutMapping("/{portfolioId}") + public ResponseEntity updatePortfolio( + @PathVariable("portfolioId") Long portfolioId, + @RequestBody PortfolioRequestDto requestDto + ) { + Long userId = (Long) httpSession.getAttribute("userId"); + return ResponseEntity.ok(portfolioService.updatePortfolio(userId, portfolioId, requestDto)); + } + + + @DeleteMapping("/{portfolioId}") + public ResponseEntity deletePortfolio(@PathVariable("portfolioId") Long portfolioId) { + Long userId = (Long) httpSession.getAttribute("userId"); + portfolioService.deletePortfolio(userId, portfolioId); + return ResponseEntity.noContent().build(); + } +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/dto/ExperienceDto.java b/src/main/java/dongguk/osori/domain/portfolio/dto/ExperienceDto.java new file mode 100644 index 0000000..a53aa6c --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/dto/ExperienceDto.java @@ -0,0 +1,15 @@ +package dongguk.osori.domain.portfolio.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ExperienceDto { + private String situation; + private String task; + private String action; + private String result; +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/dto/PmiDto.java b/src/main/java/dongguk/osori/domain/portfolio/dto/PmiDto.java new file mode 100644 index 0000000..b718de3 --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/dto/PmiDto.java @@ -0,0 +1,14 @@ +package dongguk.osori.domain.portfolio.dto; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PmiDto { + private String plus; + private String minus; + private String interesting; +} + diff --git a/src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioBaseDto.java b/src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioBaseDto.java new file mode 100644 index 0000000..dcaecb1 --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioBaseDto.java @@ -0,0 +1,21 @@ +package dongguk.osori.domain.portfolio.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +/* +목록 조회 dto + */ +public class PortfolioBaseDto { + private Long portfolioId; + private String name; + private LocalDate startDate; + private List tags; +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioDetailDto.java b/src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioDetailDto.java new file mode 100644 index 0000000..15950d5 --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioDetailDto.java @@ -0,0 +1,15 @@ +package dongguk.osori.domain.portfolio.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PortfolioDetailDto { + private PortfolioBaseDto baseInfo; + private ExperienceDto experience; + private PmiDto pmi; + +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioRequestDto.java b/src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioRequestDto.java new file mode 100644 index 0000000..8c67f0d --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/dto/PortfolioRequestDto.java @@ -0,0 +1,19 @@ +package dongguk.osori.domain.portfolio.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class PortfolioRequestDto { + private String name; + private LocalDate startDate; + private List tags; + private ExperienceDto experience; + private PmiDto pmi; +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/entity/Experience.java b/src/main/java/dongguk/osori/domain/portfolio/entity/Experience.java new file mode 100644 index 0000000..7439d72 --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/entity/Experience.java @@ -0,0 +1,44 @@ +package dongguk.osori.domain.portfolio.entity; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@Entity +public class Experience { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long experienceId; + + private String situation; + private String task; + private String action; + private String result; + + + + public Experience(String situation, String task, String action, String result) { + this.situation = situation; + this.task = task; + this.action = action; + this.result = result; + } + + public void setPortfolio(Portfolio portfolio) { + this.portfolio = portfolio; + } + + public void update(String situation, String task, String action, String result) { + this.situation = situation; + this.task = task; + this.action = action; + this.result = result; + } + + @OneToOne + @JoinColumn(name = "portfolio_id", nullable = false) + private Portfolio portfolio; +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/entity/Pmi.java b/src/main/java/dongguk/osori/domain/portfolio/entity/Pmi.java new file mode 100644 index 0000000..46bb123 --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/entity/Pmi.java @@ -0,0 +1,39 @@ +package dongguk.osori.domain.portfolio.entity; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@Entity +public class Pmi { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long pmiId; + + private String plus; + private String minus; + private String interesting; + + public Pmi(String plus, String minus, String interesting) { + this.plus = plus; + this.minus = minus; + this.interesting = interesting; + } + + public void setPortfolio(Portfolio portfolio) { + this.portfolio = portfolio; + } + + public void update(String plus, String minus, String interesting) { + this.plus = plus; + this.minus = minus; + this.interesting = interesting; + } + + @OneToOne + @JoinColumn(name = "portfolio_id", nullable = false) + private Portfolio portfolio; +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/entity/Portfolio.java b/src/main/java/dongguk/osori/domain/portfolio/entity/Portfolio.java new file mode 100644 index 0000000..059a567 --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/entity/Portfolio.java @@ -0,0 +1,67 @@ +package dongguk.osori.domain.portfolio.entity; + +import dongguk.osori.domain.user.entity.User; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; + +@Getter +@NoArgsConstructor +@Entity +public class Portfolio { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long portfolioId; + + private String name; + private LocalDate startDate; + + @ElementCollection + @CollectionTable(name = "portfolio_tags", joinColumns = @JoinColumn(name = "portfolio_id")) + @Column(name = "tag") + private Set tags = new HashSet<>(); + + public Portfolio(String name, LocalDate startDate, Set tags, Experience experience, Pmi pmi, User user) { + this.name = name; + this.startDate = startDate; + this.tags = tags; + this.user = user; + setExperience(experience); + setPmi(pmi); + } + + public void update(String name, LocalDate startDate, Set tags) { + this.name = name; + this.startDate = startDate; + this.tags = tags; + } + + public void setExperience(Experience experience) { + this.experience = experience; + if (experience != null) { + experience.setPortfolio(this); + } + } + + public void setPmi(Pmi pmi) { + this.pmi = pmi; + if (pmi != null) { + pmi.setPortfolio(this); + } + } + + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "portfolio") + private Experience experience; + + @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "portfolio") + private Pmi pmi; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/entity/Tag.java b/src/main/java/dongguk/osori/domain/portfolio/entity/Tag.java new file mode 100644 index 0000000..ac2cf25 --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/entity/Tag.java @@ -0,0 +1,8 @@ +package dongguk.osori.domain.portfolio.entity; + +public enum Tag { + 전공, 교양, 교내동아리, 교외동아리, 학회, 봉사활동, 인턴, 아르바이트, + 대외활동, 서포터즈, 기자단, 강연행사, 스터디, 부트캠프, 프로젝트, 연구, + 학생회, 기타 + +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/repository/ExperienceRepository.java b/src/main/java/dongguk/osori/domain/portfolio/repository/ExperienceRepository.java new file mode 100644 index 0000000..3b3356e --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/repository/ExperienceRepository.java @@ -0,0 +1,9 @@ +package dongguk.osori.domain.portfolio.repository; + +import dongguk.osori.domain.portfolio.entity.Experience; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ExperienceRepository extends JpaRepository { +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/repository/PmiRepository.java b/src/main/java/dongguk/osori/domain/portfolio/repository/PmiRepository.java new file mode 100644 index 0000000..ba30737 --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/repository/PmiRepository.java @@ -0,0 +1,9 @@ +package dongguk.osori.domain.portfolio.repository; + +import dongguk.osori.domain.portfolio.entity.Pmi; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PmiRepository extends JpaRepository { +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/repository/PortfolioRepository.java b/src/main/java/dongguk/osori/domain/portfolio/repository/PortfolioRepository.java new file mode 100644 index 0000000..24bf8cd --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/repository/PortfolioRepository.java @@ -0,0 +1,23 @@ +package dongguk.osori.domain.portfolio.repository; + +import dongguk.osori.domain.portfolio.entity.Portfolio; +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 org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface PortfolioRepository extends JpaRepository { + + @EntityGraph(attributePaths = {"experience", "pmi"}) + @Query("SELECT p FROM Portfolio p WHERE p.portfolioId = :portfolioId AND p.user.userId = :userId") + Optional findPortfolioWithDetails(@Param("portfolioId") Long portfolioId, @Param("userId") Long userId); + + @EntityGraph(attributePaths = {"experience", "pmi"}) + @Query("SELECT p FROM Portfolio p WHERE p.user.userId = :userId") + List findAllPortfoliosWithDetailsByUserId(@Param("userId") Long userId); +} diff --git a/src/main/java/dongguk/osori/domain/portfolio/service/PortfolioService.java b/src/main/java/dongguk/osori/domain/portfolio/service/PortfolioService.java new file mode 100644 index 0000000..a022656 --- /dev/null +++ b/src/main/java/dongguk/osori/domain/portfolio/service/PortfolioService.java @@ -0,0 +1,141 @@ +package dongguk.osori.domain.portfolio.service; + +import dongguk.osori.domain.portfolio.dto.*; +import dongguk.osori.domain.portfolio.entity.*; +import dongguk.osori.domain.portfolio.repository.PortfolioRepository; +import dongguk.osori.domain.user.entity.User; +import dongguk.osori.domain.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class PortfolioService { + + private final PortfolioRepository portfolioRepository; + private final UserRepository userRepository; + + @Transactional + public PortfolioDetailDto createPortfolio(Long userId, PortfolioRequestDto requestDto) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new IllegalArgumentException("User not found with ID: " + userId)); + + Experience experience = new Experience( + requestDto.getExperience().getSituation(), + requestDto.getExperience().getTask(), + requestDto.getExperience().getAction(), + requestDto.getExperience().getResult() + ); + + Pmi pmi = new Pmi( + requestDto.getPmi().getPlus(), + requestDto.getPmi().getMinus(), + requestDto.getPmi().getInteresting() + ); + + Portfolio portfolio = new Portfolio( + requestDto.getName(), + requestDto.getStartDate(), + Set.copyOf(requestDto.getTags()), + experience, + pmi, + user + ); + + portfolioRepository.save(portfolio); + + return mapToDetailDto(portfolio); + } + + @Transactional(readOnly = true) + public List getPortfolioList(Long userId) { + return portfolioRepository.findAllPortfoliosWithDetailsByUserId(userId).stream() + .map(this::mapToBaseDto) + .collect(Collectors.toList()); + } + + @Transactional(readOnly = true) + public PortfolioDetailDto getPortfolioDetail(Long userId, Long portfolioId) { + Portfolio portfolio = portfolioRepository.findPortfolioWithDetails(portfolioId, userId) + .orElseThrow(() -> new IllegalArgumentException("Portfolio not found or access denied for ID: " + portfolioId)); + + return mapToDetailDto(portfolio); + } + + @Transactional + public PortfolioDetailDto updatePortfolio(Long userId, Long portfolioId, PortfolioRequestDto requestDto) { + Portfolio portfolio = portfolioRepository.findPortfolioWithDetails(portfolioId, userId) + .orElseThrow(() -> new IllegalArgumentException("Portfolio not found or access denied for ID: " + portfolioId)); + + portfolio.update( + requestDto.getName(), + requestDto.getStartDate(), + Set.copyOf(requestDto.getTags()) + ); + + portfolio.getExperience().update( + requestDto.getExperience().getSituation(), + requestDto.getExperience().getTask(), + requestDto.getExperience().getAction(), + requestDto.getExperience().getResult() + ); + + portfolio.getPmi().update( + requestDto.getPmi().getPlus(), + requestDto.getPmi().getMinus(), + requestDto.getPmi().getInteresting() + ); + + return mapToDetailDto(portfolio); + } + + @Transactional + public void deletePortfolio(Long userId, Long portfolioId) { + Portfolio portfolio = portfolioRepository.findPortfolioWithDetails(portfolioId, userId) + .orElseThrow(() -> new IllegalArgumentException("Portfolio not found or access denied for ID: " + portfolioId)); + + portfolioRepository.delete(portfolio); + } + + private PortfolioBaseDto mapToBaseDto(Portfolio portfolio) { + return new PortfolioBaseDto( + portfolio.getPortfolioId(), + portfolio.getName(), + portfolio.getStartDate(), + List.copyOf(portfolio.getTags()) + ); + } + + private PortfolioDetailDto mapToDetailDto(Portfolio portfolio) { + + ExperienceDto experienceDto = portfolio.getExperience() != null + ? new ExperienceDto( + portfolio.getExperience().getSituation(), + portfolio.getExperience().getTask(), + portfolio.getExperience().getAction(), + portfolio.getExperience().getResult() + ) + : null; + + PmiDto pmiDto = portfolio.getPmi() != null + ? new PmiDto( + portfolio.getPmi().getPlus(), + portfolio.getPmi().getMinus(), + portfolio.getPmi().getInteresting() + ) + : null; + + return new PortfolioDetailDto( + mapToBaseDto(portfolio), + experienceDto, + pmiDto + ); + } + +} + diff --git a/src/main/java/dongguk/osori/domain/user/UserController.java b/src/main/java/dongguk/osori/domain/user/controller/UserController.java similarity index 99% rename from src/main/java/dongguk/osori/domain/user/UserController.java rename to src/main/java/dongguk/osori/domain/user/controller/UserController.java index e76b847..208ba08 100644 --- a/src/main/java/dongguk/osori/domain/user/UserController.java +++ b/src/main/java/dongguk/osori/domain/user/controller/UserController.java @@ -1,4 +1,4 @@ -package dongguk.osori.domain.user; +package dongguk.osori.domain.user.controller; import dongguk.osori.domain.user.dto.*; import dongguk.osori.domain.user.service.EmailService; diff --git a/src/main/java/dongguk/osori/domain/user/entity/User.java b/src/main/java/dongguk/osori/domain/user/entity/User.java index 378e399..09279d3 100644 --- a/src/main/java/dongguk/osori/domain/user/entity/User.java +++ b/src/main/java/dongguk/osori/domain/user/entity/User.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonManagedReference; import dongguk.osori.domain.follow.entity.Follow; import dongguk.osori.domain.goal.entity.Goal; +import dongguk.osori.domain.portfolio.entity.Portfolio; import jakarta.persistence.*; import lombok.*; @@ -49,7 +50,8 @@ public void updateNickName(String nickname) { public void updateMajor(String major) { this.major = major; } public void updateStudentNumber(int studentNumber) { this.studentNumber = studentNumber; } public void updateIntroduce(String introduce) { this.introduce = introduce; } - public void updateBalance(int amount) { + public void updateBalance(int + amount) { if (this.balance == null) { this.balance = 0; } @@ -66,6 +68,9 @@ public void updateBalance(int amount) { @OneToMany(mappedBy = "following", cascade = CascadeType.ALL, orphanRemoval = true) private List followers = new ArrayList<>(); + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) + private List portfolios = new ArrayList<>(); + // 팔로우하는 사용자 목록 반환 public List getFollowingUsers() { return following.stream() diff --git a/src/main/java/dongguk/osori/domain/user/UserRepository.java b/src/main/java/dongguk/osori/domain/user/repository/UserRepository.java similarity index 91% rename from src/main/java/dongguk/osori/domain/user/UserRepository.java rename to src/main/java/dongguk/osori/domain/user/repository/UserRepository.java index 0bf25fa..f76e9cf 100644 --- a/src/main/java/dongguk/osori/domain/user/UserRepository.java +++ b/src/main/java/dongguk/osori/domain/user/repository/UserRepository.java @@ -1,4 +1,4 @@ -package dongguk.osori.domain.user; +package dongguk.osori.domain.user.repository; import dongguk.osori.domain.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/dongguk/osori/domain/user/service/UserService.java b/src/main/java/dongguk/osori/domain/user/service/UserService.java index 634ca4d..1df4475 100644 --- a/src/main/java/dongguk/osori/domain/user/service/UserService.java +++ b/src/main/java/dongguk/osori/domain/user/service/UserService.java @@ -1,6 +1,6 @@ package dongguk.osori.domain.user.service; -import dongguk.osori.domain.user.UserRepository; +import dongguk.osori.domain.user.repository.UserRepository; import dongguk.osori.domain.user.dto.*; import dongguk.osori.domain.user.entity.User; import lombok.RequiredArgsConstructor;