diff --git a/book-rent/src/main/java/com/example/demo/controller/AdminBookController.java b/book-rent/src/main/java/com/example/demo/controller/AdminBookController.java index e21502e..33246bb 100644 --- a/book-rent/src/main/java/com/example/demo/controller/AdminBookController.java +++ b/book-rent/src/main/java/com/example/demo/controller/AdminBookController.java @@ -20,106 +20,108 @@ import com.example.demo.service.BookAdminService; /** BOOK-02 書籍登録 / BOOK-03 書籍編集(管理者のみ:/admin/** で拒否)。入力 → 確認 → 完了 */ @Controller public class AdminBookController { - private static final String NEW = "/admin/books/new"; - private static final String EDIT = "/admin/books/edit"; + private static final String NEW = "/admin/books/new"; + private static final String EDIT = "/admin/books/edit"; - private final BookAdminService bookAdminService; + private final BookAdminService bookAdminService; - public AdminBookController(BookAdminService bookAdminService) { - this.bookAdminService = bookAdminService; - } + public AdminBookController(BookAdminService bookAdminService) { + this.bookAdminService = bookAdminService; + } - // ===== BOOK-02 登録 ===== - @GetMapping(NEW) - public String newInput(Model model) { - return input(new BookForm(), List.of(), "書籍登録", NEW, model); - } + // ===== BOOK-02 登録 ===== + @GetMapping(NEW) + public String newInput(Model model) { + return input(new BookForm(), List.of(), "書籍登録", NEW, model); + } - @PostMapping(NEW + "/input") - public String newBack(@ModelAttribute("form") BookForm form, Model model) { - return input(form, List.of(), "書籍登録", NEW, model); - } + @PostMapping(NEW + "/input") + public String newBack(@ModelAttribute("form") BookForm form, Model model) { + return input(form, List.of(), "書籍登録", NEW, model); + } - @PostMapping(NEW + "/confirm") - public String newConfirm(@ModelAttribute("form") BookForm form, Model model) { - List errors = bookAdminService.validate(form); - if (!errors.isEmpty()) return input(form, errors, "書籍登録", NEW, model); - return confirm("書籍登録", NEW, model); - } + @PostMapping(NEW + "/confirm") + public String newConfirm(@ModelAttribute("form") BookForm form, Model model) { + List errors = bookAdminService.validate(form); + if (!errors.isEmpty()) + return input(form, errors, "書籍登録", NEW, model); + return confirm("書籍登録", NEW, model); + } - @PostMapping(NEW + "/execute") - public String newExecute(@ModelAttribute("form") BookForm form, - @SessionAttribute(Const.SESSION_LOGIN_USER) LoginUser admin, - Model model, RedirectAttributes ra) { - try { - bookAdminService.register(form, admin); - } catch (BusinessException e) { - return input(form, List.of(e.getMessage()), "書籍登録", NEW, model); - } - ra.addFlashAttribute("message", "書籍登録が完了しました。"); - return "redirect:" + NEW + "/complete"; - } + @PostMapping(NEW + "/execute") + public String newExecute(@ModelAttribute("form") BookForm form, + @SessionAttribute(Const.SESSION_LOGIN_USER) LoginUser admin, + Model model, RedirectAttributes ra) { + try { + bookAdminService.register(form, admin); + } catch (BusinessException e) { + return input(form, List.of(e.getMessage()), "書籍登録", NEW, model); + } + ra.addFlashAttribute("message", "書籍登録が完了しました。"); + return "redirect:" + NEW + "/complete"; + } - @GetMapping(NEW + "/complete") - public String newComplete(Model model) { - model.addAttribute("backUrl", "/books"); - model.addAttribute("backLabel", "書籍一覧に戻る"); - return "complete"; - } + @GetMapping(NEW + "/complete") + public String newComplete(Model model) { + model.addAttribute("backUrl", "/books"); + model.addAttribute("backLabel", "書籍一覧に戻る"); + return "complete"; + } - // ===== BOOK-03 編集 ===== - @GetMapping(EDIT) - public String editInput(@RequestParam Integer idBook, Model model, RedirectAttributes ra) { - try { - BookForm form = bookAdminService.toForm(bookAdminService.find(idBook)); - return input(form, List.of(), "書籍編集", EDIT, model); - } catch (BusinessException e) { - ra.addFlashAttribute("errorMessage", e.getMessage()); - return "redirect:/books"; - } - } + // ===== BOOK-03 編集 ===== + @GetMapping(EDIT) + public String editInput(@RequestParam Integer idBook, Model model, RedirectAttributes ra) { + try { + BookForm form = bookAdminService.toForm(bookAdminService.find(idBook)); + return input(form, List.of(), "書籍編集", EDIT, model); + } catch (BusinessException e) { + ra.addFlashAttribute("errorMessage", e.getMessage()); + return "redirect:/books"; + } + } - @PostMapping(EDIT + "/input") - public String editBack(@ModelAttribute("form") BookForm form, Model model) { - return input(form, List.of(), "書籍編集", EDIT, model); - } + @PostMapping(EDIT + "/input") + public String editBack(@ModelAttribute("form") BookForm form, Model model) { + return input(form, List.of(), "書籍編集", EDIT, model); + } - @PostMapping(EDIT + "/confirm") - public String editConfirm(@ModelAttribute("form") BookForm form, Model model) { - List errors = bookAdminService.validate(form); - if (!errors.isEmpty()) return input(form, errors, "書籍編集", EDIT, model); - return confirm("書籍編集", EDIT, model); - } + @PostMapping(EDIT + "/confirm") + public String editConfirm(@ModelAttribute("form") BookForm form, Model model) { + List errors = bookAdminService.validate(form); + if (!errors.isEmpty()) + return input(form, errors, "書籍編集", EDIT, model); + return confirm("書籍編集", EDIT, model); + } - @PostMapping(EDIT + "/execute") - public String editExecute(@ModelAttribute("form") BookForm form, - @SessionAttribute(Const.SESSION_LOGIN_USER) LoginUser admin, - Model model, RedirectAttributes ra) { - try { - bookAdminService.update(form, admin); - } catch (BusinessException e) { - return input(form, List.of(e.getMessage()), "書籍編集", EDIT, model); - } - ra.addFlashAttribute("message", "書籍編集が完了しました。"); - return "redirect:" + EDIT + "/complete"; - } + @PostMapping(EDIT + "/execute") + public String editExecute(@ModelAttribute("form") BookForm form, + @SessionAttribute(Const.SESSION_LOGIN_USER) LoginUser admin, + Model model, RedirectAttributes ra) { + try { + bookAdminService.update(form, admin); + } catch (BusinessException e) { + return input(form, List.of(e.getMessage()), "書籍編集", EDIT, model); + } + ra.addFlashAttribute("message", "書籍編集が完了しました。"); + return "redirect:" + EDIT + "/complete"; + } - @GetMapping(EDIT + "/complete") - public String editComplete(Model model) { - return newComplete(model); - } + @GetMapping(EDIT + "/complete") + public String editComplete(Model model) { + return newComplete(model); + } - private String input(BookForm form, List errors, String title, String base, Model model) { - model.addAttribute("form", form); - model.addAttribute("errors", errors); - model.addAttribute("title", title); - model.addAttribute("base", base); - return "bookInput"; - } + private String input(BookForm form, List errors, String title, String base, Model model) { + model.addAttribute("form", form); + model.addAttribute("errors", errors); + model.addAttribute("title", title); + model.addAttribute("base", base); + return "bookInput"; + } - private String confirm(String title, String base, Model model) { - model.addAttribute("title", title); - model.addAttribute("base", base); - return "bookConfirm"; - } + private String confirm(String title, String base, Model model) { + model.addAttribute("title", title); + model.addAttribute("base", base); + return "bookConfirm"; + } } diff --git a/book-rent/src/main/java/com/example/demo/controller/BookController.java b/book-rent/src/main/java/com/example/demo/controller/BookController.java index 8fa56a3..e401e80 100644 --- a/book-rent/src/main/java/com/example/demo/controller/BookController.java +++ b/book-rent/src/main/java/com/example/demo/controller/BookController.java @@ -1,39 +1,46 @@ package com.example.demo.controller; +import java.util.List; +import java.util.stream.IntStream; - - - - +import org.springframework.data.domain.Page; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; +import com.example.demo.entity.BookCollection; import com.example.demo.service.BookService; - /** BOOK-01:書籍検索(bookList.html) */ @Controller public class BookController { - private final BookService bookService; + private final BookService bookService; - public BookController(BookService bookService) { - this.bookService = bookService; - } + public BookController(BookService bookService) { + this.bookService = bookService; + } - /** メニューの「書籍一覧」=条件なし(全件)、検索ボタン=条件付きで同じURLを使う */ - @GetMapping("/books") - public String list(@RequestParam(defaultValue = "") String nmBook, - @RequestParam(defaultValue = "") String publisher, - @RequestParam(defaultValue = "") String note, - Model model) { - model.addAttribute("books", bookService.searchLendable(nmBook, publisher, note)); - // 検索条件を保持 - model.addAttribute("nmBook", nmBook); - model.addAttribute("publisher", publisher); - model.addAttribute("note", note); - return "bookList"; - } + /** メニューの「書籍一覧」=条件なし(全件)、検索ボタン=条件付きで同じURLを使う */ + @GetMapping("/books") + public String list(@RequestParam(defaultValue = "") String nmBook, + @RequestParam(defaultValue = "") String publisher, + @RequestParam(defaultValue = "") String note, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "10") int size, + Model model) { + + Page bookPage = bookService.searchLendable(nmBook, publisher, note, page, size); + List pageNumbers = IntStream.range(0, bookPage.getTotalPages()).boxed().toList(); + + model.addAttribute("books", bookPage); + model.addAttribute("bookPage", bookPage); + model.addAttribute("pageNumbers", pageNumbers); + // 検索条件を保持 + model.addAttribute("nmBook", nmBook); + model.addAttribute("publisher", publisher); + model.addAttribute("note", note); + return "bookList"; + } } diff --git a/book-rent/src/main/java/com/example/demo/controller/EmployeeController.java b/book-rent/src/main/java/com/example/demo/controller/EmployeeController.java index b358d4e..6ad0a26 100644 --- a/book-rent/src/main/java/com/example/demo/controller/EmployeeController.java +++ b/book-rent/src/main/java/com/example/demo/controller/EmployeeController.java @@ -46,7 +46,8 @@ public class EmployeeController { } @PostMapping(NEW + "/confirm") - public String registConfirm(@ModelAttribute("form") EmployeeForm form, Model model) { + public String registConfirm(@ModelAttribute("form") EmployeeForm form, + Model model) { List errors = employeeService.validateRegist(form); if (!errors.isEmpty()) return registView(form, errors, model); diff --git a/book-rent/src/main/java/com/example/demo/form/EmployeeForm.java b/book-rent/src/main/java/com/example/demo/form/EmployeeForm.java index fde4b39..469491a 100644 --- a/book-rent/src/main/java/com/example/demo/form/EmployeeForm.java +++ b/book-rent/src/main/java/com/example/demo/form/EmployeeForm.java @@ -1,5 +1,7 @@ package com.example.demo.form; + + /** 社員登録・編集フォーム */ public class EmployeeForm { private Integer idEmployee; diff --git a/book-rent/src/main/java/com/example/demo/repository/BookCollectionRepository.java b/book-rent/src/main/java/com/example/demo/repository/BookCollectionRepository.java index 99f7949..9e84087 100644 --- a/book-rent/src/main/java/com/example/demo/repository/BookCollectionRepository.java +++ b/book-rent/src/main/java/com/example/demo/repository/BookCollectionRepository.java @@ -1,8 +1,9 @@ package com.example.demo.repository; import java.time.LocalDateTime; -import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -22,10 +23,12 @@ public interface BookCollectionRepository extends JpaRepository search(@Param("lending") String lending, + Page search( + @Param("lending") String lending, @Param("nm") String nm, @Param("publisher") String publisher, - @Param("note") String note); + @Param("note") String note, + Pageable pageable); /** * 貸出フラグを from → to に更新する(現在値が from のときだけ更新)。 diff --git a/book-rent/src/main/java/com/example/demo/service/BookService.java b/book-rent/src/main/java/com/example/demo/service/BookService.java index b54cba4..a021ae8 100644 --- a/book-rent/src/main/java/com/example/demo/service/BookService.java +++ b/book-rent/src/main/java/com/example/demo/service/BookService.java @@ -1,7 +1,7 @@ package com.example.demo.service; -import java.util.List; - +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -12,22 +12,24 @@ import com.example.demo.repository.BookCollectionRepository; /** BOOK-01:書籍検索 */ @Service public class BookService { - private final BookCollectionRepository bookRepository; + private final BookCollectionRepository bookRepository; - public BookService(BookCollectionRepository bookRepository) { - this.bookRepository = bookRepository; - } + public BookService(BookCollectionRepository bookRepository) { + this.bookRepository = bookRepository; + } - /** 貸出可の蔵書を検索する。全て未入力なら全件。 */ - @Transactional(readOnly = true) - public List searchLendable(String nmBook, String publisher, String note) { - return bookRepository.search(Const.LENDING_OK, normalize(nmBook), normalize(publisher), normalize(note)); - } + /** 貸出可の蔵書を検索する。全て未入力なら全件。 */ + @Transactional(readOnly = true) + public Page searchLendable(String nmBook, String publisher, String note, int page, int size) { + return bookRepository.search(Const.LENDING_OK, normalize(nmBook), normalize(publisher), normalize(note), + PageRequest.of(page, size)); + } - /** 前後の空白除去+LIKE特殊文字(! % _)のエスケープ(エスケープ文字は '!') */ - static String normalize(String s) { - if (s == null) return ""; - return s.trim().replace("!", "!!").replace("%", "!%").replace("_", "!_"); - } -} + /** 前後の空白除去+LIKE特殊文字(! % _)のエスケープ(エスケープ文字は '!') */ + static String normalize(String s) { + if (s == null) + return ""; + return s.trim().replace("!", "!!").replace("%", "!%").replace("_", "!_"); + } +} \ No newline at end of file diff --git a/book-rent/src/main/resources/static/css/style.css b/book-rent/src/main/resources/static/css/style.css index bfebba8..6b57c0c 100644 --- a/book-rent/src/main/resources/static/css/style.css +++ b/book-rent/src/main/resources/static/css/style.css @@ -1,90 +1,153 @@ -body -{font-family: - "Meiryo","Hiragino Sans",sans-serif; - margin:0;color:#222; - background:#f6f7f9} -header.top -{display:flex; - justify-content:space-between; - align-items:center; - background:#176a78;color:#fff; - padding:10px 20px +body { + font-family: + "Meiryo", "Hiragino Sans", sans-serif; + margin: 0; + color: #222; + background: #f6f7f9 } -header.top form -{display:inline; - margin:0} -header.top .user -{margin-right:12px + +header.top { + display: flex; + justify-content: space-between; + align-items: center; + background: #176a78; + color: #fff; + padding: 10px 20px } -main -{max-width:960px; - margin:24px auto; - padding:0 16px + +header.top form { + display: inline; + margin: 0 } -h1 -{font-size:20px + +header.top .user { + margin-right: 12px } -.card -{background:#fff; - border:1px solid #dde; - border-radius:6px; - padding:20px; - margin-bottom:16px + +main { + max-width: 960px; + margin: 24px auto; + padding: 0 16px } -label -{display:block; - margin:10px 0 4px; - font-weight:bold + +h1 { + font-size: 20px } -input[type=text],input[type=password],input[type=email] -{width:100%; - max-width:360px; - padding:6px; - box-sizing:border-box + +.card { + background: #fff; + border: 1px solid #dde; + border-radius: 6px; + padding: 20px; + margin-bottom: 16px } -button,.btn -{display:inline-block; - background:#176a78; - color:#fff;border:0; - border-radius:4px; - padding:7px 16px; - cursor:pointer; - text-decoration:none; - font-size:14px + +label { + display: block; + margin: 10px 0 4px; + font-weight: bold } -button.sub,.btn.sub -{background:#6b7b80 + +input[type=text], +input[type=password], +input[type=email] { + width: 100%; + max-width: 360px; + padding: 6px; + box-sizing: border-box } -.error -{background:#fdecea;color:#b3261e; - border:1px solid #f5c2be; - padding:8px 12px; - border-radius:4px; - margin-bottom:12px + +button, +.btn { + display: inline-block; + background: #176a78; + color: #fff; + border: 0; + border-radius: 4px; + padding: 7px 16px; + cursor: pointer; + text-decoration: none; + font-size: 14px } -.info -{background:#e8f4ea; - color:#1b5e20; - border:1px solid #bfdcc3; - padding:8px 12px; - border-radius:4px; - margin-bottom:12px + +button.sub, +.btn.sub { + background: #6b7b80 } -table -{border-collapse:collapse; - width:100%; - background:#fff + +.error { + background: #fdecea; + color: #b3261e; + border: 1px solid #f5c2be; + padding: 8px 12px; + border-radius: 4px; + margin-bottom: 12px } -th,td -{border:1px solid #dde; - padding:6px 8px; - text-align:left; - font-size:14px + +.info { + background: #e8f4ea; + color: #1b5e20; + border: 1px solid #bfdcc3; + padding: 8px 12px; + border-radius: 4px; + margin-bottom: 12px } -th -{background:#eaf4f6 + +table { + border-collapse: collapse; + width: 100%; + background: #fff } -.menu a -{display:block; - margin:8px 0 + +th, +td { + border: 1px solid #dde; + padding: 6px 8px; + text-align: left; + font-size: 14px } + +th { + background: #eaf4f6 +} + +.menu a { + display: block; + margin: 8px 0 +} + +/* Responsive (ဖုန်းစခရင်သေးများတွင် အောက်သို့ ဆင်းသွားစေရန်) */ +@media (max-width: 600px) { + .login-container-flex { + flex-direction: column; + align-items: center; + text-align: center; + } + + .form-content-area { + width: 100%; + } + + input[type=text], + input[type=password], + input[type=email] { + max-width: 100% !important; + } +} + +/* ページネーション */ +.page-number { + display: inline-block; + background: #eaf4f6; + color: #176a78; + border: 1px solid #d4e3e6; + border-radius: 4px; + padding: 7px 12px; + margin: 2px; + text-decoration: none; + font-size: 14px; +} + +.page-number:hover { + background: #d5edf1; +} \ No newline at end of file diff --git a/book-rent/src/main/resources/templates/bookInput.html b/book-rent/src/main/resources/templates/bookInput.html index dddd0f0..d12d045 100644 --- a/book-rent/src/main/resources/templates/bookInput.html +++ b/book-rent/src/main/resources/templates/bookInput.html @@ -1,34 +1,39 @@ + - - 書籍情報入力 - + + 書籍情報入力 + + -
-
-

書籍情報入力

-
-
-
-

書籍登録

-
- - - - - - - - - - - -

- 書籍一覧に戻る

-
-
-
+
+
+

書籍情報入力

+
+
+
+

書籍登録

+
+ + + + + + + + + + + + +

+ 書籍一覧に戻る +

+
+
+
- + + \ No newline at end of file diff --git a/book-rent/src/main/resources/templates/bookList.html b/book-rent/src/main/resources/templates/bookList.html index 0193cfc..2cc1a0a 100644 --- a/book-rent/src/main/resources/templates/bookList.html +++ b/book-rent/src/main/resources/templates/bookList.html @@ -1,12 +1,12 @@ - + 書籍一覧 - +
@@ -26,11 +26,11 @@

- +

検索結果

-

該当する書籍はありません。

- +

該当する書籍はありません。

+
@@ -60,8 +60,21 @@
蔵書ID
+ 前へ + + + + 次へ +
+ - - \ No newline at end of file + + diff --git a/book-rent/src/main/resources/templates/employeeRegistInput.html b/book-rent/src/main/resources/templates/employeeRegistInput.html index d6511a4..a9dbc41 100644 --- a/book-rent/src/main/resources/templates/employeeRegistInput.html +++ b/book-rent/src/main/resources/templates/employeeRegistInput.html @@ -37,6 +37,7 @@
+