diff --git a/.gitignore b/.gitignore index c2065bc..ace25e9 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ out/ ### VS Code ### .vscode/ + + +.DS_Store diff --git a/build.gradle b/build.gradle index 4369268..1a7293e 100644 --- a/build.gradle +++ b/build.gradle @@ -39,6 +39,9 @@ dependencies { runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' // .env implementation 'me.paulschwarz:spring-dotenv:4.0.0' + + implementation 'com.h2database:h2' // 임베디드 데이터베이스 사용 시 + } tasks.named('test') { diff --git a/src/main/java/com/emodi/emodi/controller/AuthController.java b/src/main/java/com/emodi/emodi/controller/AuthController.java index ac7ddb9..4a29a07 100644 --- a/src/main/java/com/emodi/emodi/controller/AuthController.java +++ b/src/main/java/com/emodi/emodi/controller/AuthController.java @@ -14,6 +14,7 @@ import com.emodi.emodi.service.AuthService; import com.emodi.emodi.service.dto.SignupInfoRequest; import com.emodi.emodi.service.dto.request.LoginInfoRequest; +import com.emodi.emodi.service.dto.response.UserIdDto; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletResponse; @@ -47,7 +48,9 @@ public ResponseEntity login(@RequestBody LoginInfoRequest request, HttpS } @GetMapping("/me") - public Long getUserId(@CookieValue("jwt") String token) { - return jwtProvider.verifyToken(token); + public ResponseEntity getUserId(@CookieValue("jwt") String token) { + Long userId = jwtProvider.verifyToken(token); + return ResponseEntity.status(HttpStatus.OK) + .body(new UserIdDto(userId)); } } diff --git a/src/main/java/com/emodi/emodi/controller/DiaryController.java b/src/main/java/com/emodi/emodi/controller/DiaryController.java index d796e0d..d396db8 100644 --- a/src/main/java/com/emodi/emodi/controller/DiaryController.java +++ b/src/main/java/com/emodi/emodi/controller/DiaryController.java @@ -1,24 +1,23 @@ package com.emodi.emodi.controller; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.CookieValue; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; - import com.emodi.emodi.entity.Diary; import com.emodi.emodi.jwt.JwtProvider; import com.emodi.emodi.service.DiaryService; import com.emodi.emodi.service.dto.request.WriteDiaryRequest; import com.emodi.emodi.service.dto.response.WriteDiaryResponse; - +import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.Setter; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; @Controller @RequiredArgsConstructor @RequestMapping("/api") +@Getter +@Setter public class DiaryController { private final DiaryService diaryService; private final JwtProvider jwtProvider; @@ -40,4 +39,24 @@ public ResponseEntity writeDiary( return ResponseEntity.status(HttpStatus.CREATED) .body(writeDiaryResponse); } + + + @PutMapping("/diaries/{diaryId}") + public ResponseEntity updateDiary( + @CookieValue("jwt") String token, + @PathVariable Long diaryId, + @RequestBody WriteDiaryRequest request + ) { + Long userId = jwtProvider.verifyToken(token); + + Diary diary = diaryService.updateDiary(diaryId, request); + + WriteDiaryResponse writeDiaryResponse = WriteDiaryResponse.toWriteDiaryResponse( + "일기 수정이 완료되었습니다.", + diary + ); + + return ResponseEntity.status(HttpStatus.OK) + .body(writeDiaryResponse); + } } diff --git a/src/main/java/com/emodi/emodi/entity/Diary.java b/src/main/java/com/emodi/emodi/entity/Diary.java index 64298a6..85479c6 100644 --- a/src/main/java/com/emodi/emodi/entity/Diary.java +++ b/src/main/java/com/emodi/emodi/entity/Diary.java @@ -1,28 +1,18 @@ package com.emodi.emodi.entity; -import java.time.LocalDate; - import com.emodi.emodi.entity.common.BaseTimeEntity; +import jakarta.persistence.*; +import lombok.*; -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 lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import java.time.LocalDate; +import java.time.LocalDateTime; @Entity @Builder @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @Getter +@Setter public class Diary extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -41,4 +31,17 @@ public class Diary extends BaseTimeEntity { @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "sentiment_id") private Sentiment sentiment; + + @Column(nullable = false) + private LocalDateTime updatedAt; + + @PrePersist + public void prePersist() { + this.updatedAt = LocalDateTime.now(); + } + + @PreUpdate + public void preUpdate() { + this.updatedAt = LocalDateTime.now(); + } } diff --git a/src/main/java/com/emodi/emodi/service/DiaryService.java b/src/main/java/com/emodi/emodi/service/DiaryService.java index 2023eb4..bf50a20 100644 --- a/src/main/java/com/emodi/emodi/service/DiaryService.java +++ b/src/main/java/com/emodi/emodi/service/DiaryService.java @@ -1,16 +1,17 @@ package com.emodi.emodi.service; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - import com.emodi.emodi.entity.Diary; import com.emodi.emodi.entity.Sentiment; import com.emodi.emodi.entity.User; import com.emodi.emodi.repository.DiaryRepository; import com.emodi.emodi.repository.UserRepository; import com.emodi.emodi.service.dto.request.WriteDiaryRequest; - import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.LocalDateTime; @Service @Transactional @@ -22,13 +23,28 @@ public class DiaryService { public Diary writeDiary(Long userId, WriteDiaryRequest request) { User user = userRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다.")); + .orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다.")); Sentiment sentiment = sentimentService.analyze(request); Diary diary = request.toDiary(user, sentiment); + diary.setUpdatedAt(LocalDateTime.now()); // Set updatedAt field return diaryRepository.save(diary); + } + + public Diary updateDiary(Long diaryId, WriteDiaryRequest request) { + Diary diary = diaryRepository.findById(diaryId) + .orElseThrow(() -> new IllegalArgumentException("일기를 찾을 수 없습니다.")); + + Sentiment sentiment = sentimentService.analyze(request); + + diary.setTitle(request.title()); + diary.setContent(request.content()); + diary.setDate(LocalDate.parse(request.date())); + diary.setSentiment(sentiment); + diary.setUpdatedAt(LocalDateTime.now()); + return diaryRepository.save(diary); } } diff --git a/src/main/java/com/emodi/emodi/service/dto/response/UserIdDto.java b/src/main/java/com/emodi/emodi/service/dto/response/UserIdDto.java new file mode 100644 index 0000000..df96341 --- /dev/null +++ b/src/main/java/com/emodi/emodi/service/dto/response/UserIdDto.java @@ -0,0 +1,5 @@ +package com.emodi.emodi.service.dto.response; + +public record UserIdDto(Long userId) { + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 11a0a43..baafa65 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,20 @@ spring.application.name=emodi + +# MySQL ?????? ?? +spring.datasource.url=jdbc:mysql://localhost:3306/test +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.datasource.username=root +spring.datasource.password=@220708 + +spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect +spring.jpa.hibernate.ddl-auto=update +spring.jpa.show-sql=true + +# JWT ?? +jwt.secret-key=dGhpc19pc19hX3N1cGVyX3NlY3JldF9rZXlfdGhhdF9pc18zMl9ieXRlc19sb25nIQ== +jwt.expiration-time=3600000 + +# Sentiment API ?? +app.sentimentKey=mqqu0rvst7 +app.sentimentSecret=hqbOaHhe3oP6zecSC7GScKOIx4jImxtu1Yq395bJ +app.sentimentUrl=https://naveropenapi.apigw.ntruss.com/sentiment-analysis/v1/analyze