PhucLe
Le Phuc 5 months ago
parent d7485f796f
commit 7db94512a7
  1. 39
      BE/src/main/java/org/example/controllers/InteractionController.java
  2. 22
      BE/src/main/java/org/example/controllers/PostController.java
  3. 43
      BE/src/main/java/org/example/models/Category.java
  4. 53
      BE/src/main/java/org/example/models/Post.java
  5. 18
      BE/src/main/java/org/example/models/User.java
  6. 31
      BE/src/main/java/org/example/objects/CommentDTO.java
  7. 22
      BE/src/main/java/org/example/objects/InteractionsDTO.java
  8. 2
      BE/src/main/java/org/example/queryresults/CourseEnrolmentQueryResult.java
  9. 61
      BE/src/main/java/org/example/realtionship/CommentRelationship.java
  10. 51
      BE/src/main/java/org/example/realtionship/ShareRelationship.java
  11. 16
      BE/src/main/java/org/example/repositories/CategoryRepository.java
  12. 36
      BE/src/main/java/org/example/repositories/PostRepository.java
  13. 17
      BE/src/main/java/org/example/repositories/UserRepository.java
  14. 43
      BE/src/main/java/org/example/services/InteractService.java
  15. 24
      BE/src/main/java/org/example/services/PostService.java
  16. 39
      BE/src/main/java/org/example/services/RecommendationService.java
  17. 3
      BE/src/main/resources/application.properties

