Compare commits

..

2 Commits

Author SHA1 Message Date
Thanhzxcn 989f94de81 Update Like, ApiResponse 5 months ago
Thanhzxcn 3cbc6d31f8 Update Like, update ApiResponse 5 months ago
  1. 13
      BE/pom.xml
  2. 25
      BE/src/main/java/org/example/controllers/CategoryController.java
  3. 39
      BE/src/main/java/org/example/controllers/InteractionController.java
  4. 37
      BE/src/main/java/org/example/controllers/PostController.java
  5. 29
      BE/src/main/java/org/example/controllers/SearchController.java
  6. 14
      BE/src/main/java/org/example/controllers/UserController.java
  7. 34
      BE/src/main/java/org/example/models/Category.java
  8. 26
      BE/src/main/java/org/example/models/Like.java
  9. 22
      BE/src/main/java/org/example/models/Post.java
  10. 18
      BE/src/main/java/org/example/models/User.java
  11. 18
      BE/src/main/java/org/example/objects/ApiResponse.java
  12. 31
      BE/src/main/java/org/example/objects/CommentDTO.java
  13. 21
      BE/src/main/java/org/example/objects/FriendDTO.java
  14. 22
      BE/src/main/java/org/example/objects/InteractionsDTO.java
  15. 14
      BE/src/main/java/org/example/objects/PostDTO.java
  16. 39
      BE/src/main/java/org/example/objects/PostWithMedia.java
  17. 36
      BE/src/main/java/org/example/objects/SearchResultDTO.java
  18. 61
      BE/src/main/java/org/example/realtionship/CommentRelationship.java
  19. 51
      BE/src/main/java/org/example/realtionship/ShareRelationship.java
  20. 26
      BE/src/main/java/org/example/repositories/CategoryRepository.java
  21. 50
      BE/src/main/java/org/example/repositories/PostRepository.java
  22. 23
      BE/src/main/java/org/example/repositories/SearchRepository.java
  23. 55
      BE/src/main/java/org/example/repositories/UserRepository.java
  24. 15
      BE/src/main/java/org/example/requests/CreateLikeRequest.java
  25. 23
      BE/src/main/java/org/example/services/CategoryService.java
  26. 45
      BE/src/main/java/org/example/services/InteractService.java
  27. 31
      BE/src/main/java/org/example/services/PostService.java
  28. 67
      BE/src/main/java/org/example/services/RecommendationService.java
  29. 40
      BE/src/main/java/org/example/services/SearchService.java
  30. 19
      BE/src/main/java/org/example/services/UserService.java
  31. 1
      BE/src/main/resources/application.properties

@ -40,7 +40,18 @@
<groupId>org.neo4j.driver</groupId> <groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId> <artifactId>neo4j-java-driver</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
<version>4.0.10</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-bolt-driver</artifactId>
<version>4.0.10</version>
<scope>runtime</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId> <artifactId>spring-boot-devtools</artifactId>

@ -1,25 +0,0 @@
package org.example.controllers;
import org.example.models.Category;
import org.example.services.CategoryService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/category")
public class CategoryController {
private final CategoryService categoryService;
public CategoryController(CategoryService categoryService) {
this.categoryService = categoryService;
}
@GetMapping("/getAllCategories")
public List<Category> getAllCategories(){
return categoryService.getAllCategories();
}
}

@ -1,39 +0,0 @@
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);
}
}

