diff --git a/src/main/java/com/beotkkot/qtudy/controller/auth/AuthController.java b/src/main/java/com/beotkkot/qtudy/controller/auth/AuthController.java index 02e96d8..3c1dc5d 100644 --- a/src/main/java/com/beotkkot/qtudy/controller/auth/AuthController.java +++ b/src/main/java/com/beotkkot/qtudy/controller/auth/AuthController.java @@ -4,7 +4,6 @@ import com.beotkkot.qtudy.dto.auth.KakaoUserInfo; import com.beotkkot.qtudy.dto.auth.UserResponse; import com.beotkkot.qtudy.service.auth.AuthService; -import jakarta.servlet.http.HttpSession; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -22,7 +21,7 @@ public class AuthController { // 프론트로부터 인가 code를 받아와 카카오 서버로부터 토큰 얻기 @GetMapping("") - public ResponseEntity kakaoLogin(@RequestParam("code") String code, HttpSession session) { + public ResponseEntity kakaoLogin(@RequestParam("code") String code) { System.out.println("code = " + code); @@ -35,11 +34,6 @@ public ResponseEntity kakaoLogin(@RequestParam("code") String code, Http // 3. 로그인 Users user = authService.login(kakaoUserInfo); - if (user.getKakaoId() != null) { - session.setAttribute("kakaoId", user.getKakaoId()); - session.setAttribute("accessToken", accessToken); - } - // 4. 유저 정보 리턴 UserResponse userResponse = new UserResponse( "SU", @@ -54,14 +48,16 @@ public ResponseEntity kakaoLogin(@RequestParam("code") String code, Http } @PostMapping("/logout") - public ResponseEntity> logout(HttpSession session) { + public ResponseEntity> logout(@RequestHeader("Authorization") String header) { + + System.out.println("header = " + header); + + String[] authHeader = header.split(" "); + // 헤더에서 토큰 추출 + String accessToken = authHeader[1]; - String accessToken = (String)session.getAttribute("accessToken"); - if (accessToken != null && !"".equals(accessToken)) { - authService.logout(accessToken); - session.removeAttribute("kakaoId"); - session.removeAttribute("accessToken"); - } + // 토큰을 사용해 로그아웃 처리 + authService.logout(accessToken); // 로그아웃 성공 메시지 반환 Map response = new HashMap<>(); diff --git a/src/main/java/com/beotkkot/qtudy/controller/post/SummarizationController.java b/src/main/java/com/beotkkot/qtudy/controller/post/SummarizationController.java new file mode 100644 index 0000000..e0b17fc --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/controller/post/SummarizationController.java @@ -0,0 +1,28 @@ +package com.beotkkot.qtudy.controller.post; + +import com.beotkkot.qtudy.dto.response.posts.GetSummaryResponseDto; +import com.beotkkot.qtudy.service.posts.PostsService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +public class SummarizationController { + + private final PostsService postsService; + + /** + * 사용자가 작성한 글에 대해 AI가 요약한 내용을 반환한다. + */ + @GetMapping("summary/{postId}") + public ResponseEntity summary(@PathVariable("postId") Long postId) { + // 포스트 아이디로부터 포스트 얻어오기 + ResponseEntity response = postsService.getSummary(postId); + return response; + } +} diff --git a/src/main/java/com/beotkkot/qtudy/dto/request/posts/PostsRequestDto.java b/src/main/java/com/beotkkot/qtudy/dto/request/posts/PostsRequestDto.java index 6f6a2fc..5e55efa 100644 --- a/src/main/java/com/beotkkot/qtudy/dto/request/posts/PostsRequestDto.java +++ b/src/main/java/com/beotkkot/qtudy/dto/request/posts/PostsRequestDto.java @@ -16,6 +16,7 @@ public class PostsRequestDto { private String content; private List tag; private Long categoryId; + private String summary; public Posts toEntity(Long uid) { Date now = Date.from(Instant.now()); @@ -27,6 +28,7 @@ public Posts toEntity(Long uid) { .userUid(uid) .title(title) .content(content) + .aiScript(summary) .tag(tagString) .createdAt(writeDatetime) .commentCount(0) @@ -34,4 +36,5 @@ public Posts toEntity(Long uid) { .categoryId(categoryId) .build(); } + } diff --git a/src/main/java/com/beotkkot/qtudy/dto/response/posts/GetSummaryResponseDto.java b/src/main/java/com/beotkkot/qtudy/dto/response/posts/GetSummaryResponseDto.java new file mode 100644 index 0000000..2d23f8a --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/dto/response/posts/GetSummaryResponseDto.java @@ -0,0 +1,34 @@ +package com.beotkkot.qtudy.dto.response.posts; + +import com.beotkkot.qtudy.common.ResponseCode; +import com.beotkkot.qtudy.common.ResponseMessage; +import com.beotkkot.qtudy.dto.response.ResponseDto; +import lombok.Builder; +import lombok.Getter; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +@Getter +public class GetSummaryResponseDto extends ResponseDto { + private Long postId; + private String summary; + + @Builder + private GetSummaryResponseDto(Long postId, String summary) { + super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS); + + this.postId = postId; + this.summary = summary; + } + + public static ResponseEntity success(Long postId, String summary) { + + GetSummaryResponseDto result = new GetSummaryResponseDto(postId, summary); + return ResponseEntity.status(HttpStatus.OK).body(result); + } + + public static ResponseEntity noExistPost() { + ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_POST, ResponseMessage.NOT_EXISTED_POST); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result); + } +} diff --git a/src/main/java/com/beotkkot/qtudy/service/posts/PostsService.java b/src/main/java/com/beotkkot/qtudy/service/posts/PostsService.java index bb70513..a8a73d4 100644 --- a/src/main/java/com/beotkkot/qtudy/service/posts/PostsService.java +++ b/src/main/java/com/beotkkot/qtudy/service/posts/PostsService.java @@ -7,14 +7,11 @@ import com.beotkkot.qtudy.dto.object.PostListItem; import com.beotkkot.qtudy.dto.request.posts.PostsRequestDto; import com.beotkkot.qtudy.dto.response.*; +import com.beotkkot.qtudy.dto.response.posts.*; import com.beotkkot.qtudy.repository.posts.PostsRepository; import com.beotkkot.qtudy.repository.scrap.ScrapRepository; import com.beotkkot.qtudy.repository.tags.TagsRepository; import com.beotkkot.qtudy.repository.user.UserRepository; -import com.beotkkot.qtudy.dto.response.posts.GetPostsAllResponseDto; -import com.beotkkot.qtudy.dto.response.posts.GetPostsResponseDto; -import com.beotkkot.qtudy.dto.response.posts.PostsResponseDto; -import com.beotkkot.qtudy.dto.response.posts.PutScrapResponseDto; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; @@ -34,6 +31,7 @@ public class PostsService { private final UserRepository userRepo; private final TagsRepository tagRepo; private final ScrapRepository scrapRepo; + private final SummaryService summaryService; // private final CommentsRepository commentsRepo; (댓글 기능 구현 시 주석 제거) @Transactional @@ -41,6 +39,7 @@ public ResponseEntity savePost(Long kakao_uid, PostsRe try { if (userRepo.findByKakaoId(kakao_uid) != null) { + // 포스트 엔티티 생성 Posts post = dto.toEntity(kakao_uid); @@ -71,8 +70,16 @@ public ResponseEntity savePost(Long kakao_uid, PostsRe String tagString = String.join(",", savedTags); post.setTag(tagString); + /** + * postRepo에 해당 유저가 작성한 글에 대한 요약본 저장하는 부분 추가 + */ + String summary = summaryService.summary(dto.getContent()); + post.setContent(dto.getContent()); + post.setAiScript(summary); + // 포스트 저장 postsRepo.save(post); + } else { return PostsResponseDto.notExistUser(); } @@ -102,6 +109,25 @@ public ResponseEntity getPost(Long postId) { return GetPostsResponseDto.success(post, user); } + @Transactional + public ResponseEntity getSummary(Long postId) { + Posts post; + String summary; + try { + if (postsRepo.existsById(postId)) { + post = postsRepo.findByPostId(postId); + summary = post.getAiScript(); + } else { + return GetSummaryResponseDto.noExistPost(); + } + } catch (Exception exception) { + exception.printStackTrace(); + return ResponseDto.databaseError(); + } + + return GetSummaryResponseDto.success(postId, summary); + } + @Transactional public ResponseEntity getAllPost() { List postListItems = new ArrayList<>(); diff --git a/src/main/java/com/beotkkot/qtudy/service/posts/SummaryService.java b/src/main/java/com/beotkkot/qtudy/service/posts/SummaryService.java new file mode 100644 index 0000000..0614485 --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/service/posts/SummaryService.java @@ -0,0 +1,62 @@ +package com.beotkkot.qtudy.service.posts; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +@RequiredArgsConstructor +@Service +public class SummaryService { + + // 텍스트 데이터 받아와서 요약 + public String summary(String content) { + + String requestURL = "https://naveropenapi.apigw.ntruss.com/text-summary/v1/summarize"; + + RestTemplate rt = new RestTemplate(); + + // HTTPHeader + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type", "application/json;UTF-8"); + headers.add("X-NCP-APIGW-API-KEY-ID", "m099ib4o3p"); + headers.add("X-NCP-APIGW-API-KEY", "lNTRtcRh3AIVZfCysWBmO73eoRHnEF0NVyJTYoSx"); + + // HTTPBody + Map document = new HashMap<>(); + document.put("content", content); + + Map option = new HashMap<>(); + option.put("language", "ko"); + option.put("model", "general"); + option.put("tone", 2); + + Map params = new HashMap<>(); + params.put("document", document); + params.put("option", option); + + System.out.println("params = " + params); + + HttpEntity> summaryTextRequest = new HttpEntity<>(params, headers); + ResponseEntity response = rt.exchange(requestURL, HttpMethod.POST, summaryTextRequest, String.class); + + String responseBody = response.getBody(); + + JsonParser parser = new JsonParser(); + JsonElement element = parser.parse(responseBody); + String summaryText = element.getAsJsonObject().get("summary").getAsString(); + + System.out.println("원본 = " + content); + System.out.println("요약본 = " + summaryText); + + return summaryText; + } +}