Skip to content

Commit

Permalink
Merge pull request #146 from oduck-team/feature/139
Browse files Browse the repository at this point in the history
고객문의 어드민 서비스 구현 #139
  • Loading branch information
jaycobcoder authored Dec 12, 2023
2 parents 303b070 + 59aeb0c commit 5f292a1
Show file tree
Hide file tree
Showing 29 changed files with 354 additions and 121 deletions.
64 changes: 64 additions & 0 deletions src/main/java/io/oduck/api/domain/admin/entity/Admin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package io.oduck.api.domain.admin.entity;

import io.oduck.api.domain.contact.entity.Answer;
import io.oduck.api.domain.contact.entity.FeedbackType;
import io.oduck.api.domain.contact.service.AnswerHolder;
import io.oduck.api.domain.contact.service.AnswerUpdateHolder;
import io.oduck.api.global.exception.BadRequestException;
import io.oduck.api.global.exception.NotFoundException;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
@Builder
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Table(name = "member")
@Entity
public class Admin {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@OneToMany(mappedBy = "admin", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
private List<Answer> answers = new ArrayList<>();

public void answer(AnswerHolder holder) {
Answer answer = Answer.builder()
.content(holder.getContent())
.helpful(FeedbackType.NONE)
.check(false)
.contact(holder.getContact())
.admin(this)
.build();
answers.add(answer);

answer.answer();
}

public void updateAnswer(AnswerUpdateHolder holder) {
Answer answer = answers.stream()
.filter(a -> a.getId() == holder.getAnswerId())
.findFirst()
.orElseThrow(() -> new NotFoundException("answer"));

if(answer.isCheck() == true) {
throw new BadRequestException("이미 고객이 확인한 문의입니다.");
}

answer.update(holder.getContent());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.oduck.api.domain.admin.repository;

import io.oduck.api.domain.admin.entity.Admin;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface AdminRepository extends JpaRepository<Admin, Long> {

@Query("select distinct a from Admin a join fetch a.answers where a.id = :id")
Optional<Admin> findWithAnswerById(@Param("id") Long id);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.oduck.api.domain.inquiry.dto;
package io.oduck.api.domain.contact.dto;

import io.oduck.api.domain.inquiry.entity.FeedbackType;
import io.oduck.api.domain.contact.entity.FeedbackType;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.oduck.api.domain.inquiry.dto;
package io.oduck.api.domain.contact.dto;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.oduck.api.domain.inquiry.dto;
package io.oduck.api.domain.contact.dto;

import io.oduck.api.domain.inquiry.entity.InquiryType;
import io.oduck.api.domain.contact.entity.InquiryType;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand Down Expand Up @@ -29,8 +29,16 @@ public static class PostReq {
@Getter
@AllArgsConstructor
public static class AnswerReq {
private Long id;
@NotBlank
@Length(min = 1, max = 1000,
message = "글자 수는 1~1000를 허용합니다.")
private String content;
}


@Getter
@AllArgsConstructor
public static class AnswerUpdateReq {
@NotBlank
@Length(min = 1, max = 1000,
message = "글자 수는 1~1000를 허용합니다.")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.oduck.api.domain.inquiry.dto;
package io.oduck.api.domain.contact.dto;

import io.oduck.api.domain.inquiry.dto.ContactReq.PostReq;
import io.oduck.api.domain.inquiry.entity.Contact;
import io.oduck.api.domain.contact.dto.ContactReq.PostReq;
import io.oduck.api.domain.contact.entity.Contact;
import io.oduck.api.domain.member.entity.Member;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
Expand All @@ -18,7 +18,7 @@ public static ContactRequestHolder from(PostReq request, Member member) {
.content(request.getContent())
.type(request.getType())
.answered(false)
.member(member)
.customer(member)
.build();
return new ContactRequestHolder(contact);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.oduck.api.domain.inquiry.dto;
package io.oduck.api.domain.contact.dto;

import io.oduck.api.domain.inquiry.entity.Contact;
import io.oduck.api.domain.contact.entity.Contact;
import java.time.LocalDate;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package io.oduck.api.domain.inquiry.entity;
package io.oduck.api.domain.contact.entity;

import io.oduck.api.domain.admin.entity.Admin;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
Expand All @@ -31,14 +36,26 @@ public class Answer {
@Column(name = "check_answer")
private boolean check = false;

@OneToOne(mappedBy = "answer")
@OneToOne(mappedBy = "answer", cascade = CascadeType.PERSIST)
private Contact contact;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Admin admin;

public void check() {
check = true;
}

public void feedback(FeedbackType helpful) {
this.helpful = helpful;
}

public void update(String content) {
this.content = content;
}

public void answer() {
contact.answer();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.oduck.api.domain.inquiry.entity;
package io.oduck.api.domain.contact.entity;

import io.oduck.api.domain.member.entity.Member;
import io.oduck.api.global.audit.BaseEntity;
Expand Down Expand Up @@ -31,7 +31,7 @@ public class Contact extends BaseEntity {

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
private Member customer;

@Column(nullable = false, length = 100)
private String title;
Expand All @@ -51,4 +51,8 @@ public class Contact extends BaseEntity {
public void feedback(FeedbackType helpful) {
answer.feedback(helpful);
}

public void answer() {
answered = true;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.oduck.api.domain.inquiry.entity;
package io.oduck.api.domain.contact.entity;

public enum FeedbackType {
HELPFUL,
NOT_HELPFUL,
NOT_SELECT
NONE
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.oduck.api.domain.inquiry.entity;
package io.oduck.api.domain.contact.entity;

public enum InquiryType {
ADD_REQUEST,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.oduck.api.domain.inquiry.entity;
package io.oduck.api.domain.contact.entity;

public enum Result {
DELETE,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.oduck.api.domain.inquiry.entity;
package io.oduck.api.domain.contact.entity;

public enum Status {
WAITING,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.oduck.api.domain.contact.repository;

import io.oduck.api.domain.contact.entity.Answer;
import org.springframework.data.jpa.repository.JpaRepository;

public interface AnswerRepository extends JpaRepository<Answer, Long> {

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package io.oduck.api.domain.inquiry.repository;
package io.oduck.api.domain.contact.repository;

import io.oduck.api.domain.inquiry.entity.Contact;
import io.oduck.api.domain.contact.entity.Contact;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface ContactRepository extends JpaRepository<Contact, Long>, ContactRepositoryCustom {

@Query("select c from Contact c join fetch c.member where c.id = :id")
@Query("select c from Contact c join fetch c.customer where c.id = :id")
Optional<Contact> findWithMemberById(@Param("id") Long id);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.oduck.api.domain.inquiry.repository;
package io.oduck.api.domain.contact.repository;

import io.oduck.api.domain.inquiry.dto.ContactRes.MyInquiry;
import io.oduck.api.domain.contact.dto.ContactRes.MyInquiry;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package io.oduck.api.domain.inquiry.repository;
package io.oduck.api.domain.contact.repository;

import static io.oduck.api.domain.inquiry.entity.QAnswer.answer;
import static io.oduck.api.domain.inquiry.entity.QContact.contact;
import static io.oduck.api.domain.contact.entity.QAnswer.answer;
import static io.oduck.api.domain.contact.entity.QContact.contact;

import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import io.oduck.api.domain.inquiry.dto.ContactRes.MyInquiry;
import io.oduck.api.domain.contact.dto.ContactRes.MyInquiry;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -65,6 +65,6 @@ private BooleanExpression idEq(Long id) {
}

private BooleanExpression memberIdEq(Long memberId) {
return memberId == null ? null : contact.member.id.eq(memberId);
return memberId == null ? null : contact.customer.id.eq(memberId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.oduck.api.domain.contact.service;

import io.oduck.api.domain.contact.dto.ContactReq.AnswerReq;
import io.oduck.api.domain.contact.entity.Contact;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class AnswerHolder {
private Contact contact;
private String content;

public static AnswerHolder from(Contact contact, AnswerReq request) {
return new AnswerHolder(contact, request.getContent());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.oduck.api.domain.contact.service;

import io.oduck.api.domain.contact.dto.ContactReq.AnswerUpdateReq;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class AnswerUpdateHolder {
private Long answerId;
private String content;

public static AnswerUpdateHolder from(Long answerId, AnswerUpdateReq request) {
return new AnswerUpdateHolder(answerId, request.getContent());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.oduck.api.domain.inquiry.service;
package io.oduck.api.domain.contact.service;

import io.oduck.api.domain.inquiry.entity.Contact;
import io.oduck.api.domain.contact.entity.Contact;
import io.oduck.api.domain.member.entity.Member;
import io.oduck.api.global.exception.ForbiddenException;
import org.springframework.stereotype.Component;
Expand All @@ -12,10 +12,10 @@ public void isAccessOwnInquiry(Contact contact, Member member) {
if(!isOwnInquiry(contact, member)) {
throw new ForbiddenException("not has permission");
}
contact.getMember().getId();
contact.getCustomer().getId();
}

private boolean isOwnInquiry(Contact contact, Member member) {
return contact.getMember().getId().equals(member.getId());
return contact.getCustomer().getId().equals(member.getId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.oduck.api.domain.contact.service;

import io.oduck.api.domain.contact.dto.ContactReq.AnswerReq;
import io.oduck.api.domain.contact.dto.ContactReq.AnswerUpdateReq;
import io.oduck.api.domain.contact.dto.ContactReq.PostReq;
import io.oduck.api.domain.contact.dto.ContactRes.DetailRes;
import io.oduck.api.domain.contact.dto.ContactRes.MyInquiry;
import io.oduck.api.domain.contact.entity.FeedbackType;
import io.oduck.api.global.common.PageResponse;

public interface ContactService {
void inquiry(Long memberId, PostReq request);

PageResponse<MyInquiry> getAllByMemberId(Long memberId, int page, int size);

DetailRes getByMemberId(Long inquiryId, Long memberId);

boolean hasNotCheckedAnswer(Long id, Long memberId);

void feedbackAnswer(Long id, Long memberId, FeedbackType helpful);

// Page<?> getAll();
//
void answer(Long id, Long adminId, AnswerReq request);

void update(Long answerId, Long adminId, AnswerUpdateReq request);
}
Loading

0 comments on commit 5f292a1

Please sign in to comment.