Skip to content

Commit

Permalink
Merge pull request #24 from GDG-Hackathon-77ia/feat/memo
Browse files Browse the repository at this point in the history
feat: 메모 구현
  • Loading branch information
jhssong authored Nov 14, 2024
2 parents 16d60ad + 4b64ff4 commit 52b6cfb
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 0 deletions.
51 changes: 51 additions & 0 deletions src/main/java/com/gdg/kkia/memo/controller/MemoController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.gdg.kkia.memo.controller;

import com.gdg.kkia.common.dto.StringTypeMessageResponse;
import com.gdg.kkia.memo.dto.MemoRequest;
import com.gdg.kkia.memo.dto.MemoResponse;
import com.gdg.kkia.memo.service.MemoService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
@Tag(name = "메모", description = "메모 관련 API")
public class MemoController {

private final MemoService memoService;

@Operation(summary = "메모 작성", description = "사용자가 메모를 작성합니다.")
@PostMapping("/memo")
public ResponseEntity<StringTypeMessageResponse> writeDiary(@RequestAttribute("memberId") Long memberId, @RequestBody MemoRequest memoRequest) {
memoService.writeMemo(memberId, memoRequest);
return ResponseEntity.status(HttpStatus.CREATED).body(new StringTypeMessageResponse("메모가 작성되었습니다."));
}

@Operation(summary = "메모 가져오기", description = "특정 날짜의 메모를 가져옵니다.")
@GetMapping("/memo/{localDateTime}")
public ResponseEntity<List<MemoResponse>> getAllMemoByLocalDateTime(@RequestAttribute("memberId") Long memberId, @PathVariable("localDateTime") LocalDateTime localDateTime) {
return ResponseEntity.ok().body(memoService.getAllMemoByLocalDateTime(memberId, localDateTime));
}

@Operation(summary = "메모 수정", description = "사용자가 작성했던 메모 중 memoId에 해당하는 메모를 수정합니다.")
@PutMapping("/memo/{memoId}")
public ResponseEntity<StringTypeMessageResponse> updateMemo(@RequestAttribute("memberId") Long memberId, @PathVariable("memoId") Long memoId, @RequestBody MemoRequest memoRequest) {
memoService.updateMemo(memberId, memoId, memoRequest);
return ResponseEntity.status(HttpStatus.CREATED).body(new StringTypeMessageResponse("메모가 수정되었습니다."));
}

@Operation(summary = "메모 삭제", description = "사용자가 작성했던 메모 중 memoId에 해당하는 메모를 삭제합니다.")
@DeleteMapping("/memo/{memoId}")
public ResponseEntity<StringTypeMessageResponse> deleteMemo(@RequestAttribute("memberId") Long memberId, @PathVariable("memoId") Long memoId) {
memoService.deleteMemo(memberId, memoId);
return ResponseEntity.status(HttpStatus.CREATED).body(new StringTypeMessageResponse("메모가 삭제되었습니다."));
}
}
5 changes: 5 additions & 0 deletions src/main/java/com/gdg/kkia/memo/dto/MemoRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.gdg.kkia.memo.dto;

public record MemoRequest (
String content
) {}
9 changes: 9 additions & 0 deletions src/main/java/com/gdg/kkia/memo/dto/MemoResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.gdg.kkia.memo.dto;

import java.time.LocalDateTime;

public record MemoResponse(
Long diaryId,
LocalDateTime writtenDateTime,
String content
) { }
44 changes: 44 additions & 0 deletions src/main/java/com/gdg/kkia/memo/entity/Memo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.gdg.kkia.memo.entity;

import com.gdg.kkia.diary.entity.Diary;
import com.gdg.kkia.member.entity.Member;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.*;
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 java.time.LocalDateTime;

@Entity
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class Memo {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Setter
private String content;
@NotNull
@Setter
@CreatedDate
private LocalDateTime writtenDatetime;
@ManyToOne
@JoinColumn(name = "member_id")
@NotNull
@OnDelete(action = OnDeleteAction.CASCADE)
private Member member;

public Memo(String content, Member member) {
this.content = content;
this.member = member;
}

}
16 changes: 16 additions & 0 deletions src/main/java/com/gdg/kkia/memo/repository/MemoRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.gdg.kkia.memo.repository;

import com.gdg.kkia.member.entity.Member;
import com.gdg.kkia.memo.entity.Memo;
import org.springframework.data.jpa.repository.JpaRepository;

import java.time.LocalDateTime;
import java.util.List;

public interface MemoRepository extends JpaRepository<Memo, Long> {
List<Memo> findByMemberAndWrittenDatetimeBetween(
Member member,
LocalDateTime startDate,
LocalDateTime endDate
);
}
86 changes: 86 additions & 0 deletions src/main/java/com/gdg/kkia/memo/service/MemoService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.gdg.kkia.memo.service;

import com.gdg.kkia.common.exception.NotFoundException;
import com.gdg.kkia.common.exception.UnauthorizedException;
import com.gdg.kkia.memo.dto.MemoRequest;
import com.gdg.kkia.member.entity.Member;
import com.gdg.kkia.member.repository.MemberRepository;
import com.gdg.kkia.memo.dto.MemoResponse;
import com.gdg.kkia.memo.entity.Memo;
import com.gdg.kkia.memo.repository.MemoRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemoService {

private final MemberRepository memberRepository;
private final MemoRepository memoRepository;

@Transactional
public void writeMemo(Long memberId, MemoRequest memoRequest) {
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new NotFoundException("id에 해당하는 멤버가 없습니다."));

Memo memo = new Memo(memoRequest.content(), member);

memoRepository.save(memo);
}

@Transactional(readOnly = true)
public List<MemoResponse> getAllMemoByLocalDateTime(Long memberId, LocalDateTime localDateTime) {
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new NotFoundException("id에 해당하는 멤버가 없습니다."));

LocalDateTime start = localDateTime.toLocalDate().atStartOfDay();
LocalDateTime end = localDateTime.toLocalDate().atTime(23, 59, 59, 999999999);
return memoRepository.findByMemberAndWrittenDatetimeBetween(member, start, end)
.stream()
.map(memo -> new MemoResponse(
memo.getId(),
memo.getWrittenDatetime(),
memo.getContent()))
.collect(Collectors.toList());
}

@Transactional
public void updateMemo(Long memberId, Long memoId, MemoRequest memoRequest) {
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new NotFoundException("id에 해당하는 멤버가 없습니다."));

Memo memo = memoRepository.findById(memoId)
.orElseThrow(() -> new NotFoundException("id에 해당하는 메모가 없습니다."));

if (!Objects.equals(member.getId(), memo.getMember().getId())) {
throw new UnauthorizedException("로그인한 사용자가 작성한 메모가 아닙니다.");
}

memo.setContent(memoRequest.content());
memo.setWrittenDatetime(LocalDateTime.now());

memoRepository.save(memo);
}

@Transactional
public void deleteMemo(Long memberId, Long memoId) {
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new NotFoundException("id에 해당하는 멤버가 없습니다."));

Memo memo = memoRepository.findById(memoId)
.orElseThrow(() -> new NotFoundException("id에 해당하는 메모가 없습니다."));

if (!Objects.equals(member.getId(), memo.getMember().getId())) {
throw new UnauthorizedException("로그인한 사용자가 작성한 메모가 아닙니다.");
}

memoRepository.deleteById(memoId);
}
}

0 comments on commit 52b6cfb

Please sign in to comment.