diff --git a/src/main/java/NextLevel/demo/project/project/service/ProjectSelectService.java b/src/main/java/NextLevel/demo/project/project/service/ProjectSelectService.java deleted file mode 100644 index 1d1596b..0000000 --- a/src/main/java/NextLevel/demo/project/project/service/ProjectSelectService.java +++ /dev/null @@ -1,40 +0,0 @@ -//package NextLevel.demo.project.project.service; -// -//import NextLevel.demo.project.project.dto.request.RequestMainPageProjectListDto; -//import NextLevel.demo.project.project.dto.response.ResponseProjectListDetailDto; -//import NextLevel.demo.project.project.dto.response.ResponseProjectListDto; -//import NextLevel.demo.project.project.entity.ProjectEntity; -//import NextLevel.demo.project.project.repository.ProjectRepository; -//import lombok.RequiredArgsConstructor; -//import org.springframework.stereotype.Service; -// -//import java.util.HashMap; -//import java.util.List; -//import java.util.Map; -// -//@Service -//@RequiredArgsConstructor -//public class ProjectSelectService { -// -// private final ProjectRepository projectRepository; -// -// public ResponseProjectListDto getAllProjects(List detailDtos, RequestMainPageProjectListDto dto) { -// List detailDtos -// -// // set tags -> project select service 를 따로 분리해서 두는 것이 합당하다고 판단함 -// Map dtoMap = new HashMap<>(); -// detailDtos.forEach(e -> {dtoMap.put(e.getId(), e);}); -// -// List tags = projectRepository.findTagsByIds(dtoMap.keySet()); -// tags.forEach((e)-> -// dtoMap.get(e.getId()).setTags( -// e.getTags().stream().map(pt->pt.getTag().getName()).toList() -// ) -// ); -// -// ResponseProjectListDto resultDto = new ResponseProjectListDto(detailDtos, dto.getPageCount(), dto.getPage()); -// -// return resultDto; -// } -// -//} diff --git a/src/main/java/NextLevel/demo/project/story/service/ProjectStoryService.java b/src/main/java/NextLevel/demo/project/story/service/ProjectStoryService.java index 5daf10c..400ce8a 100644 --- a/src/main/java/NextLevel/demo/project/story/service/ProjectStoryService.java +++ b/src/main/java/NextLevel/demo/project/story/service/ProjectStoryService.java @@ -48,9 +48,9 @@ public void saveNewProjectStory(ProjectEntity project, List imgFi @ImgTransaction public void updateProjectStory(ProjectEntity project, List imgFiles, ArrayList imgPaths) { List oldImgs = project.getStories().stream().map(projectImg -> projectImg.getImg()).toList(); - log.info(Arrays.toString(oldImgs.toArray())); + projectStoryRepository.deleteAllByProjectId(project.getId()); - log.info(Arrays.toString(oldImgs.toArray())); + oldImgs.forEach(img->imgService.deleteImg(img)); saveNewProjectStory(project, imgFiles, imgPaths); } diff --git a/src/main/java/NextLevel/demo/social/controller/SocialController.java b/src/main/java/NextLevel/demo/social/controller/SocialController.java new file mode 100644 index 0000000..78c6aea --- /dev/null +++ b/src/main/java/NextLevel/demo/social/controller/SocialController.java @@ -0,0 +1,43 @@ +package NextLevel.demo.social.controller; + +import NextLevel.demo.common.SuccessResponse; +import NextLevel.demo.social.dto.RequestSocialCreateDto; +import NextLevel.demo.social.service.SocialService; +import NextLevel.demo.util.jwt.JWTUtil; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +@Controller +@RequiredArgsConstructor +public class SocialController { + + private final SocialService socialService; + + @PostMapping("/api1/social") + public ResponseEntity create(@ModelAttribute RequestSocialCreateDto dto) { + dto.setUserId(JWTUtil.getUserIdFromSecurityContext()); + socialService.create(dto, null); + return ResponseEntity.ok().body(new SuccessResponse("success", null)); + } + + @PutMapping("/api1/social") + public ResponseEntity update(@ModelAttribute RequestSocialCreateDto dto) { + dto.setUserId(JWTUtil.getUserIdFromSecurityContext()); + socialService.update(dto, null); + return ResponseEntity.ok().body(new SuccessResponse("success", null)); + } + + @DeleteMapping("/api1/social/{socialId}") + public ResponseEntity delete(@PathVariable("socialId") Long socialId) { + socialService.delete(socialId, JWTUtil.getUserIdFromSecurityContext()); + return ResponseEntity.ok().body(new SuccessResponse("success", null)); + } + + @GetMapping("/public/social/{userId}") + public ResponseEntity list(@PathVariable("userId") Long userId) { + return ResponseEntity.ok().body(new SuccessResponse("success", socialService.list(userId))); + } + +} diff --git a/src/main/java/NextLevel/demo/social/dto/RequestSocialCreateDto.java b/src/main/java/NextLevel/demo/social/dto/RequestSocialCreateDto.java new file mode 100644 index 0000000..4f9ed27 --- /dev/null +++ b/src/main/java/NextLevel/demo/social/dto/RequestSocialCreateDto.java @@ -0,0 +1,32 @@ +package NextLevel.demo.social.dto; + +import NextLevel.demo.social.entity.SocialEntity; +import NextLevel.demo.social.entity.SocialImgEntity; +import NextLevel.demo.user.entity.UserEntity; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@NoArgsConstructor +@Getter +@Setter +public class RequestSocialCreateDto { + + private Long id; + private String text; + private List imgs; + + private Long userId; + + public SocialEntity toEntity(UserEntity user) { + return SocialEntity + .builder() + .text(text) + .user(user) + .build(); + } + +} diff --git a/src/main/java/NextLevel/demo/social/dto/ResponseSocialDto.java b/src/main/java/NextLevel/demo/social/dto/ResponseSocialDto.java new file mode 100644 index 0000000..fc592b2 --- /dev/null +++ b/src/main/java/NextLevel/demo/social/dto/ResponseSocialDto.java @@ -0,0 +1,30 @@ +package NextLevel.demo.social.dto; + +import NextLevel.demo.img.ImgDto; +import NextLevel.demo.social.entity.SocialEntity; +import NextLevel.demo.social.entity.SocialImgEntity; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +@NoArgsConstructor +@Getter +@Setter +public class ResponseSocialDto { + + private Long id; + private String text; + private List imgs; + + public static ResponseSocialDto of(SocialEntity entity) { + ResponseSocialDto dto = new ResponseSocialDto(); + dto.id = entity.getId(); + dto.text = entity.getText(); + dto.imgs = entity.getImgs().stream().map(SocialImgEntity::getImg).map(ImgDto::new).toList(); + return dto; + } + +} diff --git a/src/main/java/NextLevel/demo/social/entity/SocialEntity.java b/src/main/java/NextLevel/demo/social/entity/SocialEntity.java new file mode 100644 index 0000000..ad38478 --- /dev/null +++ b/src/main/java/NextLevel/demo/social/entity/SocialEntity.java @@ -0,0 +1,39 @@ +package NextLevel.demo.social.entity; + +import NextLevel.demo.BasedEntity; +import NextLevel.demo.social.dto.RequestSocialCreateDto; +import NextLevel.demo.user.entity.UserEntity; +import jakarta.persistence.*; +import lombok.*; + +import java.util.List; + +@Entity +@Table(name = "social") +@Getter +@Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Builder +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class SocialEntity extends BasedEntity { + + @Id + @GeneratedValue + private Long id; + + @Column(nullable = true) + private String text; + + @OneToMany(mappedBy = "social") + private List imgs; + + @ManyToOne + @JoinColumn(name = "user_id") + private UserEntity user; + + public void update(RequestSocialCreateDto dto) { + if(dto.getText()!=null && !dto.getText().isEmpty()) + this.text = dto.getText(); + } + +} diff --git a/src/main/java/NextLevel/demo/social/entity/SocialImgEntity.java b/src/main/java/NextLevel/demo/social/entity/SocialImgEntity.java new file mode 100644 index 0000000..2d5ab1b --- /dev/null +++ b/src/main/java/NextLevel/demo/social/entity/SocialImgEntity.java @@ -0,0 +1,26 @@ +package NextLevel.demo.social.entity; + +import NextLevel.demo.img.entity.ImgEntity; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Table(name = "social_img") +@Getter +@Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Builder +@AllArgsConstructor(access = AccessLevel.PROTECTED) +public class SocialImgEntity { + @Id + @GeneratedValue + private Long id; + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "img_id") + private ImgEntity img; + + @ManyToOne(cascade = {}) + @JoinColumn(name = "social_id") + private SocialEntity social; +} diff --git a/src/main/java/NextLevel/demo/social/repository/SocialImgRepository.java b/src/main/java/NextLevel/demo/social/repository/SocialImgRepository.java new file mode 100644 index 0000000..312a3e1 --- /dev/null +++ b/src/main/java/NextLevel/demo/social/repository/SocialImgRepository.java @@ -0,0 +1,16 @@ +package NextLevel.demo.social.repository; + +import NextLevel.demo.social.entity.SocialImgEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface SocialImgRepository extends JpaRepository { + + @Modifying + @Query("delete from SocialImgEntity si where si.social.id = :socialId") + void deleteAllBySocialId(@Param("socialId") Long socialId); +} diff --git a/src/main/java/NextLevel/demo/social/repository/SocialRepository.java b/src/main/java/NextLevel/demo/social/repository/SocialRepository.java new file mode 100644 index 0000000..b08b8ec --- /dev/null +++ b/src/main/java/NextLevel/demo/social/repository/SocialRepository.java @@ -0,0 +1,17 @@ +package NextLevel.demo.social.repository; + +import NextLevel.demo.social.entity.SocialEntity; +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; + +@Repository +public interface SocialRepository extends JpaRepository { + + @Query("select s from SocialEntity s left join fetch s.imgs where s.user.id = :userId order by s.createdAt desc") + List findAllByUserId(@Param("userId") Long userId); + +} diff --git a/src/main/java/NextLevel/demo/social/service/SocialService.java b/src/main/java/NextLevel/demo/social/service/SocialService.java new file mode 100644 index 0000000..4c3c5e8 --- /dev/null +++ b/src/main/java/NextLevel/demo/social/service/SocialService.java @@ -0,0 +1,105 @@ +package NextLevel.demo.social.service; + +import NextLevel.demo.exception.CustomException; +import NextLevel.demo.exception.ErrorCode; +import NextLevel.demo.img.entity.ImgEntity; +import NextLevel.demo.img.service.ImgService; +import NextLevel.demo.img.service.ImgTransaction; +import NextLevel.demo.social.dto.RequestSocialCreateDto; +import NextLevel.demo.social.dto.ResponseSocialDto; +import NextLevel.demo.social.entity.SocialEntity; +import NextLevel.demo.social.entity.SocialImgEntity; +import NextLevel.demo.social.repository.SocialImgRepository; +import NextLevel.demo.social.repository.SocialRepository; +import NextLevel.demo.user.entity.UserEntity; +import NextLevel.demo.user.service.UserValidateService; +import jakarta.persistence.EntityManager; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class SocialService { + + private final SocialRepository socialRepository; + + private final UserValidateService userValidateService; + + private final ImgService imgService; + private final SocialImgRepository socialImgRepository; + + private final EntityManager entityManager; + + @ImgTransaction + @Transactional + public void create(RequestSocialCreateDto dto, ArrayList imgPaths) { + UserEntity user = userValidateService.getUserInfo(dto.getUserId()); + SocialEntity social = socialRepository.save(dto.toEntity(user)); + + saveImgs(dto.getImgs(), social, imgPaths); + } + + @ImgTransaction + @Transactional + public void update(RequestSocialCreateDto dto, ArrayList imgPaths) { + SocialEntity social = socialRepository.findById(dto.getId()).orElseThrow( + ()->{return new CustomException(ErrorCode.NOT_FOUND, "social");} + ); + + if(!social.getUser().getId().equals(dto.getUserId())) + throw new CustomException(ErrorCode.NOT_AUTHOR); + + if(dto.getImgs() != null && !dto.getImgs().isEmpty()){ + deleteImgs(social.getId(), social.getImgs().stream().map(SocialImgEntity::getImg).toList()); + saveImgs(dto.getImgs(), social, imgPaths); + } + + social.update(dto); + } + + @Transactional + public void delete(Long socialId, Long userId) { + SocialEntity social = socialRepository.findById(socialId).orElseThrow( + ()->{return new CustomException(ErrorCode.NOT_FOUND, "social");} + ); + + if(!social.getUser().getId().equals(userId)) + throw new CustomException(ErrorCode.NOT_AUTHOR); + + deleteImgs(socialId, social.getImgs().stream().map(SocialImgEntity::getImg).toList()); + + entityManager.flush(); + entityManager.clear(); + + socialRepository.deleteById(social.getId()); + } + + public List list(Long userId) { + List socials = socialRepository.findAllByUserId(userId); + return socials.stream().map(ResponseSocialDto::of).toList(); + } + + private void saveImgs(List imgFiles, SocialEntity social, ArrayList imgPaths) { + imgFiles.forEach(imgFile -> + socialImgRepository.save( + SocialImgEntity + .builder() + .social(social) + .img(imgService.saveImg(imgFile, imgPaths)) + .build() + ) + ); + } + + private void deleteImgs(Long socialId, List imgs) { + socialImgRepository.deleteAllBySocialId(socialId); + imgs.forEach(img->imgService.deleteImg(img)); + } + +} diff --git a/src/main/java/NextLevel/demo/user/controller/SocialController.java b/src/main/java/NextLevel/demo/user/controller/SocialLoginController.java similarity index 95% rename from src/main/java/NextLevel/demo/user/controller/SocialController.java rename to src/main/java/NextLevel/demo/user/controller/SocialLoginController.java index 966d18a..54dab77 100644 --- a/src/main/java/NextLevel/demo/user/controller/SocialController.java +++ b/src/main/java/NextLevel/demo/user/controller/SocialLoginController.java @@ -10,12 +10,10 @@ import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.coyote.Response; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -23,7 +21,7 @@ @RequiredArgsConstructor @Controller @RequestMapping("/public/auth") -public class SocialController { +public class SocialLoginController { private final KakaoService kakaoService; private final NaverService naverService;