@ -1,15 +1,14 @@
package org.example.controllers; package org.example.controllers;
//import org.example.models.Author; //import org.example.models.Author;
import org.example.models.*; import org.example.models.Image;
import org.example.models.LikeRequest;
import org.example.models.Post;
import org.example.models.User;
import org.example.objects.PostDTO; import org.example.objects.PostDTO;
import org.example.objects.PostWithMedia;
import org.example.repositories.CategoryRepository;
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.data.repository.query.Param;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -24,15 +23,11 @@ public class PostController {
private final PostService postService; private final PostService postService;
private final PostRepository postRepository; private final PostRepository postRepository;
private final RecommendationService recommendationService;
private final CategoryRepository categoryRepository;
@Autowired @Autowired
public PostController(PostService postService, PostRepository postRepository, RecommendationService recommendationService, CategoryRepository categoryRepository) { public PostController(PostService postService, PostRepository postRepository) {
this.postService = postService; this.postService = postService;
this.postRepository = postRepository; this.postRepository = postRepository;
this.recommendationService = recommendationService;
this.categoryRepository = categoryRepository;
} }
@GetMapping("/getAllPosts") @GetMapping("/getAllPosts")
@ -47,23 +42,29 @@ public class PostController {
@PostMapping("/edit/{id}") @PostMapping("/edit/{id}")
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.getCategory(), 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(
@RequestParam("title") String title, @RequestParam("title") String title,
@RequestParam("content") String content, @RequestParam("content") String content,
@RequestParam("category") Category category,
@RequestParam(value = "imageFile", required = false) MultipartFile imageFile, @RequestParam(value = "imageFile", required = false) MultipartFile imageFile,
@RequestParam(value = "videoFile", required = false) MultipartFile videoFile) throws IOException { @RequestParam(value = "videoFile", required = false) MultipartFile videoFile) throws IOException {
return postService.createPost(title, content,category, 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;
}
} }

@ -1,29 +0,0 @@
package org.example.controllers;
import ch.qos.logback.core.joran.sanity.Pair;
import org.example.models.Post;
import org.example.models.User;
import org.example.objects.SearchResultDTO;
import org.example.services.SearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/search")
public class SearchController {
@Autowired
private final SearchService searchService;
public SearchController(SearchService searchService) {
this.searchService = searchService;
}
@GetMapping("/get")
public List<Post> search(@RequestParam("condition") String condition) {
System.out.println(condition);
return searchService.searchResult(condition);
}
}

@ -1,9 +1,10 @@
package org.example.controllers; package org.example.controllers;
import org.example.models.User; import org.example.models.User;
import org.example.objects.FriendDTO; import org.example.objects.ApiResponse;
import org.example.objects.UserDTO; import org.example.objects.UserDTO;
import org.example.repositories.UserRepository; import org.example.repositories.UserRepository;
import org.example.requests.CreateLikeRequest;
import org.example.requests.CreateUserRequest; import org.example.requests.CreateUserRequest;
import org.example.services.UserService; import org.example.services.UserService;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
@ -37,10 +38,11 @@ public class UserController {
return new ResponseEntity<>(responseUser, HttpStatus.CREATED); return new ResponseEntity<>(responseUser, HttpStatus.CREATED);
} }
@PostMapping("/addFriend")
public ResponseEntity<String> addFriend(@RequestBody FriendDTO friendDTO){ @PostMapping("/createLike")
userService.addFriend(friendDTO.getUsername1(),friendDTO.getUsername2()); public ApiResponse<CreateLikeRequest> createLike(@RequestBody CreateLikeRequest request) {
System.out.println(friendDTO.getUsername1()); ApiResponse<CreateLikeRequest> response = new ApiResponse<>();
return new ResponseEntity<>("Friend added", HttpStatus.CREATED); response.setResult(userService.createLike(request));
return response;
} }
} }

@ -1,34 +0,0 @@
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;
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;
}
}

@ -0,0 +1,26 @@
package org.example.models;
import lombok.*;
import lombok.experimental.FieldDefaults;
import org.neo4j.ogm.annotation.EndNode;
import org.neo4j.ogm.annotation.RelationshipEntity;
import org.neo4j.ogm.annotation.StartNode;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@RelationshipEntity(type = "LIKE")
public class Like {
Long userId;
Long postId;
String status;
@StartNode
private User user;
@EndNode
private Post post;
}