@ -0,0 +1,39 @@
package org.example.controllers;
import org.example.objects.CommentDTO;
import org.example.objects.InteractionsDTO;
import org.example.services.InteractService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/interactions")
public class InteractionController {
private final InteractService interactionService;
@Autowired
public InteractionController(InteractService interactionService) {
this.interactionService = interactionService;
}
@PostMapping("/like")
public ResponseEntity<Void> likePost(@RequestBody InteractionsDTO interactionsDTO) {
interactionService.toggleLike(interactionsDTO.getUsername(), interactionsDTO.getPostId());
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/comment")
public ResponseEntity<Void> commentPost(@RequestBody CommentDTO interactionsDTO) {
interactionService.commentPost(interactionsDTO.getUsername(), interactionsDTO.getPostId(), interactionsDTO.getContent());
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/share")
public ResponseEntity<Void> sharePost(@RequestBody InteractionsDTO interactionsDTO) {
interactionService.sharePost(interactionsDTO.getUsername(), interactionsDTO.getPostId());
return new ResponseEntity<>(HttpStatus.OK);
}
}

@ -8,6 +8,7 @@ import org.example.models.User;
import org.example.objects.PostDTO; import org.example.objects.PostDTO;
import org.example.repositories.PostRepository; import org.example.repositories.PostRepository;
import org.example.services.PostService; import org.example.services.PostService;
import org.example.services.RecommendationService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -23,11 +24,13 @@ public class PostController {
private final PostService postService; private final PostService postService;
private final PostRepository postRepository; private final PostRepository postRepository;
private final RecommendationService recommendationService;
@Autowired @Autowired
public PostController(PostService postService, PostRepository postRepository) { public PostController(PostService postService, PostRepository postRepository, RecommendationService recommendationService) {
this.postService = postService; this.postService = postService;
this.postRepository = postRepository; this.postRepository = postRepository;
this.recommendationService = recommendationService;
} }
@GetMapping("/getAllPosts") @GetMapping("/getAllPosts")
@ -44,18 +47,6 @@ public class PostController {
public Post updatePost(@PathVariable Long id,@RequestBody PostDTO postDTO) throws IOException { public Post updatePost(@PathVariable Long id,@RequestBody PostDTO postDTO) throws IOException {
return postService.editPost(id, postDTO.getTitle(), postDTO.getContent(), postDTO.getImageFile(), postDTO.getVideoFile()); return postService.editPost(id, postDTO.getTitle(), postDTO.getContent(), postDTO.getImageFile(), postDTO.getVideoFile());
} }
@PostMapping("/like")
public ResponseEntity<String> handleLikeAction(@RequestBody LikeRequest request){
try{
System.out.println(request.getUsername()+" "+request.getPostId());
postService.toggleLike(request.getUsername(),request.getPostId());
return ResponseEntity.ok("Success");
}
catch(Exception e){
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error:"+e.getMessage());
}
}
@PostMapping @PostMapping
public Post createPost( public Post createPost(
@ -67,4 +58,9 @@ public class PostController {
return postService.createPost(title, content, imageFile, videoFile); return postService.createPost(title, content, imageFile, videoFile);
} }
@GetMapping("/recommend/{username}")
public List<Post> getRecommendationPostByUsername(@PathVariable String username){
List<Post> recommend= recommendationService.getRecommendationPosts(username);
return recommend;
}
} }

@ -0,0 +1,43 @@
package org.example.models;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Relationship;
import java.util.List;
@Node
public class Category {
@Id
@GeneratedValue
private Long id;
private String name;
@Relationship(type = "HAS_POST")
private List<Post> posts;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Post> getPosts() {
return posts;
}
public void setPosts(List<Post> posts) {
this.posts = posts;
}
}

@ -2,6 +2,8 @@ package org.example.models;
import lombok.Getter; import lombok.Getter;
import org.example.realtionship.CommentRelationship;
import org.example.realtionship.ShareRelationship;
import org.example.repositories.PostRepository; import org.example.repositories.PostRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.core.schema.GeneratedValue; import org.springframework.data.neo4j.core.schema.GeneratedValue;
@ -24,6 +26,57 @@ public class Post {
private String content; private String content;
private String author; private String author;
private String imgUrl; private String imgUrl;
private int interactions;
@Relationship(type = "HAS_LIKE", direction = Relationship.Direction.INCOMING)
private List<User> likedByUsers;
@Relationship(type = "HAS_COMMENT", direction = Relationship.Direction.INCOMING)
private List<CommentRelationship> comments;
@Relationship(type = "HAS_SHARE", direction = Relationship.Direction.INCOMING)
private List<ShareRelationship> sharedByUsers;
@Relationship(type = "HAS_POST", direction = Relationship.Direction.INCOMING)
private Category category;
public List<User> getLikedByUsers() {
return likedByUsers;
}
public void setLikedByUsers(List<User> likedByUsers) {
this.likedByUsers = likedByUsers;
}
public void setComments(List<CommentRelationship> comments) {
this.comments = comments;
}
public List<ShareRelationship> getSharedByUsers() {
return sharedByUsers;
}
public void setSharedByUsers(List<ShareRelationship> sharedByUsers) {
this.sharedByUsers = sharedByUsers;
}
public int getInteractions() {
return interactions;
}
public void setInteractions(int interactions) {
this.interactions = interactions;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public String getImgUrl() { public String getImgUrl() {
return imgUrl; return imgUrl;

@ -3,12 +3,14 @@ package org.example.models;
import org.springframework.data.neo4j.core.schema.GeneratedValue; import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id; import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node; import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Relationship;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List;
@Node @Node
public class User implements UserDetails { public class User implements UserDetails {
@ -20,6 +22,22 @@ public class User implements UserDetails {
private String password; private String password;
private String roles; private String roles;
@Relationship(type = "FRIEND")
private List<User> friends;
public void setId(Long id) {
this.id = id;
}
public List<User> getFriends() {
return friends;
}
public void setFriends(List<User> friends) {
this.friends = friends;
}
public User() { public User() {
} }

@ -0,0 +1,31 @@
package org.example.objects;
public class CommentDTO {
private String username;
private Long postId;
private String content;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Long getPostId() {
return postId;
}
public void setPostId(Long postId) {
this.postId = postId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}

@ -0,0 +1,22 @@
package org.example.objects;
public class InteractionsDTO {
private String username;
private Long postId;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Long getPostId() {
return postId;
}
public void setPostId(Long postId) {
this.postId = postId;
}
}

@ -3,7 +3,7 @@ package org.example.queryresults;
import org.example.models.User; import org.example.models.User;
public class CourseEnrolmentQueryResult { public class CourseEnrolmentQueryResult {
private User user; private User user;
public CourseEnrolmentQueryResult() { public CourseEnrolmentQueryResult() {

@ -0,0 +1,61 @@
package org.example.realtionship;
import org.example.models.User;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.RelationshipProperties;
import org.springframework.data.neo4j.core.schema.TargetNode;
import org.springframework.web.bind.annotation.GetMapping;
import java.time.LocalDateTime;
@RelationshipProperties
public class CommentRelationship {
@Id
@GeneratedValue
private Long id;
private String content;
private LocalDateTime timestamp;
@TargetNode private User user;
public CommentRelationship(String content, LocalDateTime timestamp, User user) {
this.content = content;
this.timestamp = timestamp;
this.user = user;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public LocalDateTime getTimestamp() {
return timestamp;
}
public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
// Getters and Setters
}

@ -0,0 +1,51 @@
package org.example.realtionship;
import org.example.models.User;
import org.springframework.data.annotation.Id;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.RelationshipProperties;
import org.springframework.data.neo4j.core.schema.TargetNode;
import java.time.LocalDateTime;
@RelationshipProperties
public class ShareRelationship {
@Id
@GeneratedValue
private Long id;
private LocalDateTime timestamp;
@TargetNode
private User user;
public ShareRelationship(LocalDateTime timestamp, User user) {
this.timestamp = timestamp;
this.user = user;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public LocalDateTime getTimestamp() {
return timestamp;
}
public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
// Getters and Setters
}

@ -0,0 +1,16 @@
package org.example.repositories;
import org.example.models.Category;
import org.example.models.Post;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CategoryRepository extends Neo4jRepository<Category, Long> {
@Query("MATCH (c:Category)-[:HAS_POST]->(p:Post) WHERE c.name IN $categoryNames RETURN p")
List<Post> findPostsByCategoryNames(@Param("categoryNames") List<String> categoryNames);
}

@ -48,11 +48,39 @@ public interface PostRepository extends Neo4jRepository<Post,Long> {
")\n" + ")\n" +
"RETURN p") "RETURN p")
Post updatePost(@Param("postId") Long postId, @Param("title") String title, @Param("content") String content, @Param("imageFile")MultipartFile imageFile, @Param("videoFile") MultipartFile videoFile); Post updatePost(@Param("postId") Long postId, @Param("title") String title, @Param("content") String content, @Param("imageFile")MultipartFile imageFile, @Param("videoFile") MultipartFile videoFile);
@Query("MATCH (u:User {username: $username}), (p:Post) WHERE ID(p)=$postId CREATE (u)-[:LIKES]->(p)")
void createLike(@Param("username") String username,@Param("postId") Long postId);
@Query("MATCH (u:User {username: $username})-[r:LIKES]->(p:Post ) WHERE ID(p)=$postId DELETE r") @Query("MATCH (u:User), (p:Post) WHERE u.username = $username AND ID(p) = $postId " +
void deleteLike(@Param("username") String username, @Param("postId") Long postId); "MERGE (u)-[:LIKED {timestamp: datetime()}]->(p) " +
"RETURN p")
Post likePost(@Param("username") String username, @Param("postId") Long postId);
@Query("MATCH (u:User)-[l:LIKES]->(p:Post) " +
"WHERE u.username=$username AND ID(p) = $postId " +
"DELETE l " +
"RETURN CASE WHEN COUNT(l) > 0 THEN true ELSE false END AS removed")
boolean toggleLike(@Param("username") String username, @Param("postId") Long postId);
@Query("MATCH (u:User), (p:Post) WHERE u.username=$username AND ID(p) = $postId " +
"MERGE (u)-[:COMMENTED {content: $content, timestamp: datetime()}]->(p) " +
"RETURN p")
Post commentPost(@Param("username") String username, @Param("postId") Long postId, @Param("content") String content);
@Query("MATCH (u:User), (p:Post) WHERE u.username=$username AND ID(p) = $postId " +
"MERGE (u)-[:SHARED {timestamp: datetime()}]->(p) " +
"RETURN p")
Post sharePost(@Param("username") String username, @Param("postId") Long postId);
@Query("MATCH (p:Post)\n" +
"OPTIONAL MATCH (p)-[:HAS_LIKE]->(l)\n" +
"OPTIONAL MATCH (p)-[:HAS_COMMENT]->(c)\n" +
"OPTIONAL MATCH (p)-[:HAS_SHARE]->(s)\n" +
"OPTIONAL MATCH (p)-[:HAS_IMAGE]->(image:Image)\n" +
"OPTIONAL MATCH (p)-[:HAS_VIDEO]->(video:Video)\n" +
"WITH p, COUNT(l) AS likeCount, COUNT(c) AS commentCount, COUNT(s) AS shareCount, COLLECT(DISTINCT image) AS images, COLLECT(DISTINCT video) AS videos\n" +
"RETURN p, images, videos\n" +
"ORDER BY (likeCount + commentCount + shareCount) DESC\n" +
"LIMIT 10")
List<Post> findTop10ByInteractions();
@Query("MATCH (user:User {username: $username}),(post:Post )"+"where ID(post)=$postId"+ " CREATE (user)-[:createPost ]->(post)"+ @Query("MATCH (user:User {username: $username}),(post:Post )"+"where ID(post)=$postId"+ " CREATE (user)-[:createPost ]->(post)"+
"RETURN user, post") "RETURN user, post")

@ -1,25 +1,28 @@
package org.example.repositories; package org.example.repositories;
import org.example.models.Category;
import org.example.models.Post;
import org.example.models.User; import org.example.models.User;
import org.example.queryresults.PostQueryResult; import org.example.queryresults.PostQueryResult;
import org.springframework.data.neo4j.repository.Neo4jRepository; import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query; import org.springframework.data.neo4j.repository.query.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional; import java.util.Optional;
@Repository
public interface UserRepository extends Neo4jRepository<User, Long> { public interface UserRepository extends Neo4jRepository<User, Long> {
Optional<User> findUserByUsername(String username); Optional<User> findUserByUsername(String username);
User findUserBy(String username);
boolean existsByUsername(String username); boolean existsByUsername(String username);
@Query("MATCH (user:User), (course:Course) WHERE user.username = $username AND course.identifier = $identifier " + @Query("MATCH (u:User)-[:FRIEND]->(f:User)-[:LIKED|COMMENTED|SHARED]->(p:Post) WHERE u.username=$username RETURN p")
"RETURN EXISTS((user)-[:ENROLLED_IN]->(course))") List<Post> findFriendPosts(@Param("username") String username);
Boolean findEnrolmentStatus(String username, String identifier);
// @Query("MATCH (user:User), (course:Course) WHERE user.username = $username AND course.identifier = $identifier " + @Query("MATCH (u:User)-[:LIKED|COMMENTED|SHARED]->(p:Post)-[:HAS_POST]->(c:Category) WHERE u.username=$username RETURN DISTINCT c")
// "CREATE (user)-[:ENROLLED_IN]->(course) RETURN user, course") List<Category> findInteractedCategories(@Param("username") String username);
// CourseEnrolmentQueryResult createEnrolmentRelationship(String username, String identifier);
} }

@ -0,0 +1,43 @@
package org.example.services;
import org.example.models.*;
import org.example.realtionship.CommentRelationship;
import org.example.realtionship.ShareRelationship;
import org.example.repositories.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
@Service
public class InteractService {
private final PostRepository postRepository;
private final UserRepository userRepository;
@Autowired
public InteractService(PostRepository postRepository, UserRepository userRepository) {
this.postRepository = postRepository;
this.userRepository = userRepository;
}
@Transactional
public void toggleLike(String username , Long postId) {
boolean removed = postRepository.toggleLike(username, postId);
if (!removed) {
postRepository.likePost(username, postId);
System.out.println("Liked");
}
}
@Transactional
public void commentPost(String username, Long postId, String content) {
postRepository.commentPost(username, postId, content);
}
@Transactional
public void sharePost(String username, Long postId) {
postRepository.sharePost(username, postId);
}
}

@ -3,10 +3,7 @@ package org.example.services;
//import org.example.models.Author; //import org.example.models.Author;
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
import org.example.controllers.UserController; import org.example.controllers.UserController;
import org.example.models.Image; import org.example.models.*;
import org.example.models.Post;
import org.example.models.User;
import org.example.models.Video;
import org.example.queryresults.PostQueryResult; import org.example.queryresults.PostQueryResult;
import org.example.repositories.PostRepository; import org.example.repositories.PostRepository;
import org.example.repositories.UserRepository; import org.example.repositories.UserRepository;
@ -23,6 +20,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.security.Principal; import java.security.Principal;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -64,27 +62,13 @@ public class PostService {
return getAllPost; return getAllPost;
} }
@Transactional @Transactional
public void toggleLike(String username,Long postId){
System.out.println("Service:"+username+postId);
boolean alreadyLiked = neo4jTemplate.count("MATCH (u:User {username: $username})-[r:LIKES]->(p:Post) WHERE ID(p)=$postId RETURN count(r) ",
Map.of("username", username, "postId", postId)) > 0;
if (alreadyLiked) {
postRepository.deleteLike(username,postId);
} else {
System.out.println("Like de");
postRepository.createLike(username,postId);
}
}
@Transactional
public Post createPost(String title, String content, MultipartFile imageFile, MultipartFile videoFile) throws IOException { public Post createPost(String title, String content, MultipartFile imageFile, MultipartFile videoFile) throws IOException {
Post post = new Post(); Post post = new Post();
post.setTitle(title); post.setTitle(title);
post.setContent(content); post.setContent(content);
if (imageFile != null) { if (imageFile != null) {
Image image = saveImageFile(imageFile, "C:\\Users\\P R O B O O K\\Documents\\Phuc\\Facebook\\FE/FE/public/picture"); Image image = saveImageFile(imageFile, "C:\\Users\\phucl\\OneDrive\\Desktop\\JAVA_INTER\\Facebook\\FE\\FE\\public\\picture");
// post.getImages().add(image); // post.getImages().add(image);
post.setImages(image); post.setImages(image);
} }
@ -116,7 +100,7 @@ public class PostService {
Post post= postRepository.updatePost(postId,title,content,imageFile,videoFile); Post post= postRepository.updatePost(postId,title,content,imageFile,videoFile);
// Update the image file if provided // Update the image file if provided
if (imageFile != null) { if (imageFile != null) {
Image newImage = saveImageFile(imageFile, "C:\\Users\\P R O B O O K\\Documents\\Phuc\\Facebook\\FE/FE/public/picture"); Image newImage = saveImageFile(imageFile, "C:\\Users\\phucl\\OneDrive\\Desktop\\JAVA_INTER\\Facebook\\FE\\FE\\public\\picture");
post.setImages(newImage); post.setImages(newImage);
} }

@ -0,0 +1,39 @@
package org.example.services;
import org.example.models.Category;
import org.example.models.Post;
import org.example.repositories.CategoryRepository;
import org.example.repositories.PostRepository;
import org.example.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class RecommendationService {
private final PostRepository postRepository;
private final UserRepository userRepository;
private final CategoryRepository categoryRepository;
@Autowired
public RecommendationService(PostRepository postRepository, UserRepository userRepository, CategoryRepository categoryRepository) {
this.postRepository = postRepository;
this.userRepository = userRepository;
this.categoryRepository = categoryRepository;
}
public List<Post> getRecommendationPosts(String username) {
List<Post> recommendationPosts = new ArrayList<>();
recommendationPosts.addAll(postRepository.findTop10ByInteractions());
List<Category> categories = userRepository.findInteractedCategories(username);
List<String> categoriesNames = categories.stream().map(Category::getName).collect(Collectors.toList());
recommendationPosts.addAll(categoryRepository.findPostsByCategoryNames(categoriesNames));
recommendationPosts.addAll(userRepository.findFriendPosts(username));
return recommendationPosts.stream().distinct().collect(Collectors.toList());
}
}

@ -1,4 +1,3 @@
spring.neo4j.uri=neo4j://localhost:7687 spring.neo4j.uri=neo4j://localhost:7687
spring.neo4j.authentication.username=neo4j spring.neo4j.authentication.username=neo4j
spring.neo4j.authentication.password=12345678 spring.neo4j.authentication.password=12345678
file_upload = C:/Users/P R O B O O K/Documents/Facebook/BE/images
Loading…
Cancel
Save