Skip to content

Commit

Permalink
Merge pull request #220 from woowacourse-teams/feature/192-report-com…
Browse files Browse the repository at this point in the history
…plete

#192 신고 도메인 구현하기
  • Loading branch information
include42 authored Oct 12, 2020
2 parents adbc7d0 + 84f351d commit 55cf090
Show file tree
Hide file tree
Showing 32 changed files with 430 additions and 81 deletions.
5 changes: 5 additions & 0 deletions src/docs/asciidoc/api-docs.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,8 @@ operation::likes/comment-likes/delete[snippets='http-request,http-response,path-
=== 신고 분류 전체 조회

operation::reports/categories[snippets='http-request,http-response,request-headers,response-fields']

[[resources-reports-create]]
=== 신고 생성

operation::reports/create[snippets='http-request,http-response,request-headers,request-fields,response-headers']
13 changes: 2 additions & 11 deletions src/frontend/src/api/modules/report.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,10 @@ const BASE_URL = '/reports';

const ReportService = {
getCategories() {
return ApiService.get(`/reports/categories`);
return ApiService.get(`${BASE_URL}/categories`);
},
create(report) {
createReport(report) {
return ApiService.post(`${BASE_URL}`, report);
},
get(reportId) {
return ApiService.get(`${BASE_URL}/${reportId}`);
},
getAll(params) {
return ApiService.getWithParams(`${BASE_URL}`, params);
},
delete(reportId) {
return ApiService.delete(`${BASE_URL}/${reportId}`);
}
};

Expand Down
45 changes: 31 additions & 14 deletions src/frontend/src/components/ReportButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<v-dialog v-model="dialog" max-width="400">
<v-card>
<v-card-title class="text-h7 pl-3">
이 {{ getReportTypeText() }}을 신고하시겠어요?
이 {{ getReportTargetText() }}을 신고하시겠어요?
</v-card-title>

<v-card-actions>
Expand Down Expand Up @@ -72,11 +72,14 @@
</div>
</template>
<script>
import { REPORT_TYPE } from '@/utils/ReportType.js';
import { REPORT_TARGET } from '@/utils/ReportTarget.js';
import { SHOW_SNACKBAR } from '@/store/shared/mutationTypes';
import { FETCH_REPORT_CATEGORIES } from '@/store/shared/actionTypes';
import {
CREATE_REPORT,
FETCH_REPORT_CATEGORIES
} from '@/store/shared/actionTypes';
import { mapMutations, mapActions, mapGetters } from 'vuex';
import { mapActions, mapGetters, mapMutations } from 'vuex';
export default {
name: 'ReportButton',
Expand All @@ -97,40 +100,54 @@ export default {
methods: {
...mapMutations([SHOW_SNACKBAR]),
...mapActions([FETCH_REPORT_CATEGORIES]),
...mapActions([CREATE_REPORT]),
onReport() {
if (this.choiceCategory === undefined) {
this.invalidCategoryChoice = true;
return;
}
//todo : 여기에 신고 연산이 들어간다
this.dialog = false;
this.showSnackbar('신고가 접수되었습니다. 감사합니다.');
this.submitReport();
},
submitReport() {
const reportCreateRequest = {
content: this.textContent,
targetContentId: this.targetContentId,
reportTarget: this.reportTarget.toString(),
reportCategoryId: this.reportCategories[this.choiceCategory].id
};
this.createReport(reportCreateRequest)
.then(() => {
this.dialog = false;
this.showSnackbar('신고가 접수되었습니다. 감사합니다.');
})
.catch(error => {
this.showSnackbar(error.response.data.errorMessage);
});
},
onClickAlarmButton() {
this.invalidCategoryChoice = false;
this.choiceCategory = undefined;
this.textContent = '';
this.dialog = true;
},
getReportTypeText() {
switch (this.reportType) {
case REPORT_TYPE.ARTICLE:
getReportTargetText() {
switch (this.reportTarget) {
case REPORT_TARGET.ARTICLE:
return '게시물';
case REPORT_TYPE.COMMENT:
case REPORT_TARGET.COMMENT:
return '댓글';
default:
return '게시물';
}
}
},
props: {
reportType: {
reportTarget: {
type: String,
required: true,
default: ''
},
reportedId: {
targetContentId: {
type: Number,
required: true,
default: 0
Expand Down
10 changes: 5 additions & 5 deletions src/frontend/src/components/card/Card.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@
<v-col align="right" justify="end" style="padding:0px" cols="2">
<report-button
v-if="!article.isMine"
:reportType="getReportType()"
:reportedId="article.id"
:reportTarget="getReportTarget()"
:targetContentId="article.id"
/>
</v-col>
</v-row>
Expand All @@ -81,7 +81,7 @@ import EmotionImage from '@/components/card/EmotionImage';
import SubEmotionChips from '@/components/card/SubEmotionChips';
import ReportButton from '@/components/ReportButton';
import DetailCardMenu from '@/components/card/DetailCardMenu';
import { REPORT_TYPE } from '@/utils/ReportType.js';
import { REPORT_TARGET } from '@/utils/ReportTarget.js';
import { mapActions } from 'vuex';
import { LIKE_ARTICLE, UNLIKE_ARTICLE } from '@/store/shared/actionTypes';
Expand Down Expand Up @@ -115,8 +115,8 @@ export default {
});
}
},
getReportType() {
return REPORT_TYPE.ARTICLE;
getReportTarget() {
return REPORT_TARGET.ARTICLE;
},
clickCardContent() {
this.$emit('clickCardContent');
Expand Down
12 changes: 6 additions & 6 deletions src/frontend/src/components/comment/Comment.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@
<div class="pb-2 pr-2">
<report-button
v-if="!comment.isMine"
:reportType="getReportType()"
:reportedId="comment.id"
:reportTarget="getReportTarget()"
:targetContentId="comment.id"
/>
</div>
</v-flex>
Expand All @@ -71,7 +71,7 @@
import CreatedDate from '@/components/CreatedDate';
import CommentMenu from '@/components/comment/CommentMenu';
import ReportButton from '@/components/ReportButton';
import { REPORT_TYPE } from '@/utils/ReportType.js';
import { REPORT_TARGET } from '@/utils/ReportTarget.js';
import { mapActions, mapGetters, mapMutations } from 'vuex';
import { LIKE_COMMENT, UNLIKE_COMMENT } from '@/store/shared/actionTypes';
import { ACTIVATE_RECOMMENT } from '@/store/shared/mutationTypes';
Expand Down Expand Up @@ -148,12 +148,12 @@ export default {
});
}
},
getReportTarget() {
return REPORT_TARGET.COMMENT;
},
specifyMemberToRecomment() {
this.activateRecomment(this.comment.nickname);
},
getReportType() {
return REPORT_TYPE.COMMENT;
},
getCommentNickname() {
return this.comment.nickname === '작성자'
? '✒️ ' + this.comment.nickname
Expand Down
10 changes: 9 additions & 1 deletion src/frontend/src/store/modules/report.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { SET_REPORT_CATEGORIES } from '@/store/shared/mutationTypes';
import { FETCH_REPORT_CATEGORIES } from '@/store/shared/actionTypes';
import {
FETCH_REPORT_CATEGORIES,
CREATE_REPORT
} from '@/store/shared/actionTypes';
import ReportService from '@/api/modules/report';

const state = {
Expand All @@ -25,6 +28,11 @@ const actions = {
commit(SET_REPORT_CATEGORIES, data);
})
.catch(error => commit('catchError', error));
},
async [CREATE_REPORT]({ commit }, report) {
return ReportService.createReport(report).catch(error =>
commit('catchError', error)
);
}
};

Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/store/shared/actionTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ export const UNLIKE_COMMENT = 'unlikeComment';
export const CHECK_NAVBAR_SPACE_NEEDED = 'checkNavbarSpaceNeeded';
export const DELETE_MEMBER = 'deleteMember';
export const FETCH_REPORT_CATEGORIES = 'fetchReportCategories';
export const CREATE_REPORT = 'createReport';
4 changes: 4 additions & 0 deletions src/frontend/src/utils/ReportTarget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const REPORT_TARGET = {
COMMENT: 'COMMENT',
ARTICLE: 'ARTICLE'
};
4 changes: 0 additions & 4 deletions src/frontend/src/utils/ReportType.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public class GlobalExceptionAdvice {
CommentNotFoundException.class,
ArticleNotFoundException.class,
EmotionNotFoundException.class,
ReportCategoryNotFoundException.class,
ReportTargetNotFoundException.class,
IllegalAccessException.class,
DuplicateArticleLikeException.class,
DuplicateCommentLikeException.class})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package com.saebyeok.saebyeok.controller;

import com.saebyeok.saebyeok.controller.resolver.LoginMember;
import com.saebyeok.saebyeok.domain.Member;
import com.saebyeok.saebyeok.domain.report.Report;
import com.saebyeok.saebyeok.dto.report.ReportCategoryResponse;
import com.saebyeok.saebyeok.dto.report.ReportCreateRequest;
import com.saebyeok.saebyeok.service.report.ReportService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.util.List;

@RequestMapping("/api")
Expand All @@ -19,7 +22,16 @@ public class ReportController {
@GetMapping("/reports/categories")
public ResponseEntity<List<ReportCategoryResponse>> getReportCategories() {
List<ReportCategoryResponse> reportCategoryResponses = reportService.getReportCategories();

return ResponseEntity.ok(reportCategoryResponses);
}

@PostMapping("/reports")
public ResponseEntity<Void> createReport(@LoginMember Member member, @RequestBody ReportCreateRequest request) {
Report report = reportService.createReport(member, request);

return ResponseEntity.
created(URI.create("/reports/" + report.getId())).
build();
}
}
58 changes: 58 additions & 0 deletions src/main/java/com/saebyeok/saebyeok/domain/report/Report.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.saebyeok.saebyeok.domain.report;

import com.saebyeok.saebyeok.domain.Member;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import java.time.LocalDateTime;

@EntityListeners(AuditingEntityListener.class)
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Report {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "REPORT_ID")
private Long id;

private String content;
private Long targetContentId;

@Enumerated(EnumType.STRING)
private ReportTarget reportTarget;

@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "MEMBER_ID", nullable = false)
@ManyToOne
private Member member;

@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "REPORT_CATEGORY_ID", nullable = false)
@ManyToOne
private ReportCategory reportCategory;

@CreatedDate
private LocalDateTime createdDate;

private Boolean isFinished = Boolean.FALSE;

public Report(String content, Member member, ReportTarget reportTarget, Long targetContentId, ReportCategory reportCategory) {
this.content = content;
this.member = member;
this.reportTarget = reportTarget;
this.targetContentId = targetContentId;
this.reportCategory = reportCategory;
}

public void finish() {
this.isFinished = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.saebyeok.saebyeok.domain.report;

import org.springframework.data.jpa.repository.JpaRepository;

public interface ReportRepository extends JpaRepository<Report, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.saebyeok.saebyeok.domain.report;

import com.saebyeok.saebyeok.exception.ReportTargetNotFoundException;
import lombok.Getter;

import java.util.Arrays;

@Getter
public enum ReportTarget {
ARTICLE("ARTICLE"),
COMMENT("COMMENT");

private final String name;

ReportTarget(String name) {
this.name = name;
}

public static ReportTarget findReportTarget(String typeValue) {
return Arrays.stream(ReportTarget.values()).
filter(reportTarget -> reportTarget.name().equals(typeValue)).
findAny().
orElseThrow(() -> new ReportTargetNotFoundException(typeValue));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.saebyeok.saebyeok.dto.report;

import com.saebyeok.saebyeok.domain.Member;
import com.saebyeok.saebyeok.domain.report.Report;
import com.saebyeok.saebyeok.domain.report.ReportCategory;
import com.saebyeok.saebyeok.domain.report.ReportTarget;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotNull;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ReportCreateRequest {
private String content;

@NotNull(message = "신고할 게시물을 반드시 선택해 주셔야 해요.")
private Long targetContentId;

@NotNull(message = "신고 분류는 반드시 선택해 주셔야 해요.")
private Long reportCategoryId;

@NotNull(message = "신고할 게시물의 종류는 반드시 선택해 주셔야 해요.")
private String reportTarget;

public Report toReport(Member member, ReportCategory reportCategory) {
return new Report(content, member, ReportTarget.findReportTarget(this.reportTarget), targetContentId, reportCategory);
}
}
Loading

0 comments on commit 55cf090

Please sign in to comment.