@ -2,8 +2,6 @@ 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;
@ -26,26 +24,6 @@ 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_CATEGORY", direction = Relationship.Direction.OUTGOING)
private Category category;
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public int getInteractions() {
return interactions;
}
public void setInteractions(int interactions) {
this.interactions = interactions;
}
public String getImgUrl() { public String getImgUrl() {
return imgUrl; return imgUrl;

@ -3,14 +3,12 @@ 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 {
@ -22,22 +20,6 @@ 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,18 @@
package org.example.objects;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.*;
import lombok.experimental.FieldDefaults;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiResponse<T>{
int code = 1000;
String message;
T result;
}

@ -1,31 +0,0 @@
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;
}
}

@ -1,21 +0,0 @@
package org.example.objects;
public class FriendDTO {
private String username1,username2;
public String getUsername1() {
return username1;
}
public void setUsername1(String username1) {
this.username1 = username1;
}
public String getUsername2() {
return username2;
}
public void setUsername2(String username2) {
this.username2 = username2;
}
}

@ -1,22 +0,0 @@
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;
}
}

@ -1,22 +1,10 @@
package org.example.objects; package org.example.objects;
import org.example.models.Category;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
public class PostDTO { public class PostDTO {
String title,content; String title,content;
Category category; MultipartFile imageFile,videoFile;
MultipartFile imageFile;
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
MultipartFile videoFile;
public String getTitle() { public String getTitle() {
return title; return title;

@ -1,39 +0,0 @@
package org.example.objects;
import org.example.models.Image;
import org.example.models.Post;
import org.example.models.Video;
import org.springframework.data.neo4j.core.schema.Node;
import java.util.List;
public class PostWithMedia {
private Post post;
private List<Image> images;
private List<Video> videos;
// Getters and setters
public Post getPost() {
return post;
}
public void setPost(Post post) {
this.post = post;
}
public List<Image> getImages() {
return images;
}
public void setImages(List<Image> images) {
this.images = images;
}
public List<Video> getVideos() {
return videos;
}
public void setVideos(List<Video> videos) {
this.videos = videos;
}
}

@ -1,36 +0,0 @@
package org.example.objects;
import org.example.models.Post;
import org.example.models.User;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.web.bind.annotation.GetMapping;
public class SearchResultDTO {
@Id
@GeneratedValue
private Long id;
private User user;
private Post post;
public SearchResultDTO(Post post, User user) {
this.user = user;
this.post = post;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Post getPost() {
return post;
}
public void setPost(Post post) {
this.post = post;
}
}

@ -1,61 +0,0 @@
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
}

@ -1,51 +0,0 @@
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
}

@ -1,26 +0,0 @@
package org.example.repositories;
import org.example.models.Category;
import org.example.models.Post;
import org.example.objects.PostDTO;
import org.example.objects.PostWithMedia;
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> {
Category findByName(String name);
@Query("MATCH (c:Category)<-[:HAS_CATEGORY]-(p:Post)\n" +
"WHERE c.name = $categoryName\n" +
"OPTIONAL MATCH (p)-[:HAS_IMAGE]->(image:Image)\n" +
"OPTIONAL MATCH (p)-[:HAS_VIDEO]->(video:Video)\n" +
"RETURN ID(p)")
List<Long> findPostsByCategoryNames(@Param("categoryName") String categoryName);
@Query("MATCH (post:Post)-[HAS_CATEGORY]->(cate:Category) WHERE ID(post)=$postId return cate")
Category getCategory(@Param("postId") Long postId);
}

@ -1,7 +1,6 @@
package org.example.repositories; package org.example.repositories;
import org.example.controllers.UserController; import org.example.controllers.UserController;
import org.example.models.Category;
import org.example.models.Image; import org.example.models.Image;
import org.example.models.Post; import org.example.models.Post;
import org.example.queryresults.PostQueryResult; import org.example.queryresults.PostQueryResult;
@ -29,8 +28,6 @@ public interface PostRepository extends Neo4jRepository<Post,Long> {
"return image.filename") "return image.filename")
String getImage(@Param("postId") Long postId); String getImage(@Param("postId") Long postId);
@Query("MATCH (p:Post ) where ID(p)=$postId \n" + @Query("MATCH (p:Post ) where ID(p)=$postId \n" +
"SET p.title = $title,\n" + "SET p.title = $title,\n" +
" p.content = $content\n" + " p.content = $content\n" +
@ -51,52 +48,13 @@ 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), (p:Post) WHERE u.username = $username AND ID(p) = $postId " + @Query("MATCH (u:User {username: $username})-[r:LIKES]->(p:Post ) WHERE ID(p)=$postId DELETE r")
"MERGE (u)-[:LIKED {timestamp: datetime()}]->(p) " + void deleteLike(@Param("username") String username, @Param("postId") Long postId);
"RETURN p")
Post likePost(@Param("username") String username, @Param("postId") Long postId);
@Query("MATCH (u:User)-[l:LIKED]->(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),(u:User)\n" +
"OPTIONAL MATCH (p)<-[l:LIKED]-(u)\n" +
"OPTIONAL MATCH (p)<-[c:COMMENTED]-(u)\n" +
"OPTIONAL MATCH (p)<-[s:SHARED]-(u)\n" +
"OPTIONAL MATCH (p)-[:HAS_IMAGE]->(image:Image)\n" +
"OPTIONAL MATCH (p)-[:HAS_VIDEO]->(video:Video)\n" +
"WITH p, \n" +
" COUNT(DISTINCT l) AS likeCount, \n" +
" COUNT(DISTINCT c) AS commentCount, \n" +
" COUNT(DISTINCT s) AS shareCount, \n" +
" COLLECT(DISTINCT image) AS images, \n" +
" COLLECT(DISTINCT video) AS videos\n" +
"RETURN p, images, videos\n" +
"ORDER BY (likeCount + commentCount + shareCount) DESC\n" +
"LIMIT 10\n")
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")
PostQueryResult createPostRelationship(@Param("username") String username,@Param("postId") Long postId); PostQueryResult createPostRelationship(@Param("username") String username,@Param("postId") Long postId);
// @Query("match (p:Post)where id(p)=$postID\n" +
// "optional match (p)-[:HAS_IMAGE]->(image:Image)\n" +
// "optional match (p)-[:HAS_VIDEO]->(video:Video)\n" +
// "return p,image")
// List<Post> fi
} }

