From 5d767b46e95b246b57e38425b3d934f1d83bedc8 Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Tue, 2 Jul 2024 16:07:48 +0900 Subject: [PATCH 01/15] =?UTF-8?q?feat=20:=201=EC=A3=BC=EC=B0=A8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=B3=B5=EC=82=AC=20+=20=ED=94=BC?= =?UTF-8?q?=EB=93=9C=EB=B0=B1=20=EB=B0=98=EC=98=81=20(#72)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 +- src/main/java/gift/Product.java | 5 ++ src/main/java/gift/ProductController.java | 69 ++++++++++++++++++ src/main/java/gift/ProductDTO.java | 40 +++++++++++ src/main/java/gift/ProductRepository.java | 71 +++++++++++++++++++ src/main/java/gift/ProductViewController.java | 2 + src/main/resources/application.properties | 4 ++ src/main/resources/schema.sql | 9 +++ .../templates/AddOrUpdateProduct.html | 49 +++++++++++++ .../resources/templates/ManageProduct.html | 42 +++++++++++ src/main/resources/templates/ProductInfo.html | 60 ++++++++++++++++ 11 files changed, 353 insertions(+), 2 deletions(-) create mode 100644 src/main/java/gift/Product.java create mode 100644 src/main/java/gift/ProductController.java create mode 100644 src/main/java/gift/ProductDTO.java create mode 100644 src/main/java/gift/ProductRepository.java create mode 100644 src/main/java/gift/ProductViewController.java create mode 100644 src/main/resources/schema.sql create mode 100644 src/main/resources/templates/AddOrUpdateProduct.html create mode 100644 src/main/resources/templates/ManageProduct.html create mode 100644 src/main/resources/templates/ProductInfo.html diff --git a/build.gradle b/build.gradle index df7db9334..da113fd5e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' id 'org.springframework.boot' version '3.3.1' - id 'io.spring.dependency-management' version '1.1.5' + id 'io.spring.dependency-management' version '1.1.4' } group = 'camp.nextstep.edu' @@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT' java { toolchain { - languageVersion = JavaLanguageVersion.of(21) + languageVersion = JavaLanguageVersion.of(17) } } diff --git a/src/main/java/gift/Product.java b/src/main/java/gift/Product.java new file mode 100644 index 000000000..985795526 --- /dev/null +++ b/src/main/java/gift/Product.java @@ -0,0 +1,5 @@ +package gift; + +public record Product(Long id, String name, Long price, String imageUrl) { + +} diff --git a/src/main/java/gift/ProductController.java b/src/main/java/gift/ProductController.java new file mode 100644 index 000000000..82f6839db --- /dev/null +++ b/src/main/java/gift/ProductController.java @@ -0,0 +1,69 @@ +package gift; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +@Controller +@RequestMapping("/manager") +public class ProductController { + private final ProductRepository productRepository; + + public ProductController(ProductRepository productRepository) { + this.productRepository = productRepository; + } + + @PostMapping("/products/add") + public String addProduct(@ModelAttribute ProductDTO newProduct, RedirectAttributes redirectAttributes){ + System.out.println("add"); + Product product1 = productRepository.insertProduct(newProduct); + redirectAttributes.addAttribute("id", product1.id()); + System.out.println(product1.id()); + return "redirect:/manager/products/{id}"; + } + + @PutMapping("/products/update/{id}") + public String updateProduct(@PathVariable Long id, @ModelAttribute ProductDTO product, RedirectAttributes redirectAttributes){ + System.out.println("update"); + productRepository.updateProduct(id, product); + redirectAttributes.addAttribute("id", id); + return "redirect:/manager/products/{id}"; + } + + @DeleteMapping("/products/delete/{id}") + public String deleteProduct(@PathVariable Long id){ + System.out.println("delete"); + Product product = productRepository.selectProduct(id); + if(product != null){ + productRepository.deleteProduct(id); + } + return "redirect:/manager/products"; + } + + @GetMapping("/products") + public String getProductsView(Model model){ + model.addAttribute("products", productRepository.selectProducts()); + return "ManageProduct"; + } + + @GetMapping("/products/add") + public String addProductView(Model model){ + model.addAttribute("product", new Product(null,null,null,null)); + return "AddOrUpdateProduct"; + } + + @GetMapping("/products/update/{id}") + public String updateProductView(@PathVariable Long id, Model model){ + model.addAttribute("product", productRepository.selectProduct(id)); + return "AddOrUpdateProduct"; + } + + @GetMapping("/products/{id}") + public String getProduct(@PathVariable long id, Model model) { + Product product = productRepository.selectProduct(id); + model.addAttribute("product", product); + return "ProductInfo"; + } +} + diff --git a/src/main/java/gift/ProductDTO.java b/src/main/java/gift/ProductDTO.java new file mode 100644 index 000000000..37fd455ab --- /dev/null +++ b/src/main/java/gift/ProductDTO.java @@ -0,0 +1,40 @@ +package gift; + +public class ProductDTO { + String name; + Long price; + String imageUrl; + + public ProductDTO() { + } + + public ProductDTO(String name, Long price, String imageUrl) { + this.name = name; + this.price = price; + this.imageUrl = imageUrl; + } + + public String getName() { + return name; + } + + public Long getPrice() { + return price; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setName(String name) { + this.name = name; + } + + public void setPrice(Long price) { + this.price = price; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } +} diff --git a/src/main/java/gift/ProductRepository.java b/src/main/java/gift/ProductRepository.java new file mode 100644 index 000000000..1113078f9 --- /dev/null +++ b/src/main/java/gift/ProductRepository.java @@ -0,0 +1,71 @@ +package gift; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.stereotype.Repository; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Repository +public class ProductRepository { + private final JdbcTemplate jdbcTemplate; + private SimpleJdbcInsert simpleJdbcInsert; + public ProductRepository(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + this.simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate) + .withTableName("Products") + .usingGeneratedKeyColumns("id"); + } + + public Product insertProduct(ProductDTO product){ + Map parameters = new HashMap(); + parameters.put("name", product.getName()); + parameters.put("price", product.getPrice()); + parameters.put("imageUrl", product.getImageUrl()); + Long id = simpleJdbcInsert.executeAndReturnKey(parameters).longValue(); + return new Product(id, product.getName(), product.getPrice(), product.getImageUrl()); + } + public Product selectProduct(Long id) { + var sql = "select id, name, price, imageUrl from Products where id = ?"; + return jdbcTemplate.queryForObject( + sql, + getProductRowMapper(), + id + ); + } + + public List selectProducts(){ + var sql = "select id, name, price, imageUrl from Products"; + return jdbcTemplate.query( + sql, + getProductRowMapper() + ); + } + + private static RowMapper getProductRowMapper() { + return (resultSet, rowNum) -> new Product( + resultSet.getLong("id"), + resultSet.getString("name"), + resultSet.getLong("price"), + resultSet.getString("imageUrl") + ); + } + + public Product updateProduct(Long id, ProductDTO updateParam){ + var sql = "update Products set name=?, price=?, imageUrl=? where id = ?"; + jdbcTemplate.update(sql, + updateParam.getName(), + updateParam.getPrice(), + updateParam.getImageUrl(), + id); + return new Product(id, updateParam.getName(), updateParam.getPrice(), updateParam.getImageUrl()); + } + + public void deleteProduct(Long id){ + var sql = "delete from Products where id = ?"; + jdbcTemplate.update(sql, id); + } +} diff --git a/src/main/java/gift/ProductViewController.java b/src/main/java/gift/ProductViewController.java new file mode 100644 index 000000000..d1fd996e4 --- /dev/null +++ b/src/main/java/gift/ProductViewController.java @@ -0,0 +1,2 @@ +package gift;public class ProductViewController { +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3d16b65f4..8267f6161 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,5 @@ spring.application.name=spring-gift +spring.mvc.hiddenmethod.filter.enabled=true +spring.h2.console.enabled=true +spring.datasource.url=jdbc:h2:mem:test +spring.datasource.username=sa diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 000000000..5a98b3ff5 --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,9 @@ +DROP TABLE IF EXISTS PRODUCTS; + +CREATE TABLE PRODUCTS ( + id long NOT NULL AUTO_INCREMENT, + name varchar(255) NOT NULL, + price long NOT NULL, + imageurl varchar(255), + primary key (id) + ); \ No newline at end of file diff --git a/src/main/resources/templates/AddOrUpdateProduct.html b/src/main/resources/templates/AddOrUpdateProduct.html new file mode 100644 index 000000000..d2e977868 --- /dev/null +++ b/src/main/resources/templates/AddOrUpdateProduct.html @@ -0,0 +1,49 @@ + + + + + 상품 등록/수정 + + + +
+

상품 관리

+

관리자 전용 상품 관리 페이지

+
+
+
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ + +
+
+ +
+
+ +
+ +
+ diff --git a/src/main/resources/templates/ManageProduct.html b/src/main/resources/templates/ManageProduct.html new file mode 100644 index 000000000..7628a4392 --- /dev/null +++ b/src/main/resources/templates/ManageProduct.html @@ -0,0 +1,42 @@ + + + + + 상품 관리 + + + +
+

상품 관리

+

관리자 전용 상품 관리 페이지

+
+ +
+ + + +
+ + + + + + + + + + + + + + + + + +
ID상품명가격이미지 URL
회원id상품명1000010
+
+
+ + diff --git a/src/main/resources/templates/ProductInfo.html b/src/main/resources/templates/ProductInfo.html new file mode 100644 index 000000000..05ae404ec --- /dev/null +++ b/src/main/resources/templates/ProductInfo.html @@ -0,0 +1,60 @@ + + + + + 상품 조회 + + + +
+

상품 관리

+

관리자 전용 상품 관리 페이지

+
+ +
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+
+
+ From 9666cd5d75a317ea4ca82a2ecd6671b85082a36a Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:24:09 +0900 Subject: [PATCH 02/15] =?UTF-8?q?feat=20:=20build.gradle=20Validation=20va?= =?UTF-8?q?lidation=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index da113fd5e..c1a899698 100644 --- a/build.gradle +++ b/build.gradle @@ -21,6 +21,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-validation' + runtimeOnly 'com.h2database:h2' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' From b73671b1c44fff622759e519646cff5e410a32aa Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:25:21 +0900 Subject: [PATCH 03/15] =?UTF-8?q?fix=20:=20Product=20record=20record?= =?UTF-8?q?=EC=97=90=EC=84=9C=20class=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/gift/Product.java | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/gift/Product.java b/src/main/java/gift/Product.java index 985795526..fb7bec51b 100644 --- a/src/main/java/gift/Product.java +++ b/src/main/java/gift/Product.java @@ -1,5 +1,37 @@ package gift; -public record Product(Long id, String name, Long price, String imageUrl) { +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +public class Product { + Long id; + String name; + Long price; + String imageUrl; + + public Product() { + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public Long getPrice() { + return price; + } + + public String getImageUrl() { + return imageUrl; + } + + public Product(Long id, String name, Long price, String imageUrl) { + this.id = id; + this.name = name; + this.price = price; + this.imageUrl = imageUrl; + } } From fa0a41a07b6a286b664ce4b297677adf8b6fcd57 Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:26:08 +0900 Subject: [PATCH 04/15] =?UTF-8?q?feat=20:=20ProductDTO=20Bean=20Validation?= =?UTF-8?q?=20ProductDTO=EC=9D=98=20=ED=95=84=EB=93=9C=EC=97=90=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EA=B3=BC=20=EC=98=A4=EB=A5=98=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/gift/ProductDTO.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/gift/ProductDTO.java b/src/main/java/gift/ProductDTO.java index 37fd455ab..1333caf7d 100644 --- a/src/main/java/gift/ProductDTO.java +++ b/src/main/java/gift/ProductDTO.java @@ -1,8 +1,16 @@ package gift; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + public class ProductDTO { + @NotBlank(message = "상품명은 공백으로 둘 수 없습니다.") + @Pattern(regexp = "^[a-zA-Zㄱ-ㅎ가-힣0-9\\(\\)\\[\\]\\+\\-&/\\_ ]{1,16}$", message = "상품명은 공백을 포함하여 최대 15자까지 입력할 수 있습니다. 특수문자는 ( ) [ ] + - & / _ 만 사용 가능합니다.") String name; + @NotNull(message = "가격은 공백으로 둘 수 없습니다.") Long price; + @NotBlank(message = "이미지 URL은 공백으로 둘 수 없습니다.") String imageUrl; public ProductDTO() { From 5082e06cd351b91f267c09f3c2be21c2cce34b70 Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:28:53 +0900 Subject: [PATCH 05/15] =?UTF-8?q?fix=20:=20ProductController=20attribute?= =?UTF-8?q?=20product=20->=20newProduct=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/gift/ProductController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/gift/ProductController.java b/src/main/java/gift/ProductController.java index 82f6839db..f5cd1644f 100644 --- a/src/main/java/gift/ProductController.java +++ b/src/main/java/gift/ProductController.java @@ -49,8 +49,8 @@ public String getProductsView(Model model){ @GetMapping("/products/add") public String addProductView(Model model){ - model.addAttribute("product", new Product(null,null,null,null)); - return "AddOrUpdateProduct"; + model.addAttribute("newProduct", new Product()); + return "AddProduct"; } @GetMapping("/products/update/{id}") From df579ba80f62a7f2767ecbb6c469a91dbac8eae2 Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:30:40 +0900 Subject: [PATCH 06/15] =?UTF-8?q?feat=20:=20ProductController=20valid=20ad?= =?UTF-8?q?dProduct=20=EC=83=81=ED=92=88=20=EC=B6=94=EA=B0=80=20API?= =?UTF-8?q?=EC=97=90=20=EA=B2=80=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/gift/ProductController.java | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/gift/ProductController.java b/src/main/java/gift/ProductController.java index f5cd1644f..f632d58d4 100644 --- a/src/main/java/gift/ProductController.java +++ b/src/main/java/gift/ProductController.java @@ -1,7 +1,10 @@ package gift; +import jakarta.validation.Valid; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.support.RedirectAttributes; @@ -15,11 +18,20 @@ public ProductController(ProductRepository productRepository) { } @PostMapping("/products/add") - public String addProduct(@ModelAttribute ProductDTO newProduct, RedirectAttributes redirectAttributes){ + public String addProduct(@Valid @ModelAttribute("newProduct") ProductDTO newProduct, BindingResult bindingResult, RedirectAttributes redirectAttributes){ + + if(newProduct.name.contains("카카오")){ + bindingResult.addError(new FieldError("product", "name", "\"카카오\"가 포함된 문구는 담당 MD와 협의한 경우에만 사용할 수 있습니다.")); + } + + if (bindingResult.hasErrors()) { + return "AddProduct"; + } + System.out.println("add"); - Product product1 = productRepository.insertProduct(newProduct); - redirectAttributes.addAttribute("id", product1.id()); - System.out.println(product1.id()); + Product product = productRepository.insertProduct(newProduct); + redirectAttributes.addAttribute("id", product.getId()); + System.out.println(product.id); return "redirect:/manager/products/{id}"; } From 5fe4d2193e700056d75a05fcc87fdec93ee7ec9d Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:32:00 +0900 Subject: [PATCH 07/15] =?UTF-8?q?feat=20:=20ProductController=20valid=20up?= =?UTF-8?q?date=20=EC=83=81=ED=92=88=20=EC=88=98=EC=A0=95=20API=EC=97=90?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/gift/ProductController.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/gift/ProductController.java b/src/main/java/gift/ProductController.java index f632d58d4..8dc5c31f9 100644 --- a/src/main/java/gift/ProductController.java +++ b/src/main/java/gift/ProductController.java @@ -36,7 +36,15 @@ public String addProduct(@Valid @ModelAttribute("newProduct") ProductDTO newProd } @PutMapping("/products/update/{id}") - public String updateProduct(@PathVariable Long id, @ModelAttribute ProductDTO product, RedirectAttributes redirectAttributes){ + public String updateProduct(@PathVariable Long id, @Valid @ModelAttribute("product") ProductDTO product, BindingResult bindingResult, RedirectAttributes redirectAttributes){ + if(product.name.contains("카카오")){ + bindingResult.addError(new FieldError("product", "name", "\"카카오\"가 포함된 문구는 담당 MD와 협의한 경우에만 사용할 수 있습니다.")); + } + + if (bindingResult.hasErrors()) { + return "UpdateProduct"; + } + System.out.println("update"); productRepository.updateProduct(id, product); redirectAttributes.addAttribute("id", id); @@ -68,7 +76,7 @@ public String addProductView(Model model){ @GetMapping("/products/update/{id}") public String updateProductView(@PathVariable Long id, Model model){ model.addAttribute("product", productRepository.selectProduct(id)); - return "AddOrUpdateProduct"; + return "UpdateProduct"; } @GetMapping("/products/{id}") @@ -78,4 +86,3 @@ public String getProduct(@PathVariable long id, Model model) { return "ProductInfo"; } } - From c827550f7f371910d8a855a049ed083dbc9cda66 Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:34:29 +0900 Subject: [PATCH 08/15] =?UTF-8?q?fix=20:=20ProductInfo=20Product=EB=A5=BC?= =?UTF-8?q?=20record=EC=97=90=EC=84=9C=20class=EB=A1=9C=20=EB=B0=94?= =?UTF-8?q?=EA=BE=B8=EB=A9=B4=EC=84=9C=20=EC=83=9D=EA=B8=B4=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/ManageProduct.html | 8 ++++---- src/main/resources/templates/ProductInfo.html | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/resources/templates/ManageProduct.html b/src/main/resources/templates/ManageProduct.html index 7628a4392..2b77a2f1a 100644 --- a/src/main/resources/templates/ManageProduct.html +++ b/src/main/resources/templates/ManageProduct.html @@ -29,10 +29,10 @@

관리자 전용 상품 관리 페이지

- 회원id - 상품명 - 10000 - 10 + 회원id + 상품명 + 10000 + 10 diff --git a/src/main/resources/templates/ProductInfo.html b/src/main/resources/templates/ProductInfo.html index 05ae404ec..a2bbe01d5 100644 --- a/src/main/resources/templates/ProductInfo.html +++ b/src/main/resources/templates/ProductInfo.html @@ -17,19 +17,19 @@

관리자 전용 상품 관리 페이지

- +
- +
- +
- +
From 19a03c87a1a860e052169c7385e234249fe74970 Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:35:11 +0900 Subject: [PATCH 09/15] =?UTF-8?q?feat=20:=20AddProduct=20=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EC=B6=94=EA=B0=80,=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B7=B0=EB=A5=BC=20=EB=82=98=EB=88=94=20=EC=9E=98=EB=AA=BB?= =?UTF-8?q?=EB=90=9C=20=ED=95=84=EB=93=9C=20=EA=B0=92=EC=9D=B4=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EB=90=9C=20=EA=B2=BD=EC=9A=B0=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/AddProduct.html | 61 ++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/main/resources/templates/AddProduct.html diff --git a/src/main/resources/templates/AddProduct.html b/src/main/resources/templates/AddProduct.html new file mode 100644 index 000000000..7a55a1d0d --- /dev/null +++ b/src/main/resources/templates/AddProduct.html @@ -0,0 +1,61 @@ + + + + + 상품 등록 + + + + +
+

상품 관리

+

관리자 전용 상품 관리 페이지

+
+
+ + +
+ + +
+

+
+
+
+ + +
+

+
+
+
+ + +
+

+
+
+ +
+
+ +
+
+ +
+
+ + +
+ From 808b2c9308b6aaeba81e541987c8b4a59925d948 Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:36:20 +0900 Subject: [PATCH 10/15] =?UTF-8?q?feat=20:=20UpdateProduct=20=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EC=B6=94=EA=B0=80=20=EB=B7=B0=EC=99=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B7=B0=EB=A5=BC=20=EB=B6=84=EB=A6=AC=20=EC=83=81?= =?UTF-8?q?=ED=92=88=EC=9D=84=20=EC=88=98=EC=A0=95=ED=95=A0=20=EB=95=8C=20?= =?UTF-8?q?=EC=9E=98=EB=AA=BB=EB=90=9C=20=ED=95=84=EB=93=9C=20=EA=B0=92?= =?UTF-8?q?=EC=9D=B4=20=EB=93=A4=EC=96=B4=EC=98=A8=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/templates/UpdateProduct.html | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/main/resources/templates/UpdateProduct.html diff --git a/src/main/resources/templates/UpdateProduct.html b/src/main/resources/templates/UpdateProduct.html new file mode 100644 index 000000000..996067ab4 --- /dev/null +++ b/src/main/resources/templates/UpdateProduct.html @@ -0,0 +1,61 @@ + + + + + 상품 수정 + + + + +
+

상품 관리

+

관리자 전용 상품 관리 페이지

+
+
+
+
+ + +
+

+
+
+
+ + +
+

+
+
+
+ + +
+

+
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ From 22902580c7739bae00cfc280e6353dc08c280c61 Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Wed, 3 Jul 2024 00:42:00 +0900 Subject: [PATCH 11/15] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 구현할 기능 목록 --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8376bdfff..7fd1d9661 100644 --- a/README.md +++ b/README.md @@ -1 +1,9 @@ -# spring-gift-wishlist \ No newline at end of file +# spring-gift-wishlist +구현할 기능 목록 +1. Product DTO에 조건 추가 +2. 컨트롤러 수정 + - 상품 추가 시 검증 + - 상품 수정 시 검증 +3. 뷰 수정 + - 상품 추가 뷰 : 필드값 에러 시 오류 메시지 출력 + - 삼품 수정 뷰 : 필드값 에러 시 오류 메시지 출력 From 36c1603ddd2a3a225fdc4489137076f80a513a97 Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Thu, 4 Jul 2024 09:31:06 +0900 Subject: [PATCH 12/15] =?UTF-8?q?fix=20:=20ProductDTO=20Product=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=EB=A5=BC=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=EB=A1=9C=20=EB=B0=9B=EB=8A=94=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=9E=90=20&=20AssertTrue=EB=A1=9C=20"=EC=B9=B4=EC=B9=B4?= =?UTF-8?q?=EC=98=A4"=20=EB=8B=A8=EC=96=B4=20=ED=8F=AC=ED=95=A8=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/gift/ProductDTO.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/gift/ProductDTO.java b/src/main/java/gift/ProductDTO.java index 1333caf7d..026e74307 100644 --- a/src/main/java/gift/ProductDTO.java +++ b/src/main/java/gift/ProductDTO.java @@ -1,5 +1,6 @@ package gift; +import jakarta.validation.constraints.AssertTrue; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; @@ -13,6 +14,11 @@ public class ProductDTO { @NotBlank(message = "이미지 URL은 공백으로 둘 수 없습니다.") String imageUrl; + @AssertTrue(message = "\"카카오\"가 포함된 문구는 담당 MD와 협의한 경우에만 사용할 수 있습니다.") + public boolean isNameNotContainingKakao() { + return name == null || !name.contains("카카오"); + } + public ProductDTO() { } @@ -22,6 +28,12 @@ public ProductDTO(String name, Long price, String imageUrl) { this.imageUrl = imageUrl; } + public ProductDTO(Product product) { + this.name = product.getName(); + this.price = product.getPrice(); + this.imageUrl = product.getImageUrl(); + } + public String getName() { return name; } From 5b2e7cea1a0c25ca171e944b5dc00578393cacb3 Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Thu, 4 Jul 2024 09:32:22 +0900 Subject: [PATCH 13/15] =?UTF-8?q?fix=20:=20ProductController=20"=EC=B9=B4?= =?UTF-8?q?=EC=B9=B4=EC=98=A4"=20=EB=8B=A8=EC=96=B4=20=ED=8F=AC=ED=95=A8?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8A=94=20=ED=8C=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C,=20=EC=83=81=ED=92=88=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20=EB=B7=B0=EC=97=90=20ProductDTO=EB=A5=BC=20attribute?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=84=EB=8B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/gift/ProductController.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/main/java/gift/ProductController.java b/src/main/java/gift/ProductController.java index 8dc5c31f9..3d2219125 100644 --- a/src/main/java/gift/ProductController.java +++ b/src/main/java/gift/ProductController.java @@ -19,11 +19,6 @@ public ProductController(ProductRepository productRepository) { @PostMapping("/products/add") public String addProduct(@Valid @ModelAttribute("newProduct") ProductDTO newProduct, BindingResult bindingResult, RedirectAttributes redirectAttributes){ - - if(newProduct.name.contains("카카오")){ - bindingResult.addError(new FieldError("product", "name", "\"카카오\"가 포함된 문구는 담당 MD와 협의한 경우에만 사용할 수 있습니다.")); - } - if (bindingResult.hasErrors()) { return "AddProduct"; } @@ -37,10 +32,6 @@ public String addProduct(@Valid @ModelAttribute("newProduct") ProductDTO newProd @PutMapping("/products/update/{id}") public String updateProduct(@PathVariable Long id, @Valid @ModelAttribute("product") ProductDTO product, BindingResult bindingResult, RedirectAttributes redirectAttributes){ - if(product.name.contains("카카오")){ - bindingResult.addError(new FieldError("product", "name", "\"카카오\"가 포함된 문구는 담당 MD와 협의한 경우에만 사용할 수 있습니다.")); - } - if (bindingResult.hasErrors()) { return "UpdateProduct"; } @@ -75,7 +66,7 @@ public String addProductView(Model model){ @GetMapping("/products/update/{id}") public String updateProductView(@PathVariable Long id, Model model){ - model.addAttribute("product", productRepository.selectProduct(id)); + model.addAttribute("product", new ProductDTO(productRepository.selectProduct(id))); return "UpdateProduct"; } From 646fe57bf767670781031bb36a9e3228ccf6c75b Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Thu, 4 Jul 2024 09:34:07 +0900 Subject: [PATCH 14/15] =?UTF-8?q?feat=20:=20AddProduct=20view=20AssertTrue?= =?UTF-8?q?=EB=A5=BC=20=ED=86=B5=EA=B3=BC=ED=95=98=EC=A7=80=20=EB=AA=BB?= =?UTF-8?q?=ED=95=9C=20=EA=B2=BD=EC=9A=B0=20=EC=97=90=EB=9F=AC=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/AddProduct.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/resources/templates/AddProduct.html b/src/main/resources/templates/AddProduct.html index 7a55a1d0d..75a9746e3 100644 --- a/src/main/resources/templates/AddProduct.html +++ b/src/main/resources/templates/AddProduct.html @@ -22,9 +22,11 @@

관리자 전용 상품 관리 페이지

-
+

+

From f8fb86ffda3392910b38c4336a46cf18fa13b513 Mon Sep 17 00:00:00 2001 From: yoonsu0325 <84390426+yoonsu0325@users.noreply.github.com> Date: Thu, 4 Jul 2024 09:35:30 +0900 Subject: [PATCH 15/15] =?UTF-8?q?feat=20:=20UpdateProduct=20View=20AssertT?= =?UTF-8?q?rue=EB=A5=BC=20=ED=86=B5=EA=B3=BC=ED=95=98=EC=A7=80=20=EB=AA=BB?= =?UTF-8?q?=ED=95=9C=20=EA=B2=BD=EC=9A=B0=20=EC=97=90=EB=9F=AC=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/UpdateProduct.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/resources/templates/UpdateProduct.html b/src/main/resources/templates/UpdateProduct.html index 996067ab4..220a1d08d 100644 --- a/src/main/resources/templates/UpdateProduct.html +++ b/src/main/resources/templates/UpdateProduct.html @@ -21,9 +21,11 @@

관리자 전용 상품 관리 페이지

-
+

+