diff --git a/src/main/java/com/beotkkot/qtudy/common/ResponseCode.java b/src/main/java/com/beotkkot/qtudy/common/ResponseCode.java index eb5f033..8f0dece 100644 --- a/src/main/java/com/beotkkot/qtudy/common/ResponseCode.java +++ b/src/main/java/com/beotkkot/qtudy/common/ResponseCode.java @@ -9,6 +9,7 @@ public interface ResponseCode { String NOT_EXISTED_USER = "NEU"; String NOT_EXISTED_POST = "NEP"; String NOT_EXISTED_COMMENT = "NEC"; + String INVALID_FORMAT = "IF"; // HTTP Status 401 String SIGN_IN_FAIL = "SF"; diff --git a/src/main/java/com/beotkkot/qtudy/common/ResponseMessage.java b/src/main/java/com/beotkkot/qtudy/common/ResponseMessage.java index 6985937..9b3c2da 100644 --- a/src/main/java/com/beotkkot/qtudy/common/ResponseMessage.java +++ b/src/main/java/com/beotkkot/qtudy/common/ResponseMessage.java @@ -9,6 +9,7 @@ public interface ResponseMessage { String NOT_EXISTED_USER = "This user does not exist."; String NOT_EXISTED_POST = "This post does not exist."; String NOT_EXISTED_COMMENT = "This comment does not exist."; + String INVALID_FORMAT = "Invalid Format"; // HTTP Status 401 String SIGN_IN_FAIL = "Login information mismatch."; diff --git a/src/main/java/com/beotkkot/qtudy/controller/mypage/MyPageController.java b/src/main/java/com/beotkkot/qtudy/controller/mypage/MyPageController.java new file mode 100644 index 0000000..1bb588e --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/controller/mypage/MyPageController.java @@ -0,0 +1,128 @@ +package com.beotkkot.qtudy.controller.mypage; + +import com.beotkkot.qtudy.dto.response.mypage.GetMyInterestResponseDto; +import com.beotkkot.qtudy.dto.response.mypage.GetMyPageAllResponseDto; +import com.beotkkot.qtudy.dto.response.mypage.GetMyPageInfoResponseDto; +import com.beotkkot.qtudy.dto.response.mypage.MyInterestResponseDto; +import com.beotkkot.qtudy.service.auth.AuthService; +import com.beotkkot.qtudy.service.mypage.MyPageService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@Slf4j +public class MyPageController { + + private final AuthService authService; + private final MyPageService myPageService; + + // 관심 분야 목록 초기 선택 + @PostMapping("/my/interests") + public ResponseEntity saveMyInterests(@RequestParam("interests") List interests, @RequestHeader("Authorization") String token) { + + Long kakao_uid; + try { + kakao_uid = authService.getKakaoUserInfo(token).getId(); + if (kakao_uid == null) + return MyInterestResponseDto.noAuthentication(); + } catch (Exception exception) { + log.info(exception.getMessage()); + return MyInterestResponseDto.databaseError(); + } + + ResponseEntity response = myPageService.saveMyInterests(kakao_uid, interests); + return response; + } + + // 내 관심 분야 목록 조회 + @GetMapping("my/interests") + public ResponseEntity getMyInterests(@RequestHeader("Authorization") String token) { + Long kakao_uid; + try { + kakao_uid = authService.getKakaoUserInfo(token).getId(); + if (kakao_uid == null) + return GetMyInterestResponseDto.noAuthentication(); + } catch (Exception exception) { + log.info(exception.getMessage()); + return GetMyInterestResponseDto.databaseError(); + } + ResponseEntity response = myPageService.getMyInterests(kakao_uid); + return response; + } + + // 내 관심 분야 목록 수정 + @PatchMapping("my/interests") + public ResponseEntity patchMyInterests(@RequestParam("interests") List interests, @RequestHeader("Authorization") String token) { + Long kakao_uid; + try { + kakao_uid = authService.getKakaoUserInfo(token).getId(); + if (kakao_uid == null) + return MyInterestResponseDto.noAuthentication(); + } catch (Exception exception) { + log.info(exception.getMessage()); + return MyInterestResponseDto.databaseError(); + } + ResponseEntity response = myPageService.patchMyInterests(kakao_uid, interests); + return response; + } + + // 사용자 프로필 조회 + @GetMapping("/my") + public ResponseEntity getMyPageInfo(@RequestHeader("Authorization") String token) { + + Long kakao_uid; + String email; + try { + kakao_uid = authService.getKakaoUserInfo(token).getId(); + if (kakao_uid == null) + return GetMyPageInfoResponseDto.noAuthentication(); + email = authService.getKakaoUserInfo(token).getEmail(); + } catch (Exception exception) { + log.info(exception.getMessage()); + return GetMyPageInfoResponseDto.databaseError(); + } + + ResponseEntity response = myPageService.getMyPageInfo(kakao_uid, email); + + return response; + } + + // 내가 작성한 게시글 확인 + @GetMapping("my/posts") + public ResponseEntity getAllPost(@RequestParam("page") int page, @RequestHeader("Authorization") String token) { + Long kakao_uid; + try { + kakao_uid = authService.getKakaoUserInfo(token).getId(); + if (kakao_uid == null) + return GetMyPageAllResponseDto.noAuthentication(); + } catch (Exception exception) { + log.info(exception.getMessage()); + return GetMyPageAllResponseDto.databaseError(); + } + + ResponseEntity response = myPageService.getAllPost(kakao_uid, page); + return response; + } + + // 내가 스크랩한 글 확인 + @GetMapping("/my/scrap") + public ResponseEntity getAllScrapPost(@RequestParam("page") int page, @RequestHeader("Authorization") String token) { + Long kakao_uid; + try { + kakao_uid = authService.getKakaoUserInfo(token).getId(); + if (kakao_uid == null) + return GetMyPageAllResponseDto.noAuthentication(); + } catch (Exception exception) { + log.info(exception.getMessage()); + return GetMyPageAllResponseDto.databaseError(); + } + + ResponseEntity response = myPageService.getAllScrapPost(kakao_uid, page); + return response; + } +} diff --git a/src/main/java/com/beotkkot/qtudy/domain/category/Category.java b/src/main/java/com/beotkkot/qtudy/domain/category/Category.java index 3dc76ee..8f3c20c 100644 --- a/src/main/java/com/beotkkot/qtudy/domain/category/Category.java +++ b/src/main/java/com/beotkkot/qtudy/domain/category/Category.java @@ -1,20 +1,19 @@ package com.beotkkot.qtudy.domain.category; import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; @Getter +@Setter @NoArgsConstructor @AllArgsConstructor @Entity public class Category { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) private Long categoryId; private String name; diff --git a/src/main/java/com/beotkkot/qtudy/domain/interests/Interests.java b/src/main/java/com/beotkkot/qtudy/domain/interests/Interests.java new file mode 100644 index 0000000..a9999e1 --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/domain/interests/Interests.java @@ -0,0 +1,24 @@ +package com.beotkkot.qtudy.domain.interests; + +import com.beotkkot.qtudy.domain.primaryKey.InterestsPK; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.IdClass; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Entity +@IdClass(InterestsPK.class) // 복합 키 생성 +public class Interests { + @Id + private Long userId; + + @Id + private Long categoryId; +} diff --git a/src/main/java/com/beotkkot/qtudy/domain/primaryKey/InterestsPK.java b/src/main/java/com/beotkkot/qtudy/domain/primaryKey/InterestsPK.java new file mode 100644 index 0000000..ee11932 --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/domain/primaryKey/InterestsPK.java @@ -0,0 +1,21 @@ +package com.beotkkot.qtudy.domain.primaryKey; + +import jakarta.persistence.Column; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.io.Serializable; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class InterestsPK implements Serializable { + @Column(name = "user_id") + private Long userId; + + @Column(name = "category_id") + private Long categoryId; +} diff --git a/src/main/java/com/beotkkot/qtudy/domain/user/Users.java b/src/main/java/com/beotkkot/qtudy/domain/user/Users.java index 49c18c0..5b6276e 100644 --- a/src/main/java/com/beotkkot/qtudy/domain/user/Users.java +++ b/src/main/java/com/beotkkot/qtudy/domain/user/Users.java @@ -16,4 +16,6 @@ public class Users { private String name; private String profileImageUrl; + + private boolean first; } diff --git a/src/main/java/com/beotkkot/qtudy/dto/object/KakaoUserInfo.java b/src/main/java/com/beotkkot/qtudy/dto/object/KakaoUserInfo.java index 1026066..8f5e93a 100644 --- a/src/main/java/com/beotkkot/qtudy/dto/object/KakaoUserInfo.java +++ b/src/main/java/com/beotkkot/qtudy/dto/object/KakaoUserInfo.java @@ -10,6 +10,7 @@ public class KakaoUserInfo { private Long id; private String name; + private String email; private String profileImageUrl; private String accessToken; diff --git a/src/main/java/com/beotkkot/qtudy/dto/response/auth/GetAuthResponseDto.java b/src/main/java/com/beotkkot/qtudy/dto/response/auth/GetAuthResponseDto.java index 59c35e8..f8145d1 100644 --- a/src/main/java/com/beotkkot/qtudy/dto/response/auth/GetAuthResponseDto.java +++ b/src/main/java/com/beotkkot/qtudy/dto/response/auth/GetAuthResponseDto.java @@ -17,6 +17,7 @@ public class GetAuthResponseDto extends ResponseDto { private String accessToken; private String name; private String profileImageUrl; + private boolean first; @Builder private GetAuthResponseDto(Users user, String accessToken) { @@ -27,6 +28,7 @@ private GetAuthResponseDto(Users user, String accessToken) { this.accessToken = accessToken; this.name = user.getName(); this.profileImageUrl = user.getProfileImageUrl(); + this.first = user.isFirst(); } public static ResponseEntity success(Users user, String accessToken) { diff --git a/src/main/java/com/beotkkot/qtudy/dto/response/mypage/GetMyInterestResponseDto.java b/src/main/java/com/beotkkot/qtudy/dto/response/mypage/GetMyInterestResponseDto.java new file mode 100644 index 0000000..d36c292 --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/dto/response/mypage/GetMyInterestResponseDto.java @@ -0,0 +1,37 @@ +package com.beotkkot.qtudy.dto.response.mypage; + +import com.beotkkot.qtudy.common.ResponseCode; +import com.beotkkot.qtudy.common.ResponseMessage; +import com.beotkkot.qtudy.dto.response.ResponseDto; +import lombok.Getter; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.util.List; + +@Getter +public class GetMyInterestResponseDto extends ResponseDto { + + private List interests; + + public GetMyInterestResponseDto(List interests) { + super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS); + this.interests = interests; + } + + public static ResponseEntity success(List interestIds) { + GetMyInterestResponseDto result = new GetMyInterestResponseDto(interestIds); + return ResponseEntity.status(HttpStatus.OK).body(result); + } + + public static ResponseEntity noAuthentication() { + ResponseDto result = new ResponseDto(ResponseCode.AUTHORIZATION_FAIL, ResponseMessage.AUTHORIZATION_FAIL); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result); + } + + public static ResponseEntity notExistedUser() { + ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_USER, ResponseMessage.NOT_EXISTED_USER); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result); + } + +} diff --git a/src/main/java/com/beotkkot/qtudy/dto/response/mypage/GetMyPageAllResponseDto.java b/src/main/java/com/beotkkot/qtudy/dto/response/mypage/GetMyPageAllResponseDto.java new file mode 100644 index 0000000..76f1755 --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/dto/response/mypage/GetMyPageAllResponseDto.java @@ -0,0 +1,49 @@ +package com.beotkkot.qtudy.dto.response.mypage; + +import com.beotkkot.qtudy.common.ResponseCode; +import com.beotkkot.qtudy.common.ResponseMessage; +import com.beotkkot.qtudy.dto.object.PostListItem; +import com.beotkkot.qtudy.dto.response.ResponseDto; +import lombok.Getter; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.util.List; + + +@Getter +public class GetMyPageAllResponseDto extends ResponseDto { + private int page; + private int totalPages; + private List postList; + + public GetMyPageAllResponseDto(List postListItem, int page, int totalPages) { + super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS); + this.page = page; + this.totalPages = totalPages; + this.postList = postListItem; + } + + public static ResponseEntity success(List postListItem, int page, int totalPages) { + GetMyPageAllResponseDto result = new GetMyPageAllResponseDto(postListItem, page, totalPages); + return ResponseEntity.status(HttpStatus.OK).body(result); + } + + public static ResponseEntity notExistedPost(){ + ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_POST, ResponseMessage.NOT_EXISTED_POST); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result); + } + + public static ResponseEntity notExistedUser() { + ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_USER, ResponseMessage.NOT_EXISTED_USER); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result); + } + + public static ResponseEntity noAuthentication() { + ResponseDto result = new ResponseDto(ResponseCode.AUTHORIZATION_FAIL, ResponseMessage.AUTHORIZATION_FAIL); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result); + } +} + + + diff --git a/src/main/java/com/beotkkot/qtudy/dto/response/mypage/GetMyPageInfoResponseDto.java b/src/main/java/com/beotkkot/qtudy/dto/response/mypage/GetMyPageInfoResponseDto.java new file mode 100644 index 0000000..802739b --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/dto/response/mypage/GetMyPageInfoResponseDto.java @@ -0,0 +1,41 @@ +package com.beotkkot.qtudy.dto.response.mypage; + +import com.beotkkot.qtudy.common.ResponseCode; +import com.beotkkot.qtudy.common.ResponseMessage; +import com.beotkkot.qtudy.domain.user.Users; +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 GetMyPageInfoResponseDto extends ResponseDto { + + private String name; + private String profileImageUrl; + private String email; + + @Builder + private GetMyPageInfoResponseDto(Users user, String email) { + super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS); + this.name = user.getName(); + this.email = email; + this.profileImageUrl = null; + } + + public static ResponseEntity success(Users user, String email) { + GetMyPageInfoResponseDto result = new GetMyPageInfoResponseDto(user, email); + return ResponseEntity.status(HttpStatus.OK).body(result); + } + + public static ResponseEntity noAuthentication() { + ResponseDto result = new ResponseDto(ResponseCode.AUTHORIZATION_FAIL, ResponseMessage.AUTHORIZATION_FAIL); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result); + } + + public static ResponseEntity notExistedUser() { + ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_USER, ResponseMessage.NOT_EXISTED_USER); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result); + } +} diff --git a/src/main/java/com/beotkkot/qtudy/dto/response/mypage/MyInterestResponseDto.java b/src/main/java/com/beotkkot/qtudy/dto/response/mypage/MyInterestResponseDto.java new file mode 100644 index 0000000..e4f4293 --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/dto/response/mypage/MyInterestResponseDto.java @@ -0,0 +1,39 @@ +package com.beotkkot.qtudy.dto.response.mypage; + +import com.beotkkot.qtudy.common.ResponseCode; +import com.beotkkot.qtudy.common.ResponseMessage; +import com.beotkkot.qtudy.dto.response.ResponseDto; +import lombok.Getter; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +@Getter +public class MyInterestResponseDto extends ResponseDto { + + public MyInterestResponseDto() { + super(ResponseCode.SUCCESS, ResponseMessage.SUCCESS); + + } + + public static ResponseEntity success() { + MyInterestResponseDto result = new MyInterestResponseDto(); + return ResponseEntity.status(HttpStatus.OK).body(result); + } + + public static ResponseEntity notExistedUser() { + ResponseDto result = new ResponseDto(ResponseCode.NOT_EXISTED_USER, ResponseMessage.NOT_EXISTED_USER); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result); + } + + public static ResponseEntity noAuthentication() { + ResponseDto result = new ResponseDto(ResponseCode.AUTHORIZATION_FAIL, ResponseMessage.AUTHORIZATION_FAIL); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result); + } + + public static ResponseEntity inputFailed() { + ResponseDto result = new ResponseDto(ResponseCode.INVALID_FORMAT, ResponseMessage.INVALID_FORMAT); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result); + } + + +} diff --git a/src/main/java/com/beotkkot/qtudy/repository/category/CategoryRepository.java b/src/main/java/com/beotkkot/qtudy/repository/category/CategoryRepository.java new file mode 100644 index 0000000..24aa4d4 --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/repository/category/CategoryRepository.java @@ -0,0 +1,10 @@ +package com.beotkkot.qtudy.repository.category; + +import com.beotkkot.qtudy.domain.category.Category; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CategoryRepository extends JpaRepository { + +} diff --git a/src/main/java/com/beotkkot/qtudy/repository/interests/InterestsRepository.java b/src/main/java/com/beotkkot/qtudy/repository/interests/InterestsRepository.java new file mode 100644 index 0000000..64e9931 --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/repository/interests/InterestsRepository.java @@ -0,0 +1,16 @@ +package com.beotkkot.qtudy.repository.interests; + +import com.beotkkot.qtudy.domain.interests.Interests; +import com.beotkkot.qtudy.domain.primaryKey.InterestsPK; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface InterestsRepository extends JpaRepository { + + List findAllByUserId(Long userId); + + void deleteAllByUserId(Long userId); +} diff --git a/src/main/java/com/beotkkot/qtudy/service/auth/AuthService.java b/src/main/java/com/beotkkot/qtudy/service/auth/AuthService.java index c616aae..dccdf30 100644 --- a/src/main/java/com/beotkkot/qtudy/service/auth/AuthService.java +++ b/src/main/java/com/beotkkot/qtudy/service/auth/AuthService.java @@ -15,6 +15,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.HttpClientErrorException; @@ -96,12 +97,14 @@ public KakaoUserInfo getKakaoUserInfo(String accessToken) { // 유저 정보 추출 Long id = element.getAsJsonObject().get("id").getAsLong(); JsonObject properties = element.getAsJsonObject().get("properties").getAsJsonObject(); + JsonObject kakaoAccount = element.getAsJsonObject().get("kakao_account").getAsJsonObject(); + System.out.println("properties = " + properties); String name = properties.getAsJsonObject().get("nickname").getAsString(); String profileImageUrl = properties.getAsJsonObject().get("profile_image").getAsString(); - + String email = kakaoAccount.getAsJsonObject().get("email").getAsString(); // 카카오 유저 정보 생성해서 리턴 - return new KakaoUserInfo(id, name, profileImageUrl, accessToken); + return new KakaoUserInfo(id, name, email, profileImageUrl, accessToken); } catch (Exception exception) { log.info("error message: " + exception.getMessage()); @@ -109,6 +112,7 @@ public KakaoUserInfo getKakaoUserInfo(String accessToken) { } } + @Transactional // 3. 사용자 정보를 DB에서 조회하고, 가입되지 않은 사용자라면 DB에 저장 후 해당 사용자 반환 public Users login(KakaoUserInfo kakaoUserInfo) { Long kakaoId = kakaoUserInfo.getId(); // 사용자의 카카오 아이디 불러오기 @@ -120,8 +124,14 @@ public Users login(KakaoUserInfo kakaoUserInfo) { userService.saveUser(kakaoUserInfo); // 사용자 재조회 findUser = userService.findUserKaKaoId(kakaoId); + // 최초 사용자로 설정 + findUser.setFirst(true); + System.out.println("findUser.isFirst() = " + findUser.isFirst()); + } else { // 이미 가입한 사용자라면 + if (findUser.isFirst()) { + findUser.setFirst(false); + } } - return findUser; } diff --git a/src/main/java/com/beotkkot/qtudy/service/category/CategoryInitializerService.java b/src/main/java/com/beotkkot/qtudy/service/category/CategoryInitializerService.java new file mode 100644 index 0000000..fdfcc7a --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/service/category/CategoryInitializerService.java @@ -0,0 +1,30 @@ +package com.beotkkot.qtudy.service.category; + +import com.beotkkot.qtudy.domain.category.Category; +import com.beotkkot.qtudy.repository.category.CategoryRepository; +import jakarta.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CategoryInitializerService { + + @Autowired + private CategoryRepository categoryRepository; + + @PostConstruct + public void initializeCategories() { + String[] categoryNames = { + "경영학", "교육", "광고 및 미디어", "법학", "사회과학", + "식품 및 체육", "언어 및 문학", "인문학", "약학", "예술 및 디자인", + "자연과학", "전기 및 전자기학", "컴퓨터공학", "환경", "정치 및 외교" + }; + + for (long i = 1L; i < 16L; i++) { + if (!categoryRepository.existsById(i)) { + Category category = new Category(i, categoryNames[(int) (i - 1)]); + categoryRepository.save(category); + } + } + } +} diff --git a/src/main/java/com/beotkkot/qtudy/service/mypage/MyPageService.java b/src/main/java/com/beotkkot/qtudy/service/mypage/MyPageService.java new file mode 100644 index 0000000..5d45418 --- /dev/null +++ b/src/main/java/com/beotkkot/qtudy/service/mypage/MyPageService.java @@ -0,0 +1,173 @@ +package com.beotkkot.qtudy.service.mypage; + +import com.beotkkot.qtudy.domain.category.Category; +import com.beotkkot.qtudy.domain.interests.Interests; +import com.beotkkot.qtudy.domain.posts.Posts; +import com.beotkkot.qtudy.domain.user.Users; +import com.beotkkot.qtudy.dto.object.PostListItem; +import com.beotkkot.qtudy.dto.response.ResponseDto; +import com.beotkkot.qtudy.dto.response.mypage.GetMyInterestResponseDto; +import com.beotkkot.qtudy.dto.response.mypage.GetMyPageAllResponseDto; +import com.beotkkot.qtudy.dto.response.mypage.GetMyPageInfoResponseDto; +import com.beotkkot.qtudy.dto.response.mypage.MyInterestResponseDto; +import com.beotkkot.qtudy.repository.category.CategoryRepository; +import com.beotkkot.qtudy.repository.interests.InterestsRepository; +import com.beotkkot.qtudy.repository.posts.PostsRepository; +import com.beotkkot.qtudy.repository.scrap.ScrapRepository; +import com.beotkkot.qtudy.repository.user.UserRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Service +@Slf4j +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MyPageService { + + private final PostsRepository postRepo; + private final UserRepository userRepo; + private final ScrapRepository scrapRepo; + private final CategoryRepository categoryRepo; + private final InterestsRepository interestsRepo; + + // 관심사 저장 + @Transactional + public ResponseEntity saveMyInterests(Long kakao_uid, List interests) { + + try { + if (userRepo.findByKakaoId(kakao_uid) == null) return MyInterestResponseDto.notExistedUser(); + List findInterests = interestsRepo.findAllByUserId(kakao_uid); + if ((interests.size() > 3) || (findInterests.size() > 0)) return MyInterestResponseDto.inputFailed(); + + for (Long categoryId : interests) { + // 사용자의 관심사 3개를 interestsRepo에 저장한다. + // 1. CategoryRepo에서 사용자가 선택한 interests에 해당되는 관심사 조회 + Optional category = categoryRepo.findById(categoryId); + if (!category.isPresent()) { // 존재하지 않는 카테고리일 경우 + return MyInterestResponseDto.databaseError(); + } + // 2. 존재하는 카테고리이고, 사용자가 아직 관심사를 등록하지 않았다면, 해당하는 사용자의 관심사를 등록 + Interests interest = new Interests(kakao_uid, categoryId); + interestsRepo.save(interest); + } + } catch (Exception exception) { + log.info("error ", exception.getMessage()); + return MyInterestResponseDto.databaseError(); + } + MyInterestResponseDto responseDto = new MyInterestResponseDto(); + return responseDto.success(); + } + + // 관심 분야 목록 조회 + public ResponseEntity getMyInterests(Long kakao_uid) { + + List interestIds = new ArrayList<>(); + try { + if (userRepo.findByKakaoId(kakao_uid) == null) return GetMyInterestResponseDto.notExistedUser(); + List interests = interestsRepo.findAllByUserId(kakao_uid); + for (Interests interest : interests) { + interestIds.add(interest.getCategoryId()); + } + } catch (Exception exception) { + log.info("error ", exception.getMessage()); + return GetMyInterestResponseDto.databaseError(); + } + + return GetMyInterestResponseDto.success(interestIds); + } + + // 마이페이지에서 자신의 정보 조회 (관심사, 사용자 이름, 이메일, 사용자 프로필이미지) + public ResponseEntity getMyPageInfo(Long kakao_uid, String email) { + + Users user; + try { + // 유저가 존재하지 않으면 에러 + if (userRepo.findByKakaoId(kakao_uid) == null) return GetMyPageInfoResponseDto.notExistedUser(); + // 존재하면 유저 가져오기 + user = userRepo.findByKakaoId(kakao_uid); + } catch (Exception exception) { + log.info("error " + exception.getMessage()); + return GetMyPageInfoResponseDto.databaseError(); + } + return GetMyPageInfoResponseDto.success(user, email); + } + + public ResponseEntity getAllPost(Long kakao_uid, int page) { + List postListItems = new ArrayList<>(); + int totalPages; + try { + PageRequest pageRequest = PageRequest.of(page, 6, Sort.by("createdAt").descending()); + Page posts = postRepo.findAllByKakaoId(kakao_uid, pageRequest); + totalPages = posts.getTotalPages(); + for (Posts post : posts.getContent()) + postListItems.add(PostListItem.of(post)); + } catch (Exception exception) { + log.info("error " + exception.getMessage()); + return ResponseDto.databaseError(); + } + + GetMyPageAllResponseDto responseDto = new GetMyPageAllResponseDto(postListItems, page, totalPages); + return responseDto.success(postListItems, page, totalPages); + } + + public ResponseEntity getAllScrapPost(Long kakao_uid, int page) { + + List postListItems = new ArrayList<>(); + int totalPages; + try { + if (userRepo.findByKakaoId(kakao_uid) == null) return GetMyPageAllResponseDto.notExistedUser(); + + PageRequest pageRequest = PageRequest.of(page, 6, Sort.by("createdAt").descending()); + List postIdList = scrapRepo.findPostIdsByUserId(kakao_uid); + Page posts = postRepo.findByPostIds(postIdList, pageRequest); + totalPages = posts.getTotalPages(); + + if (posts == null) return GetMyPageAllResponseDto.notExistedPost(); + + for (Posts post : posts.getContent()) + postListItems.add(PostListItem.of(post)); + } catch (Exception exception) { + log.info("error " + exception.getMessage()); + return ResponseDto.databaseError(); + } + + GetMyPageAllResponseDto responseDto = new GetMyPageAllResponseDto(postListItems, page, totalPages); + return responseDto.success(postListItems, page, totalPages); + } + + @Transactional + public ResponseEntity patchMyInterests(Long kakao_uid, List interests) { + try { + if (userRepo.findByKakaoId(kakao_uid) == null) return MyInterestResponseDto.notExistedUser(); + if (interests.size() > 3) return MyInterestResponseDto.inputFailed(); + + // 기존의 관심사를 모두 삭제 + interestsRepo.deleteAllByUserId(kakao_uid); + + // 새로운 관심사 추가 + for (Long categoryId : interests) { + Optional category = categoryRepo.findById(categoryId); + if (!category.isPresent()) { // 존재하지 않는 카테고리일 경우 + return MyInterestResponseDto.databaseError(); + } + Interests newInterest = new Interests(kakao_uid, categoryId); + interestsRepo.save(newInterest); + } + } catch (Exception exception) { + log.info("error ", exception.getMessage()); + return MyInterestResponseDto.databaseError(); + } + MyInterestResponseDto responseDto = new MyInterestResponseDto(); + return responseDto.success(); + } +} 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 9e94ddb..d38a536 100644 --- a/src/main/java/com/beotkkot/qtudy/service/posts/PostsService.java +++ b/src/main/java/com/beotkkot/qtudy/service/posts/PostsService.java @@ -38,6 +38,8 @@ public class PostsService { @Transactional public ResponseEntity savePost(Long kakao_uid, PostsRequestDto dto) { Long postId; + List newTagList = new ArrayList<>(); + List increasedTag = new ArrayList<>(); try { if (userRepo.findByKakaoId(kakao_uid) != null) { @@ -47,7 +49,6 @@ public ResponseEntity savePost(Long kakao_uid, PostsRe // 태그 처리 List postTags = dto.getTag(); - List savedTags = new ArrayList<>(); for (String tagName : postTags) { Optional existingTag = tagRepo.findByName(tagName); @@ -55,27 +56,23 @@ public ResponseEntity savePost(Long kakao_uid, PostsRe // 기존에 있는 태그인 경우 count를 증가시킴 Tags tag = existingTag.get(); tag.increaseTagCount(); - savedTags.add(tagName); + increasedTag.add(tagName); } else { // 새로운 태그인 경우 태그를 생성하고 count를 1로 초기화함 Tags newTag = new Tags(); newTag.setName(tagName); newTag.setCount(1); // 새로운 태그의 count를 1로 초기화 newTag.setCategoryId(dto.getCategoryId()); - savedTags.add(tagName); - // 새로운 태그를 저장 - tagRepo.save(newTag); + newTagList.add(newTag); } } // 저장된 태그 목록을 포스트에 설정 - String tagString = String.join(",", savedTags); + String tagString = String.join(",", postTags); post.setTag(tagString); - /** - * postRepo에 해당 유저가 작성한 글에 대한 요약본 저장하는 부분 추가 - */ + // postRepo에 해당 유저가 작성한 글에 대한 요약본 저장하는 부분 추가 String summary = summaryService.summary(dto.getContent()); post.setContent(dto.getContent()); post.setSummary(summary); @@ -84,11 +81,17 @@ public ResponseEntity savePost(Long kakao_uid, PostsRe Posts savedPost = postsRepo.save(post); postId = savedPost.getPostId(); + tagRepo.saveAll(newTagList); } else { return PostsResponseDto.notExistUser(); } } catch (Exception exception) { exception.printStackTrace(); + for (String tagName : increasedTag) { + Optional existingTag = tagRepo.findByName(tagName); + Tags tag = existingTag.get(); + tag.decreaseTagCount(); + } return ResponseDto.databaseError(); } return PostsResponseDto.success(postId); diff --git a/src/main/java/com/beotkkot/qtudy/service/posts/SummaryService.java b/src/main/java/com/beotkkot/qtudy/service/posts/SummaryService.java index 0614485..01ce348 100644 --- a/src/main/java/com/beotkkot/qtudy/service/posts/SummaryService.java +++ b/src/main/java/com/beotkkot/qtudy/service/posts/SummaryService.java @@ -3,6 +3,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonParser; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -16,19 +17,22 @@ @RequiredArgsConstructor @Service public class SummaryService { + @Value("${CLOVA_API_KEY_ID}") + private String CLOVA_API_KEY_ID; + @Value("${CLOVA_API_KEY}") + private String CLOVA_API_KEY; + private static final String ENDPOINT = "https://naveropenapi.apigw.ntruss.com/text-summary/v1/summarize"; // 텍스트 데이터 받아와서 요약 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"); + headers.add("X-NCP-APIGW-API-KEY-ID", CLOVA_API_KEY_ID); + headers.add("X-NCP-APIGW-API-KEY", CLOVA_API_KEY); // HTTPBody Map document = new HashMap<>(); @@ -46,7 +50,7 @@ public String summary(String content) { System.out.println("params = " + params); HttpEntity> summaryTextRequest = new HttpEntity<>(params, headers); - ResponseEntity response = rt.exchange(requestURL, HttpMethod.POST, summaryTextRequest, String.class); + ResponseEntity response = rt.exchange(ENDPOINT, HttpMethod.POST, summaryTextRequest, String.class); String responseBody = response.getBody(); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6ddbb08..b866dc3 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -17,4 +17,6 @@ spring: ddl-auto: update # OPEN AI API KEY -GPT_API_KEY: ${GPT_API_KEY} \ No newline at end of file +GPT_API_KEY: ${GPT_API_KEY} +CLOVA_API_KEY_ID: ${CLOVA_API_KEY_ID} +CLOVA_API_KEY: ${CLOVA_API_KEY} \ No newline at end of file