@ -1,23 +0,0 @@
package org.example.repositories;
import ch.qos.logback.core.joran.sanity.Pair;
import org.example.models.Post;
import org.example.models.User;
import org.example.objects.SearchResultDTO;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@Repository
public interface SearchRepository extends Neo4jRepository<Post,Long> {
@Query("MATCH (p:Post)<-[:createPost]-(u:User)\n" +
"WHERE p.title CONTAINS $condition OR p.content CONTAINS $condition OR u.username CONTAINS $condition \n" +
"RETURN p \n")
List<Post> search(@Param("condition") String condition);
}

@ -1,53 +1,36 @@
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.objects.FriendDTO;
import org.example.queryresults.PostQueryResult; import org.example.queryresults.PostQueryResult;
import org.example.services.UserService;
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.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.RequestBody;
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 (u:User {name:$username1}), (f:User {name:$username2})\n" +
"OPTIONAL MATCH (u)-[fr:Friend]->(f), (f)-[fr1:Friend]->(u)\n" + @Query("MATCH (user:User), (course:Course) WHERE user.username = $username AND course.identifier = $identifier " +
"WITH u, f, collect(fr) as friendships1, collect(fr1) as friendships2\n" + "RETURN EXISTS((user)-[:ENROLLED_IN]->(course))")
"FOREACH (_ IN CASE WHEN size(friendships1) = 0 AND size(friendships2) = 0 THEN [1] ELSE [] END | \n" + Boolean findEnrolmentStatus(String username, String identifier);
" CREATE (u)-[:Friend]->(f) \n" +
" CREATE (f)-[:Friend]->(u))\n" + @Query("match (u:User), (p:POST)\n" +
"FOREACH (_ IN CASE WHEN size(friendships1) > 0 AND size(friendships2) > 0 THEN [1] ELSE [] END | \n" + "WHERE id(u) = $nameId AND id(p) = $postId\n" +
" DELETE friendships1[0], friendships2[0])\n") "create (u) - [:LIKE] -> (p)")
void addFriend(@Param("username1") String username1, @Param("username2") String username2); void createLike(@Param("nameId") Long nameId, @Param("postId*") Long postId);
@Query("match (a:User)-[r:LIKE]-> (b:POST)\n" +
"WHERE id(a) = $id AND id(b) = $idd\n" +
@Query("MATCH (u:User {username:$username})-[:Friend]->(f:User)\n" + "RETURN COUNT(r) > 0 AS Relationship")
"match (f)-[:createPost]->(p:Post)RETURN ID(p)") boolean checkLike(@Param("id") Long userId,@Param("idd") Long postId);
List<Long> findFriendPosts(@Param("username") String username);
// @Query("MATCH (user:User), (course:Course) WHERE user.username = $username AND course.identifier = $identifier " +
@Query("MATCH (u:User {username: $username})-[r:LIKED|COMMENTED|SHARED]->(p:Post)\n" + // "CREATE (user)-[:ENROLLED_IN]->(course) RETURN user, course")
"OPTIONAL MATCH (p)<-[like:LIKED]-(:User)\n" + // CourseEnrolmentQueryResult createEnrolmentRelationship(String username, String identifier);
"OPTIONAL MATCH (p)<-[comment:COMMENTED]-(:User)\n" +
"OPTIONAL MATCH (p)<-[share:SHARED]-(:User)\n" +
"OPTIONAL MATCH (p)-[:HAS_CATEGORY]->(c:Category)\n" +
"WITH p, COUNT(DISTINCT like) AS likeCount, COUNT(DISTINCT comment) AS commentCount, COUNT(DISTINCT share) AS shareCount, c.name AS categories \n" +
"WHERE likeCount > 0 OR commentCount > 0 OR shareCount > 0\n" +
"RETURN categories \n" +
"ORDER BY (likeCount + commentCount + shareCount) DESC")
List<String> findInteractedCategories(@Param("username") String username);
} }

