1. recipes: add, getAll, getById, update を実装しました

feature-backend-recipe
zhang.pengcheng 4 months ago
parent 7e9297bc06
commit 044718ecf7
  1. 92
      backend/src/main/java/com/example/todoapp/controller/RecipesController.java
  2. 8
      backend/src/main/java/com/example/todoapp/controller/StocksController.java
  3. 1
      backend/src/main/java/com/example/todoapp/controller/ToBuysController.java
  4. 14
      backend/src/main/java/com/example/todoapp/dto/RecipeDetailDTO.java
  5. 13
      backend/src/main/java/com/example/todoapp/dto/RecipeRequestDTO.java
  6. 11
      backend/src/main/java/com/example/todoapp/dto/RecipeResponseDTO.java
  7. 6
      backend/src/main/java/com/example/todoapp/dto/StockDTOResponse.java
  8. 10
      backend/src/main/java/com/example/todoapp/dto/StuffDetailDTO.java
  9. 10
      backend/src/main/java/com/example/todoapp/dto/StuffRequestDTO.java
  10. 12
      backend/src/main/java/com/example/todoapp/model/RecipeStuffs.java
  11. 2
      backend/src/main/java/com/example/todoapp/model/Recipes.java
  12. 18
      backend/src/main/java/com/example/todoapp/repository/RecipeStuffsRepository.java
  13. 7
      backend/src/main/java/com/example/todoapp/repository/RecipesRepository.java
  14. 197
      backend/src/main/java/com/example/todoapp/service/RecipeService.java

@ -0,0 +1,92 @@
package com.example.todoapp.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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.service.RecipeService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@RestController
@RequestMapping("/recipes")
public class RecipesController {
@Autowired
private RecipeService recipeService;
@PostMapping("/add")
public ResponseEntity<Map<String, Object>> addRecipe(@RequestBody RecipeRequestDTO dto) {
Recipes createAllReipes = recipeService.addRecipe(dto);
Map<String, Object> response = new HashMap<>();
response.put("result", true);
response.put("recipeId", createAllReipes.getRecipeId());
response.put("message", "追加に成功しました");
return ResponseEntity.ok(response);
}
@GetMapping("/getAll")
public ResponseEntity<List<RecipeResponseDTO>> getRecipe(Authentication authentication) {
List<Recipes> recipes = recipeService.getAllRecipes();
// エンティティからDTOへの変換
List<RecipeResponseDTO> responseList = recipes.stream()
.map(recipe -> {
RecipeResponseDTO dto = new RecipeResponseDTO();
dto.setRecipeId(recipe.getRecipeId());
dto.setRecipeName(recipe.getRecipeName());
dto.setSummary(recipe.getSummary());
return dto;
})
.collect(Collectors.toList());
return ResponseEntity.ok(responseList);
}
/**
* 指定されたIDの在庫を取得する
*
* @param authentication 認証情報
* @param recipeId 在庫ID
* @return 在庫情報
*/
@GetMapping("/getById")
public ResponseEntity<RecipeDetailDTO> getRecipeById(
Authentication authentication,
@RequestParam Long recipeId) {
recipeService.getRecipeDetailsById(recipeId);
return ResponseEntity.ok(recipeService.getRecipeDetailsById(recipeId));
}
@PutMapping("/update")
public ResponseEntity<Map<String, Object>> updateRecipe(@RequestBody RecipeDetailDTO dto) {
Recipes recipes = recipeService.updateRecipe(dto);
Map<String, Object> response = new HashMap<>();
if (recipes != null) {
response.put("result",true );
response.put("message", "料理リストの編集が完了しました");
} else {
response.put("result", false);
response.put("message", "編集に失敗しました");
}
return ResponseEntity.ok(response);
}
}

