detail 페이지
This commit is contained in:
@@ -16,6 +16,15 @@ function getArticles({page = 0, size = 10, q = ''}) {
|
||||
});
|
||||
}
|
||||
|
||||
function getArticle(id) {
|
||||
return axios({
|
||||
url: '/api/articles/' + id,
|
||||
headers: {
|
||||
'Authorization': commonUtil.getAuthenticationHeaderBearer.bind(this)()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function postArticle({title = '', content = ''}) {
|
||||
|
||||
return axios({
|
||||
@@ -33,5 +42,6 @@ function postArticle({title = '', content = ''}) {
|
||||
|
||||
export default {
|
||||
getArticles,
|
||||
getArticle,
|
||||
postArticle
|
||||
}
|
||||
38
src/front/src/pages/articles/Detail.vue
Normal file
38
src/front/src/pages/articles/Detail.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
title : <span v-if="!pending">{{ article.title }}</span>
|
||||
</div>
|
||||
<div>
|
||||
content: <p v-if="!pending">{{ article.content }}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import articleApi from "../../api/articleApi";
|
||||
|
||||
export default {
|
||||
name: "Detail",
|
||||
data() {
|
||||
return {
|
||||
article: null,
|
||||
pending: true
|
||||
}
|
||||
},
|
||||
async beforeCreate() {
|
||||
try {
|
||||
const result = await articleApi.getArticle.bind(this)(this.$route.params.id);
|
||||
this.article = result.data;
|
||||
this.pending = false;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,8 +1,7 @@
|
||||
<template>
|
||||
<div v-if="!pending">
|
||||
<article v-for="article in articles" v-bind:key="article.id">
|
||||
<span>{{ article.title }}</span>
|
||||
<span>{{ article }}</span>
|
||||
<router-link :to="{name: 'DetailArticle', params: {id: article.id}}"><span>{{ article.title }}</span></router-link>
|
||||
</article>
|
||||
|
||||
<div>
|
||||
|
||||
@@ -6,6 +6,7 @@ import Login from "../pages/auth/Login";
|
||||
import Register from "../pages/auth/Register";
|
||||
import Articles from "../pages/articles/List";
|
||||
import WriteArticle from '../pages/articles/Write';
|
||||
import DetailArticle from '../pages/articles/Detail';
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
@@ -31,6 +32,11 @@ export const router = new VueRouter({
|
||||
{
|
||||
path: '/articles/write',
|
||||
component: WriteArticle
|
||||
},
|
||||
{
|
||||
path: '/articles/:id',
|
||||
name: 'DetailArticle',
|
||||
component: DetailArticle
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.example.vue.domain.article;
|
||||
|
||||
import com.example.vue.domain.user.User;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
@@ -15,7 +16,7 @@ import java.time.LocalDateTime;
|
||||
public class Article {
|
||||
|
||||
@Id @GeneratedValue
|
||||
Long id;
|
||||
private Long id;
|
||||
|
||||
@Column(name = "title")
|
||||
private String title;
|
||||
@@ -23,6 +24,9 @@ public class Article {
|
||||
@Column(name = "content")
|
||||
private String content;
|
||||
|
||||
@ManyToOne
|
||||
private User user;
|
||||
|
||||
@CreatedDate
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
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.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -20,6 +22,12 @@ public class ArticleController {
|
||||
return articleService.findAll(pageable);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/{articleId}")
|
||||
@Transactional(readOnly = true)
|
||||
public ArticleResponseDto getArticle(@PathVariable Long articleId, @AuthenticationPrincipal User user) {
|
||||
return articleService.findById(articleId, user);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Transactional
|
||||
public ArticleResponseDto postArticles(@RequestBody @Valid ArticleRequestDto articleRequestDto) {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.example.vue.domain.article;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ArticleException {
|
||||
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public static class NoExist extends RuntimeException {
|
||||
public NoExist(Long id) {
|
||||
super("존재하지 않는 게시글입니다. [articleId=" + id + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public static Supplier<NoExist> passNoExistException(Long id) {
|
||||
return () -> new NoExist(id);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
@@ -29,4 +30,8 @@ public class ArticleRepository {
|
||||
.getResultList();
|
||||
}
|
||||
|
||||
public Optional<Article> findById(Long id) {
|
||||
return Optional.ofNullable(em.find(Article.class, id));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.example.vue.domain.article;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@@ -11,6 +11,9 @@ public class ArticleResponseDto {
|
||||
private Long id;
|
||||
private String title;
|
||||
private String content;
|
||||
|
||||
@JsonProperty("isOwn")
|
||||
private boolean isOwn;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
|
||||
@@ -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.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -24,4 +25,11 @@ public class ArticleService {
|
||||
.map(ArticleResponseDto::new)
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user