Compare commits

...

2 Commits

Author SHA1 Message Date
PaulK
fce585e089 gruppen und likes fertig 2025-02-14 11:39:39 +01:00
PaulK
fdd18bdb6c gruppen und likes 2025-02-12 11:49:46 +01:00
15 changed files with 513 additions and 2 deletions

View File

@ -0,0 +1,77 @@
package com.example.hangry;
import jakarta.persistence.*;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "`group`")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
@ManyToMany
@JoinTable(
name = "group_users",
joinColumns = @JoinColumn(name = "group_id"),
inverseJoinColumns = @JoinColumn(name = "user_id")
)
private Set<User> members = new HashSet<>();
@OneToMany(mappedBy = "group", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<GroupRecipe> sharedRecipes = new HashSet<>();
public Group() {}
public Group(String name, String description) {
this.name = name;
this.description = description;
}
// Getter und Setter
public Long getId() {
return id;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public Set<User> getMembers() {
return members;
}
public Set<GroupRecipe> getSharedRecipes() {
return sharedRecipes;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setDescription(String description) {
this.description = description;
}
public void setMembers(Set<User> members) {
this.members = members;
}
public void setSharedRecipes(Set<GroupRecipe> sharedRecipes) {
this.sharedRecipes = sharedRecipes;
}
}

View File

@ -0,0 +1,43 @@
package com.example.hangry;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Set;
@RestController
@RequestMapping("/api/groups")
@CrossOrigin(origins = "*")
public class GroupController {
private final GroupService groupService;
public GroupController(GroupService groupService) {
this.groupService = groupService;
}
// Neue Gruppe erstellen
@PostMapping
public ResponseEntity<Group> createGroup(@RequestParam String name, @RequestParam String description) {
return ResponseEntity.ok(groupService.createGroup(name, description));
}
// Gruppe beitreten
@PostMapping("/{groupId}/join/{userId}")
public ResponseEntity<String> joinGroup(@PathVariable Long groupId, @PathVariable Long userId) {
boolean joined = groupService.joinGroup(userId, groupId);
return joined ? ResponseEntity.ok("Gruppe beigetreten") : ResponseEntity.badRequest().body("Bereits Mitglied");
}
// Gruppe verlassen
@PostMapping("/{groupId}/leave/{userId}")
public ResponseEntity<String> leaveGroup(@PathVariable Long groupId, @PathVariable Long userId) {
boolean left = groupService.leaveGroup(userId, groupId);
return left ? ResponseEntity.ok("Gruppe verlassen") : ResponseEntity.badRequest().body("Nicht in der Gruppe");
}
// Mitglieder einer Gruppe abrufen
@GetMapping("/{groupId}/members")
public ResponseEntity<Set<User>> getGroupMembers(@PathVariable Long groupId) {
return ResponseEntity.ok(groupService.getGroupMembers(groupId));
}
}

View File

@ -0,0 +1,52 @@
package com.example.hangry;
import jakarta.persistence.*;
@Entity
public class GroupRecipe {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "group_id", nullable = false)
private Group group;
@ManyToOne
@JoinColumn(name = "recipe_id", nullable = false)
private Recipe recipe;
public GroupRecipe() {}
public GroupRecipe(Group group, Recipe recipe) {
this.group = group;
this.recipe = recipe;
}
// Getter und Setter
public Long getId() {
return id;
}
public Group getGroup() {
return group;
}
public Recipe getRecipe() {
return recipe;
}
public void setId(Long id) {
this.id = id;
}
public void setGroup(Group group) {
this.group = group;
}
public void setRecipe(Recipe recipe) {
this.recipe = recipe;
}
}

View File

@ -0,0 +1,32 @@
package com.example.hangry;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Set;
@RestController
@RequestMapping("/api/group-recipes")
@CrossOrigin(origins = "*")
public class GroupRecipeController {
private final GroupRecipeService groupRecipeService;
public GroupRecipeController(GroupRecipeService groupRecipeService) {
this.groupRecipeService = groupRecipeService;
}
@PostMapping("/{groupId}/share/{recipeId}")
public ResponseEntity<String> shareRecipe(@PathVariable Long groupId, @PathVariable Long recipeId) {
boolean shared = groupRecipeService.shareRecipeWithGroup(groupId, recipeId);
return shared ? ResponseEntity.ok("Rezept geteilt") : ResponseEntity.badRequest().body("Fehler beim Teilen");
}
@GetMapping("/{groupId}")
public ResponseEntity<Set<Recipe>> getGroupRecipes(@PathVariable Long groupId) {
return ResponseEntity.ok(groupRecipeService.getGroupRecipes(groupId));
}
}

View File

@ -0,0 +1,6 @@
package com.example.hangry;
import org.springframework.data.jpa.repository.JpaRepository;
public interface GroupRecipeRepository extends JpaRepository<GroupRecipe, Long> {
}

View File

@ -0,0 +1,38 @@
package com.example.hangry;
import org.springframework.stereotype.Service;
import java.util.Set;
import java.util.stream.Collectors;
@Service
public class GroupRecipeService {
private final GroupRepository groupRepository;
private final RecipeRepository recipeRepository;
private final GroupRecipeRepository groupRecipeRepository;
public GroupRecipeService(GroupRepository groupRepository, RecipeRepository recipeRepository, GroupRecipeRepository groupRecipeRepository) {
this.groupRepository = groupRepository;
this.recipeRepository = recipeRepository;
this.groupRecipeRepository = groupRecipeRepository;
}
// Rezept mit Gruppe teilen
public boolean shareRecipeWithGroup(Long groupId, Long recipeId) {
Group group = groupRepository.findById(groupId)
.orElseThrow(() -> new RuntimeException("Gruppe nicht gefunden"));
Recipe recipe = recipeRepository.findById(recipeId)
.orElseThrow(() -> new RuntimeException("Rezept nicht gefunden"));
GroupRecipe groupRecipe = new GroupRecipe(group, recipe);
groupRecipeRepository.save(groupRecipe);
return true;
}
// Alle Rezepte einer Gruppe abrufen
public Set<Recipe> getGroupRecipes(Long groupId) {
Group group = groupRepository.findById(groupId)
.orElseThrow(() -> new RuntimeException("Gruppe nicht gefunden"));
return group.getSharedRecipes().stream().map(GroupRecipe::getRecipe).collect(Collectors.toSet());
}
}

View File

@ -0,0 +1,6 @@
package com.example.hangry;
import org.springframework.data.jpa.repository.JpaRepository;
public interface GroupRepository extends JpaRepository<Group, Long> {
}

View File

@ -0,0 +1,60 @@
package com.example.hangry;
import org.springframework.stereotype.Service;
import java.util.Optional;
import java.util.Set;
@Service
public class GroupService {
private final GroupRepository groupRepository;
private final UserRepository userRepository;
public GroupService(GroupRepository groupRepository, UserRepository userRepository) {
this.groupRepository = groupRepository;
this.userRepository = userRepository;
}
// Gruppe erstellen
public Group createGroup(String name, String description) {
Group group = new Group(name, description);
return groupRepository.save(group);
}
// Gruppe beitreten
public boolean joinGroup(Long userId, Long groupId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("User nicht gefunden"));
Group group = groupRepository.findById(groupId)
.orElseThrow(() -> new RuntimeException("Gruppe nicht gefunden"));
if (!group.getMembers().contains(user)) {
group.getMembers().add(user);
groupRepository.save(group);
return true;
}
return false;
}
// Gruppe verlassen
public boolean leaveGroup(Long userId, Long groupId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("User nicht gefunden"));
Group group = groupRepository.findById(groupId)
.orElseThrow(() -> new RuntimeException("Gruppe nicht gefunden"));
if (group.getMembers().contains(user)) {
group.getMembers().remove(user);
groupRepository.save(group);
return true;
}
return false;
}
// Alle Mitglieder einer Gruppe abrufen
public Set<User> getGroupMembers(Long groupId) {
Group group = groupRepository.findById(groupId)
.orElseThrow(() -> new RuntimeException("Gruppe nicht gefunden"));
return group.getMembers();
}
}