@ -1,7 +1,7 @@
package com.example.todoapp.controller;
import com.example.todoapp.dto.DeleteStockRequest;
import com.example.todoapp.dto.ResponseStockDTO;
import com.example.todoapp.dto.StockDTOResponse;
import com.example.todoapp.dto.StockDTO;
import com.example.todoapp.model.Stocks;
import com.example.todoapp.model.User;
@ -43,11 +43,11 @@ public class StocksController {
* @return ユーザーの在庫リスト
*/
@GetMapping("/get")
public ResponseEntity<List<ResponseStockDTO>> getAllStocks(Authentication authentication) {
public ResponseEntity<List<StockDTOResponse>> getAllStocks(Authentication authentication) {
List<Stocks> stocks = stockService.getALLStocksByUser(authentication.getName());
// エンティティからDTOへの変換
List<ResponseStockDTO> stockDTOs = stocks.stream()
.map(ResponseStockDTO::fromEntity)
List<StockDTOResponse> stockDTOs = stocks.stream()
.map(StockDTOResponse::fromEntity)
.collect(Collectors.toList());
return ResponseEntity.ok(stockDTOs);
}

@ -22,7 +22,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;

@ -0,0 +1,14 @@
package com.example.todoapp.dto;
import java.util.List;
import lombok.Data;
@Data
public class RecipeDetailDTO {
private Long recipeId;
private String recipeName;
private String summary;
private List<StuffDetailDTO> stuffs;
}

@ -0,0 +1,13 @@
package com.example.todoapp.dto;
import java.util.List;
import lombok.Data;
@Data
public class RecipeRequestDTO {
private Long recipeId;
private String recipeName;
private String summary;
private List<StuffRequestDTO> stuffAndAmountArray;
}

@ -0,0 +1,11 @@
package com.example.todoapp.dto;
import lombok.Data;
@Data
public class RecipeResponseDTO {
private Long recipeId;
private String recipeName;
private String summary;
}

@ -16,7 +16,7 @@ import java.time.LocalDate;
*/
@Data
public class ResponseStockDTO {
public class StockDTOResponse {
private Long stockId;
private Long stuffId;
private Long userId;
@ -34,8 +34,8 @@ public class ResponseStockDTO {
* @param stock 変換元の在庫エンティティ
* @return 変換されたStockDTOオブジェクト
*/
public static ResponseStockDTO fromEntity(Stocks stock) {
ResponseStockDTO dto = new ResponseStockDTO();
public static StockDTOResponse fromEntity(Stocks stock) {
StockDTOResponse dto = new StockDTOResponse();
Stuffs stuff = stock.getStuff();
dto.setStockId(stock.getStockId());

@ -0,0 +1,10 @@
package com.example.todoapp.dto;
import lombok.Data;
@Data
public class StuffDetailDTO {
private Long stuffId;
private String stuffName;
private Integer amount;
}

@ -0,0 +1,10 @@
package com.example.todoapp.dto;
import lombok.Data;
@Data
public class StuffRequestDTO {
private String stuffId;
private String stuffName;
private String category;
private String amount;
}

@ -1,5 +1,5 @@
//--------------------------------
// RecipiesStuffs.java
// RecipesStuffs.java
//
// 分類:社員管理システムV2・ビジネスロジック層
//
@ -18,7 +18,7 @@ import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -43,7 +43,7 @@ public class RecipeStuffs {
/**
* 料理の一意識別子 FK
*/
@NotBlank
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(
name = "recipeId",
@ -56,7 +56,7 @@ public class RecipeStuffs {
/**
* 材料の一意識別子 FK
*/
@NotBlank
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(
name = "stuffId",
@ -68,8 +68,8 @@ public class RecipeStuffs {
/**
* 材料の数量(デフォルト1)
*/
@NotBlank
@NotNull
@Column(nullable = false)
private int amount = 1;
private Integer amount = 1;
}

@ -43,7 +43,7 @@ public class Recipes {
*/
@NotNull
@Column(name="recipeName", unique = true, length = 255, nullable = false)
private String recipieName;
private String recipeName;
/**
* カテゴリ

@ -0,0 +1,18 @@
package com.example.todoapp.repository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.todoapp.model.RecipeStuffs;
public interface RecipeStuffsRepository extends JpaRepository<RecipeStuffs, Long> {
List<RecipeStuffs> findByRecipesRecipeId(Long recipeId);
Optional<RecipeStuffs> findByRecipesRecipeIdAndStuffStuffId(Long recipeId, Long stuffId);
}

@ -0,0 +1,7 @@
package com.example.todoapp.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.todoapp.model.Recipes;
public interface RecipesRepository extends JpaRepository<Recipes, Long> {}

@ -0,0 +1,197 @@
//--------------------------------
// RecipeService.java
//
//
// 更新履歴:2025/06/05 新規作成
// Copyright(c) 2025 IVIS All rights reserved.
//--------------------------------------------
package com.example.todoapp.service;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.todoapp.dto.RecipeDetailDTO;
import com.example.todoapp.dto.RecipeRequestDTO;
import com.example.todoapp.dto.StuffDetailDTO;
import com.example.todoapp.dto.StuffRequestDTO;
import com.example.todoapp.model.RecipeStuffs;
import com.example.todoapp.model.Recipes;
import com.example.todoapp.model.Stuffs;
import com.example.todoapp.repository.RecipeStuffsRepository;
import com.example.todoapp.repository.RecipesRepository;
import com.example.todoapp.repository.StuffsRepository;
import jakarta.transaction.Transactional;
/**
* レシピ管理サービスクラス
* <p>
* このクラスはレシピの登録処理を提供します
* 材料の存在確認新規作成数量管理などの機能を含みます
* </p>
*/
@Service
public class RecipeService {
@Autowired
private RecipesRepository recipesRepository;
@Autowired
private StuffsRepository stuffsRepository;
@Autowired
private RecipeStuffsRepository recipeStuffsRepository;
/**
* レシピを新規登録する
*
* @param dto レシピ登録情報レシピ名概要材料情報含む
* @return レシピ登録結果成功/失敗レシピID含む
*/
@Transactional // トランザクション管理を実施
public Recipes addRecipe(RecipeRequestDTO dto) {
Recipes recipe = new Recipes();
recipe.setRecipeName(dto.getRecipeName());
recipe.setSummary(dto.getSummary());
recipe = recipesRepository.save(recipe);
List<RecipeStuffs> recipeStuffsList = new ArrayList<>();
for (StuffRequestDTO stuffDTO : dto.getStuffAndAmountArray()) {
Stuffs stuff;
if (stuffDTO.getStuffId() != null && !stuffDTO.getStuffId().isEmpty()) {
// stuffIdが存在する
stuff = stuffsRepository.findById(Long.valueOf(stuffDTO.getStuffId()))
.orElseThrow(() -> new RuntimeException("材料がありません"));
} else {
// stuffIdが存在しない
stuff = new Stuffs();
stuff.setStuffName(stuffDTO.getStuffName());
stuff.setCategory(stuffDTO.getCategory());
stuff = stuffsRepository.save(stuff);
}
RecipeStuffs recipeStuffs = new RecipeStuffs();
recipeStuffs.setRecipes(recipe); // 関連レシピ設定
recipeStuffs.setStuff(stuff); // 関連材料設定
// 数量設定、defaultは1
if (stuffDTO.getAmount() == null || stuffDTO.getAmount().isEmpty()) {
stuffDTO.setAmount("1");
}
recipeStuffs.setAmount(Integer.parseInt(stuffDTO.getAmount()));
recipeStuffsList.add(recipeStuffs);
}
recipeStuffsRepository.saveAll(recipeStuffsList);
return recipe;
}
/**
* 登録済のレシピを取得する
*
* @param authentication 認証情報
* @return 登録済のレシピ情報
*/
public List<Recipes> getAllRecipes() {
return recipesRepository.findAll();
}
/**
* レシピをIDで取得する
*
* @param recipeId 検索するレシピID
* @return 検索結果のレシピ情報
*/
public RecipeDetailDTO getRecipeDetailsById(Long recipeId) {
Recipes recipe = recipesRepository.findById(recipeId)
.orElseThrow(() -> new RuntimeException("レシピが見つかりません"));
List<RecipeStuffs> recipeStuffsList = recipeStuffsRepository.findByRecipesRecipeId(recipeId);
List<StuffDetailDTO> stuffList = recipeStuffsList.stream()
.map(rs -> {
StuffDetailDTO stuffDTO = new StuffDetailDTO();
stuffDTO.setStuffId(rs.getStuff().getStuffId());
stuffDTO.setStuffName(rs.getStuff().getStuffName());
stuffDTO.setAmount(rs.getAmount());
return stuffDTO;
})
.collect(Collectors.toList());
RecipeDetailDTO dto = new RecipeDetailDTO();
dto.setRecipeId(recipe.getRecipeId());
dto.setRecipeName(recipe.getRecipeName());
dto.setSummary(recipe.getSummary());
dto.setStuffs(stuffList);
return dto;
}
@Transactional
public Recipes updateRecipe(RecipeDetailDTO dto) {
Recipes recipe = recipesRepository.findById(dto.getRecipeId())
.orElseThrow(() -> new RuntimeException("レシピが見つかりません"));
recipe.setRecipeName(dto.getRecipeName());
recipe.setSummary(dto.getSummary());
recipesRepository.save(recipe);
Set<Long> incomingStuffIds = new HashSet<>();
for (StuffDetailDTO stuffDTO : dto.getStuffs()) {
if (stuffDTO.getStuffId() == null) {
Stuffs newStuff = new Stuffs();
newStuff.setStuffName(stuffDTO.getStuffName());
newStuff.setCategory("その他");
newStuff = stuffsRepository.save(newStuff);
RecipeStuffs rs = new RecipeStuffs();
rs.setRecipes(recipe);
rs.setStuff(newStuff);
rs.setAmount(stuffDTO.getAmount());
recipeStuffsRepository.save(rs);
incomingStuffIds.add(newStuff.getStuffId());
} else {
Optional<RecipeStuffs> optionalRs = recipeStuffsRepository
.findByRecipesRecipeIdAndStuffStuffId(dto.getRecipeId(), stuffDTO.getStuffId());
if (optionalRs.isPresent()) {
RecipeStuffs rs = optionalRs.get();
rs.setAmount(stuffDTO.getAmount());
recipeStuffsRepository.save(rs);
incomingStuffIds.add(rs.getStuff().getStuffId());
} else {
// 可选:创建新的 RecipeStuffs
Stuffs existingStuff = stuffsRepository.findById(stuffDTO.getStuffId())
.orElseThrow(() -> new RuntimeException("材料が見つかりません"));
RecipeStuffs rs = new RecipeStuffs();
rs.setRecipes(recipe);
rs.setStuff(existingStuff);
rs.setAmount(stuffDTO.getAmount());
recipeStuffsRepository.save(rs);
incomingStuffIds.add(existingStuff.getStuffId());
}
}
}
List<RecipeStuffs> existingStuffs = recipeStuffsRepository.findByRecipesRecipeId(dto.getRecipeId());
for (RecipeStuffs rs : existingStuffs) {
System.out.println("dddddwtestst" + rs.getStuff().getStuffId());
if (!incomingStuffIds.contains(rs.getStuff().getStuffId())) {
recipeStuffsRepository.delete(rs);
}
}
return recipe;
}
}
Loading…
Cancel
Save