diff --git a/BE/src/main/java/org/example/controllers/PostController.java b/BE/src/main/java/org/example/controllers/PostController.java index 6c918a0..463b7e1 100644 --- a/BE/src/main/java/org/example/controllers/PostController.java +++ b/BE/src/main/java/org/example/controllers/PostController.java @@ -2,11 +2,15 @@ package org.example.controllers; //import org.example.models.Author; 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.repositories.PostRepository; import org.example.services.PostService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -31,7 +35,27 @@ public class PostController { return postService.getAllPost(); } + @GetMapping("/edit/{id}") + public Post getPostById(@PathVariable Long id){ + return postService.findPostById(id); + } + + @PostMapping("/edit/{id}") + public Post updatePost(@PathVariable Long id,@RequestBody PostDTO postDTO) throws IOException { + return postService.editPost(id, postDTO.getTitle(), postDTO.getContent(), postDTO.getImageFile(), postDTO.getVideoFile()); + } + @PostMapping("/like") + public ResponseEntity 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 public Post createPost( diff --git a/BE/src/main/java/org/example/models/Author.java b/BE/src/main/java/org/example/models/Author.java deleted file mode 100644 index e69de29..0000000 diff --git a/BE/src/main/java/org/example/models/LikeRequest.java b/BE/src/main/java/org/example/models/LikeRequest.java new file mode 100644 index 0000000..51f270a --- /dev/null +++ b/BE/src/main/java/org/example/models/LikeRequest.java @@ -0,0 +1,22 @@ +package org.example.models; + +public class LikeRequest { + String username; + 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; + } +} diff --git a/BE/src/main/java/org/example/objects/PostDTO.java b/BE/src/main/java/org/example/objects/PostDTO.java new file mode 100644 index 0000000..00e5e52 --- /dev/null +++ b/BE/src/main/java/org/example/objects/PostDTO.java @@ -0,0 +1,40 @@ +package org.example.objects; + +import org.springframework.web.multipart.MultipartFile; + +public class PostDTO { + String title,content; + MultipartFile imageFile,videoFile; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public MultipartFile getImageFile() { + return imageFile; + } + + public void setImageFile(MultipartFile imageFile) { + this.imageFile = imageFile; + } + + public MultipartFile getVideoFile() { + return videoFile; + } + + public void setVideoFile(MultipartFile videoFile) { + this.videoFile = videoFile; + } +} diff --git a/BE/src/main/java/org/example/repositories/PostRepository.java b/BE/src/main/java/org/example/repositories/PostRepository.java index 657ee73..367d51f 100644 --- a/BE/src/main/java/org/example/repositories/PostRepository.java +++ b/BE/src/main/java/org/example/repositories/PostRepository.java @@ -7,7 +7,10 @@ import org.example.queryresults.PostQueryResult; 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.security.core.parameters.P; import org.springframework.stereotype.Repository; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; import java.util.List; import java.util.UUID; @@ -25,9 +28,32 @@ public interface PostRepository extends Neo4jRepository { "return image.filename") String getImage(@Param("postId") Long postId); -// @Query("MATCH (user:User {username: $username}), (post:Post ) " +" WHERE ID(post)=$postId "+ -// "CREATE (user)-[:createPost]->(post) Return user,post") -// void createPostRelationship(@Param("username") String username,@Param("postId") Long postId); + @Query("MATCH (p:Post ) where ID(p)=$postId \n" + + "SET p.title = $title,\n" + + " p.content = $content\n" + + "WITH p\n" + + "OPTIONAL MATCH (p)-[r:HAS_IMAGE]->(oldImage:Image)\n" + + "DELETE r, oldImage\n" + + "WITH p\n" + + "OPTIONAL MATCH (p)-[r:HAS_VIDEO]->(oldVideo:Video)\n" + + "DELETE r, oldVideo\n" + + "WITH p\n" + + "FOREACH (ignoreMe IN CASE WHEN $imageFile IS NOT NULL THEN [1] ELSE [] END |\n" + + " CREATE (newImage:Image {url: $imageFile})\n" + + " CREATE (p)-[:HAS_IMAGE]->(newImage)\n" + + ")\n" + + "FOREACH (ignoreMe IN CASE WHEN $videoFile IS NOT NULL THEN [1] ELSE [] END |\n" + + " CREATE (newVideo:Video {url: $videoFile})\n" + + " CREATE (p)-[:HAS_VIDEO]->(newVideo)\n" + + ")\n" + + "RETURN p") + 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") + void deleteLike(@Param("username") String username, @Param("postId") Long postId); + @Query("MATCH (user:User {username: $username}),(post:Post )"+"where ID(post)=$postId"+ " CREATE (user)-[:createPost ]->(post)"+ "RETURN user, post") PostQueryResult createPostRelationship(@Param("username") String username,@Param("postId") Long postId); diff --git a/BE/src/main/java/org/example/services/PostService.java b/BE/src/main/java/org/example/services/PostService.java index a3c879d..d0eb34b 100644 --- a/BE/src/main/java/org/example/services/PostService.java +++ b/BE/src/main/java/org/example/services/PostService.java @@ -11,6 +11,10 @@ import org.example.queryresults.PostQueryResult; import org.example.repositories.PostRepository; import org.example.repositories.UserRepository; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.core.Neo4jOperations; +import org.springframework.data.neo4j.core.Neo4jTemplate; +import org.springframework.data.neo4j.repository.Neo4jRepository; +import org.springframework.data.neo4j.repository.query.Query; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -20,6 +24,8 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.security.Principal; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.UUID; @Service @@ -31,7 +37,8 @@ public class PostService { private final UserRepository userRepository; private String username; - + @Autowired + private Neo4jTemplate neo4jTemplate; @Autowired public PostService(PostRepository postRepository, UserController userController, UserService userService, UserRepository userRepository) { this.postRepository = postRepository; @@ -57,6 +64,20 @@ public class PostService { return getAllPost; } @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 { Post post = new Post(); post.setTitle(title); @@ -81,6 +102,34 @@ public class PostService { return post1; } + @Transactional + public Post findPostById(Long postId) { + Optional checkPost = postRepository.findById(postId); + if (!checkPost.isPresent()) { + throw new IllegalArgumentException("Post with ID " + postId + " not found."); + }else{ + return checkPost.get(); + } + } + @Transactional + public Post editPost(Long postId, String title, String content, MultipartFile imageFile, MultipartFile videoFile) throws IOException { + Post post= postRepository.updatePost(postId,title,content,imageFile,videoFile); + // Update the image file if provided + if (imageFile != null) { + Image newImage = saveImageFile(imageFile, "C:\\Users\\P R O B O O K\\Documents\\Phuc\\Facebook\\FE/FE/public/picture"); + post.setImages(newImage); + } + + // Update the video file if provided + if (videoFile != null) { + Video newVideo = saveVideoFile(videoFile, "videos"); + post.getVideos().clear(); + post.getVideos().add(newVideo); + } else { + post.getVideos().clear(); + } + return post; + } private Image saveImageFile(MultipartFile file, String folder) throws IOException { // Ensure directory exists; create if not