diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/domain/answer/service/AnswerService.java b/baebae-BE/src/main/java/com/web/baebaeBE/domain/answer/service/AnswerService.java new file mode 100644 index 00000000..3b1537cd --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/domain/answer/service/AnswerService.java @@ -0,0 +1,83 @@ +package com.web.baebaeBE.domain.answer.service; + +import com.web.baebaeBE.infra.answer.entity.Answer; +import com.web.baebaeBE.infra.answer.repository.AnswerRepository; +import com.web.baebaeBE.infra.question.entity.Question; +import com.web.baebaeBE.infra.question.repository.QuestionRepository; +import com.web.baebaeBE.presentation.answer.dto.AnswerCreateRequest; +import com.web.baebaeBE.presentation.answer.dto.AnswerDetailResponse; +import jakarta.transaction.Transactional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + + +@Service +public class AnswerService { + private final QuestionRepository questionRepository; + private final AnswerRepository answerRepository; + + @Autowired + public AnswerService(QuestionRepository questionRepository, AnswerRepository answerRepository) { + this.questionRepository = questionRepository; + this.answerRepository = answerRepository; + } + @Transactional + public Answer createAnswer(AnswerCreateRequest request) { + Question question = questionRepository.findById(request.getQuestionId()) + .orElseThrow(() -> new IllegalArgumentException("Question not found with ID")); + + Answer answer = Answer.builder() + .question(question) + .content(request.getContent()) + .linkAttachment(request.getLinkAttachment()) + .musicSearch(request.getMusicSearch()) + .imageFiles(request.getImageFiles()) + .createdDate(LocalDateTime.now()) + .likeCount(0) + .build(); + + return answerRepository.save(answer); + } + + @Transactional + public Page getAllAnswers(Long memberId, Pageable pageable) { + Page answersPage = answerRepository.findAllByMemberId(memberId, pageable); + return answersPage.map(answer -> AnswerDetailResponse.of(answer.getId(), answer.getQuestion().getId(), + answer.getMember().getId(), answer.getContent(),answer.getLinkAttachment(), answer.getMusicSearch(), + answer.getImageFiles(), answer.getCreatedDate(), answer.getLikeCount())); + + } + + @Transactional + public AnswerDetailResponse updateAnswer(Long answerId, AnswerCreateRequest request) { + Answer answer = answerRepository.findByAnswerId(answerId) + .orElseThrow(() -> new IllegalArgumentException("Answer not found with ID: " + answerId)); + + answer.setContent(request.getContent()); + answer.setLinkAttachment(request.getLinkAttachment()); + answer.setMusicSearch(request.getMusicSearch()); + answer.setImageFiles(request.getImageFiles()); + + Answer updatedAnswer = answerRepository.save(answer); + return AnswerDetailResponse.of( + updatedAnswer.getId(), + updatedAnswer.getQuestion().getId(), + updatedAnswer.getMember().getId(), + updatedAnswer.getContent(), + updatedAnswer.getLinkAttachment(), + updatedAnswer.getMusicSearch(), + updatedAnswer.getImageFiles(), + updatedAnswer.getCreatedDate(), + updatedAnswer.getLikeCount()); + } + @Transactional + public void deleteAnswer(Long answerId) { + Answer answer = answerRepository.findByAnswerId(answerId) + .orElseThrow(() -> new IllegalArgumentException("Answer not found with ID: " + answerId)); + answerRepository.delete(answer); + } +} diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/domain/question/service/QuestionService.java b/baebae-BE/src/main/java/com/web/baebaeBE/domain/question/service/QuestionService.java new file mode 100644 index 00000000..7ef10ad8 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/domain/question/service/QuestionService.java @@ -0,0 +1,87 @@ +package com.web.baebaeBE.domain.question.service; + +import com.web.baebaeBE.infra.member.entity.Member; +import com.web.baebaeBE.infra.member.repository.MemberRepository; +import com.web.baebaeBE.infra.question.entity.QuestionEntity; +import com.web.baebaeBE.infra.question.repository.QuestionRepository; +import com.web.baebaeBE.presentation.question.dto.QuestionCreateRequest; +import com.web.baebaeBE.presentation.question.dto.QuestionDetailResponse; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + + +@Service +public class QuestionService { + private final QuestionRepository questionRepository; + private final MemberRepository memberRepository; + + @Autowired + public QuestionService(QuestionRepository questionRepository, MemberRepository memberRepository) { + this.questionRepository = questionRepository; + this.memberRepository = memberRepository; + } + + @Transactional + public QuestionDetailResponse createQuestion(Long memberId, QuestionCreateRequest request) { + if (request.getContent() == null || request.getContent().trim().isEmpty()) { + throw new IllegalArgumentException("Content cannot be empty."); + } + + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new IllegalArgumentException("No member found with id")); + + QuestionEntity questionEntity = QuestionEntity.builder() + .member(member) + .content(request.getContent()) + .createdDate(LocalDateTime.now()) + .build(); + + QuestionEntity savedQuestionEntity = questionRepository.save(questionEntity); + return QuestionDetailResponse.of( + savedQuestionEntity.getId(), + savedQuestionEntity.getContent(), + member.getNickname(), + savedQuestionEntity.getCreatedDate()); + } + + @Transactional(readOnly = true) + public Page getAllQuestions(Long memberId, Pageable pageable) { + Page questionsPage = questionRepository.findAllByMemberId(memberId, pageable); + return questionsPage.map(question -> QuestionDetailResponse.of(question.getId(), question.getContent(), + question.getMember().getEmail(), + question.getCreatedDate())); + } + + + @Transactional + public QuestionDetailResponse updateQuestion(Long questionId, String content) { + if (content == null || content.trim().isEmpty()) { + throw new IllegalArgumentException("Question content cannot be empty."); + } + + QuestionEntity questionEntity = questionRepository.findById(questionId) + .orElseThrow(() -> new IllegalArgumentException("No question found with id")); + + questionEntity.updateContent(content); + QuestionEntity updatedQuestionEntity = questionRepository.save(questionEntity); + return QuestionDetailResponse.of( + updatedQuestionEntity.getId(), + updatedQuestionEntity.getContent(), + updatedQuestionEntity.getMember().getNickname(), + updatedQuestionEntity.getCreatedDate()); + } + + @Transactional + public void deleteQuestion(Long questionId) { + QuestionEntity questionEntity = questionRepository.findById(questionId) + .orElseThrow(() -> new IllegalArgumentException("No question found with id")); + questionRepository.delete(questionEntity); + } + + +} diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/global/converter/StringListConverter.java b/baebae-BE/src/main/java/com/web/baebaeBE/global/converter/StringListConverter.java new file mode 100644 index 00000000..04bc5ff7 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/global/converter/StringListConverter.java @@ -0,0 +1,21 @@ +package com.web.baebaeBE.global.converter; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +import java.util.Arrays; +import java.util.List; + +@Converter(autoApply = true) +public class StringListConverter implements AttributeConverter , String> { + + @Override + public String convertToDatabaseColumn(List attribute) { + return (attribute == null || attribute.isEmpty()) ? "" : String.join(",", attribute); + } + + @Override + public List convertToEntityAttribute(String dbData) { + return (dbData == null || dbData.trim().isEmpty()) ? null : Arrays.asList(dbData.split(",")); + } +} diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/entity/Answer.java b/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/entity/Answer.java new file mode 100644 index 00000000..bf452231 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/entity/Answer.java @@ -0,0 +1,54 @@ + +package com.web.baebaeBE.infra.answer.entity; + +import com.web.baebaeBE.global.converter.StringListConverter; +import com.web.baebaeBE.infra.member.entity.Member; +import com.web.baebaeBE.infra.question.entity.Question; +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.annotations.Type; + +import java.time.LocalDateTime; +import java.util.List; + +@Entity +@Table(name = "answer") +@Getter +@Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@Builder +public class Answer { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "answer_id", updatable = false, nullable = false) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "question_id", nullable = false) + private Question question; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id", nullable = false) + private Member member; + + @Column(nullable = false, columnDefinition = "TEXT") + private String content; + + @Column(name = "link_attachment", nullable = true, length = 255) + private String linkAttachment; + + @Column(name = "music_search", nullable = true, length = 255) + private String musicSearch; + + @Convert(converter = StringListConverter.class) + @Column(name = "image_file", nullable = true) + private List imageFiles; + + @Column(name = "created_date", nullable = false) + private LocalDateTime createdDate; + + @Column(name = "like_count", nullable = false) + private Integer likeCount; + +} diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/repository/AnswerJpaRepository.java b/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/repository/AnswerJpaRepository.java new file mode 100644 index 00000000..ebfc4e02 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/repository/AnswerJpaRepository.java @@ -0,0 +1,10 @@ +package com.web.baebaeBE.infra.answer.repository; + +import com.web.baebaeBE.infra.answer.entity.Answer; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AnswerJpaRepository extends JpaRepository { + Page findAllByMemberId(Long memberId, Pageable pageable); +} diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/repository/AnswerRepository.java b/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/repository/AnswerRepository.java new file mode 100644 index 00000000..60825307 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/repository/AnswerRepository.java @@ -0,0 +1,15 @@ +package com.web.baebaeBE.infra.answer.repository; + +import com.web.baebaeBE.infra.answer.entity.Answer; +import com.web.baebaeBE.infra.question.entity.Question; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.Optional; + +public interface AnswerRepository { + Optional findByAnswerId(Long answerId); + Answer save(Answer answer); + Page findAllByMemberId(Long memberId, Pageable pageable); + void delete(Answer answer); +} diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/repository/AnswerRepositoryImpl.java b/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/repository/AnswerRepositoryImpl.java new file mode 100644 index 00000000..568af393 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/infra/answer/repository/AnswerRepositoryImpl.java @@ -0,0 +1,41 @@ +package com.web.baebaeBE.infra.answer.repository; + +import com.web.baebaeBE.infra.answer.entity.Answer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +@Primary +public class AnswerRepositoryImpl implements AnswerRepository{ + private final AnswerJpaRepository jpaRepository; + + @Autowired + public AnswerRepositoryImpl(AnswerJpaRepository jpaRepository) { + this.jpaRepository = jpaRepository; + } + + @Override + public Optional findByAnswerId(Long answerId) { + return jpaRepository.findById(answerId); + } + + @Override + public Answer save(Answer answer) { + return jpaRepository.save(answer); + } + + @Override + public Page findAllByMemberId(Long memberId, Pageable pageable) { + return jpaRepository.findAllByMemberId(memberId, pageable); + } + + @Override + public void delete(Answer answerEntity) { + jpaRepository.delete(answerEntity); + } +} diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/entity/Question.java b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/entity/Question.java new file mode 100644 index 00000000..8f2f0377 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/entity/Question.java @@ -0,0 +1,17 @@ +package com.web.baebaeBE.infra.question.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +@AllArgsConstructor + +public class Question { + private Long questionId; + private Long memberId; + private String content; + private LocalDateTime createdDate; +} + diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/entity/QuestionEntity.java b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/entity/QuestionEntity.java new file mode 100644 index 00000000..2a5ee63b --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/entity/QuestionEntity.java @@ -0,0 +1,37 @@ +package com.web.baebaeBE.infra.question.entity; + +import com.web.baebaeBE.infra.member.entity.Member; +import jakarta.persistence.*; +import lombok.*; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "question") +@Getter +@Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@Builder +public class QuestionEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "question_id", updatable = false, nullable = false) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id", nullable = false) + private Member member; + + @Column(nullable = false, columnDefinition = "TEXT") + private String content; + + @Column(name = "created_date", nullable = false, length = 30) + private LocalDateTime createdDate; + + public void updateContent(String content) { + this.content = content; + } + +} + diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionJpaRepository.java b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionJpaRepository.java new file mode 100644 index 00000000..d0612534 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionJpaRepository.java @@ -0,0 +1,11 @@ +package com.web.baebaeBE.infra.question.repository; + +import com.web.baebaeBE.infra.question.entity.QuestionEntity; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface QuestionJpaRepository extends JpaRepository { + Page findAllByMemberId(Long memberId, Pageable pageable); +} + diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionMapper.java b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionMapper.java new file mode 100644 index 00000000..db30eb20 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionMapper.java @@ -0,0 +1,45 @@ +package com.web.baebaeBE.infra.question.repository; + +import com.web.baebaeBE.infra.member.entity.Member; +import com.web.baebaeBE.infra.member.repository.MemberRepository; +import com.web.baebaeBE.infra.question.entity.Question; +import com.web.baebaeBE.infra.question.entity.QuestionEntity; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +@Component +@RequiredArgsConstructor +public class QuestionMapper { + private final MemberRepository memberRepository; + + public QuestionEntity toEntity(Question question, String email) { + Optional optionalMember = memberRepository.findByEmail(email); + Member member = optionalMember.orElseThrow(() -> new IllegalArgumentException("No member found with email: " + email)); + + return QuestionEntity.builder() + .content(question.getContent()) + .member(member) + .build(); + } + + public QuestionEntity toEntity(Question question, Long memberId) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new IllegalArgumentException("No member found with id: " + memberId)); + + return QuestionEntity.builder() + .content(question.getContent()) + .member(member) + .build(); + } + + public Question toDomain(QuestionEntity questionEntity) { + return new Question( + questionEntity.getId(), + questionEntity.getMember().getId(), + questionEntity.getContent() + ); + } +} + diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionRepository.java b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionRepository.java new file mode 100644 index 00000000..2dd63575 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionRepository.java @@ -0,0 +1,18 @@ +package com.web.baebaeBE.infra.question.repository; + +import com.web.baebaeBE.infra.question.entity.QuestionEntity; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.Optional; + + +public interface QuestionRepository{ +// Optional findById(Long questionId); + Optional findById(Long questionId); + QuestionEntity save(QuestionEntity questionEntity); + Page findAllByMemberId(Long memberId, Pageable pageable); + void delete(QuestionEntity questionEntity); + +} + diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionRepositoryImpl.java b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionRepositoryImpl.java new file mode 100644 index 00000000..3539f5f2 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/infra/question/repository/QuestionRepositoryImpl.java @@ -0,0 +1,44 @@ +package com.web.baebaeBE.infra.question.repository; + +import com.web.baebaeBE.infra.question.entity.QuestionEntity; +import org.springframework.context.annotation.Primary; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +@Primary +public class QuestionRepositoryImpl implements QuestionRepository{ + private final QuestionJpaRepository questionJpaRepository; +// private final QuestionMapper questionMapper; + + public QuestionRepositoryImpl(QuestionJpaRepository questionJpaRepository /*, QuestionMapper questionMapper*/) { + this.questionJpaRepository = questionJpaRepository; +// this.questionMapper = questionMapper; + } + + @Override + public Optional findById(Long questionId) { + return questionJpaRepository.findById(questionId); + } + + @Override + public QuestionEntity save(QuestionEntity questionEntity) { + return questionJpaRepository.save(questionEntity); + } + + @Override + public Page findAllByMemberId(Long memberId, Pageable pageable) { + return questionJpaRepository.findAllByMemberId(memberId, pageable); + } + + @Override + public void delete(QuestionEntity questionEntity) { + questionJpaRepository.delete(questionEntity); + } +} + + + diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/presentation/answer/AnswerController.java b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/answer/AnswerController.java new file mode 100644 index 00000000..b8a8202c --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/answer/AnswerController.java @@ -0,0 +1,55 @@ +package com.web.baebaeBE.presentation.answer; + +import com.web.baebaeBE.domain.answer.service.AnswerService; +import com.web.baebaeBE.infra.answer.entity.Answer; +import com.web.baebaeBE.presentation.answer.dto.AnswerCreateRequest; +import com.web.baebaeBE.presentation.answer.dto.AnswerDetailResponse; +import io.swagger.v3.oas.annotations.Operation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/answers") +public class AnswerController { + private final AnswerService answerService; + + @Autowired + public AnswerController(AnswerService answerService) { + this.answerService = answerService; + } + + @Operation(summary = "피드 생성") + @PostMapping("/member/{memberId}") + public ResponseEntity createAnswer(@RequestBody AnswerCreateRequest request) { + Answer createdAnswer = answerService.createAnswer(request); + return ResponseEntity.status(HttpStatus.CREATED).body(createdAnswer); + } + + @Operation(summary = "피드 조회") + @GetMapping + public ResponseEntity> getAllAnswers(@RequestParam Long memberId, Pageable pageable) { + List answers = answerService.getAllAnswers(memberId, pageable).getContent(); + return new ResponseEntity<>(answers, HttpStatus.OK); + } + + @Operation(summary = "피드 수정") + @PutMapping("/{answerId}") + public ResponseEntity updateAnswer(@PathVariable Long answerId, @RequestBody AnswerCreateRequest request) { + AnswerDetailResponse updatedAnswer = answerService.updateAnswer(answerId, request); + return ResponseEntity.ok(updatedAnswer); + } + + @Operation(summary = "피드 삭제") + @DeleteMapping("/{answerId}") + public ResponseEntity deleteAnswer(@PathVariable Long answerId) { + answerService.deleteAnswer(answerId); + return ResponseEntity.noContent().build(); + } + +} diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/presentation/answer/dto/AnswerCreateRequest.java b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/answer/dto/AnswerCreateRequest.java new file mode 100644 index 00000000..2fd7f340 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/answer/dto/AnswerCreateRequest.java @@ -0,0 +1,28 @@ +package com.web.baebaeBE.presentation.answer.dto; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class AnswerCreateRequest { + private Long questionId; + private String content; + private String linkAttachment; + private String musicSearch; + private List imageFiles; + + public AnswerCreateRequest(Long questionId, String content, String linkAttachment, String musicSearch, List imageFiles) { + this.questionId = questionId; + this.content = content; + this.linkAttachment = linkAttachment; + this.musicSearch = musicSearch; + this.imageFiles = imageFiles; + } + + public static AnswerCreateRequest of(Long questionId, String content, String linkAttachment, String musicSearch, List imageFiles) { + return new AnswerCreateRequest(questionId, content, linkAttachment, musicSearch, imageFiles); + } +} diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/presentation/answer/dto/AnswerDetailResponse.java b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/answer/dto/AnswerDetailResponse.java new file mode 100644 index 00000000..ac2183f0 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/answer/dto/AnswerDetailResponse.java @@ -0,0 +1,42 @@ +package com.web.baebaeBE.presentation.answer.dto; + +import com.web.baebaeBE.infra.answer.entity.Answer; +import com.web.baebaeBE.presentation.question.dto.QuestionDetailResponse; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; +import java.util.List; + +@Getter +@Setter +public class AnswerDetailResponse { + private Long answerId; + private Long questionId; + private Long memberId; + private String content; + private String linkAttachment; + private String musicSearch; + private List imageFiles; + private LocalDateTime createdDate; + private Integer likeCount; + + public AnswerDetailResponse(Long answerId, Long questionId, Long memberId, String content, String linkAttachment, + String musicSearch, List imageFiles, LocalDateTime createdDate, Integer likeCount) { + this.answerId = answerId; + this.questionId = questionId; + this.memberId = memberId; + this.content = content; + this.linkAttachment = linkAttachment; + this.musicSearch = musicSearch; + this.imageFiles = imageFiles; + this.createdDate = createdDate; + this.likeCount = likeCount; + } + + public static AnswerDetailResponse of(Long answerId, Long questionId, Long memberId, String content, String linkAttachment, + String musicSearch, List imageFiles, LocalDateTime createdDate, Integer likeCount) { + return new AnswerDetailResponse(answerId, questionId, memberId, content, linkAttachment, + musicSearch, imageFiles, createdDate, likeCount); + } +} diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/QuestionController.java b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/QuestionController.java new file mode 100644 index 00000000..ac8a2d5b --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/QuestionController.java @@ -0,0 +1,54 @@ +package com.web.baebaeBE.presentation.question; + +import com.web.baebaeBE.domain.question.service.QuestionService; +import com.web.baebaeBE.presentation.question.dto.QuestionCreateRequest; +import com.web.baebaeBE.presentation.question.dto.QuestionDetailResponse; +import io.swagger.v3.oas.annotations.Operation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/questions") +public class QuestionController { + private final QuestionService questionService; + + @Autowired + public QuestionController(QuestionService questionService) { + this.questionService = questionService; + } + + @Operation(summary = "질문 생성") + @PostMapping("/member/{memberId}") + public ResponseEntity createQuestion(@RequestBody QuestionCreateRequest questionDTO, @PathVariable Long memberId) { + QuestionDetailResponse createdQuestion = questionService.createQuestion(memberId, questionDTO); + return ResponseEntity.status(HttpStatus.CREATED).body(createdQuestion); + } + + @Operation(summary = "질문 조회") + @GetMapping() + public ResponseEntity> getAllQuestions(@RequestParam Long memberId, Pageable pageable) { + List questions = questionService.getAllQuestions(memberId, pageable).getContent(); + return new ResponseEntity<>(questions, HttpStatus.OK); + } + + @Operation(summary = "질문 수정") + @PutMapping("/{questionId}") + public ResponseEntity updateQuestion(@PathVariable Long questionId, @RequestParam String content) { + questionService.updateQuestion(questionId, content); + return ResponseEntity.status(HttpStatus.NO_CONTENT).body(null); + } + + @Operation(summary = "질문 삭제") + @DeleteMapping("/{questionId}") + public ResponseEntity deleteQuestion(@PathVariable Long questionId) { + questionService.deleteQuestion(questionId); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } +} + diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/dto/QuestionCreateRequest.java b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/dto/QuestionCreateRequest.java new file mode 100644 index 00000000..77350365 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/dto/QuestionCreateRequest.java @@ -0,0 +1,17 @@ +package com.web.baebaeBE.presentation.question.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class QuestionCreateRequest { + private String content; + public QuestionCreateRequest(String content) { + this.content = content; + } + + public static QuestionCreateRequest of(String content) {return new QuestionCreateRequest(content); + } +} + diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/dto/QuestionDTO.java b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/dto/QuestionDTO.java new file mode 100644 index 00000000..0adb7aa1 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/dto/QuestionDTO.java @@ -0,0 +1,8 @@ +package com.web.baebaeBE.presentation.question.dto; + +public class QuestionDTO { + private Long id; + private String content; + private String userEmail; +} + diff --git a/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/dto/QuestionDetailResponse.java b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/dto/QuestionDetailResponse.java new file mode 100644 index 00000000..44acd8a3 --- /dev/null +++ b/baebae-BE/src/main/java/com/web/baebaeBE/presentation/question/dto/QuestionDetailResponse.java @@ -0,0 +1,26 @@ +package com.web.baebaeBE.presentation.question.dto; + +import java.time.LocalDateTime; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class QuestionDetailResponse { + private Long questionId; + private String content; + private String userEmail; + private LocalDateTime createdDate; + + public QuestionDetailResponse(Long questionId, String content, String userEmail, LocalDateTime createdDate) { + this.questionId = questionId; + this.content = content; + this.userEmail = userEmail; + this.createdDate = createdDate; + } + public static QuestionDetailResponse of(Long questionId, String content, String userEmail, LocalDateTime createdDate) { + return new QuestionDetailResponse(questionId, content, userEmail, createdDate); + } +} +