@ -0,0 +1,15 @@
package org.example.requests;
import lombok.*;
import lombok.experimental.FieldDefaults;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class CreateLikeRequest {
Long userId;
Long postId;
}

@ -1,23 +0,0 @@
package org.example.services;
import org.example.models.Category;
import org.example.repositories.CategoryRepository;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class CategoryService {
private final CategoryRepository categoryRepository;
public CategoryService(CategoryRepository categoryRepository) {
this.categoryRepository = categoryRepository;
}
public List<Category> getAllCategories() {
List<Category> categories = categoryRepository.findAll();
return categories;
}
}

@ -1,45 +0,0 @@
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;
import java.util.List;
import java.util.Optional;
@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,7 +3,10 @@ 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.*; import org.example.models.Image;
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;
@ -20,7 +23,6 @@ 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;
@ -34,7 +36,6 @@ public class PostService {
private final UserService userService; private final UserService userService;
private final UserRepository userRepository; private final UserRepository userRepository;
private String username; private String username;
private Category category;
@Autowired @Autowired
private Neo4jTemplate neo4jTemplate; private Neo4jTemplate neo4jTemplate;
@ -63,13 +64,27 @@ public class PostService {
return getAllPost; return getAllPost;
} }
@Transactional @Transactional
public Post createPost(String title, String content,Category category, MultipartFile imageFile, MultipartFile videoFile) throws IOException { 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 {
Post post = new Post(); Post post = new Post();
post.setTitle(title); post.setTitle(title);
post.setContent(content); post.setContent(content);
post.setCategory(category);
if (imageFile != null) { if (imageFile != null) {
Image image = saveImageFile(imageFile, "C:\\Users\\phucl\\OneDrive\\Desktop\\JAVA_INTER\\Facebook\\FE\\FE\\public\\picture"); Image image = saveImageFile(imageFile, "C:\\Users\\P R O B O O K\\Documents\\Phuc\\Facebook\\FE/FE/public/picture");
// post.getImages().add(image); // post.getImages().add(image);
post.setImages(image); post.setImages(image);
} }
@ -97,11 +112,11 @@ public class PostService {
} }
} }
@Transactional @Transactional
public Post editPost(Long postId, String title, String content,Category category, MultipartFile imageFile, MultipartFile videoFile) throws IOException { public Post editPost(Long postId, String title, String content, MultipartFile imageFile, MultipartFile videoFile) throws IOException {
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\\phucl\\OneDrive\\Desktop\\JAVA_INTER\\Facebook\\FE\\FE\\public\\picture"); Image newImage = saveImageFile(imageFile, "C:\\Users\\P R O B O O K\\Documents\\Phuc\\Facebook\\FE/FE/public/picture");
post.setImages(newImage); post.setImages(newImage);
} }

