Skip to content

Commit

Permalink
Merge pull request #16 from olmangjolmang/OMJM-76-post_scrap
Browse files Browse the repository at this point in the history
게시글 스크랩/스크랩 취소 기능 구현
  • Loading branch information
chaeyeonKong authored Jul 6, 2024
2 parents 5166f39 + 735778f commit 81661ba
Show file tree
Hide file tree
Showing 14 changed files with 171 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ public class SecurityConfig {
private final JwtTokenProvider jwtTokenProvider;

@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity)throws Exception {
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.httpBasic(HttpBasicConfigurer::disable)
.csrf(CsrfConfigurer::disable)
.cors(Customizer.withDefaults())
.sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(authorize ->
authorize.requestMatchers("/users/sign-in", "/users/sign-up", "/swagger-ui/**", "/v3/api-docs/**", "/global/health-check","/users/**","/post/**","/mypage/**").permitAll()
authorize.requestMatchers("/users/sign-in", "/users/sign-up", "/swagger-ui/**", "/v3/api-docs/**", "/global/health-check", "/users/**", "/post/**", "/mypage/**").permitAll()

.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.requestMatchers("/users/**").hasRole("USER")
Expand All @@ -41,7 +41,7 @@ public SecurityFilterChain filterChain(HttpSecurity httpSecurity)throws Exceptio
}

@Bean
public PasswordEncoder passwordEncoder(){
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
12 changes: 6 additions & 6 deletions src/main/java/com/ticle/server/memo/domain/Memo.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.sql.Timestamp;
import java.time.LocalDateTime;

@Table(name="Memo")
@Table(name = "Memo")
@Entity
@Data
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand All @@ -19,23 +19,23 @@ public class Memo {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="memo_id")
@Column(name = "memo_id")
private Long memoId;

@Column(name="content")
@Column(name = "content")
private String content;

@CreatedDate
@Column(name="memo_date",nullable = false)
@Column(name = "memo_date", nullable = false)
private LocalDateTime memoDate;


@ManyToOne
@JoinColumn(name="user_id")
@JoinColumn(name = "user_id")
private User user;

@ManyToOne
@JoinColumn(name="post_id")
@JoinColumn(name = "post_id")
private Post post;

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.ticle.server.post.domain.Post;
import com.ticle.server.post.dto.PostResponse;
import com.ticle.server.post.service.PostService;
import com.ticle.server.scrapped.domain.Scrapped;
import com.ticle.server.scrapped.dto.ScrappedDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
Expand All @@ -23,10 +25,11 @@ public class PostApiController {
private final PostService postService;

//카테고리로 아티클 조회
@Operation(summary = "아티클 조회", description = "카테고리로 아티클 조회")
@Operation(summary = "아티클 조회", description = "카테고리로 아티클 조회 \n 공백 입력시 모든 아티클")
@GetMapping
public ResponseEntity<ResponseTemplate<Object>> findAllArticles(@RequestParam(required = false) String category) {


System.out.println("come");
List<PostResponse> posts = postService.findAllByCategory(category)
.stream()
.map(PostResponse::from)
Expand All @@ -48,4 +51,22 @@ public ResponseEntity<ResponseTemplate<Object>> findArticle(@PathVariable long i
.body(ResponseTemplate.from(post));
}

@Operation(summary = "스크랩 기능", description = "새로운 아티클 스크랩 및 스크랩 취소")
@PostMapping("/{id}/scrap")
public ResponseEntity<ResponseTemplate<Object>> scrappedArticle(@PathVariable long id) {

Object scrapped = postService.scrappedById(id);

if (scrapped instanceof ScrappedDto) { // 이미 스크랩 했던 경우(취소기능)
return ResponseEntity
.status(HttpStatus.OK)
.body(ResponseTemplate.from(scrapped));

} else { //새로 스크랩 하는 경우(스크랩 추가)
return ResponseEntity
.status(HttpStatus.OK)
.body(ResponseTemplate.from(ScrappedDto.from((Scrapped) scrapped)));
}

}
}
2 changes: 1 addition & 1 deletion src/main/java/com/ticle/server/post/domain/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class Post extends BaseTimeEntity {
@JoinColumn(name = "user_id")
private User user;

@OneToMany(mappedBy = "post",cascade = CascadeType.ALL,orphanRemoval = true)
@OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Scrapped> scrappeds;

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.ticle.server.post.repository;

import com.ticle.server.user.domain.type.Category;
import com.ticle.server.post.domain.Post;
import com.ticle.server.talk.domain.Talk;

import com.ticle.server.user.domain.type.Category;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
Expand All @@ -12,6 +10,5 @@
public interface PostRepository extends JpaRepository<Post, Long> {
Post findByPostId(Long postId);
List<Post> findByCategory(Category category);
// List<Post> findByUserId(Long userId);

}
48 changes: 47 additions & 1 deletion src/main/java/com/ticle/server/post/service/PostService.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
package com.ticle.server.post.service;

import com.ticle.server.scrapped.dto.ScrappedDto;
import com.ticle.server.user.domain.type.Category;
import com.ticle.server.post.domain.Post;
import com.ticle.server.post.repository.PostRepository;
import com.ticle.server.scrapped.domain.Scrapped;
import com.ticle.server.scrapped.repository.ScrappedRepository;
import com.ticle.server.user.domain.User;
import com.ticle.server.user.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.List;

@RequiredArgsConstructor
@Service
public class PostService {

private final PostRepository postRepository;

private final ScrappedRepository scrappedRepository;
private final UserService userService;

// 카테고리에 맞는 글 찾기
public List<Post> findAllByCategory(String category) {
Expand All @@ -30,4 +40,40 @@ public List<Post> findAllByCategory(String category) {
public Post findById(long id) {
return postRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("not found: " + id));
}


public Object scrappedById(long id) {
// 게시물 조회
Post post = postRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("해당 id의 post 찾을 수 없음 id: " + id));

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.getPrincipal() instanceof UserDetails) {
} else {
throw new IllegalStateException("principal 없음");
}

UserDetails userDetails = (UserDetails) authentication.getPrincipal();

// getUsername에는 email이 들어있음. / email로 유저 찾고 id 찾도록 함.
User user = userService.getLoginUserByEmail(userDetails.getUsername());
Long userId = user.getId();
// System.out.println("User ID: " + userId);

// 이미 스크랩했는지 확인
Optional<Scrapped> existingScrap = scrappedRepository.findByUserIdAndPost_PostId(userId, post.getPostId());
if (existingScrap.isPresent()) {
// 이미 스크랩한 상태라면 스크랩 취소
existingScrap.get().changeToUnscrapped(); //status를 unscrapped로 변경
scrappedRepository.delete(existingScrap.get());
return ScrappedDto.from(existingScrap.get());
}

Scrapped scrapped = new Scrapped();
scrapped.setPost(post);
scrapped.setUser(user);
scrapped.changeToScrapped(); //status를 scrapped로 변경

return scrappedRepository.save(scrapped);
}
}

This file was deleted.

20 changes: 15 additions & 5 deletions src/main/java/com/ticle/server/scrapped/domain/Scrapped.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
@Entity
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor()
@AllArgsConstructor
@Builder
public class Scrapped {
Expand All @@ -19,11 +19,21 @@ public class Scrapped {
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id",nullable = false)
@JoinColumn(name = "user_id", nullable = false)
private User user;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id",nullable = false)
private Post post;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id", nullable = false)
private Post post;

@Column(name = "status")
private String status;

public void changeToScrapped() {
this.status = "SCRAPPED";
}

public void changeToUnscrapped() {
this.status = "UNSCRAPPED";
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/ticle/server/scrapped/dto/ScrappedDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.ticle.server.scrapped.dto;

import com.ticle.server.scrapped.domain.Scrapped;
import lombok.*;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ScrappedDto {

private Long userId;
private Long postId;
private String postName;
private String status;

public static ScrappedDto from(Scrapped scrapped) {
return ScrappedDto.builder()
.userId(scrapped.getUser().getId())
.postId(scrapped.getPost().getPostId())
.postName(scrapped.getPost().getTitle())
.status(scrapped.getStatus())
.build();
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
package com.ticle.server.scrapped.repository;

public class ScrappedRepository {
import com.ticle.server.scrapped.domain.Scrapped;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;


public interface ScrappedRepository extends JpaRepository<Scrapped, Long> {
Optional<Scrapped> findByUserIdAndPost_PostId(Long userId, Long postId);

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ public class UserController {

@Operation(summary = "로그인", description = "로그인하기")
@PostMapping("/sign-in")
public ResponseEntity<ResponseTemplate<Object>> signIn(@RequestBody LoginRequest loginRequest){
public ResponseEntity<ResponseTemplate<Object>> signIn(@RequestBody LoginRequest loginRequest) {
String email = loginRequest.email();
String password = loginRequest.password();
log.info("request username = {}, password = {}", email, password);
JwtToken jwtToken = userService.signIn(email,password);
JwtToken jwtToken = userService.signIn(email, password);
log.info("jwtToken accessToken = {}, refreshToken = {}", jwtToken.getAccessToken(), jwtToken.getRefreshToken());
return ResponseEntity
.status(HttpStatus.OK)
Expand All @@ -43,7 +43,7 @@ public ResponseEntity<ResponseTemplate<Object>> signIn(@RequestBody LoginRequest

@Operation(summary = "회원가입", description = "회원가입하기")
@PostMapping("sign-up")
public ResponseEntity<ResponseTemplate<Object>> signUp(@RequestBody JoinRequest joinRequest){
public ResponseEntity<ResponseTemplate<Object>> signUp(@RequestBody JoinRequest joinRequest) {
UserDto savedUserDto = userService.signUp(joinRequest);
return ResponseEntity
.status(HttpStatus.OK)
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/com/ticle/server/user/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@
@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor()
@AllArgsConstructor
public class User {
// 애플리케이션의 핵심 비즈니스 로직을 담고 있는 개체
// 주로 데이터베이스와 직접적으로 연관되어 있음
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="user_id")
@Column(name = "user_id")
private Long id;

@Column(name="email",nullable = false)
@Column(name = "email", nullable = false)
private String email;

@Column(name = "password",nullable = false)
@Column(name = "password", nullable = false)
private String password;


Expand All @@ -57,11 +57,11 @@ public class User {
@OneToMany(mappedBy = "user",cascade = CascadeType.ALL,orphanRemoval = true)
private List<Scrapped> scrappeds;

@ElementCollection(fetch=FetchType.EAGER)
@ElementCollection(fetch = FetchType.EAGER)
@Builder.Default
private List<String> roles = new ArrayList<>();

public Collection<? extends GrantedAuthority> getAuthorities(){
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.roles.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
Expand Down
Loading

0 comments on commit 81661ba

Please sign in to comment.