fix: User Repository, Service Refactoring.
This commit is contained in:
29
README.md
29
README.md
@@ -35,4 +35,31 @@ you can See Vue.js + SpringBoot FullStack Web Site Demo
|
||||
|
||||
#### **Total 82% Code Coverage**
|
||||
|
||||
------
|
||||
-----
|
||||
|
||||
# How it works
|
||||
|
||||
- Spring Boot(Java)
|
||||
- JPA
|
||||
- Security
|
||||
- H2
|
||||
- Vue3
|
||||
- Vite
|
||||
- vuerouter
|
||||
- vuex
|
||||
- localStorage
|
||||
|
||||
# Getting started
|
||||
|
||||
## Run Local
|
||||
```shell
|
||||
./gradlew bootRun
|
||||
```
|
||||
|
||||
# FrontEnd
|
||||
|
||||
**I don't know much about the front end. I wanted to create a visible application, so I adopted and implemented that framework.**
|
||||
|
||||
But my codes are simple codes that even beginners can easily see.
|
||||
|
||||
|
||||
|
||||
@@ -61,9 +61,10 @@ public class CommentServiceImpl implements CommentService {
|
||||
if (article.isEmpty()) {
|
||||
throw new CustomException(Error.ARTICLE_NOT_FOUND);
|
||||
}
|
||||
System.out.println(user.get().getUsername()+"!!");
|
||||
Comment comment = commentRepository.save(Comment.builder().body(commentdto.getBody()).article(article.get()).author(user.get()).build());
|
||||
|
||||
return convertComment(userAuth, article.get(), comment);
|
||||
return convertComment(userAuth, comment);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,9 +81,9 @@ public class CommentServiceImpl implements CommentService {
|
||||
commentRepository.delete(comment.get());
|
||||
}
|
||||
|
||||
private CommentResponse convertComment(UserAuth userAuth, Article article, Comment comment) {
|
||||
private CommentResponse convertComment(UserAuth userAuth, Comment comment) {
|
||||
|
||||
ProfileResponse profile = profileService.getProfile(userAuth, article.getAuthor().getUsername());
|
||||
ProfileResponse profile = profileService.getProfile(userAuth, userAuth.getUsername());
|
||||
|
||||
return CommentResponse.builder()
|
||||
.id(comment.getId())
|
||||
|
||||
@@ -2,9 +2,6 @@ package com.io.realworld.domain.aggregate.user.repository;
|
||||
|
||||
import com.io.realworld.domain.aggregate.user.entity.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.io.realworld.domain.aggregate.user.service;
|
||||
|
||||
import com.io.realworld.domain.aggregate.user.dto.*;
|
||||
import com.io.realworld.domain.aggregate.user.entity.User;
|
||||
|
||||
public interface UserService {
|
||||
UserResponse signup(UserSignupRequest userSignupRequest);
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.io.realworld.domain.aggregate.user.entity.User;
|
||||
import com.io.realworld.domain.aggregate.user.repository.UserRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -17,7 +16,6 @@ import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Log4j2
|
||||
public class UserServiceImpl implements UserService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
|
||||
@@ -74,7 +74,7 @@ const createArticle = async (article: object | undefined): Promise<AxiosResponse
|
||||
})
|
||||
}
|
||||
|
||||
const updateArticle = async (article: object | undefined, slug: string): Promise<AxiosResponse> => {
|
||||
const updateArticle = async (article: object | undefined, slug: string | undefined): Promise<AxiosResponse> => {
|
||||
let currentToken = localStorage.getItem("token");
|
||||
return await axiosService.put('/api/articles/' + slug, { article },{
|
||||
headers :{
|
||||
@@ -84,6 +84,16 @@ const updateArticle = async (article: object | undefined, slug: string): Promise
|
||||
})
|
||||
}
|
||||
|
||||
const deleteArticle = async (slug: string | undefined): Promise<AxiosResponse> => {
|
||||
let currentToken = localStorage.getItem("token");
|
||||
return await axiosService.delete('/api/articles/' + slug,{
|
||||
headers :{
|
||||
Authorization : "TOKEN " + currentToken,
|
||||
"Content-Type": `application/json`,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const listArticles = async (): Promise<AxiosResponse> => {
|
||||
let currentToken = localStorage.getItem("token");
|
||||
if(currentToken == null){
|
||||
@@ -171,6 +181,17 @@ const getCommentsFromArticle = async (slug: string | undefined): Promise<AxiosRe
|
||||
}
|
||||
}
|
||||
|
||||
const deleteCommentsFromArticle = async (slug: string | undefined, id: number): Promise<AxiosResponse> => {
|
||||
let currentToken = localStorage.getItem("token");
|
||||
return await axiosService.delete('/api/articles/' + slug + '/comments/' + id,{
|
||||
headers:{
|
||||
Authorization : "TOKEN " + currentToken,
|
||||
"Content-Type": `application/json`,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const favoriteArticle = async (slug: string | undefined): Promise<AxiosResponse> => {
|
||||
let currentToken = localStorage.getItem("token");
|
||||
return await axiosService.post('/api/articles/' + slug + '/favorite',{},
|
||||
@@ -206,5 +227,6 @@ export { signUp, signIn,
|
||||
addCommentToArticle, getCommentsFromArticle,
|
||||
favoriteArticle, unFavoriteArticle,
|
||||
listArticlesByFavorite, updateArticle,
|
||||
deleteArticle, deleteCommentsFromArticle,
|
||||
getTags
|
||||
}
|
||||
@@ -7,17 +7,21 @@
|
||||
<a href="javascript:(0)" class="comment-author" @click="viewProfile">
|
||||
<img :src="comment.author.image" class="comment-author-img"/>
|
||||
</a>
|
||||
|
||||
<a href="javascript:(0)" class="comment-author" @click="viewProfile">{{comment.author.username}}</a>
|
||||
<span class="date-posted">{{convertDate(comment.updatedAt)}}</span>
|
||||
<span v-if="isMe" class="mod-options" @click="deleteComment">
|
||||
<i class="ion-trash-a"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent,} from "vue";
|
||||
import {defineComponent, defineEmits, onMounted, ref,} from "vue";
|
||||
import convertDate from "@/ts/common";
|
||||
import router from "@/router";
|
||||
|
||||
import {useStore} from "vuex";
|
||||
export default defineComponent({
|
||||
name: "commentList",
|
||||
props:{
|
||||
@@ -36,7 +40,10 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
},
|
||||
setup(props){
|
||||
setup(props, {emit}){
|
||||
const store = useStore();
|
||||
|
||||
const isMe = ref(false);
|
||||
|
||||
const viewProfile = () => {
|
||||
router.push({
|
||||
@@ -44,7 +51,19 @@ export default defineComponent({
|
||||
params: {username: props.comment.author.username}})
|
||||
}
|
||||
|
||||
return { convertDate, viewProfile}
|
||||
const deleteComment = () => {
|
||||
emit('delete:comment', props.comment.id);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if(store.state.username == props.comment.author.username){
|
||||
isMe.value = true;
|
||||
}else{
|
||||
isMe.value = false;
|
||||
}
|
||||
})
|
||||
|
||||
return { isMe, convertDate, viewProfile, deleteComment}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
@@ -34,7 +34,7 @@ const routes = [
|
||||
component: () => import(/* webpackChunkName "inputTag" */ '@/views/TheArticle.vue')
|
||||
},
|
||||
{
|
||||
path: "/editor/@:slug",
|
||||
path: "/editor/:slug",
|
||||
name: "ArticleUpdateEditor",
|
||||
component: () => import(/* webpackChunkName "inputTag" */ '@/views/ArticleUpdate.vue'),
|
||||
props: true
|
||||
|
||||
@@ -31,33 +31,29 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { reactive } from "vue";
|
||||
import { reactive, defineComponent } from "vue";
|
||||
import { updateArticle } from "@/api/index.js";
|
||||
import router from "@/router";
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: "ArticleUpdate",
|
||||
props:{
|
||||
slug: String,
|
||||
},
|
||||
setup(){
|
||||
setup(props){
|
||||
const article = reactive({
|
||||
title: "",
|
||||
description: "",
|
||||
body: "",
|
||||
})
|
||||
|
||||
const getSlug = (title:string) => {
|
||||
return title.replace(' ','-');
|
||||
}
|
||||
|
||||
const updateContent = async () => {
|
||||
const slug = getSlug(article.title);
|
||||
try{
|
||||
await updateArticle(article, slug);
|
||||
const { data } = await updateArticle(article, props.slug);
|
||||
await router.push({
|
||||
name:"ArticleDetail",
|
||||
params: {slug}
|
||||
params: {slug: data.article.slug}
|
||||
})
|
||||
}catch (error: any){
|
||||
alert(error);
|
||||
@@ -66,7 +62,7 @@ export default {
|
||||
|
||||
return { article, updateContent }
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<i class="ion-edit"></i>
|
||||
Edit Article
|
||||
</button>
|
||||
<button v-if= "isMe" class="btn btn-outline-danger btn-sm" @click="followUpdate(articleDetail.article.author.following)">
|
||||
<button v-if= "isMe" class="btn btn-outline-danger btn-sm" @click="articleDelete()">
|
||||
<i class="ion-trash-a"></i>
|
||||
Delete Article
|
||||
</button>
|
||||
@@ -62,11 +62,11 @@
|
||||
<a href="javascript:void(0)" class="author" @click="viewProfile">{{ articleDetail.article.author.username }}</a>
|
||||
<span class="date">{{convertDate(articleDetail.article.createdAt)}}</span>
|
||||
</div>
|
||||
<button v-if= "isMe" class="btn btn-sm btn-outline-secondary" @click="followUpdate(articleDetail.article.author.following)">
|
||||
<button v-if= "isMe" class="btn btn-sm btn-outline-secondary" @click="articleUpdate()">
|
||||
<i class="ion-edit"></i>
|
||||
Edit Article
|
||||
</button>
|
||||
<button v-if= "isMe" class="btn btn-outline-danger btn-sm" @click="followUpdate(articleDetail.article.author.following)">
|
||||
<button v-if= "isMe" class="btn btn-outline-danger btn-sm" @click="articleDelete()">
|
||||
<i class="ion-trash-a"></i>
|
||||
Delete Article
|
||||
</button>
|
||||
@@ -112,6 +112,7 @@
|
||||
<comment-list v-for="(comment,index) in getCommentList.comment"
|
||||
:key="comment.id"
|
||||
:comment="comment"
|
||||
@delete:comment="deleteComment"
|
||||
:imgs="comment.author.image">
|
||||
</comment-list>
|
||||
</div>
|
||||
@@ -130,7 +131,7 @@ import router from "@/router";
|
||||
import { useStore } from "vuex";
|
||||
import convertDate from "@/ts/common";
|
||||
import {
|
||||
addCommentToArticle,
|
||||
addCommentToArticle, deleteArticle, deleteCommentsFromArticle,
|
||||
favoriteArticle,
|
||||
followUser,
|
||||
getArticle,
|
||||
@@ -157,7 +158,7 @@ export default defineComponent({
|
||||
})
|
||||
|
||||
const getCommentList = reactive({
|
||||
comment: reactive([{id:0,author:{image:""}}])
|
||||
comment: reactive([{id:0,author:{username:"",image:""}}])
|
||||
})
|
||||
|
||||
const articleDetail = reactive({
|
||||
@@ -188,11 +189,18 @@ export default defineComponent({
|
||||
|
||||
const articleUpdate = async () => {
|
||||
await router.push({
|
||||
name: 'ArticleEditor',
|
||||
name: 'ArticleUpdateEditor',
|
||||
params: {slug: articleDetail.article.slug}
|
||||
})
|
||||
}
|
||||
|
||||
const articleDelete = async () => {
|
||||
await deleteArticle(articleDetail.article.slug);
|
||||
await router.push({
|
||||
name: 'Home'
|
||||
})
|
||||
}
|
||||
|
||||
const followUpdate = async (followState: boolean) => {
|
||||
if(token == ''){
|
||||
await router.push({name:"Login"});
|
||||
@@ -241,6 +249,11 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
const deleteComment = async (commentId: number) => {
|
||||
await deleteCommentsFromArticle(articleDetail.article.slug,commentId);
|
||||
getCommentList.comment.splice(commentId,1);
|
||||
}
|
||||
|
||||
onMounted(async ()=>{
|
||||
try{
|
||||
const { data } = await getArticle(props.slug);
|
||||
@@ -260,7 +273,7 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
|
||||
return { isMe, articleDetail, comment, getCommentList, convertDate, viewProfile, articleUpdate, followUpdate, favoriteUpdate, sendComment }
|
||||
return { isMe, articleDetail, comment, getCommentList, convertDate, deleteComment, viewProfile, articleUpdate, followUpdate, favoriteUpdate, sendComment, articleDelete }
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user