feature-backend-add-springdocs
commit
a4db8a5017
@ -0,0 +1,140 @@ |
||||
//--------------------------------
|
||||
// ToBuysController.java
|
||||
//
|
||||
// 更新履歴:2025/06/05 新規作成
|
||||
// Copyright(c) 2025 IVIS All rights reserved.
|
||||
//--------------------------------------------
|
||||
|
||||
package com.example.todoapp.controller; |
||||
|
||||
import com.example.todoapp.dto.DeleteToBuyRequest; |
||||
import com.example.todoapp.dto.ToBuyResponse; |
||||
import com.example.todoapp.dto.ToBuysDTO; |
||||
import com.example.todoapp.model.ToBuys; |
||||
import com.example.todoapp.model.User; |
||||
import com.example.todoapp.repository.UserRepository; |
||||
import com.example.todoapp.service.ToBuysService; |
||||
import jakarta.validation.Valid; |
||||
|
||||
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.security.core.userdetails.UsernameNotFoundException; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
/** |
||||
* 購入リストに関するRESTコントローラー |
||||
* <p> |
||||
* このコントローラーは、購入リスト (to_buys) へのアイテム追加機能を提供します。 |
||||
* リクエストボディには ToBuyDTO 形式のデータが期待されます。 |
||||
* </p> |
||||
*/ |
||||
@RestController |
||||
@RequestMapping("/tobuy") |
||||
public class ToBuysController { |
||||
|
||||
@Autowired |
||||
private ToBuysService toBuysService; |
||||
|
||||
@Autowired |
||||
private UserRepository userRepository; |
||||
|
||||
/** |
||||
* 新しい購入アイテムを追加する |
||||
* |
||||
* @param dto 追加する購入アイテムのデータ(DTO) |
||||
* @return 成功時のレスポンスメッセージ |
||||
*/ |
||||
|
||||
@PostMapping("/add") |
||||
public ResponseEntity<String> addToBuys( |
||||
@Valid @RequestBody ToBuysDTO dto, |
||||
Authentication authentication) { |
||||
toBuysService.addToBuys(dto, authentication); |
||||
return ResponseEntity.ok("Item added to 'To Buys' successfully"); |
||||
} |
||||
|
||||
@PutMapping("/update") |
||||
public ResponseEntity<String> updateToBuys( |
||||
@Valid @RequestBody ToBuysDTO dto, |
||||
Authentication authentication) { |
||||
toBuysService.updateToBuys(dto, authentication); |
||||
return ResponseEntity.ok("Item updated to 'To Buys' successfully"); |
||||
} |
||||
|
||||
|
||||
|
||||
/** |
||||
* 指定されたユーザーIDに基づいてすべての「買うもの」リストを取得する |
||||
* |
||||
* @param userId ユーザーID |
||||
* @return ユーザーに紐づく「買うもの」リスト |
||||
*/ |
||||
@GetMapping("/get") |
||||
public ResponseEntity<?> getAllToBuysByUserId(Authentication authentication) { |
||||
|
||||
// 認証されたユーザー名を取得
|
||||
String username = authentication.getName(); |
||||
|
||||
// ユーザー情報を取得
|
||||
User user = userRepository.findByUsername(username) |
||||
.orElseThrow(() -> new UsernameNotFoundException("User not found")); |
||||
|
||||
List<ToBuys> toBuysList = toBuysService.getToBuysByUserId(user.getId()); |
||||
|
||||
// DTO形式に変換して返す
|
||||
List<ToBuyResponse> responseList = toBuysList.stream() |
||||
.map(toBuy -> { |
||||
ToBuyResponse resp = new ToBuyResponse(); |
||||
resp.setTobuy_id(toBuy.getTobuy_id()); |
||||
resp.setStuff_id(toBuy.getStuffs().getStuff_id()); |
||||
resp.setStuff_name(toBuy.getStuffs().getStuff_name()); |
||||
resp.setAmount(toBuy.getAmount()); |
||||
resp.setShop(toBuy.getStore()); |
||||
return resp; |
||||
}) |
||||
.collect(Collectors.toList()); |
||||
|
||||
Map<String, Object> responseBody = new HashMap<>(); |
||||
responseBody.put("tobuy_array", responseList); |
||||
|
||||
return ResponseEntity.ok(responseList); |
||||
} |
||||
|
||||
/** |
||||
* ユーザーが指定したIDの「買うもの」を削除する |
||||
* |
||||
* @param request 削除する「買うもの」の情報を含むリクエストボディ |
||||
* @return 削除が成功した場合にtrueを含むレスポンス |
||||
*/ |
||||
@DeleteMapping("/delete") |
||||
public ResponseEntity<Map<String, Boolean>> deleteToBuy( |
||||
@RequestBody DeleteToBuyRequest request, |
||||
Authentication authentication) { |
||||
|
||||
// 認証されたユーザー名を取得
|
||||
String username = authentication.getName(); |
||||
|
||||
// ユーザー情報を取得
|
||||
User user = userRepository.findByUsername(username) |
||||
.orElseThrow(() -> new UsernameNotFoundException("User not found")); |
||||
|
||||
int deletedCount = toBuysService.deleteToBuyByIds(user.getId(), request.getTobuy_id()); |
||||
|
||||
Map<String, Boolean> response = new HashMap<>(); |
||||
|
||||
|
||||
if (deletedCount > 0) { |
||||
response.put("result", true); |
||||
} else { |
||||
response.put("result", false); |
||||
} |
||||
|
||||
return ResponseEntity.ok(response); |
||||
} |
||||
} |
||||
@ -0,0 +1,9 @@ |
||||
package com.example.todoapp.dto; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Data |
||||
public class DeleteToBuyRequest { |
||||
private Long user_id; |
||||
private int tobuy_id; |
||||
} |
||||
@ -0,0 +1,12 @@ |
||||
package com.example.todoapp.dto; |
||||
|
||||
import lombok.Data; |
||||
|
||||
@Data |
||||
public class ToBuyResponse { |
||||
private int tobuy_id; |
||||
private Long stuff_id; |
||||
private String stuff_name; |
||||
private int amount; |
||||
private String shop; |
||||
} |
||||
@ -0,0 +1,21 @@ |
||||
package com.example.todoapp.dto; |
||||
|
||||
import lombok.Data; |
||||
/** |
||||
* カテゴリDTOクラス |
||||
* このクラスはタスクのカテゴリ情報を表します。 |
||||
* カテゴリは名前、色、所有ユーザーなどの情報を持ちます。 |
||||
* |
||||
*/ |
||||
|
||||
@Data |
||||
public class ToBuysDTO { |
||||
private Long stuff_id; |
||||
private Long user_id; |
||||
|
||||
private int amount; |
||||
private String shop; |
||||
|
||||
private String stuff_name; |
||||
private String category; |
||||
} |
||||
@ -0,0 +1,74 @@ |
||||
//--------------------------------
|
||||
// RecipiesStuffs.java
|
||||
//
|
||||
// 分類:社員管理システムV2・ビジネスロジック層
|
||||
//
|
||||
// 更新履歴:2025/06/02 新規作成
|
||||
// Copyright(c) 2025 IVIS All rights reserved.
|
||||
//--------------------------------------------
|
||||
|
||||
package com.example.todoapp.model; |
||||
|
||||
import jakarta.persistence.Column; |
||||
import jakarta.persistence.Entity; |
||||
import jakarta.persistence.FetchType; |
||||
import jakarta.persistence.GeneratedValue; |
||||
import jakarta.persistence.GenerationType; |
||||
import jakarta.persistence.Id; |
||||
import jakarta.persistence.JoinColumn; |
||||
import jakarta.persistence.ManyToOne; |
||||
import jakarta.persistence.Table; |
||||
import jakarta.validation.constraints.NotBlank; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* 料理に必要な材料 |
||||
*/ |
||||
@Data |
||||
@NoArgsConstructor |
||||
@Entity |
||||
@Table(name = "recipe_stuffs") |
||||
public class RecipeStuffs { |
||||
|
||||
|
||||
/** |
||||
* 料理に必要リストの一意識別子 |
||||
*/ |
||||
@Id |
||||
@GeneratedValue(strategy = GenerationType.IDENTITY) |
||||
private int recipe_stuffs_id ; |
||||
|
||||
/** |
||||
* 料理の一意識別子 FK |
||||
*/ |
||||
@NotBlank |
||||
@ManyToOne(fetch = FetchType.LAZY) |
||||
@JoinColumn( |
||||
name = "recipe_id", |
||||
referencedColumnName = "recipe_id", |
||||
nullable = false |
||||
) |
||||
private Recipes recipes; |
||||
|
||||
|
||||
/** |
||||
* 材料の一意識別子 FK |
||||
*/ |
||||
@NotBlank |
||||
@ManyToOne(fetch = FetchType.LAZY) |
||||
@JoinColumn( |
||||
name = "stuff_id", |
||||
referencedColumnName = "stuff_id", |
||||
nullable = false |
||||
) |
||||
private Stuffs stuffs; |
||||
|
||||
/** |
||||
* 材料の数量 |
||||
*/ |
||||
@NotBlank |
||||
@Column(nullable = false) |
||||
private int amount; |
||||
|
||||
} |
||||
@ -0,0 +1,53 @@ |
||||
//--------------------------------
|
||||
// Recipes.java
|
||||
//
|
||||
// 分類:社員管理システムV2・ビジネスロジック層
|
||||
//
|
||||
// 更新履歴:2025/06/02 新規作成
|
||||
// Copyright(c) 2025 IVIS All rights reserved.
|
||||
//--------------------------------------------
|
||||
|
||||
package com.example.todoapp.model; |
||||
|
||||
import jakarta.persistence.Column; |
||||
import jakarta.persistence.Entity; |
||||
import jakarta.persistence.GeneratedValue; |
||||
import jakarta.persistence.GenerationType; |
||||
import jakarta.persistence.Id; |
||||
import jakarta.persistence.Table; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* カテゴリエンティティクラス |
||||
* このクラスはタスクのカテゴリ情報を表します。 |
||||
* カテゴリは名前、色、所有ユーザーなどの情報を持ちます。 |
||||
*/ |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@Entity |
||||
@Table(name = "recipes") |
||||
public class Recipes { |
||||
/** |
||||
* カテゴリID(主キー) |
||||
*/ |
||||
@Id |
||||
@GeneratedValue(strategy = GenerationType.IDENTITY) |
||||
private int recipe_id ; |
||||
|
||||
/** |
||||
* カテゴリ名 |
||||
*/ |
||||
@NotNull |
||||
@Column(unique = true, length = 255, nullable = false) |
||||
private String recipie_name; |
||||
|
||||
/** |
||||
* カテゴリ |
||||
*/ |
||||
@Column (columnDefinition = "TEXT") |
||||
private String summary; |
||||
|
||||
} |
||||
@ -0,0 +1,100 @@ |
||||
//--------------------------------
|
||||
// Stocks.java
|
||||
//
|
||||
// 分類:社員管理システムV2・ビジネスロジック層
|
||||
//
|
||||
// 更新履歴:2025/06/03 新規作成
|
||||
// Copyright(c) 2025 IVIS All rights reserved.
|
||||
//--------------------------------------------
|
||||
|
||||
package com.example.todoapp.model; |
||||
|
||||
import java.time.LocalDate; |
||||
|
||||
import jakarta.persistence.Column; |
||||
import jakarta.persistence.Entity; |
||||
import jakarta.persistence.FetchType; |
||||
import jakarta.persistence.GeneratedValue; |
||||
import jakarta.persistence.GenerationType; |
||||
import jakarta.persistence.Id; |
||||
import jakarta.persistence.JoinColumn; |
||||
import jakarta.persistence.ManyToOne; |
||||
import jakarta.persistence.Table; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
|
||||
/** |
||||
* 在庫にある食材 |
||||
*/ |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@Entity |
||||
@Table(name = "stocks") |
||||
public class Stocks { |
||||
/** |
||||
* 在庫リストの一意識別子 |
||||
*/ |
||||
@Id |
||||
@GeneratedValue(strategy = GenerationType.IDENTITY) |
||||
private int stock_id ; |
||||
|
||||
|
||||
/** |
||||
* 商品テーブル参照用の外部キー |
||||
*/ |
||||
@NotNull |
||||
@ManyToOne(fetch = FetchType.LAZY) |
||||
@JoinColumn( |
||||
name = "stuff_id", |
||||
referencedColumnName = "stuff_id", |
||||
nullable = false |
||||
) |
||||
private Stuffs stuffs; |
||||
|
||||
|
||||
/** |
||||
* ユーザーテーブル参照用の外部キー |
||||
*/ |
||||
@NotNull |
||||
@ManyToOne(fetch = FetchType.LAZY) |
||||
@JoinColumn( |
||||
name = "user_id", |
||||
referencedColumnName = "id", |
||||
nullable = false |
||||
) |
||||
private User user_id; |
||||
|
||||
/** |
||||
* 在庫数量(デフォルト値: 1) |
||||
*/ |
||||
@Column(nullable = false) |
||||
private int amount = 1; |
||||
|
||||
/** |
||||
* シングルの値段(デフォルト値: 0) |
||||
*/ |
||||
@Column(nullable = false) |
||||
private int price = 0; |
||||
|
||||
/** |
||||
* 購入日 |
||||
*/ |
||||
@Column(nullable = false) |
||||
private LocalDate buy_date; |
||||
|
||||
/** |
||||
* 最後の操作時間 |
||||
*/ |
||||
@Column(nullable = false) |
||||
private LocalDate last_update; |
||||
|
||||
/** |
||||
* 賞味期限 |
||||
*/ |
||||
@Column(nullable = false) |
||||
private LocalDate exp_date; |
||||
|
||||
} |
||||
@ -0,0 +1,59 @@ |
||||
//--------------------------------
|
||||
// Stuffs.java
|
||||
//
|
||||
// 分類:社員管理システムV2・ビジネスロジック層
|
||||
//
|
||||
// 更新履歴:2025/06/02 新規作成
|
||||
// Copyright(c) 2025 IVIS All rights reserved.
|
||||
//--------------------------------------------
|
||||
|
||||
package com.example.todoapp.model; |
||||
|
||||
import jakarta.persistence.Column; |
||||
import jakarta.persistence.Entity; |
||||
import jakarta.persistence.GeneratedValue; |
||||
import jakarta.persistence.GenerationType; |
||||
import jakarta.persistence.Id; |
||||
import jakarta.persistence.Table; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* カテゴリエンティティクラス |
||||
* このクラスはタスクのカテゴリ情報を表します。 |
||||
* カテゴリは名前、色、所有ユーザーなどの情報を持ちます。 |
||||
*/ |
||||
@Data |
||||
@NoArgsConstructor |
||||
@Entity |
||||
@Table(name = "stuffs") |
||||
public class Stuffs { |
||||
|
||||
/** |
||||
* カテゴリID(主キー) |
||||
*/ |
||||
@Id |
||||
@GeneratedValue(strategy = GenerationType.IDENTITY) |
||||
private Long stuff_id ; |
||||
|
||||
/** |
||||
* カテゴリ名 |
||||
*/ |
||||
@NotNull |
||||
@Column(unique = true, length = 255, nullable = false) |
||||
private String stuff_name; |
||||
|
||||
/** |
||||
* カテゴリ |
||||
*/ |
||||
@Column (columnDefinition = "TEXT") |
||||
private String summary; |
||||
|
||||
/** |
||||
* カテゴリ |
||||
*/ |
||||
@NotNull |
||||
@Column(nullable = false, length = 225) |
||||
private String category = "その他" ; |
||||
} |
||||
@ -0,0 +1,79 @@ |
||||
//--------------------------------
|
||||
// ToBuys.java
|
||||
//
|
||||
//
|
||||
// 更新履歴:2025/06/03 新規作成
|
||||
// Copyright(c) 2025 IVIS All rights reserved.
|
||||
//--------------------------------------------
|
||||
|
||||
package com.example.todoapp.model; |
||||
|
||||
import jakarta.persistence.Column; |
||||
import jakarta.persistence.Entity; |
||||
import jakarta.persistence.FetchType; |
||||
import jakarta.persistence.GeneratedValue; |
||||
import jakarta.persistence.GenerationType; |
||||
import jakarta.persistence.Id; |
||||
import jakarta.persistence.JoinColumn; |
||||
import jakarta.persistence.ManyToOne; |
||||
import jakarta.persistence.Table; |
||||
import jakarta.validation.constraints.NotNull; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* ユーザーの買うものリスト |
||||
*/ |
||||
|
||||
@Data |
||||
@NoArgsConstructor |
||||
@Entity |
||||
@Table(name = "to_buys") |
||||
public class ToBuys { |
||||
|
||||
/** |
||||
* 購入項目の一意識別子 |
||||
*/ |
||||
@Id |
||||
@GeneratedValue(strategy = GenerationType.IDENTITY) |
||||
private int tobuy_id ; |
||||
|
||||
/** |
||||
* 材料の一意識別子 FK |
||||
*/ |
||||
@NotNull |
||||
@ManyToOne(fetch = FetchType.LAZY) |
||||
@JoinColumn( |
||||
name = "stuff_id", |
||||
referencedColumnName = "stuff_id", |
||||
nullable = false |
||||
) |
||||
private Stuffs stuffs; |
||||
|
||||
/** |
||||
* ユーザーテーブル参照用の外部キー |
||||
*/ |
||||
// @NotNull
|
||||
@ManyToOne(fetch = FetchType.LAZY) |
||||
@JoinColumn( |
||||
name = "user_id", |
||||
referencedColumnName = "id" |
||||
) |
||||
private User user_id; |
||||
|
||||
/** |
||||
* 購入する数量 |
||||
*/ |
||||
@NotNull |
||||
@Column(nullable = false) |
||||
private int amount = 1; |
||||
|
||||
/** |
||||
* 購入するお店 |
||||
*/ |
||||
@NotNull |
||||
@Column(nullable = false) |
||||
private String store; |
||||
|
||||
} |
||||
|
||||
@ -0,0 +1,25 @@ |
||||
//--------------------------------
|
||||
// StuffsRepository.java
|
||||
//
|
||||
//
|
||||
// 更新履歴:2025/06/05 新規作成
|
||||
// Copyright(c) 2025 IVIS All rights reserved.
|
||||
//--------------------------------------------
|
||||
|
||||
package com.example.todoapp.repository; |
||||
|
||||
import com.example.todoapp.model.Stuffs; |
||||
import org.springframework.data.jpa.repository.JpaRepository; |
||||
import org.springframework.stereotype.Repository; |
||||
|
||||
/** |
||||
* 材料 (stuffs) テーブルへのアクセスを行うリポジトリ. |
||||
* <p> |
||||
* このクラスは材料テーブル (stuffs) に対する基本的なCRUD操作を提供します。 |
||||
* Spring Data JPAによって自動的に実装されます。 |
||||
* </p> |
||||
*/ |
||||
@Repository |
||||
public interface StuffsRepository extends JpaRepository<Stuffs, Long> { |
||||
// 材料情報を主キーで取得するメソッド(必要に応じて追加)
|
||||
} |
||||
@ -0,0 +1,49 @@ |
||||
//--------------------------------
|
||||
// ToBuysRepository.java
|
||||
//
|
||||
//
|
||||
// 更新履歴:2025/06/05 新規作成
|
||||
// Copyright(c) 2025 IVIS All rights reserved.
|
||||
//--------------------------------------------
|
||||
package com.example.todoapp.repository; |
||||
|
||||
import com.example.todoapp.model.ToBuys; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository; |
||||
import org.springframework.data.jpa.repository.Modifying; |
||||
import org.springframework.data.jpa.repository.Query; |
||||
import org.springframework.data.repository.query.Param; |
||||
import org.springframework.stereotype.Repository; |
||||
|
||||
/** |
||||
* to_buys テーブルへのアクセスを行うリポジトリ |
||||
* <p> |
||||
* このクラスは to_buys テーブルに対する基本的なCRUD操作を提供します。 |
||||
* Spring Data JPAによって自動的に実装されます。 |
||||
* </p> |
||||
*/ |
||||
@Repository |
||||
public interface ToBuysRepository extends JpaRepository<ToBuys, Integer> { |
||||
|
||||
/** |
||||
* 指定されたユーザーIDに基づいて「買うもの」リストを取得する |
||||
* |
||||
* @param userId ユーザーID |
||||
* @return 「買うもの」リスト |
||||
*/ |
||||
@Query("SELECT t FROM ToBuys t WHERE t.user_id.id = ?1") |
||||
List<ToBuys> findByUserId(Long user_id); |
||||
|
||||
/** |
||||
* 指定されたユーザーIDに基づいて「買うもの」リストを取得する |
||||
* |
||||
* @param userId ユーザーID |
||||
* @param tobuyId 「買うもの」ID |
||||
* @return |
||||
*/ |
||||
@Modifying |
||||
@Query("DELETE FROM ToBuys t WHERE t.user_id.id = :userId AND t.tobuy_id = :tobuyId") |
||||
int deleteByUserIdAndTobuyId(@Param("userId") Long userId, @Param("tobuyId") int tobuyId); |
||||
} |
||||
@ -0,0 +1,154 @@ |
||||
//--------------------------------
|
||||
// ToBuysService.java
|
||||
//
|
||||
//
|
||||
// 更新履歴:2025/06/05 新規作成
|
||||
// Copyright(c) 2025 IVIS All rights reserved.
|
||||
//--------------------------------------------
|
||||
|
||||
package com.example.todoapp.service; |
||||
|
||||
import com.example.todoapp.dto.ToBuysDTO; |
||||
import com.example.todoapp.model.Stuffs; |
||||
import com.example.todoapp.model.ToBuys; |
||||
import com.example.todoapp.model.User; |
||||
import com.example.todoapp.repository.StuffsRepository; |
||||
import com.example.todoapp.repository.ToBuysRepository; |
||||
import com.example.todoapp.repository.UserRepository; |
||||
|
||||
import jakarta.transaction.Transactional; |
||||
|
||||
import org.springframework.security.core.Authentication; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
/** |
||||
* 購入リストのサービスクラス |
||||
* <p> |
||||
* このクラスは、購入リスト (to_buys) の登録処理を提供します。 |
||||
* 材料 (stuffs) の存在確認と新規作成、ユーザー情報の取得などを行います。 |
||||
* </p> |
||||
*/ |
||||
|
||||
@Service |
||||
public class ToBuysService { |
||||
|
||||
@Autowired |
||||
private ToBuysRepository toBuysRepository; |
||||
|
||||
@Autowired |
||||
private UserRepository userRepository; |
||||
|
||||
@Autowired |
||||
private StuffsRepository stuffsRepository; |
||||
|
||||
|
||||
/** |
||||
* 購入リストに新しいアイテムを追加する |
||||
* |
||||
* @param toBuyDTO 追加する購入アイテムのデータ(DTO) |
||||
*/ |
||||
public void addToBuys(ToBuysDTO toBuyDTO, Authentication authentication) { |
||||
|
||||
// ユーザー情報を取得
|
||||
String username = authentication.getName(); |
||||
User user = userRepository.findByUsername(username) |
||||
.orElseThrow(() -> new RuntimeException("ユーザーが見つかりません: " + username)); |
||||
|
||||
Stuffs stuffs; |
||||
if (toBuyDTO.getStuff_id() == null) { |
||||
// 新しい材料を作成
|
||||
stuffs = new Stuffs(); |
||||
stuffs.setStuff_name(toBuyDTO.getStuff_name()); |
||||
stuffs.setCategory(toBuyDTO.getCategory()); |
||||
stuffs = stuffsRepository.save(stuffs); |
||||
} else { |
||||
// 材料情報を取得
|
||||
Optional<Stuffs> optionalStuffs = stuffsRepository.findById(toBuyDTO.getStuff_id()); |
||||
if (!optionalStuffs.isPresent()) { |
||||
throw new RuntimeException("材料がありません"); |
||||
} |
||||
stuffs = optionalStuffs.get(); |
||||
} |
||||
|
||||
ToBuys toBuys = new ToBuys(); |
||||
toBuys.setUser_id(user); |
||||
toBuys.setStuffs(stuffs); |
||||
toBuys.setAmount(toBuyDTO.getAmount()); |
||||
toBuys.setStore(toBuyDTO.getShop()); |
||||
|
||||
// データベースに保存
|
||||
toBuysRepository.save(toBuys); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 購入リストに新しいアイテムを変更する |
||||
* |
||||
* @param toBuyDTO 変更する購入アイテムのデータ(DTO) |
||||
*/ |
||||
public void updateToBuys(ToBuysDTO toBuyDTO, Authentication authentication) { |
||||
|
||||
// ユーザー情報を取得
|
||||
String username = authentication.getName(); |
||||
User user = userRepository.findByUsername(username) |
||||
.orElseThrow(() -> new RuntimeException("ユーザーが見つかりません: " + username)); |
||||
|
||||
Stuffs stuffs; |
||||
if (toBuyDTO.getStuff_id() == null) { |
||||
// 新しい材料を作成
|
||||
stuffs = new Stuffs(); |
||||
stuffs.setStuff_name(toBuyDTO.getStuff_name()); |
||||
stuffs.setCategory(toBuyDTO.getCategory()); |
||||
stuffs = stuffsRepository.save(stuffs); |
||||
} else { |
||||
// 材料情報を取得
|
||||
Optional<Stuffs> optionalStuffs = stuffsRepository.findById(toBuyDTO.getStuff_id()); |
||||
if (!optionalStuffs.isPresent()) { |
||||
throw new RuntimeException("材料がありません"); |
||||
} |
||||
stuffs = optionalStuffs.get(); |
||||
|
||||
//update
|
||||
// stuffs.setStuff_name(toBuyDTO.getStuff_name());
|
||||
// stuffs.setCategory(toBuyDTO.getCategory());
|
||||
stuffs = stuffsRepository.save(stuffs); |
||||
} |
||||
|
||||
|
||||
|
||||
ToBuys toBuys = new ToBuys(); |
||||
toBuys.setUser_id(user); |
||||
toBuys.setStuffs(stuffs); |
||||
toBuys.setAmount(toBuyDTO.getAmount()); |
||||
toBuys.setStore(toBuyDTO.getShop()); |
||||
|
||||
// データベースに保存
|
||||
toBuysRepository.save(toBuys); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 指定されたユーザーIDに基づいてすべての「買うもの」リストを取得する |
||||
* |
||||
* @param userId ユーザーID |
||||
* @return ユーザーに紐づく「買うもの」リスト |
||||
*/ |
||||
public List<ToBuys> getToBuysByUserId(Long userId) { |
||||
return toBuysRepository.findByUserId(userId); |
||||
} |
||||
|
||||
/** |
||||
* 指定されたユーザーIDと購入リストIDに基づいて「買うもの」を削除する |
||||
* |
||||
* @param userId ユーザーID |
||||
* @param tobuyId 購入リストID |
||||
*/ |
||||
@Transactional |
||||
public int deleteToBuyByIds(Long userId, int tobuyId) { |
||||
return toBuysRepository.deleteByUserIdAndTobuyId(userId, tobuyId); |
||||
} |
||||
} |
||||
@ -0,0 +1,82 @@ |
||||
import React, { useState } from 'react'; |
||||
import { useNavigate } from 'react-router-dom'; |
||||
import {
|
||||
AppBar,
|
||||
Toolbar,
|
||||
Typography,
|
||||
Container,
|
||||
Box,
|
||||
Button,
|
||||
Drawer, |
||||
List, |
||||
ListItemText, |
||||
ListItemIcon, |
||||
ListItemButton, |
||||
Divider, |
||||
IconButton, |
||||
TextField, |
||||
Paper, |
||||
Alert, |
||||
Link, |
||||
Grid, |
||||
} from '@mui/material'; |
||||
import { LoginCredentials } from '../types/types'; |
||||
import { authApi } from '../services/api'; |
||||
import { GENERAL_ERRORS } from '../constants/errorMessages'; |
||||
|
||||
const AddDishes1: React.FC = () => { |
||||
const navigate = useNavigate(); |
||||
const [dish, setDish] = useState(""); |
||||
// エラーメッセージの状態管理
|
||||
const [error, setError] = useState(false); |
||||
|
||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { |
||||
setDish(event.target.value); |
||||
}; |
||||
const handleSubmit = async (e: React.FormEvent) => { |
||||
e.preventDefault(); // フォームのデフォルト送信動作を防止
|
||||
if (!dish.trim()) { |
||||
alert("エラー"); |
||||
setError(true); |
||||
} else { |
||||
alert("送信成功!"); |
||||
localStorage.setItem("dishName", dish); // ローカルストレージにフォームに入力された料理名を保存
|
||||
navigate('/add2', { state: dish }); // 料理名から材料名追加ページにリダイレクト
|
||||
} |
||||
}; |
||||
|
||||
return ( |
||||
<div> |
||||
<Typography variant="h4" component="h1" gutterBottom> |
||||
料理の追加・編集 |
||||
</Typography> |
||||
<Box component="form" onSubmit={handleSubmit}> |
||||
<div style={{ border: '3px solid black', borderRadius: '8px', backgroundColor: '#add8e6', height: 'auto', padding: '10px', textAlign: 'center'}}> |
||||
<TextField |
||||
required |
||||
// id="username"
|
||||
label="追加・編集したい料理名を入力" |
||||
variant="outlined" |
||||
InputLabelProps={{ style: { fontSize: "40px" }}} |
||||
style={{width: "80%" }} |
||||
InputProps={{ style: { fontSize: "40px"} }} |
||||
name="dish_name" |
||||
// autoComplete="username"
|
||||
autoFocus |
||||
value={dish} |
||||
onChange={handleChange} |
||||
error={error} |
||||
helperText={error ? "入力が必要です" : ""} |
||||
/> |
||||
</div> |
||||
<div style={{position: "fixed", left: "75%", transform: 'translateX(-50%)', bottom: "10px"}}> |
||||
<Button type="submit" variant='contained' sx={{ width: "250px", height: "60px", fontSize: "40px" }} color="primary" > |
||||
編集・追加 |
||||
</Button> |
||||
</div> |
||||
</Box> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default AddDishes1; |
||||
@ -0,0 +1,279 @@ |
||||
/** |
||||
* テストページコンポーネント |
||||
* 白紙の状態で表示されるテスト用のページ |
||||
*/ |
||||
import React, { useState, useEffect } from 'react'; |
||||
import { taskApi, toBuyApi } from '../services/api'; |
||||
import {
|
||||
Container, |
||||
Typography, |
||||
Tooltip, |
||||
List, |
||||
ListItem, |
||||
ListItemText, |
||||
ListItemSecondaryAction, |
||||
IconButton, |
||||
Checkbox, |
||||
Fab, |
||||
Dialog, |
||||
DialogTitle, |
||||
DialogContent, |
||||
DialogActions, |
||||
TextField, |
||||
Button, |
||||
Box, |
||||
MenuItem, |
||||
Select, |
||||
FormControl, |
||||
InputLabel |
||||
} from '@mui/material'; |
||||
import { |
||||
Add as AddIcon, Delete as DeleteIcon, ShoppingBasket as ShoppingBasketIcon, |
||||
SoupKitchen as SoupKitchenIcon |
||||
} from '@mui/icons-material'; |
||||
import { Task } from '../types/types'; |
||||
import { TASK_ERRORS } from '../constants/errorMessages'; |
||||
import { GENERAL_ERRORS } from '../constants/errorMessages'; |
||||
import CategoryDropDown from "../components/CategoryDropDown"; |
||||
|
||||
// 新規タスクの初期状態(画面表示用)
|
||||
const EMPTY_TASK = { id: 0, title: '', amount: 0, completed: false }; |
||||
|
||||
// 新規タスクの初期状態(データベース登録用)
|
||||
const EMPTY_TASK_DATA_BASE = { id: 0, title: '', amount: 0, completed: false }; |
||||
|
||||
interface Empty_Task { |
||||
title: string; // 食材名
|
||||
amount: number; // 食材の個数
|
||||
completed: boolean; //
|
||||
} |
||||
|
||||
const AddDishes2: React.FC = () => { |
||||
const receivedData = localStorage.getItem("dishName"); |
||||
// タスク一覧の状態管理
|
||||
const [tasks, setTasks] = useState<Task[]>([]); |
||||
|
||||
const [addtasks, setAddTasks] = useState<Empty_Task[]>([]); |
||||
// エラーメッセージの状態管理
|
||||
const [error, setError] = useState(false); |
||||
// 新規タスク作成ダイアログの表示状態
|
||||
const [openDialog, setOpenDialog] = useState(false); |
||||
// 新規タスクの入力内容
|
||||
const [newTask, setNewTask] = useState(EMPTY_TASK); |
||||
|
||||
// コンポーネントマウント時にタスク一覧を取得
|
||||
useEffect(() => { |
||||
fetchTasks(); |
||||
}, []); |
||||
|
||||
/** |
||||
* APIからタスク一覧を取得する関数 |
||||
* 取得したタスクをstate(tasks)に設定 |
||||
*/ |
||||
const fetchTasks = async () => { |
||||
try { |
||||
const tasks = await taskApi.getTasks(); |
||||
setTasks(tasks); |
||||
} catch (error) { |
||||
console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error); |
||||
} |
||||
}; |
||||
/** |
||||
* タスクを削除するハンドラー |
||||
* 指定されたIDのタスクをAPIを通じて削除 |
||||
*/ |
||||
const handleDeleteTask = async (index: number) => { |
||||
try { |
||||
let newAddTasks = [...addtasks]; // 配列をコピー
|
||||
newAddTasks.splice(index, 1); |
||||
setAddTasks(newAddTasks); |
||||
// fetchTasks(); // 削除後のタスク一覧を再取得
|
||||
} catch (error) { |
||||
console.error(`${TASK_ERRORS.DELETE_FAILED}:`, error); |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* 新規タスクを作成するハンドラー |
||||
* 入力されたタスク情報をAPIに送信して新規作成 |
||||
* 作成後はダイアログを閉じ、入力内容をリセット |
||||
*/ |
||||
const handleSubmit = async (e: React.FormEvent) => { |
||||
e.preventDefault(); // フォームのデフォルト送信動作を防止
|
||||
if (addtasks[0] == null) { |
||||
setError(true); |
||||
alert("食材を追加してください"); |
||||
} else { |
||||
alert("送信成功!"); |
||||
handleCreateTask_DataBase(); |
||||
// localStorage.setItem("dishName", dish); // ローカルストレージにフォームに入力された料理名を保存
|
||||
// navigate('/add2', { state: dish }); // 料理名から材料名追加ページにリダイレクト
|
||||
} |
||||
}; |
||||
const handleCreateTask_Temp = async () => { |
||||
try { |
||||
// await taskApi.createTask(newTask);
|
||||
let newAddTasks = [...addtasks]; // 配列をコピー
|
||||
newAddTasks.push(newTask); |
||||
setAddTasks(newAddTasks); |
||||
setOpenDialog(false); // ダイアログを閉じる
|
||||
setNewTask(EMPTY_TASK); // 入力内容をリセット
|
||||
// fetchTasks(); // 作成後のタスク一覧を再取得
|
||||
} catch (error) { |
||||
console.error(`${TASK_ERRORS.CREATE_FAILED}:`, error); |
||||
} |
||||
}; |
||||
|
||||
const handleCreateTask_DataBase = async () => { |
||||
try { |
||||
// for (let i = 0; i < addtasks.length; i++) {
|
||||
// // await taskApi.createTask(addtasks[i]);
|
||||
// await toBuyApi.addToBuy(addtasks[i]);
|
||||
// }
|
||||
setOpenDialog(false); // ダイアログを閉じる
|
||||
setNewTask(EMPTY_TASK); // 入力内容をリセット
|
||||
// fetchTasks(); // 作成後のタスク一覧を再取得
|
||||
} catch (error) { |
||||
console.error(`${TASK_ERRORS.CREATE_FAILED}:`, error); |
||||
} |
||||
}; |
||||
|
||||
return ( |
||||
<Box> |
||||
<div> |
||||
<h1>追加する料理名</h1> |
||||
<p style={{fontSize: "40px"}}>{receivedData}</p> |
||||
</div> |
||||
<List> |
||||
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */} |
||||
{addtasks.map((task, index) => ( |
||||
<ListItem |
||||
key={index} |
||||
sx={{ |
||||
bgcolor: 'background.paper', |
||||
mb: 1, |
||||
borderRadius: 1, |
||||
boxShadow: 1, |
||||
}} |
||||
> |
||||
{/* タスク完了状態を切り替えるチェックボックス |
||||
<Checkbox |
||||
checked={task.completed} |
||||
onChange={() => handleToggleComplete(task.id)} |
||||
/> */} |
||||
{/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */} |
||||
<ListItemText |
||||
primary={task.title} |
||||
// secondary={task.description}
|
||||
sx={{ |
||||
textDecoration: task.completed ? 'line-through' : 'none', |
||||
}} |
||||
/> |
||||
{/* 食材の個数を表示 */} |
||||
<ListItemText |
||||
primary={<Typography style={{textAlign:"center"}}>個数<br /> |
||||
{task.amount} |
||||
</Typography> |
||||
} |
||||
// secondary={task.description}
|
||||
primaryTypographyProps={{ align: "right", marginRight: "20%", fontSize: "20px" }} |
||||
/> |
||||
{/* 買い物リスト:食材情報記入ボタン */} |
||||
<ListItemSecondaryAction> |
||||
<Tooltip title="食材情報追加"> |
||||
<IconButton |
||||
edge="end" |
||||
aria-label="食材情報追加" |
||||
//onClick={() => handleDeleteTask(task.id)}
|
||||
> |
||||
<ShoppingBasketIcon /> |
||||
</IconButton> |
||||
</Tooltip> |
||||
{/* 買い物リスト:食材削除ボタン */} |
||||
<Tooltip title="項目を削除" |
||||
componentsProps={{ |
||||
tooltip: { |
||||
sx: { |
||||
backgroundColor: "white", |
||||
color: "red", |
||||
fontSize: "0.8rem", |
||||
padding: "6px", |
||||
borderRadius: "6px", |
||||
}, |
||||
}, |
||||
}} |
||||
> |
||||
|
||||
<IconButton |
||||
edge="end" |
||||
aria-label="delete" |
||||
onClick={() => handleDeleteTask(index)} |
||||
> |
||||
<DeleteIcon /> |
||||
</IconButton> |
||||
</Tooltip> |
||||
</ListItemSecondaryAction> |
||||
|
||||
</ListItem> |
||||
))} |
||||
</List> |
||||
<div style={{position: "fixed", left: "75%", transform: 'translateX(-50%)', bottom: "20%"}}> |
||||
<Button variant='contained' sx={{ width: "250px", height: "60px", fontSize: "40px" }}
|
||||
color="primary" onClick={() => setOpenDialog(true)}> |
||||
食材の追加 |
||||
</Button> |
||||
</div> |
||||
<div style={{position: "fixed", width: "60%", left: "50%", transform: 'translateX(-50%)', bottom: "2%"}}> |
||||
<Button variant='contained' sx={{ width: "100%", height: "100px", fontSize: "40px" }}
|
||||
color="primary" onClick={handleSubmit}> |
||||
料理リストへ追加 |
||||
</Button> |
||||
</div> |
||||
{/* 新規タスク作成ダイアログ */} |
||||
<Dialog open={openDialog} onClose={() => setOpenDialog(false)} disableScrollLock={true}> |
||||
<DialogTitle>材料の追加</DialogTitle> |
||||
<DialogContent> |
||||
<Box sx={{ pt: 1 }}> |
||||
{/*材料カテゴリ選択 */} |
||||
<CategoryDropDown></CategoryDropDown> |
||||
{/* タスクタイトル入力フィールド */} |
||||
<TextField |
||||
autoFocus |
||||
margin="dense" |
||||
label="材料名" |
||||
fullWidth |
||||
value={newTask.title} |
||||
onChange={(e) => setNewTask({ ...newTask, title: e.target.value })} |
||||
sx={{ marginBottom: 2 }} |
||||
/> |
||||
{/* 数量入力フィールド */} |
||||
<TextField |
||||
margin="dense" |
||||
label="数量" |
||||
fullWidth |
||||
value={newTask.amount} |
||||
onChange={(e) => { |
||||
const value = e.target.value; |
||||
const parsedValue = parseInt(value, 10); // 数値に変換
|
||||
if (!isNaN(parsedValue)) { |
||||
setNewTask({ ...newTask, amount: parsedValue }); // number型で保存
|
||||
} |
||||
}} |
||||
sx={{ width: "20%" }} |
||||
type="number" |
||||
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }} // ここで整数のみ許可
|
||||
/> |
||||
</Box> |
||||
</DialogContent> |
||||
<DialogActions> |
||||
<Button onClick={() => setOpenDialog(false)}>キャンセル</Button> |
||||
<Button onClick={handleCreateTask_Temp} variant="contained"> |
||||
追加 |
||||
</Button> |
||||
</DialogActions> |
||||
</Dialog> |
||||
</Box> |
||||
); |
||||
}; |
||||
|
||||
export default AddDishes2; |
||||
@ -0,0 +1,12 @@ |
||||
import React from 'react'; |
||||
import { Box } from '@mui/material'; |
||||
|
||||
const TestPage: React.FC = () => { |
||||
return ( |
||||
<Box> |
||||
{/* 白紙のページ - 何も表示しない */} |
||||
</Box> |
||||
); |
||||
}; |
||||
|
||||
export default TestPage; |
||||
Loading…
Reference in new issue