From d74ac7995a16f46e7d383af1ec9d802607d6d2ac Mon Sep 17 00:00:00 2001 From: "Masaharu.Kato" Date: Wed, 18 Jun 2025 11:25:33 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=E3=83=AC=E3=82=B7=E3=83=94=E4=B8=80?= =?UTF-8?q?=E8=A6=A7=E5=8F=96=E5=BE=97=E6=99=82=EF=BC=8C=E6=9C=80=E5=A4=A7?= =?UTF-8?q?=E8=AA=BF=E7=90=86=E5=8F=AF=E8=83=BD=E6=95=B0=E3=82=92=E8=BF=94?= =?UTF-8?q?=E3=81=99=E3=82=88=E3=81=86=E3=81=AB=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../todoapp/controller/RecipesController.java | 12 +++++++ .../todoapp/dto/RecipeResponseDTO.java | 6 ++++ .../todoapp/service/RecipeService.java | 31 +++++++++++++++++++ frontend/src/services/api.ts | 7 ++++- frontend/src/types/types.ts | 3 +- 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/com/example/todoapp/controller/RecipesController.java b/backend/src/main/java/com/example/todoapp/controller/RecipesController.java index b2f97ab..6156ba5 100644 --- a/backend/src/main/java/com/example/todoapp/controller/RecipesController.java +++ b/backend/src/main/java/com/example/todoapp/controller/RecipesController.java @@ -8,6 +8,7 @@ import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -18,6 +19,8 @@ import com.example.todoapp.dto.RecipeDetailDTO; import com.example.todoapp.dto.RecipeRequestDTO; import com.example.todoapp.dto.RecipeResponseDTO; import com.example.todoapp.model.Recipes; +import com.example.todoapp.model.User; +import com.example.todoapp.repository.UserRepository; import com.example.todoapp.service.RecipeService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -36,6 +39,9 @@ public class RecipesController { @Autowired private RecipeService recipeService; + @Autowired + private UserRepository userRepository; + /** * 新しいレシピを作成する * @@ -62,7 +68,12 @@ public class RecipesController { */ @GetMapping("/getAll") public ResponseEntity> getRecipe(Authentication authentication) { + + User user = userRepository.findByUsername(authentication.getName()) + .orElseThrow(() -> new UsernameNotFoundException("User not found")); + List recipes = recipeService.getAllRecipes(); + // エンティティからDTOへの変換 List responseList = recipes.stream() .map(recipe -> { @@ -70,6 +81,7 @@ public class RecipesController { dto.setRecipeId(recipe.getRecipeId()); dto.setRecipeName(recipe.getRecipeName()); dto.setSummary(recipe.getSummary()); + dto.setMaxServings(recipeService.getRecipeMaxServings(user.getId(), recipe)); return dto; }) .collect(Collectors.toList()); diff --git a/backend/src/main/java/com/example/todoapp/dto/RecipeResponseDTO.java b/backend/src/main/java/com/example/todoapp/dto/RecipeResponseDTO.java index 38d69a3..b8d6887 100644 --- a/backend/src/main/java/com/example/todoapp/dto/RecipeResponseDTO.java +++ b/backend/src/main/java/com/example/todoapp/dto/RecipeResponseDTO.java @@ -28,4 +28,10 @@ public class RecipeResponseDTO { * レシピの簡単な説明文 */ private String summary; + + /** + * 最大調理可能数 + * そのレシピを何人分調理可能か + */ + private int maxServings; } diff --git a/backend/src/main/java/com/example/todoapp/service/RecipeService.java b/backend/src/main/java/com/example/todoapp/service/RecipeService.java index 3329420..ad27f08 100644 --- a/backend/src/main/java/com/example/todoapp/service/RecipeService.java +++ b/backend/src/main/java/com/example/todoapp/service/RecipeService.java @@ -49,6 +49,9 @@ public class RecipeService { @Autowired private RecipeStuffsRepository recipeStuffsRepository; + @Autowired + private StocksService stockService; + /** * レシピを新規登録する * @@ -102,6 +105,34 @@ public class RecipeService { return recipesRepository.findAll(); } + /** + * レシピを指定して,現在の在庫を参照しそのレシピが最大何人分作れるか返す + * + * @param userId ユーザーID + * @param recipe レシピのエンティティ + * @throws RuntimeException レシピが材料を持たないなど,計算に失敗したとき + * @return 最大何人分作れるか + */ + public int getRecipeMaxServings(Long userId, Recipes recipe) { + + List recipeStuffs = recipeStuffsRepository.findByRecipesRecipeId(recipe.getRecipeId()); + + // 各材料がその料理のレシピで何人分在庫があるか計算し,それらの最小値が料理全体での人数になる + Integer minNServings = null; + for (RecipeStuffs recipeStuff : recipeStuffs) { + int stockAmount = stockService.calcAmountByStuffId(userId, recipeStuff.getStuff().getStuffId()); + int nServings = stockAmount / recipeStuff.getAmount(); // 小数点以下切り捨て(整数除算) + if (minNServings == null || minNServings > nServings) { + minNServings = nServings; + } + } + + // recipeStuffs が空の場合などに null のままになる(通常は起こりえない) + if (minNServings == null) throw new RuntimeException("Failed to calculate recipeMaxServings"); + + return minNServings; + } + /** * 指定されたIDのレシピ詳細情報を取得する * diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index e6f0442..82350fb 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -456,7 +456,12 @@ export const recipeApi = { errorData?.message ); } - return response.json(); + + // デバッグ用に表示 + const recipes = response.json(); + console.log('recipes: ', recipes); + + return recipes; }, /** diff --git a/frontend/src/types/types.ts b/frontend/src/types/types.ts index bd64d97..dc970d7 100644 --- a/frontend/src/types/types.ts +++ b/frontend/src/types/types.ts @@ -142,7 +142,8 @@ export interface Recipe { } export interface RecipeWithId extends Recipe { - recipeId: number; + recipeId: number; // レシピID + maxServings: number; // 最大調理可能数 } /** From 3e16bc22d6048c375bfab2f4305bbcf86f49f833 Mon Sep 17 00:00:00 2001 From: "Masaharu.Kato" Date: Wed, 18 Jun 2025 11:47:25 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=E8=B3=BC=E5=85=A5=E5=87=A6=E7=90=86?= =?UTF-8?q?=E3=81=A7=E8=B3=BC=E5=85=A5=E6=95=B0=E9=87=8F=E3=81=8C=E4=BA=88?= =?UTF-8?q?=E5=AE=9A=E6=95=B0=E9=87=8F=E3=81=AB=E6=BA=80=E3=81=9F=E3=81=AA?= =?UTF-8?q?=E3=81=84=E5=A0=B4=E5=90=88=EF=BC=8C=E6=AE=8B=E3=82=8A=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E3=82=92=E8=B2=B7=E3=81=86=E3=82=82=E3=81=AE=E3=83=AA?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=81=AB=E6=AE=8B=E3=81=99=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../todoapp/repository/ToBuysRepository.java | 11 ++++++++++ .../todoapp/service/ToBuysService.java | 22 +++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/com/example/todoapp/repository/ToBuysRepository.java b/backend/src/main/java/com/example/todoapp/repository/ToBuysRepository.java index 0778f5f..24d464f 100644 --- a/backend/src/main/java/com/example/todoapp/repository/ToBuysRepository.java +++ b/backend/src/main/java/com/example/todoapp/repository/ToBuysRepository.java @@ -47,6 +47,17 @@ public interface ToBuysRepository extends JpaRepository { */ @Query("SELECT t FROM ToBuys t WHERE t.user.id = :userId ORDER BY t.tobuyId ASC") List findByUserIdOrderByTobuyIdAsc(@Param("userId") Long userId); + + /** + * 指定された「買うもの」IDに基づいて「買うもの」での数量を更新 + * + * @param tobuyId 「買うもの」ID + * @param amount 「買うもの」数量 + * @return 更新された行数 + */ + @Modifying + @Query("UPDATE ToBuys t SET t.amount = :amount WHERE t.tobuyId = :tobuyId") + int updateAmountByTobuyId(Long tobuyId, int amount); /** * 指定された「買うもの」IDに基づいて「買うもの」リストを削除 diff --git a/backend/src/main/java/com/example/todoapp/service/ToBuysService.java b/backend/src/main/java/com/example/todoapp/service/ToBuysService.java index 2c0cc2a..323a447 100644 --- a/backend/src/main/java/com/example/todoapp/service/ToBuysService.java +++ b/backend/src/main/java/com/example/todoapp/service/ToBuysService.java @@ -171,6 +171,16 @@ public class ToBuysService { return toBuysRepository.findByUserIdOrderByTobuyIdAsc(user.getId()); } + /** + * 指定された購入リストIDに基づいて「数量」を変更する + * + * @param tobuyId 購入リストID + */ + @Transactional + public int updateToBuysAmountByTobuyId(Long tobuyId, int amount) { + return toBuysRepository.updateAmountByTobuyId(tobuyId, amount); + } + /** * 指定された購入リストIDに基づいて「買うもの」を削除する * @@ -207,9 +217,17 @@ public class ToBuysService { stock.setBuyDate(dto.getBuyDate()); stock.setExpDate(dto.getExpDate()); - // 買うものリストから削除 + // まだ買うべき数量を計算 + int remainAmount = Math.max(tobuy.getAmount() - dto.getAmount(), 0); + System.out.println("remainAmount=" + remainAmount); + + // 買うものリストから削除または数量変更 System.out.println("tobuy.getTobuyId()=" + tobuy.getTobuyId()); - deleteToBuysByTobuyId(tobuy.getTobuyId()); + if (remainAmount > 0) { + updateToBuysAmountByTobuyId(tobuy.getTobuyId(), remainAmount); + } else { + deleteToBuysByTobuyId(tobuy.getTobuyId()); + } // データベースに保存 return stocksRepository.save(stock);