View File

@ -0,0 +1,64 @@
package com.example.hangry;
import jakarta.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "`likes`")
public class Like {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private User user;
@ManyToOne
@JoinColumn(name = "recipe_id", nullable = false)
private Recipe recipe;
private LocalDateTime createdAt = LocalDateTime.now();
// Konstruktoren, Getter & Setter#
public Like(){}
public Like( User user, Recipe recipe) {
this.user = user;
this.recipe = recipe;
this.createdAt=LocalDateTime.now();
}
public Long getId() {
return id;
}
public User getUser() {
return user;
}
public Recipe getRecipe() {
return recipe;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setId(Long id) {
this.id = id;
}
public void setUser(User user) {
this.user = user;
}
public void setRecipe(Recipe recipe) {
this.recipe = recipe;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
}

View File

@ -0,0 +1,44 @@
package com.example.hangry;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/likes")
@CrossOrigin(origins = "*")
public class LikeController {
private final LikeService likeService;
public LikeController(LikeService likeService) {
this.likeService = likeService;
}
// Rezept liken
@PostMapping("/{userId}/{recipeId}")
public ResponseEntity<String> likeRecipe(@PathVariable Long userId, @PathVariable Long recipeId) {
boolean liked = likeService.likeRecipe(userId, recipeId);
return liked ? ResponseEntity.ok("Rezept geliked") : ResponseEntity.badRequest().body("Bereits geliked");
}
// Rezept entliken
@DeleteMapping("/{userId}/{recipeId}")
public ResponseEntity<String> unlikeRecipe(@PathVariable Long userId, @PathVariable Long recipeId) {
boolean unliked = likeService.unlikeRecipe(userId, recipeId);
return unliked ? ResponseEntity.ok("Like entfernt") : ResponseEntity.badRequest().body("Like existiert nicht");
}
// Anzahl der Likes für ein Rezept abrufen
@GetMapping("/count/{recipeId}")
public ResponseEntity<Long> getLikeCount(@PathVariable Long recipeId) {
return ResponseEntity.ok(likeService.getLikeCount(recipeId));
}
// Alle geliketen Rezepte eines Users abrufen
@GetMapping("/user/{userId}")
public ResponseEntity<List<Recipe>> getLikedRecipes(@PathVariable Long userId) {
return ResponseEntity.ok(likeService.getLikedRecipes(userId));
}
}

View File

@ -0,0 +1,17 @@
package com.example.hangry;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;
public interface LikeRepository extends JpaRepository<Like, Long> {
boolean existsByUserAndRecipe(User user, Recipe recipe);
long countByRecipe(Recipe recipe);
List<Like> findAllByUser(User user);
void deleteByUserAndRecipe(User user, Recipe recipe);
}

View File

@ -0,0 +1,66 @@
package com.example.hangry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class LikeService {
private final LikeRepository likeRepository;
private final RecipeRepository recipeRepository;
private final UserRepository userRepository;
public LikeService(LikeRepository likeRepository, RecipeRepository recipeRepository, UserRepository userRepository) {
this.likeRepository = likeRepository;
this.recipeRepository = recipeRepository;
this.userRepository = userRepository;
}
// Rezept liken
public boolean likeRecipe(Long userId, Long recipeId) {
User user = userRepository.findById(userId).orElseThrow();
Recipe recipe = recipeRepository.findById(recipeId).orElseThrow();
if (likeRepository.existsByUserAndRecipe(user, recipe)) {
return false; // Bereits geliked
}
Like like = new Like();
like.setUser(user);
like.setRecipe(recipe);
likeRepository.save(like);
return true;
}
// Rezept entliken
@Transactional
public boolean unlikeRecipe(Long userId, Long recipeId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("User nicht gefunden"));
Recipe recipe = recipeRepository.findById(recipeId)
.orElseThrow(() -> new RuntimeException("Rezept nicht gefunden"));
// Prüfen, ob das Like existiert
if (!likeRepository.existsByUserAndRecipe(user, recipe)) {
return false; // Like existiert nicht
}
likeRepository.deleteByUserAndRecipe(user, recipe);
return true;
}
// Anzahl der Likes für ein Rezept abrufen
public long getLikeCount(Long recipeId) {
Recipe recipe = recipeRepository.findById(recipeId).orElseThrow();
return likeRepository.countByRecipe(recipe);
}
// Alle geliketen Rezepte eines Users abrufen
public List<Recipe> getLikedRecipes(Long userId) {
User user = userRepository.findById(userId).orElseThrow();
List<Like> likes = likeRepository.findAllByUser(user);
return likes.stream().map(Like::getRecipe).toList();
}
}

View File

@ -76,4 +76,6 @@ public class Recipe {
public void setRecipeIngredients(List<RecipeIngredient> recipeIngredients) { public void setRecipeIngredients(List<RecipeIngredient> recipeIngredients) {
this.recipeIngredients = recipeIngredients; this.recipeIngredients = recipeIngredients;
} }
} }

View File

@ -11,6 +11,7 @@ public interface RecipeRepository extends JpaRepository<Recipe, Long> {
Page<Recipe> findByCategoryIgnoreCase(String category, Pageable pageable); Page<Recipe> findByCategoryIgnoreCase(String category, Pageable pageable);
// Sucht nach Rezepten, die eine bestimmte Zutat enthalten // Sucht nach Rezepten, die eine bestimmte Zutat enthalten
@Query("SELECT r FROM Recipe r JOIN r.recipeIngredients i WHERE LOWER(i.name) LIKE LOWER(CONCAT('%', :ingredient, '%'))") @Query("SELECT r FROM Recipe r JOIN r.recipeIngredients i WHERE LOWER(i.ingredient.name) LIKE LOWER(CONCAT('%', :ingredient, '%'))")
Page<Recipe> findByIngredient(@Param("ingredient") String ingredient, Pageable pageable); Page<Recipe> findByIngredient(@Param("ingredient") String ingredient, Pageable pageable);
} }

View File

@ -4,6 +4,9 @@ spring.datasource.username=root
spring.datasource.password= spring.datasource.password=
# Hibernate Einstellungen # Hibernate Einstellungen
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.hibernate.ddl-auto=update