This commit is contained in:
이진석
2020-02-04 11:56:15 +09:00
parent 16fcb632f4
commit 0c91429132
8 changed files with 71 additions and 12 deletions

View File

@@ -40,6 +40,17 @@ function postArticle({title = '', content = ''}) {
});
}
function removeArticle(id) {
return axios({
url: '/api/articles/' + id,
headers: {
'Authorization': commonUtil.getAuthenticationHeaderBearer.bind(this)()
},
method: 'delete'
});
}
export default {
getArticles,
getArticle,

View File

@@ -11,6 +11,9 @@
createdAt: <span>{{ article.createdAt }}</span>
</div>
<div v-if="article.isOwn">
<button type="button" @click="remove">삭제</button>
</div>
</div>
</template>
@@ -33,6 +36,14 @@
this.init = true;
} catch (e) {
console.log(e);
}
},
methods: {
remove() {
const articleId = this.$route.params.id;
if(!confirm('정말 삭제하시겠습니까?')) return;
}
}
}

View File

@@ -47,4 +47,12 @@ public class Article {
private void preUpdate() {
this.updatedAt = LocalDateTime.now();
}
public boolean compareUser(User user) {
return compareUser(user.getId());
}
public boolean compareUser(Long id) {
return this.user.getId().equals(id);
}
}

View File

@@ -3,6 +3,7 @@ package com.example.vue.domain.article;
import com.example.vue.domain.user.User;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
@@ -17,20 +18,28 @@ public class ArticleController {
private final ArticleService articleService;
@ResponseStatus(HttpStatus.OK)
@GetMapping
public List<ArticleResponseDto> getArticles(Pageable pageable) {
return articleService.findAll(pageable);
public List<ArticleResponseDto> getArticles(Pageable pageable, @AuthenticationPrincipal User user) {
return articleService.findAll(pageable, user);
}
@ResponseStatus(HttpStatus.OK)
@GetMapping(value = "/{articleId}")
@Transactional(readOnly = true)
public ArticleResponseDto getArticle(@PathVariable Long articleId, @AuthenticationPrincipal User user) {
return articleService.findById(articleId, user);
}
@ResponseStatus(HttpStatus.CREATED)
@PostMapping
@Transactional
public ArticleResponseDto postArticles(@RequestBody @Valid ArticleRequestDto articleRequestDto) {
return articleService.save(articleRequestDto);
public ArticleResponseDto postArticles(@RequestBody @Valid ArticleRequestDto articleRequestDto, @AuthenticationPrincipal User user) {
return articleService.save(articleRequestDto, user);
}
@DeleteMapping(value = "/{articleId}")
public void deleteArticle(@PathVariable Long articleId, @AuthenticationPrincipal User user) {
articleService.delete(articleId, user);
}
}

View File

@@ -17,4 +17,11 @@ public class ArticleException {
public static Supplier<NoExist> passNoExistException(Long id) {
return () -> new NoExist(id);
}
@ResponseStatus(HttpStatus.FORBIDDEN)
public static class AccessNotOwned extends RuntimeException {
public AccessNotOwned(Long id) {
super("사용자에게 권한이 없습니다.");
}
}
}

View File

@@ -1,5 +1,6 @@
package com.example.vue.domain.article;
import com.example.vue.domain.user.User;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
@@ -34,4 +35,12 @@ public class ArticleRepository {
return Optional.ofNullable(em.find(Article.class, id));
}
public void deleteById(Long id, User user) {
Article article = findById(id).orElseThrow(ArticleException.passNoExistException(id));
if (!article.compareUser(user)) {
throw new ArticleException.AccessNotOwned(id);
}
em.remove(article);
}
}

View File

@@ -1,5 +1,6 @@
package com.example.vue.domain.article;
import com.example.vue.domain.user.User;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@@ -17,11 +18,12 @@ public class ArticleResponseDto {
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
public ArticleResponseDto(Article article) {
public ArticleResponseDto(Article article, User user) {
this.id = article.getId();
this.title = article.getTitle();
this.content = article.getContent();
this.createdAt = article.getCreatedAt();
this.updatedAt = article.getUpdatedAt();
this.isOwn = article.compareUser(user);
}
}

View File

@@ -14,22 +14,24 @@ public class ArticleService {
private final ArticleRepository articleRepository;
public ArticleResponseDto save(ArticleRequestDto articleRequestDto) {
public ArticleResponseDto save(ArticleRequestDto articleRequestDto, User user) {
Article article = articleRepository.save(new Article(articleRequestDto));
return new ArticleResponseDto(article);
return new ArticleResponseDto(article, user);
}
public List<ArticleResponseDto> findAll(Pageable pageable) {
public List<ArticleResponseDto> findAll(Pageable pageable, User user) {
return articleRepository.findAll(pageable)
.stream()
.map(ArticleResponseDto::new)
.map(article -> new ArticleResponseDto(article, user))
.collect(Collectors.toList());
}
public ArticleResponseDto findById(Long id, User user) {
Article article = articleRepository.findById(id).orElseThrow(ArticleException.passNoExistException(id));
ArticleResponseDto articleResponseDto = new ArticleResponseDto(article);
articleResponseDto.setOwn(article.getUser().getId().equals(user.getId()));
return articleResponseDto;
return new ArticleResponseDto(article, user);
}
public void delete(Long id, User user) {
articleRepository.deleteById(id, user);
}
}