Skip to content
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
2 changes: 2 additions & 0 deletions src/main/java/NextLevel/demo/follow/FollowRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ public interface FollowRepository extends JpaRepository<FollowEntity, Long> {
@Query("select f from FollowEntity f where f.user.id = :userId and f.target.id = :targetId")
Optional<FollowEntity> findByUserIdAndTargetId(@Param("userId") Long userId, @Param("targetId") Long targetId);

@Query("select count(f.id) from FollowEntity f where f.target.id = :userId")
Long followCount(@Param("userId") Long userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package NextLevel.demo.follow;

import NextLevel.demo.user.dto.user.response.UserSocialProfileDto;
import NextLevel.demo.user.entity.UserEntity;
import NextLevel.demo.user.service.UserValidateService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class SelectSocialProfileService {

private final FollowRepository followRepository;
private final UserValidateService validateService;

public UserSocialProfileDto selectUserSocialProfile(long userId) {
UserEntity user = validateService.findUserWithUserId(userId);
return selectUserSocialProfile(user);
}

public UserSocialProfileDto selectUserSocialProfile(UserEntity user) {
return UserSocialProfileDto.of(user, followRepository.followCount(user.getId()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import NextLevel.demo.common.SuccessResponse;
import NextLevel.demo.social.dto.RequestSocialCreateDto;
import NextLevel.demo.social.dto.SocialLikeDto;
import NextLevel.demo.social.service.SocialService;
import NextLevel.demo.util.jwt.JWTUtil;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,29 +16,36 @@ public class SocialController {

private final SocialService socialService;

@PostMapping("/api1/social")
@PostMapping("/social/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")
@PutMapping("/social/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}")
@DeleteMapping("/social/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)));
public ResponseEntity list(@PathVariable("userId") Long targetUserId) {
return ResponseEntity.ok().body(new SuccessResponse("success", socialService.list(targetUserId,JWTUtil.getUserIdFromSecurityContextCanNULL())));
}

@PostMapping("/social/social/like")
public ResponseEntity socialLike(@RequestBody SocialLikeDto dto) {
dto.setUserId(JWTUtil.getUserIdFromSecurityContext());
socialService.socialLike(dto);
return ResponseEntity.ok().body(new SuccessResponse("success", null));
}

}
16 changes: 10 additions & 6 deletions src/main/java/NextLevel/demo/social/dto/ResponseSocialDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import NextLevel.demo.img.ImgDto;
import NextLevel.demo.social.entity.SocialEntity;
import NextLevel.demo.social.entity.SocialImgEntity;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
Expand All @@ -18,13 +19,16 @@ public class ResponseSocialDto {
private Long id;
private String text;
private List<ImgDto> imgs;
private Long socialLikeCount;
@JsonProperty("isLiked")
private boolean isSocialLike; // 내 좋아요 여부

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;
public ResponseSocialDto(SocialEntity entity, Long totalLikeCount, Long myLikeCount) {
id = entity.getId();
text = entity.getText();
imgs = entity.getImgs().stream().map(SocialImgEntity::getImg).map(ImgDto::new).toList();
socialLikeCount = totalLikeCount != null ? totalLikeCount : 0L;
isSocialLike = myLikeCount != null && myLikeCount.equals(1L);
}

}
20 changes: 20 additions & 0 deletions src/main/java/NextLevel/demo/social/dto/SocialLikeDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package NextLevel.demo.social.dto;

import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@NoArgsConstructor
@Getter
@Setter
public class SocialLikeDto {

@NotNull
private Long socialId;

private Long userId;

@NotNull
private Boolean like;
}
25 changes: 25 additions & 0 deletions src/main/java/NextLevel/demo/social/dto/SocialListDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package NextLevel.demo.social.dto;

import NextLevel.demo.user.dto.user.response.UserSocialProfileDto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.List;

@NoArgsConstructor
@Getter
@Setter
public class SocialListDto {

private UserSocialProfileDto user;
private List<ResponseSocialDto> socials;

public static SocialListDto of(UserSocialProfileDto user, List<ResponseSocialDto> socials) {
SocialListDto dto = new SocialListDto();
dto.user = user;
dto.socials = socials;
return dto;
}

}
3 changes: 3 additions & 0 deletions src/main/java/NextLevel/demo/social/entity/SocialEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ public class SocialEntity extends BasedEntity {
@JoinColumn(name = "user_id")
private UserEntity user;

@OneToMany(mappedBy = "social", fetch = FetchType.LAZY, cascade = {})
private List<SocialLikeEntity> likes;

public void update(RequestSocialCreateDto dto) {
if(dto.getText()!=null && !dto.getText().isEmpty())
this.text = dto.getText();
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/NextLevel/demo/social/entity/SocialLikeEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package NextLevel.demo.social.entity;

import NextLevel.demo.project.project.entity.ProjectEntity;
import NextLevel.demo.user.entity.UserEntity;
import jakarta.persistence.*;
import lombok.*;

@Entity
@Table(name = "social_like" , uniqueConstraints = {@UniqueConstraint(name="socialLikeUniqueConstraint", columnNames = {"user_id", "social_id"})})
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class SocialLikeEntity {

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

@ManyToOne
@JoinColumn(name = "social_id", nullable = false)
private SocialEntity social;

@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private UserEntity user;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package NextLevel.demo.social.repository;

public interface IsSelectSocialLikedListInterface {
Long getSocialId();
Long getTotalLikeCount();
Long getMyLikeCount();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package NextLevel.demo.social.repository;

import NextLevel.demo.social.entity.SocialLikeEntity;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface SocialLikeRepository extends JpaRepository<SocialLikeEntity, Long> {
Optional<SocialLikeEntity> findByUserIdAndSocialId(Long userId, Long socialId);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package NextLevel.demo.social.repository;

import NextLevel.demo.social.dto.ResponseSocialDto;
import NextLevel.demo.social.entity.SocialEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -11,7 +12,20 @@
@Repository
public interface SocialRepository extends JpaRepository<SocialEntity, Long> {

@Query("select s from SocialEntity s left join fetch s.imgs where s.user.id = :userId order by s.createdAt desc")
List<SocialEntity> findAllByUserId(@Param("userId") Long userId);
@Query("select s " +
"from SocialEntity s " +
"left join fetch s.imgs " +
"where s.user.id = :targetUserId " +
"order by s.createdAt desc "
)
List<SocialEntity> findAllByUserId(@Param("targetUserId") Long targetUserId);

@Query("select sl.id as socialId, count(distinct total_like) as totalLikeCount, count(distinct my_like) as myLikeCount " +
"from SocialEntity sl " +
"left join SocialLikeEntity total_like on total_like.social.id = sl.id " +
"left join SocialLikeEntity my_like on my_like.social.id = sl.id and my_like.user.id = :userId " +
"where sl.id in :socialIds " +
"group by sl ")
List<IsSelectSocialLikedListInterface> isSelectSocialLikeList(@Param("socialIds") List<Long> socialIds, @Param("userId") Long userId);

}
57 changes: 52 additions & 5 deletions src/main/java/NextLevel/demo/social/service/SocialService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@

import NextLevel.demo.exception.CustomException;
import NextLevel.demo.exception.ErrorCode;
import NextLevel.demo.follow.SelectSocialProfileService;
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.dto.SocialLikeDto;
import NextLevel.demo.social.dto.SocialListDto;
import NextLevel.demo.social.entity.SocialEntity;
import NextLevel.demo.social.entity.SocialImgEntity;
import NextLevel.demo.social.entity.SocialLikeEntity;
import NextLevel.demo.social.repository.SocialImgRepository;
import NextLevel.demo.social.repository.SocialLikeRepository;
import NextLevel.demo.social.repository.SocialRepository;
import NextLevel.demo.social.repository.IsSelectSocialLikedListInterface;
import NextLevel.demo.user.dto.user.response.UserSocialProfileDto;
import NextLevel.demo.user.entity.UserEntity;
import NextLevel.demo.user.service.UserValidateService;
import jakarta.persistence.EntityManager;
Expand All @@ -20,8 +27,7 @@
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.*;

@Service
@RequiredArgsConstructor
Expand All @@ -35,6 +41,8 @@ public class SocialService {
private final SocialImgRepository socialImgRepository;

private final EntityManager entityManager;
private final SocialLikeRepository socialLikeRepository;
private final SelectSocialProfileService selectSocialProfileService;

@ImgTransaction
@Transactional
Expand Down Expand Up @@ -80,9 +88,48 @@ public void delete(Long socialId, Long userId) {
socialRepository.deleteById(social.getId());
}

public List<ResponseSocialDto> list(Long userId) {
List<SocialEntity> socials = socialRepository.findAllByUserId(userId);
return socials.stream().map(ResponseSocialDto::of).toList();
public void socialLike( SocialLikeDto dto) {
SocialEntity social = socialRepository.findById(dto.getSocialId()).orElseThrow(
()->{return new CustomException(ErrorCode.NOT_FOUND, "social");}
);
Optional<SocialLikeEntity> oldLikeOpt = socialLikeRepository.findByUserIdAndSocialId(dto.getUserId(), dto.getSocialId());
if(dto.getLike() && oldLikeOpt.isEmpty()) {
// 좋야요를 누름
socialLikeRepository.save(SocialLikeEntity
.builder()
.user(entityManager.getReference(UserEntity.class, dto.getUserId()))
.social(social)
.build());
}
if(!dto.getLike() && oldLikeOpt.isPresent()) {
// 좋아요 취소
socialLikeRepository.delete(oldLikeOpt.get());
}
}

public SocialListDto list(Long targetUserId, Long userId) {
UserEntity targetUser = userValidateService.findUserWithUserId(targetUserId);

List<SocialEntity> socialEntityList = socialRepository.findAllByUserId(targetUserId);
List<IsSelectSocialLikedListInterface> isSocialLikedList = socialRepository.isSelectSocialLikeList(socialEntityList.stream().map(SocialEntity::getId).toList(), userId);

Map<Long, IsSelectSocialLikedListInterface> isSocialLikedMap = new HashMap<>();
isSocialLikedList.forEach(isLikedInterface->
isSocialLikedMap.put(
isLikedInterface.getSocialId(),
isLikedInterface
)
);

List<ResponseSocialDto> socials = socialEntityList.stream().map(entity->
new ResponseSocialDto(
entity,
isSocialLikedMap.get(entity.getId()).getTotalLikeCount(),
isSocialLikedMap.get(entity.getId()).getMyLikeCount()
)).toList();

UserSocialProfileDto user = selectSocialProfileService.selectUserSocialProfile(targetUser);
return SocialListDto.of(user, socials);
}

private void saveImgs(List<MultipartFile> imgFiles, SocialEntity social, ArrayList<Path> imgPaths) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package NextLevel.demo.user.dto.user.response;

import NextLevel.demo.img.ImgDto;
import NextLevel.demo.user.entity.UserEntity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@NoArgsConstructor
@Getter
@Setter
public class UserSocialProfileDto {

private String name;
private String nickName;
private Long followCount;
private ImgDto img;

public static UserSocialProfileDto of(UserEntity user, Long followCount) {
UserSocialProfileDto dto = new UserSocialProfileDto();
dto.followCount = followCount;
dto.name = user.getName();
dto.nickName = user.getNickName();
dto.img = new ImgDto(user.getImg());
return dto;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

public interface UserRepository extends JpaRepository<UserEntity, Long> {

@Query("select u from UserEntity u left join fetch u.userDetail where u.id = :userId")
@Query("select u from UserEntity u left join fetch u.userDetail left join fetch u.img where u.id = :userId")
Optional<UserEntity> findUserFullInfoByUserId(@Param("userId")Long userId);

@Query("select u from UserEntity u where u.nickName = :nickName")
Expand Down
Loading