상품 상세 페이지에서 자신이 작성한 글만 수정, 삭제 할수있도록
구현해보겠다.
ItemController 추가
@GetMapping("/detail/{id}")
public String item_detail(Model model, @PathVariable Long id, Principal principal){
model.addAttribute("item", itemService.itemFindId(id));
model.addAttribute("reviews", reviewService.FindItemId(id));
if(principal != null) {
Member member = memberService.findEmail(principal.getName());
model.addAttribute("member", member);
} else
model.addAttribute("member", null);
return "item/detail";
}
먼저 detail에 현재 로그인된 사용자가 있으면 member를 model에 담아 뿌려줄것이고
없으면 null값을 보내줄것이다.
이유는 현재 로그인된 사용자와 item.member가 같은지 비교하여 수정, 삭제 버튼이 표시되게 할것이기때문
detail.html 추가
<!DOCTYPE html>
<html lang="en" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<div th:replace="/fragments/header.html :: header"></div>
<title>Title</title>
</head>
<body>
<div th:replace="/fragments/nav.html :: nav"></div>
<div class="container">
<h1>상품 상세</h1>
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title" th:text="${item.name}"></h5>
<h6 class="card-subtitle mb-2 text-muted" th:text="'가격: ' + ${item.price} +'원'"></h6>
<p class="card-text" th:text="'판매자: '+${item.member.getName()}"></p>
<pre class="card-footer" th:text="${item.content}"></pre>
</div>
</div>
<form class="mb-3" method="post" th:action="@{/cart/addCart/{id}/{itemId}(id=${member.id}, itemId=${item.id})}" sec:authorize="hasAuthority('USER')">
<div class="mb-3">
<label for="quantity" class="form-label">수량</label>
<input type="number" class="form-control" id="quantity" name="quantity" value="1" required>
</div>
<button type="submit" class="btn btn-dark">장바구니담기</button>
</form>
<!-- 이 부분 추가 -->
<div class="mb-3" th:if="${member != null and item.member.id == member.id}">
<a th:href="@{/item/update/{id}(id=${item.id})}" class="btn btn-primary">수정</a>
<a th:href="@{/item/delete/{id}(id=${item.id})}" class="btn btn-danger">삭제</a>
</div>
<form class="mb-2" th:action="@{/review/review_reg/{id}(id=${item.id})}" method="post" sec:authorize="isAuthenticated()">
<div class="mb-3">
<label for="content">리뷰 내용: </label>
<textarea class="form-control" id="content" name="content" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary">제출</button>
</form>
<div>
<h3 class="mb-2">리뷰 목록</h3>
<div class="card-sm">
<ul class="list-group list-group-flush">
<li th:each="review : ${reviews}" class="list-group-item">
<div class="card-body mb-2">
<h6 class="card-title" th:text="${review.content}"></h6>
<p class="card-text">작성자: <span th:text="${review.member.getName()}"></span></p>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
상품 상세 페이지에 수정, 삭제 버튼을 추가하였다.
th:if="${member != null and item.member.id == member.id}"
th:if를 이용해 member가 null이 아닐떄, item.member.id와 member.id의 값이 같을때 표시되게 하였다.
여기서 member는 현재 로그인된 사용자이다.
그리고 각각 /item/update/, /item/delete/로 이동하면서 파마리터로 item.id를 넘겨준다.
ItemController 추가
@GetMapping("/update/{id}")
public String update(@PathVariable Long id, Model model){
model.addAttribute("item", itemService.itemFindId(id));
return "item/item_update";
}
@GetMapping("/delete/{id}")
public String delete(@PathVariable Long id){
itemService.delete(id);
return "redirect:/";
}
/item/update/ 경로로 get요청이 왔을시에 파라미터인 item.id값을 이용해
item객체를 model에 담아 html로 보내줄것이다.
/item/delete/ 경로로 get요청이 왔을시에는 똑같이 id값을 이용해 게시물을 삭제할것이다.
item_update.html 작성
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>상품 수정 페이지</title>
<div th:replace="/fragments/header.html :: header"></div>
</head>
<body>
<div th:replace="/fragments/nav.html :: nav"></div>
<div class="container">
<h1>상품 수정</h1>
<form th:action="@{/item/update/{id}(id=${item.id})}" method="post">
<div class="mb-3">
<label for="name">상품명:</label>
<input type="text" class="form-control" id="name" name="name" th:value="${item.name}">
</div>
<div class="mb-3">
<label for="price">가격:</label>
<input type="number" class="form-control" id="price" name="price" th:value="${item.price}">
</div>
<div class="mb-3">
<label for="count">재고:</label>
<input type="number" class="form-control" id="count" name="count" th:value="${item.count}">
</div>
<div class="mb-3">
<label for="content">상세 내용:</label>
<textarea class="form-control" id="content" name="content" rows="5" th:text="${item.content}"></textarea>
</div>
<input type="hidden" name="member" th:value="${item.member.id}">
<button type="submit" class="btn btn-primary">수정</button>
</form>
</div>
</body>
</html>
각각의 칸 에는 현재 db에 저장되어있는 값이 기본값으로 들어간다.
input태그 타입을 hidden으로 숨겨 member.id값도 같이 컨트롤러로 넘겨줄것이다.
ItemController 추가
@PostMapping("/update/{id}")
public String update(@ModelAttribute ItemDto itemDto,
@ModelAttribute(value = "member") Long memberId
@PathVariable Long id){
itemService.itemUpdate(itemDto, id, memberId);
return "redirect:/item/detail/"+id;
}
/item/update/ 경로로 Post요청이 왔을때 itemDto와 id, memberId를 ModelAttribute 어노테이션을 통해 받고 파라미터로 item.id값을 받아서
Service로 넘겨 수정한다.
이후 상세페이지로 redirect한다.
ItemService 추가
@Override
public void itemUpdate(ItemDto itemDto, Long id, Long memberId) {
Member member = memberRepository.findById(memberId).get();
itemRepository.save(Item.builder()
.price(itemDto.getPrice())
.count(itemDto.getCount())
.content(itemDto.getContent())
.name(itemDto.getName())
.id(id)
.member(member)
.build());
}
@Override
public void delete(Long id) {
itemRepository.deleteById(id);
}
각각 수정, 삭제하는 메서드이다.
상품 상세 페이지에서 자신이 작성한 글만 수정, 삭제 할수있도록
구현해보겠다.
ItemController 추가
@GetMapping("/detail/{id}")
public String item_detail(Model model, @PathVariable Long id, Principal principal){
model.addAttribute("item", itemService.itemFindId(id));
model.addAttribute("reviews", reviewService.FindItemId(id));
if(principal != null) {
Member member = memberService.findEmail(principal.getName());
model.addAttribute("member", member);
} else
model.addAttribute("member", null);
return "item/detail";
}
먼저 detail에 현재 로그인된 사용자가 있으면 member를 model에 담아 뿌려줄것이고
없으면 null값을 보내줄것이다.
이유는 현재 로그인된 사용자와 item.member가 같은지 비교하여 수정, 삭제 버튼이 표시되게 할것이기때문
detail.html 추가
<!DOCTYPE html>
<html lang="en" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<div th:replace="/fragments/header.html :: header"></div>
<title>Title</title>
</head>
<body>
<div th:replace="/fragments/nav.html :: nav"></div>
<div class="container">
<h1>상품 상세</h1>
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title" th:text="${item.name}"></h5>
<h6 class="card-subtitle mb-2 text-muted" th:text="'가격: ' + ${item.price} +'원'"></h6>
<p class="card-text" th:text="'판매자: '+${item.member.getName()}"></p>
<pre class="card-footer" th:text="${item.content}"></pre>
</div>
</div>
<form class="mb-3" method="post" th:action="@{/cart/addCart/{id}/{itemId}(id=${member.id}, itemId=${item.id})}" sec:authorize="hasAuthority('USER')">
<div class="mb-3">
<label for="quantity" class="form-label">수량</label>
<input type="number" class="form-control" id="quantity" name="quantity" value="1" required>
</div>
<button type="submit" class="btn btn-dark">장바구니담기</button>
</form>
<!-- 이 부분 추가 -->
<div class="mb-3" th:if="${member != null and item.member.id == member.id}">
<a th:href="@{/item/update/{id}(id=${item.id})}" class="btn btn-primary">수정</a>
<a th:href="@{/item/delete/{id}(id=${item.id})}" class="btn btn-danger">삭제</a>
</div>
<form class="mb-2" th:action="@{/review/review_reg/{id}(id=${item.id})}" method="post" sec:authorize="isAuthenticated()">
<div class="mb-3">
<label for="content">리뷰 내용: </label>
<textarea class="form-control" id="content" name="content" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary">제출</button>
</form>
<div>
<h3 class="mb-2">리뷰 목록</h3>
<div class="card-sm">
<ul class="list-group list-group-flush">
<li th:each="review : ${reviews}" class="list-group-item">
<div class="card-body mb-2">
<h6 class="card-title" th:text="${review.content}"></h6>
<p class="card-text">작성자: <span th:text="${review.member.getName()}"></span></p>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
상품 상세 페이지에 수정, 삭제 버튼을 추가하였다.
th:if="${member != null and item.member.id == member.id}"
th:if를 이용해 member가 null이 아닐떄, item.member.id와 member.id의 값이 같을때 표시되게 하였다.
여기서 member는 현재 로그인된 사용자이다.
그리고 각각 /item/update/, /item/delete/로 이동하면서 파마리터로 item.id를 넘겨준다.
ItemController 추가
@GetMapping("/update/{id}")
public String update(@PathVariable Long id, Model model){
model.addAttribute("item", itemService.itemFindId(id));
return "item/item_update";
}
@GetMapping("/delete/{id}")
public String delete(@PathVariable Long id){
itemService.delete(id);
return "redirect:/";
}
/item/update/ 경로로 get요청이 왔을시에 파라미터인 item.id값을 이용해
item객체를 model에 담아 html로 보내줄것이다.
/item/delete/ 경로로 get요청이 왔을시에는 똑같이 id값을 이용해 게시물을 삭제할것이다.
item_update.html 작성
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>상품 수정 페이지</title>
<div th:replace="/fragments/header.html :: header"></div>
</head>
<body>
<div th:replace="/fragments/nav.html :: nav"></div>
<div class="container">
<h1>상품 수정</h1>
<form th:action="@{/item/update/{id}(id=${item.id})}" method="post">
<div class="mb-3">
<label for="name">상품명:</label>
<input type="text" class="form-control" id="name" name="name" th:value="${item.name}">
</div>
<div class="mb-3">
<label for="price">가격:</label>
<input type="number" class="form-control" id="price" name="price" th:value="${item.price}">
</div>
<div class="mb-3">
<label for="count">재고:</label>
<input type="number" class="form-control" id="count" name="count" th:value="${item.count}">
</div>
<div class="mb-3">
<label for="content">상세 내용:</label>
<textarea class="form-control" id="content" name="content" rows="5" th:text="${item.content}"></textarea>
</div>
<input type="hidden" name="member" th:value="${item.member.id}">
<button type="submit" class="btn btn-primary">수정</button>
</form>
</div>
</body>
</html>
각각의 칸 에는 현재 db에 저장되어있는 값이 기본값으로 들어간다.
input태그 타입을 hidden으로 숨겨 member.id값도 같이 컨트롤러로 넘겨줄것이다.
ItemController 추가
@PostMapping("/update/{id}")
public String update(@ModelAttribute ItemDto itemDto,
@ModelAttribute(value = "member") Long memberId
@PathVariable Long id){
itemService.itemUpdate(itemDto, id, memberId);
return "redirect:/item/detail/"+id;
}
/item/update/ 경로로 Post요청이 왔을때 itemDto와 id, memberId를 ModelAttribute 어노테이션을 통해 받고 파라미터로 item.id값을 받아서
Service로 넘겨 수정한다.
이후 상세페이지로 redirect한다.
ItemService 추가
@Override
public void itemUpdate(ItemDto itemDto, Long id, Long memberId) {
Member member = memberRepository.findById(memberId).get();
itemRepository.save(Item.builder()
.price(itemDto.getPrice())
.count(itemDto.getCount())
.content(itemDto.getContent())
.name(itemDto.getName())
.id(id)
.member(member)
.build());
}
@Override
public void delete(Long id) {
itemRepository.deleteById(id);
}
각각 수정, 삭제하는 메서드이다.