Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] 요약 기능 구현 #8

Merged
merged 6 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -22,7 +21,7 @@ public class AuthController {

// 프론트로부터 인가 code를 받아와 카카오 서버로부터 토큰 얻기
@GetMapping("")
public ResponseEntity<Object> kakaoLogin(@RequestParam("code") String code, HttpSession session) {
public ResponseEntity<Object> kakaoLogin(@RequestParam("code") String code) {

System.out.println("code = " + code);

Expand All @@ -35,11 +34,6 @@ public ResponseEntity<Object> 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",
Expand All @@ -54,14 +48,16 @@ public ResponseEntity<Object> kakaoLogin(@RequestParam("code") String code, Http
}

@PostMapping("/logout")
public ResponseEntity<Map<String,String>> logout(HttpSession session) {
public ResponseEntity<Map<String,String>> 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<String, String> response = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -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<? super GetSummaryResponseDto> summary(@PathVariable("postId") Long postId) {
// 포스트 아이디로부터 포스트 얻어오기
ResponseEntity<? super GetSummaryResponseDto> response = postsService.getSummary(postId);
return response;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class PostsRequestDto {
private String content;
private List<String> tag;
private Long categoryId;
private String summary;

public Posts toEntity(Long uid) {
Date now = Date.from(Instant.now());
Expand All @@ -27,11 +28,13 @@ public Posts toEntity(Long uid) {
.userUid(uid)
.title(title)
.content(content)
.aiScript(summary)
.tag(tagString)
.createdAt(writeDatetime)
.commentCount(0)
.scrapCount(0)
.categoryId(categoryId)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -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<GetSummaryResponseDto> success(Long postId, String summary) {

GetSummaryResponseDto result = new GetSummaryResponseDto(postId, summary);
return ResponseEntity.status(HttpStatus.OK).body(result);
}

public static ResponseEntity<ResponseDto> noExistPost() {
ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_POST, ResponseMessage.NOT_EXISTED_POST);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
}
}
34 changes: 30 additions & 4 deletions src/main/java/com/beotkkot/qtudy/service/posts/PostsService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -34,13 +31,15 @@ public class PostsService {
private final UserRepository userRepo;
private final TagsRepository tagRepo;
private final ScrapRepository scrapRepo;
private final SummaryService summaryService;
// private final CommentsRepository commentsRepo; (댓글 기능 구현 시 주석 제거)

@Transactional
public ResponseEntity<? super PostsResponseDto> savePost(Long kakao_uid, PostsRequestDto dto) {
try {

if (userRepo.findByKakaoId(kakao_uid) != null) {

// 포스트 엔티티 생성
Posts post = dto.toEntity(kakao_uid);

Expand Down Expand Up @@ -71,8 +70,16 @@ public ResponseEntity<? super PostsResponseDto> 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();
}
Expand Down Expand Up @@ -102,6 +109,25 @@ public ResponseEntity<? super GetPostsResponseDto> getPost(Long postId) {
return GetPostsResponseDto.success(post, user);
}

@Transactional
public ResponseEntity<? super GetSummaryResponseDto> 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<? super GetPostsAllResponseDto> getAllPost() {
List<PostListItem> postListItems = new ArrayList<>();
Expand Down
62 changes: 62 additions & 0 deletions src/main/java/com/beotkkot/qtudy/service/posts/SummaryService.java
Original file line number Diff line number Diff line change
@@ -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<String, Object> document = new HashMap<>();
document.put("content", content);

Map<String, Object> option = new HashMap<>();
option.put("language", "ko");
option.put("model", "general");
option.put("tone", 2);

Map<String, Object> params = new HashMap<>();
params.put("document", document);
params.put("option", option);

System.out.println("params = " + params);

HttpEntity<Map<String, Object>> summaryTextRequest = new HttpEntity<>(params, headers);
ResponseEntity<String> 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;
}
}