@ -1,67 +0,0 @@
package org.example.services;
import org.example.models.Category;
import org.example.models.Post;
import org.example.objects.PostDTO;
import org.example.objects.PostWithMedia;
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.HashSet;
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<>();
//tim kiem bai viết phổ biến theo số lượng interact
List<Post> postsInteracts = new ArrayList<>();
postsInteracts=postRepository.findTop10ByInteractions();
for (Post post : postsInteracts) {
post.setImgUrl(postRepository.getImage(post.getId()));
recommendationPosts.add(post);
}
//tìm kiếm các bài post có chung chủ đề
List<String> categoriesNames = userRepository.findInteractedCategories(username);
for (String categoryName : categoriesNames) {
System.out.println(categoryName);
List<Long> IDposts = categoryRepository.findPostsByCategoryNames(categoryName);
for(Long IDpost : IDposts) {
System.out.println(IDpost);
Post post= postRepository.findById(IDpost).get();
if(!recommendationPosts.contains(post)) {
recommendationPosts.add(post);
post.setImgUrl(postRepository.getImage(IDpost));
}
}
}
List<Long> postsFriend;
postsFriend=userRepository.findFriendPosts(username);
for (Long postID : postsFriend) {
Post post = postRepository.findById(postID).get();
if(!recommendationPosts.contains(post)) {
post.setImgUrl(postRepository.getImage(post.getId()));
recommendationPosts.add(post);
}
}
return recommendationPosts.stream().distinct().collect(Collectors.toList());
}
}

@ -1,40 +0,0 @@
package org.example.services;
import ch.qos.logback.core.joran.sanity.Pair;
import org.example.models.Post;
import org.example.models.User;
import org.example.objects.SearchResultDTO;
import org.example.repositories.CategoryRepository;
import org.example.repositories.PostRepository;
import org.example.repositories.SearchRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class SearchService {
@Autowired
private final SearchRepository searchRepository;
@Autowired
private final PostRepository postRepository;
@Autowired
private final CategoryRepository categoryRepository;
public SearchService(SearchRepository searchRepository, PostRepository postRepository,CategoryRepository categoryRepository) {
this.searchRepository = searchRepository;
this.postRepository = postRepository;
this.categoryRepository = categoryRepository;
}
public List<Post> searchResult(String condition) {
List<Post> posts= searchRepository.search(condition);
for(Post post: posts) {
post.setImgUrl(postRepository.getImage(post.getId()));
post.setCategory(categoryRepository.getCategory(post.getId()));
}
return posts;
}
}

@ -1,8 +1,8 @@
package org.example.services; package org.example.services;
import org.example.models.User; import org.example.models.User;
import org.example.repositories.PostRepository;
import org.example.repositories.UserRepository; import org.example.repositories.UserRepository;
import org.example.requests.CreateLikeRequest;
import org.example.requests.CreateUserRequest; import org.example.requests.CreateUserRequest;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -12,12 +12,10 @@ public class UserService {
private final UserRepository userRepository; private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder; private final PasswordEncoder passwordEncoder;
private final PostRepository postRepository;
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, PostRepository postRepository) { public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository; this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder; this.passwordEncoder = passwordEncoder;
this.postRepository = postRepository;
} }
public User createUser(CreateUserRequest request) { public User createUser(CreateUserRequest request) {
@ -36,7 +34,16 @@ public class UserService {
return user; return user;
} }
public void addFriend(String username1, String username2) {
userRepository.addFriend(username1,username2); public CreateLikeRequest createLike(CreateLikeRequest request) {
Long userId = request.getUserId();
Long postId = request.getPostId();
if(userRepository.checkLike(userId, postId)){
throw new IllegalArgumentException("Already liked");
}
userRepository.createLike(userId, postId);
return request;
} }
} }

@ -1,3 +1,4 @@
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