From 44d8fcf3af9aa764fb97aafe2ff550ca16e4394b Mon Sep 17 00:00:00 2001 From: KJBig Date: Wed, 25 Sep 2024 17:14:49 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat=20:=20=EB=A9=80=ED=8B=B0=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 0 -> 6148 bytes .github/workflows/mulit-ci-cd.yml | 86 +++ .gitmodules | 5 +- build.gradle | 103 ++-- env | 1 + gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 61608 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 12 +- gradlew.bat | 183 +++---- settings.gradle | 8 +- sluv-admin/Dockerfile | 4 + sluv-admin/build.gradle | 21 + .../java/com/sluv/admin/AdminApplication.java | 13 + sluv-admin/src/main/resources/application.yml | 38 ++ sluv-admin/src/main/resources/banner.txt | 5 + .../com/sluv/admin/AdminApplicationTests.java | 5 +- sluv-api/Dockerfile | 4 + sluv-api/build.gradle | 30 ++ sluv-api/src/.DS_Store | Bin 0 -> 6148 bytes sluv-api/src/main/.DS_Store | Bin 0 -> 6148 bytes .../java/com/sluv/api/ApiApplication.java | 19 + .../api/admin/controller/AdminController.java | 36 ++ .../api/admin/dto/request/AdminRequest.java | 4 +- .../dto/request/AdminUserTokenRequest.java | 4 +- .../api/admin/dto/response/AdminResponse.java | 8 +- .../dto/response/AdminUserTokenResponse.java | 8 +- .../sluv/api/admin/service/AdminService.java | 30 ++ .../api/alarm/controller/AlarmController.java | 49 ++ .../sluv/api}/alarm/dto/AlarmResponse.java | 16 +- .../sluv/api/alarm/service/AlarmService.java | 73 +++ .../alarm/service/CommentAlarmService.java | 53 +- .../api}/alarm/service/ItemAlarmService.java | 67 +-- .../alarm/service/QuestionAlarmService.java | 47 +- .../api}/alarm/service/UserAlarmService.java | 38 +- .../api/auth/controller/AuthController.java | 72 +++ .../com/sluv/api/auth/dto/MemberDetails.java | 51 ++ .../api/auth/dto/request/AuthRequest.java | 10 +- .../auth/dto/request/AutoLoginRequest.java | 13 + .../api/auth/dto/response/AuthResponse.java | 30 ++ .../auth/dto/response/AutoLoginResponse.java | 12 +- .../api/auth/service/AppleUserService.java | 116 ++++ .../sluv/api/auth/service/AuthService.java | 58 ++ .../api/auth/service/GoogleUserService.java | 33 ++ .../api/auth/service/KakaoUserService.java | 30 ++ .../utils/AuthUserIdArgumentResolver.java | 35 ++ .../brand/controller/BrandController.java | 32 +- .../brand/controller/NewBrandController.java | 33 ++ .../RecentSelectBrandController.java | 64 +-- .../dto/request/NewBrandPostRequest.java | 10 +- .../dto/request/RecentSelectBrandRequest.java | 13 +- .../dto/response/BrandSearchResponse.java | 19 +- .../dto/response/NewBrandPostResponse.java | 19 +- .../response/RecentSelectBrandResponse.java | 23 +- .../sluv/api/brand/service/BrandService.java | 53 ++ .../api/brand/service/NewBrandService.java | 30 ++ .../service/RecentSelectBrandService.java | 47 ++ .../controller/CelebActivityController.java | 22 +- .../celeb/controller/CelebController.java | 53 +- .../celeb/controller/NewCelebController.java | 23 +- .../RecentSelectCelebController.java | 61 +-- .../request/InterestedCelebPostRequest.java | 7 +- .../dto/request/NewCelebPostRequest.java | 4 +- .../dto/request/RecentSelectCelebRequest.java | 4 +- .../dto/response/CelebActivityResponse.java | 10 +- .../celeb/dto/response/CelebChipResponse.java | 16 +- .../CelebSearchByCategoryResponse.java | 12 +- .../dto/response/CelebSearchResponse.java | 10 +- .../InterestedCelebCategoryResponse.java | 14 +- .../InterestedCelebChildResponse.java | 10 +- .../InterestedCelebParentResponse.java | 16 +- .../dto/response/InterestedCelebResponse.java | 10 +- .../dto/response/NewCelebPostResponse.java | 10 +- .../response/RecentSelectCelebResponse.java | 10 +- .../celeb/service/CelebActivityService.java | 21 + .../sluv/api/celeb/service/CelebService.java | 128 +++++ .../celeb/service/CelebWithdrawService.java | 4 +- .../api/celeb/service/NewCelebService.java | 29 + .../service/RecentSelectCelebService.java | 45 ++ .../closet/controller/ClosetController.java | 65 +-- .../controller/ClosetItemController.java | 61 +-- .../dto/request/ClosetItemSelectRequest.java | 11 +- .../api/closet/dto/request/ClosetRequest.java | 15 +- .../dto/response/ClosetDetailResponse.java | 16 +- .../dto/response/ClosetListCountResponse.java | 25 + .../dto/response/ClosetNameCheckResponse.java | 24 + .../closet/dto/response/ClosetResponse.java | 14 +- .../sluv/api/closet/mapper/ClosetMapper.java | 12 + .../api/closet/service/ClosetItemService.java | 132 +++++ .../api/closet/service/ClosetService.java | 112 ++++ .../comment/controller/CommentController.java | 98 ++-- .../controller/CommentReportController.java | 21 +- .../dto/reponse/CommentItemResponse.java | 31 ++ .../comment/dto/reponse/CommentResponse.java | 27 +- .../dto/reponse/CommentSimpleResponse.java | 12 +- .../dto/reponse/SubCommentPageResponse.java | 26 + .../dto/request/CommentItemRequest.java | 4 +- .../dto/request/CommentPostRequest.java | 10 +- .../dto/request/CommentReportPostRequest.java | 6 +- .../api/comment/helper}/CommentHelper.java | 29 +- .../api/comment/helper/CommentImgHelper.java | 21 +- .../api/comment/helper/CommentItemHelper.java | 25 +- .../comment/service/CommentReportService.java | 42 ++ .../api/comment/service/CommentService.java | 213 ++++++++ .../elb}/ElasticBeanstalkController.java | 2 +- .../exception/GlobalExceptionHandler.java | 15 +- .../api/common/image/AWSS3Controller.java | 60 +++ .../api/common/log/RestControllerLogAop.java | 55 ++ .../api}/common/response/ErrorResponse.java | 4 +- .../response/PaginationCountResponse.java | 6 +- .../common/response/PaginationResponse.java | 8 +- .../common/response/SuccessDataResponse.java | 11 +- .../api}/common/response/SuccessResponse.java | 9 +- .../common/utils/PasswordEncoderUtil.java | 8 +- .../com/sluv/api}/config/AsyncConfig.java | 2 +- .../com/sluv/api/config/ComponentConfig.java | 9 + .../com/sluv/api}/config/SwaggerConfig.java | 18 +- .../java/com/sluv/api/config/WebConfig.java | 21 + .../sluv/api}/config/security/CorsConfig.java | 2 +- .../config/security/SpringSecurityConfig.java | 16 +- .../CustomAuthenticationEntryPoint.java | 11 +- .../filter/ExceptionHandlerFilter.java | 13 +- .../filter/JwtAuthenticationFilter.java | 49 ++ .../item/controller/HashtagController.java | 34 +- .../controller/ItemCategoryController.java | 15 +- .../api/item/controller/ItemController.java | 239 ++++++++ .../item/controller/ItemEditController.java | 19 +- .../item/controller/ItemReportController.java | 19 +- .../item/controller/PlaceRankController.java | 61 +-- .../item/controller/TempItemController.java | 69 +++ .../api}/item/dto/HashtagPostResponseDto.java | 4 +- .../sluv/api}/item/dto/HashtagRequestDto.java | 2 +- .../api}/item/dto/HashtagResponseDto.java | 4 +- .../sluv/api}/item/dto/HotPlaceResDto.java | 2 +- .../dto/ItemCategoryChildResponseDto.java | 4 +- .../sluv/api}/item/dto/ItemCategoryDto.java | 4 +- .../dto/ItemCategoryParentResponseDto.java | 4 +- .../sluv/api}/item/dto/ItemDetailFixData.java | 48 +- .../sluv/api}/item/dto/ItemDetailResDto.java | 34 +- .../sluv/api}/item/dto/ItemEditReqDto.java | 4 +- .../api}/item/dto/ItemHashtagResponseDto.java | 4 +- .../item/dto/ItemKeywordSearchResDto.java | 4 +- .../sluv/api}/item/dto/ItemPostReqDto.java | 8 +- .../sluv/api}/item/dto/ItemPostResDto.java | 2 +- .../sluv/api}/item/dto/ItemReportReqDto.java | 4 +- .../sluv/api}/item/dto/PlaceRankReqDto.java | 2 +- .../sluv/api}/item/dto/PlaceRankResDto.java | 4 +- .../api}/item/dto/TempItemCountResDto.java | 2 +- .../api}/item/dto/TempItemPostReqDto.java | 8 +- .../api}/item/dto/TempItemPostResDto.java | 2 +- .../sluv/api}/item/dto/TempItemResDto.java | 32 +- .../sluv/api/item/helper/HashtagHelper.java | 14 + .../com/sluv/api/item/helper/ItemHelper.java | 78 +++ .../sluv/api/item/service/HashtagService.java | 50 ++ .../api}/item/service/ItemCacheService.java | 13 +- .../item/service/ItemCategoryService.java | 17 +- .../api/item/service/ItemEditReqService.java | 31 ++ .../api/item/service/ItemReportService.java | 43 ++ .../sluv/api/item/service/ItemService.java | 491 +++++++++++++++++ .../item/service/ItemWithdrawService.java | 8 +- .../api/item/service/PlaceRankService.java | 42 ++ .../api/item/service/TempItemService.java | 198 +++++++ .../notice/controller/NoticeController.java | 31 +- .../api/notice/dto/NoticeDetailResponse.java | 12 +- .../api/notice/dto/NoticeSimpleResponse.java | 12 +- .../api/notice/service/NoticeService.java | 49 ++ .../controller/QuestionController.java | 217 +++----- .../question/dto/QuestionBuyPostReqDto.java | 2 +- .../question/dto/QuestionBuySimpleResDto.java | 18 +- .../question/dto/QuestionFindPostReqDto.java | 2 +- .../question/dto/QuestionGetDetailResDto.java | 16 +- .../api}/question/dto/QuestionHomeResDto.java | 21 +- .../dto/QuestionHowaboutPostReqDto.java | 2 +- .../api}/question/dto/QuestionImgReqDto.java | 2 +- .../api}/question/dto/QuestionImgResDto.java | 4 +- .../api}/question/dto/QuestionItemReqDto.java | 2 +- .../api}/question/dto/QuestionItemResDto.java | 12 +- .../api}/question/dto/QuestionPostResDto.java | 2 +- .../dto/QuestionRecommendPostReqDto.java | 3 +- .../question/dto/QuestionReportReqDto.java | 4 +- .../question/dto/QuestionVoteDataDto.java | 2 +- .../api}/question/dto/QuestionVoteReqDto.java | 2 +- .../question/mapper/QuestionDtoMapper.java | 50 +- .../question/service/QuestionService.java | 450 ++++++++-------- .../service/QuestionWithdrawService.java | 16 + .../search/controller/SearchController.java | 143 ++--- .../search/dto/RecentSearchChipResDto.java | 2 +- .../search/dto/SearchItemCountResDto.java | 2 +- .../api}/search/dto/SearchKeywordResDto.java | 2 +- .../search/dto/SearchKeywordTotalResDto.java | 16 +- .../api}/search/dto/SearchTotalResDto.java | 12 +- .../api}/search/engine/DBSearchEngine.java | 14 +- .../api}/search/engine/ELKSearchEngine.java | 0 .../sluv/api}/search/engine/SearchEngine.java | 2 +- .../search/service/SearchEngineService.java | 132 +++++ .../service/SearchEngineTotalService.java | 44 +- .../api/search/service/SearchService.java | 124 +++++ .../utils/ElasticSearchConnectUtil.java | 81 +++ .../api/user/controller/FollowController.java | 69 +++ .../user/controller/UserCelebController.java | 73 +++ .../api/user/controller/UserController.java | 177 ++++++ .../user/controller/UserLikeController.java | 53 ++ .../user/controller/UserRecentController.java | 41 ++ .../user/controller/UserReportController.java | 21 +- .../com/sluv/api}/user/dto/UserIdDto.java | 2 +- .../sluv/api}/user/dto/UserMypageResDto.java | 5 +- .../api}/user/dto/UserProfileImgReqDto.java | 2 +- .../sluv/api}/user/dto/UserProfileReqDto.java | 2 +- .../sluv/api}/user/dto/UserReportReqDto.java | 4 +- .../com/sluv/api}/user/dto/UserSocialDto.java | 6 +- .../sluv/api}/user/dto/UserTermsResDto.java | 5 +- .../api}/user/dto/UserWithdrawReqDto.java | 4 +- .../sluv/api/user/service/FollowService.java | 72 +++ .../api}/user/service/UserCelebService.java | 107 ++-- .../api/user/service/UserLikeService.java | 75 +++ .../api/user/service/UserRecentService.java | 104 ++++ .../api/user/service/UserReportService.java | 36 ++ .../sluv/api/user/service/UserService.java | 260 +++++++++ .../user/service/UserWithdrawDataService.java | 55 ++ sluv-api/src/main/resources/application.yml | 38 ++ sluv-api/src/main/resources/banner.txt | 6 + .../com/sluv/api/ApiApplicationTests.java | 14 + .../brand/repository/BrandRepositoryTest.java | 0 .../brand/service/BrandServiceTest.java | 0 .../brand/service/NewBrandServiceTest.java | 0 .../service/RecentSelectBrandServiceTest.java | 0 .../closet/service/ClosetServiceTest.java | 0 .../item/service/HashtagServiceTest.java | 0 .../item/service/ItemCategoryServiceTest.java | 0 .../domain/item/service/ItemServiceTest.java | 0 .../notice/service/NoticeServiceTest.java | 0 .../user/service/FollowServiceTest.java | 0 .../user/service/UserReportServiceTest.java | 0 .../com/sluv/api}/fixture/BrandFixture.java | 4 +- .../com/sluv/api}/fixture/CelebFixture.java | 12 +- .../com/sluv/api/fixture/ClosetFixture.java | 25 + .../com/sluv/api}/fixture/ItemFixture.java | 18 +- .../com/sluv/api}/fixture/NoticeFixture.java | 8 +- .../com/sluv/api}/fixture/UserFixture.java | 12 +- sluv-batch/Dockerfile | 4 + sluv-batch/build.gradle | 24 + .../java/com/sluv/batch/BatchApplication.java | 6 +- .../sluv/batch/config/ComponentConfig.java | 9 + .../com/sluv/batch/item}/ItemScheduler.java | 69 +-- .../batch/question}/QuestionScheduler.java | 26 +- .../sluv/batch/search/SearchScheduler.java | 38 ++ .../com/sluv/batch/user}/UserScheduler.java | 11 +- .../com/sluv/batch/visit}/VisitScheduler.java | 16 +- sluv-batch/src/main/resources/application.yml | 38 ++ sluv-batch/src/main/resources/banner.txt | 5 + .../com/sluv/batch/BatchApplicationTests.java | 13 + sluv-common/build.gradle | 12 + .../sluv/common/annotation/CurrentUserId.java | 9 + .../com/sluv/common/config}/JasyptConfig.java | 6 +- .../sluv/common/constant/ConstantData.java | 7 + .../exception/ApplicationException.java | 17 + .../com/sluv}/common/exception/ErrorCode.java | 4 +- .../sluv/common/exception/HttpStatusCode.java | 17 + .../com/sluv/common}/jwt/JwtProvider.java | 69 +-- .../jwt/exception/ExpiredTokenException.java | 6 +- .../common/jwt/exception/HttpStatusCode.java | 16 + .../exception/InvalidateTokenException.java | 6 +- .../NoAuthorizationTokenException.java | 6 +- .../common/jwt/exception/TokenException.java | 10 + .../src/main/resources/application-common.yml | 36 ++ .../com/sluv/common/TestConfiguration.java | 7 + sluv-domain/build.gradle | 39 ++ .../com/sluv}/domain/admin/entity/Admin.java | 4 +- .../admin/exception/AdminException.java | 10 + .../exception/AdminNotFoundException.java | 6 +- .../AdminPasswordNotMatchException.java | 6 +- .../admin/repository/AdminRepository.java | 4 +- .../admin/service/AdminDomainService.java | 41 ++ .../sluv}/domain/alarm/dto/AlarmElement.java | 10 +- .../sluv}/domain/alarm/dto/AlarmImages.java | 8 +- .../com/sluv}/domain/alarm/entity/Alarm.java | 24 +- .../domain/alarm/enums/AlarmMessage.java | 2 +- .../sluv}/domain/alarm/enums/AlarmStatus.java | 2 +- .../sluv}/domain/alarm/enums/AlarmType.java | 2 +- .../exception/AlarmAccessDeniedException.java | 6 +- .../alarm/exception/AlarmException.java | 10 + .../exception/AlarmNotFoundException.java | 6 +- .../alarm/repository/AlarmRepository.java | 6 +- .../impl/AlarmRepositoryCustom.java | 4 +- .../repository/impl/AlarmRepositoryImpl.java | 12 +- .../alarm/service/AlarmDomainService.java | 69 +++ .../domain/auth/dto/SocialUserInfoDto.java | 12 +- .../com/sluv}/domain/auth/enums/SnsType.java | 4 +- .../domain/auth/exception/AuthException.java | 10 + .../NoSupportSocialTypeException.java | 6 +- .../auth/exception/UserBlockedException.java | 6 +- .../com/sluv}/domain/brand/entity/Brand.java | 16 +- .../sluv}/domain/brand/entity/NewBrand.java | 28 +- .../brand/entity/RecentSelectBrand.java | 21 +- .../domain/brand/enums/NewBrandStatus.java | 2 +- .../brand/exception/BrandException.java | 10 + .../exception/BrandNotFoundException.java | 6 +- .../exception/NewBrandNotFoundException.java | 6 +- .../brand/repository/BrandRepository.java | 8 + .../brand/repository/NewBrandRepository.java | 7 +- .../RecentSelectBrandRepository.java | 9 +- .../impl/BrandRepositoryCustom.java | 4 +- .../repository/impl/BrandRepositoryImpl.java | 8 +- .../RecentSelectBrandRepositoryCustom.java | 9 + .../impl/RecentSelectBrandRepositoryImpl.java | 12 +- .../brand/service/BrandDomainService.java | 47 ++ .../brand/service/NewBrandDomainService.java | 39 ++ .../RecentSelectBrandDomainService.java | 44 ++ .../com/sluv}/domain/celeb/dto/CelebDto.java | 4 +- .../com/sluv}/domain/celeb/entity/Celeb.java | 6 +- .../domain/celeb/entity/CelebActivity.java | 4 +- .../domain/celeb/entity/CelebCategory.java | 4 +- .../domain/celeb/entity/InterestedCeleb.java | 6 +- .../sluv}/domain/celeb/entity/NewCeleb.java | 11 +- .../celeb/entity/RecentSelectCeleb.java | 14 +- .../sluv}/domain/celeb/enums/CelebStatus.java | 2 +- .../domain/celeb/enums/NewCelebStatus.java | 2 +- .../celeb/exception/CelebException.java | 10 + .../exception/CelebNotFoundException.java | 6 +- .../exception/NewCelebNotFoundException.java | 6 +- .../repository/CelebActivityRepository.java | 8 + .../repository/CelebCategoryRepository.java | 7 +- .../celeb/repository/CelebRepository.java | 9 + .../Impl/CelebActivityRepositoryCustom.java | 5 +- .../Impl/CelebActivityRepositoryImpl.java | 6 +- .../Impl/CelebRepositoryCustom.java | 8 +- .../repository/Impl/CelebRepositoryImpl.java | 24 +- .../RecentSelectCelebRepositoryCustom.java | 10 + .../Impl/RecentSelectCelebRepositoryImpl.java | 14 +- .../repository/InterestedCelebRepository.java | 7 +- .../celeb/repository/NewCelebRepository.java | 9 +- .../RecentSelectCelebRepository.java | 9 +- .../service/CelebActivityDomainService.java | 17 +- .../service/CelebCategoryDomainService.java | 21 + .../celeb/service/CelebDomainService.java | 66 +++ .../service/InterestedCelebDomainService.java | 25 + .../celeb/service/NewCelebDomainService.java | 35 ++ .../RecentSelectCelebDomainService.java | 42 ++ .../domain/closet/dto/ClosetCountDto.java | 14 + .../domain/closet/dto/ClosetDomainDto.java | 29 + .../sluv}/domain/closet/entity/Closet.java | 34 +- .../domain/closet/enums/ClosetColor.java | 2 +- .../domain/closet/enums/ClosetStatus.java | 2 +- .../exception/BasicClosetDeleteException.java | 6 +- .../closet/exception/ClosetException.java | 10 + .../exception/ClosetNotFoundException.java | 6 +- .../closet/repository/ClosetRepository.java | 6 +- .../impl/ClosetRepositoryCustom.java | 10 +- .../repository/impl/ClosetRepositoryImpl.java | 18 +- .../closet/service/ClosetDomainService.java | 83 +++ .../domain/comment/dto/CommentImgDto.java | 4 +- .../sluv}/domain/comment/entity/Comment.java | 10 +- .../domain/comment/entity/CommentImg.java | 6 +- .../domain/comment/entity/CommentItem.java | 11 +- .../domain/comment/entity/CommentLike.java | 6 +- .../domain/comment/entity/CommentReport.java | 18 +- .../comment/enums/CommentReportReason.java | 2 +- .../domain/comment/enums/CommentStatus.java | 2 +- .../comment/exception/CommentException.java | 10 + .../exception/CommentNotFoundException.java | 6 +- .../CommentReportDuplicateException.java | 6 +- .../repository/CommentImgRepository.java | 7 +- .../repository/CommentItemRepository.java | 8 +- .../repository/CommentLikeRepository.java | 4 +- .../repository/CommentReportRepository.java | 4 +- .../comment/repository/CommentRepository.java | 6 +- .../impl/CommentRepositoryCustom.java | 8 +- .../impl/CommentRepositoryImpl.java | 14 +- .../comment/service/CommentDomainService.java | 78 +++ .../service/CommentImgDomainService.java | 26 + .../service/CommentLikeDomainService.java | 33 ++ .../service/CommentReportDomainService.java | 29 + .../domain}/common/entity/BaseEntity.java | 9 +- .../common/enums/ItemImgOrLinkStatus.java | 2 +- .../domain}/common/enums/ReportStatus.java | 2 +- .../com/sluv/domain/config/JpaConfig.java | 13 + .../sluv/domain}/config/QueryDslConfig.java | 2 +- .../com/sluv/domain/item/dto/ItemImgDto.java | 16 +- .../com/sluv/domain/item/dto/ItemLinkDto.java | 16 +- .../com/sluv/domain/item/dto/ItemSaveDto.java | 21 + .../sluv/domain/item/dto/ItemSimpleDto.java | 12 +- .../sluv/domain/item/dto/TempItemSaveDto.java | 21 + .../item/dto/hashtag/HashtagCountDto.java | 24 + .../sluv}/domain/item/entity/DayHotItem.java | 14 +- .../domain/item/entity/EfficientItem.java | 4 +- .../com/sluv}/domain/item/entity/Item.java | 24 +- .../domain/item/entity/ItemCategory.java | 4 +- .../sluv}/domain/item/entity/ItemEditReq.java | 15 +- .../com/sluv}/domain/item/entity/ItemImg.java | 10 +- .../sluv}/domain/item/entity/ItemLike.java | 6 +- .../sluv}/domain/item/entity/ItemLink.java | 11 +- .../sluv}/domain/item/entity/ItemReport.java | 18 +- .../sluv}/domain/item/entity/ItemScrap.java | 6 +- .../sluv}/domain/item/entity/LuxuryItem.java | 4 +- .../sluv}/domain/item/entity/PlaceRank.java | 11 +- .../sluv}/domain/item/entity/RecentItem.java | 6 +- .../sluv}/domain/item/entity/TempItem.java | 24 +- .../sluv}/domain/item/entity/TempItemImg.java | 10 +- .../domain/item/entity/TempItemLink.java | 10 +- .../sluv}/domain/item/entity/WeekHotItem.java | 14 +- .../domain/item/entity/hashtag/Hashtag.java | 4 +- .../item/entity/hashtag/HashtagStatus.java | 2 +- .../item/entity/hashtag/ItemHashtag.java | 6 +- .../item/entity/hashtag/TempItemHashtag.java | 6 +- .../domain/item/enums/ItemEditReqReason.java | 2 +- .../domain/item/enums/ItemNumberConfig.java | 2 +- .../domain/item/enums/ItemReportReason.java | 2 +- .../sluv}/domain/item/enums/ItemStatus.java | 2 +- .../ItemCategoryNotFoundException.java | 6 +- .../domain/item/exception/ItemException.java | 10 + .../exception/ItemNotActiveException.java | 6 +- .../item/exception/ItemNotFoundException.java | 6 +- .../ItemReportDuplicateException.java | 6 +- .../exception/StandardNotFoundException.java | 6 +- .../exception/TempItemNotFoundException.java | 6 +- .../exception/hashtag/HashtagException.java | 10 + .../hashtag/HashtagNotFoundException.java | 6 +- .../item/repository/DayHotItemRepository.java | 4 +- .../repository/EfficientItemRepository.java | 4 +- .../repository/ItemCategoryRepository.java | 7 +- .../repository/ItemEditReqRepository.java | 4 +- .../item/repository/ItemImgRepository.java | 9 +- .../item/repository/ItemLikeRepository.java | 4 +- .../item/repository/ItemLinkRepository.java | 9 +- .../item/repository/ItemReportRepository.java | 9 + .../item/repository/ItemRepository.java | 8 +- .../item/repository/ItemScrapRepository.java | 8 +- .../item/repository/LuxuryItemRepository.java | 4 +- .../item/repository/PlaceRankRepository.java | 9 +- .../item/repository/RecentItemRepository.java | 6 +- .../repository/TempItemImgRepository.java | 12 +- .../repository/TempItemLinkRepository.java | 13 + .../item/repository/TempItemRepository.java | 6 +- .../repository/WeekHotItemRepository.java | 4 +- .../repository/hashtag/HashtagRepository.java | 9 +- .../hashtag/ItemHashtagRepository.java | 7 +- .../hashtag/TempItemHashtagRepository.java | 14 + .../hashtag/impl/HashtagRepositoryCustom.java | 9 + .../hashtag/impl/HashtagRepositoryImpl.java | 15 +- .../impl/TempItemHashtagRepositoryCustom.java | 9 + .../impl/TempItemHashtagRepositoryImpl.java | 23 + .../impl/ItemImgRepositoryCustom.java | 7 + .../impl/ItemImgRepositoryImpl.java | 6 +- .../impl/ItemReportRepositoryCustom.java | 8 + .../impl/ItemReportRepositoryImpl.java | 8 +- .../repository/impl/ItemRepositoryCustom.java | 31 +- .../repository/impl/ItemRepositoryImpl.java | 184 +++---- .../impl/ItemScrapRepositoryCustom.java | 9 + .../impl/ItemScrapRepositoryImpl.java | 8 +- .../impl/PlaceRankRepositoryCustom.java | 8 + .../impl/PlaceRankRepositoryImpl.java | 11 +- .../impl/RecentItemRepositoryCustom.java | 6 +- .../impl/RecentItemRepositoryImpl.java | 8 +- .../impl/TempItemImgRepositoryCustom.java | 9 + .../impl/TempItemImgRepositoryImpl.java | 24 + .../impl/TempItemLinkRepositoryCustom.java | 9 + .../impl/TempItemLinkRepositoryImpl.java | 23 + .../impl/TempItemRepositoryCustom.java | 8 +- .../impl/TempItemRepositoryImpl.java | 57 ++ .../item/service/DayHotItemDomainService.java | 25 + .../service/EfficientItemDomainService.java | 26 + .../service/ItemCategoryDomainService.java | 32 ++ .../item/service/ItemDomainService.java | 200 +++++++ .../service/ItemEditReqDomainService.java | 24 + .../service/ItemHashtagDomainService.java | 33 ++ .../item/service/ItemImgDomainService.java | 38 ++ .../item/service/ItemLikeDomainService.java | 37 ++ .../item/service/ItemLinkDomainService.java | 33 ++ .../item/service/ItemReportDomainService.java | 30 ++ .../item/service/ItemScrapDomainService.java | 53 ++ .../item/service/LuxuryItemDomainService.java | 25 + .../item/service/PlaceRankDomainService.java | 38 ++ .../item/service/RecentItemDomainService.java | 27 + .../item/service/TempItemDomainService.java | 49 ++ .../service/TempItemImgDomainService.java | 34 ++ .../service/TempItemLinkDomainService.java | 33 ++ .../service/WeekHotItemDomainService.java | 25 + .../service/hashtag/HashtagDomainService.java | 40 ++ .../hashtag/TempItemHashtagDomainService.java | 33 ++ .../sluv}/domain/notice/entity/Notice.java | 8 +- .../domain/notice/enums/NoticeStatus.java | 2 +- .../sluv/domain/notice/enums/NoticeType.java | 5 + .../notice/exception/NoticeException.java | 10 + .../exception/NoticeNotFoundException.java | 14 + .../notice/repository/NoticeRepository.java | 8 + .../impl/NoticeRepositoryCustom.java | 4 +- .../repository/impl/NoticeRepositoryImpl.java | 6 +- .../notice/service/NoticeDomainService.java | 28 + .../question/dto/QuestionImgSimpleDto.java | 16 +- .../question/dto/QuestionSimpleResDto.java | 24 +- .../question/entity/DailyHotQuestion.java | 16 +- .../domain/question/entity/Question.java | 8 +- .../domain/question/entity/QuestionBuy.java | 18 +- .../domain/question/entity/QuestionFind.java | 22 +- .../question/entity/QuestionHowabout.java | 18 +- .../domain/question/entity/QuestionImg.java | 18 +- .../domain/question/entity/QuestionItem.java | 16 +- .../domain/question/entity/QuestionLike.java | 6 +- .../question/entity/QuestionRecommend.java | 17 +- .../entity/QuestionRecommendCategory.java | 4 +- .../question/entity/QuestionReport.java | 18 +- .../domain/question/entity/QuestionVote.java | 11 +- .../question/entity/RecentQuestion.java | 6 +- .../question/enums/QuestionReportReason.java | 2 +- .../domain/question/enums/QuestionStatus.java | 2 +- .../question/exception/QuestionException.java | 10 + .../exception/QuestionNotFoundException.java | 9 +- .../QuestionReportDuplicateException.java | 7 +- .../QuestionTypeNotFoundException.java | 6 +- .../DailyHotQuestionRepository.java | 4 +- .../repository/QuestionImgRepository.java | 7 +- .../repository/QuestionItemRepository.java | 7 +- .../repository/QuestionLikeRepository.java | 4 +- .../QuestionRecommendCategoryRepository.java | 7 +- .../repository/QuestionReportRepository.java | 4 +- .../repository/QuestionRepository.java | 8 +- .../repository/QuestionVoteRepository.java | 4 +- .../repository/RecentQuestionRepository.java | 6 +- .../impl/QuestionRepositoryCustom.java | 18 +- .../impl/QuestionRepositoryImpl.java | 110 ++-- .../impl/RecentQuestionRepositoryCustom.java | 6 +- .../impl/RecentQuestionRepositoryImpl.java | 12 +- .../service/QuestionDomainService.java | 131 +++++ .../service/QuestionImgDomainService.java | 36 ++ .../service/QuestionItemDomainService.java | 35 ++ .../service/QuestionLikeDomainService.java | 38 ++ ...uestionRecommendCategoryDomainService.java | 30 ++ .../service/QuestionReportDomainService.java | 29 + .../service/QuestionVoteDomainService.java | 44 ++ .../service/RecentQuestionDomainService.java | 35 ++ .../domain/search/dto/SearchFilterReqDto.java | 2 +- .../domain/search/entity/RecentSearch.java | 6 +- .../domain/search/entity/SearchData.java | 4 +- .../domain/search/entity/SearchRank.java | 6 +- .../domain/search/enums/SearchRankStatus.java | 2 +- .../repository/RecentSearchRepository.java | 6 +- .../repository/SearchDataRepository.java | 8 + .../repository/SearchRankRepository.java | 7 +- .../impl/RecentSearchRepositoryCustom.java | 9 + .../impl/RecentSearchRepositoryImpl.java | 8 +- .../impl/SearchDataRepositoryCustom.java | 7 +- .../impl/SearchDataRepositoryImpl.java | 6 +- .../service/RecentSearchDomainService.java | 37 ++ .../service/SearchDataDomainService.java | 41 ++ .../service/SearchRankDomainService.java | 31 ++ .../sluv}/domain/user/dto/UserInfoDto.java | 4 +- .../domain/user/dto/UserSearchInfoDto.java | 4 +- .../com/sluv}/domain/user/entity/Follow.java | 4 +- .../com/sluv}/domain/user/entity/User.java | 56 +- .../sluv}/domain/user/entity/UserReport.java | 15 +- .../domain/user/entity/UserReportStack.java | 4 +- .../domain/user/entity/UserWithdraw.java | 13 +- .../com/sluv}/domain/user/enums/UserAge.java | 2 +- .../sluv}/domain/user/enums/UserGender.java | 2 +- .../domain/user/enums/UserReportReason.java | 2 +- .../sluv}/domain/user/enums/UserStatus.java | 2 +- .../domain/user/enums/UserWithdrawReason.java | 2 +- .../domain/user/exception/UserException.java | 10 + .../UserNicknameDuplicatedException.java | 6 +- .../user/exception/UserNoFCMException.java | 6 +- .../user/exception/UserNotFoundException.java | 7 +- .../exception/UserNotMatchedException.java | 7 +- .../UserReportDuplicateException.java | 6 +- .../user/repository/FollowRepository.java | 8 + .../user/repository/UserReportRepository.java | 8 + .../repository/UserReportStackRepository.java | 4 +- .../user/repository/UserRepository.java | 8 +- .../repository/UserWithdrawRepository.java | 4 +- .../impl/FollowRepositoryCustom.java | 8 +- .../repository/impl/FollowRepositoryImpl.java | 14 +- .../impl/UserReportRepositoryCustom.java | 4 +- .../impl/UserReportRepositoryImpl.java | 6 +- .../repository/impl/UserRepositoryCustom.java | 4 +- .../repository/impl/UserRepositoryImpl.java | 22 +- .../user/service/FollowDomainService.java | 62 +++ .../user/service/UserDomainService.java | 72 +++ .../user/service/UserReportDomainService.java | 27 + .../service/UserReportStackDomainService.java | 19 + .../service/UserWithdrawDomainService.java | 22 + .../domain/visit/entity/VisitHistory.java | 4 +- .../repository/VisitHistoryRepository.java | 4 +- .../service/VisitHistoryDomainService.java | 22 + .../src/main/resources/application-domain.yml | 47 ++ sluv-infra/build.gradle | 20 + .../com/sluv/infra}/ai/AiModelRepository.java | 14 +- .../com/sluv/infra}/ai/AiModelService.java | 22 +- .../infra}/ai/dto/CommentCleanBotReqDto.java | 2 +- .../infra}/ai/dto/ItemColorCheckReqDto.java | 2 +- .../com/sluv/infra}/cache/CacheService.java | 13 +- .../com/sluv/infra}/cache/RedisService.java | 17 +- .../com/sluv/infra}/config/FcmConfig.java | 2 +- .../com/sluv/infra}/config/RedisConfig.java | 2 +- .../discord/DiscordWebHookConnector.java | 2 +- .../discord/DiscordWebHookException.java | 6 +- .../infra}/discord/DiscordWebHookService.java | 12 +- .../sluv/infra/discord/WebHookException.java | 10 + .../sluv/infra}/discord/WebHookMessage.java | 2 +- .../sluv/infra}/discord/WebHookService.java | 8 +- .../firebase/FcmNotificationService.java | 12 +- .../FcmAccessTokenInvalidateException.java | 6 +- .../exception/FcmConnectException.java | 6 +- .../firebase/exception/FcmException.java | 10 + .../oauth/apple/ApplePlatformClient.java | 148 +++++ .../oauth/google/GooglePlatformClient.java | 40 +- .../oauth/kakao/KakaoPlatformClient.java | 37 +- .../java/com/sluv/infra}/s3/AWSS3Service.java | 26 +- .../java/com/sluv/infra}/s3/ImgExtension.java | 2 +- .../sluv/infra}/s3/PreSingedUrlResDto.java | 2 +- .../java/com/sluv/infra}/s3/S3Config.java | 10 +- .../src/main/resources/application-infra.yml | 49 ++ .../admin/controller/AdminController.java | 42 -- .../admin/exception/AdminException.java | 10 - .../domain/admin/service/AdminService.java | 49 -- .../alarm/controller/AlarmController.java | 58 -- .../alarm/exception/AlarmException.java | 10 - .../domain/alarm/service/AlarmService.java | 101 ---- .../auth/controller/AuthController.java | 79 --- .../domain/auth/dto/AuthResponseDto.java | 20 - .../domain/auth/dto/AutoLoginRequestDto.java | 11 - .../domain/auth/exception/AuthException.java | 10 - .../domain/auth/service/AppleUserService.java | 249 --------- .../domain/auth/service/AuthService.java | 59 -- .../brand/controller/NewBrandController.java | 34 -- .../brand/exception/BrandException.java | 10 - .../brand/repository/BrandRepository.java | 8 - .../RecentSelectBrandRepositoryCustom.java | 10 - .../domain/brand/service/BrandService.java | 54 -- .../domain/brand/service/NewBrandService.java | 31 -- .../service/RecentSelectBrandService.java | 56 -- .../celeb/exception/CelebException.java | 10 - .../domain/celeb/handler/CelebHandler.java | 21 - .../repository/CelebActivityRepository.java | 10 - .../celeb/repository/CelebRepository.java | 9 - .../RecentSelectCelebRepositoryCustom.java | 11 - .../domain/celeb/service/CelebService.java | 127 ----- .../domain/celeb/service/NewCelebService.java | 30 -- .../service/RecentSelectCelebService.java | 58 -- .../closet/dto/ClosetListCountResDto.java | 23 - .../closet/dto/ClosetNameCheckResDto.java | 22 - .../closet/exception/ClosetException.java | 10 - .../closet/service/ClosetItemService.java | 138 ----- .../domain/closet/service/ClosetService.java | 115 ---- .../domain/comment/dto/CommentItemResDto.java | 31 -- .../comment/dto/SubCommentPageResDto.java | 26 - .../comment/exception/CommentException.java | 10 - .../comment/service/CommentReportService.java | 42 -- .../comment/service/CommentService.java | 199 ------- .../item/controller/ItemController.java | 310 ----------- .../item/controller/TempItemController.java | 85 --- .../domain/item/exception/ItemException.java | 10 - .../exception/hashtag/HashtagException.java | 10 - .../server/domain/item/helper/ItemHelper.java | 51 -- .../item/repository/ItemReportRepository.java | 9 - .../repository/TempItemLinkRepository.java | 13 - .../hashtag/TempItemHashtagRepository.java | 13 - .../hashtag/impl/HashtagRepositoryCustom.java | 9 - .../impl/ItemImgRepositoryCustom.java | 7 - .../impl/ItemReportRepositoryCustom.java | 8 - .../impl/ItemScrapRepositoryCustom.java | 11 - .../impl/PlaceRankRepositoryCustom.java | 10 - .../impl/TempItemRepositoryImpl.java | 106 ---- .../domain/item/service/HashtagService.java | 51 -- .../item/service/ItemEditReqService.java | 29 - .../item/service/ItemReportService.java | 38 -- .../domain/item/service/ItemService.java | 509 ------------------ .../domain/item/service/PlaceRankService.java | 40 -- .../domain/item/service/TempItemService.java | 174 ------ .../domain/notice/enums/NoticeType.java | 5 - .../notice/exception/NoticeException.java | 10 - .../exception/NoticeNotFoundException.java | 14 - .../notice/repository/NoticeRepository.java | 8 - .../domain/notice/service/NoticeService.java | 49 -- .../question/exception/QuestionException.java | 10 - .../service/QuestionWithdrawService.java | 15 - .../repository/SearchDataRepository.java | 8 - .../impl/RecentSearchRepositoryCustom.java | 10 - .../search/scheduler/SearchScheduler.java | 48 -- .../search/service/SearchEngineService.java | 126 ----- .../domain/search/service/SearchService.java | 124 ----- .../utils/ElasticSearchConnectUtil.java | 81 --- .../user/controller/FollowController.java | 87 --- .../user/controller/UserCelebController.java | 83 --- .../user/controller/UserController.java | 222 -------- .../user/controller/UserLikeController.java | 63 --- .../user/controller/UserRecentController.java | 49 -- .../server/domain/user/enums/SnsType.java | 7 - .../domain/user/exception/UserException.java | 10 - .../user/repository/FollowRepository.java | 8 - .../user/repository/UserReportRepository.java | 8 - .../domain/user/service/FollowService.java | 70 --- .../domain/user/service/UserLikeService.java | 69 --- .../user/service/UserRecentService.java | 110 ---- .../user/service/UserReportService.java | 38 -- .../domain/user/service/UserService.java | 246 --------- .../user/service/UserWithdrawDataService.java | 55 -- .../exception/ApplicationException.java | 17 - .../global/discord/WebHookException.java | 10 - .../firebase/exception/FcmException.java | 10 - .../global/jwt/exception/TokenException.java | 10 - .../jwt/filter/JwtAuthenticationFilter.java | 30 -- .../server/global/s3/AWSS3Controller.java | 132 ----- src/main/resources | 1 - .../sluv/server/fixture/ClosetFixture.java | 21 - 702 files changed, 10995 insertions(+), 8225 deletions(-) create mode 100644 .DS_Store create mode 100644 .github/workflows/mulit-ci-cd.yml create mode 160000 env create mode 100644 sluv-admin/Dockerfile create mode 100644 sluv-admin/build.gradle create mode 100644 sluv-admin/src/main/java/com/sluv/admin/AdminApplication.java create mode 100644 sluv-admin/src/main/resources/application.yml create mode 100644 sluv-admin/src/main/resources/banner.txt rename src/test/java/com/sluv/server/SluvServerApplicationTests.java => sluv-admin/src/test/java/com/sluv/admin/AdminApplicationTests.java (62%) create mode 100644 sluv-api/Dockerfile create mode 100644 sluv-api/build.gradle create mode 100644 sluv-api/src/.DS_Store create mode 100644 sluv-api/src/main/.DS_Store create mode 100644 sluv-api/src/main/java/com/sluv/api/ApiApplication.java create mode 100644 sluv-api/src/main/java/com/sluv/api/admin/controller/AdminController.java rename src/main/java/com/sluv/server/domain/admin/dto/AdminReqDto.java => sluv-api/src/main/java/com/sluv/api/admin/dto/request/AdminRequest.java (76%) rename src/main/java/com/sluv/server/domain/admin/dto/AdminUserTokenReqDto.java => sluv-api/src/main/java/com/sluv/api/admin/dto/request/AdminUserTokenRequest.java (80%) rename src/main/java/com/sluv/server/domain/admin/dto/AdminResDto.java => sluv-api/src/main/java/com/sluv/api/admin/dto/response/AdminResponse.java (60%) rename src/main/java/com/sluv/server/domain/admin/dto/AdminUserTokenResDto.java => sluv-api/src/main/java/com/sluv/api/admin/dto/response/AdminUserTokenResponse.java (58%) create mode 100644 sluv-api/src/main/java/com/sluv/api/admin/service/AdminService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/alarm/controller/AlarmController.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/alarm/dto/AlarmResponse.java (85%) create mode 100644 sluv-api/src/main/java/com/sluv/api/alarm/service/AlarmService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/alarm/service/CommentAlarmService.java (56%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/alarm/service/ItemAlarmService.java (59%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/alarm/service/QuestionAlarmService.java (54%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/alarm/service/UserAlarmService.java (55%) create mode 100644 sluv-api/src/main/java/com/sluv/api/auth/controller/AuthController.java create mode 100644 sluv-api/src/main/java/com/sluv/api/auth/dto/MemberDetails.java rename src/main/java/com/sluv/server/domain/auth/dto/AuthRequestDto.java => sluv-api/src/main/java/com/sluv/api/auth/dto/request/AuthRequest.java (70%) create mode 100644 sluv-api/src/main/java/com/sluv/api/auth/dto/request/AutoLoginRequest.java create mode 100644 sluv-api/src/main/java/com/sluv/api/auth/dto/response/AuthResponse.java rename src/main/java/com/sluv/server/domain/auth/dto/AutoLoginResponseDto.java => sluv-api/src/main/java/com/sluv/api/auth/dto/response/AutoLoginResponse.java (60%) create mode 100644 sluv-api/src/main/java/com/sluv/api/auth/service/AppleUserService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/auth/service/AuthService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/auth/service/GoogleUserService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/auth/service/KakaoUserService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/auth/utils/AuthUserIdArgumentResolver.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/brand/controller/BrandController.java (52%) create mode 100644 sluv-api/src/main/java/com/sluv/api/brand/controller/NewBrandController.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/brand/controller/RecentSelectBrandController.java (58%) rename src/main/java/com/sluv/server/domain/brand/dto/NewBrandPostReqDto.java => sluv-api/src/main/java/com/sluv/api/brand/dto/request/NewBrandPostRequest.java (56%) rename src/main/java/com/sluv/server/domain/brand/dto/RecentSelectBrandReqDto.java => sluv-api/src/main/java/com/sluv/api/brand/dto/request/RecentSelectBrandRequest.java (55%) rename src/main/java/com/sluv/server/domain/brand/dto/BrandSearchResDto.java => sluv-api/src/main/java/com/sluv/api/brand/dto/response/BrandSearchResponse.java (63%) rename src/main/java/com/sluv/server/domain/brand/dto/NewBrandPostResDto.java => sluv-api/src/main/java/com/sluv/api/brand/dto/response/NewBrandPostResponse.java (54%) rename src/main/java/com/sluv/server/domain/brand/dto/RecentSelectBrandResDto.java => sluv-api/src/main/java/com/sluv/api/brand/dto/response/RecentSelectBrandResponse.java (69%) create mode 100644 sluv-api/src/main/java/com/sluv/api/brand/service/BrandService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/brand/service/NewBrandService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/brand/service/RecentSelectBrandService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/celeb/controller/CelebActivityController.java (64%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/celeb/controller/CelebController.java (51%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/celeb/controller/NewCelebController.java (51%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/celeb/controller/RecentSelectCelebController.java (58%) rename src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebPostReqDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/request/InterestedCelebPostRequest.java (80%) rename src/main/java/com/sluv/server/domain/celeb/dto/NewCelebPostReqDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/request/NewCelebPostRequest.java (73%) rename src/main/java/com/sluv/server/domain/celeb/dto/RecentSelectCelebReqDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/request/RecentSelectCelebRequest.java (77%) rename src/main/java/com/sluv/server/domain/celeb/dto/CelebActivityResDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebActivityResponse.java (61%) rename src/main/java/com/sluv/server/domain/celeb/dto/CelebChipResDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebChipResponse.java (70%) rename src/main/java/com/sluv/server/domain/celeb/dto/CelebSearchByCategoryResDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebSearchByCategoryResponse.java (67%) rename src/main/java/com/sluv/server/domain/celeb/dto/CelebSearchResDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebSearchResponse.java (90%) rename src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebCategoryResDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebCategoryResponse.java (55%) rename src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebChildResDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebChildResponse.java (77%) rename src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebParentResDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebParentResponse.java (72%) rename src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebResDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebResponse.java (78%) rename src/main/java/com/sluv/server/domain/celeb/dto/NewCelebPostResDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/response/NewCelebPostResponse.java (68%) rename src/main/java/com/sluv/server/domain/celeb/dto/RecentSelectCelebResDto.java => sluv-api/src/main/java/com/sluv/api/celeb/dto/response/RecentSelectCelebResponse.java (86%) create mode 100644 sluv-api/src/main/java/com/sluv/api/celeb/service/CelebActivityService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/celeb/service/CelebService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/celeb/service/CelebWithdrawService.java (75%) create mode 100644 sluv-api/src/main/java/com/sluv/api/celeb/service/NewCelebService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/celeb/service/RecentSelectCelebService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/closet/controller/ClosetController.java (52%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/closet/controller/ClosetItemController.java (62%) rename src/main/java/com/sluv/server/domain/closet/dto/ClosetItemSelectReqDto.java => sluv-api/src/main/java/com/sluv/api/closet/dto/request/ClosetItemSelectRequest.java (66%) rename src/main/java/com/sluv/server/domain/closet/dto/ClosetReqDto.java => sluv-api/src/main/java/com/sluv/api/closet/dto/request/ClosetRequest.java (71%) rename src/main/java/com/sluv/server/domain/closet/dto/ClosetDetailResDto.java => sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetDetailResponse.java (72%) create mode 100644 sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetListCountResponse.java create mode 100644 sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetNameCheckResponse.java rename src/main/java/com/sluv/server/domain/closet/dto/ClosetResDto.java => sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetResponse.java (75%) create mode 100644 sluv-api/src/main/java/com/sluv/api/closet/mapper/ClosetMapper.java create mode 100644 sluv-api/src/main/java/com/sluv/api/closet/service/ClosetItemService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/closet/service/ClosetService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/comment/controller/CommentController.java (50%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/comment/controller/CommentReportController.java (59%) create mode 100644 sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentItemResponse.java rename src/main/java/com/sluv/server/domain/comment/dto/CommentResDto.java => sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentResponse.java (71%) rename src/main/java/com/sluv/server/domain/comment/dto/CommentSimpleResDto.java => sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentSimpleResponse.java (75%) create mode 100644 sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/SubCommentPageResponse.java rename src/main/java/com/sluv/server/domain/comment/dto/CommentItemReqDto.java => sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentItemRequest.java (83%) rename src/main/java/com/sluv/server/domain/comment/dto/CommentPostReqDto.java => sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentPostRequest.java (72%) rename src/main/java/com/sluv/server/domain/comment/dto/CommentReportPostReqDto.java => sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentReportPostRequest.java (71%) rename {src/main/java/com/sluv/server/domain/comment/handler => sluv-api/src/main/java/com/sluv/api/comment/helper}/CommentHelper.java (61%) rename src/main/java/com/sluv/server/domain/comment/manager/CommentImgManager.java => sluv-api/src/main/java/com/sluv/api/comment/helper/CommentImgHelper.java (52%) rename src/main/java/com/sluv/server/domain/comment/manager/CommentItemManager.java => sluv-api/src/main/java/com/sluv/api/comment/helper/CommentItemHelper.java (59%) create mode 100644 sluv-api/src/main/java/com/sluv/api/comment/service/CommentReportService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/comment/service/CommentService.java rename {src/main/java/com/sluv/server/global/common => sluv-api/src/main/java/com/sluv/api/common/elb}/ElasticBeanstalkController.java (90%) rename {src/main/java/com/sluv/server/global => sluv-api/src/main/java/com/sluv/api}/common/exception/GlobalExceptionHandler.java (90%) create mode 100644 sluv-api/src/main/java/com/sluv/api/common/image/AWSS3Controller.java create mode 100644 sluv-api/src/main/java/com/sluv/api/common/log/RestControllerLogAop.java rename {src/main/java/com/sluv/server/global => sluv-api/src/main/java/com/sluv/api}/common/response/ErrorResponse.java (87%) rename src/main/java/com/sluv/server/global/common/response/PaginationCountResDto.java => sluv-api/src/main/java/com/sluv/api/common/response/PaginationCountResponse.java (59%) rename src/main/java/com/sluv/server/global/common/response/PaginationResDto.java => sluv-api/src/main/java/com/sluv/api/common/response/PaginationResponse.java (76%) rename {src/main/java/com/sluv/server/global => sluv-api/src/main/java/com/sluv/api}/common/response/SuccessDataResponse.java (58%) rename {src/main/java/com/sluv/server/global => sluv-api/src/main/java/com/sluv/api}/common/response/SuccessResponse.java (79%) rename {src/main/java/com/sluv/server/global => sluv-api/src/main/java/com/sluv/api}/common/utils/PasswordEncoderUtil.java (59%) rename {src/main/java/com/sluv/server/global => sluv-api/src/main/java/com/sluv/api}/config/AsyncConfig.java (97%) create mode 100644 sluv-api/src/main/java/com/sluv/api/config/ComponentConfig.java rename {src/main/java/com/sluv/server/global => sluv-api/src/main/java/com/sluv/api}/config/SwaggerConfig.java (86%) create mode 100644 sluv-api/src/main/java/com/sluv/api/config/WebConfig.java rename {src/main/java/com/sluv/server/global => sluv-api/src/main/java/com/sluv/api}/config/security/CorsConfig.java (95%) rename {src/main/java/com/sluv/server/global => sluv-api/src/main/java/com/sluv/api}/config/security/SpringSecurityConfig.java (83%) rename {src/main/java/com/sluv/server/global/jwt/exception => sluv-api/src/main/java/com/sluv/api/config/security/filter}/CustomAuthenticationEntryPoint.java (68%) rename {src/main/java/com/sluv/server/global/jwt => sluv-api/src/main/java/com/sluv/api/config/security}/filter/ExceptionHandlerFilter.java (81%) create mode 100644 sluv-api/src/main/java/com/sluv/api/config/security/filter/JwtAuthenticationFilter.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/controller/HashtagController.java (57%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/controller/ItemCategoryController.java (61%) create mode 100644 sluv-api/src/main/java/com/sluv/api/item/controller/ItemController.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/controller/ItemEditController.java (62%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/controller/ItemReportController.java (62%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/controller/PlaceRankController.java (51%) create mode 100644 sluv-api/src/main/java/com/sluv/api/item/controller/TempItemController.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/HashtagPostResponseDto.java (87%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/HashtagRequestDto.java (89%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/HashtagResponseDto.java (89%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/HotPlaceResDto.java (92%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/ItemCategoryChildResponseDto.java (87%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/ItemCategoryDto.java (92%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/ItemCategoryParentResponseDto.java (91%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/ItemDetailFixData.java (53%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/ItemDetailResDto.java (77%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/ItemEditReqDto.java (80%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/ItemHashtagResponseDto.java (88%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/ItemKeywordSearchResDto.java (93%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/ItemPostReqDto.java (89%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/ItemPostResDto.java (92%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/ItemReportReqDto.java (80%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/PlaceRankReqDto.java (85%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/PlaceRankResDto.java (84%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/TempItemCountResDto.java (92%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/TempItemPostReqDto.java (89%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/TempItemPostResDto.java (92%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/dto/TempItemResDto.java (77%) create mode 100644 sluv-api/src/main/java/com/sluv/api/item/helper/HashtagHelper.java create mode 100644 sluv-api/src/main/java/com/sluv/api/item/helper/ItemHelper.java create mode 100644 sluv-api/src/main/java/com/sluv/api/item/service/HashtagService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/service/ItemCacheService.java (61%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/service/ItemCategoryService.java (61%) create mode 100644 sluv-api/src/main/java/com/sluv/api/item/service/ItemEditReqService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/item/service/ItemReportService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/item/service/ItemService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/item/service/ItemWithdrawService.java (63%) create mode 100644 sluv-api/src/main/java/com/sluv/api/item/service/PlaceRankService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/item/service/TempItemService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/notice/controller/NoticeController.java (53%) rename src/main/java/com/sluv/server/domain/notice/dto/NoticeDetailResDto.java => sluv-api/src/main/java/com/sluv/api/notice/dto/NoticeDetailResponse.java (73%) rename src/main/java/com/sluv/server/domain/notice/dto/NoticeSimpleResDto.java => sluv-api/src/main/java/com/sluv/api/notice/dto/NoticeSimpleResponse.java (73%) create mode 100644 sluv-api/src/main/java/com/sluv/api/notice/service/NoticeService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/controller/QuestionController.java (53%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionBuyPostReqDto.java (94%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionBuySimpleResDto.java (84%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionFindPostReqDto.java (94%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionGetDetailResDto.java (88%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionHomeResDto.java (69%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionHowaboutPostReqDto.java (94%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionImgReqDto.java (93%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionImgResDto.java (93%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionItemReqDto.java (93%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionItemResDto.java (83%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionPostResDto.java (91%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionRecommendPostReqDto.java (91%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionReportReqDto.java (70%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionVoteDataDto.java (92%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/dto/QuestionVoteReqDto.java (76%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/mapper/QuestionDtoMapper.java (62%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/question/service/QuestionService.java (53%) create mode 100644 sluv-api/src/main/java/com/sluv/api/question/service/QuestionWithdrawService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/search/controller/SearchController.java (56%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/search/dto/RecentSearchChipResDto.java (92%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/search/dto/SearchItemCountResDto.java (92%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/search/dto/SearchKeywordResDto.java (91%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/search/dto/SearchKeywordTotalResDto.java (72%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/search/dto/SearchTotalResDto.java (72%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/search/engine/DBSearchEngine.java (84%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/search/engine/ELKSearchEngine.java (100%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/search/engine/SearchEngine.java (85%) create mode 100644 sluv-api/src/main/java/com/sluv/api/search/service/SearchEngineService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/search/service/SearchEngineTotalService.java (64%) create mode 100644 sluv-api/src/main/java/com/sluv/api/search/service/SearchService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/search/utils/ElasticSearchConnectUtil.java create mode 100644 sluv-api/src/main/java/com/sluv/api/user/controller/FollowController.java create mode 100644 sluv-api/src/main/java/com/sluv/api/user/controller/UserCelebController.java create mode 100644 sluv-api/src/main/java/com/sluv/api/user/controller/UserController.java create mode 100644 sluv-api/src/main/java/com/sluv/api/user/controller/UserLikeController.java create mode 100644 sluv-api/src/main/java/com/sluv/api/user/controller/UserRecentController.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/user/controller/UserReportController.java (59%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/user/dto/UserIdDto.java (91%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/user/dto/UserMypageResDto.java (93%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/user/dto/UserProfileImgReqDto.java (77%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/user/dto/UserProfileReqDto.java (91%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/user/dto/UserReportReqDto.java (80%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/user/dto/UserSocialDto.java (82%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/user/dto/UserTermsResDto.java (86%) rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/user/dto/UserWithdrawReqDto.java (79%) create mode 100644 sluv-api/src/main/java/com/sluv/api/user/service/FollowService.java rename {src/main/java/com/sluv/server/domain => sluv-api/src/main/java/com/sluv/api}/user/service/UserCelebService.java (55%) create mode 100644 sluv-api/src/main/java/com/sluv/api/user/service/UserLikeService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/user/service/UserRecentService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/user/service/UserReportService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/user/service/UserService.java create mode 100644 sluv-api/src/main/java/com/sluv/api/user/service/UserWithdrawDataService.java create mode 100644 sluv-api/src/main/resources/application.yml create mode 100644 sluv-api/src/main/resources/banner.txt create mode 100644 sluv-api/src/test/java/com/sluv/api/ApiApplicationTests.java rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/domain/brand/repository/BrandRepositoryTest.java (100%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/domain/brand/service/BrandServiceTest.java (100%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/domain/brand/service/NewBrandServiceTest.java (100%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/domain/brand/service/RecentSelectBrandServiceTest.java (100%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/domain/closet/service/ClosetServiceTest.java (100%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/domain/item/service/HashtagServiceTest.java (100%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/domain/item/service/ItemCategoryServiceTest.java (100%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/domain/item/service/ItemServiceTest.java (100%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/domain/notice/service/NoticeServiceTest.java (100%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/domain/user/service/FollowServiceTest.java (100%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/domain/user/service/UserReportServiceTest.java (100%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/fixture/BrandFixture.java (73%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/fixture/CelebFixture.java (72%) create mode 100644 sluv-api/src/test/java/com/sluv/api/fixture/ClosetFixture.java rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/fixture/ItemFixture.java (72%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/fixture/NoticeFixture.java (57%) rename {src/test/java/com/sluv/server => sluv-api/src/test/java/com/sluv/api}/fixture/UserFixture.java (81%) create mode 100644 sluv-batch/Dockerfile create mode 100644 sluv-batch/build.gradle rename src/main/java/com/sluv/server/SluvServerApplication.java => sluv-batch/src/main/java/com/sluv/batch/BatchApplication.java (77%) create mode 100644 sluv-batch/src/main/java/com/sluv/batch/config/ComponentConfig.java rename {src/main/java/com/sluv/server/domain/item/scheduler => sluv-batch/src/main/java/com/sluv/batch/item}/ItemScheduler.java (54%) rename {src/main/java/com/sluv/server/domain/question/scheduler => sluv-batch/src/main/java/com/sluv/batch/question}/QuestionScheduler.java (71%) create mode 100644 sluv-batch/src/main/java/com/sluv/batch/search/SearchScheduler.java rename {src/main/java/com/sluv/server/domain/user/scheduler => sluv-batch/src/main/java/com/sluv/batch/user}/UserScheduler.java (85%) rename {src/main/java/com/sluv/server/domain/visit/scheduler => sluv-batch/src/main/java/com/sluv/batch/visit}/VisitScheduler.java (64%) create mode 100644 sluv-batch/src/main/resources/application.yml create mode 100644 sluv-batch/src/main/resources/banner.txt create mode 100644 sluv-batch/src/test/java/com/sluv/batch/BatchApplicationTests.java create mode 100644 sluv-common/build.gradle create mode 100644 sluv-common/src/main/java/com/sluv/common/annotation/CurrentUserId.java rename {src/main/java/com/sluv/server/global/config/security => sluv-common/src/main/java/com/sluv/common/config}/JasyptConfig.java (86%) create mode 100644 sluv-common/src/main/java/com/sluv/common/constant/ConstantData.java create mode 100644 sluv-common/src/main/java/com/sluv/common/exception/ApplicationException.java rename {src/main/java/com/sluv/server/global => sluv-common/src/main/java/com/sluv}/common/exception/ErrorCode.java (90%) create mode 100644 sluv-common/src/main/java/com/sluv/common/exception/HttpStatusCode.java rename {src/main/java/com/sluv/server/global => sluv-common/src/main/java/com/sluv/common}/jwt/JwtProvider.java (60%) rename {src/main/java/com/sluv/server/global => sluv-common/src/main/java/com/sluv/common}/jwt/exception/ExpiredTokenException.java (62%) create mode 100644 sluv-common/src/main/java/com/sluv/common/jwt/exception/HttpStatusCode.java rename {src/main/java/com/sluv/server/global => sluv-common/src/main/java/com/sluv/common}/jwt/exception/InvalidateTokenException.java (62%) rename {src/main/java/com/sluv/server/global => sluv-common/src/main/java/com/sluv/common}/jwt/exception/NoAuthorizationTokenException.java (63%) create mode 100644 sluv-common/src/main/java/com/sluv/common/jwt/exception/TokenException.java create mode 100644 sluv-common/src/main/resources/application-common.yml create mode 100644 sluv-common/src/test/java/com/sluv/common/TestConfiguration.java create mode 100644 sluv-domain/build.gradle rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/admin/entity/Admin.java (89%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/admin/exception/AdminException.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/admin/exception/AdminNotFoundException.java (62%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/admin/exception/AdminPasswordNotMatchException.java (65%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/admin/repository/AdminRepository.java (67%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/admin/service/AdminDomainService.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/alarm/dto/AlarmElement.java (70%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/alarm/dto/AlarmImages.java (53%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/alarm/entity/Alarm.java (78%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/alarm/enums/AlarmMessage.java (96%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/alarm/enums/AlarmStatus.java (58%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/alarm/enums/AlarmType.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/alarm/exception/AlarmAccessDeniedException.java (64%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/alarm/exception/AlarmException.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/alarm/exception/AlarmNotFoundException.java (62%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/alarm/repository/AlarmRepository.java (53%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/alarm/repository/impl/AlarmRepositoryCustom.java (66%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/alarm/repository/impl/AlarmRepositoryImpl.java (79%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/alarm/service/AlarmDomainService.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/auth/dto/SocialUserInfoDto.java (54%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/auth/enums/SnsType.java (78%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/auth/exception/AuthException.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/auth/exception/NoSupportSocialTypeException.java (64%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/auth/exception/UserBlockedException.java (61%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/brand/entity/Brand.java (61%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/brand/entity/NewBrand.java (55%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/brand/entity/RecentSelectBrand.java (62%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/brand/enums/NewBrandStatus.java (61%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/brand/exception/BrandException.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/brand/exception/BrandNotFoundException.java (63%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/brand/exception/NewBrandNotFoundException.java (64%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/brand/repository/BrandRepository.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/brand/repository/NewBrandRepository.java (69%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/brand/repository/RecentSelectBrandRepository.java (53%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/brand/repository/impl/BrandRepositoryCustom.java (76%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/brand/repository/impl/BrandRepositoryImpl.java (88%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/RecentSelectBrandRepositoryCustom.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/brand/repository/impl/RecentSelectBrandRepositoryImpl.java (70%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/brand/service/BrandDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/brand/service/NewBrandDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/brand/service/RecentSelectBrandDomainService.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/dto/CelebDto.java (95%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/entity/Celeb.java (93%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/entity/CelebActivity.java (89%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/entity/CelebCategory.java (91%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/entity/InterestedCeleb.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/entity/NewCeleb.java (76%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/entity/RecentSelectCeleb.java (73%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/enums/CelebStatus.java (54%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/enums/NewCelebStatus.java (61%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/celeb/exception/CelebException.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/exception/CelebNotFoundException.java (62%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/exception/NewCelebNotFoundException.java (63%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/celeb/repository/CelebActivityRepository.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/repository/CelebCategoryRepository.java (67%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/celeb/repository/CelebRepository.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/repository/Impl/CelebActivityRepositoryCustom.java (53%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/repository/Impl/CelebActivityRepositoryImpl.java (75%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/repository/Impl/CelebRepositoryCustom.java (74%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/repository/Impl/CelebRepositoryImpl.java (92%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/RecentSelectCelebRepositoryCustom.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/repository/Impl/RecentSelectCelebRepositoryImpl.java (68%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/repository/InterestedCelebRepository.java (71%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/repository/NewCelebRepository.java (65%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/celeb/repository/RecentSelectCelebRepository.java (53%) rename src/main/java/com/sluv/server/domain/celeb/service/CelebActivityService.java => sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebActivityDomainService.java (51%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebCategoryDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/celeb/service/InterestedCelebDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/celeb/service/NewCelebDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/celeb/service/RecentSelectCelebDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/closet/dto/ClosetCountDto.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/closet/dto/ClosetDomainDto.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/closet/entity/Closet.java (67%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/closet/enums/ClosetColor.java (67%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/closet/enums/ClosetStatus.java (54%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/closet/exception/BasicClosetDeleteException.java (64%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/closet/exception/ClosetException.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/closet/exception/ClosetNotFoundException.java (63%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/closet/repository/ClosetRepository.java (59%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/closet/repository/impl/ClosetRepositoryCustom.java (61%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/closet/repository/impl/ClosetRepositoryImpl.java (84%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/closet/service/ClosetDomainService.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/dto/CommentImgDto.java (86%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/entity/Comment.java (89%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/entity/CommentImg.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/entity/CommentItem.java (80%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/entity/CommentLike.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/entity/CommentReport.java (78%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/enums/CommentReportReason.java (74%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/enums/CommentStatus.java (54%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/comment/exception/CommentException.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/exception/CommentNotFoundException.java (63%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/exception/CommentReportDuplicateException.java (64%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/repository/CommentImgRepository.java (71%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/repository/CommentItemRepository.java (71%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/repository/CommentLikeRepository.java (74%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/repository/CommentReportRepository.java (66%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/repository/CommentRepository.java (58%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/repository/impl/CommentRepositoryCustom.java (70%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/comment/repository/impl/CommentRepositoryImpl.java (92%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentImgDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentLikeDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentReportDomainService.java rename {src/main/java/com/sluv/server/global => sluv-domain/src/main/java/com/sluv/domain}/common/entity/BaseEntity.java (79%) rename {src/main/java/com/sluv/server/global => sluv-domain/src/main/java/com/sluv/domain}/common/enums/ItemImgOrLinkStatus.java (57%) rename {src/main/java/com/sluv/server/global => sluv-domain/src/main/java/com/sluv/domain}/common/enums/ReportStatus.java (55%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/config/JpaConfig.java rename {src/main/java/com/sluv/server/global => sluv-domain/src/main/java/com/sluv/domain}/config/QueryDslConfig.java (92%) rename src/main/java/com/sluv/server/domain/item/dto/ItemImgResDto.java => sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemImgDto.java (68%) rename src/main/java/com/sluv/server/domain/item/dto/ItemLinkResDto.java => sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemLinkDto.java (61%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemSaveDto.java rename src/main/java/com/sluv/server/domain/item/dto/ItemSimpleResDto.java => sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemSimpleDto.java (84%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/dto/TempItemSaveDto.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/dto/hashtag/HashtagCountDto.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/DayHotItem.java (61%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/EfficientItem.java (91%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/Item.java (87%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/ItemCategory.java (90%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/ItemEditReq.java (79%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/ItemImg.java (85%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/ItemLike.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/ItemLink.java (82%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/ItemReport.java (78%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/ItemScrap.java (89%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/LuxuryItem.java (91%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/PlaceRank.java (77%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/RecentItem.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/TempItem.java (85%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/TempItemImg.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/TempItemLink.java (87%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/WeekHotItem.java (62%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/hashtag/Hashtag.java (92%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/hashtag/HashtagStatus.java (51%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/hashtag/ItemHashtag.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/entity/hashtag/TempItemHashtag.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/enums/ItemEditReqReason.java (80%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/enums/ItemNumberConfig.java (83%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/enums/ItemReportReason.java (75%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/enums/ItemStatus.java (60%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/exception/ItemCategoryNotFoundException.java (65%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemException.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/exception/ItemNotActiveException.java (63%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/exception/ItemNotFoundException.java (62%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/exception/ItemReportDuplicateException.java (64%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/exception/StandardNotFoundException.java (63%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/exception/TempItemNotFoundException.java (63%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/exception/hashtag/HashtagException.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/exception/hashtag/HashtagNotFoundException.java (62%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/DayHotItemRepository.java (58%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/EfficientItemRepository.java (59%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/ItemCategoryRepository.java (72%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/ItemEditReqRepository.java (58%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/ItemImgRepository.java (61%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/ItemLikeRepository.java (74%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/ItemLinkRepository.java (66%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemReportRepository.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/ItemRepository.java (61%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/ItemScrapRepository.java (70%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/LuxuryItemRepository.java (58%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/PlaceRankRepository.java (51%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/RecentItemRepository.java (54%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/TempItemImgRepository.java (50%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/TempItemLinkRepository.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/TempItemRepository.java (57%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/WeekHotItemRepository.java (58%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/hashtag/HashtagRepository.java (55%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/hashtag/ItemHashtagRepository.java (68%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/TempItemHashtagRepository.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/HashtagRepositoryCustom.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/hashtag/impl/HashtagRepositoryImpl.java (75%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/TempItemHashtagRepositoryCustom.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/TempItemHashtagRepositoryImpl.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemImgRepositoryCustom.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/impl/ItemImgRepositoryImpl.java (75%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemReportRepositoryCustom.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/impl/ItemReportRepositoryImpl.java (71%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/impl/ItemRepositoryCustom.java (73%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/impl/ItemRepositoryImpl.java (86%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemScrapRepositoryCustom.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/impl/ItemScrapRepositoryImpl.java (71%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/PlaceRankRepositoryCustom.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/impl/PlaceRankRepositoryImpl.java (59%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/impl/RecentItemRepositoryCustom.java (58%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/impl/RecentItemRepositoryImpl.java (84%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemImgRepositoryCustom.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemImgRepositoryImpl.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemLinkRepositoryCustom.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemLinkRepositoryImpl.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/item/repository/impl/TempItemRepositoryCustom.java (56%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemRepositoryImpl.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/DayHotItemDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/EfficientItemDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/ItemCategoryDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/ItemDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/ItemEditReqDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/ItemHashtagDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/ItemImgDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/ItemLikeDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/ItemLinkDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/ItemReportDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/ItemScrapDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/LuxuryItemDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/PlaceRankDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/RecentItemDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemImgDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemLinkDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/WeekHotItemDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/hashtag/HashtagDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/item/service/hashtag/TempItemHashtagDomainService.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/notice/entity/Notice.java (85%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/notice/enums/NoticeStatus.java (59%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/notice/enums/NoticeType.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/notice/exception/NoticeException.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/notice/exception/NoticeNotFoundException.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/notice/repository/NoticeRepository.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/notice/repository/impl/NoticeRepositoryCustom.java (63%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/notice/repository/impl/NoticeRepositoryImpl.java (85%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/notice/service/NoticeDomainService.java rename src/main/java/com/sluv/server/domain/question/dto/QuestionImgSimpleResDto.java => sluv-domain/src/main/java/com/sluv/domain/question/dto/QuestionImgSimpleDto.java (60%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/dto/QuestionSimpleResDto.java (83%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/DailyHotQuestion.java (63%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/Question.java (91%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/QuestionBuy.java (62%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/QuestionFind.java (66%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/QuestionHowabout.java (57%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/QuestionImg.java (75%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/QuestionItem.java (77%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/QuestionLike.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/QuestionRecommend.java (60%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/QuestionRecommendCategory.java (92%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/QuestionReport.java (78%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/QuestionVote.java (79%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/entity/RecentQuestion.java (89%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/enums/QuestionReportReason.java (73%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/enums/QuestionStatus.java (59%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionException.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/exception/QuestionNotFoundException.java (56%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/exception/QuestionReportDuplicateException.java (58%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/exception/QuestionTypeNotFoundException.java (64%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/DailyHotQuestionRepository.java (57%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/QuestionImgRepository.java (78%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/QuestionItemRepository.java (78%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/QuestionLikeRepository.java (74%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/QuestionRecommendCategoryRepository.java (74%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/QuestionReportRepository.java (67%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/QuestionRepository.java (50%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/QuestionVoteRepository.java (82%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/RecentQuestionRepository.java (53%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/impl/QuestionRepositoryCustom.java (79%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/impl/QuestionRepositoryImpl.java (85%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/impl/RecentQuestionRepositoryCustom.java (58%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/question/repository/impl/RecentQuestionRepositoryImpl.java (83%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionImgDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionItemDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionLikeDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionRecommendCategoryDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionReportDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionVoteDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/question/service/RecentQuestionDomainService.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/search/dto/SearchFilterReqDto.java (93%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/search/entity/RecentSearch.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/search/entity/SearchData.java (89%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/search/entity/SearchRank.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/search/enums/SearchRankStatus.java (56%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/search/repository/RecentSearchRepository.java (59%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/search/repository/SearchDataRepository.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/search/repository/SearchRankRepository.java (67%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/RecentSearchRepositoryCustom.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/search/repository/impl/RecentSearchRepositoryImpl.java (73%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/search/repository/impl/SearchDataRepositoryCustom.java (73%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/search/repository/impl/SearchDataRepositoryImpl.java (89%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/search/service/RecentSearchDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/search/service/SearchDataDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/search/service/SearchRankDomainService.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/dto/UserInfoDto.java (91%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/dto/UserSearchInfoDto.java (92%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/entity/Follow.java (92%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/entity/User.java (75%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/entity/UserReport.java (80%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/entity/UserReportStack.java (90%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/entity/UserWithdraw.java (79%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/enums/UserAge.java (89%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/enums/UserGender.java (55%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/enums/UserReportReason.java (76%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/enums/UserStatus.java (71%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/enums/UserWithdrawReason.java (69%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/user/exception/UserException.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/exception/UserNicknameDuplicatedException.java (64%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/exception/UserNoFCMException.java (61%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/exception/UserNotFoundException.java (56%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/exception/UserNotMatchedException.java (57%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/exception/UserReportDuplicateException.java (63%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/user/repository/FollowRepository.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/user/repository/UserReportRepository.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/repository/UserReportStackRepository.java (65%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/repository/UserRepository.java (59%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/repository/UserWithdrawRepository.java (59%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/repository/impl/FollowRepositoryCustom.java (71%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/repository/impl/FollowRepositoryImpl.java (88%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/repository/impl/UserReportRepositoryCustom.java (58%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/repository/impl/UserReportRepositoryImpl.java (85%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/repository/impl/UserRepositoryCustom.java (84%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/user/repository/impl/UserRepositoryImpl.java (90%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/user/service/FollowDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/user/service/UserDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/user/service/UserReportDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/user/service/UserReportStackDomainService.java create mode 100644 sluv-domain/src/main/java/com/sluv/domain/user/service/UserWithdrawDomainService.java rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/visit/entity/VisitHistory.java (89%) rename {src/main/java/com/sluv/server => sluv-domain/src/main/java/com/sluv}/domain/visit/repository/VisitHistoryRepository.java (58%) create mode 100644 sluv-domain/src/main/java/com/sluv/domain/visit/service/VisitHistoryDomainService.java create mode 100644 sluv-domain/src/main/resources/application-domain.yml create mode 100644 sluv-infra/build.gradle rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/ai/AiModelRepository.java (81%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/ai/AiModelService.java (63%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/ai/dto/CommentCleanBotReqDto.java (91%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/ai/dto/ItemColorCheckReqDto.java (91%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/cache/CacheService.java (60%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/cache/RedisService.java (80%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/config/FcmConfig.java (97%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/config/RedisConfig.java (97%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/discord/DiscordWebHookConnector.java (96%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/discord/DiscordWebHookException.java (63%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/discord/DiscordWebHookService.java (94%) create mode 100644 sluv-infra/src/main/java/com/sluv/infra/discord/WebHookException.java rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/discord/WebHookMessage.java (55%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/discord/WebHookService.java (54%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/firebase/FcmNotificationService.java (88%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/firebase/exception/FcmAccessTokenInvalidateException.java (63%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/firebase/exception/FcmConnectException.java (61%) create mode 100644 sluv-infra/src/main/java/com/sluv/infra/firebase/exception/FcmException.java create mode 100644 sluv-infra/src/main/java/com/sluv/infra/oauth/apple/ApplePlatformClient.java rename src/main/java/com/sluv/server/domain/auth/service/GoogleUserService.java => sluv-infra/src/main/java/com/sluv/infra/oauth/google/GooglePlatformClient.java (62%) rename src/main/java/com/sluv/server/domain/auth/service/KakaoUserService.java => sluv-infra/src/main/java/com/sluv/infra/oauth/kakao/KakaoPlatformClient.java (77%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/s3/AWSS3Service.java (82%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/s3/ImgExtension.java (87%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/s3/PreSingedUrlResDto.java (88%) rename {src/main/java/com/sluv/server/global => sluv-infra/src/main/java/com/sluv/infra}/s3/S3Config.java (85%) create mode 100644 sluv-infra/src/main/resources/application-infra.yml delete mode 100644 src/main/java/com/sluv/server/domain/admin/controller/AdminController.java delete mode 100644 src/main/java/com/sluv/server/domain/admin/exception/AdminException.java delete mode 100644 src/main/java/com/sluv/server/domain/admin/service/AdminService.java delete mode 100644 src/main/java/com/sluv/server/domain/alarm/controller/AlarmController.java delete mode 100644 src/main/java/com/sluv/server/domain/alarm/exception/AlarmException.java delete mode 100644 src/main/java/com/sluv/server/domain/alarm/service/AlarmService.java delete mode 100644 src/main/java/com/sluv/server/domain/auth/controller/AuthController.java delete mode 100644 src/main/java/com/sluv/server/domain/auth/dto/AuthResponseDto.java delete mode 100644 src/main/java/com/sluv/server/domain/auth/dto/AutoLoginRequestDto.java delete mode 100644 src/main/java/com/sluv/server/domain/auth/exception/AuthException.java delete mode 100644 src/main/java/com/sluv/server/domain/auth/service/AppleUserService.java delete mode 100644 src/main/java/com/sluv/server/domain/auth/service/AuthService.java delete mode 100644 src/main/java/com/sluv/server/domain/brand/controller/NewBrandController.java delete mode 100644 src/main/java/com/sluv/server/domain/brand/exception/BrandException.java delete mode 100644 src/main/java/com/sluv/server/domain/brand/repository/BrandRepository.java delete mode 100644 src/main/java/com/sluv/server/domain/brand/repository/impl/RecentSelectBrandRepositoryCustom.java delete mode 100644 src/main/java/com/sluv/server/domain/brand/service/BrandService.java delete mode 100644 src/main/java/com/sluv/server/domain/brand/service/NewBrandService.java delete mode 100644 src/main/java/com/sluv/server/domain/brand/service/RecentSelectBrandService.java delete mode 100644 src/main/java/com/sluv/server/domain/celeb/exception/CelebException.java delete mode 100644 src/main/java/com/sluv/server/domain/celeb/handler/CelebHandler.java delete mode 100644 src/main/java/com/sluv/server/domain/celeb/repository/CelebActivityRepository.java delete mode 100644 src/main/java/com/sluv/server/domain/celeb/repository/CelebRepository.java delete mode 100644 src/main/java/com/sluv/server/domain/celeb/repository/Impl/RecentSelectCelebRepositoryCustom.java delete mode 100644 src/main/java/com/sluv/server/domain/celeb/service/CelebService.java delete mode 100644 src/main/java/com/sluv/server/domain/celeb/service/NewCelebService.java delete mode 100644 src/main/java/com/sluv/server/domain/celeb/service/RecentSelectCelebService.java delete mode 100644 src/main/java/com/sluv/server/domain/closet/dto/ClosetListCountResDto.java delete mode 100644 src/main/java/com/sluv/server/domain/closet/dto/ClosetNameCheckResDto.java delete mode 100644 src/main/java/com/sluv/server/domain/closet/exception/ClosetException.java delete mode 100644 src/main/java/com/sluv/server/domain/closet/service/ClosetItemService.java delete mode 100644 src/main/java/com/sluv/server/domain/closet/service/ClosetService.java delete mode 100644 src/main/java/com/sluv/server/domain/comment/dto/CommentItemResDto.java delete mode 100644 src/main/java/com/sluv/server/domain/comment/dto/SubCommentPageResDto.java delete mode 100644 src/main/java/com/sluv/server/domain/comment/exception/CommentException.java delete mode 100644 src/main/java/com/sluv/server/domain/comment/service/CommentReportService.java delete mode 100644 src/main/java/com/sluv/server/domain/comment/service/CommentService.java delete mode 100644 src/main/java/com/sluv/server/domain/item/controller/ItemController.java delete mode 100644 src/main/java/com/sluv/server/domain/item/controller/TempItemController.java delete mode 100644 src/main/java/com/sluv/server/domain/item/exception/ItemException.java delete mode 100644 src/main/java/com/sluv/server/domain/item/exception/hashtag/HashtagException.java delete mode 100644 src/main/java/com/sluv/server/domain/item/helper/ItemHelper.java delete mode 100644 src/main/java/com/sluv/server/domain/item/repository/ItemReportRepository.java delete mode 100644 src/main/java/com/sluv/server/domain/item/repository/TempItemLinkRepository.java delete mode 100644 src/main/java/com/sluv/server/domain/item/repository/hashtag/TempItemHashtagRepository.java delete mode 100644 src/main/java/com/sluv/server/domain/item/repository/hashtag/impl/HashtagRepositoryCustom.java delete mode 100644 src/main/java/com/sluv/server/domain/item/repository/impl/ItemImgRepositoryCustom.java delete mode 100644 src/main/java/com/sluv/server/domain/item/repository/impl/ItemReportRepositoryCustom.java delete mode 100644 src/main/java/com/sluv/server/domain/item/repository/impl/ItemScrapRepositoryCustom.java delete mode 100644 src/main/java/com/sluv/server/domain/item/repository/impl/PlaceRankRepositoryCustom.java delete mode 100644 src/main/java/com/sluv/server/domain/item/repository/impl/TempItemRepositoryImpl.java delete mode 100644 src/main/java/com/sluv/server/domain/item/service/HashtagService.java delete mode 100644 src/main/java/com/sluv/server/domain/item/service/ItemEditReqService.java delete mode 100644 src/main/java/com/sluv/server/domain/item/service/ItemReportService.java delete mode 100644 src/main/java/com/sluv/server/domain/item/service/ItemService.java delete mode 100644 src/main/java/com/sluv/server/domain/item/service/PlaceRankService.java delete mode 100644 src/main/java/com/sluv/server/domain/item/service/TempItemService.java delete mode 100644 src/main/java/com/sluv/server/domain/notice/enums/NoticeType.java delete mode 100644 src/main/java/com/sluv/server/domain/notice/exception/NoticeException.java delete mode 100644 src/main/java/com/sluv/server/domain/notice/exception/NoticeNotFoundException.java delete mode 100644 src/main/java/com/sluv/server/domain/notice/repository/NoticeRepository.java delete mode 100644 src/main/java/com/sluv/server/domain/notice/service/NoticeService.java delete mode 100644 src/main/java/com/sluv/server/domain/question/exception/QuestionException.java delete mode 100644 src/main/java/com/sluv/server/domain/question/service/QuestionWithdrawService.java delete mode 100644 src/main/java/com/sluv/server/domain/search/repository/SearchDataRepository.java delete mode 100644 src/main/java/com/sluv/server/domain/search/repository/impl/RecentSearchRepositoryCustom.java delete mode 100644 src/main/java/com/sluv/server/domain/search/scheduler/SearchScheduler.java delete mode 100644 src/main/java/com/sluv/server/domain/search/service/SearchEngineService.java delete mode 100644 src/main/java/com/sluv/server/domain/search/service/SearchService.java delete mode 100644 src/main/java/com/sluv/server/domain/search/utils/ElasticSearchConnectUtil.java delete mode 100644 src/main/java/com/sluv/server/domain/user/controller/FollowController.java delete mode 100644 src/main/java/com/sluv/server/domain/user/controller/UserCelebController.java delete mode 100644 src/main/java/com/sluv/server/domain/user/controller/UserController.java delete mode 100644 src/main/java/com/sluv/server/domain/user/controller/UserLikeController.java delete mode 100644 src/main/java/com/sluv/server/domain/user/controller/UserRecentController.java delete mode 100644 src/main/java/com/sluv/server/domain/user/enums/SnsType.java delete mode 100644 src/main/java/com/sluv/server/domain/user/exception/UserException.java delete mode 100644 src/main/java/com/sluv/server/domain/user/repository/FollowRepository.java delete mode 100644 src/main/java/com/sluv/server/domain/user/repository/UserReportRepository.java delete mode 100644 src/main/java/com/sluv/server/domain/user/service/FollowService.java delete mode 100644 src/main/java/com/sluv/server/domain/user/service/UserLikeService.java delete mode 100644 src/main/java/com/sluv/server/domain/user/service/UserRecentService.java delete mode 100644 src/main/java/com/sluv/server/domain/user/service/UserReportService.java delete mode 100644 src/main/java/com/sluv/server/domain/user/service/UserService.java delete mode 100644 src/main/java/com/sluv/server/domain/user/service/UserWithdrawDataService.java delete mode 100644 src/main/java/com/sluv/server/global/common/exception/ApplicationException.java delete mode 100644 src/main/java/com/sluv/server/global/discord/WebHookException.java delete mode 100644 src/main/java/com/sluv/server/global/firebase/exception/FcmException.java delete mode 100644 src/main/java/com/sluv/server/global/jwt/exception/TokenException.java delete mode 100644 src/main/java/com/sluv/server/global/jwt/filter/JwtAuthenticationFilter.java delete mode 100644 src/main/java/com/sluv/server/global/s3/AWSS3Controller.java delete mode 160000 src/main/resources delete mode 100644 src/test/java/com/sluv/server/fixture/ClosetFixture.java diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..23ee62e4fce39ef6e71a164ee7458efbf22af391 GIT binary patch literal 6148 zcmeHK-AcnS6i&A4GKR1V1-%P+JG65{Cf<}eU%-l9sLYj(S**=iJ9{w(z1J7=MSLF5 zNm6k*Z$;cWkbLJiX+CIv7-PIU8#WoMGsXloM2^Y|LHEi~$tELm93#k*Nf4<3>^B?x z>ww?xumd(`Axpo0e=v!{Bz4_)UMf2qn-x(JHF4)ZsLW3X=`86ErZ;F^DisBVJ_xSD zQP!_-pQ$(kG`=D0{YkTOOXZ652g96wJ#}0ResK5&#D7BfC0i;u3Yp^DO2D UaTN6HazMHWXhNtX27ZBo4}fe+7XSbN literal 0 HcmV?d00001 diff --git a/.github/workflows/mulit-ci-cd.yml b/.github/workflows/mulit-ci-cd.yml new file mode 100644 index 00000000..75ddbe26 --- /dev/null +++ b/.github/workflows/mulit-ci-cd.yml @@ -0,0 +1,86 @@ +name: dev CI/CD + +on: + push: + branches: [ to_multi-module ] + paths: + - 'api-module/**' + +jobs: + dev-ci-cd: + runs-on: ubuntu-latest + steps: + - name: Checkout Latest Repo + uses: actions/checkout@v3 + with: + token: ${{ secrets.TOKEN_OF_GITHUB }} + submodules: true + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew :sluv-api:clean :sluv-api:build + + - name: Docker build + run: | + docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} + docker build -t sluv-api-module ./sluv-api + docker tag sluv-api-module sluv2323/sluv-api-module:latest + docker push sluv2323/sluv-api-module:latest + + - name: Get timestamp + uses: gerred/actions/current-time@master + id: current-time + + - name: Run string replace + uses: frabert/replace-string-action@master + id: format-time + with: + pattern: '[:\.]+' + string: "${{ steps.current-time.outputs.time }}" + replace-with: '-' + flags: 'g' + + + - name: Deploy to Local Server + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.LOCAL_SERVER_HOST }} + username: ${{ secrets.LOCAL_SERVER_USER }} + password: ${{ secrets.LOCAL_SERVER_SSH_PASSWORD }} + script: | + chmod +x /home/sluv/api_module_deploy_script.sh + echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S /home/sluv/api_module_deploy_script.sh + + current-time: + needs: dev-ci-cd + runs-on: ubuntu-latest + steps: + - name: Get Current Time + uses: 1466587594/get-current-time@v2 + id: current-time + with: + format: YYYY-MM-DDTHH:mm:ss + utcOffset: "+09:00" # 기준이 UTC이기 때문에 한국시간인 KST를 맞추기 위해 +9시간 추가 + + - name: Print Current Time + run: echo "Current Time=${{steps.current-time.outputs.formattedTime}}" # current-time 에서 지정한 포맷대로 현재 시간 출력 + shell: bash + + ## discord + action-discord: + needs: dev-ci-cd + runs-on: ubuntu-latest + steps: + - name: Discord Alarm + uses: tsickert/discord-webhook@v5.3.0 + with: + webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} + content: "Dev Deploy ${{ job.status }}" \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index f1d2542a..cd0a4a05 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,3 @@ -[submodule "src/main/resources"] - path = src/main/resources +[submodule "env"] + path = env url = https://github.com/CELEBIT/sluv-springboot-server-env.git - branch = main \ No newline at end of file diff --git a/build.gradle b/build.gradle index b3686f4a..babc2b5f 100644 --- a/build.gradle +++ b/build.gradle @@ -2,90 +2,57 @@ plugins { id 'java' id 'org.springframework.boot' version '3.0.2' id 'io.spring.dependency-management' version '1.1.0' -// id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } -group = 'com.sluv' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '17' - -configurations { - compileOnly { - extendsFrom annotationProcessor - } -} +bootJar.enabled = false repositories { mavenCentral() } -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-validation:3.0.4' - - - compileOnly 'org.projectlombok:lombok' - runtimeOnly 'com.mysql:mysql-connector-j' - annotationProcessor 'org.projectlombok:lombok' - - testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.security:spring-security-test' - testImplementation 'com.h2database:h2' - - //swagger - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.3' - - // Jasypt - implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5' - - // JWT - implementation 'io.jsonwebtoken:jjwt-api:0.11.5' - implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' - implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' - implementation 'com.nimbusds:nimbus-jose-jwt:9.30.2' - - // Oauth - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - implementation 'com.google.api-client:google-api-client:2.2.0' - implementation 'com.google.auth:google-auth-library-oauth2-http:1.16.0' +subprojects { + group = 'com.sluv' + version = '0.0.1-SNAPSHOT' + sourceCompatibility = '17' - // QueryDsl - implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' - annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" +// java { +// toolchain { +// languageVersion = JavaLanguageVersion.of(17) +// } +// } - annotationProcessor "jakarta.annotation:jakarta.annotation-api" - annotationProcessor "jakarta.persistence:jakarta.persistence-api" - // java.lang.NoClassDefFoundError (javax.annotation.Entity) 대응 코드 + apply plugin: 'java' + apply plugin: 'java-library' + apply plugin: 'org.springframework.boot' + apply plugin: 'io.spring.dependency-management' - // AWS S3 - implementation 'com.amazonaws:aws-java-sdk-s3:1.12.232' + repositories { + mavenCentral() + } - // Redis - implementation 'org.springframework.boot:spring-boot-starter-data-redis' + dependencies { + implementation 'org.springframework.boot:spring-boot-starter' + implementation 'org.springframework.boot:spring-boot-starter-validation:3.0.4' - // FCM - implementation 'com.google.firebase:firebase-admin:9.1.1' + compileOnly 'org.projectlombok:lombok' +// runtimeOnly 'com.h2database:h2' + annotationProcessor 'org.projectlombok:lombok' -} + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'com.h2database:h2' -tasks.named('test') { - useJUnitPlatform() -} -// QueryDsl -def querydslDir = "$buildDir/generated/querydsl" - -sourceSets { - main.java.srcDirs += [querydslDir] -} + } -tasks.withType(JavaCompile) { - options.annotationProcessorGeneratedSourcesDirectory = file(querydslDir) -} + tasks.withType(ProcessResources) { + from(rootProject.file('env')) { + include '.env', 'firebase/*' + into 'env' + } + } -clean.doLast { - file(querydslDir).deleteDir() + test { + useJUnitPlatform() + } } \ No newline at end of file diff --git a/env b/env new file mode 160000 index 00000000..cbfc8fe8 --- /dev/null +++ b/env @@ -0,0 +1 @@ +Subproject commit cbfc8fe83fee62047f64fdeec8adbaf368c28d0e diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..ccebba7710deaf9f98673a68957ea02138b60d0a 100644 GIT binary patch delta 39304 zcmY(qV{|1@vn?9iwrv|7+qP{xJ5I+=$F`jv+ji1XM;+U~ea?CBp8Ne-wZ>TWb5_k- zRW+A?gIDZj+Jtg0hJQDi3-TohW5u_A^b9Act5-!5t~)TlFb=zVn=`t z9)^XDzg&l+L`qLt4olX*h+!l<%~_&Vw6>AM&UIe^bzcH_^nRaxG56Ee#O9PxC z4a@!??RT zo4;dqbZam)(h|V!|2u;cvr6(c-P?g0}dxtQKZt;3GPM9 zb3C?9mvu{uNjxfbxF&U!oHPX_Mh66L6&ImBPkxp}C+u}czdQFuL*KYy=J!)$3RL`2 zqtm^$!Q|d&5A@eW6F3|jf)k<^7G_57E7(W%Z-g@%EQTXW$uLT1fc=8&rTbN1`NG#* zxS#!!9^zE}^AA5*OxN3QKC)aXWJ&(_c+cmnbAjJ}1%2gSeLqNCa|3mqqRs&md+8Mp zBgsSj5P#dVCsJ#vFU5QX9ALs^$NBl*H+{)+33-JcbyBO5p4^{~3#Q-;D8(`P%_cH> zD}cDevkaj zWb`w02`yhKPM;9tw=AI$|IsMFboCRp-Bi6@6-rq1_?#Cfp|vGDDlCs6d6dZ6dA!1P zUOtbCT&AHlgT$B10zV3zSH%b6clr3Z7^~DJ&cQM1ViJ3*l+?p-byPh-=Xfi#!`MFK zlCw?u)HzAoB^P>2Gnpe2vYf>)9|_WZg5)|X_)`HhgffSe7rX8oWNgz3@e*Oh;fSSl zCIvL>tl%0!;#qdhBR4nDK-C;_BQX0=Xg$ zbMtfdrHf$N8H?ft=h8%>;*={PQS0MC%KL*#`8bBZlChij69=7&$8*k4%Sl{L+p=1b zq1ti@O2{4=IP)E!hK%Uyh(Lm6XN)yFo)~t#_ydGo7Cl_s7okAFk8f-*P^wFPK14B* zWnF9svn&Me_y$dm4-{e58(;+S0rfC1rE(x0A-jDrc!-hh3ufR9 zLzd#Kqaf!XiR}wwVD%p_yubuuYo4fMTb?*pL>B?20bvsGVB>}tB?d&GVF`=bYRWgLuT!!j9c?umYj%eI(omP#Dd(mfF zXsr`)AOp%MTxp#z*J0DSA=~z?@{=YkqdbaDQujr?gNja^H+zXw9?dT9hlWs;a#+55 zkt%8xRaIEo&)2L9EY9eP74cjcnj%AV_+e41HH0Jac6n-mv=N`p7@Fjj@|{sh)QBql zE-YPr6eSr=L$!etl>$G9`TRJ<0WMyu1dl8rTroqF<~#+ZT>d1?f=V=$;OE$5Dypr1 zw(XXBVrtJ=Jv)?x0t4n$3GgUdyD%zkA50>QqY-Yc`EpwSGE19r5_6#-iqn*FNv%dr zyqIbbZJh#;63!5!q*JJB$&P>25-YG~{TiRL%|XOHhD4=ArIXpCwq&CKv|%D|9GqtB zS$1=t>o4M7d$t@hiH<#~zXU|hHAjdUTv zR<71yhm7y}b)n71$uBDfOzts(xyTfYnLQZvY$^s+S~EBF%f)s-mRxde5P|KPVm%C; zZCD9A7>f`v5yd!?1A*pwv!`q-a?GvRJJhR@-@ov~wchVU(`qLhp7EbDY;rHG%vhG% z+{P>zTOzG8d`odv;7*f>x=92!a}R#w9!+}_-tjS7pT>iXI15ZU6Wq#LD4|}>-w52} zfyV=Kpp?{Nn6GDu7-EjCxtsZzn5!RS6;Chg*2_yLu2M4{8zq1~+L@cpC}pyBH`@i{ z;`2uuI?b^QKqh7m&FGiSK{wbo>bcR5q(yqpCFSz(uCgWT?BdX<-zJ?-MJsBP59tr*f9oXDLU$Q{O{A9pxayg$FH&waxRb6%$Y!^6XQ?YZu_`15o z5-x{C#+_j|#jegLc{(o@b6dQZ`AbnKdBlApt77RR4`B-n@osJ-e^wn8*rtl8)t@#$ z@9&?`aaxC1zVosQTeMl`eO*#cobmBmO8M%6M3*{ghT_Z zOl0QDjdxx{oO`ztr4QaPzLsAf_l0(dB)ThiN@u(s?IH%HNy&rfSvQtSCe_ zz}+!R2O*1GNHIeoIddaxY#F7suK};8HrJeqXExUc=bVHnfkb2_;e8=}M>7W*UhSc- z8Ft~|2zxgAoY2_*4x=8i-Z6HTJbxVK^|FP)q=run-O0 z8oaSHO~wi?rJ~?J1zb^_;1on-zg=pw#mRjl*{!pl#EG$-9ZC*{T6$ntv=c_wgD}^B z#x%li0~0}kKl6Tvn61Ns|N4W_wzpwDqOcy7-3Z@q%w>r_3?th#weak;I_|haGk%#F&h| zEAxvb?ZqYZ$D$m+#F|tZG%s-+E5#Y1Et@v5Ch>?)Y9-tNv&p+>OjC%)dHr?U9_(mK zw2q=JjP&MCPIv{fdJI}dsBxL7AIzs8wepikGD4p#-q*QTkxz26{vaNZROLTrIpR3; z*Az3fcjD8lj)vUto~>!}7H53lK3+l(%c*fW#a{R2d$3<3cm~%VcWh+jqR8h0>v;V( zF4y9jCzmgw?-P`2X%&HK;?E*Nn}HAYUn!~uz8}IDzW+(ht{cx9Nzf%QR%Rhw(O2%QE#3rtsx~4V%Xnd> z`7oVbWl%nCDuck_L5CY%^lWGPW+m|o*PF`gv7{SxuIOpIR-0qu{fcqWsN(m8okFaNN=g9DgQ`8c4#Q3akjh=aXJMDnWmCheHhg+#qh$hgz%LMg7X%37AY*j5CJleB!%~_a!8mIK?3h6j_r(= ztV8qvPak21zIC7uLlg12BryEy%e`-{3dSV8n=@u`dyXqC&!d4mmV8hsait2SF z1^~hKzbVcsEr)H+HCzy&2rW0f>Bx?x{)K}$bRn){2Pa8eHtc`pcMt~JF-ekZr10N@>J^3U% zZ?5Lu>mOxi3mX7t_=3Z))A-82rs^6+g8*3w^;w+}^Am!S!c zcjkGeB+sQ5ucZt4aN$8rIH{+-KqWtHU2A&`KCT!%E@)=CqBQf`5^_KNLCk(#6~Hbj z?vTfwWpQsYc39-!g?VV8&;a^tEFN}mp(p7ZVKDejD~rvUs6FwcA9Ug>(jNnODeLnX zB09V$hNck7A3=>09Li^14a%frrt>+5MTVa5}d!8W~$r?{T^~f%YV&2oFFOdHZ+W-461bP_f zr=XH50NN@@gtQ=n>79e3$wtL*NGUKC<|S2(7%o+m>ijJIXaXVnVwfpZWH@fYUkYQJ z*P3%$4*N5xy4ahW`!Y9jH@`j}FQJ2Qw^$0yhJWA{Z&Spb(%?y(4)#+p5UTN&;j&@Y z8y*+wx`xfLXy2L7RLK~6I8^WRt&%h0dwRI60j%;!J(f`80Wl`t96JFu(~0^IRS*g-$IGS$#+8QxY?}x25E^_h!`yuuOJz9c>a3L`vc) z06t3`-)vWQI>tBkAzNtINbOsRmd2G=Ka($9B?iBJCCR$$wF)J>dY4q#l|!uI<()=8%evp ziiTDYFWO5?r_X@tBOcSN@&r|&xTDB!fF}g@NGHTM{{y8olafox=dOCu9O9u!#kenG zJgVQ3-&u}&`fvU|t-fAUzq+Tl75wtC3u3_pf7$qoouVoWN~mIUtXP?!l3ohg;LYHs zT>fB>F-lyg(ilR;OCS;9&o7SY2^ugYlWO}ai<12xzvh+R=5$2kJq@=h*IVVVZ)^$u27tLhOLV# z4nn+w3^prURshPx6UM_kXLNAh1ana69ZeS#TC$no-1Qu{ z#V0rjhzC3fh(L<6AVo^=E6Yq!c`Lre}$T!52UafPazM<+x=PO%{Q`xH9T9w7mJG6XV zscF#ORMKOf5z#a4Y`3WQ>47NKy;Sro_qS={sx3d?5H9Juy}DedhY_QOG}`P6M{855 zZp1owcyiDbOG}k-l@8!dVW?^|T(Z(8MWn+ltFu*8<=i88c`=Wq*Z@(bMC4Mr6`nV@ zkp*FSI;2+D^DD|>Sw21i7izopJO;_3sZ}u3uO_g#jIK&Y5z~H(WokolB9;3AX)|n~ zUe`jzAX4znlT#{R+7)ZyM?Q@uVO83DOXInC*fhbdd1Py~QexaxUbrIeE}rDD7u zK<;xyI9QY7*K5UYnt?e)AlCBB55cu?wSi+2Hz{$5kZ&o(5Av9`$Qb9C=Zc*|X}A*j z@nZl>XzxW`1a%Vum01W=VAu*FCNGaDqs#KLa)Xk6j@YB*57;O~6*KO>6u)-kWL%Zw z@AEm1o=j-$EGhu`41tWMH1j@{vAJot5bF#IpZu!-X=B|6ff22;3K|h-1ms*IS3Hb0 z@IAOeZp8Gf4>Qsbq=QK-uPS{9>7*jGBc;#N*L>&H*M1);i-0evQDR7(R%4rGSTD82 z{s3fpyvZxqH$vR3D5=2tIXF*MP^G!*5D`<$vMul9(GJjX|7om3f^!Wyzy*DaYj5_v z=~&Ypytt&>;CICFz=uY6oSLPPX03A(a=&*gPnddD$mA8?C)_P#_YLp;>-{^Xb6BQ^ zOtfbSrB$B+18pQ*Gw?;65qfB|rAxt2ct)1ti`>7_+Z6fh+U9zQpCb>;%AP2|9#kZK zw2K12j2*BzMzayoT%;?@7J=;CX!FSI{IF1SB}O-jZjT(0-AMe$FZgR%&Y3t+jD$Q+ zy3cGCGye@~FJOFx$03w;Q7iA-tN=%d@iUfP0?>2=Rw#(@)tTVT%1hR>=zHFQo*48- z)B&MKmZ8Nuna(;|M>h(Fu(zVYM-$4f*&)eF6OfW|9i{NSa zjIEBx$ZDstG3eRGP$H<;IAZXgRQ4W7@pg!?zl<~oqgDtap5G0%0BPlnU6eojhkPP( z&Iad8H2M2~dZPcA*lrwd(Bx9|XmkM0pV}3Am5^0MFl4fQ=7r3oEjG(kR0?NOs)O$> zglB)6Hm4n<03+Y?*hVb311}d&WGA`X3W!*>QOLRcZpT}0*Sxu(fwxEWL3p;f8SAsg zBFwY`%Twg&{Cox+DqJe8Di+e*CG??GVny0~=F)B5!N%HW(pud_`43@ye*^)MY_IWa z$Frnbs`&@zY~IuX5ph`05}S|V=TkrOq8$rL`0ahD$?LrT&_Y#Tc8azVT)l_D8M+H_ zwnRoF6PP>`+Mqv$b%Ad`GHUfIZ@ST(BUlOxEa32u%(4m}wGC|-5|W-bXR2n~cB_yG zdKsN(g38z1mDrOc#N*(sn0Em{uloQaQjI5a+dB{O62cX8ma-1$31T<;mG2&x-M1zQ zChtb`2r&k{?mjH5`}lw?O9JV!uOn?UP3M#fHUp=cxBb%PML70LPmiQKcq^FvojvtcZOCYEydgWQNAIrV0%IkxPmv)Qs^S zmLvL{F2@2dL%N^h=e6PRXa2lFh-sVtYlM1Qpp~@J7a19T>r^m-c7jZvDu*fb`U(;T zS-<-##+6Cv75X~D?Qq?ues%u!jBF(Y zIUnJIJJp~diP4wdU?54`;#zd^hZHa?76P3cnLEu#V!{F@Hpqm#X4W1HN8!VX5v&6W zKQ#Ri6w9~%aVjl6Q88)_;gH4||&p%hS9?1k@B725D5=L&$fMhxMi2%8__R)RBc0Hvur>!w7Xa6Uvni@ z-M$OMYiA1HoMqfnHs&K5H%2ezc5dj>A_TuZd4Qr!KJ5ZhljtBjT3*^sPX90A&m8*M z?Xx3`iM%6$mb>}UAvhvUS3*TGaL^sQ(hFc<_CRoL-r&;oX@N0g;K0y5*nQK=w#nvi zLnfCUUy*@0?cxGZMmRuvu}0w(AUq@uC^A4b41vdVsmKSrdL4BxqOJw8sUY)P>r+p) zw%X%tIjoew%BG{L`f^ocMtx~wQ(jAr%ZK}Vy>x7%xo_X;VkZ!ic|WNCH)WW;t4 zE~|&S+p@_f9xIx!=(f#uExcWOs`qDQKPnm;gxYBzj4iO%W+**s-`c#vqk z;hpHcBSV*Wa%DTA(u_u{isR4PgcO1>x?|AccFc^w;-Bxq_O+5jQV3$yUVaQlg4s59 zs@|ZELO22k&s6~h4q4%O)Ew;~wKkI65kC&(Ck>2G9~@ab3!5R=kIvfu>T>l!Mz3}L z*yeB){8laO${1xC@s%#F_E89?YUbqXSgp9mI3c`;=cLihTb=>+nr~i_xFq>r_+ieN zltGcpCFW2R-6j@74ChKK(ZFbs!!s=@nq2$6b z60H$h$(&CfxyO0UwlHEY^S<7wu|@6JK{)c|w_(C4-+FSF?iy8{FY1l65}9X1$Qa#( z)yNhnz5lG480H9oJsRdRHFxddQ{piIFZqGDOc0oyD6^D(CxW~fDWXKtbd3}~z2m4? zxyJ}qey{})xa{GBpPnR7{8@{vL!KF3)1$w>==~^CYQ&`SrlKA}ca_{ywJ&)(vrONU z`MZ=`jXu0zp@nH+24+c`FoWh&+$TLyJZ+(ygHExS!WXObvm6yqOsB;JVbA&ir^I>* zhim~-oI&{L^o24mh6HpUGd1d$GA)u>uQw*=J`5HhW=)yiaEx)dd2uZk$sKGbS`c$5 zI)L$3^TMIB-4r0!(uZ^oejT5P`S&a;UQ8$~+)8D^s5DGypyq4wL<;6PFm|Jy^;mz1 zhi+-pt=w^`v&IBWgK}Lo`fn~pTs3{~&ANBOzaUZz~c zM*cyzx1{QIcv_UUq9oW`FAFf#Fki3iara|&1HtpR2#wu>TutxnMh0Dh_cHiBPUfQo+v>aK09@y3!5u>0;;mKBv_oBXxPU(bBkNlj~o18?(tNrXa4g~o(#m3(ajqPU0qoaH~DjedUbfA0fcbp4M=u_@gF zNNP~e%ENNEkS4%P*L3#BYa5cw{(CeP@sY+Er(eD{Rkh@n0|uCl>|Eio-xm z2uEt#(w0yH2Wxv>6h1^3Th)^%Kctp-{mjFZ1?<#>SVoc8aUeAfG47|~>&=;=JtaOR zaBj&@I7<*`&^j!J>bH@^{Ta&l>)t-I=38&}ik2kJwn1#rw~@>3apDL0fAVFuAn1Mx z7zoG%)c^l)gWkgjH^l>!B(I#l5nTnmj2ZPt7VepToH8YL3@rC3aAUTZ7E{(vtGrn67u#c1>T4151-2olaIYPwPBA_P9^ zT)MH&vb|0#h>+^T3#**}Ven2sZdL3Myq!p+bzU$gK2Kk^jkJwh zepO$%drajHu=2bgO0y}tI#t~}5b`KJY;IQj&#lk(`Vwa z-+Lp^Np?>+Wia|z#`I!SW@sAEvijh>buf;(!)G}jWelyra1x)OM!Wgn_XTvimNQE) ztbtgCMUXPV=MA>P-2G%cFd2IK!5^8tVO!lG(qnQUa**au$Q=?*1vV$Jh7e0SFjUzu zUBRpkDW<$z4_DV9R0guKEc~Bfjx+=_srm=zVW<>Tdg>JCA5baQoWvwRmwg~bDwqCb zX=({}xx?ZQ+8$?GObN_F5=aR;r|jXBa!y7-e-F;SwB3ACQWt9+(E%P6OXa{1&5=|n zOm;d~Jktyf6=j!PQbUg{1;@4MbO*LrEJBsJ707zdY5i7{qdeEWtkxCb49bX~&x@{0 zuS6$E`tJpaCl*s}-TVm1)FFEVcPSQ77Auu1O|Yly)|~WZ-lO!0cL*4{bWW)q4JDTV ze#}fJv9pObE8eF`Bb4bgGUjZ#V5Gr;DKS1co@Qyxe!&FFH0I3`5$lUU{{kh$|uY(m+FQuf)ZS?{Hm zG(9h)3g;SwO-ZNXoU{ZXEQLqTXihvJFlW&PeTeR_$JSs-v;?7?wq*wVwE0oERWzp@ z(6CbDb_gM~XG`^xYv|#Y=lNU$ahYFXLZq1+Fqp?C|0(C7v1NgSoOl0V?-yU3?l*sw zR4`CpcdL6jfUk7J=F~FXC$HI&T_u-`H(RZ-ao9wk5~gsP}#JMbr-9IybPT zKE^{Fr6qspSUwfQ8!X6iBFRieSIT3-z$*e}$sw(l{>f4+L*4~%*-#IItJVbrxSI=^ zRn4&|Xk?{W=ZP5qRfLmU_$V;HBNK<>V%Xm>*Dc*9E)jcyO+$?IN`?VF<#{8H0N-^yEhtR5j>6ZK70+5rd6|5|0IB-&jR{Y;y-sDA@lqXvt*g zJ4lh`cLzraz-=Dj_Xb7&-ysYy1NB8^inO3K;4@#%~2xu?Xj)(s9b}a$R!s2KhpDZ|%6md^c_{(sD=32)hrm>lo=?HLmLJ z`%yhND<$<5$Bk$VQDXyxUXKFEHBES>xY_Wr$w(0DH;PiNT*W+7Ka&=(#3 zffXt$z?CQ&k?~6w3aeq9#TD!MHU41rqQ4)V0T&p>3MDzP#!|LND|RZ{jm!28xYgor zzqECq^uXX;@QZj@y*K^v#knPc6XsdK8dCl>gC(?>ay(OZx$@JoJqSsw%L?z*o0$x! zJl`lfuoEsW#ZpFBGd5!u_<$HfM5lvqK5`0NndUuZo~o-o;lu3x=^Azmo` zN3;zN)wef2A~_IFS|Qa$6+IjSuxNvS$yV4BEO8ILZ2tig<%IJN>2QD|WAc=gzu*G$ z$uF6}^rmERp&BUfDhtCX1Z_C0;}yF-4FBuF?$AfVX3}B zsCI{^qUP?}QrD{*Xpm$tjfm0sSuK(-&1jC_{@{>rfiBu>BltP*njy|0kTOgt@4-^6 zIL9_bYl)7gD`GeaCV3Qyq5CMPAFRkU(6FmMXAN$k_A(wgsvq=l6B0hKtxq zqH^ZaE+Y>&vJmdIP2=dC&S2QNkH%D`QN9!Pk35k@pR`(YxhE~vDE%AcRVa|=UtO2Oj=$*Pk-V!HiuZ1NxMF3TPe~xz;p@8VeEr;$M^aI zUtQM8+o8`!uCob zmsiMx{H41NPFS>1Xisf183g&fQG)hrwes%FEyxmg39MlU)gf|>-omm!gQU4On zJt@Pjytp;5<8Mle9(*8f($*m39Z!ty+{mQCdxc$(V|M$B zr#eh)yv#~2zhGwJ8UZ}F&pJ7t*4$iRgRx06-3!t}3qC6j6#D}m7)kqE%UO8v_?Dz; z38?6qb4N>u!792F7G?!yokb>#^NsYMc&$MgC4l^gS0Drk2-|;8IE=*50R~Qs#u$N$ zv>5Pi{y>G}F%*~3MwRW{0c)~_;V^qSmag?}c#ax5AG;k-$?p{I9qavY;eKKZ0jDV{ zdE)sMaGHstenmqaLckjCOWqRfs2OQwrxm(t>O_z5L0M~If5&qDGgn6Vl zlY4H_5AG1-u$Dk~o$_KC`(D85yqHT!n0)yQTA{&jARG^PEf8>a&YqE;M}-Wp6QThi zN| zGol9%&|!Ii`vDvQBn_pnmw5sDUq<6Wv-5FtOW0g5j?qCjHTumdX-35<+hAp~s}U5o z8A^MHK72zh$;)()ZxtQ zcqxsR(Nk)^i(0;m-eI-C8ngrA1FlVll9w4SP5Es4w#EUnr{DH(_0fWkfJ30G*jbb8=*9)gLqh+vS4@+Lu87{+2-Rc=$2HXTNNQ5 zl_RUQAs)1~Wo@>QoIxsQcIT>g)ontxy_!aw&;D{+wGNm%Z~V`*@|MXlQJ-d4yw5q; z{>OTNV}36~p|1xM5cZ==f|diNvsx?%BGl7YN%7D&M!4);aYe0 z&l%66;NGL-NBX%cy@#QWh{*|>PUTd%Ym(O4$|0Qs6BZ8VUIVTH8r-m{r96wJgp>dd z?AloIfb)6s_}};+94HCmoH~pdEfgs1c7v?!1n{Gwzp_80Abg(A9z5(I00&G+?UCeq zLr;g3KR7HU&kurul@pX(w;?IhoG_An2=$m4%TQ*ljt+C0QhK$tXR6z1+{I7U@+lr6 z3#;S21J(?NyBpFST+o9v<_+uiQQ|X!2U#^rxCOp;B(|0pT_TCutj@ID^6lxy%h74o zwwlWhHPv+nZ7vp%RT@)FfGYHtbSF4{qKcDPXfaHc=9MkYMmCgk^}UV|R8+n75d#?_ z^2G`}aKe&_O60Z(@Y`7$PW^OV{<%Oz$iZ4nuF#Gt@`cstRqFy?b4`x$5KP$Zbm*Zn z#)~b;LtZu%IEl7ZsP@bmSU1>I3n`rg+^_xVib^`ZqSehsV}^Mg0Go~YT(>a~juFW? z6N9NcFkL)Lfl}D3>U?XL*!5;4XN?CAV zBm5ldOm8_qw6%se4w?6m>#;|b5Sj}tV55zS9hVOuvKfAu&gv3J@Lo{iM4inB&jg71J1i;&WM@HS}O ze$SmM#w~dWP=cFB$`S4sX^q~tkqy2Hq4u`9z?xkCq;^7K?v}gkJO~(DX@(N!CRnvu ztdL2eg78}_lTHNXu4jo`NS3BC=h6ZFgRz7}azu4T?^I5{9zCjHUUV~?65=)4(UADPnk|!@Y=pZIpKy5}(F$HFBx`6tDy- zcO4n)uU)tJL$zi9XR7L1V@opZY;(W+M@`(OwJF{rSuNDnXaLx^aRYx4^wMY|7pyDv zMhVd+AY@V`0e|dFu@=duX(O>g9N{#PF+yB|R2FcIi}p(quk+tB%#=lSf&Dz;61-9? zYO@hNy`IvQ!Q1TaH}RUtTcnO( z38tR-%<7MyBeutubg6VDI^r9WPfGb%*;mM_eag!S9A2;4K2?!3e_bg@yi&#b?8eFI zPOH)(2KS`5h^-wJD;(-eO~7RI-m>kpv;|P&-rJ!L9KKF1mZlK5g77(gmJ`Pg0e)Em zb!bj8#@i^ozayNY!wx`w8Bxxx;lnBwIo1!IY>Oka7@!v@x29~l6q&!Lmm7xUQvxC` zv_fK;_4{tB9tpKHBgdc5JSq)0MiECOA_Pd47Ary}8DrihLeUU?Rr1+sVp6s@B9nDy zxqSzw=K#ofa9jC@cKtPlg-<~V0B|vh_^*5zh|>IHGLBR;%KLlKiHTD}RpvfqoSLb` zqh}LbOxh{O@-yzxX|SceOiEicwYNV>)(5b|7acaZkIF^e^my8Bel;Pv^kbM#TAvW?+CPF-8w%jc?1iYrdPR0M+d6Bel#l zH5d9O=N9fJNoqbh?Y#3V6<1pe-gj?W$|uU+bs9!UZSHqGXHtm|5U{pTI44G0MhCpR z%Vi%K#j`EqHCPy{JXljh>OAF@4XYyIfTNI$7f1_lQ+5mUbGgY_(yjIPfSUP`JxjOj z&d#n1)i_tHxMtfH@B>DJPAy$N5Pj%{hWh!{Gg}ha%$(o3*DU<~5W`|~~0Ahu6Kd{Oo6(Lo< z-jZ-n?Es`IPrA0FSw#bfR&7X+tR`)tlVThp<=YocC_di1<_BLyr0>l-sQuWF_d0%73{0&0z7ZH3Dkd3#MoU#^6xv$ zXJU1vZi*v4su^N807`n?Wj0W;k<(dT32}WGwmN*$!t^^oX$c8H@Q0(Nm?#LpyrSw?4}%AO%qG*7mpdDlVs-PO-ZH92;-F<9p9u#vfdMIZQ$zS}x36hydt6K5#nkHECWqmCcZr z1K}IM6v3ggF@qPpO*@~)T?M!iJ0U%ZY&CsX6kX)*gz^mU8i^?eC^P#a2=JB7P(Pk; zk0%5B>!WMOEvbQVj(00{)?fDeJ>xbf;XBG76irB^TFxM&pa|8MBR3KIs=Ps{9+Z)Z zWB6fH$9!Q)A%N|>=(8jEyrBv@ugtma(1orem3;ob0%$W&@_KAD{N+U#k8M}x$N)he z3vNZy(m92FH9wZ#$%Fd`V=&k{vH|g!g017(?A=hAG@|ULAdEnX>Q@fpUHxA=c1j0D zZXMQ5ttT8Yt4E57$+dHrG7Ad76KMUEf1Fj8?1XL^$^(k&6~BdkC00xpFF*MpnfPK| z3QFGIQFykL4B^A>XkeK?`BF|kRy6BzaCD334C zBvGQrlnqc>3-FiJL7t@v*osEMRC-sLJPyZ+jA03nQjXK$A;!M%zyqx@an%oD;xOi4 zWy4%$y;?mGvF}d-Vthx$c_aSX(<<>tj(dU5at51WLnw=th>`zM{jxwMu})!CY;cB} z?6J;}jgo}qKEAR}#!XI#OiGn-^GR!;W;IXA{09K%gSj?--Dn`xkMs(&HdPK3i9aZ- zVJIt${*+=#cJ*-@r@FP^9Mx)(+>N9OdLbMQUb-7|@g6t96$rF+oixyf*{?${!SZD8j3z-I*6c!|=$4o+ru7srWWe_qH&NZg-5jPq6QZ zdF$;6zUQ_BI$cjM2l}spQo!ijnAoPLeni(its-$FhjWOzBBwoU)?BG+kChS!Sr`^g zDMKYUVU9~G(%fZ5A!mNX4**Nw9D;ML5obF_;bm}zz^AHv3zw_aS zyf1JiifW6oiJfS7y93Vn?T-ZX=N0-yVH($bVE3>42>CdAqAwQ9?+?YW5iw7Y zeQ2j2Sm*@jqf8kl5x!Jzg#xsWJi3{j{v6-QeGEoF8sI2?$wjS*3tqjk1om6602hQkROLQ|U)0w&iMA7O>LrwZnEzSp%g$zv;uBN^6jI2LKi9(Z{d#Krqc~gEv)^bw5X@_0Q++t+mm25YE6nGMcHx+&_(^*bzIeehm(6h&srgPimn~AQ ze0pz~wmGI({WV=ct>xfG7kWZPo#h8L;XrD_o=^lBeHL!A+FkdHQ(0Yrs#b$Wyc*SP zV9Bn5iRN$I%hB(O+>RH(EdVK|`OSzU2m8D4V3sW`7l7;2r(}?crNbV?+}8t5N`z47 z2yDvlPyLvIMhygG1ix1Fai2KA>S8cUa=t;vnjl^nc!FCEL>);a(`cSNiY1Rx_d=0?a=FP{AQ?GrJia_&-UIkmb^UDTC0g7yp@m>h_d38@&Iy z(AkpzKdr6qE==pde{115P$?$1OaM8rB}t4gswVOgO>Y?0!Qx6hA{mTCU6ODL4oFdJ z8wKx-FshQ6D0Ut(i;1++lGC#6uc#Mf_n{(p6W8Bro!1Fxr-U02*wZ30nH>ooyI#b_ zfUnO3%Aos~x*&lNu=oRX^n6_&r+raSY*vk+;JJs>2PfJGq1;E|0ZbtJ> zczCsLujO86xDPxx0|SOLx)IVJ`mM#XdPaYWE6xG>6hg^Mo`5 zm+d*3Pyd?OB2OuBaL6K0n$atjx0O~cVnH=WJ=AuPTNITe6#*QVHc4CnLDQm#VDgP& zC^%IZi-Jj&%e7z2L67o^J?TPT`7>M9 zY$Nxrga-8XrtCpK5 zAlXC9dbLh*qr9mn-redGmX*V0bCm4L8ra2kwZ{MsZ@;w$w4aIiMQCZCdfPu*()Rp{ zF`<1QfG_vk_T>w&R;29dGiV@I&4@fpyY2R$^4H(a46>SwC|G}{R!hTqckS$3#SuHJ z?7}5y8EBeuwGbgy3gC9T5d1$}oda{FQG;$fwr$%^I<{^5#5PaIcE`4DcASo_jykqa ztm&Csw`%6A+P~qgUGG|ZJy3%BG8}dj?uA;~8%sGFw-Tz8OVl9`Rn1EWSK0U30(3DX z_~ccQ_K=Kd4(?a(>N`rQ6>ON*Vq1!PT{4_v8)WhVeyE&~0rH2v^B3%>yG7CRw`np* zK7Y6_w}b@mhQ~mW_jAU?3bUBC6qHac9JLQdKLpFgNrZ}8fx_y@L#4}({3?;Ee_))^ z%fF{jveoeoSbRG;RNyBzj7RdLUwg~YNr zS`sY#E+7ZyetVe&Qmg&3nXntMHCu3l)}!TQJL4O zAH-Vuos7{k0OwAyov|aF<1O-C;ZA;Wt&dn##mEXPHoK%!izEOerda$eav&gAB(}Ye z_+a#%vov6iRmuqNa)vTTA9D(07qTs+Dq#DeChp0jJ3=Ws6e!E!08(EuJEFfO>b#q# zBlAom<{{Y@c0`Xu3<+O|hL{LF;?b(4%ndJdiXRMCu+6^y!za69i8_E7aj>ml3{%QCIs(tAptIiV>q=rmgDAe z)q8)x`b6?A&rG2%jp*y3s!sJd3v? z>t3#jY>Sci5&)WoGxj_hL7s&$pvdzCt|bbGE@t#@F>m{jwY6ndtN)jDS~| zxie$yDZfo_lb^CLCTWU5PUGw&en1abNQvM8C_YpP9A{4Ua58 zAxu8AV2(VF*M1c+Ga3ZRhrfwl4P5DNY8aTRr6juNX%fm$^2{Jf%Y?cX8>2* zs0#n z0n6=OM3HVO`RR(;acPNFxe3<<0(oQAw;qveEzl7ndwKdc7iX0h$*M~+eWMW@PlN3F zE_Iu8n32d&ZI>H@{|g)@TxkN}puT-W{8tiT`k#tOpA#WaUmHUk^AlM%gB8(;99}d? zr+^YwX8w;>fkqtdTtONw_rf3Kak5w?z(OXRnA4*p%WS|+t?)n}q@LELezz7-U0eGp zQ% zDvDT1JZ)#7<|tPWMH&^JXo;o47*Zo6jElO=HWE3-ZdxcCUan5kE%CO~n1es*?hvWQ zuC*qkZsP%^GhP6>FRmT>9pXffsWU@mb=$N<_=?T+Tn-+zF=yM4<4|2h6kWT^r}{%?Jttf}|$L zLcA^CW|kT3+Fq(DYgcktv10|CA=h10i@A+d;6#cwU@y7so(?C$_KV3CDGY z5j73sAsg?Hz-6#4+G~vsum7UUqEe=9d| z3-zF%&H@~$*^d9NbDLDGWBJpsPk|BLXQlK)Xt3^7P;0crIOw3KkIC+kR>O!RXI808 zHWmf}1%a!<8pjhA+-r~~7ha6@{LhtdmTd->9FvEiO1P5`?V?%bN;7vKMrkxkV$ZNh zau(Ci*kG#bGr^%G?UMO<=j_fIC018^!PY`54iIf($+(Btl`o~B*DTZ0_9vRq)9z8g zrGXQ~2Pf-5H<0b-1uNRqJ>%x1cDuKY^%ip)jeNff!VIN-#>}7R!#WPCaGonvX@gXLjOcOWnWC!B9t=@2_o>R^xHFiu83^B6c5HRi`>Fyf*;1^e?f+ zy8)}Q?cBNUX3ZU4XIpr-qOpQ5nj`pSl!iMrr^GlwAy&3mYoelhNI^V72#O7pUkmaG zMrEzbSmA66)q8lP(YS(mQmk@XEtwDEMZf~g9ns0u#$WTj2*%V0PhUYIqd3af1s((o z`Q5MpnWePbxKy(Ac_sML*m$4=VFu{>ugRM6Xkmk}dq?b?1t}ryzeg!Eu`KSKhNF$+ zE6xn}0`Uu8tJ4i%JnkH@4S_fpuoij=7{eIW;w&F#Cu5l8GHNq)Jrcq!(AL(-gJg5$ zg?uRPRAjfAM7{UC{K7|YV>e}-x$m?Nr2FcaOZCv-Z5%L z&W^66Z)iDg2w#vFHelFoP{&)Z#-tM>KNl`{7ec=NAEixsci;P83Ki)jW-5EirH3{U zDO*uST&!>oT+bHvXMq;x!b+P6C+AN&+DNTjs!qi=Lr<6HpiiWLn@W~|d75&TKKFkh zLE){8NGe75)yNfqhgJj)%0$ImI4o z->!E^EUrEOP_1kZBI9-7#HVHj6hy+~Tre=w-iJWALp$&E@USJg$>26-Wdb!Q?8KJ_Oxm@5g$1vN1|CUqUT54}Tq*&DHCAgy+cyPTH@1nr7m~28-{9I;@=MfHM=0oP&TC z#l^CkS$)Y)uW_#u)9zJ0gL7%j+uW;DHA5d4ah+n0zIxURQ*x4&CXu}-fXFn%h~!tv zD~%8Q+zZZ-z7zwCSah+MnOI=wAB`MzgWO!T3{4}~dulk1#SNXy!|>yz=zE6W_iOWvVI_kfj?>fvJ8 zN6-cVEv=6V`(8#KFD9_uT)6cm>$pxnA`yGTZ7QRP?kCoL-ASRCC@8VXOm)30o|gl( z;E(}%8x|aTg4^|pUSwm97};0ICiCf-L+Ka&$+XxdX3pLWmxi|~LdwwsMpbN2`Ya>$ zkmwL0_oyBHfyDGo#P%*K14Ji2q1m60SiI{}lrx~V0_PKPI|EKrZ@0tF3JCY=dO5TG19B@c8S$PMW^58$QWA zX6I*d!*#xyGt#bGMsgHhHW7>w$jE!{yNmog@vm2?tUWq+yx}{k6-Y;XvJCNOOIi8A> z6WH;WEFEWA%l1&rgO?~s^u??mW~VcgV9FMLvi#p0n3S#R@1m3+zM?<}H+4zOz(;Bj zbvpsRS*b>iMpQHk6+kF_iU|CH z2ct5E@(CvV9JPDl@JDt*DLU8vDQD|ANAQ@>>Pg7=b8+^YQnAHfTB%~r9PYUYuT)>^ z=%<^$WFgiYvKf5bp$=fY8*~vo>WDO2j`n?+qrq@!ygV8vdB&2ezkO8zwE{^A;{Q+ z@D$5lwN`HMfS)LL^Zdu&6^lGDZHmXBeyPQ(6M1M{qsv>{pUE{IDv(Rg!YYtQ6yAi_}ouv=vLm+DpfTJgXW>k*6sz6 zJ|TBnBm{7WsRqGm@P3$DP@xhe7nBv4@2mxXN`<(3eG3Fg2Mf@9D=`T~(P*pPl@h26Nf*X^%^fN!SyO zp~uO{)YBX>=^g6)Arr2+hdT`~lE-l1uqo270xO{Hvv%wyL`?f&nRKAI_TF!hIAvOd z^qIFMLhlpZn)WpeT&0QfJPy=zu9&|VNn$w&$v3?D8KU|b!|Mh|;XMxi6E1mNrN8=Q zWWxfB9K_Tkj!u#7QX-=kx`ba@cKQX|a?I)hvj6&oNC@F2v}I+Lg(e%(23RB5|MQpI z(ZrF;aRZX|KtuHgVT&FquC_C@_sk%2*zM{YP#iqCw+z>z{)4 zgYMfmvTrGcCltVGJvjgW*01`eT%D+S$nZ#6BU$O?A7RN&z*W)FVJ!v}z@asID0#;F zEvRQUO%QT<7~GMW)@&-c^PM9v3E@JOPQPM%h@Sg0N=p6SIkkeWP=s zF3h~Z1jnOsHNx%@WXuyHf(=LkdSHSBVemL`kq};YoNSmeg%YOq5pq6VI#Z}a3ZexX zhq`-9_Nf8zv$t~sLgPbjFBT|7$3A8mEOYN>yd&Zc{#AqJbUppzF+PP6*tg^;y+bi0 zo|(84n!vi7Iei1VaC$b4m_jMUR$||5<)<5TBl>U-Orx^9Ok%y6Nkhs{EDWq0c%#!o zo)^Z{a{+_d>fyp=@Fu-o=&;#G6$*Y0A!+~B$U@aa>RZEV*XC#JNCJIKBbqfsmT)aL zd(_`oB_R6mXFnmcSTL1pWfRq>A=%|i#` zSE~H_J1BT#T9FOSJ{e2H!gS2--Cdz8?R8WyL|TE0o5TsxRIjQY`NPDCq2RHG0%BDk ziNhGp_$os6bq&6{J4YAigh4;7?Xi;9@FA%dx{@(7saTs&J#&$Sh^f{j!Ce)J>mAHE zM4(ihP7M<-2NEf}57?h>C&f)d_CY{{G7rT!rSsFZwfW9c^S7g;IuSc7n7KcmXWb8f z5{ZdxkTT{?yc_Z=8|cvEGkw=KYa;f-C(>D&bT&4d%F1i~{G{EU(q`)7HoEmUvibeG z+S}XPT3eyBvj5R&=!}kK(Uy*k%7Vu7QebJPonL{69fyeJutrN|wVR=~8)-wYjo`C0 zECWZUc+!CAz>Ta!(uv8XiN-YwUaMcx>+eXkT8ETu6WM_-aT0D+qznh{qDB+SDGdR3 z*_$(iC;yy0XEzsnlB1zDup&InKe+%pDo1GX*2`De#5;(AfdV&9CIUTPltw$z?d{mb4tbs>VX& z;LIH^m_dJS+xj?~*|23;Zv-gtR)Oh9eMD6e7^MD?QfaP_agSr+X?W)3t2c&R?>Lb}~=3zW091MJo~i%bPWA#O9!3^}aV zQsG^CDTG)_t3tZ!hExM>{rwCuEPzO9pNuOT2pGmF4cLPeII*aRl1P_0M$hq4N~_h?9(Z8nNcc z*{nGrSvk_P1@xapg;Sr@*Bb3IVD_o)D%1I=4r(*_E5h^r=5z`+ouHxrI$#trF60E#blj>D9Kv_)jPPmNgjBlWKk=;RlLOgL?w3T67b_ zgTd_p&{}2TlzY*L673**1%PEvqM?5F=8y3@OM21q)0hbN#S>YZy`{~S32c2^X2uOt z56JYQ+#j6VHRl$*tiWm7NuLnuer|%@zIVcNN6hwN1U%+EsJ$4mEqig=gqK)!l5)PtKj1TPFYNQDFY=Mn>5&?J@q&OuNmy z?yJf^|L}#W7KZxT|chAgkJ@>AMZa#QN;K`;BmGf z@zd6qireD%45{k{Km3nyq0l&}q2&b@ zu1|E5x#!7uthitF;bSjwarp=3oS*n48qYRy`MdRY?~FTHoS8Baxs?UxcT{1Z>v{9f z0-2@x=SUmSD(qPVrjoV5Ldi`N-bE>k zC-No2$$qi=EGa}Eo{k#!2}bn&wEjMOCHIrP@gC`5epjdS?`8IH@l3Y5+xF1o0DVLj z1S~>~X6@k{dgz>Iyvr$6Ub!O^<9sD<;BlTtm$EEEBl>&|E*cQPdJ!*yFQ{2lrbLxJ&-?h7A(_L_3HBb zmy&PUFOoiDq^n4T9Q?1c#2|l`_>o|hO5r?m+zQcW1lJ_%8}#n}4kl_&-~7P3+o$I@ z{9iLpq%R1Cb`rF!oD+A2w=RJgfoaU}uo-YK+Q9wxXNL_S$1Jl|k>|;l z9ndlfpFc+Dw3L&eW4w-guoPHy+f80)`BJg&fP*n@v@U6u)k>%&{!^xAw91fps;R$= zk%opTc9}W$WfFVz>=1Z}ryjSnpHI$zDC1jer`~%qu6{U7b+V%30^bY|R-#<5Zwh{n zL&f1LxRAVSXZ4G6CDakQYH|zKlDfqi8t4m9vYvF!y(+Y}NO&O3&1}y7{V4d-75)P@ zM4`+o-Ew8S#;SpyWEl+NLrfMMTjW8vDw)@owX|S?5md4#(fqw+?0al)nLnMqBmz-d z%!McAvQ6i}xfFy@T~=j-I#~0D&sgM1mUfz=(09D#`_DLFlXUut8BvHBLX2xe3NYn) zUENDU-GNz$9Ii~zW{~AhfNiLy8(~;c>O3Qi<~s4JKpLzir;XPp3dAuf*i$Wx8&=&h z6$u)^RJtoAdpExunn@40?6n#;Lfd4_IemAd-pqW6y%Wo0-rwUj3TX?ulK*l&NdZ1- z2Jb%xRPNOAO&++l$!ym=mH(BT14?VXPfw`GJPyhCusbsm_AB&Z>@L-I@Y5To)-^fA znd#0yRD$-w8!I z(SXb~d?TJCOLfU|C2E;3tab%XzfntN2K)mk0ea1fvCgO24_>-oJysJQbWTrMyoH*C0t`s~oFGYHE-M=Q1af`+XfI`A@`}_U`MF)*NzW(fz1vJnN#}If`6=lo5VlS5U=AefvMX%By8Qq$s?rdDLZ0Fp?0CBi)gjsH{2k~cB zreeNzM_i3~lW1-HR#fsY*VJ&;d@!BhSBO`26=FgO04s(uF5+;u$Jq?JsBum!BQd# zlJr$@?TG4=fVt7M5e(4%bHs2LE5z-#tGuyz9N7UyWxUef_ zM8ft}YDNG~%Jco8IQ*7Y49ns!E6YXjrS$u_Y28<^=^=J{#qI~gp3@;#@j-2cfW#t0 z70P@pd_M3Vb-L!J6B$iAR@KJIa+!AeyF@bspbI4l<+s~H4oi`LEK@-ra`QuCK`LMl zdU#e!Pr*S$@v;Sy8(pooy`r>4FDu#BMy{%qt}?BxM9)^93NU!SiFd~|oqT=%?30GP zE^6|(rJt_eJ8jKx0WB*VhJ_)iI_2;TSCOFDrx%DNAa{?FBFv2Z<|Z6C7!J?mqR#gZ}|6#&E?7g z9)FaWPBwqd_}RpV;xWLBI(kx>ltM{YYy%aSg_hYkghi{7V|OBIPq&xhY;QW_lg`|z zPA<;OTWY_H9upQ^eV0TfES5URpuYYC$%O!?-*e8|Y@u`QFd`sI;6Fj@AfU&?^b{7| zF~@UxvN#7sBPvI+j(fiIw|;{Vk_=?>>c9z9awh`?qWLSrXpu}8gIOe#Rf)yv$^rS4 zQa#Ch#c!TW&%#UF=3y@jVs^t+O-8JFGTo_0RP7!Io1e&#SxRY6*}cyXK@P8&C)efq z1?;^E6QK6~S19@g7$u^1$u zH5Vw@ng!80CMoVaz+U#d55A$;=XNK{y3#eXLhC!r-&JqOh1Ix$D&Ng`Jh7q=NL^?8oY1?4Nf+YiomKA+;3_7AkN zot-{7))AI6Nm~}Y&DXeF9p-g^>&#XP%ieTKuT>{|s0Nuw86#=)nOTwXM13ij5#av2 z&v_F2qD!GxHWz|(&YV|-`vCJEAGLzZAsu?tIq^_8P*F9v?^BZ8gCg_KRJ-P)i6|r7 zg>q=rpCAezNSEGFd3{0wg^{nS_S(gBWqzsQ8u)fHrH#<9bcB>B<=P9g7QQ(C;<~?z z!F4>PS826LwoN` zK#CPere|VyK2&{a@$?0FVlS$yC;$rCRgur;f*?0Ec0*Jb*vdD#&=XBqrNa9A!l3p3 zXNFh1O%?I-`5luZNT3BbdjHNqu=rdfR5$$c@%1SQ>$zCb3lv~b+EMoO6}wU!v@1jY zCG!PI92U+%=R|lwv=E0T@(Ysq*a9n7MD)?SG|r!w${)!z{d9S(MYRCPI_Q8R;0c^AMYfr8_IV}NV`D$wiBY)*0P{|%`i-~ z5}B}U5~VEb8;~K(D8k*zB#`jY8$%U@EjPB|4u-DKrQ0>M@|#oUlVxG>K5_F))3yX3 z>SU)xN^24D>b1_;T8#CEGG)+V#rHu2xH3!qjQQN)wrA=iCoh$-3ExETU@e|@nRlYv z6?i4#`(&ZVB!lAH9ej?Em%oMXfM*s)*{KdH9IzwyfIa^Iylgu0`k(66n*&jE`$ z#cSTmsQTBAPKnGu{a-^SOwct(hW|EAlK=fhBmW--!TAg&r8Wm1$Tn#KZbMs0U`;^R zCQqs>)`^ac05@U{%Lyh{AW7Xl1V~=b^zcj*5v*vl)pt5iU3nX%ryl`eM00P$=$!|| ztQ6b!o|8PPkG#H3Ur={vQ&An=kNe$kzis`xzJA)yd%G4#fzSy9&WIu~5~~UHWWZ!c zaH7P=YFSVcCZP=i8$yfOEiAlUVt+Xz?NSN+`srmfIyC9SJ2T|Kp6neK>)4YVv2pwt zxhMLU5z{_bM~duKvI~z9!QgoY=z**!$g)>;H2Vgy?ITZhHK3n)JIl1vP?v1m}RGeQcvnMFfqdoX0<_&};f!z%u^OunVVhByakeJ%gQ2J|(>TR;5 zM3AK1xWLg+`HL02M%prR)nwRStg7>zg;TS(yQv5kNqI0#oFjp!DqyTGDs?*|OwHEY z_X_Wyq;-yQQ)ennM_rv>k(NznFak0o9wbJ!GL=kp%Pnb&;Pm4N^xW69)aj<?q)&xk98Mm~GoMp(9pQByiCm0BA(FWA%u#>7pzn^JdCnHxjN#L}Jk zGjv>uohypMIA@pq#BQKuAwG8_ezZk{dCXOqbj9Qb}Q`^5(-+yW0<|IHdCo3 zF8KG^#2Uqu4jzA*kLbj4S=2Zz=f+fqX(^l>Kc`iHwES~RFbrFj34xa!a42kj|CFlGh%)FeltAr zXlU^4?Tyd&8+c#EU-{>z;QGJS=zV2>&w0!L5c@mcei<(UC39gLc+YI*|q)_2kMjN_=* zw<-_5V!P2AT@k#{QBhGJz##iU!2j;`EqiHGtjj^;1Yb2Yi#kflvol<3iCyO((rOA4gHf*TN$t4 z4bEiA@32nHS1bHNzDZe)p4BXGS>O9T(R!gKqUv{>`g2&v6!Fnk)TPOGVkwbB2Py9aPRlv2We2Vf6#Nc+^ZUi@7Ql=&nfx z2!O)sW{a80QQw%d)t)M8%Sh=RzppdfzUyS1)z6v)w|F9y=f^iZ6q;^BV2Lz5$Q1vy zv2E%54l7G%gco`Yb(kmyhdkO@sKSnusw(VZEbFg*+33*~M=^pD zYFX-3+@oKe&sA{fwrN9!&a4vy?9c5s0f2iw7Y)*4gr{b(J0NAZxjdG696&Vfk_R}_ zn-o4D94}L$F+d~JkV&*EKlE)BrCZACVvD(7HfI|S3Vht6F3=DdJCxiA?4U+T;j1hf z{!u-12wcp)gRU`$z_&8*|Gc~GHt+(y%I^AA{FUV)GCE&R%Vr)(6B{-L%1ur(Serr- zd|q3%Fhmpn5p7z6#L_v`_^170zQo_ufs?qCO@J?w}&alFy+c z$CIzILZ5;a)$}7+BcclfWfl=^YDxu@e<-^S5IUU@Q@7>Di>d(3NV-!5#a=9zuT35Hkmu=EsvN<9Kd3#YL{lVVhx}Tx<^!-| zoXdINIm2X#j1rbW~0#eJJ_Z5 z+_2C%0WMr&mjd_ z#A^r8snFEWk(0CYxcDS@|MI3iC?K$>(u3n6B5GLtiP!%fq`J@{2Dyi)@C9v8F| zONdBw-(dGcZw!behA~cx)q_l3NS4>Z_5_))2BtM~g#@V1oDqqu+NMNTUR zBWpVqqEhvsODr+Tst8&&erl}CX$b`9z@(U26FQ%IAa>oOB0e#~rQCg6nlnP^`Q`ZM zGU)w3q}CujVUXXy`~u#;$P&}Hl=GWziP@L8xMxU!Md zk||E5#6T1|Bu>TIsrB3^zU%eOt$#73cW{*fa|jnq%M4`|+VKX`MM)w{K4v_bf+F+G z0c&snF)SASh+xyEuGt;8NgG{)c!s>WFvF`3B4vB{ons`uBsi^(p7jP>hglnL>r~=8 zGgf1+4{oom2SHPkiWa&akMy^`8@!b}tK~4;NuZrh5ZrmlSVDZLRoKr>(zrA0^I9T$ zc1@40J&$8&eQ&3iwrYb``>U1CTS?4L@W}!t&tVXOCUJ?)Wv+$RmVnT(ws2b`jtlkLgxyJjyvjC)f<&5;J0dxHHR^72%E&9o9*G(WoHaiVNk14 zBT_1EjuH_uAiCkWTkJtQPTWM2Z9P2#{EXKe!cV` z4-b&t#pv{dq&WJYqn@!D0z*D^E1A_}CxQI-*xJ^P|13dGHpKMg?9M`k_o3`?)`R_{dV+_|2i{>Ne6CedHsS__%}6)I20R=`|5>x z%@8@bSMtbFBqm3(8B>VD4fA`10O`nL91P)$OK;i?e=*O@w=ue;(M>l_q@}wfiK0QnfA7!J}8C*%5bO}(Y#cK z(%1=%NWRCwydNA_vU??SiVEjXmCLwQ<(Io8<<}jbE=$uV}qHGuTYU}vWNXO!^5X$NJv?z5o$9r*n@14zwChU-wRFMyCyR#q}D@l;YxO1b) zzuphcPq9CAi*ApRN5`ItTWWE6%)MMD)78ohr)Z4b~aWyDoQ{fsd>k9U) ztaQYY?YK#bQsj)+r=so4XyM1y{H|>QNT(l6aElF7Si2=7Eo-VF)1D|1ZDAYga6|B8 z=9*M(i$lO$xyGoDA}X)E%7YGB(PFIz<3nhbT!|W%b8LZj7&=D|hBF6etlg}{;Z7TvLp`*? z7SW2NHf<&7rq$i9NON%3b+GN(vIs2(4&Wh!jH_KbRukYfi;;3ITwX(O;g+n2Aw5iB zi=kv{Oxnqj#RN>nmK*rR>bna2cATHVQhuDDU4J>2#mpSN3Oe`pXLXnKTyQBxJ2KFqYTn#r0oO4BPm3Pxs5xHLE|Tlp&k~zu zPcXkUT<6@($nX@|sBgo6O>9*-l^b};_#Hzg>)T93ECW50`~vq>dsQl5!mVaMsC=`%_i(wH)7tt3$1p%jyff zO5Wv8wB4JpKofsI)xlIQDOTFIGhJ|Yb>j^;N9^i~mTwcO^==wK{d?G+g{HpXFgPHj zQ$eME<{k9Y`@Yp(BsUb!Bw_vRCyl|6ZmIhIk;*kFQ)~ZZ^PEH9e)G{939l8niT*Xc zC`K&?jx$K9qXzXXWGjosuwljU?LRp{7ujSnE=E#$xeX8GuK9Y95I13>M;8053Y$F7iF_Uxfx7 z4l6af3YYQHmPZC3UkaW+hRr3JOw&1mbVpH`GccY~@Y2ld-x32hg^php|H;=C9U*MxO z8V?g?^=Ix-hLww!?wzB?i#|L+%}z#X6kQ|sM;L?b$PG1y3aiaaw@cb*qTUuxXZI(=-abNt~ia_rZs zd`xm{s9;5;8OeD~sWTihpFkZn^K|=xPqOp^7MN)B(8z_oiU&uQwJdnjfbbJIg>vdn zuvK?I^p25>GElPFC_4cxbB>wV8}QCvTrtT8J8sJ}z+{N#0^5wYE0XeR7+Q0L&Q|2W zZi%%n$3z<-GOacTs44^)QWl9;4>inX4B*A@AaexgM)7j%ZHb=DGxgX;^rW=#vwN1=L8;)8zphVmdR6bXeO(kc;{d zpkk6G8x_Qm&6J~>b^vKeHQzh}mC_VHZpc;kk3Bw#eihuCj_2-29A&h?$=U5y%2Y=a{v3}S zP{<{`xM2Ai;&3ZLOZ##x83(MtCmCkb6X4?rk5=7JcmD)Z{HnRlcMlBvs<}6QuFu#u zT}}V~YXZ3V!WBqFRcnq{x~TsiKI0Tkv9tHficz4%bK!*~x%;c~{@1f*?ibTlp1>NO z9Smj&hU=os)z9Z$;k~qW58w39>U;io!-CtBh;NIr`!x|NfmUTy6{=1%e76a&vDc}S zO-7bkATko*LZ|mQ6N4MA!->qW*IIrO1+*4d#Y4pK__v5djdlg|TsgG|DzZaA7sFhT z60}>Fp(x#^qaH*niKYSjv#;e~fg~Rews{OuJ#Fw<6aOL~jcYC_=?VZ39aY;`-E{U~ zy!712?5F59F3r3Kt#{dx>Q+bDEA=X0|K~PaaTgp|&e$J`B2wK1JqXtUZGgLO34uun z4V4Prh;7Zgv5Q}HfV(Q;SWu&R)9T?9wJA{gT^~u_mKAX=@xDc3Pd3(De-Uk$nK{X> zavq|&v`dNzFrxjiLyd*K%4haF=DNzWTHI9MJNoh<#aGQ`dhTHzq2jLC?zm;sYJ|hp zde;Kz(6TtVTHmgii+F}$3)@&L&U8T=*yfqf)cR%vAVr)p?V(wH zjU{1>DfGvDCp469u_YzrZNCiN+gY3j;)tkOYfw_92oEsG5LnrK zng0Gt!T8<;`~xq^V$X4>`EomH;}yz9ZAOMsOnhXND4jYfn4Q#a2$|~LyBg|IrrzIy zXqMYB#0Zbpsha_o@YD}neg;8VolOXY4_#t)CVQ6o%c}hMwemQ33X2IbmYU(o z0b-K_w06?*(l zG)+oOz<@xaQUUL(4Ft=wlqc>u*KH_Jmw>JK23ZFwCeu*s)uSQ1$wwk&`GR14)6HOB z8#xvajSh)`!qt+8-liopQ*3_wFwU{r=?}z51EFh(R;FDA7>7msceL$0YaFcKBT#t=2iW2d>GOwGzk=%|grV)~i>l`Xk)86vpm<(^Hl@8k zjsHl0mIa#@pUxXCJk8%MGzFBTrd?Aw*^CI`H)^{)3;c;XkmM)eXRu+M4nlOZp`R{R zw-GW7`L|s|9T3zfQ<5h^t))z^ndgh%X@L8IZWx1>1Q33a75~*z6CqV6%28DaBE}Dj zm?!h<-x7x+OK>+AGm1q)@qV)g+N<026Wshv*957VqQv?A7~SEMnUS1xVWZU+U7_NP zQYu!r&P;Yoon~SI-<-0+1sMR`ku;Y+wH){l;=YU zmJfYY7aA;Gwe`$!!alnKh!rT6UOXLcp=vx zaMS>p=Dn`-rn=7fJ_K=!8j(Xk_lV>VwO65!Z|ppCryy|^mykC#U{}gx@V4O^M?wn) z>G`sCxzs*amwvIIPH{k}Q(Ywk*V%1=Nbzl*YT{1uDgJVg{18k>6Ha0a#38J;uf(UC z_uQh2%MSqS4QpG$S^!BZXXgaLllo~OeK!Wj;csmo^D48OpXcAErzk`;=6dq!Nd}5^ zL$Jq(FZfdt_hL?e0uvtfPChKH{fVH!Ce=imqWh3*oeEli>~((I<&ra|GF<^Uz?aqJ zA@{fW6u2^P$pTA3nMhme$v1#2t0r=u%^5!m&U&!1`NDNili6tiA7nGy1NpvDOSXiW2-zD(cR_o z3m!J%U3NbZfETEYpiLZ zl%EV85{)AsLm84#huW^YfW#IqOg>3@4v5ZcGyet+0@BZu44O9D^K?Ev&Oetm1t&bH zJ>WZ@6dx*Xzg3itYc_xzu~dZ3?!KnR^}2WE_G**)QQR+GmZb)?bX6wISSLTd8tE;{ zBavC$w>CU{Uz^(yx8e@-kFfR^VbF1s{x@^KCLWiagf%iufd4pWk$pieu;;&~OmbaF zjkiWl420hcoqM%rpbaegTSNR^-z2gwV&=5a?MW5fqi<#=Y7apA()`@K_mu( z`gZwhQrGvqJarQwZA?&v25T|2)T^ISP%mobt(R`YYVxcXq<;V&$$q(1@gaV1!MrV! zP3U%UB`yYOhZ|1Pf0cFBaZ#*Y7#8Vn7nfYRK|)|bIz^F?5CjS7k}emJ@Ja{{-HkM| zfOLt7C?F!;wUPo?T7_>!zbokcGrQ+~&e`+U{&r^1JP+^qBev9VT)92LkIyg9L%o3{ zIvun1LUiM^{BWbSw*>DP>>A;Ikgr3?r&s0B`f+;;>wLEL9?ReTsPlaO9Z3|K!_6vT zttu9#R&#q_Q^9prk*z#mr^j_T-MH9AU&e|ga74pNLcD_G$y&6A@uOmVjO4ce zm-`4MT%Y81rGB~)5_R06GmRaKI4sd_!0{&Ae85}Z@I-QPhg5u)_v(!pzrflz zRUO0IL?Br@|5#Mkv_)e3; z;YmJ1kJa+YqbRd|{_o-eij$9of@}wD#MSG=ghxH^4?^}wY!!V%xo7!D-4;CpUAZZ4 z=${A`+G+E%3f#yVfMvZwK$l)4sZzRh+(@=_O1qRQk4fXYl<)?`hnSscHTmg++ztcu zRHyRY`~7Y_P7m0;$-GY}-J`<29{#c@6&UrT3?)Xf}7J5@w@D{*B!uIH$3tzk+8$6IR7lm5iS{nk#Ze> zJVv!CD91E`4BXo?rC*iw4I6QCNpNwLrH#n1*N z8q$D#FSExj*VMPe|f1zlShPl0k~ zvu0*Mf#C&VB-_i3H18#X_deYFZ`V3Bm&emCO<@tN9*8 zTNP=h)&KLw*KqnxA_0d=y!_$fQ2RtMp3o!8q(#+;1}mN@oS@he`Xj#@MO9hj5GrB| zU8z?C=qQcmyPTrrU3cX}@D!C)KcHWoe5+wz?R6n7{zvmmT_3ptuPrid7H(18IN zzNkik>~iUHJCy%XTQIMi9IFg?F3q}EL#o<=WjG%kS;@3!9P`ybhMdL{OEfh=_9;U* z7QbpB_M7{135QIWG?uiY^)gIcq>AX^3x+Y${M`yNsxjC;Q7Pg9vR#N6l`Cy`V&*D{ zx@E*@EvXsy1Fv}mbn>f0MdM|dc1RyGG@)&Vf7Ryvr>gnFAkAk29|NP58Uuq9nC+zp z1UE>K@%lbyR7=z+npLS|M1YwXD;Zvcd7PCO^W&RjWJ`EfqWUO&5wq0mVt}P33f0$l z-=^%OzD2??^JWp( z$MZ^v*Y*J!a+e!Grr`)W_)ccc7Tta*~X#Ztu6l+ zZE2Tvwcgc*X>8&$Vsr+SI+>Xm8M`XT$~@_Ts=aOBZ!@;N7v~5a+peKl6-yp#Dzn;f zG%Co_FaU`$TosB3A8K7+pAf7ZQZUw1zJ_$15^VanxFlTX;S>dWQ+1EH5Xbkc6c4#{ zoO)eGU(iPLcX1L@)bg(j7*jPvqOBtBhH!zCst8w<~(hM#%v#q^*Z$)b%$u>4Ebr)IP zJXX1EZ}gSbUGZ&uCdqTRiVXhuLJ&d+VHGu0y@~RzO|EOv%fo?U9SvcP@2V5V3Jh^7 zrZj6O;x&$$rH$KK2o%<|YZIo2%9bYGMAsrq?^YyMR?BN3NBAb#<#H@EGyGR3Q-|Hk zaUpvla?#FGS1D7$Kh_3$15mMrX_t^(g56nGs&z~a@5p0@Hul<&S#epNX-eI>blDzj z>oN%}=ve0D+vh?)z^aAanJnyb12U@dpoTrJCaJvRa>^X2`rr+Riui3?XlCrT;r)|3 zC%+;1luaS;7RCI)35SNIiFe?&G3b;;I?!K~4mFKc2Jm*uI7_xYZW zu#AeDilMWS=Zn~WO8YlZb@e=CozAl_+&xy<5iymENLrfYnuiE+W?L+r7wYR0V zDm%@(Mm*07)D4>9lU=(0P}94%rulvD8TtA1$;P#R?F<3`ts zG0XcCd{aHslmCin(rn+RZhg6__buo$TLd{2sk_bb&9KW<_Zu}*XB#X%>bk1;jnJCa zVOa>C!_DGHY|}(V;?((RUb=*XHkIR?Fr(mG0 zmF%qJ)bh;~cyD3ohiS?J2LXT=Ex^4q3BPljoMs{(`Oh zdgP+CNmcEjMT9`Y2g<6V?u`2slA5@x?(fBv*hF<(2oL+vM(iVs0W)mx$gf#n^X%+! zn;BnB64{=ZH(|TK;m^o{a@bmHe((aZ68|F9!?DFV#W1WVXUp&P6=XWlQa_?Ku5r&X zAT2axxhAQw+#)lV;AvgbF+*?m)i461N@#lZxO@q>`}-qk#;(7S^KL2afaHpysp{G# z#2Q<5%K)k+ZrCKlgX(UJj|~I*txBXj{eZy@W1bMyIU;vFE+(2w1?YVu%V5j07t*}|3+J`@XOv2Q-=dw!F1$m1R_GnH zI6D8jY`XFk_zV$G;!QrwkArxf`0$`xrCZ(Vb@$fEnzVU{-S?&B^I`OO@B4~IMON{> z`7uphV8qWmT|+Fk7i=N{vG6T3ge&BW`Rhl*Q3YHg5w_kkq&i3g!Kef-UiUp33BNLP z=jSM|Y?K$d52tWwM0zhwF%2IepVrwlUW8;m<2o>h9Gqq+Dsd zcPMfz%|FE9@hmfp8K5t8ki!b7U?QAYCf!wk_cDI*h-AJYWxjT=jz1JrQ=BL`LDArI_0xhDsKfBx;%?5CMmjX*c3DUcbK*%41{Aw)Byz96=`# zD#^<-toG7#q>#``$N!)J_IP zn~u3?F5}$`aRzl3bo$Pj?ZwPOCel&%+?UG}b(a<3)T&$y{GNI)m&*s>I&&}5c)rN6 zRIx=^SKfPssH~OBNa~P0GV!~pPWt4nl9s*NEuEX6L*uHl4EaLKGAu*5(o=1WRV{de zPz>bR6XxPye2`s1ck_G%T~OkRnlP5=Cy^$woNJmlr__!H7G9V2$BR^XFmuq4=nwBd zdX2?Af<B<3WS3<32sEVb2gEye?0TUVA$6X`1c0Uprvh^p2#&uE*1&Q zWL8FNu1(FL(YZ8kwB1FYQF--?*y}V<$}WcWd=x=Z^AjYDhEtMB&fWKF15T+MN)#jp z!Q@_4zr=fkChReVf_KJpc_hdXTOArxOrICR_`&H0nKgWS{ZOQYBFU>RNt{Cb%gC$w zGLFh1x^8?2gf^ys32t3Ep0WOga`-H5UE5caSzH@xDkb%NIclGw6j_Z~5j!J@3S}Yr zHJFJ%UJdg36}_IDMY{AFs%m5@@&tWs?*u=yjx>=Gy3ks!Oewa$rp&6%;dfLr88?Re zcygpKV(@iF*a$FH>C5dxL#!sLOWDdBBkr!|9?j~M*5D)=Ph1fr#Z38BLJEh~c&TTBRuk28b3ocvJW{y66kf=(z^z0u~OoAWh0?R={^cD3Cr$0C6V*GD)BS9}(Su(H17*kP{NnEd8J9 z+7ukK5^$N41V6u@3JQk(dE^BtQv)}pVZiznHP|FT0|hQk6F>@RPK}=yDL~_`X*gsZ z1{&Z%1q_$x&tX|Uux-@A1#cQCLAAt1>szvjwTJ& zpCkE0%n-<)qk&9bImI|$A>;iM^FzI`5EBC<7aW)?=ki#WI&}(=BLBwctlKV6L1zFHR0PvUnJGFCyUguI9Q~;gefT_aYshyK{I_JcxeCjl~ zzuWWIq0=Cd3XF7h4k@8%}NnL-r{Qd&?=6<$Y z7M>vg3U~qQf%n%upOUqK`(+f|k#gsvDtnzeZG7TAlf)@06S(jmfN+s>@DaaLxbZUM z8Tfe;nBVxkptnd6&IOKiZ_L?DKRrE-Lc9V4o0?qCsO$`l*p=mHJFF=boqeoeTIi6`64gcR2??U-SAKpBKbccnWV@Wje!p z_p?B8bCnvhS@bI!E-}A_!(BJGUy}_8tid7Jt*4D7%|!q8BD(c#H=nly*=w?3KjuMn z{7di+3&6GhV@Zpx!y!{Wpu6y2v-tZa-;es--$!21Mn5puEAW@Yxw{*`@!(io9|Rp> O;LQ#O9OtPYE&l^NyjRr# delta 38549 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 ltSba#rbH)&uY59oK&k!`i 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 070cb702..42defcc9 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index a69d9cb6..79a61d42 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,10 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' @@ -143,12 +143,16 @@ fi if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac diff --git a/gradlew.bat b/gradlew.bat index f127cfd4..6689b85b 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,91 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle index 096502d2..be676519 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,7 @@ -rootProject.name = 'server' +rootProject.name = 'sluv' +include 'sluv-api' +include 'sluv-domain' +include 'sluv-common' +include 'sluv-infra' +include 'sluv-admin' +include 'sluv-batch' \ No newline at end of file diff --git a/sluv-admin/Dockerfile b/sluv-admin/Dockerfile new file mode 100644 index 00000000..b8b5bd34 --- /dev/null +++ b/sluv-admin/Dockerfile @@ -0,0 +1,4 @@ +FROM eclipse-temurin:17-jdk +ARG JAR_FILE_PATH=build/libs/*.jar +COPY ${JAR_FILE_PATH} app.jar +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/sluv-admin/build.gradle b/sluv-admin/build.gradle new file mode 100644 index 00000000..8bb204ee --- /dev/null +++ b/sluv-admin/build.gradle @@ -0,0 +1,21 @@ +plugins { + id 'java' +} + +group 'com.sluv' +version 'unspecified' + +bootJar.enabled = true + +jar.enabled = false + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + + implementation project(":sluv-domain") + implementation project(":sluv-common") +} + +tasks.named('test') { + dependsOn ':sluv-domain:test', ':sluv-common:test' +} diff --git a/sluv-admin/src/main/java/com/sluv/admin/AdminApplication.java b/sluv-admin/src/main/java/com/sluv/admin/AdminApplication.java new file mode 100644 index 00000000..e852f57c --- /dev/null +++ b/sluv-admin/src/main/java/com/sluv/admin/AdminApplication.java @@ -0,0 +1,13 @@ +package com.sluv.admin; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AdminApplication { + + public static void main(String[] args) { + SpringApplication.run(AdminApplication.class, args); + } + +} \ No newline at end of file diff --git a/sluv-admin/src/main/resources/application.yml b/sluv-admin/src/main/resources/application.yml new file mode 100644 index 00000000..363321e5 --- /dev/null +++ b/sluv-admin/src/main/resources/application.yml @@ -0,0 +1,38 @@ +spring: + application: + name: admin + profiles: + include: + - domain + - common + - infra + active: dev + +# security: +# user: +# name: user +# password: 1234 +--- +spring: + config: + activate: + on-profile: prod + +--- +spring: + config: + activate: + on-profile: dev + +--- +spring: + config: + activate: + on-profile: local + +--- +spring: + config: + activate: + on-profile: test + diff --git a/sluv-admin/src/main/resources/banner.txt b/sluv-admin/src/main/resources/banner.txt new file mode 100644 index 00000000..55828493 --- /dev/null +++ b/sluv-admin/src/main/resources/banner.txt @@ -0,0 +1,5 @@ + ____ _ _ _ _ + / ___|| |_ ___ __ / \ __| |_ __ ___ (_)_ __ + \___ \| | | | \ \ / /____ / _ \ / _` | '_ ` _ \| | '_ \ + ___) | | |_| |\ V /_____/ ___ \ (_| | | | | | | | | | | + |____/|_|\__,_| \_/ /_/ \_\__,_|_| |_| |_|_|_| |_| \ No newline at end of file diff --git a/src/test/java/com/sluv/server/SluvServerApplicationTests.java b/sluv-admin/src/test/java/com/sluv/admin/AdminApplicationTests.java similarity index 62% rename from src/test/java/com/sluv/server/SluvServerApplicationTests.java rename to sluv-admin/src/test/java/com/sluv/admin/AdminApplicationTests.java index 8ba4e516..3a9a4770 100644 --- a/src/test/java/com/sluv/server/SluvServerApplicationTests.java +++ b/sluv-admin/src/test/java/com/sluv/admin/AdminApplicationTests.java @@ -1,11 +1,10 @@ -package com.sluv.server; +package com.sluv.admin; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest -//@ActiveProfiles(profiles = "test") -class SluvServerApplicationTests { +class AdminApplicationTests { @Test void contextLoads() { diff --git a/sluv-api/Dockerfile b/sluv-api/Dockerfile new file mode 100644 index 00000000..b8b5bd34 --- /dev/null +++ b/sluv-api/Dockerfile @@ -0,0 +1,4 @@ +FROM eclipse-temurin:17-jdk +ARG JAR_FILE_PATH=build/libs/*.jar +COPY ${JAR_FILE_PATH} app.jar +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/sluv-api/build.gradle b/sluv-api/build.gradle new file mode 100644 index 00000000..e87bf626 --- /dev/null +++ b/sluv-api/build.gradle @@ -0,0 +1,30 @@ +plugins { + id 'java' +} + +group 'com.sluv' +version 'unspecified' + +bootJar.enabled = true + +jar.enabled = false + +dependencies { + + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-security' + + //swagger + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.3' + + testImplementation 'org.springframework.security:spring-security-test' + + implementation project(':sluv-domain') + implementation project(':sluv-common') + implementation project(':sluv-infra') + +} + +//tasks.named('test') { +// dependsOn ':sluv-domain:test', ':sluv-common:test', ':sluv-infra:test' +//} diff --git a/sluv-api/src/.DS_Store b/sluv-api/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..773c82515fd410e7c768c8ce4687bf2f90163fff GIT binary patch literal 6148 zcmeHK%}T>S5Z-O0O({YS3Oz1(Etpm*6fYsx7cim+m70*E!8BW%)E-J9XMG``#OHBl zcOw?-Rm9G~?l-@?*$=Wmj4|%d<1S+kW6Xwz$WhrK=-wErnPfzcV?>L58l^G<`_07u zI^efkY{Ej8u;|n%DbuLZ!{{m* zFGkM(naqkX$;LBPki=t1xxG%ZST1}y&*EIw20CCj?dHg7FPFVRzaviE?y4h}gPsfe zaeuXH+6RY6rx&BAbdt#zO(+MxmFyX;;1!h5^*jf&ES1><_^SLWkB}H328aP-V0#%b zXM)|@UJ7XC!~iky0|U4}2xy3&!BV5zI-tYrGsZ1M6wvW4fhY`m21|_)0pYq7P?vJ^ z#NfId{KDjU21|{)oN+ZXjALf59xq(Y4t}B18TT|&PYe(P>kQPj>EQW)4!_LCNB(*V zS;PP_@Xr|F)-V|Quqbo3ep?=%wF25bG!)D$Q2_yc?GgY6?jvm#)Nz42S5Z-O8-B5%c6nYGJEtpm*6fYsx7cim+mD-q~!I&*gYYwH5v%Zi|;`2DO zyAew(coMNQF#FBUPnP{Q>U$0C*m z`ARl9{vrdob{4D}tQnK+%lc*GAdvw?--2-xXH&;{=ap)0Yr8J$q9Jbl2bufR(R7x1 zqsbNa&ZSI((jEmDag-06yC*W8j^Z?$sDe0*Am#cpPD7b{a+Zdfs`Yh1Si%}MTl0Ch z-)q}PPG`}!=l!k&_F-?au*BZ}!SUJfF?mYmi>8yqpQmKUUjr-b1vk zEGr0!0b+m{*c1lL{wErnGGUr0F+dFbm;u}$Y*0kkV4+cM9nj$Q5#u#P6tM9vfoL0a z4Hg<90>X7Epf2U+iNSR__-&Kt8Z0#Ga>muj@EtQUH!l>fMhCyG(iwL(QcDaF1Ir9l zb+?J<|LOPd|K%d;5d*})zhZ#b2L8Z> getUserTokenByAdmin( + @RequestBody AdminUserTokenRequest request) { + + AdminUserTokenResponse response = adminService.getUserTokenByAdmin(request); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @PostMapping("") + public ResponseEntity> saveAdmin(@RequestBody AdminRequest request) { + AdminResponse response = adminService.getAdminData(request); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + +} diff --git a/src/main/java/com/sluv/server/domain/admin/dto/AdminReqDto.java b/sluv-api/src/main/java/com/sluv/api/admin/dto/request/AdminRequest.java similarity index 76% rename from src/main/java/com/sluv/server/domain/admin/dto/AdminReqDto.java rename to sluv-api/src/main/java/com/sluv/api/admin/dto/request/AdminRequest.java index 9d3e8bfe..e95c0ae3 100644 --- a/src/main/java/com/sluv/server/domain/admin/dto/AdminReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/admin/dto/request/AdminRequest.java @@ -1,10 +1,10 @@ -package com.sluv.server.domain.admin.dto; +package com.sluv.api.admin.dto.request; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data -public class AdminReqDto { +public class AdminRequest { @Schema(description = "Admin 이메일") private String email; @Schema(description = "Admin 비밀번호") diff --git a/src/main/java/com/sluv/server/domain/admin/dto/AdminUserTokenReqDto.java b/sluv-api/src/main/java/com/sluv/api/admin/dto/request/AdminUserTokenRequest.java similarity index 80% rename from src/main/java/com/sluv/server/domain/admin/dto/AdminUserTokenReqDto.java rename to sluv-api/src/main/java/com/sluv/api/admin/dto/request/AdminUserTokenRequest.java index b0987d97..8812c996 100644 --- a/src/main/java/com/sluv/server/domain/admin/dto/AdminUserTokenReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/admin/dto/request/AdminUserTokenRequest.java @@ -1,10 +1,10 @@ -package com.sluv.server.domain.admin.dto; +package com.sluv.api.admin.dto.request; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data -public class AdminUserTokenReqDto { +public class AdminUserTokenRequest { @Schema(description = "Admin 이메일") private String email; @Schema(description = "Admin 비밀번호") diff --git a/src/main/java/com/sluv/server/domain/admin/dto/AdminResDto.java b/sluv-api/src/main/java/com/sluv/api/admin/dto/response/AdminResponse.java similarity index 60% rename from src/main/java/com/sluv/server/domain/admin/dto/AdminResDto.java rename to sluv-api/src/main/java/com/sluv/api/admin/dto/response/AdminResponse.java index 0ed53b87..8a68cbe2 100644 --- a/src/main/java/com/sluv/server/domain/admin/dto/AdminResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/admin/dto/response/AdminResponse.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.admin.dto; +package com.sluv.api.admin.dto.response; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; @@ -6,13 +6,13 @@ @Data @AllArgsConstructor -public class AdminResDto { +public class AdminResponse { @Schema(description = "Admin 이메일") private String email; @Schema(description = "Encodeing 된 Admin 비밀번호") private String encodesPassword; - public static AdminResDto of(String email, String encodedPassword) { - return new AdminResDto(email, encodedPassword); + public static AdminResponse of(String email, String encodedPassword) { + return new AdminResponse(email, encodedPassword); } } diff --git a/src/main/java/com/sluv/server/domain/admin/dto/AdminUserTokenResDto.java b/sluv-api/src/main/java/com/sluv/api/admin/dto/response/AdminUserTokenResponse.java similarity index 58% rename from src/main/java/com/sluv/server/domain/admin/dto/AdminUserTokenResDto.java rename to sluv-api/src/main/java/com/sluv/api/admin/dto/response/AdminUserTokenResponse.java index 7eb86d47..a99c05ba 100644 --- a/src/main/java/com/sluv/server/domain/admin/dto/AdminUserTokenResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/admin/dto/response/AdminUserTokenResponse.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.admin.dto; +package com.sluv.api.admin.dto.response; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; @@ -8,11 +8,11 @@ @Data @NoArgsConstructor @AllArgsConstructor -public class AdminUserTokenResDto { +public class AdminUserTokenResponse { @Schema(description = "유저 엑세스 토큰") private String token; - public static AdminUserTokenResDto from(String token) { - return new AdminUserTokenResDto(token); + public static AdminUserTokenResponse from(String token) { + return new AdminUserTokenResponse(token); } } diff --git a/sluv-api/src/main/java/com/sluv/api/admin/service/AdminService.java b/sluv-api/src/main/java/com/sluv/api/admin/service/AdminService.java new file mode 100644 index 00000000..7a4b78d5 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/admin/service/AdminService.java @@ -0,0 +1,30 @@ +package com.sluv.api.admin.service; + +import com.sluv.api.admin.dto.request.AdminRequest; +import com.sluv.api.admin.dto.request.AdminUserTokenRequest; +import com.sluv.api.admin.dto.response.AdminResponse; +import com.sluv.api.admin.dto.response.AdminUserTokenResponse; +import com.sluv.api.common.utils.PasswordEncoderUtil; +import com.sluv.domain.admin.service.AdminDomainService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class AdminService { + + private final AdminDomainService adminDomainService; + + public AdminUserTokenResponse getUserTokenByAdmin(AdminUserTokenRequest request) { + String dbPassword = adminDomainService.getAdminPasswordByEmail(request.getEmail()); + boolean isMatched = PasswordEncoderUtil.matches(request.getPassword(), dbPassword); + String accessToken = adminDomainService.getUserTokenByAdmin(isMatched, request.getUserId()); + return AdminUserTokenResponse.from(accessToken); + } + + public AdminResponse getAdminData(AdminRequest request) { + String encodedPassword = PasswordEncoderUtil.encodePassword(request.getPassword()); + return AdminResponse.of(request.getEmail(), encodedPassword); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/alarm/controller/AlarmController.java b/sluv-api/src/main/java/com/sluv/api/alarm/controller/AlarmController.java new file mode 100644 index 00000000..cf0cd7ba --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/alarm/controller/AlarmController.java @@ -0,0 +1,49 @@ +package com.sluv.api.alarm.controller; + +import com.sluv.api.alarm.dto.AlarmResponse; +import com.sluv.api.alarm.service.AlarmService; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.common.annotation.CurrentUserId; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RequestMapping("/app/alarm") +@RestController +@RequiredArgsConstructor +public class AlarmController { + + private final AlarmService alarmService; + + @GetMapping("") + public ResponseEntity>> getAlarms( + @CurrentUserId Long userId, Pageable pageable) { + PaginationResponse response = alarmService.getAlarmsByUserId(userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @PatchMapping("/read") + public ResponseEntity pathAlarmStatusToRead(@CurrentUserId Long userId, + @RequestParam Long alarmId) { + alarmService.patchAlarmStatusToRead(userId, alarmId); + + return ResponseEntity.ok().body(SuccessResponse.create()); + } + + @DeleteMapping("/{alarmId}") + public ResponseEntity deleteAlarm(@CurrentUserId Long userId, + @PathVariable("alarmId") Long alarmId) { + alarmService.deleteAlarm(userId, alarmId); + return ResponseEntity.ok().body(SuccessResponse.create()); + } + + @DeleteMapping("/all") + public ResponseEntity deleteAllAlarm(@CurrentUserId Long userId) { + alarmService.deleteAllAlarm(userId); + return ResponseEntity.ok().body(SuccessResponse.create()); + } + +} diff --git a/src/main/java/com/sluv/server/domain/alarm/dto/AlarmResponse.java b/sluv-api/src/main/java/com/sluv/api/alarm/dto/AlarmResponse.java similarity index 85% rename from src/main/java/com/sluv/server/domain/alarm/dto/AlarmResponse.java rename to sluv-api/src/main/java/com/sluv/api/alarm/dto/AlarmResponse.java index b42edbfc..a314a020 100644 --- a/src/main/java/com/sluv/server/domain/alarm/dto/AlarmResponse.java +++ b/sluv-api/src/main/java/com/sluv/api/alarm/dto/AlarmResponse.java @@ -1,15 +1,17 @@ -package com.sluv.server.domain.alarm.dto; +package com.sluv.api.alarm.dto; -import com.sluv.server.domain.alarm.entity.Alarm; -import com.sluv.server.domain.alarm.enums.AlarmStatus; -import com.sluv.server.domain.question.dto.QuestionImgSimpleResDto; -import java.time.LocalDateTime; -import java.util.List; +import com.sluv.domain.alarm.dto.AlarmImages; +import com.sluv.domain.alarm.entity.Alarm; +import com.sluv.domain.alarm.enums.AlarmStatus; +import com.sluv.domain.question.dto.QuestionImgSimpleDto; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import java.time.LocalDateTime; +import java.util.List; + @Data @Builder @NoArgsConstructor @@ -25,7 +27,7 @@ public class AlarmResponse { private Long commentId; private Long followerId; - private List images; + private List images; private String userImageUrl; diff --git a/sluv-api/src/main/java/com/sluv/api/alarm/service/AlarmService.java b/sluv-api/src/main/java/com/sluv/api/alarm/service/AlarmService.java new file mode 100644 index 00000000..569f009c --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/alarm/service/AlarmService.java @@ -0,0 +1,73 @@ +package com.sluv.api.alarm.service; + +import com.sluv.api.alarm.dto.AlarmResponse; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.domain.alarm.dto.AlarmImages; +import com.sluv.domain.alarm.entity.Alarm; +import com.sluv.domain.alarm.service.AlarmDomainService; +import com.sluv.domain.item.entity.ItemImg; +import com.sluv.domain.item.service.ItemImgDomainService; +import com.sluv.domain.question.dto.QuestionImgSimpleDto; +import com.sluv.domain.question.service.QuestionImgDomainService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class AlarmService { + + private final AlarmDomainService alarmDomainService; + private final ItemImgDomainService itemImgDomainService; + private final QuestionImgDomainService questionImgDomainService; + + + public PaginationResponse getAlarmsByUserId(Long userId, Pageable pageable) { + Page alarmPage = alarmDomainService.findAllByUserId(userId, pageable); + List content = alarmPage.stream() + .map(alarm -> AlarmResponse.of(alarm, getAlarmImages(alarm))) + .toList(); + return PaginationResponse.create(alarmPage, content); + } + + private AlarmImages getAlarmImages(Alarm alarm) { + List images = new ArrayList<>(); + String useImageUrl = null; + + if (alarm.getSender() != null) { + useImageUrl = alarm.getSender().getProfileImgUrl(); + } + + if (alarm.getItem() != null) { + ItemImg mainImg = itemImgDomainService.findMainImg(alarm.getItem().getId()); + images.add(QuestionImgSimpleDto.of(mainImg)); + } + + if (alarm.getQuestion() != null) { + images = questionImgDomainService.findAllByQuestionId(alarm.getQuestion().getId()) + .stream() + .map(QuestionImgSimpleDto::of) + .toList(); + } + + return AlarmImages.of(images, useImageUrl); + } + + public void patchAlarmStatusToRead(Long userId, Long alarmId) { + alarmDomainService.patchAlarmStatusToRead(userId, alarmId); + } + + public void deleteAlarm(Long userId, Long alarmId) { + alarmDomainService.deleteAlarm(userId, alarmId); + } + + + public void deleteAllAlarm(Long useId) { + alarmDomainService.deleteAllAlarm(useId); + } + +} diff --git a/src/main/java/com/sluv/server/domain/alarm/service/CommentAlarmService.java b/sluv-api/src/main/java/com/sluv/api/alarm/service/CommentAlarmService.java similarity index 56% rename from src/main/java/com/sluv/server/domain/alarm/service/CommentAlarmService.java rename to sluv-api/src/main/java/com/sluv/api/alarm/service/CommentAlarmService.java index 891a2fa1..68f16a9a 100644 --- a/src/main/java/com/sluv/server/domain/alarm/service/CommentAlarmService.java +++ b/sluv-api/src/main/java/com/sluv/api/alarm/service/CommentAlarmService.java @@ -1,65 +1,68 @@ -package com.sluv.server.domain.alarm.service; +package com.sluv.api.alarm.service; -import com.sluv.server.domain.alarm.dto.AlarmElement; -import com.sluv.server.domain.alarm.enums.AlarmMessage; -import com.sluv.server.domain.alarm.enums.AlarmType; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.exception.CommentNotFoundException; -import com.sluv.server.domain.comment.repository.CommentRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.firebase.FcmNotificationService; -import java.util.HashMap; +import com.sluv.domain.alarm.dto.AlarmElement; +import com.sluv.domain.alarm.enums.AlarmMessage; +import com.sluv.domain.alarm.enums.AlarmType; +import com.sluv.domain.alarm.service.AlarmDomainService; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.service.CommentDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import com.sluv.infra.firebase.FcmNotificationService; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; + +import static com.sluv.common.constant.ConstantData.ALARM_TITLE; @Service +@Transactional @RequiredArgsConstructor public class CommentAlarmService { - private final FcmNotificationService fcmNotificationService; - private final UserRepository userRepository; - private final CommentRepository commentRepository; - private final AlarmService alarmService; + private final AlarmDomainService alarmDomainService; + private final UserDomainService userDomainService; + private final CommentDomainService commentDomainService; - private static final String ALARM_TITLE = "[스럽]"; + private final FcmNotificationService fcmNotificationService; @Async("alarmThreadPoolExecutor") public void sendAlarmAboutCommentLike(Long userId, Long commentId) { - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - Comment comment = commentRepository.findById(commentId).orElseThrow(CommentNotFoundException::new); + User user = userDomainService.findById(userId); + Comment comment = commentDomainService.findById(commentId); String message = AlarmMessage.getMessageWithUserName(user.getNickname(), AlarmMessage.COMMENT_LIKE); sendMessageTypeComment(comment.getUser().getId(), comment, message, user); } @Async("alarmThreadPoolExecutor") public void sendAlarmAboutComment(Long userId, Long commentId, User sender) { - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - Comment comment = commentRepository.findById(commentId).orElseThrow(CommentNotFoundException::new); + User user = userDomainService.findById(userId); + Comment comment = commentDomainService.findById(commentId); String message = AlarmMessage.getMessageWithUserName(user.getNickname(), AlarmMessage.QUESTION_COMMENT); sendMessageTypeComment(comment.getQuestion().getUser().getId(), comment, message, sender); } @Async("alarmThreadPoolExecutor") public void sendAlarmAboutSubComment(Long userId, Long commentId, User sender) { - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - Comment comment = commentRepository.findById(commentId).orElseThrow(CommentNotFoundException::new); + User user = userDomainService.findById(userId); + Comment comment = commentDomainService.findById(commentId); String message = AlarmMessage.getMessageWithUserName(user.getNickname(), AlarmMessage.COMMENT_SUB); sendMessageTypeComment(comment.getUser().getId(), comment, message, sender); } @Async("alarmThreadPoolExecutor") public void sendAlarmAboutReportByAI(Long commentId, User sender) { - Comment comment = commentRepository.findById(commentId).orElseThrow(CommentNotFoundException::new); + Comment comment = commentDomainService.findById(commentId); String message = AlarmMessage.COMMENT_REPORT_BY_AI.getMessage(); sendMessageTypeComment(comment.getUser().getId(), comment, message, sender); } private void sendMessageTypeComment(Long receiverId, Comment comment, String message, User sender) { AlarmElement alarmElement = AlarmElement.of(null, comment.getQuestion(), comment, sender); - alarmService.saveAlarm(comment.getUser(), ALARM_TITLE, message, AlarmType.COMMENT, alarmElement); + alarmDomainService.saveAlarm(comment.getUser(), ALARM_TITLE, message, AlarmType.COMMENT, alarmElement); fcmNotificationService.sendFCMNotification( receiverId, ALARM_TITLE, message, AlarmType.COMMENT, getIdsAboutComment(comment) ); diff --git a/src/main/java/com/sluv/server/domain/alarm/service/ItemAlarmService.java b/sluv-api/src/main/java/com/sluv/api/alarm/service/ItemAlarmService.java similarity index 59% rename from src/main/java/com/sluv/server/domain/alarm/service/ItemAlarmService.java rename to sluv-api/src/main/java/com/sluv/api/alarm/service/ItemAlarmService.java index d0cff1e0..42f919ba 100644 --- a/src/main/java/com/sluv/server/domain/alarm/service/ItemAlarmService.java +++ b/sluv-api/src/main/java/com/sluv/api/alarm/service/ItemAlarmService.java @@ -1,55 +1,60 @@ -package com.sluv.server.domain.alarm.service; - -import com.sluv.server.domain.alarm.dto.AlarmElement; -import com.sluv.server.domain.alarm.enums.AlarmMessage; -import com.sluv.server.domain.alarm.enums.AlarmType; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.exception.ItemNotFoundException; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.user.entity.Follow; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.repository.FollowRepository; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.firebase.FcmNotificationService; -import java.util.HashMap; -import java.util.List; +package com.sluv.api.alarm.service; + +import com.sluv.domain.alarm.dto.AlarmElement; +import com.sluv.domain.alarm.enums.AlarmMessage; +import com.sluv.domain.alarm.enums.AlarmType; +import com.sluv.domain.alarm.service.AlarmDomainService; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.service.ItemDomainService; +import com.sluv.domain.user.entity.Follow; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.FollowDomainService; +import com.sluv.domain.user.service.UserDomainService; +import com.sluv.infra.firebase.FcmNotificationService; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; + +import static com.sluv.common.constant.ConstantData.ALARM_TITLE; @Service +@Transactional @RequiredArgsConstructor public class ItemAlarmService { - private final FcmNotificationService fcmNotificationService; - private final UserRepository userRepository; - private final ItemRepository itemRepository; - private final FollowRepository followRepository; - private final AlarmService alarmService; + private final AlarmDomainService alarmDomainService; + private final UserDomainService userDomainService; + private final ItemDomainService itemDomainService; + private final FollowDomainService followDomainService; - private static final String ALARM_TITLE = "[스럽]"; + private final FcmNotificationService fcmNotificationService; @Async("alarmThreadPoolExecutor") public void sendAlarmAboutItemLike(Long userId, Long itemId) { - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - Item item = itemRepository.findById(itemId).orElseThrow(ItemNotFoundException::new); + User user = userDomainService.findById(userId); + Item item = itemDomainService.findById(itemId); String message = AlarmMessage.getMessageWithUserName(user.getNickname(), AlarmMessage.ITEM_LIKE); sendMessageTypeItem(user, item, message, user); } @Async("alarmThreadPoolExecutor") public void sendAlarmAboutItemEdit(Long itemId, Long itemEditReqId, User sender) { - Item item = itemRepository.findById(itemId).orElseThrow(ItemNotFoundException::new); + Item item = itemDomainService.findById(itemId); String message = AlarmMessage.ITEM_EDIT.getMessage(); sendMessageTypeItemEdit(itemEditReqId, item, message, sender); } @Async("alarmThreadPoolExecutor") public void sendAlarmAboutFollowItem(Long userId, Long itemId) { - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - Item item = itemRepository.findById(itemId).orElseThrow(ItemNotFoundException::new); - List follower = followRepository.getAllFollower(userId).stream().map(Follow::getFollower) + User user = userDomainService.findById(userId); + Item item = itemDomainService.findById(itemId); + List follower = followDomainService.getAllFollower(userId) + .stream() + .map(Follow::getFollower) .toList(); String message = AlarmMessage.getMessageWithUserName(user.getNickname(), AlarmMessage.USER_FOLLOW_ITEM); @@ -58,7 +63,7 @@ public void sendAlarmAboutFollowItem(Long userId, Long itemId) { private void sendMessageTypeItem(User user, Item item, String message, User sender) { AlarmElement alarmElement = AlarmElement.of(item, null, null, sender); - alarmService.saveAlarm(user, ALARM_TITLE, message, AlarmType.ITEM, alarmElement); + alarmDomainService.saveAlarm(user, ALARM_TITLE, message, AlarmType.ITEM, alarmElement); fcmNotificationService.sendFCMNotification( item.getUser().getId(), ALARM_TITLE, message, AlarmType.ITEM, getIdAboutItem(item.getId()) ); @@ -72,7 +77,7 @@ private void sendMulticastMessageTypeItem(List follower, Item item, String .toList(); AlarmElement alarmElement = AlarmElement.of(item, null, null, sender); - alarmService.saveAllAlarm(follower, ALARM_TITLE, message, AlarmType.ITEM, alarmElement); + alarmDomainService.saveAllAlarm(follower, ALARM_TITLE, message, AlarmType.ITEM, alarmElement); fcmNotificationService.sendFCMNotificationMulticast( followerIds, ALARM_TITLE, message, AlarmType.ITEM, getIdAboutItem(item.getId()) ); @@ -80,7 +85,7 @@ followerIds, ALARM_TITLE, message, AlarmType.ITEM, getIdAboutItem(item.getId()) private void sendMessageTypeItemEdit(Long itemEditReqId, Item item, String message, User sender) { AlarmElement alarmElement = AlarmElement.of(item, null, null, sender); - alarmService.saveAlarm(item.getUser(), ALARM_TITLE, message, AlarmType.EDIT, alarmElement); + alarmDomainService.saveAlarm(item.getUser(), ALARM_TITLE, message, AlarmType.EDIT, alarmElement); fcmNotificationService.sendFCMNotification( item.getUser().getId(), ALARM_TITLE, message, AlarmType.EDIT, getIdAboutItemEdit(itemEditReqId) ); diff --git a/src/main/java/com/sluv/server/domain/alarm/service/QuestionAlarmService.java b/sluv-api/src/main/java/com/sluv/api/alarm/service/QuestionAlarmService.java similarity index 54% rename from src/main/java/com/sluv/server/domain/alarm/service/QuestionAlarmService.java rename to sluv-api/src/main/java/com/sluv/api/alarm/service/QuestionAlarmService.java index 252702d1..01dedc35 100644 --- a/src/main/java/com/sluv/server/domain/alarm/service/QuestionAlarmService.java +++ b/sluv-api/src/main/java/com/sluv/api/alarm/service/QuestionAlarmService.java @@ -1,42 +1,45 @@ -package com.sluv.server.domain.alarm.service; - -import com.sluv.server.domain.alarm.dto.AlarmElement; -import com.sluv.server.domain.alarm.enums.AlarmMessage; -import com.sluv.server.domain.alarm.enums.AlarmType; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.exception.QuestionNotFoundException; -import com.sluv.server.domain.question.repository.QuestionRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.firebase.FcmNotificationService; -import java.util.HashMap; +package com.sluv.api.alarm.service; + +import com.sluv.domain.alarm.dto.AlarmElement; +import com.sluv.domain.alarm.enums.AlarmMessage; +import com.sluv.domain.alarm.enums.AlarmType; +import com.sluv.domain.alarm.service.AlarmDomainService; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.service.QuestionDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import com.sluv.infra.firebase.FcmNotificationService; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; + +import static com.sluv.common.constant.ConstantData.ALARM_TITLE; @Service +@Transactional @RequiredArgsConstructor public class QuestionAlarmService { - private final FcmNotificationService fcmNotificationService; - private final UserRepository userRepository; - private final QuestionRepository questionRepository; - private final AlarmService alarmService; + private final AlarmDomainService alarmDomainService; + private final UserDomainService userDomainService; + private final QuestionDomainService questionDomainService; - private static final String ALARM_TITLE = "[스럽]"; + private final FcmNotificationService fcmNotificationService; @Async("alarmThreadPoolExecutor") public void sendAlarmAboutQuestionLike(Long userId, Long questionId) { - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - Question question = questionRepository.findById(questionId).orElseThrow(QuestionNotFoundException::new); + User user = userDomainService.findById(userId); + Question question = questionDomainService.findById(questionId); String message = AlarmMessage.getMessageWithUserName(user.getNickname(), AlarmMessage.QUESTION_LIKE); sendMessageTypeQuestion(user, question, message, user, AlarmType.QUESTION); } private void sendMessageTypeQuestion(User user, Question question, String message, User sender, AlarmType type) { AlarmElement alarmElement = AlarmElement.of(null, question, null, sender); - alarmService.saveAlarm(user, ALARM_TITLE, message, type, alarmElement); + alarmDomainService.saveAlarm(user, ALARM_TITLE, message, type, alarmElement); fcmNotificationService.sendFCMNotification( question.getUser().getId(), ALARM_TITLE, message, type, getIdAboutQuestion(question.getId()) @@ -51,7 +54,7 @@ private HashMap getIdAboutQuestion(Long questionId) { @Async("alarmThreadPoolExecutor") public void sendAlarmAboutQuestionVote(Long questionId) { - Question question = questionRepository.findById(questionId).orElseThrow(QuestionNotFoundException::new); + Question question = questionDomainService.findById(questionId); String message = AlarmMessage.QUESTION_VOTE.getMessage(); sendMessageTypeQuestion(question.getUser(), question, message, null, AlarmType.VOTE); } diff --git a/src/main/java/com/sluv/server/domain/alarm/service/UserAlarmService.java b/sluv-api/src/main/java/com/sluv/api/alarm/service/UserAlarmService.java similarity index 55% rename from src/main/java/com/sluv/server/domain/alarm/service/UserAlarmService.java rename to sluv-api/src/main/java/com/sluv/api/alarm/service/UserAlarmService.java index 96dbefce..299b9088 100644 --- a/src/main/java/com/sluv/server/domain/alarm/service/UserAlarmService.java +++ b/sluv-api/src/main/java/com/sluv/api/alarm/service/UserAlarmService.java @@ -1,31 +1,35 @@ -package com.sluv.server.domain.alarm.service; - -import com.sluv.server.domain.alarm.dto.AlarmElement; -import com.sluv.server.domain.alarm.enums.AlarmMessage; -import com.sluv.server.domain.alarm.enums.AlarmType; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.firebase.FcmNotificationService; -import java.util.HashMap; +package com.sluv.api.alarm.service; + +import com.sluv.domain.alarm.dto.AlarmElement; +import com.sluv.domain.alarm.enums.AlarmMessage; +import com.sluv.domain.alarm.enums.AlarmType; +import com.sluv.domain.alarm.service.AlarmDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import com.sluv.infra.firebase.FcmNotificationService; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; + +import static com.sluv.common.constant.ConstantData.ALARM_TITLE; @Service +@Transactional @RequiredArgsConstructor public class UserAlarmService { - private final FcmNotificationService fcmNotificationService; - private final UserRepository userRepository; - private final AlarmService alarmService; + private final AlarmDomainService alarmDomainService; + private final UserDomainService userDomainService; - private static final String ALARM_TITLE = "[스럽]"; + private final FcmNotificationService fcmNotificationService; @Async("alarmThreadPoolExecutor") public void sendAlarmAboutFollow(Long userId, Long targetUserId) { - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - User targetUser = userRepository.findById(targetUserId).orElseThrow(UserNotFoundException::new); + User user = userDomainService.findById(userId); + User targetUser = userDomainService.findById(targetUserId); String message = AlarmMessage.getMessageWithUserName(user.getNickname(), AlarmMessage.USER_FOLLOW); sendMessageTypeUser(user, targetUser, message); @@ -33,7 +37,7 @@ public void sendAlarmAboutFollow(Long userId, Long targetUserId) { private void sendMessageTypeUser(User sender, User targetUser, String message) { AlarmElement alarmElement = AlarmElement.of(null, null, null, sender); - alarmService.saveAlarm(targetUser, ALARM_TITLE, message, AlarmType.QUESTION, alarmElement); + alarmDomainService.saveAlarm(targetUser, ALARM_TITLE, message, AlarmType.QUESTION, alarmElement); fcmNotificationService.sendFCMNotification( targetUser.getId(), ALARM_TITLE, message, AlarmType.USER, getIdAboutUser(sender.getId()) ); diff --git a/sluv-api/src/main/java/com/sluv/api/auth/controller/AuthController.java b/sluv-api/src/main/java/com/sluv/api/auth/controller/AuthController.java new file mode 100644 index 00000000..728654ce --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/auth/controller/AuthController.java @@ -0,0 +1,72 @@ +package com.sluv.api.auth.controller; + +import com.sluv.api.auth.dto.request.AuthRequest; +import com.sluv.api.auth.dto.request.AutoLoginRequest; +import com.sluv.api.auth.dto.response.AuthResponse; +import com.sluv.api.auth.dto.response.AutoLoginResponse; +import com.sluv.api.auth.service.AppleUserService; +import com.sluv.api.auth.service.AuthService; +import com.sluv.api.auth.service.GoogleUserService; +import com.sluv.api.auth.service.KakaoUserService; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.common.annotation.CurrentUserId; +import com.sluv.domain.auth.enums.SnsType; +import com.sluv.domain.user.entity.User; +import com.sluv.infra.cache.CacheService; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/app/auth") +@RequiredArgsConstructor +public class AuthController { + + private final KakaoUserService kakaoUserService; + private final GoogleUserService googleUserService; + private final AppleUserService appleUserService; + private final AuthService authService; + private final CacheService cacheService; + ; + + + @Operation(summary = "소셜 로그인", description = "KAKAO:[AccessToken], GOOGLE, APPLE: [IdToken]") + @PostMapping("/social-login") + public ResponseEntity> socialLogin(@RequestBody AuthRequest request) + throws Exception { + User loginUser = null; + + SnsType userSnsType = SnsType.fromString(request.getSnsType()); + switch (userSnsType) { + case KAKAO -> loginUser = kakaoUserService.kakaoLogin(request); + case GOOGLE -> loginUser = googleUserService.googleLogin(request); + case APPLE -> loginUser = appleUserService.appleLogin(request); + } + + cacheService.visitMember(loginUser.getId()); + + AuthResponse response = authService.getAuthResDto(loginUser); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*자동 로그인", description = "토큰 만료 시 error code : 4002") + @GetMapping("/auto-login") + public ResponseEntity> autoLogin(@CurrentUserId Long userId) { + cacheService.visitMember(userId); + User user = authService.findLogInUser(userId); +// authService.checkFcm(user); + AutoLoginResponse response = AutoLoginResponse.of(user); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*FCM 토큰 갱신", description = "FCM 토큰을 갱신") + @PostMapping("/fcm") + public ResponseEntity changeFcm(@CurrentUserId Long userId, + @RequestBody AutoLoginRequest dto) { + authService.changeFcm(userId, dto.getFcm()); + return ResponseEntity.ok().body(SuccessResponse.create()); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/auth/dto/MemberDetails.java b/sluv-api/src/main/java/com/sluv/api/auth/dto/MemberDetails.java new file mode 100644 index 00000000..b473d85d --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/auth/dto/MemberDetails.java @@ -0,0 +1,51 @@ +package com.sluv.api.auth.dto; + +import java.util.Collection; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class MemberDetails implements UserDetails { + + private Long memberId; + + @Override + public boolean isAccountNonExpired() { + return false; + } + + @Override + public boolean isAccountNonLocked() { + return false; + } + + @Override + public boolean isCredentialsNonExpired() { + return false; + } + + @Override + public boolean isEnabled() { + return false; + } + + @Override + public Collection getAuthorities() { + return null; + } + + @Override + public String getPassword() { + return null; + } + + @Override + public String getUsername() { + return this.memberId.toString(); + } +} diff --git a/src/main/java/com/sluv/server/domain/auth/dto/AuthRequestDto.java b/sluv-api/src/main/java/com/sluv/api/auth/dto/request/AuthRequest.java similarity index 70% rename from src/main/java/com/sluv/server/domain/auth/dto/AuthRequestDto.java rename to sluv-api/src/main/java/com/sluv/api/auth/dto/request/AuthRequest.java index 5dd0d226..3c47b993 100644 --- a/src/main/java/com/sluv/server/domain/auth/dto/AuthRequestDto.java +++ b/sluv-api/src/main/java/com/sluv/api/auth/dto/request/AuthRequest.java @@ -1,11 +1,13 @@ -package com.sluv.server.domain.auth.dto; +package com.sluv.api.auth.dto.request; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; import org.springframework.lang.Nullable; -@Data -public class AuthRequestDto { +@Getter +@NoArgsConstructor +public class AuthRequest { @Schema(description = "소셜에서 발급한 AccessToken") private String accessToken; @Schema(description = "SNS 타입 이름") diff --git a/sluv-api/src/main/java/com/sluv/api/auth/dto/request/AutoLoginRequest.java b/sluv-api/src/main/java/com/sluv/api/auth/dto/request/AutoLoginRequest.java new file mode 100644 index 00000000..674639ec --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/auth/dto/request/AutoLoginRequest.java @@ -0,0 +1,13 @@ +package com.sluv.api.auth.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class AutoLoginRequest { + + @Schema(description = "FCM 토큰") + private String fcm; +} diff --git a/sluv-api/src/main/java/com/sluv/api/auth/dto/response/AuthResponse.java b/sluv-api/src/main/java/com/sluv/api/auth/dto/response/AuthResponse.java new file mode 100644 index 00000000..fba0261f --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/auth/dto/response/AuthResponse.java @@ -0,0 +1,30 @@ +package com.sluv.api.auth.dto.response; + +import com.sluv.domain.user.enums.UserStatus; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Schema(description = "유저토큰 응답") +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Builder +public class AuthResponse { + + @Schema(description = "유저 엑세스 토큰") + private String token; + @Schema(description = "유저 Status") + private UserStatus userStatus; + + public static AuthResponse of(String token, UserStatus status) { + return AuthResponse.builder() + .token(token) + .userStatus(status) + .build(); + } + +} diff --git a/src/main/java/com/sluv/server/domain/auth/dto/AutoLoginResponseDto.java b/sluv-api/src/main/java/com/sluv/api/auth/dto/response/AutoLoginResponse.java similarity index 60% rename from src/main/java/com/sluv/server/domain/auth/dto/AutoLoginResponseDto.java rename to sluv-api/src/main/java/com/sluv/api/auth/dto/response/AutoLoginResponse.java index 021696db..7bc15640 100644 --- a/src/main/java/com/sluv/server/domain/auth/dto/AutoLoginResponseDto.java +++ b/sluv-api/src/main/java/com/sluv/api/auth/dto/response/AutoLoginResponse.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.auth.dto; +package com.sluv.api.auth.dto.response; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.enums.UserStatus; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.enums.UserStatus; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -13,12 +13,12 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class AutoLoginResponseDto { +public class AutoLoginResponse { @Schema(description = "유저 Status") private UserStatus userStatus; - public static AutoLoginResponseDto of(User user) { - return AutoLoginResponseDto.builder() + public static AutoLoginResponse of(User user) { + return AutoLoginResponse.builder() .userStatus(user.getUserStatus()) .build(); } diff --git a/sluv-api/src/main/java/com/sluv/api/auth/service/AppleUserService.java b/sluv-api/src/main/java/com/sluv/api/auth/service/AppleUserService.java new file mode 100644 index 00000000..49a91553 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/auth/service/AppleUserService.java @@ -0,0 +1,116 @@ +package com.sluv.api.auth.service; + +import static com.sluv.domain.auth.enums.SnsType.APPLE; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.sluv.api.auth.dto.request.AuthRequest; +import com.sluv.common.jwt.exception.InvalidateTokenException; +import com.sluv.domain.auth.dto.SocialUserInfoDto; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.enums.UserAge; +import com.sluv.domain.user.enums.UserGender; +import com.sluv.infra.oauth.apple.ApplePlatformClient; +import java.util.Base64; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + + +@Service +@RequiredArgsConstructor +public class AppleUserService { + + private final AuthService authService; + private final ApplePlatformClient applePlatformClient; + + private final ObjectMapper objectMapper = new ObjectMapper(); + + public User appleLogin(AuthRequest request) throws Exception { + String identityToken = request.getAccessToken(); + + // 1. 검증 + if (!applePlatformClient.verifyIdToken(identityToken)) { + throw new InvalidateTokenException(); + } + + // 2. UserIngoDto 생성 + SocialUserInfoDto userInfo = getAppleUserInfo(identityToken); + + // 3. idToken의 정보로 DB 탐색 및 등록 + return authService.getOrCreateUser(userInfo, APPLE, request.getFcm()); + } + + /** + * identityToken의 정보 SocialUserDto로 변환 + * + * @param identityToken + * @return SocialUserInfoDto + * @throws JsonProcessingException + */ + + private SocialUserInfoDto getAppleUserInfo(String identityToken) throws JsonProcessingException { + String[] pieces = identityToken.split("\\."); + String payload = new String(Base64.getUrlDecoder().decode(pieces[1])); + + JsonNode jsonNode = objectMapper.readTree(payload); + + String email = jsonNode.get("email").asText(); + + String profileImgUrl; + try { + profileImgUrl = jsonNode.get("picture").asText(); + } catch (Exception e) { + profileImgUrl = null; + } + + String gender; + + try { + gender = jsonNode.get("gender").asText(); + } catch (Exception e) { + gender = null; + } + + String ageRange; + try { + ageRange = jsonNode.get("birthdate").asText(); + } catch (Exception e) { + ageRange = null; + } + + return SocialUserInfoDto.builder() + .email(email) + .profileImgUrl(profileImgUrl) + .gender(convertGender(gender)) + .ageRange(convertAge(ageRange)) + .build(); + } + + private UserGender convertGender(String gender) { + UserGender userGender = UserGender.UNKNOWN; + if (gender != null) { + if (gender.equals("male")) { + userGender = UserGender.MALE; + } + if (gender.equals("female")) { + userGender = UserGender.FEMALE; + } + } + return userGender; + } + + private UserAge convertAge(String age) { + UserAge userGender = UserAge.UNKNOWN; + if (age != null) { + int startAge = Integer.parseInt(age.split("-")[0]); + for (UserAge value : UserAge.values()) { + if (startAge == value.getStartAge()) { + userGender = value; + break; + } + } + } + return userGender; + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/auth/service/AuthService.java b/sluv-api/src/main/java/com/sluv/api/auth/service/AuthService.java new file mode 100644 index 00000000..a29ee108 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/auth/service/AuthService.java @@ -0,0 +1,58 @@ +package com.sluv.api.auth.service; + +import com.sluv.api.auth.dto.response.AuthResponse; +import com.sluv.api.closet.service.ClosetService; +import com.sluv.domain.auth.dto.SocialUserInfoDto; +import com.sluv.domain.auth.enums.SnsType; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.exception.UserNoFCMException; +import com.sluv.domain.user.service.UserDomainService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class AuthService { + + // private final JwtProvider jwtProvider; + private final UserDomainService userDomainService; + + private final ClosetService closetService; + + public AuthResponse getAuthResDto(User user) { +// return AuthResponse.of(jwtProvider.createAccessToken(user.getId()), user.getUserStatus()); + return null; + } + + public User getOrCreateUser(SocialUserInfoDto userInfoDto, SnsType snsType, String fcm) { + User user = userDomainService.findByEmailOrNull(userInfoDto.getEmail()); + + if (user == null) { + user = userDomainService.createUser(User.toEntity(userInfoDto, snsType, fcm)); + + // 생성과 동시에 기본 Closet 생성 + closetService.postBasicCloset(user); + } + + changeFcm(user.getId(), fcm); + + return user; + } + + public void checkFcm(User user) { + if (user.getFcmToken() == null) { + throw new UserNoFCMException(); + } + } + + public void changeFcm(Long userId, String fcmToken) { + User user = userDomainService.findById(userId); + user.changeFcmToken(fcmToken); + userDomainService.saveUser(user); + } + + public User findLogInUser(Long userId) { + return userDomainService.findById(userId); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/auth/service/GoogleUserService.java b/sluv-api/src/main/java/com/sluv/api/auth/service/GoogleUserService.java new file mode 100644 index 00000000..c44e1b39 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/auth/service/GoogleUserService.java @@ -0,0 +1,33 @@ +package com.sluv.api.auth.service; + +import static com.sluv.domain.auth.enums.SnsType.GOOGLE; + +import com.sluv.api.auth.dto.request.AuthRequest; +import com.sluv.domain.auth.dto.SocialUserInfoDto; +import com.sluv.domain.user.entity.User; +import com.sluv.infra.oauth.google.GooglePlatformClient; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + + +@Service +@RequiredArgsConstructor +public class GoogleUserService { + + private final AuthService authService; + private final GooglePlatformClient googlePlatformClient; + + @Transactional + public User googleLogin(AuthRequest request) { + String idToken = request.getAccessToken(); + + // 1. idToken 검증 + SocialUserInfoDto verifiedIdToken = googlePlatformClient.verifyIdToken(idToken); + + // 2. user 정보로 DB 탐색 및 등록 + return authService.getOrCreateUser(verifiedIdToken, GOOGLE, request.getFcm()); + } + + +} diff --git a/sluv-api/src/main/java/com/sluv/api/auth/service/KakaoUserService.java b/sluv-api/src/main/java/com/sluv/api/auth/service/KakaoUserService.java new file mode 100644 index 00000000..a6b62ad3 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/auth/service/KakaoUserService.java @@ -0,0 +1,30 @@ +package com.sluv.api.auth.service; + +import static com.sluv.domain.auth.enums.SnsType.KAKAO; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.sluv.api.auth.dto.request.AuthRequest; +import com.sluv.domain.auth.dto.SocialUserInfoDto; +import com.sluv.domain.user.entity.User; +import com.sluv.infra.oauth.kakao.KakaoPlatformClient; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + + +@Service +@RequiredArgsConstructor +public class KakaoUserService { + + private final AuthService authService; + private final KakaoPlatformClient kakaoPlatformClient; + + public User kakaoLogin(AuthRequest request) throws JsonProcessingException { + String accessToken = request.getAccessToken(); + // 1. accessToken으로 user 정보 요청 + SocialUserInfoDto userInfo = kakaoPlatformClient.getKakaoUserInfo(accessToken); + + // 2. user 정보로 DB 탐색 및 등록 + return authService.getOrCreateUser(userInfo, KAKAO, request.getFcm()); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/auth/utils/AuthUserIdArgumentResolver.java b/sluv-api/src/main/java/com/sluv/api/auth/utils/AuthUserIdArgumentResolver.java new file mode 100644 index 00000000..621e512a --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/auth/utils/AuthUserIdArgumentResolver.java @@ -0,0 +1,35 @@ +package com.sluv.api.auth.utils; + +import com.sluv.common.annotation.CurrentUserId; +import lombok.RequiredArgsConstructor; +import org.springframework.core.MethodParameter; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@Component +@RequiredArgsConstructor +public class AuthUserIdArgumentResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.hasParameterAnnotation(CurrentUserId.class) && + parameter.getParameterType().equals(Long.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, + ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, + WebDataBinderFactory binderFactory) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null && !authentication.getName().equals("anonymousUser")) { + return Long.parseLong(authentication.getName()); + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/com/sluv/server/domain/brand/controller/BrandController.java b/sluv-api/src/main/java/com/sluv/api/brand/controller/BrandController.java similarity index 52% rename from src/main/java/com/sluv/server/domain/brand/controller/BrandController.java rename to sluv-api/src/main/java/com/sluv/api/brand/controller/BrandController.java index 3f33a570..b8a5be1b 100644 --- a/src/main/java/com/sluv/server/domain/brand/controller/BrandController.java +++ b/sluv-api/src/main/java/com/sluv/api/brand/controller/BrandController.java @@ -1,9 +1,9 @@ -package com.sluv.server.domain.brand.controller; +package com.sluv.api.brand.controller; -import com.sluv.server.domain.brand.dto.BrandSearchResDto; -import com.sluv.server.domain.brand.service.BrandService; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; +import com.sluv.api.brand.dto.response.BrandSearchResponse; +import com.sluv.api.brand.service.BrandService; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.common.response.SuccessDataResponse; import io.swagger.v3.oas.annotations.Operation; import java.util.List; import lombok.RequiredArgsConstructor; @@ -22,25 +22,17 @@ public class BrandController { @Operation(summary = "브랜드 검색", description = "브랜드 검색(Pagination)") @GetMapping("/search") - public ResponseEntity>> getBrandSearch( + public ResponseEntity>> getBrandSearch( @RequestParam String brandName, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(brandService.findAllBrand(brandName, pageable)) - .build() - ); - + PaginationResponse response = brandService.findAllBrand(brandName, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "인기 브랜드 검색", description = "인기 브랜드 검색(상위 10개)") @GetMapping("/top") - public ResponseEntity>> getTopBrand() { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(brandService.findTopBrand()) - .build() - ); + public ResponseEntity>> getTopBrand() { + List response = brandService.findTopBrand(); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } + } diff --git a/sluv-api/src/main/java/com/sluv/api/brand/controller/NewBrandController.java b/sluv-api/src/main/java/com/sluv/api/brand/controller/NewBrandController.java new file mode 100644 index 00000000..d0239e5a --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/brand/controller/NewBrandController.java @@ -0,0 +1,33 @@ +package com.sluv.api.brand.controller; + +import com.sluv.api.brand.dto.request.NewBrandPostRequest; +import com.sluv.api.brand.dto.response.NewBrandPostResponse; +import com.sluv.api.brand.service.NewBrandService; +import com.sluv.api.common.response.SuccessDataResponse; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Slf4j +@RequiredArgsConstructor +@RequestMapping("/app/newBrand") +public class NewBrandController { + + private final NewBrandService newBrandService; + + @Operation(summary = "NewBrand 등록", description = "새로운 NewBrand를 등록한다.") + @PostMapping("") + public ResponseEntity> postNewBrand( + @RequestBody NewBrandPostRequest request) { + log.info("NewBrand 등록. NewBrand Name:{}", request.getNewBrandName()); + NewBrandPostResponse response = newBrandService.postNewBrand(request); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + +} diff --git a/src/main/java/com/sluv/server/domain/brand/controller/RecentSelectBrandController.java b/sluv-api/src/main/java/com/sluv/api/brand/controller/RecentSelectBrandController.java similarity index 58% rename from src/main/java/com/sluv/server/domain/brand/controller/RecentSelectBrandController.java rename to sluv-api/src/main/java/com/sluv/api/brand/controller/RecentSelectBrandController.java index 8c3ef5ca..5d2d4826 100644 --- a/src/main/java/com/sluv/server/domain/brand/controller/RecentSelectBrandController.java +++ b/sluv-api/src/main/java/com/sluv/api/brand/controller/RecentSelectBrandController.java @@ -1,18 +1,17 @@ -package com.sluv.server.domain.brand.controller; +package com.sluv.api.brand.controller; -import com.sluv.server.domain.brand.dto.RecentSelectBrandReqDto; -import com.sluv.server.domain.brand.dto.RecentSelectBrandResDto; -import com.sluv.server.domain.brand.service.BrandService; -import com.sluv.server.domain.brand.service.RecentSelectBrandService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; +import com.sluv.api.brand.dto.request.RecentSelectBrandRequest; +import com.sluv.api.brand.dto.response.RecentSelectBrandResponse; +import com.sluv.api.brand.service.BrandService; +import com.sluv.api.brand.service.RecentSelectBrandService; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.common.annotation.CurrentUserId; import io.swagger.v3.oas.annotations.Operation; import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -32,50 +31,37 @@ public class RecentSelectBrandController { @Operation(summary = "*최근 선택한 브랜드 검색", description = "최근 선택한 브랜드을 검색") @GetMapping("") - public ResponseEntity>> getRecentSelectBrand( - @AuthenticationPrincipal User user) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(brandService.findRecentSelectBrand(user)) - .build() - ); - + public ResponseEntity>> getRecentSelectBrand( + @CurrentUserId Long userId) { + List response = brandService.findRecentSelectBrand(userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*최근 선택한 브랜드 등록", description = "User 토큰 필요") @PostMapping("") - public ResponseEntity postRecentSelectBrand(@AuthenticationPrincipal User user, - @RequestBody RecentSelectBrandReqDto dto) { + public ResponseEntity postRecentSelectBrand(@CurrentUserId Long userId, + @RequestBody RecentSelectBrandRequest request) { log.info("유저의 최근 선택한 브랜드 등록. 유저 : {}, Brand {}, NewBrand {}", - user.getId(), dto.getBrandId(), dto.getNewBrandId()); - - recentSelectBrandService.postRecentSelectBrand(user, dto); - - return ResponseEntity.ok().body( - new SuccessResponse() - ); + userId, request.getBrandId(), request.getNewBrandId()); + recentSelectBrandService.postRecentSelectBrand(userId, request); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*유저가 최근 선택한 브랜드 모두 삭제", description = "User 토큰 필요") @DeleteMapping("") - public ResponseEntity deleteAllRecentSelectBrand(@AuthenticationPrincipal User user) { - log.info("유저의 최근 선택한 브랜드 모두 삭제. 유저 : {}", user.getId()); - recentSelectBrandService.deleteAllRecentSelectBrand(user); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + public ResponseEntity deleteAllRecentSelectBrand(@CurrentUserId Long userId) { + log.info("유저의 최근 선택한 브랜드 모두 삭제. 유저 : {}", userId); + recentSelectBrandService.deleteAllRecentSelectBrand(userId); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*유저의 특정 [최근 선택한 브랜드] 삭제", description = "User 토큰 필요") @DeleteMapping("/{brandId}") - public ResponseEntity deleteRecentSelectBrand(@AuthenticationPrincipal User user, + public ResponseEntity deleteRecentSelectBrand(@CurrentUserId Long userId, @PathVariable("brandId") Long brandId, @RequestParam("flag") String flag) { - log.info("유저의 최근 선택한 브랜드 삭제. 유저 : {}, 브랜드 : {}, 플래그 : {}", user.getId(), brandId, flag); - recentSelectBrandService.deleteRecentSelectBrand(user, brandId, flag); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + log.info("유저의 최근 선택한 브랜드 삭제. 유저 : {}, 브랜드 : {}, 플래그 : {}", userId, brandId, flag); + recentSelectBrandService.deleteRecentSelectBrand(userId, brandId, flag); + return ResponseEntity.ok().body(SuccessResponse.create()); } } diff --git a/src/main/java/com/sluv/server/domain/brand/dto/NewBrandPostReqDto.java b/sluv-api/src/main/java/com/sluv/api/brand/dto/request/NewBrandPostRequest.java similarity index 56% rename from src/main/java/com/sluv/server/domain/brand/dto/NewBrandPostReqDto.java rename to sluv-api/src/main/java/com/sluv/api/brand/dto/request/NewBrandPostRequest.java index ad18ec4e..f3113a7b 100644 --- a/src/main/java/com/sluv/server/domain/brand/dto/NewBrandPostReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/brand/dto/request/NewBrandPostRequest.java @@ -1,14 +1,12 @@ -package com.sluv.server.domain.brand.dto; +package com.sluv.api.brand.dto.request; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; -@Data +@Getter @NoArgsConstructor -@AllArgsConstructor -public class NewBrandPostReqDto { +public class NewBrandPostRequest { @Schema(description = "새로 등록할 브랜드의 이름") private String newBrandName; } diff --git a/src/main/java/com/sluv/server/domain/brand/dto/RecentSelectBrandReqDto.java b/sluv-api/src/main/java/com/sluv/api/brand/dto/request/RecentSelectBrandRequest.java similarity index 55% rename from src/main/java/com/sluv/server/domain/brand/dto/RecentSelectBrandReqDto.java rename to sluv-api/src/main/java/com/sluv/api/brand/dto/request/RecentSelectBrandRequest.java index ae2cb8d4..362f6770 100644 --- a/src/main/java/com/sluv/server/domain/brand/dto/RecentSelectBrandReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/brand/dto/request/RecentSelectBrandRequest.java @@ -1,14 +1,13 @@ -package com.sluv.server.domain.brand.dto; +package com.sluv.api.brand.dto.request; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Data; +import lombok.AccessLevel; +import lombok.Getter; import lombok.NoArgsConstructor; -@Data -@NoArgsConstructor -@AllArgsConstructor -public class RecentSelectBrandReqDto { +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class RecentSelectBrandRequest { @Schema(description = "브랜드 Id") private Long brandId; @Schema(description = "뉴브랜드 Id") diff --git a/src/main/java/com/sluv/server/domain/brand/dto/BrandSearchResDto.java b/sluv-api/src/main/java/com/sluv/api/brand/dto/response/BrandSearchResponse.java similarity index 63% rename from src/main/java/com/sluv/server/domain/brand/dto/BrandSearchResDto.java rename to sluv-api/src/main/java/com/sluv/api/brand/dto/response/BrandSearchResponse.java index 69dd0586..362d329e 100644 --- a/src/main/java/com/sluv/server/domain/brand/dto/BrandSearchResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/brand/dto/response/BrandSearchResponse.java @@ -1,18 +1,19 @@ -package com.sluv.server.domain.brand.dto; +package com.sluv.api.brand.dto.response; -import com.sluv.server.domain.brand.entity.Brand; +import com.sluv.domain.brand.entity.Brand; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; +import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; -@Data -@NoArgsConstructor -@AllArgsConstructor +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) @Builder -public class BrandSearchResDto implements Serializable { +public class BrandSearchResponse implements Serializable { @Schema(description = "브랜드 Id") private Long id; @Schema(description = "브랜드 한글이름") @@ -22,8 +23,8 @@ public class BrandSearchResDto implements Serializable { @Schema(description = "브랜드 이미지 URL") private String brandImgUrl; - public static BrandSearchResDto of(Brand brand) { - return BrandSearchResDto.builder() + public static BrandSearchResponse of(Brand brand) { + return BrandSearchResponse.builder() .id(brand.getId()) .brandKr(brand.getBrandKr()) .brandEn(brand.getBrandEn()) diff --git a/src/main/java/com/sluv/server/domain/brand/dto/NewBrandPostResDto.java b/sluv-api/src/main/java/com/sluv/api/brand/dto/response/NewBrandPostResponse.java similarity index 54% rename from src/main/java/com/sluv/server/domain/brand/dto/NewBrandPostResDto.java rename to sluv-api/src/main/java/com/sluv/api/brand/dto/response/NewBrandPostResponse.java index ea59a8f1..f2ec164d 100644 --- a/src/main/java/com/sluv/server/domain/brand/dto/NewBrandPostResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/brand/dto/response/NewBrandPostResponse.java @@ -1,25 +1,26 @@ -package com.sluv.server.domain.brand.dto; +package com.sluv.api.brand.dto.response; -import com.sluv.server.domain.brand.entity.NewBrand; +import com.sluv.domain.brand.entity.NewBrand; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; +import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; -@Data -@NoArgsConstructor -@AllArgsConstructor +@Getter @Builder -public class NewBrandPostResDto implements Serializable { +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class NewBrandPostResponse implements Serializable { @Schema(description = "생성된 newBrand의 Id") private Long newBrandId; @Schema(description = "생성된 newBrand의 이름") private String newBrandName; - public static NewBrandPostResDto of(NewBrand newBrand) { - return NewBrandPostResDto.builder() + public static NewBrandPostResponse of(NewBrand newBrand) { + return NewBrandPostResponse.builder() .newBrandId(newBrand.getId()) .newBrandName(newBrand.getBrandName()) .build(); diff --git a/src/main/java/com/sluv/server/domain/brand/dto/RecentSelectBrandResDto.java b/sluv-api/src/main/java/com/sluv/api/brand/dto/response/RecentSelectBrandResponse.java similarity index 69% rename from src/main/java/com/sluv/server/domain/brand/dto/RecentSelectBrandResDto.java rename to sluv-api/src/main/java/com/sluv/api/brand/dto/response/RecentSelectBrandResponse.java index c7526912..6f6abb9b 100644 --- a/src/main/java/com/sluv/server/domain/brand/dto/RecentSelectBrandResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/brand/dto/response/RecentSelectBrandResponse.java @@ -1,17 +1,18 @@ -package com.sluv.server.domain.brand.dto; +package com.sluv.api.brand.dto.response; -import com.sluv.server.domain.brand.entity.RecentSelectBrand; +import com.sluv.domain.brand.entity.RecentSelectBrand; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; -@Data -@NoArgsConstructor -@AllArgsConstructor +@Getter @Builder -public class RecentSelectBrandResDto { +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class RecentSelectBrandResponse { @Schema(description = "브랜드 Id") private Long id; @Schema(description = "브랜드 이름") @@ -21,25 +22,25 @@ public class RecentSelectBrandResDto { @Schema(description = "브랜드(Y)와 뉴브랜드(N)를 구분하는 플래그") private String flag; - public static RecentSelectBrandResDto of(RecentSelectBrand recentSelectBrand){ + public static RecentSelectBrandResponse of(RecentSelectBrand recentSelectBrand) { Long id; String brandName; String brandImgUrl; String flag; - if(recentSelectBrand.getBrand() != null){ + if (recentSelectBrand.getBrand() != null) { id = recentSelectBrand.getBrand().getId(); brandName = recentSelectBrand.getBrand().getBrandKr(); brandImgUrl = recentSelectBrand.getBrand().getBrandImgUrl(); flag = "Y"; - }else{ + } else { id = recentSelectBrand.getNewBrand().getId(); brandName = recentSelectBrand.getNewBrand().getBrandName(); brandImgUrl = null; flag = "N"; } - return RecentSelectBrandResDto.builder() + return RecentSelectBrandResponse.builder() .id(id) .brandName(brandName) .brandImgUrl(brandImgUrl) diff --git a/sluv-api/src/main/java/com/sluv/api/brand/service/BrandService.java b/sluv-api/src/main/java/com/sluv/api/brand/service/BrandService.java new file mode 100644 index 00000000..470776c3 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/brand/service/BrandService.java @@ -0,0 +1,53 @@ +package com.sluv.api.brand.service; + +import com.sluv.api.brand.dto.response.BrandSearchResponse; +import com.sluv.api.brand.dto.response.RecentSelectBrandResponse; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.domain.brand.entity.Brand; +import com.sluv.domain.brand.entity.RecentSelectBrand; +import com.sluv.domain.brand.service.BrandDomainService; +import com.sluv.domain.brand.service.RecentSelectBrandDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class BrandService { + + private final UserDomainService userDomainService; + private final BrandDomainService brandDomainService; + private final RecentSelectBrandDomainService recentSelectBrandDomainService; + + public PaginationResponse findAllBrand(String brandName, Pageable pageable) { + Page brandPage = brandDomainService.findByAllBrandKrOrBrandEnStartingWith(brandName, pageable); + + List dtoList = brandPage.stream() + .map(BrandSearchResponse::of) + .toList(); + + return PaginationResponse.create(brandPage, dtoList); + } + + public List findTopBrand() { + return brandDomainService.findTopBrand() + .stream() + .map(BrandSearchResponse::of) + .toList(); + } + + public List findRecentSelectBrand(Long userId) { + User user = userDomainService.findById(userId); + List recentSelectBrandList = recentSelectBrandDomainService.getRecentSelectBrandTop20(user); + + return recentSelectBrandList.stream() + .map(RecentSelectBrandResponse::of) + .toList(); + } + +} + diff --git a/sluv-api/src/main/java/com/sluv/api/brand/service/NewBrandService.java b/sluv-api/src/main/java/com/sluv/api/brand/service/NewBrandService.java new file mode 100644 index 00000000..b886641e --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/brand/service/NewBrandService.java @@ -0,0 +1,30 @@ +package com.sluv.api.brand.service; + +import com.sluv.api.brand.dto.request.NewBrandPostRequest; +import com.sluv.api.brand.dto.response.NewBrandPostResponse; +import com.sluv.domain.brand.entity.NewBrand; +import com.sluv.domain.brand.service.NewBrandDomainService; +import com.sluv.infra.discord.WebHookService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class NewBrandService { + + private final NewBrandDomainService newBrandDomainService; + private final WebHookService webHookService; + + public NewBrandPostResponse postNewBrand(NewBrandPostRequest request) { + NewBrand newBrand = newBrandDomainService.findByBrandName(request.getNewBrandName()); + + if (newBrand == null) { + newBrand = newBrandDomainService.saveNewBrand(NewBrand.toEntity(request.getNewBrandName())); + webHookService.sendCreateNewBrandMessage(newBrand); + } + + return NewBrandPostResponse.of(newBrand); + } + + +} diff --git a/sluv-api/src/main/java/com/sluv/api/brand/service/RecentSelectBrandService.java b/sluv-api/src/main/java/com/sluv/api/brand/service/RecentSelectBrandService.java new file mode 100644 index 00000000..71762072 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/brand/service/RecentSelectBrandService.java @@ -0,0 +1,47 @@ +package com.sluv.api.brand.service; + +import com.sluv.api.brand.dto.request.RecentSelectBrandRequest; +import com.sluv.domain.brand.entity.Brand; +import com.sluv.domain.brand.entity.NewBrand; +import com.sluv.domain.brand.entity.RecentSelectBrand; +import com.sluv.domain.brand.service.BrandDomainService; +import com.sluv.domain.brand.service.NewBrandDomainService; +import com.sluv.domain.brand.service.RecentSelectBrandDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +@RequiredArgsConstructor +public class RecentSelectBrandService { + + private final UserDomainService userDomainService; + private final BrandDomainService brandDomainService; + private final NewBrandDomainService newBrandDomainService; + private final RecentSelectBrandDomainService recentSelectBrandDomainService; + + + public void postRecentSelectBrand(Long userId, RecentSelectBrandRequest request) { + User user = userDomainService.findById(userId); + Brand brand = brandDomainService.findByIdOrNull(request.getBrandId()); + NewBrand newBrand = newBrandDomainService.findByIdOrNull(request.getNewBrandId()); + + recentSelectBrandDomainService.saveRecentSelectBrand(RecentSelectBrand.toEntity(brand, newBrand, user)); + } + + public void deleteAllRecentSelectBrand(Long userId) { + recentSelectBrandDomainService.deleteAllByUserId(userId); + } + + public void deleteRecentSelectBrand(Long userId, Long brandId, String flag) { + if (flag.equals("Y")) { + recentSelectBrandDomainService.deleteByUserIdAndBrandId(userId, brandId); + } else { + recentSelectBrandDomainService.deleteByUserIdAndNewBrandId(userId, brandId); + } + } + +} diff --git a/src/main/java/com/sluv/server/domain/celeb/controller/CelebActivityController.java b/sluv-api/src/main/java/com/sluv/api/celeb/controller/CelebActivityController.java similarity index 64% rename from src/main/java/com/sluv/server/domain/celeb/controller/CelebActivityController.java rename to sluv-api/src/main/java/com/sluv/api/celeb/controller/CelebActivityController.java index c891d476..039510e8 100644 --- a/src/main/java/com/sluv/server/domain/celeb/controller/CelebActivityController.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/controller/CelebActivityController.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.celeb.controller; +package com.sluv.api.celeb.controller; -import com.sluv.server.domain.celeb.dto.CelebActivityResDto; -import com.sluv.server.domain.celeb.service.CelebActivityService; -import com.sluv.server.global.common.response.SuccessDataResponse; +import com.sluv.api.celeb.dto.response.CelebActivityResponse; +import com.sluv.api.celeb.service.CelebActivityService; +import com.sluv.api.common.response.SuccessDataResponse; import io.swagger.v3.oas.annotations.Operation; import java.util.List; import lombok.RequiredArgsConstructor; @@ -16,19 +16,15 @@ @RequiredArgsConstructor @RequestMapping("/app/celeb/activity") public class CelebActivityController { - private final CelebActivityService celebActivityService; + private final CelebActivityService celebActivityService; @Operation(summary = "셀럽의 활동 목록 조회", description = "중복 이름을 가진 셀럽을 분류할 때 사용. [최신순으로 8개를 조회]") @GetMapping("/{celebId}") - public ResponseEntity>> getCelebActivity( + public ResponseEntity>> getCelebActivity( @PathVariable("celebId") Long celebId) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(celebActivityService.getCelebActivity(celebId)) - .build() - ); - + List response = celebActivityService.getCelebActivity(celebId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } + } diff --git a/src/main/java/com/sluv/server/domain/celeb/controller/CelebController.java b/sluv-api/src/main/java/com/sluv/api/celeb/controller/CelebController.java similarity index 51% rename from src/main/java/com/sluv/server/domain/celeb/controller/CelebController.java rename to sluv-api/src/main/java/com/sluv/api/celeb/controller/CelebController.java index 3add4e41..289f307b 100644 --- a/src/main/java/com/sluv/server/domain/celeb/controller/CelebController.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/controller/CelebController.java @@ -1,10 +1,10 @@ -package com.sluv.server.domain.celeb.controller; +package com.sluv.api.celeb.controller; -import com.sluv.server.domain.celeb.dto.CelebSearchByCategoryResDto; -import com.sluv.server.domain.celeb.dto.CelebSearchResDto; -import com.sluv.server.domain.celeb.service.CelebService; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; +import com.sluv.api.celeb.dto.response.CelebSearchByCategoryResponse; +import com.sluv.api.celeb.dto.response.CelebSearchResponse; +import com.sluv.api.celeb.service.CelebService; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.common.response.SuccessDataResponse; import io.swagger.v3.oas.annotations.Operation; import java.util.List; import lombok.RequiredArgsConstructor; @@ -19,51 +19,36 @@ @RequiredArgsConstructor @RequestMapping("/app/celeb") public class CelebController { + private final CelebService celebService; @Operation(summary = "Celeb 검색", description = "입력한 이름으로 Celeb을 검색. Pagination 적용.") @GetMapping("/search") - public ResponseEntity>> searchCelebByName( + public ResponseEntity>> searchCelebByName( @RequestParam String celebName, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(celebService.searchCeleb(celebName, pageable)) - .build() - ); + PaginationResponse response = celebService.searchCeleb(celebName, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "관심셀럽 등록 시 Celeb 검색", description = "멤버 이름을 검색하면 그룹이 검색됨. Pagination X") @GetMapping("/search/interested") - public ResponseEntity>> searchInterestedCelebByName( + public ResponseEntity>> searchInterestedCelebByName( @RequestParam String celebName) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(celebService.searchInterestedCelebByName(celebName)) - .build() - ); + List response = celebService.searchInterestedCelebByName(celebName); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "인기 셀럽 조회", description = "조회가 많이된 Celeb 상위 10개 조회") @GetMapping("/top") - public ResponseEntity>> searchTop10Celeb() { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(celebService.getTop10Celeb()) - .build() - ); + public ResponseEntity>> searchTop10Celeb() { + List response = celebService.getTop10Celeb(); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "관심 셀럽 조회 시, 카테고리별 셀럽 조회", description = "카테고리별 최대 30개를 한번에 전달, 카테고리는 순서 X, 셀럽는 가나다 순서.") @GetMapping("/category") - public ResponseEntity>> searchCelebByCategory() { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(celebService.getCelebByCategory()) - .build() - ); + public ResponseEntity>> searchCelebByCategory() { + List response = celebService.getCelebByCategory(); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } } diff --git a/src/main/java/com/sluv/server/domain/celeb/controller/NewCelebController.java b/sluv-api/src/main/java/com/sluv/api/celeb/controller/NewCelebController.java similarity index 51% rename from src/main/java/com/sluv/server/domain/celeb/controller/NewCelebController.java rename to sluv-api/src/main/java/com/sluv/api/celeb/controller/NewCelebController.java index 8e97c2b5..6cbd2d42 100644 --- a/src/main/java/com/sluv/server/domain/celeb/controller/NewCelebController.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/controller/NewCelebController.java @@ -1,9 +1,9 @@ -package com.sluv.server.domain.celeb.controller; +package com.sluv.api.celeb.controller; -import com.sluv.server.domain.celeb.dto.NewCelebPostReqDto; -import com.sluv.server.domain.celeb.dto.NewCelebPostResDto; -import com.sluv.server.domain.celeb.service.NewCelebService; -import com.sluv.server.global.common.response.SuccessDataResponse; +import com.sluv.api.celeb.dto.request.NewCelebPostRequest; +import com.sluv.api.celeb.dto.response.NewCelebPostResponse; +import com.sluv.api.celeb.service.NewCelebService; +import com.sluv.api.common.response.SuccessDataResponse; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -16,16 +16,15 @@ @RequiredArgsConstructor @RequestMapping("/app/newCeleb") public class NewCelebController { - private final NewCelebService newCelebService; + private final NewCelebService newCelebService; @Operation(summary = "NewCeleb 등록", description = "사용자가 새로운 NewCeleb 등록") @PostMapping("") - public ResponseEntity> postNewCeleb(@RequestBody NewCelebPostReqDto dto) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(newCelebService.postNewCeleb(dto)) - .build() - ); + public ResponseEntity> postNewCeleb( + @RequestBody NewCelebPostRequest request) { + NewCelebPostResponse response = newCelebService.postNewCeleb(request); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } + } diff --git a/src/main/java/com/sluv/server/domain/celeb/controller/RecentSelectCelebController.java b/sluv-api/src/main/java/com/sluv/api/celeb/controller/RecentSelectCelebController.java similarity index 58% rename from src/main/java/com/sluv/server/domain/celeb/controller/RecentSelectCelebController.java rename to sluv-api/src/main/java/com/sluv/api/celeb/controller/RecentSelectCelebController.java index f3032c50..79f2d8d7 100644 --- a/src/main/java/com/sluv/server/domain/celeb/controller/RecentSelectCelebController.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/controller/RecentSelectCelebController.java @@ -1,17 +1,16 @@ -package com.sluv.server.domain.celeb.controller; - -import com.sluv.server.domain.celeb.dto.RecentSelectCelebReqDto; -import com.sluv.server.domain.celeb.dto.RecentSelectCelebResDto; -import com.sluv.server.domain.celeb.service.CelebService; -import com.sluv.server.domain.celeb.service.RecentSelectCelebService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; +package com.sluv.api.celeb.controller; + +import com.sluv.api.celeb.dto.request.RecentSelectCelebRequest; +import com.sluv.api.celeb.dto.response.RecentSelectCelebResponse; +import com.sluv.api.celeb.service.CelebService; +import com.sluv.api.celeb.service.RecentSelectCelebService; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.common.annotation.CurrentUserId; import io.swagger.v3.oas.annotations.Operation; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -25,52 +24,40 @@ @RequiredArgsConstructor @RequestMapping("/app/celeb/recent") public class RecentSelectCelebController { + private final CelebService celebService; private final RecentSelectCelebService recentSelectCelebService; @Operation(summary = "*최근 선택한 Celeb 조회", description = "User 토큰 필요. 최근 선택한 20개 조회.") @GetMapping("") - public ResponseEntity>> getRecentSelectCeleb( - @AuthenticationPrincipal User user) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(celebService.getUserRecentSelectCeleb(user)) - .build() - ); + public ResponseEntity>> getRecentSelectCeleb( + @CurrentUserId Long userId) { + List response = celebService.getUserRecentSelectCeleb(userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*최근 선택한 셀럽 등록", description = "User 토큰 필요.") @PostMapping("") - public ResponseEntity postRecentSelectCeleb(@AuthenticationPrincipal User user, - @RequestBody RecentSelectCelebReqDto dto) { + public ResponseEntity postRecentSelectCeleb(@CurrentUserId Long userId, + @RequestBody RecentSelectCelebRequest request) { - recentSelectCelebService.postRecentSelectCeleb(user, dto); - - return ResponseEntity.ok().body( - new SuccessResponse() - ); + recentSelectCelebService.postRecentSelectCeleb(userId, request); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*유저가 최근 선택한 셀럽 모두 삭제", description = "User 토큰 필요.") @DeleteMapping("") - public ResponseEntity deleteAllRecentSelectCeleb(@AuthenticationPrincipal User user) { - recentSelectCelebService.deleteAllRecentSelectCeleb(user); - - return ResponseEntity.ok().body( - new SuccessResponse() - ); + public ResponseEntity deleteAllRecentSelectCeleb(@CurrentUserId Long userId) { + recentSelectCelebService.deleteAllRecentSelectCeleb(userId); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*유저의 특정 [최근 선택한 셀럽] 삭제", description = "User 토큰 필요.") @DeleteMapping("/{celebId}") - public ResponseEntity deleteRecentSelectCeleb(@AuthenticationPrincipal User user, + public ResponseEntity deleteRecentSelectCeleb(@CurrentUserId Long userId, @PathVariable("celebId") Long celebId, @RequestParam("flag") String flag) { - recentSelectCelebService.deleteRecentSelectCeleb(user, celebId, flag); - - return ResponseEntity.ok().body( - new SuccessResponse() - ); + recentSelectCelebService.deleteRecentSelectCeleb(userId, celebId, flag); + return ResponseEntity.ok().body(SuccessResponse.create()); } } diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebPostReqDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/request/InterestedCelebPostRequest.java similarity index 80% rename from src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebPostReqDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/request/InterestedCelebPostRequest.java index ec47e0f7..cc0d86fd 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebPostReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/request/InterestedCelebPostRequest.java @@ -1,18 +1,17 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.request; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import java.util.List; - @Data @NoArgsConstructor @AllArgsConstructor @Builder -public class InterestedCelebPostReqDto { +public class InterestedCelebPostRequest { @Schema(description = "유저가 선택한 관심셀럽의 Id 리스트") private List celebIdList; } diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/NewCelebPostReqDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/request/NewCelebPostRequest.java similarity index 73% rename from src/main/java/com/sluv/server/domain/celeb/dto/NewCelebPostReqDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/request/NewCelebPostRequest.java index 205b690e..1f0f9dd4 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/NewCelebPostReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/request/NewCelebPostRequest.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.request; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -6,7 +6,7 @@ @Data @NoArgsConstructor -public class NewCelebPostReqDto { +public class NewCelebPostRequest { @Schema(description = "뉴셀럽의 이름") private String newCelebName; } diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/RecentSelectCelebReqDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/request/RecentSelectCelebRequest.java similarity index 77% rename from src/main/java/com/sluv/server/domain/celeb/dto/RecentSelectCelebReqDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/request/RecentSelectCelebRequest.java index bde632f2..9d540744 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/RecentSelectCelebReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/request/RecentSelectCelebRequest.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.request; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -6,7 +6,7 @@ @Data @NoArgsConstructor -public class RecentSelectCelebReqDto { +public class RecentSelectCelebRequest { @Schema(description = "셀럽의 Id") private Long celebId; @Schema(description = "뉴셀럽의 Id") diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/CelebActivityResDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebActivityResponse.java similarity index 61% rename from src/main/java/com/sluv/server/domain/celeb/dto/CelebActivityResDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebActivityResponse.java index ced94b09..03228534 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/CelebActivityResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebActivityResponse.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.response; -import com.sluv.server.domain.celeb.entity.CelebActivity; +import com.sluv.domain.celeb.entity.CelebActivity; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -11,12 +11,12 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class CelebActivityResDto { +public class CelebActivityResponse { @Schema(description = "셀럽의 활동명") private String activityName; - public static CelebActivityResDto of(CelebActivity celebActivity) { - return CelebActivityResDto.builder() + public static CelebActivityResponse of(CelebActivity celebActivity) { + return CelebActivityResponse.builder() .activityName(celebActivity.getActivityName()) .build(); } diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/CelebChipResDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebChipResponse.java similarity index 70% rename from src/main/java/com/sluv/server/domain/celeb/dto/CelebChipResDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebChipResponse.java index a06488a1..ef819dbc 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/CelebChipResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebChipResponse.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.response; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.NewCeleb; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.NewCeleb; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -12,7 +12,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class CelebChipResDto { +public class CelebChipResponse { /** * 관심셀럽 선택 시 카테고리 안에 들어가는 셀럽 Dto */ @@ -21,20 +21,20 @@ public class CelebChipResDto { @Schema(description = "셀럽 이름") private String celebName; - public static CelebChipResDto of(Celeb celeb) { + public static CelebChipResponse of(Celeb celeb) { String celebName = celeb.getParent() != null ? celeb.getParent().getCelebNameKr() + " " + celeb.getCelebNameKr() : celeb.getCelebNameKr(); - return CelebChipResDto.builder() + return CelebChipResponse.builder() .celebId(celeb.getId()) .celebName(celebName) .build(); } - public static CelebChipResDto of(NewCeleb celeb) { - return CelebChipResDto.builder() + public static CelebChipResponse of(NewCeleb celeb) { + return CelebChipResponse.builder() .celebId(celeb.getId()) .celebName(celeb.getCelebName()) .build(); diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/CelebSearchByCategoryResDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebSearchByCategoryResponse.java similarity index 67% rename from src/main/java/com/sluv/server/domain/celeb/dto/CelebSearchByCategoryResDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebSearchByCategoryResponse.java index 95511554..e10d846b 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/CelebSearchByCategoryResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebSearchByCategoryResponse.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.response; -import com.sluv.server.domain.celeb.entity.CelebCategory; +import com.sluv.domain.celeb.entity.CelebCategory; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import lombok.AllArgsConstructor; @@ -12,7 +12,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class CelebSearchByCategoryResDto { +public class CelebSearchByCategoryResponse { /** * 관심셀럽 선택 시 카테고리 그룹이 되는 Dto */ @@ -21,10 +21,10 @@ public class CelebSearchByCategoryResDto { @Schema(description = "카테고리 이름") private String categoryName; @Schema(description = "카테고리에 속한 셀럽 리스트") - private List celebList; + private List celebList; - public static CelebSearchByCategoryResDto of(CelebCategory celebCategory, List list) { - return CelebSearchByCategoryResDto.builder() + public static CelebSearchByCategoryResponse of(CelebCategory celebCategory, List list) { + return CelebSearchByCategoryResponse.builder() .categoryId(celebCategory.getId()) .categoryName(celebCategory.getName()) .celebList(list) diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/CelebSearchResDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebSearchResponse.java similarity index 90% rename from src/main/java/com/sluv/server/domain/celeb/dto/CelebSearchResDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebSearchResponse.java index 301418d5..4c5a1225 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/CelebSearchResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/CelebSearchResponse.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.response; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.sluv.server.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.Celeb; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; import lombok.AllArgsConstructor; @@ -14,7 +14,7 @@ @AllArgsConstructor @Builder @JsonPropertyOrder({"id", "CelebNameKr", "CelebNameEn"}) -public class CelebSearchResDto implements Serializable { +public class CelebSearchResponse implements Serializable { @Schema(description = "Celeb id") private Long id; @Schema(description = "Parent Celeb id") @@ -30,8 +30,8 @@ public class CelebSearchResDto implements Serializable { @Schema(description = "total 영어 이름") private String celebTotalNameEn; - public static CelebSearchResDto of(Celeb celeb) { - return CelebSearchResDto.builder() + public static CelebSearchResponse of(Celeb celeb) { + return CelebSearchResponse.builder() .id(celeb.getId()) .parentId( celeb.getParent() != null diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebCategoryResDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebCategoryResponse.java similarity index 55% rename from src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebCategoryResDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebCategoryResponse.java index a9901198..76645a75 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebCategoryResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebCategoryResponse.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.response; -import com.sluv.server.domain.celeb.entity.CelebCategory; +import com.sluv.domain.celeb.entity.CelebCategory; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import lombok.AllArgsConstructor; @@ -14,15 +14,15 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class InterestedCelebCategoryResDto { +public class InterestedCelebCategoryResponse { @Schema(description = "카테고리 이름") private String categoryName; @Schema(description = "카테고리에 속한 셀럽 리스트") - private List celebList; + private List celebList; - public static InterestedCelebCategoryResDto of(CelebCategory celebCategory, - List list) { - return InterestedCelebCategoryResDto.builder() + public static InterestedCelebCategoryResponse of(CelebCategory celebCategory, + List list) { + return InterestedCelebCategoryResponse.builder() .categoryName(celebCategory.getName()) .celebList(list) .build(); diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebChildResDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebChildResponse.java similarity index 77% rename from src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebChildResDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebChildResponse.java index fa3c7a4e..5d0999ed 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebChildResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebChildResponse.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.response; -import com.sluv.server.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.Celeb; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -13,7 +13,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class InterestedCelebChildResDto { +public class InterestedCelebChildResponse { @Schema(description = "멤버 Celeb Id") private Long id; @Schema(description = "멤버 Celeb 한글 이름") @@ -21,8 +21,8 @@ public class InterestedCelebChildResDto { @Schema(description = "Celeb 카테고리 이름") private String celebCategory; - public static InterestedCelebChildResDto of(Celeb celeb) { - return InterestedCelebChildResDto.builder() + public static InterestedCelebChildResponse of(Celeb celeb) { + return InterestedCelebChildResponse.builder() .id(celeb.getId()) .celebNameKr(celeb.getCelebNameKr()) .celebCategory( diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebParentResDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebParentResponse.java similarity index 72% rename from src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebParentResDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebParentResponse.java index 4c2dadfe..894a7297 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebParentResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebParentResponse.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.response; -import com.sluv.server.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.Celeb; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import lombok.AllArgsConstructor; @@ -14,7 +14,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class InterestedCelebParentResDto { +public class InterestedCelebParentResponse { @Schema(description = "상위 Celeb id") private Long id; @Schema(description = "Celeb 한글 이름") @@ -22,16 +22,16 @@ public class InterestedCelebParentResDto { @Schema(description = "Celeb 카테고리 이름") private String celebCategory; @Schema(description = "하위 Celeb 리스트") - private List subCelebList; + private List subCelebList; - public static InterestedCelebParentResDto of(Celeb celeb) { - List subDtoList = null; + public static InterestedCelebParentResponse of(Celeb celeb) { + List subDtoList = null; if (!celeb.getSubCelebList().isEmpty()) { subDtoList = celeb.getSubCelebList().stream() - .map(InterestedCelebChildResDto::of) + .map(InterestedCelebChildResponse::of) .toList(); } - return InterestedCelebParentResDto.builder() + return InterestedCelebParentResponse.builder() .id(celeb.getId()) .celebNameKr(celeb.getCelebNameKr()) .celebCategory( diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebResDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebResponse.java similarity index 78% rename from src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebResDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebResponse.java index bc61c37d..2fc6283f 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/InterestedCelebResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/InterestedCelebResponse.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.response; -import com.sluv.server.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.Celeb; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -11,7 +11,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class InterestedCelebResDto { +public class InterestedCelebResponse { @Schema(description = "Celeb Id") private Long id; @Schema(description = "Celeb 한글 이름") @@ -19,8 +19,8 @@ public class InterestedCelebResDto { @Schema(description = "Celeb 카테고리 이름") private String celebCategory; - public static InterestedCelebResDto of(Celeb celeb) { - return InterestedCelebResDto.builder() + public static InterestedCelebResponse of(Celeb celeb) { + return InterestedCelebResponse.builder() .id(celeb.getId()) .celebNameKr(celeb.getCelebNameKr()) .celebCategory( diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/NewCelebPostResDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/NewCelebPostResponse.java similarity index 68% rename from src/main/java/com/sluv/server/domain/celeb/dto/NewCelebPostResDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/response/NewCelebPostResponse.java index 036c2f76..6b38e8e7 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/NewCelebPostResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/NewCelebPostResponse.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.response; -import com.sluv.server.domain.celeb.entity.NewCeleb; +import com.sluv.domain.celeb.entity.NewCeleb; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; import lombok.AllArgsConstructor; @@ -12,14 +12,14 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class NewCelebPostResDto implements Serializable { +public class NewCelebPostResponse implements Serializable { @Schema(description = "생성된 newCeleb의 Id") private Long newCelebId; @Schema(description = "생성된 newCeleb의 이름") private String newCelebName; - public static NewCelebPostResDto of(NewCeleb newCeleb) { - return NewCelebPostResDto.builder() + public static NewCelebPostResponse of(NewCeleb newCeleb) { + return NewCelebPostResponse.builder() .newCelebId(newCeleb.getId()) .newCelebName(newCeleb.getCelebName()) .build(); diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/RecentSelectCelebResDto.java b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/RecentSelectCelebResponse.java similarity index 86% rename from src/main/java/com/sluv/server/domain/celeb/dto/RecentSelectCelebResDto.java rename to sluv-api/src/main/java/com/sluv/api/celeb/dto/response/RecentSelectCelebResponse.java index 6d4fbdd5..8c2616ed 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/RecentSelectCelebResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/dto/response/RecentSelectCelebResponse.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.api.celeb.dto.response; -import com.sluv.server.domain.celeb.entity.RecentSelectCeleb; +import com.sluv.domain.celeb.entity.RecentSelectCeleb; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -11,7 +11,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class RecentSelectCelebResDto { +public class RecentSelectCelebResponse { @Schema(description = "child 셀럽의 Id") private Long id; @Schema(description = "parent 셀럽 Id") @@ -23,7 +23,7 @@ public class RecentSelectCelebResDto { @Schema(description = "셀럽(Y)과 뉴셀럽(N)을 구분하는 플래그") private String flag; - public static RecentSelectCelebResDto of(RecentSelectCeleb recentSelectCeleb) { + public static RecentSelectCelebResponse of(RecentSelectCeleb recentSelectCeleb) { Long celebChildId; Long celebParentId; String celebChildName; @@ -45,7 +45,7 @@ public static RecentSelectCelebResDto of(RecentSelectCeleb recentSelectCeleb) { celebChildName = recentSelectCeleb.getNewCeleb().getCelebName(); celebParentName = null; } - return RecentSelectCelebResDto.builder() + return RecentSelectCelebResponse.builder() .id(celebChildId) .parentId(celebParentId) .childCelebName(celebChildName) diff --git a/sluv-api/src/main/java/com/sluv/api/celeb/service/CelebActivityService.java b/sluv-api/src/main/java/com/sluv/api/celeb/service/CelebActivityService.java new file mode 100644 index 00000000..0b9431f4 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/celeb/service/CelebActivityService.java @@ -0,0 +1,21 @@ +package com.sluv.api.celeb.service; + +import com.sluv.api.celeb.dto.response.CelebActivityResponse; +import com.sluv.domain.celeb.service.CelebActivityDomainService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class CelebActivityService { + + private final CelebActivityDomainService celebActivityDomainService; + + public List getCelebActivity(Long celebId) { + return celebActivityDomainService.findAllByCelebId(celebId).stream() + .map(CelebActivityResponse::of) + .toList(); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/celeb/service/CelebService.java b/sluv-api/src/main/java/com/sluv/api/celeb/service/CelebService.java new file mode 100644 index 00000000..a06a911b --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/celeb/service/CelebService.java @@ -0,0 +1,128 @@ +package com.sluv.api.celeb.service; + +import com.sluv.api.celeb.dto.response.CelebChipResponse; +import com.sluv.api.celeb.dto.response.CelebSearchByCategoryResponse; +import com.sluv.api.celeb.dto.response.CelebSearchResponse; +import com.sluv.api.celeb.dto.response.RecentSelectCelebResponse; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.CelebCategory; +import com.sluv.domain.celeb.entity.RecentSelectCeleb; +import com.sluv.domain.celeb.service.CelebCategoryDomainService; +import com.sluv.domain.celeb.service.CelebDomainService; +import com.sluv.domain.celeb.service.RecentSelectCelebDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Stream; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class CelebService { + + private final UserDomainService userDomainService; + private final CelebDomainService celebDomainService; + private final CelebCategoryDomainService celebCategoryDomainService; + private final RecentSelectCelebDomainService recentSelectCelebDomainService; + + public PaginationResponse searchCeleb(String celebName, Pageable pageable) { + Page celebPage = celebDomainService.searchCeleb(celebName, pageable); + + List content = celebPage.stream() + .map(CelebSearchResponse::of) + .toList(); + + return PaginationResponse.create(celebPage, content); + + } + + public List getUserRecentSelectCeleb(Long userId) { + User user = userDomainService.findById(userId); + List recentSelectCelebList = recentSelectCelebDomainService.getRecentSelectCelebTop20(user); + + return recentSelectCelebList + .stream() + .map(RecentSelectCelebResponse::of) + .toList(); + } + + public List getTop10Celeb() { + return celebDomainService.findTop10Celeb() + .stream() + .map(CelebSearchResponse::of) + .toList(); + } + + public List getCelebByCategory() { + // Parent Id가 null인 CelebCategory를 모두 조회 + List categoryList = celebCategoryDomainService.findAllByParentIdIsNull(); + changeCategoryOrder(categoryList); + + return categoryList.stream() + // 카테고리별 CelebSearchByCategoryResDto 생성 + .map(category -> CelebSearchByCategoryResponse.of(category, + celebDomainService.getCelebByCategory(category) + .stream() + // 셀럽별 CelebChipResDto 생성 + .map(CelebChipResponse::of) + .toList() + ) + ).toList(); + + } + + /** + * 가수 -> 배우 -> 방송인 -> 스포츠인 -> 인플루언서 순서로 변 + */ + + private void changeCategoryOrder(List categoryList) { + categoryList.sort(Comparator.comparing(CelebCategory::getName)); + + CelebCategory tempCategory = categoryList.get(1); + categoryList.set(1, categoryList.get(2)); + categoryList.set(2, tempCategory); + } + + public List searchInterestedCelebByName(String celebName) { + // 1. Parent Celeb과 일치 + List celebByParent = celebDomainService.searchInterestedCelebByParent(celebName); + + // 2. Child Celeb과 일치 + List celebByChild = celebDomainService.searchInterestedCelebByChild(celebName); + + // 1 + 2 를 합친 Celeb + List celebList = Stream.concat(celebByParent.stream(), celebByChild.stream()).distinct().toList(); + + // Celeb의 모든 카테고리 조회 + List celebCategoryList = celebCategoryDomainService.findAllByParentIdIsNull(); + + // Category별 맞는 celeb들을 골라내서 조립. + return celebCategoryList.stream() + // 카테고리별 분류 + .map(category -> { + List eachCategoryCeleb = + // 카테고리에 맞는 셀럽 filtering + celebList.stream().filter(celeb -> { + // ParentCategory가 있다면 ParentCategory. 없다면, CelebCategory. + CelebCategory tempCategory = celeb.getCelebCategory().getParent() != null + ? celeb.getCelebCategory().getParent() + : celeb.getCelebCategory(); + + return tempCategory == category; + // Category에 맞게 분류된 celeb을 Dto로 변경 + }).map(CelebChipResponse::of) + // 가나다 순으로 정렬 + .sorted(Comparator.comparing(CelebChipResponse::getCelebName)) + .toList(); + + return CelebSearchByCategoryResponse.of(category, eachCategoryCeleb); + }) + .toList(); + } + +} diff --git a/src/main/java/com/sluv/server/domain/celeb/service/CelebWithdrawService.java b/sluv-api/src/main/java/com/sluv/api/celeb/service/CelebWithdrawService.java similarity index 75% rename from src/main/java/com/sluv/server/domain/celeb/service/CelebWithdrawService.java rename to sluv-api/src/main/java/com/sluv/api/celeb/service/CelebWithdrawService.java index 6e34e4c7..0f01e207 100644 --- a/src/main/java/com/sluv/server/domain/celeb/service/CelebWithdrawService.java +++ b/sluv-api/src/main/java/com/sluv/api/celeb/service/CelebWithdrawService.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.celeb.service; +package com.sluv.api.celeb.service; -import com.sluv.server.domain.celeb.repository.InterestedCelebRepository; +import com.sluv.domain.celeb.repository.InterestedCelebRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/sluv-api/src/main/java/com/sluv/api/celeb/service/NewCelebService.java b/sluv-api/src/main/java/com/sluv/api/celeb/service/NewCelebService.java new file mode 100644 index 00000000..a16af905 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/celeb/service/NewCelebService.java @@ -0,0 +1,29 @@ +package com.sluv.api.celeb.service; + +import com.sluv.api.celeb.dto.request.NewCelebPostRequest; +import com.sluv.api.celeb.dto.response.NewCelebPostResponse; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.celeb.service.NewCelebDomainService; +import com.sluv.infra.discord.WebHookService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class NewCelebService { + + private final NewCelebDomainService newCelebDomainService; + private final WebHookService webHookService; + + public NewCelebPostResponse postNewCeleb(NewCelebPostRequest dto) { + NewCeleb newCeleb = newCelebDomainService.findByCelebNameOrNull(dto.getNewCelebName()); + + if (newCeleb == null) { + newCeleb = newCelebDomainService.saveNewCelebByName(NewCeleb.toEntity(dto.getNewCelebName())); + webHookService.sendCreateNewCelebMessage(newCeleb); + } + + return NewCelebPostResponse.of(newCeleb); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/celeb/service/RecentSelectCelebService.java b/sluv-api/src/main/java/com/sluv/api/celeb/service/RecentSelectCelebService.java new file mode 100644 index 00000000..86d4b520 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/celeb/service/RecentSelectCelebService.java @@ -0,0 +1,45 @@ +package com.sluv.api.celeb.service; + +import com.sluv.api.celeb.dto.request.RecentSelectCelebRequest; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.celeb.entity.RecentSelectCeleb; +import com.sluv.domain.celeb.service.CelebDomainService; +import com.sluv.domain.celeb.service.NewCelebDomainService; +import com.sluv.domain.celeb.service.RecentSelectCelebDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class RecentSelectCelebService { + + private final UserDomainService userDomainService; + private final CelebDomainService celebDomainService; + private final NewCelebDomainService newCelebDomainService; + private final RecentSelectCelebDomainService recentSelectCelebDomainService; + + public void postRecentSelectCeleb(Long userId, RecentSelectCelebRequest dto) { + User user = userDomainService.findById(userId); + Celeb celeb = celebDomainService.findByIdOrNull(dto.getCelebId()); + NewCeleb newCeleb = newCelebDomainService.findByNewCelebIdOrNull(dto.getNewCelebId()); + + recentSelectCelebDomainService.saveRecentSelectCeleb(RecentSelectCeleb.toEntity(user, celeb, newCeleb)); + + } + + public void deleteAllRecentSelectCeleb(Long userId) { + recentSelectCelebDomainService.deleteAllByUserId(userId); + } + + public void deleteRecentSelectCeleb(Long userId, Long celebId, String flag) { + if (flag.equals("Y")) { + recentSelectCelebDomainService.deleteByUserIdAndCelebId(userId, celebId); + } else { + recentSelectCelebDomainService.deleteByUserIdAndNewCelebId(userId, celebId); + } + } + +} diff --git a/src/main/java/com/sluv/server/domain/closet/controller/ClosetController.java b/sluv-api/src/main/java/com/sluv/api/closet/controller/ClosetController.java similarity index 52% rename from src/main/java/com/sluv/server/domain/closet/controller/ClosetController.java rename to sluv-api/src/main/java/com/sluv/api/closet/controller/ClosetController.java index ce4f40df..71c8762c 100644 --- a/src/main/java/com/sluv/server/domain/closet/controller/ClosetController.java +++ b/sluv-api/src/main/java/com/sluv/api/closet/controller/ClosetController.java @@ -1,17 +1,16 @@ -package com.sluv.server.domain.closet.controller; +package com.sluv.api.closet.controller; -import com.sluv.server.domain.closet.dto.ClosetListCountResDto; -import com.sluv.server.domain.closet.dto.ClosetNameCheckResDto; -import com.sluv.server.domain.closet.dto.ClosetReqDto; -import com.sluv.server.domain.closet.service.ClosetService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; +import com.sluv.api.closet.dto.request.ClosetRequest; +import com.sluv.api.closet.dto.response.ClosetListCountResponse; +import com.sluv.api.closet.dto.response.ClosetNameCheckResponse; +import com.sluv.api.closet.service.ClosetService; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.common.annotation.CurrentUserId; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.lang.Nullable; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -30,47 +29,33 @@ public class ClosetController { @Operation(summary = "*현재 유저의 옷장 리스트 조회", description = "User 토큰 필요") @GetMapping("/list") - public ResponseEntity> getClosetList( - @AuthenticationPrincipal User user) { - - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(closetService.getClosetList(user)) - .build() - ); + public ResponseEntity> getClosetList(@CurrentUserId Long userId) { + ClosetListCountResponse response = closetService.getClosetList(userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "옷장 이름 중복 검사", description = "옷장 등록 및 수정 시 호출") @GetMapping("/check-name") - public ResponseEntity> checkClosetNameDuplicated( + public ResponseEntity> checkClosetNameDuplicated( @RequestParam("name") String name, @Nullable @RequestParam("id") Long closetId) { - - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(closetService.checkClosetNameDuplicated(name, closetId)) - .build() - ); + ClosetNameCheckResponse response = closetService.checkClosetNameDuplicated(name, closetId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*옷장 생성", description = "User 토큰 필요") @PostMapping("") - public ResponseEntity postCloset(@AuthenticationPrincipal User user, - @RequestBody ClosetReqDto dto) { - closetService.postCloset(user, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + public ResponseEntity postCloset(@CurrentUserId Long userId, @RequestBody ClosetRequest request) { + closetService.postCloset(userId, request); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*옷장 커버정보 수정", description = "User 토큰 필요") @PutMapping("/{closetId}") - public ResponseEntity patchCloset(@AuthenticationPrincipal User user, + public ResponseEntity patchCloset(@CurrentUserId Long userId, @PathVariable("closetId") Long closetId, - @RequestBody ClosetReqDto dto) { - closetService.patchCloset(user, closetId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + @RequestBody ClosetRequest request) { + closetService.patchCloset(userId, closetId, request); + return ResponseEntity.ok().body(SuccessResponse.create()); } /** @@ -78,11 +63,9 @@ public ResponseEntity patchCloset(@AuthenticationPrincipal User */ @Operation(summary = "*옷장 삭제", description = "User 토큰 필요. 기본 Closet은 삭제 불가.") @DeleteMapping("/{closetId}") - public ResponseEntity deleteCloset(@AuthenticationPrincipal User user, + public ResponseEntity deleteCloset(@CurrentUserId Long userId, @PathVariable("closetId") Long closetId) { - closetService.deleteCloset(user, closetId); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + closetService.deleteCloset(userId, closetId); + return ResponseEntity.ok().body(SuccessResponse.create()); } } diff --git a/src/main/java/com/sluv/server/domain/closet/controller/ClosetItemController.java b/sluv-api/src/main/java/com/sluv/api/closet/controller/ClosetItemController.java similarity index 62% rename from src/main/java/com/sluv/server/domain/closet/controller/ClosetItemController.java rename to sluv-api/src/main/java/com/sluv/api/closet/controller/ClosetItemController.java index f6373c61..6bbcda53 100644 --- a/src/main/java/com/sluv/server/domain/closet/controller/ClosetItemController.java +++ b/sluv-api/src/main/java/com/sluv/api/closet/controller/ClosetItemController.java @@ -1,16 +1,15 @@ -package com.sluv.server.domain.closet.controller; +package com.sluv.api.closet.controller; -import com.sluv.server.domain.closet.dto.ClosetDetailResDto; -import com.sluv.server.domain.closet.dto.ClosetItemSelectReqDto; -import com.sluv.server.domain.closet.service.ClosetItemService; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.SuccessResponse; +import com.sluv.api.closet.dto.request.ClosetItemSelectRequest; +import com.sluv.api.closet.dto.response.ClosetDetailResponse; +import com.sluv.api.closet.service.ClosetItemService; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.common.annotation.CurrentUserId; +import com.sluv.domain.item.dto.ItemSimpleDto; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; @@ -28,13 +27,11 @@ public class ClosetItemController { @Operation(summary = "*옷장 상세조회", description = "User 토큰 필요. Pagination 적용. 가장 최근 Scrap 한 순서대로 정렬.") @GetMapping("/{closetId}") - public ResponseEntity> getClosetDetails(@AuthenticationPrincipal User user, - @PathVariable("closetId") Long closetId, - Pageable pageable) { + public ResponseEntity> getClosetDetails(@CurrentUserId Long userId, + @PathVariable("closetId") Long closetId, + Pageable pageable) { - return ResponseEntity.ok().body( - closetItemService.getClosetDetails(user, closetId, pageable) - ); + return ResponseEntity.ok().body(closetItemService.getClosetDetails(userId, closetId, pageable)); } /** @@ -42,45 +39,37 @@ public ResponseEntity> getClosetDetails(@Au */ @Operation(summary = "*옷장에 아이템 스크랩(저장하기)", description = "User 토큰 필요. 유저당 아이템 1개만 저장 가능)") @PostMapping("/{itemId}/scrap/{closetId}") - public ResponseEntity postItemScrapToCloset(@AuthenticationPrincipal User user, + public ResponseEntity postItemScrapToCloset(@CurrentUserId Long userId, @PathVariable("itemId") Long itemId, @PathVariable("closetId") Long closetId) { - closetItemService.postItemScrapToCloset(user, itemId, closetId); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + closetItemService.postItemScrapToCloset(userId, itemId, closetId); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*옷장에 편집하기로 선택한 Item들을 다른 옷장으로 이동", description = "User 토큰 필요") @PatchMapping("/{fromClosetId}/{toClosetId}/items") - public ResponseEntity patchSaveCloset(@AuthenticationPrincipal User user, + public ResponseEntity patchSaveCloset(@CurrentUserId Long userId, @PathVariable("fromClosetId") Long fromClosetId, @PathVariable("toClosetId") Long toClosetId, - @RequestBody ClosetItemSelectReqDto dto) { - closetItemService.moveItemInCloset(user, fromClosetId, toClosetId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + @RequestBody ClosetItemSelectRequest request) { + closetItemService.moveItemInCloset(userId, fromClosetId, toClosetId, request); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*옷장에 편집하기로 선택한 Item을 모두 삭제", description = "User 토큰 필요") @PatchMapping("/{closetId}/items") - public ResponseEntity patchItems(@AuthenticationPrincipal User user, + public ResponseEntity patchItems(@CurrentUserId Long userId, @PathVariable("closetId") Long closetId, - @RequestBody ClosetItemSelectReqDto dto) { - closetItemService.removeSelectItemInCloset(user, closetId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + @RequestBody ClosetItemSelectRequest request) { + closetItemService.removeSelectItemInCloset(userId, closetId, request); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*아이템 게시글에서 북마크 버튼으로 삭제 시", description = "User 토큰 필요") @DeleteMapping("/{itemId}/scrap") - public ResponseEntity deleteItemScrapFromCloset(@AuthenticationPrincipal User user, + public ResponseEntity deleteItemScrapFromCloset(@CurrentUserId Long userId, @PathVariable("itemId") Long itemId) { - closetItemService.deleteItemScrapFromCloset(user, itemId); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + closetItemService.deleteItemScrapFromCloset(userId, itemId); + return ResponseEntity.ok().body(SuccessResponse.create()); } } diff --git a/src/main/java/com/sluv/server/domain/closet/dto/ClosetItemSelectReqDto.java b/sluv-api/src/main/java/com/sluv/api/closet/dto/request/ClosetItemSelectRequest.java similarity index 66% rename from src/main/java/com/sluv/server/domain/closet/dto/ClosetItemSelectReqDto.java rename to sluv-api/src/main/java/com/sluv/api/closet/dto/request/ClosetItemSelectRequest.java index 5149a8d3..b7babaf9 100644 --- a/src/main/java/com/sluv/server/domain/closet/dto/ClosetItemSelectReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/closet/dto/request/ClosetItemSelectRequest.java @@ -1,14 +1,13 @@ -package com.sluv.server.domain.closet.dto; +package com.sluv.api.closet.dto.request; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.NoArgsConstructor; - import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; -@Data +@Getter @NoArgsConstructor -public class ClosetItemSelectReqDto { +public class ClosetItemSelectRequest { @Schema(description = "Closet에서 선택한 Item Id List") List itemList; } diff --git a/src/main/java/com/sluv/server/domain/closet/dto/ClosetReqDto.java b/sluv-api/src/main/java/com/sluv/api/closet/dto/request/ClosetRequest.java similarity index 71% rename from src/main/java/com/sluv/server/domain/closet/dto/ClosetReqDto.java rename to sluv-api/src/main/java/com/sluv/api/closet/dto/request/ClosetRequest.java index c6054c05..1c8ad445 100644 --- a/src/main/java/com/sluv/server/domain/closet/dto/ClosetReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/closet/dto/request/ClosetRequest.java @@ -1,19 +1,18 @@ -package com.sluv.server.domain.closet.dto; +package com.sluv.api.closet.dto.request; -import com.sluv.server.domain.closet.enums.ClosetColor; -import com.sluv.server.domain.closet.enums.ClosetStatus; +import com.sluv.domain.closet.enums.ClosetColor; +import com.sluv.domain.closet.enums.ClosetStatus; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Data; +import lombok.Getter; import lombok.NoArgsConstructor; -@Data +@Getter +@Builder @NoArgsConstructor @AllArgsConstructor -@Builder -public class -ClosetReqDto { +public class ClosetRequest { @Schema(description = "Closet 이름") private String name; @Schema(description = "Closet 커버 사진 URL") diff --git a/src/main/java/com/sluv/server/domain/closet/dto/ClosetDetailResDto.java b/sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetDetailResponse.java similarity index 72% rename from src/main/java/com/sluv/server/domain/closet/dto/ClosetDetailResDto.java rename to sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetDetailResponse.java index d67117fe..88ffaefa 100644 --- a/src/main/java/com/sluv/server/domain/closet/dto/ClosetDetailResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetDetailResponse.java @@ -1,9 +1,9 @@ -package com.sluv.server.domain.closet.dto; +package com.sluv.api.closet.dto.response; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.closet.enums.ClosetColor; -import com.sluv.server.domain.closet.enums.ClosetStatus; -import com.sluv.server.global.common.response.PaginationResDto; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.closet.enums.ClosetColor; +import com.sluv.domain.closet.enums.ClosetStatus; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.NoArgsConstructor; @@ -13,7 +13,7 @@ @Getter @NoArgsConstructor @SuperBuilder -public class ClosetDetailResDto extends PaginationResDto { +public class ClosetDetailResponse extends PaginationResponse { @Schema(description = "Closet id") private Long id; @Schema(description = "Closet 커버 이미지 Url") @@ -27,9 +27,9 @@ public class ClosetDetailResDto extends PaginationResDto { @Schema(description = "Closet에 있는 아이템 개수") private Long itemNum; - public static ClosetDetailResDto of(Page page, Closet closet) { + public static ClosetDetailResponse of(Page page, Closet closet) { String coverImg = closet.getCoverImgUrl() == null ? null : closet.getCoverImgUrl(); - return ClosetDetailResDto.builder() + return ClosetDetailResponse.builder() .hasNext(page.hasNext()) .page(page.getNumber()) .content(page.getContent()) diff --git a/sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetListCountResponse.java b/sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetListCountResponse.java new file mode 100644 index 00000000..cf0cefee --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetListCountResponse.java @@ -0,0 +1,25 @@ +package com.sluv.api.closet.dto.response; + +import java.util.List; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class ClosetListCountResponse { + Long closetCount; + List closetList; + + public static ClosetListCountResponse of(Long closetCount, List closetList) { + return ClosetListCountResponse.builder() + .closetCount(closetCount) + .closetList(closetList) + .build(); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetNameCheckResponse.java b/sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetNameCheckResponse.java new file mode 100644 index 00000000..35980a93 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetNameCheckResponse.java @@ -0,0 +1,24 @@ +package com.sluv.api.closet.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class ClosetNameCheckResponse { + @Schema(description = "Closet의 이름이 중복인지 확인") + Boolean isDuplicated; + + public static ClosetNameCheckResponse of(Boolean checkStatus) { + return ClosetNameCheckResponse.builder() + .isDuplicated(checkStatus) + .build(); + } + +} diff --git a/src/main/java/com/sluv/server/domain/closet/dto/ClosetResDto.java b/sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetResponse.java similarity index 75% rename from src/main/java/com/sluv/server/domain/closet/dto/ClosetResDto.java rename to sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetResponse.java index db40290a..099c573f 100644 --- a/src/main/java/com/sluv/server/domain/closet/dto/ClosetResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/closet/dto/response/ClosetResponse.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.closet.dto; +package com.sluv.api.closet.dto.response; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.closet.enums.ClosetColor; -import com.sluv.server.domain.closet.enums.ClosetStatus; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.closet.enums.ClosetColor; +import com.sluv.domain.closet.enums.ClosetStatus; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -13,7 +13,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class ClosetResDto { +public class ClosetResponse { @Schema(description = "Closet id") private Long id; @Schema(description = "Closet 이름") @@ -27,9 +27,9 @@ public class ClosetResDto { @Schema(description = "해당 Closet의 Item 개수") private Long itemNum; - public static ClosetResDto of(Closet closet, Long itemNum) { + public static ClosetResponse of(Closet closet, Long itemNum) { String coverImg = closet.getCoverImgUrl() == null ? null : closet.getCoverImgUrl(); - return ClosetResDto.builder() + return ClosetResponse.builder() .id(closet.getId()) .name(closet.getName()) .coverImgUrl(coverImg) diff --git a/sluv-api/src/main/java/com/sluv/api/closet/mapper/ClosetMapper.java b/sluv-api/src/main/java/com/sluv/api/closet/mapper/ClosetMapper.java new file mode 100644 index 00000000..fd048f4a --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/closet/mapper/ClosetMapper.java @@ -0,0 +1,12 @@ +package com.sluv.api.closet.mapper; + +import com.sluv.api.closet.dto.request.ClosetRequest; +import com.sluv.domain.closet.dto.ClosetDomainDto; + +public class ClosetMapper { + + public static ClosetDomainDto toClosetDomainDto(ClosetRequest dto) { + return ClosetDomainDto.of(dto.getName(), dto.getCoverImgUrl(), dto.getClosetStatus(), dto.getColorScheme()); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/closet/service/ClosetItemService.java b/sluv-api/src/main/java/com/sluv/api/closet/service/ClosetItemService.java new file mode 100644 index 00000000..81e77769 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/closet/service/ClosetItemService.java @@ -0,0 +1,132 @@ +package com.sluv.api.closet.service; + +import com.sluv.api.closet.dto.request.ClosetItemSelectRequest; +import com.sluv.api.closet.dto.response.ClosetDetailResponse; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.closet.enums.ClosetStatus; +import com.sluv.domain.closet.service.ClosetDomainService; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemScrap; +import com.sluv.domain.item.service.ItemDomainService; +import com.sluv.domain.item.service.ItemScrapDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.exception.UserNotMatchedException; +import com.sluv.domain.user.service.UserDomainService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Slf4j +@Service +public class ClosetItemService { + + private final UserDomainService userDomainService; + private final ItemDomainService itemDomainService; + private final ItemScrapDomainService itemScrapDomainService; + private final ClosetDomainService closetDomainService; + + /** + * 옷장 상세 조회 + */ + @Transactional(readOnly = true) + public ClosetDetailResponse getClosetDetails(Long userId, Long closetId, Pageable pageable) { + Closet closet = closetDomainService.findById(closetId); + if (closet.getClosetStatus().equals(ClosetStatus.PRIVATE) && !closet.getUser().getId().equals(userId)) { + log.info("User did Not Matched. User Id: {}, Closet Owner Id : {}", userId, closet.getUser().getId()); + throw new UserNotMatchedException(); + } + Page itemPage = itemDomainService.getClosetItems(closet, pageable); + return ClosetDetailResponse.of(itemPage, closet); + } + + /** + * 아이템 스크랩 + */ + @Transactional + public void postItemScrapToCloset(Long userId, Long itemId, Long closetId) { + Item item = itemDomainService.findById(itemId); + Closet closet = closetDomainService.findById(closetId); + + if (!closet.getUser().getId().equals(userId)) { + log.info("User did Not Matched. User Id: {}, Closet Owner Id : {}", userId, closet.getUser().getId()); + throw new UserNotMatchedException(); + } + + log.info("Save ItemScrap with item Id: {}, Closet Id {}", item.getId(), closet.getId()); + ItemScrap saveItemScrap = itemScrapDomainService.saveItemScrap(item, closet); + log.info("Save Success with ItemScrap Id: {}", saveItemScrap.getId()); + + + } + + /** + * 아이템 스크랩 취소 + */ + @Transactional + public void deleteItemScrapFromCloset(Long userId, Long itemId) { + User user = userDomainService.findById(userId); + List closetList = closetDomainService.findAllByUserId(user.getId()); + + log.info("DELETE ItemScrap {}", itemId); + closetList.forEach(closet -> { + itemScrapDomainService.deleteByClosetIdAndItemId(closet.getId(), itemId); + }); + } + + /** + * 옷장에서 선택한 아이템 삭제 + */ + @Transactional + public void removeSelectItemInCloset(Long userId, Long closetId, ClosetItemSelectRequest dto) { + Closet closet = closetDomainService.findById(closetId); + + if (!closet.getUser().getId().equals(userId)) { + log.info("User did Not Matched. User Id: {}, Closet Owner Id : {}", userId, closet.getUser().getId()); + throw new UserNotMatchedException(); + } + + dto.getItemList().forEach(itemId -> { + log.info("Delete Item {}, from Closet {}", itemId, closet.getId()); + itemScrapDomainService.deleteByClosetIdAndItemId(closet.getId(), itemId); + }); + + } + + + /** + * 특정 옷장에 있는 아이템을 다른 옷장으로 이동 + */ + @Transactional + public void moveItemInCloset(Long userId, Long fromClosetId, Long toClosetId, ClosetItemSelectRequest dto) { + Closet fromCloset = closetDomainService.findById(fromClosetId); + Closet toCloset = closetDomainService.findById(toClosetId); + + // fromCloset과 현재 유저 일치 비교 + if (!fromCloset.getUser().getId().equals(userId)) { + log.info("User did Not Matched. User Id: {}, fromCloset Owner Id : {}", userId, + fromCloset.getUser().getId()); + throw new UserNotMatchedException(); + } + + // toCloset과 현재 유저 일치 비교 + if (!toCloset.getUser().getId().equals(userId)) { + log.info("User did Not Matched. User Id: {}, toCloset Owner Id : {}", userId, toCloset.getUser().getId()); + throw new UserNotMatchedException(); + } + + // Target ItemScrap 모두 조회 + List itemScrapList = dto.getItemList() + .stream() + .map(itemId -> itemScrapDomainService.findByClosetIdAndItemId(fromClosetId, itemId)).toList(); + + // Target ItemScrap의 Closet을 toCloset으로 모두 변경 + itemScrapList.forEach(itemScrap -> itemScrap.changeCloset(toCloset)); + + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/closet/service/ClosetService.java b/sluv-api/src/main/java/com/sluv/api/closet/service/ClosetService.java new file mode 100644 index 00000000..47043fc8 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/closet/service/ClosetService.java @@ -0,0 +1,112 @@ +package com.sluv.api.closet.service; + +import com.sluv.api.closet.dto.request.ClosetRequest; +import com.sluv.api.closet.dto.response.ClosetListCountResponse; +import com.sluv.api.closet.dto.response.ClosetNameCheckResponse; +import com.sluv.api.closet.dto.response.ClosetResponse; +import com.sluv.api.closet.mapper.ClosetMapper; +import com.sluv.domain.closet.dto.ClosetDomainDto; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.closet.exception.BasicClosetDeleteException; +import com.sluv.domain.closet.service.ClosetDomainService; +import com.sluv.domain.item.service.ItemScrapDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.exception.UserNotMatchedException; +import com.sluv.domain.user.service.UserDomainService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Slf4j +@RequiredArgsConstructor +public class ClosetService { + + private final UserDomainService userDomainService; + private final ClosetDomainService closetDomainService; + private final ItemScrapDomainService itemScrapDomainService; + + /** + * 유저의 옷장 목록 조회 + */ + @Transactional(readOnly = true) + public ClosetListCountResponse getClosetList(Long userId) { + User user = userDomainService.findById(userId); + List closetResponses = closetDomainService.getUserClosetList(user) + .stream() + .map(countDto -> ClosetResponse.of(countDto.getCloset(), countDto.getItemCount())) + .toList(); + Long closetCount = closetDomainService.countByUserId(userId); + return ClosetListCountResponse.of(closetCount, closetResponses); + } + + /** + * 옷장 생성 전 이름 중복 체크 + */ + @Transactional(readOnly = true) + public ClosetNameCheckResponse checkClosetNameDuplicated(String name, Long closetId) { + Boolean isDuplicated = closetDomainService.checkDuplicate(name, closetId); + return ClosetNameCheckResponse.of(isDuplicated); + } + + /** + * 신규 유저 생성 시 기본 옷장 생성 + */ + public void postBasicCloset(User user) { + closetDomainService.saveBasicCloset(user); + } + + /** + * 옷장 생성 + */ + @Transactional + public void postCloset(Long userId, ClosetRequest dto) { + User user = userDomainService.findById(userId); + log.info("옷장 생성 - 사용자: {}, 이름: {}", userId, dto.getName()); + ClosetDomainDto closetDomainDto = ClosetMapper.toClosetDomainDto(dto); + closetDomainService.saveCloset(Closet.toEntity(user, closetDomainDto)); + } + + /** + * 옷장 정보 변경 + */ + public void patchCloset(Long userId, Long closetId, ClosetRequest dto) { + log.info("옷장 변경 - 사용자: {} ", userId); + Closet closet = closetDomainService.findById(closetId); + if (!closet.getUser().getId().equals(userId)) { + log.info("옷장 변경 실패 - 사용자: {}, 옷장 주인: {}", userId, closet.getUser().getId()); + throw new UserNotMatchedException(); + } + + ClosetDomainDto closetDomainDto = ClosetMapper.toClosetDomainDto(dto); + closetDomainService.changeClosetData(closet, closetDomainDto); + } + + /** + * 옷장 삭제 + */ + public void deleteCloset(Long userId, Long closetId) { +// User user = userDomainService.findById(userId); + Closet closet = closetDomainService.findById(closetId); + + // 현재 유저와 Closet Owner 비교 + if (!closet.getUser().getId().equals(userId)) { + log.info("User did Not Matched. User Id: {}, Closet Owner Id : {}", userId, closet.getUser().getId()); + throw new UserNotMatchedException(); + } + // 기본 Closet 여부 확인 + if (closet.getBasicFlag()) { + log.info("Closet Id {} is Basic Closet", closet.getId()); + throw new BasicClosetDeleteException(); + } + + log.info("ItemScrap Delete By Closet Id: {}", closet.getId()); + itemScrapDomainService.deleteAllByClosetId(closet.getId()); + + log.info("Delete Closet Id: {}", closet.getId()); + closetDomainService.deleteById(closet.getId()); + } + +} diff --git a/src/main/java/com/sluv/server/domain/comment/controller/CommentController.java b/sluv-api/src/main/java/com/sluv/api/comment/controller/CommentController.java similarity index 50% rename from src/main/java/com/sluv/server/domain/comment/controller/CommentController.java rename to sluv-api/src/main/java/com/sluv/api/comment/controller/CommentController.java index 8d5a310c..b2ef1cd8 100644 --- a/src/main/java/com/sluv/server/domain/comment/controller/CommentController.java +++ b/sluv-api/src/main/java/com/sluv/api/comment/controller/CommentController.java @@ -1,18 +1,17 @@ -package com.sluv.server.domain.comment.controller; +package com.sluv.api.comment.controller; -import com.sluv.server.domain.comment.dto.CommentPostReqDto; -import com.sluv.server.domain.comment.dto.CommentResDto; -import com.sluv.server.domain.comment.dto.SubCommentPageResDto; -import com.sluv.server.domain.comment.service.CommentService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; +import com.sluv.api.comment.dto.reponse.CommentResponse; +import com.sluv.api.comment.dto.reponse.SubCommentPageResponse; +import com.sluv.api.comment.dto.request.CommentPostRequest; +import com.sluv.api.comment.service.CommentService; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.common.annotation.CurrentUserId; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -30,93 +29,74 @@ public class CommentController { @Operation(summary = "*Question 게시글의 댓글 조회", description = "User 토큰 필요. Pagination 적용.") @GetMapping("/{questionId}") - public ResponseEntity>> getComment( - @AuthenticationPrincipal User user, + public ResponseEntity>> getComment( + @CurrentUserId Long userId, @PathVariable("questionId") Long questionId, Pageable pageable) { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(commentService.getComment(user, questionId, pageable)) - .build() - ); + PaginationResponse response = commentService.getComment(userId, questionId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*Question 게시글의 댓글의 대댓글 조회", description = "User 토큰 필요. Pagination 적용.") @GetMapping("/{commentId}/subcomment") - public ResponseEntity>> getSubComment( - @AuthenticationPrincipal User user, + public ResponseEntity>> getSubComment( + @CurrentUserId Long userId, @PathVariable("commentId") Long commentId, Pageable pageable) { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(commentService.getSubComment(user, commentId, pageable)) - .build() - ); + SubCommentPageResponse response = commentService.getSubComment(userId, commentId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*댓글 상세 조회", description = "User 토큰 필요. Pagination 적용.") @GetMapping("/detail/{commentId}") - public ResponseEntity> getCommentDetail( - @AuthenticationPrincipal User user, + public ResponseEntity> getCommentDetail( + @CurrentUserId Long userId, @PathVariable("commentId") Long commentId) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(commentService.getCommentDetail(user, commentId)) - .build() - ); + CommentResponse response = commentService.getCommentDetail(userId, commentId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*댓글 작성", description = "User 토큰 필요") @PostMapping("/{questionId}") - public ResponseEntity postComment(@AuthenticationPrincipal User user, + public ResponseEntity postComment(@CurrentUserId Long userId, @PathVariable("questionId") Long questionId, - @RequestBody CommentPostReqDto dto) { - commentService.postComment(user, questionId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + @RequestBody CommentPostRequest request) { + commentService.postComment(userId, questionId, request); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*대댓글 작성", description = "User 토큰 필요") @PostMapping("/{questionId}/{commentId}") - public ResponseEntity postSubComment(@AuthenticationPrincipal User user, + public ResponseEntity postSubComment(@CurrentUserId Long userId, @PathVariable("questionId") Long questionId, @PathVariable("commentId") Long commentId, - @RequestBody CommentPostReqDto dto) { - commentService.postSubComment(user, questionId, commentId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + @RequestBody CommentPostRequest request) { + commentService.postSubComment(userId, questionId, commentId, request); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*댓글 수정", description = " User 토큰 필요") @PutMapping("/{commentId}") - public ResponseEntity putComment(@AuthenticationPrincipal User user, + public ResponseEntity putComment(@CurrentUserId Long userId, @PathVariable("commentId") Long commentId, - @RequestBody CommentPostReqDto dto) { - commentService.putComment(user, commentId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + @RequestBody CommentPostRequest request) { + commentService.putComment(userId, commentId, request); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*댓글 삭제", description = "User 토큰 필요. 삭제 시 Comment Status를 변경하는 것이 아닌 DB에서 삭제.") @DeleteMapping("/{commentId}") - public ResponseEntity deleteComment(@AuthenticationPrincipal User user, + public ResponseEntity deleteComment(@CurrentUserId Long userId, @PathVariable("commentId") Long commentId) { - commentService.deleteComment(user, commentId); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + commentService.deleteComment(userId, commentId); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*댓글 좋아요", description = "User 토큰 필요. 없다면 -> 생성, 있다면 -> 삭제") @PostMapping("/{commentId}/like") - public ResponseEntity postCommentLike(@AuthenticationPrincipal User user, + public ResponseEntity postCommentLike(@CurrentUserId Long userId, @PathVariable("commentId") Long commentId) { - commentService.postCommentLike(user, commentId); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + commentService.postCommentLike(userId, commentId); + return ResponseEntity.ok().body(SuccessResponse.create()); } } diff --git a/src/main/java/com/sluv/server/domain/comment/controller/CommentReportController.java b/sluv-api/src/main/java/com/sluv/api/comment/controller/CommentReportController.java similarity index 59% rename from src/main/java/com/sluv/server/domain/comment/controller/CommentReportController.java rename to sluv-api/src/main/java/com/sluv/api/comment/controller/CommentReportController.java index 75c02182..50908a43 100644 --- a/src/main/java/com/sluv/server/domain/comment/controller/CommentReportController.java +++ b/sluv-api/src/main/java/com/sluv/api/comment/controller/CommentReportController.java @@ -1,13 +1,12 @@ -package com.sluv.server.domain.comment.controller; +package com.sluv.api.comment.controller; -import com.sluv.server.domain.comment.dto.CommentReportPostReqDto; -import com.sluv.server.domain.comment.service.CommentReportService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.SuccessResponse; +import com.sluv.api.comment.dto.request.CommentReportPostRequest; +import com.sluv.api.comment.service.CommentReportService; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.common.annotation.CurrentUserId; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -22,13 +21,11 @@ public class CommentReportController { @Operation(summary = "*댓글 신고", description = "User 토큰 필요. 한 유저가 하나의 댓글 중복 신고 불가.") @PostMapping("/{commentId}/report") - public ResponseEntity postCommentReport(@AuthenticationPrincipal User user, + public ResponseEntity postCommentReport(@CurrentUserId Long userId, @PathVariable("commentId") Long commentId, - @RequestBody CommentReportPostReqDto dto) { - commentReportService.postCommentReport(user, commentId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + @RequestBody CommentReportPostRequest request) { + commentReportService.postCommentReport(userId, commentId, request); + return ResponseEntity.ok().body(SuccessResponse.create()); } } diff --git a/sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentItemResponse.java b/sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentItemResponse.java new file mode 100644 index 00000000..0f3c7d45 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentItemResponse.java @@ -0,0 +1,31 @@ +package com.sluv.api.comment.dto.reponse; + +import com.sluv.domain.comment.entity.CommentItem; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.entity.ItemImg; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class CommentItemResponse { + @Schema(description = "Comment 아이템 정보") + private ItemSimpleDto item; + @Schema(description = "Comment 아이템 순서") + private Integer sortOrder; + + public static CommentItemResponse of(CommentItem commentItem, ItemImg mainImg, Boolean scrapStatus) { + + ItemSimpleDto itemSimpleDto = ItemSimpleDto.of(commentItem.getItem(), mainImg, scrapStatus); + + return CommentItemResponse.builder() + .item(itemSimpleDto) + .sortOrder(commentItem.getSortOrder()) + .build(); + } +} diff --git a/src/main/java/com/sluv/server/domain/comment/dto/CommentResDto.java b/sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentResponse.java similarity index 71% rename from src/main/java/com/sluv/server/domain/comment/dto/CommentResDto.java rename to sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentResponse.java index eba0a4f0..8795ae2f 100644 --- a/src/main/java/com/sluv/server/domain/comment/dto/CommentResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentResponse.java @@ -1,9 +1,10 @@ -package com.sluv.server.domain.comment.dto; +package com.sluv.api.comment.dto.reponse; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.enums.CommentStatus; -import com.sluv.server.domain.user.dto.UserInfoDto; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.comment.dto.CommentImgDto; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.enums.CommentStatus; +import com.sluv.domain.user.dto.UserInfoDto; +import com.sluv.domain.user.entity.User; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; import java.util.List; @@ -16,7 +17,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class CommentResDto { +public class CommentResponse { @Schema(description = "Comment Id") private Long id; @Schema(description = "Comment 작성자 정보") @@ -26,7 +27,7 @@ public class CommentResDto { @Schema(description = "Comment 이미지 Url 리스트") private List imgUrlList; @Schema(description = "Comment 아이템 리스트") - private List itemList; + private List itemList; @Schema(description = "Comment 작성 시간") private LocalDateTime createdAt; @@ -42,15 +43,15 @@ public class CommentResDto { private CommentStatus commentStatus; - public static CommentResDto of(Comment comment, User writer, User user, - List imgList, - List itemList, - Integer likeNum, - Boolean likeStatus) { + public static CommentResponse of(Comment comment, User writer, User user, + List imgList, + List itemList, + Integer likeNum, + Boolean likeStatus) { boolean hasMine = user != null && comment.getUser().getId().equals(user.getId()); - return CommentResDto.builder() + return CommentResponse.builder() .id(comment.getId()) .user(UserInfoDto.of(writer)) .content(comment.getContent()) diff --git a/src/main/java/com/sluv/server/domain/comment/dto/CommentSimpleResDto.java b/sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentSimpleResponse.java similarity index 75% rename from src/main/java/com/sluv/server/domain/comment/dto/CommentSimpleResDto.java rename to sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentSimpleResponse.java index 9170ff97..72cc7431 100644 --- a/src/main/java/com/sluv/server/domain/comment/dto/CommentSimpleResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/CommentSimpleResponse.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.comment.dto; +package com.sluv.api.comment.dto.reponse; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.enums.CommentStatus; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.enums.CommentStatus; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -12,7 +12,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class CommentSimpleResDto { +public class CommentSimpleResponse { @Schema(description = "Comment Id") private Long id; @Schema(description = "Question Id") @@ -24,8 +24,8 @@ public class CommentSimpleResDto { @Schema(description = "Comment 상태") private CommentStatus commentStatus; - public static CommentSimpleResDto of(Comment comment) { - return CommentSimpleResDto.builder() + public static CommentSimpleResponse of(Comment comment) { + return CommentSimpleResponse.builder() .id(comment.getId()) .questionId(comment.getQuestion().getId()) .questionTitle(comment.getQuestion().getTitle()) diff --git a/sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/SubCommentPageResponse.java b/sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/SubCommentPageResponse.java new file mode 100644 index 00000000..43fea899 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/comment/dto/reponse/SubCommentPageResponse.java @@ -0,0 +1,26 @@ +package com.sluv.api.comment.dto.reponse; + +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.domain.comment.entity.Comment; +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.springframework.data.domain.Page; + +@NoArgsConstructor +@Getter +@SuperBuilder +public class SubCommentPageResponse extends PaginationResponse { + private Long restCommentNum; + + public static SubCommentPageResponse of(Page commentPage, List content, + long restCommentNum) { + return SubCommentPageResponse.builder() + .hasNext(commentPage.hasNext()) + .page(commentPage.getNumber()) + .content(content) + .restCommentNum(restCommentNum) + .build(); + } +} diff --git a/src/main/java/com/sluv/server/domain/comment/dto/CommentItemReqDto.java b/sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentItemRequest.java similarity index 83% rename from src/main/java/com/sluv/server/domain/comment/dto/CommentItemReqDto.java rename to sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentItemRequest.java index 46fccb8a..ec174b82 100644 --- a/src/main/java/com/sluv/server/domain/comment/dto/CommentItemReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentItemRequest.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.comment.dto; +package com.sluv.api.comment.dto.request; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; @@ -10,7 +10,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class CommentItemReqDto { +public class CommentItemRequest { @Schema(description = "Comment 아이템 아이디") private Long itemId; @Schema(description = "Comment 아이템 순서") diff --git a/src/main/java/com/sluv/server/domain/comment/dto/CommentPostReqDto.java b/sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentPostRequest.java similarity index 72% rename from src/main/java/com/sluv/server/domain/comment/dto/CommentPostReqDto.java rename to sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentPostRequest.java index 439895fd..5f581b4c 100644 --- a/src/main/java/com/sluv/server/domain/comment/dto/CommentPostReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentPostRequest.java @@ -1,22 +1,22 @@ -package com.sluv.server.domain.comment.dto; +package com.sluv.api.comment.dto.request; +import com.sluv.domain.comment.dto.CommentImgDto; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import java.util.List; - @Data @NoArgsConstructor @AllArgsConstructor @Builder -public class CommentPostReqDto { +public class CommentPostRequest { @Schema(description = "Comment 내용") private String content; @Schema(description = "Comment Img List") private List imgList; @Schema(description = "Comment Item List") - private List itemList; + private List itemList; } diff --git a/src/main/java/com/sluv/server/domain/comment/dto/CommentReportPostReqDto.java b/sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentReportPostRequest.java similarity index 71% rename from src/main/java/com/sluv/server/domain/comment/dto/CommentReportPostReqDto.java rename to sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentReportPostRequest.java index 32e1671e..d004c270 100644 --- a/src/main/java/com/sluv/server/domain/comment/dto/CommentReportPostReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/comment/dto/request/CommentReportPostRequest.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.comment.dto; +package com.sluv.api.comment.dto.request; -import com.sluv.server.domain.comment.enums.CommentReportReason; +import com.sluv.domain.comment.enums.CommentReportReason; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -11,7 +11,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class CommentReportPostReqDto { +public class CommentReportPostRequest { @Schema(description = "신고 이유") private CommentReportReason reason; @Schema(description = "신고 내용") diff --git a/src/main/java/com/sluv/server/domain/comment/handler/CommentHelper.java b/sluv-api/src/main/java/com/sluv/api/comment/helper/CommentHelper.java similarity index 61% rename from src/main/java/com/sluv/server/domain/comment/handler/CommentHelper.java rename to sluv-api/src/main/java/com/sluv/api/comment/helper/CommentHelper.java index f3d55c68..af473e40 100644 --- a/src/main/java/com/sluv/server/domain/comment/handler/CommentHelper.java +++ b/sluv-api/src/main/java/com/sluv/api/comment/helper/CommentHelper.java @@ -1,15 +1,15 @@ -package com.sluv.server.domain.comment.handler; +package com.sluv.api.comment.helper; -import com.sluv.server.domain.comment.dto.CommentImgDto; -import com.sluv.server.domain.comment.dto.CommentItemResDto; -import com.sluv.server.domain.comment.dto.CommentResDto; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.repository.CommentImgRepository; -import com.sluv.server.domain.comment.repository.CommentItemRepository; -import com.sluv.server.domain.comment.repository.CommentLikeRepository; -import com.sluv.server.domain.item.helper.ItemHelper; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.repository.UserRepository; +import com.sluv.api.comment.dto.reponse.CommentItemResponse; +import com.sluv.api.comment.dto.reponse.CommentResponse; +import com.sluv.api.item.helper.ItemHelper; +import com.sluv.domain.comment.dto.CommentImgDto; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.repository.CommentImgRepository; +import com.sluv.domain.comment.repository.CommentItemRepository; +import com.sluv.domain.comment.repository.CommentLikeRepository; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.repository.UserRepository; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -23,17 +23,18 @@ public class CommentHelper { private final UserRepository userRepository; private final ItemHelper itemHelper; - public List getCommentResDtos(User user, List commentPage) { + public List getCommentResDtos(User user, List commentPage) { return commentPage .stream() .map(comment -> { // 해당 Comment에 해당하는 이미지 조회 List imgList = commentImgRepository.findAllByCommentId(comment.getId()) +// .stream().map(CommentImgDto::of) .stream().map(CommentImgDto::of) .toList(); // 해당 Comment에 해당하는 아이템 조회 - List itemList = commentItemRepository.findAllByCommentId(comment.getId()) + List itemList = commentItemRepository.findAllByCommentId(comment.getId()) .stream().map(commentItem -> itemHelper.getCommentItemResDto(commentItem, user)) .toList(); @@ -45,7 +46,7 @@ public List getCommentResDtos(User user, List commentPag User writer = userRepository.findById(comment.getUser().getId()).orElse(null); - return CommentResDto.of(comment, writer, user, imgList, itemList, likeNum, likeStatus); + return CommentResponse.of(comment, writer, user, imgList, itemList, likeNum, likeStatus); }).toList(); } } diff --git a/src/main/java/com/sluv/server/domain/comment/manager/CommentImgManager.java b/sluv-api/src/main/java/com/sluv/api/comment/helper/CommentImgHelper.java similarity index 52% rename from src/main/java/com/sluv/server/domain/comment/manager/CommentImgManager.java rename to sluv-api/src/main/java/com/sluv/api/comment/helper/CommentImgHelper.java index 7bfa55e7..86358f45 100644 --- a/src/main/java/com/sluv/server/domain/comment/manager/CommentImgManager.java +++ b/sluv-api/src/main/java/com/sluv/api/comment/helper/CommentImgHelper.java @@ -1,9 +1,9 @@ -package com.sluv.server.domain.comment.manager; +package com.sluv.api.comment.helper; -import com.sluv.server.domain.comment.dto.CommentPostReqDto; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.entity.CommentImg; -import com.sluv.server.domain.comment.repository.CommentImgRepository; +import com.sluv.api.comment.dto.request.CommentPostRequest; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.entity.CommentImg; +import com.sluv.domain.comment.service.CommentImgDomainService; import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -12,16 +12,17 @@ @Component @Slf4j @RequiredArgsConstructor -public class CommentImgManager { - private final CommentImgRepository commentImgRepository; +public class CommentImgHelper { + + private final CommentImgDomainService commentImgDomainService; /** * 댓글 이미지 등록 */ - public void saveCommentImg(CommentPostReqDto dto, Comment comment) { + public void saveCommentImg(CommentPostRequest dto, Comment comment) { if (dto.getImgList() != null) { // 초기화 - commentImgRepository.deleteAllByCommentId(comment.getId()); + commentImgDomainService.deleteAllByCommentId(comment.getId()); // dto로 부터 새로운 CommentImg 생성 if (dto.getImgList() != null) { @@ -30,7 +31,7 @@ public void saveCommentImg(CommentPostReqDto dto, Comment comment) { ).toList(); // 저장 - commentImgRepository.saveAll(imgList); + commentImgDomainService.saveAll(imgList); } } } diff --git a/src/main/java/com/sluv/server/domain/comment/manager/CommentItemManager.java b/sluv-api/src/main/java/com/sluv/api/comment/helper/CommentItemHelper.java similarity index 59% rename from src/main/java/com/sluv/server/domain/comment/manager/CommentItemManager.java rename to sluv-api/src/main/java/com/sluv/api/comment/helper/CommentItemHelper.java index 726c6357..21d05000 100644 --- a/src/main/java/com/sluv/server/domain/comment/manager/CommentItemManager.java +++ b/sluv-api/src/main/java/com/sluv/api/comment/helper/CommentItemHelper.java @@ -1,12 +1,12 @@ -package com.sluv.server.domain.comment.manager; +package com.sluv.api.comment.helper; -import com.sluv.server.domain.comment.dto.CommentPostReqDto; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.entity.CommentItem; -import com.sluv.server.domain.comment.repository.CommentItemRepository; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.exception.ItemNotFoundException; -import com.sluv.server.domain.item.repository.ItemRepository; +import com.sluv.api.comment.dto.request.CommentPostRequest; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.entity.CommentItem; +import com.sluv.domain.comment.repository.CommentItemRepository; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.exception.ItemNotFoundException; +import com.sluv.domain.item.repository.ItemRepository; import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -15,22 +15,23 @@ @Component @Slf4j @RequiredArgsConstructor -public class CommentItemManager { +public class CommentItemHelper { private final CommentItemRepository commentItemRepository; private final ItemRepository itemRepository; /** * 댓글 아이템 등록 */ - public void saveCommentItem(CommentPostReqDto dto, Comment comment) { + public void saveCommentItem(CommentPostRequest dto, Comment comment) { if (dto.getItemList() != null) { // 초기화 commentItemRepository.deleteAllByCommentId(comment.getId()); if (dto.getItemList() != null) { // dto로 부터 새로운 CommentItem 생성 List itemList = dto.getItemList().stream().map(itemReqDto -> { - Item item = itemRepository.findById(itemReqDto.getItemId()).orElseThrow(ItemNotFoundException::new); - return CommentItem.toEntity(comment, item, itemReqDto); + Item item = itemRepository.findById(itemReqDto.getItemId()).orElseThrow( + ItemNotFoundException::new); + return CommentItem.toEntity(comment, item, itemReqDto.getSortOrder()); } ).toList(); diff --git a/sluv-api/src/main/java/com/sluv/api/comment/service/CommentReportService.java b/sluv-api/src/main/java/com/sluv/api/comment/service/CommentReportService.java new file mode 100644 index 00000000..cd172047 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/comment/service/CommentReportService.java @@ -0,0 +1,42 @@ +package com.sluv.api.comment.service; + +import com.sluv.api.comment.dto.request.CommentReportPostRequest; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.exception.CommentReportDuplicateException; +import com.sluv.domain.comment.service.CommentDomainService; +import com.sluv.domain.comment.service.CommentReportDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Slf4j +@RequiredArgsConstructor +public class CommentReportService { + + private final CommentDomainService commentDomainService; + private final CommentReportDomainService commentReportDomainService; + private final UserDomainService userDomainService; + + /** + * 댓글 신고 + */ + @Transactional + public void postCommentReport(Long userId, Long commentId, CommentReportPostRequest request) { + User user = userDomainService.findById(userId); + + log.info("댓글 신고 - 사용자 : {}, 신고 댓글 : {}", user.getId(), commentId); + Boolean reportStatus = commentReportDomainService.existsByReporterIdAndCommentId(user.getId(), commentId); + + if (reportStatus) { + throw new CommentReportDuplicateException(); + } + + Comment comment = commentDomainService.findById(commentId); + commentReportDomainService.saveCommentReport(comment, user, request.getReason(), request.getContent()); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/comment/service/CommentService.java b/sluv-api/src/main/java/com/sluv/api/comment/service/CommentService.java new file mode 100644 index 00000000..9e282c17 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/comment/service/CommentService.java @@ -0,0 +1,213 @@ +package com.sluv.api.comment.service; + +import com.sluv.api.alarm.service.CommentAlarmService; +import com.sluv.api.comment.dto.reponse.CommentResponse; +import com.sluv.api.comment.dto.reponse.SubCommentPageResponse; +import com.sluv.api.comment.dto.request.CommentPostRequest; +import com.sluv.api.comment.helper.CommentHelper; +import com.sluv.api.comment.helper.CommentImgHelper; +import com.sluv.api.comment.helper.CommentItemHelper; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.service.CommentDomainService; +import com.sluv.domain.comment.service.CommentLikeDomainService; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.service.QuestionDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.exception.UserNotMatchedException; +import com.sluv.domain.user.service.UserDomainService; +import com.sluv.infra.ai.AiModelService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Slf4j +@RequiredArgsConstructor +public class CommentService { + private final QuestionDomainService questionDomainService; + private final CommentDomainService commentDomainService; + private final CommentLikeDomainService commentLikeDomainService; + private final UserDomainService userDomainService; + + private final AiModelService aiModelService; + private final CommentHelper commentHelper; + private final CommentItemHelper commentItemHelper; + private final CommentImgHelper commentImgHelper; + + private final CommentAlarmService commentAlarmService; + + /** + * 댓글 조회 + */ + @Transactional(readOnly = true) + public PaginationResponse getComment(Long userId, Long questionId, Pageable pageable) { + User user = userDomainService.findById(userId); + + // 해당 페이지 검색 + Page commentPage = commentDomainService.getAllQuestionComment(questionId, pageable); + + // Content 제작 + List content = commentHelper.getCommentResDtos(user, commentPage.getContent()); + + return PaginationResponse.create(commentPage, content); + } + + /** + * 댓글 상세 조회 + */ + @Transactional(readOnly = true) + public CommentResponse getCommentDetail(Long userId, Long commentId) { + User user = userDomainService.findById(userId); + + // 댓글 조회 + Comment comment = commentDomainService.findById(commentId); + + // Content 제작 + List content = commentHelper.getCommentResDtos(user, List.of(comment)); + + return content.get(0); + + } + + /** + * 대댓글 조회 + */ + @Transactional(readOnly = true) + public SubCommentPageResponse getSubComment(Long userId, Long commentId, Pageable pageable) { + User user = userDomainService.findById(userId); + + // 대댓글 페이지 검색 + Page commentPage = commentDomainService.getAllSubComment(commentId, pageable); + + // Content 제작 + List content = commentHelper.getCommentResDtos(user, commentPage.getContent()); + + // 남은 댓글 수. 총 댓글 수 - ((현재 페이지 +1)*페이지당 size)가 0보다 작으면 0, 아닐 경우 해당 값 + long restCommentNum = + commentPage.getTotalElements() - ((long) (commentPage.getNumber() + 1) * commentPage.getSize()) >= 0 + ? commentPage.getTotalElements() - ((long) (commentPage.getNumber() + 1) + * commentPage.getSize()) + : 0; + + return SubCommentPageResponse.of(commentPage, content, restCommentNum); + + } + + /** + * 댓글 등록 + */ + @Transactional + public void postComment(Long userId, Long questionId, CommentPostRequest request) { + User user = userDomainService.findById(userId); + + log.info("댓글 등록 - 사용자 : {}, 질문 게시글 : {}, 댓글 내용 {}", user.getId(), questionId, request.getContent()); + Question question = questionDomainService.findById(questionId); + + Comment comment = commentDomainService.saveComment(user, question, request.getContent()); + commentItemHelper.saveCommentItem(request, comment); + commentImgHelper.saveCommentImg(request, comment); + + aiModelService.censorComment(comment); + commentAlarmService.sendAlarmAboutComment(user.getId(), comment.getId(), user); + + } + + /** + * 대댓글 등록 + */ + @Transactional + public void postSubComment(Long userId, Long questionId, Long commentId, CommentPostRequest request) { + User user = userDomainService.findById(userId); + + log.info("대댓글 등록 - 사용자 : {}, 질문 게시글 : {}, 상위 댓글 : {}, 댓글 내용 {}", + user.getId(), questionId, commentId, request.getContent()); + + Question question = questionDomainService.findById(questionId); + + // Parent Comment 조회 + Comment parentComment = commentDomainService.findById(commentId); + + Comment comment = commentDomainService.saveSubComment(user, question, request.getContent(), parentComment); + commentItemHelper.saveCommentItem(request, comment); + commentImgHelper.saveCommentImg(request, comment); + + aiModelService.censorComment(comment); + commentAlarmService.sendAlarmAboutComment(user.getId(), comment.getId(), user); + commentAlarmService.sendAlarmAboutSubComment(user.getId(), comment.getId(), user); + } + + /** + * 댓글 수정 + */ + @Transactional + public void putComment(Long userId, Long commentId, CommentPostRequest request) { + /** + * 1. Comment의 content 수정 + * 2. Comment와 관련된 img 초기화 후 재등록 + * 3. Comment와 관련된 item 초기화 후 재등록 + */ + User user = userDomainService.findById(userId); + + log.info("댓글 수정 - 사용자 : {}. 댓글 : {}", user.getId(), commentId); + Comment comment = commentDomainService.findById(commentId); + + if (!comment.getUser().getId().equals(user.getId())) { + throw new UserNotMatchedException(); + } + // content 변경 + comment.changeContent(request.getContent()); + + commentItemHelper.saveCommentItem(request, comment); + commentImgHelper.saveCommentImg(request, comment); + aiModelService.censorComment(comment); + + } + + /** + * 댓글 삭제 + */ + @Transactional + public void deleteComment(Long userId, Long commentId) { + User user = userDomainService.findById(userId); + + log.info("댓글 삭제 - 사용자 : {}, 댓글 : {}", user.getId(), commentId); + Comment comment = commentDomainService.findById(commentId); + + // comment 작성자와 현재 User가 불일치 시 예외 처리 + if (!comment.getUser().getId().equals(user.getId())) { + throw new UserNotMatchedException(); + } + + // Target Comment 제거 + commentDomainService.deleteById(commentId); + + // Target의 대댓글 제거 + commentDomainService.deleteAllByParentId(commentId); + + } + + /** + * 댓글 좋아요 + */ + @Transactional + public void postCommentLike(Long userId, Long commentId) { + User user = userDomainService.findById(userId); + + log.info("댓글 삭제 - 사용자 : {}, 댓글 : {}", user.getId(), commentId); + Boolean commentListStatus = commentLikeDomainService.existsByUserIdAndCommentId(user.getId(), commentId); + + if (!commentListStatus) { + Comment comment = commentDomainService.findById(commentId); + commentLikeDomainService.saveCommentLike(user, comment); + commentAlarmService.sendAlarmAboutCommentLike(user.getId(), comment.getId()); + } else { + commentLikeDomainService.deleteByUserIdAndCommentId(user.getId(), commentId); + } + } + +} diff --git a/src/main/java/com/sluv/server/global/common/ElasticBeanstalkController.java b/sluv-api/src/main/java/com/sluv/api/common/elb/ElasticBeanstalkController.java similarity index 90% rename from src/main/java/com/sluv/server/global/common/ElasticBeanstalkController.java rename to sluv-api/src/main/java/com/sluv/api/common/elb/ElasticBeanstalkController.java index d0d1ca11..164e0710 100644 --- a/src/main/java/com/sluv/server/global/common/ElasticBeanstalkController.java +++ b/sluv-api/src/main/java/com/sluv/api/common/elb/ElasticBeanstalkController.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.common; +package com.sluv.api.common.elb; import org.springframework.http.HttpStatusCode; import org.springframework.web.bind.annotation.GetMapping; diff --git a/src/main/java/com/sluv/server/global/common/exception/GlobalExceptionHandler.java b/sluv-api/src/main/java/com/sluv/api/common/exception/GlobalExceptionHandler.java similarity index 90% rename from src/main/java/com/sluv/server/global/common/exception/GlobalExceptionHandler.java rename to sluv-api/src/main/java/com/sluv/api/common/exception/GlobalExceptionHandler.java index 3e90afe8..9626dd7d 100644 --- a/src/main/java/com/sluv/server/global/common/exception/GlobalExceptionHandler.java +++ b/sluv-api/src/main/java/com/sluv/api/common/exception/GlobalExceptionHandler.java @@ -1,17 +1,17 @@ -package com.sluv.server.global.common.exception; +package com.sluv.api.common.exception; -import static com.sluv.server.global.common.exception.ErrorCode.DB_ACCESS_ERROR; -import static com.sluv.server.global.common.exception.ErrorCode.ENUM_ERROR; -import static com.sluv.server.global.common.exception.ErrorCode.INTERNAL_SERVER_ERROR; - -import com.sluv.server.global.common.response.ErrorResponse; +import com.sluv.api.common.response.ErrorResponse; +import com.sluv.common.exception.ApplicationException; import lombok.extern.slf4j.Slf4j; import org.springframework.dao.DataAccessException; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import static com.sluv.common.exception.ErrorCode.*; + @RestControllerAdvice @Slf4j public class GlobalExceptionHandler { @@ -34,9 +34,10 @@ public ResponseEntity applicationException(ApplicationException e exception.getErrorCode(), exception.getMessage() ); + HttpStatus httpStatus = HttpStatus.valueOf(exception.getHttpStatusCode().getCode()); return ResponseEntity - .status(exception.getHttpStatus()) + .status(httpStatus) .body(ErrorResponse.builder() .code(exception.getErrorCode()) .message(exception.getMessage()) diff --git a/sluv-api/src/main/java/com/sluv/api/common/image/AWSS3Controller.java b/sluv-api/src/main/java/com/sluv/api/common/image/AWSS3Controller.java new file mode 100644 index 00000000..e918b597 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/common/image/AWSS3Controller.java @@ -0,0 +1,60 @@ +package com.sluv.api.common.image; + +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.infra.s3.AWSS3Service; +import com.sluv.infra.s3.ImgExtension; +import com.sluv.infra.s3.PreSingedUrlResDto; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/app/s3/pre-signed-url") +public class AWSS3Controller { + private final AWSS3Service awss3Service; + + @Operation(summary = "user 프로필 이미지 업로드", description = "user 프로필 이미지 업로드\n imgExtension: 이미지 확장자") + @PostMapping("/user") + public ResponseEntity> getUserProfileUrl( + @RequestParam ImgExtension imgExtension) { + PreSingedUrlResDto response = awss3Service.forUserProfile(imgExtension); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "아이템 이미지 업로드", description = "아이템 이미지 업로드\n imgExtension: 이미지 확장자") + @PostMapping("/item") + public ResponseEntity> getItemImgUrl( + @RequestParam ImgExtension imgExtension) { + PreSingedUrlResDto response = awss3Service.forItem(imgExtension); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "커뮤니티 게시글 이미지 업로드", description = "커뮤니티 게시글 이미지 업로드\n imgExtension: 이미지 확장자") + @PostMapping("/question") + public ResponseEntity> getQuestionImgUrl( + @RequestParam ImgExtension imgExtension) { + PreSingedUrlResDto response = awss3Service.forCommunityPost(imgExtension); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "커뮤니티 댓글 이미지 업로드", description = "커뮤니티 댓글 이미지 업로드\n imgExtension: 이미지 확장자") + @PostMapping("/comment") + public ResponseEntity> getCommentImgUrl( + @RequestParam ImgExtension imgExtension) { + PreSingedUrlResDto response = awss3Service.forCommunityComment(imgExtension); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "옷장 이미지 업로드", description = "옷장 이미지 업로드\n imgExtension: 이미지 확장자") + @PostMapping("/closet") + public ResponseEntity> getClosetImgUrl( + @RequestParam ImgExtension imgExtension) { + PreSingedUrlResDto response = awss3Service.forCloset(imgExtension); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/common/log/RestControllerLogAop.java b/sluv-api/src/main/java/com/sluv/api/common/log/RestControllerLogAop.java new file mode 100644 index 00000000..89a10d9c --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/common/log/RestControllerLogAop.java @@ -0,0 +1,55 @@ +package com.sluv.api.common.log; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; + +@Slf4j +@Aspect +@Component +public class RestControllerLogAop { + + @Pointcut("execution(* com.sluv.api.*.controller..*.*(..))") + private void cut() { + } + + // Pointcut에 의해 필터링된 경로로 들어오는 경우 메서드 호출 전에 적용 + @Before("cut()") + public void beforeParameterLog(JoinPoint joinPoint) { + // 메서드 정보 받아오기 + Method method = getMethod(joinPoint); + log.info("======= Method name = {} =======", method.getName()); + + // 파라미터 받아오기 + Object[] args = joinPoint.getArgs(); + if (args.length <= 0) log.info("No parameter"); + for (Object arg : args) { + log.info("Parameter type = {}", arg.getClass().getSimpleName()); + log.info("Parameter value = {}", arg); + } + } + + // Poincut에 의해 필터링된 경로로 들어오는 경우 메서드 리턴 후에 적용 + @AfterReturning(value = "cut()", returning = "returnObj") + public void afterReturnLog(JoinPoint joinPoint, Object returnObj) { + // 메서드 정보 받아오기 + Method method = getMethod(joinPoint); + log.info("======= Method name = {} =======", method.getName()); + + log.info("Return type = {}", returnObj.getClass().getSimpleName()); + log.info("Return value = {}", returnObj.toString()); + } + + // JoinPoint로 메서드 정보 가져오기 + private Method getMethod(JoinPoint joinPoint) { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + return signature.getMethod(); + } +} \ No newline at end of file diff --git a/src/main/java/com/sluv/server/global/common/response/ErrorResponse.java b/sluv-api/src/main/java/com/sluv/api/common/response/ErrorResponse.java similarity index 87% rename from src/main/java/com/sluv/server/global/common/response/ErrorResponse.java rename to sluv-api/src/main/java/com/sluv/api/common/response/ErrorResponse.java index 2442b2a1..749e74b3 100644 --- a/src/main/java/com/sluv/server/global/common/response/ErrorResponse.java +++ b/sluv-api/src/main/java/com/sluv/api/common/response/ErrorResponse.java @@ -1,7 +1,7 @@ -package com.sluv.server.global.common.response; +package com.sluv.api.common.response; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.sluv.server.global.common.exception.ErrorCode; +import com.sluv.common.exception.ErrorCode; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/src/main/java/com/sluv/server/global/common/response/PaginationCountResDto.java b/sluv-api/src/main/java/com/sluv/api/common/response/PaginationCountResponse.java similarity index 59% rename from src/main/java/com/sluv/server/global/common/response/PaginationCountResDto.java rename to sluv-api/src/main/java/com/sluv/api/common/response/PaginationCountResponse.java index c5092efd..6a2520bd 100644 --- a/src/main/java/com/sluv/server/global/common/response/PaginationCountResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/common/response/PaginationCountResponse.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.common.response; +package com.sluv.api.common.response; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; @@ -8,11 +8,11 @@ @Getter @NoArgsConstructor -public class PaginationCountResDto extends PaginationResDto { +public class PaginationCountResponse extends PaginationResponse { @Schema(description = "전체 개수") private Long countNum; - public PaginationCountResDto(Boolean hasNext, Integer page, List content, Long countNum) { + public PaginationCountResponse(Boolean hasNext, Integer page, List content, Long countNum) { super(hasNext, page, content); this.countNum = countNum; } diff --git a/src/main/java/com/sluv/server/global/common/response/PaginationResDto.java b/sluv-api/src/main/java/com/sluv/api/common/response/PaginationResponse.java similarity index 76% rename from src/main/java/com/sluv/server/global/common/response/PaginationResDto.java rename to sluv-api/src/main/java/com/sluv/api/common/response/PaginationResponse.java index d7af51e0..e12d958d 100644 --- a/src/main/java/com/sluv/server/global/common/response/PaginationResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/common/response/PaginationResponse.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.common.response; +package com.sluv.api.common.response; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; @@ -12,7 +12,7 @@ @NoArgsConstructor @AllArgsConstructor @SuperBuilder -public class PaginationResDto { +public class PaginationResponse { @Schema(description = "다음 페이지 존재 여부") private Boolean hasNext; @Schema(description = "현재 page") @@ -20,8 +20,8 @@ public class PaginationResDto { @Schema(description = "데이터들") private List content; - public static PaginationResDto of(Page page, List content) { - return PaginationResDto.builder() + public static PaginationResponse create(Page page, List content) { + return PaginationResponse.builder() .page(page.getNumber()) .hasNext(page.hasNext()) .content(content) diff --git a/src/main/java/com/sluv/server/global/common/response/SuccessDataResponse.java b/sluv-api/src/main/java/com/sluv/api/common/response/SuccessDataResponse.java similarity index 58% rename from src/main/java/com/sluv/server/global/common/response/SuccessDataResponse.java rename to sluv-api/src/main/java/com/sluv/api/common/response/SuccessDataResponse.java index 0df6d1cb..eb6c4f2b 100644 --- a/src/main/java/com/sluv/server/global/common/response/SuccessDataResponse.java +++ b/sluv-api/src/main/java/com/sluv/api/common/response/SuccessDataResponse.java @@ -1,6 +1,7 @@ -package com.sluv.server.global.common.response; +package com.sluv.api.common.response; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -11,9 +12,15 @@ public class SuccessDataResponse extends SuccessResponse { private T result; - @Builder + @Builder(access = AccessLevel.PRIVATE) public SuccessDataResponse(T result) { this.result = result; } + public static SuccessDataResponse create(T result) { + return SuccessDataResponse.builder() + .result(result) + .build(); + } + } diff --git a/src/main/java/com/sluv/server/global/common/response/SuccessResponse.java b/sluv-api/src/main/java/com/sluv/api/common/response/SuccessResponse.java similarity index 79% rename from src/main/java/com/sluv/server/global/common/response/SuccessResponse.java rename to sluv-api/src/main/java/com/sluv/api/common/response/SuccessResponse.java index 6c218b4b..74033e0e 100644 --- a/src/main/java/com/sluv/server/global/common/response/SuccessResponse.java +++ b/sluv-api/src/main/java/com/sluv/api/common/response/SuccessResponse.java @@ -1,9 +1,7 @@ -package com.sluv.server.global.common.response; +package com.sluv.api.common.response; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -18,4 +16,9 @@ public class SuccessResponse { @Schema(defaultValue = "1000") private final int code = 1000; + + public static SuccessResponse create() { + return new SuccessResponse(); + } + } diff --git a/src/main/java/com/sluv/server/global/common/utils/PasswordEncoderUtil.java b/sluv-api/src/main/java/com/sluv/api/common/utils/PasswordEncoderUtil.java similarity index 59% rename from src/main/java/com/sluv/server/global/common/utils/PasswordEncoderUtil.java rename to sluv-api/src/main/java/com/sluv/api/common/utils/PasswordEncoderUtil.java index 37993873..3bcb34b0 100644 --- a/src/main/java/com/sluv/server/global/common/utils/PasswordEncoderUtil.java +++ b/sluv-api/src/main/java/com/sluv/api/common/utils/PasswordEncoderUtil.java @@ -1,17 +1,15 @@ -package com.sluv.server.global.common.utils; +package com.sluv.api.common.utils; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.stereotype.Component; -@Component public class PasswordEncoderUtil { private static final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); - public String encodePassword(String password) { + public static String encodePassword(String password) { return passwordEncoder.encode(password); } - public boolean matches(String password, String encodedPassword) { + public static boolean matches(String password, String encodedPassword) { return passwordEncoder.matches(password, encodedPassword); } } diff --git a/src/main/java/com/sluv/server/global/config/AsyncConfig.java b/sluv-api/src/main/java/com/sluv/api/config/AsyncConfig.java similarity index 97% rename from src/main/java/com/sluv/server/global/config/AsyncConfig.java rename to sluv-api/src/main/java/com/sluv/api/config/AsyncConfig.java index 7d9315f8..2df2f47a 100644 --- a/src/main/java/com/sluv/server/global/config/AsyncConfig.java +++ b/sluv-api/src/main/java/com/sluv/api/config/AsyncConfig.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.config; +package com.sluv.api.config; import java.util.concurrent.Executor; import org.springframework.context.annotation.Bean; diff --git a/sluv-api/src/main/java/com/sluv/api/config/ComponentConfig.java b/sluv-api/src/main/java/com/sluv/api/config/ComponentConfig.java new file mode 100644 index 00000000..e144ccdf --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/config/ComponentConfig.java @@ -0,0 +1,9 @@ +package com.sluv.api.config; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackages = {"com.sluv.common", "com.sluv.infra"}) +public class ComponentConfig { +} diff --git a/src/main/java/com/sluv/server/global/config/SwaggerConfig.java b/sluv-api/src/main/java/com/sluv/api/config/SwaggerConfig.java similarity index 86% rename from src/main/java/com/sluv/server/global/config/SwaggerConfig.java rename to sluv-api/src/main/java/com/sluv/api/config/SwaggerConfig.java index a251cba1..0eb5e024 100644 --- a/src/main/java/com/sluv/server/global/config/SwaggerConfig.java +++ b/sluv-api/src/main/java/com/sluv/api/config/SwaggerConfig.java @@ -1,17 +1,23 @@ -package com.sluv.server.global.config; +package com.sluv.api.config; +import com.sluv.common.annotation.CurrentUserId; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.servers.Server; +import lombok.extern.slf4j.Slf4j; +import org.springdoc.core.customizers.GlobalOperationCustomizer; import org.springdoc.core.models.GroupedOpenApi; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.Arrays; + @Configuration +@Slf4j public class SwaggerConfig { // 1개만 있는 경우 @@ -41,6 +47,16 @@ public OpenAPI api() { .components(components); } + @Bean + public GlobalOperationCustomizer customize() { + return (operation, handlerMethod) -> { + Arrays.stream(handlerMethod.getMethodParameters()) + .filter(param -> param.hasParameterAnnotation(CurrentUserId.class)) + .forEach(param -> operation.getParameters().remove(param.getParameterIndex())); + return operation; + }; + } + @Bean public GroupedOpenApi allGroup() { return GroupedOpenApi.builder() diff --git a/sluv-api/src/main/java/com/sluv/api/config/WebConfig.java b/sluv-api/src/main/java/com/sluv/api/config/WebConfig.java new file mode 100644 index 00000000..18ede6c5 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/config/WebConfig.java @@ -0,0 +1,21 @@ +package com.sluv.api.config; + +import com.sluv.api.auth.utils.AuthUserIdArgumentResolver; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +@Configuration +@RequiredArgsConstructor +public class WebConfig implements WebMvcConfigurer { + + private final AuthUserIdArgumentResolver authUserIdArgumentResolver; + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(authUserIdArgumentResolver); + } +} \ No newline at end of file diff --git a/src/main/java/com/sluv/server/global/config/security/CorsConfig.java b/sluv-api/src/main/java/com/sluv/api/config/security/CorsConfig.java similarity index 95% rename from src/main/java/com/sluv/server/global/config/security/CorsConfig.java rename to sluv-api/src/main/java/com/sluv/api/config/security/CorsConfig.java index 59f96b0d..62c73134 100644 --- a/src/main/java/com/sluv/server/global/config/security/CorsConfig.java +++ b/sluv-api/src/main/java/com/sluv/api/config/security/CorsConfig.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.config.security; +package com.sluv.api.config.security; import java.util.Arrays; import org.springframework.context.annotation.Bean; diff --git a/src/main/java/com/sluv/server/global/config/security/SpringSecurityConfig.java b/sluv-api/src/main/java/com/sluv/api/config/security/SpringSecurityConfig.java similarity index 83% rename from src/main/java/com/sluv/server/global/config/security/SpringSecurityConfig.java rename to sluv-api/src/main/java/com/sluv/api/config/security/SpringSecurityConfig.java index f17c455f..39810434 100644 --- a/src/main/java/com/sluv/server/global/config/security/SpringSecurityConfig.java +++ b/sluv-api/src/main/java/com/sluv/api/config/security/SpringSecurityConfig.java @@ -1,9 +1,10 @@ -package com.sluv.server.global.config.security; +package com.sluv.api.config.security; -import com.sluv.server.global.jwt.JwtProvider; -import com.sluv.server.global.jwt.exception.CustomAuthenticationEntryPoint; -import com.sluv.server.global.jwt.filter.ExceptionHandlerFilter; -import com.sluv.server.global.jwt.filter.JwtAuthenticationFilter; +import com.sluv.api.config.security.filter.CustomAuthenticationEntryPoint; +import com.sluv.api.config.security.filter.ExceptionHandlerFilter; +import com.sluv.api.config.security.filter.JwtAuthenticationFilter; +import com.sluv.common.jwt.JwtProvider; +import com.sluv.domain.user.service.UserDomainService; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -23,6 +24,7 @@ public class SpringSecurityConfig { private final JwtProvider jwtProvider; + private final UserDomainService userDomainService; private final ExceptionHandlerFilter exceptionHandlerFilter = new ExceptionHandlerFilter(); private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint; @@ -77,7 +79,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { ) .exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint) .and() - .addFilterBefore(new JwtAuthenticationFilter(jwtProvider), UsernamePasswordAuthenticationFilter.class) +// .addFilterBefore(new JwtAuthenticationFilter(jwtProvider, userDomainService), + .addFilterBefore(new JwtAuthenticationFilter(jwtProvider), + UsernamePasswordAuthenticationFilter.class) .addFilterBefore(exceptionHandlerFilter, JwtAuthenticationFilter.class); return http.build(); diff --git a/src/main/java/com/sluv/server/global/jwt/exception/CustomAuthenticationEntryPoint.java b/sluv-api/src/main/java/com/sluv/api/config/security/filter/CustomAuthenticationEntryPoint.java similarity index 68% rename from src/main/java/com/sluv/server/global/jwt/exception/CustomAuthenticationEntryPoint.java rename to sluv-api/src/main/java/com/sluv/api/config/security/filter/CustomAuthenticationEntryPoint.java index fbe1793f..b1c0ba7d 100644 --- a/src/main/java/com/sluv/server/global/jwt/exception/CustomAuthenticationEntryPoint.java +++ b/sluv-api/src/main/java/com/sluv/api/config/security/filter/CustomAuthenticationEntryPoint.java @@ -1,23 +1,24 @@ -package com.sluv.server.global.jwt.exception; +package com.sluv.api.config.security.filter; +import com.sluv.common.jwt.exception.NoAuthorizationTokenException; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.stereotype.Component; -import java.io.IOException; - @Slf4j @Component public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override - public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { - if (request.getHeader("Authorization") == null){ + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException, ServletException { + if (request.getHeader("Authorization") == null) { throw new NoAuthorizationTokenException(); } } diff --git a/src/main/java/com/sluv/server/global/jwt/filter/ExceptionHandlerFilter.java b/sluv-api/src/main/java/com/sluv/api/config/security/filter/ExceptionHandlerFilter.java similarity index 81% rename from src/main/java/com/sluv/server/global/jwt/filter/ExceptionHandlerFilter.java rename to sluv-api/src/main/java/com/sluv/api/config/security/filter/ExceptionHandlerFilter.java index f099b0e6..9bd64381 100644 --- a/src/main/java/com/sluv/server/global/jwt/filter/ExceptionHandlerFilter.java +++ b/sluv-api/src/main/java/com/sluv/api/config/security/filter/ExceptionHandlerFilter.java @@ -1,8 +1,8 @@ -package com.sluv.server.global.jwt.filter; +package com.sluv.api.config.security.filter; import com.fasterxml.jackson.databind.ObjectMapper; -import com.sluv.server.global.common.response.ErrorResponse; -import com.sluv.server.global.jwt.exception.TokenException; +import com.sluv.api.common.response.ErrorResponse; +import com.sluv.common.jwt.exception.TokenException; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -23,11 +23,10 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse try { filterChain.doFilter(request, response); } catch (TokenException e) { - setErrorResponse(response, e.getMessage(), e.getErrorCode(), e.getHttpStatus()); + int code = e.getHttpStatusCode().getCode(); + setErrorResponse(response, e.getMessage(), e.getErrorCode(), HttpStatus.valueOf(code)); } -// } catch (MemberNotFoundException e) { -// setErrorResponse(response, e.getMessage(), e.getErrorCode(),e.getHttpStatus()); -// } + } private void setErrorResponse(HttpServletResponse response, String message, int errorCode, HttpStatus status) diff --git a/sluv-api/src/main/java/com/sluv/api/config/security/filter/JwtAuthenticationFilter.java b/sluv-api/src/main/java/com/sluv/api/config/security/filter/JwtAuthenticationFilter.java new file mode 100644 index 00000000..23c85e34 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/config/security/filter/JwtAuthenticationFilter.java @@ -0,0 +1,49 @@ +package com.sluv.api.config.security.filter; + +import com.sluv.api.auth.dto.MemberDetails; +import com.sluv.common.jwt.JwtProvider; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +import static com.sluv.common.constant.ConstantData.ACCESS_TOKEN_HEADER; +import static com.sluv.common.constant.ConstantData.TOKEN_TYPER; + +@RequiredArgsConstructor +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + private final JwtProvider jwtProvider; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + String token = resolveToken(request); + if (token != null && jwtProvider.validateToken(token)) { + Authentication authentication = getAuthentication(token); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + + filterChain.doFilter(request, response); + } + + private String resolveToken(HttpServletRequest request) { + return request.getHeader(ACCESS_TOKEN_HEADER); + } + + private Authentication getAuthentication(String headerToken) { + String token = headerToken.split(TOKEN_TYPER + " ")[1]; + Long userId = jwtProvider.getUserId(token); + UserDetails userDetails = new MemberDetails(userId); + return new UsernamePasswordAuthenticationToken(userDetails, headerToken, userDetails.getAuthorities()); + } + +} diff --git a/src/main/java/com/sluv/server/domain/item/controller/HashtagController.java b/sluv-api/src/main/java/com/sluv/api/item/controller/HashtagController.java similarity index 57% rename from src/main/java/com/sluv/server/domain/item/controller/HashtagController.java rename to sluv-api/src/main/java/com/sluv/api/item/controller/HashtagController.java index 91cb90fe..40659215 100644 --- a/src/main/java/com/sluv/server/domain/item/controller/HashtagController.java +++ b/sluv-api/src/main/java/com/sluv/api/item/controller/HashtagController.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.item.controller; - -import com.sluv.server.domain.item.dto.HashtagPostResponseDto; -import com.sluv.server.domain.item.dto.HashtagRequestDto; -import com.sluv.server.domain.item.dto.HashtagResponseDto; -import com.sluv.server.domain.item.service.HashtagService; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; +package com.sluv.api.item.controller; + +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.item.dto.HashtagPostResponseDto; +import com.sluv.api.item.dto.HashtagRequestDto; +import com.sluv.api.item.dto.HashtagResponseDto; +import com.sluv.api.item.service.HashtagService; import io.swagger.v3.oas.annotations.Operation; import jakarta.annotation.Nullable; import lombok.RequiredArgsConstructor; @@ -27,15 +27,10 @@ public class HashtagController { @Operation(summary = "해쉬태그 검색(Pagination)", description = "Pagination 적용") @GetMapping("") - public ResponseEntity>> getHashtag( + public ResponseEntity>> getHashtag( @Nullable @RequestParam String name, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(hashtagService.getHashtag(name, pageable)) - .build() - - ); + PaginationResponse response = hashtagService.getHashtag(name, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "새로운 해쉬태그 등록", @@ -43,10 +38,7 @@ public ResponseEntity>> @PostMapping("") public ResponseEntity> postHashtag( @RequestBody HashtagRequestDto requestDto) { - - return ResponseEntity.ok().body(SuccessDataResponse.builder() - .result(hashtagService.postHashtag(requestDto)) - .build() - ); + HashtagPostResponseDto response = hashtagService.postHashtag(requestDto); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } } diff --git a/src/main/java/com/sluv/server/domain/item/controller/ItemCategoryController.java b/sluv-api/src/main/java/com/sluv/api/item/controller/ItemCategoryController.java similarity index 61% rename from src/main/java/com/sluv/server/domain/item/controller/ItemCategoryController.java rename to sluv-api/src/main/java/com/sluv/api/item/controller/ItemCategoryController.java index 49fc87b4..1db5eef6 100644 --- a/src/main/java/com/sluv/server/domain/item/controller/ItemCategoryController.java +++ b/sluv-api/src/main/java/com/sluv/api/item/controller/ItemCategoryController.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.item.controller; +package com.sluv.api.item.controller; -import com.sluv.server.domain.item.dto.ItemCategoryParentResponseDto; -import com.sluv.server.domain.item.service.ItemCategoryService; -import com.sluv.server.global.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.item.dto.ItemCategoryParentResponseDto; +import com.sluv.api.item.service.ItemCategoryService; import io.swagger.v3.oas.annotations.Operation; import java.util.List; import lombok.RequiredArgsConstructor; @@ -22,11 +22,8 @@ public class ItemCategoryController { @GetMapping("") public ResponseEntity>> getItemCategory() { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemCategoryService.getItemCategory()) - .build() - ); + List response = itemCategoryService.getItemCategory(); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } } diff --git a/sluv-api/src/main/java/com/sluv/api/item/controller/ItemController.java b/sluv-api/src/main/java/com/sluv/api/item/controller/ItemController.java new file mode 100644 index 00000000..79de84f6 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/item/controller/ItemController.java @@ -0,0 +1,239 @@ +package com.sluv.api.item.controller; + +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.api.item.dto.ItemDetailResDto; +import com.sluv.api.item.dto.ItemPostReqDto; +import com.sluv.api.item.dto.ItemPostResDto; +import com.sluv.api.item.service.ItemService; +import com.sluv.common.annotation.CurrentUserId; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.exception.StandardNotFoundException; +import com.sluv.domain.search.dto.SearchFilterReqDto; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/app/item") +@Slf4j +public class ItemController { + + private final ItemService itemService; + + /** + * 아이템 상세조회 + */ + @Operation(summary = "*특정 아이템 게시글 상세조회", description = "User 토큰 필요") + @GetMapping("/{itemId}") + public ResponseEntity> getItemDetail(@CurrentUserId Long userId, + @PathVariable("itemId") Long itemId) { + ItemDetailResDto response = itemService.getItemDetail(userId, itemId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + /** + * 같은 셀럽 아이템 리스트 -> 10개 같은 브랜드 아이템 리스트 -> 10개 + */ + @Operation(summary = "*같은 셀럽 아이템 리스트 조회", description = "User 토큰 필요") + @GetMapping("/sameCelebItem") + public ResponseEntity>> getSameCelebItem( + @CurrentUserId Long userId, @RequestParam("itemId") Long itemId) { + List response = itemService.getSameCelebItems(userId, itemId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + /** + * 같은 브랜드의 아이템 -> 브랜드를 기준으로 최신 아이템 검색 -> 10개 + */ + @Operation(summary = "*같은 브랜드의 아이템 리스트 조회", description = "User 토큰 필요") + @GetMapping("/sameBrandItem") + public ResponseEntity>> getSameBrandItem( + @CurrentUserId Long userId, @RequestParam("itemId") Long itemId) { + List response = itemService.getSameBrandItem(userId, itemId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + /** + * 함께 스크랩한 아이템 -> 10개 + */ + @Operation(summary = "*함께 스크랩한 아이템 리스트 조회", description = "User 토큰 필요") + @GetMapping("/togetherScrap") + public ResponseEntity>> getTogetherScrapItem( + @CurrentUserId Long userId, + @RequestParam("itemId") Long itemId) { + List response = itemService.getTogetherScrapItem(userId, itemId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*최근 본 아이템 조회", description = "User 토큰 필요. Pagination 적용. 최근 본 순서로 정렬.") + @GetMapping("/recent") + public ResponseEntity>> getRecentItem( + @CurrentUserId Long userId, Pageable pageable) { + PaginationResponse response = itemService.getRecentItem(userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*찜한 아이템 조회", description = "User 토큰 필요. Pagination 적용. 스크랩한 최신순으로 정렬.") + @GetMapping("/scrap") + public ResponseEntity>> getScrapItem( + @CurrentUserId Long userId, Pageable pageable) { + PaginationResponse response = itemService.getScrapItem(userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*아이템 등록 및 수정", description = "User 토큰 필요") + @PostMapping("") + public ResponseEntity> postItem(@CurrentUserId Long userId, + @RequestBody ItemPostReqDto reqDto) { + ItemPostResDto response = itemService.postItem(userId, reqDto); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "아이템 게시글 좋아요", description = "User 토큰 필요") + @PostMapping("/{itemId}/like") + public ResponseEntity postItemLike(@CurrentUserId Long userId, + @PathVariable("itemId") Long itemId) { + itemService.postItemLike(userId, itemId); + return ResponseEntity.ok().body(SuccessResponse.create()); + } + + @Operation(summary = "아이템 게시글 삭제") + @DeleteMapping("/{itemId}") + public ResponseEntity deleteItem(@PathVariable("itemId") Long itemId) { + itemService.deleteItem(itemId); + return ResponseEntity.ok().body(SuccessResponse.create()); + } + + /* 홈페이지 기능 */ + + /** + * 초반: 좋아요 수, 스크랩 수, 조회수를 모두 합산하여 높은 순서 + 착용 최신순으로 정렬 후반: 유저별 검색기록, 관심셀럽을 기준으로 조회 + */ + @Operation(summary = "*유저별 추천 인기 아이템 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/recommend") + public ResponseEntity>> getRecommendItem( + @CurrentUserId Long userId, Pageable pageable) { + log.info("유저별 추천 인기 아이템 조회"); + PaginationResponse response = itemService.getRecommendItem(userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*핫한 셀럽들이 선택한 여름나기 아이템 조회", + description = "User 토큰 필요. Pagination 적용. Ordering -> 최신순, 인기순, 저가순, 고가순. Filtering -> Price, Color.") + @GetMapping("/summer") + public ResponseEntity>> getSummerItem( + @CurrentUserId Long userId, + Pageable pageable, + SearchFilterReqDto dto) { + log.info("핫한 셀럽들이 선택한 여름나기 아이템 조회"); + PaginationResponse response = itemService.getSummerItem(userId, pageable, dto); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*지금 당장 구매가능한 아이템 조회", + description = "User 토큰 필요. Pagination 적용. Filtering -> Category, Price, Color") + @GetMapping("/nowBuy") + public ResponseEntity>> getNowBuyItem( + @CurrentUserId Long userId, + Pageable pageable, + SearchFilterReqDto dto) { + log.info("지금 당장 구매가능한 아이템 조회"); + PaginationResponse response = itemService.getNowBuyItem(userId, pageable, dto); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*실시간 뉴 아이템 조회", description = "WhenDiscovery 기준 아이템 조회. User 토큰 필요. Pagination 적용.") + @GetMapping("/new") + public ResponseEntity>> getNewItem( + @CurrentUserId Long userId, + Pageable pageable) { + log.info("최신 등록 아이템 조회"); + PaginationResponse response = itemService.getNewItem(userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*주목해야할 럭셔리 무드 아이템 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/luxury") + public ResponseEntity>> getLuxuryItem( + @CurrentUserId Long userId, + Pageable pageable, + SearchFilterReqDto dto) { + log.info("주목해야할 럭셔리 무드 아이템 조회"); + PaginationResponse response = itemService.getLuxuryItem(userId, pageable, dto); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*가성비 좋은 선물 아이템 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/efficient") + public ResponseEntity>> getEfficientItem( + @CurrentUserId Long userId, + Pageable pageable, + SearchFilterReqDto filterReqDto) { + PaginationResponse response = itemService.getEfficientItem(userId, pageable, filterReqDto); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Deprecated + @Operation(summary = "*일간/주간 HOT 아이템 조회", description = "User 토큰 필요. 정적으로 21개 조회.") + @GetMapping("/hotItem") + public ResponseEntity>> getHotItem(@CurrentUserId Long userId, + @RequestParam("standard") String standard) { + log.info("일간 주간 핫 아이템 조회: {}", standard); + List result; + if (standard.equals("주간")) { + result = itemService.getWeekHotItem(userId); + } else if (standard.equals("일간")) { + result = itemService.getDayHotItem(userId); + } else { + throw new StandardNotFoundException(); + } + + return ResponseEntity.ok().body(SuccessDataResponse.create(result)); + } + + /** + * 셀럽 변경은 백오피스 개발시 다시 적용 예정 + */ + @Operation(summary = "*요즘 Hot Celeb의 아이템 조회", + description = "User 토큰 필요. Pagination 적용. Filtering 적용. Ordering 적용.") + @GetMapping("/hotCeleb") + public ResponseEntity>> getHotCelebItem( + @CurrentUserId Long userId, Pageable pageable, SearchFilterReqDto dto) { + log.info("요즘 핫셀럽 아이템 조회"); + PaginationResponse response = itemService.getHotCelebItem(userId, pageable, dto); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + /** + * 현재 실시간 -> 24시간 기준 추가 예정 10개가 안되면 최신순으로 랜덤으로 채우기 + */ + @Operation(summary = "*큐레이션 아이템 조회", + description = "오늘 올라온 관심 셀럽의 아이템을 인기 순으로 검색. User 토큰 필요. 정적으로 10개.") + @GetMapping("/curation") + public ResponseEntity>> getCurationItem( + @CurrentUserId Long userId) { + log.info("큐레이션 아이템 조회"); + List response = itemService.getCurationItem(userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + /** + * 전체 아이템 중 랜덤으로 4개 조회, 홈 회면 접속 할 때마다 리프레쉬 + */ + @Operation(summary = "*이 아이템은 어때요 아이템 조회", description = "User 토큰 필요.") + @GetMapping("/howabout") + public ResponseEntity>> getHowAboutItem( + @CurrentUserId Long userId) { + log.info("이 아이템은 어때요 아이템 조회"); + List response = itemService.getHowAboutItem(userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } +} diff --git a/src/main/java/com/sluv/server/domain/item/controller/ItemEditController.java b/sluv-api/src/main/java/com/sluv/api/item/controller/ItemEditController.java similarity index 62% rename from src/main/java/com/sluv/server/domain/item/controller/ItemEditController.java rename to sluv-api/src/main/java/com/sluv/api/item/controller/ItemEditController.java index 6d2ef282..fc6144b3 100644 --- a/src/main/java/com/sluv/server/domain/item/controller/ItemEditController.java +++ b/sluv-api/src/main/java/com/sluv/api/item/controller/ItemEditController.java @@ -1,14 +1,13 @@ -package com.sluv.server.domain.item.controller; +package com.sluv.api.item.controller; -import com.sluv.server.domain.item.dto.ItemEditReqDto; -import com.sluv.server.domain.item.service.ItemEditReqService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.SuccessResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.api.item.dto.ItemEditReqDto; +import com.sluv.api.item.service.ItemEditReqService; +import com.sluv.common.annotation.CurrentUserId; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -24,12 +23,10 @@ public class ItemEditController { @Operation(summary = "*아이템 게시글 수정 요청", description = "User 토큰 필요") @PostMapping("/{itemId}/edit-req") - public ResponseEntity postItemEdit(@AuthenticationPrincipal User user, + public ResponseEntity postItemEdit(@CurrentUserId Long userId, @PathVariable(name = "itemId") Long itemId, @RequestBody ItemEditReqDto dto) { - itemEditReqService.postItemEdit(user, itemId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + itemEditReqService.postItemEdit(userId, itemId, dto); + return ResponseEntity.ok().body(SuccessResponse.create()); } } diff --git a/src/main/java/com/sluv/server/domain/item/controller/ItemReportController.java b/sluv-api/src/main/java/com/sluv/api/item/controller/ItemReportController.java similarity index 62% rename from src/main/java/com/sluv/server/domain/item/controller/ItemReportController.java rename to sluv-api/src/main/java/com/sluv/api/item/controller/ItemReportController.java index 2130c296..49dc5b58 100644 --- a/src/main/java/com/sluv/server/domain/item/controller/ItemReportController.java +++ b/sluv-api/src/main/java/com/sluv/api/item/controller/ItemReportController.java @@ -1,14 +1,13 @@ -package com.sluv.server.domain.item.controller; +package com.sluv.api.item.controller; -import com.sluv.server.domain.item.dto.ItemReportReqDto; -import com.sluv.server.domain.item.service.ItemReportService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.SuccessResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.api.item.dto.ItemReportReqDto; +import com.sluv.api.item.service.ItemReportService; +import com.sluv.common.annotation.CurrentUserId; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -24,12 +23,10 @@ public class ItemReportController { @Operation(summary = "*아이템 게시글 신고", description = "User 토큰 필요") @PostMapping("/{itemId}/report") - public ResponseEntity postItemReport(@AuthenticationPrincipal User user, + public ResponseEntity postItemReport(@CurrentUserId Long userId, @PathVariable(name = "itemId") Long itemId, @RequestBody ItemReportReqDto dto) { - itemReportService.postItemReport(user, itemId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + itemReportService.postItemReport(userId, itemId, dto); + return ResponseEntity.ok().body(SuccessResponse.create()); } } diff --git a/src/main/java/com/sluv/server/domain/item/controller/PlaceRankController.java b/sluv-api/src/main/java/com/sluv/api/item/controller/PlaceRankController.java similarity index 51% rename from src/main/java/com/sluv/server/domain/item/controller/PlaceRankController.java rename to sluv-api/src/main/java/com/sluv/api/item/controller/PlaceRankController.java index 4f2cdc73..3da3b407 100644 --- a/src/main/java/com/sluv/server/domain/item/controller/PlaceRankController.java +++ b/sluv-api/src/main/java/com/sluv/api/item/controller/PlaceRankController.java @@ -1,18 +1,17 @@ -package com.sluv.server.domain.item.controller; +package com.sluv.api.item.controller; -import com.sluv.server.domain.item.dto.HotPlaceResDto; -import com.sluv.server.domain.item.dto.PlaceRankReqDto; -import com.sluv.server.domain.item.dto.PlaceRankResDto; -import com.sluv.server.domain.item.service.ItemService; -import com.sluv.server.domain.item.service.PlaceRankService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.api.item.dto.HotPlaceResDto; +import com.sluv.api.item.dto.PlaceRankReqDto; +import com.sluv.api.item.dto.PlaceRankResDto; +import com.sluv.api.item.service.ItemService; +import com.sluv.api.item.service.PlaceRankService; +import com.sluv.common.annotation.CurrentUserId; import io.swagger.v3.oas.annotations.Operation; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -32,54 +31,40 @@ public class PlaceRankController { @Operation(summary = "인기 장소 조회", description = "인기 장소 조회. 상위 10개") @GetMapping("/top") public ResponseEntity>> getTopPlace() { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getTopPlace()) - .build() - ); + List response = itemService.getTopPlace(); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*유저가 최근 입력한 장소 검색", description = "User 토큰 필요") @GetMapping("/recent") public ResponseEntity>> getRecentPlaceTop20( - @AuthenticationPrincipal User user) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(placeRankService.getRecentPlaceTop20(user)) - .build() - ); + @CurrentUserId Long userId) { + List response = placeRankService.getRecentPlaceTop20(userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*최근 입력한 장소 등록", description = "User 토큰 필요.") @PostMapping("") - public ResponseEntity postPlace(@AuthenticationPrincipal User user, + public ResponseEntity postPlace(@CurrentUserId Long userId, @RequestBody PlaceRankReqDto dto) { - placeRankService.postPlace(user, dto); + placeRankService.postPlace(userId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*유저의 최근 입력한 장소 모두 삭제", description = "User 토큰 필요.") @DeleteMapping("/all") - public ResponseEntity deleteAllPlace(@AuthenticationPrincipal User user) { - placeRankService.deleteAllPlace(user); + public ResponseEntity deleteAllPlace(@CurrentUserId Long userId) { + placeRankService.deleteAllPlace(userId); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*유저의 특정 최근 입력한 장소 삭제", description = "User 토큰 필요") @DeleteMapping("") - public ResponseEntity deletePlace(@AuthenticationPrincipal User user, + public ResponseEntity deletePlace(@CurrentUserId Long userId, @RequestParam("placename") String placeName) { - placeRankService.deletePlace(user, placeName); - - return ResponseEntity.ok().body( - new SuccessResponse() - ); + placeRankService.deletePlace(userId, placeName); + return ResponseEntity.ok().body(SuccessResponse.create()); } } diff --git a/sluv-api/src/main/java/com/sluv/api/item/controller/TempItemController.java b/sluv-api/src/main/java/com/sluv/api/item/controller/TempItemController.java new file mode 100644 index 00000000..eac02412 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/item/controller/TempItemController.java @@ -0,0 +1,69 @@ +package com.sluv.api.item.controller; + +import com.sluv.api.common.response.PaginationCountResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.api.item.dto.TempItemCountResDto; +import com.sluv.api.item.dto.TempItemPostReqDto; +import com.sluv.api.item.dto.TempItemPostResDto; +import com.sluv.api.item.dto.TempItemResDto; +import com.sluv.api.item.service.TempItemService; +import com.sluv.common.annotation.CurrentUserId; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/app/item/temp") +@Slf4j +public class TempItemController { + private final TempItemService tempItemService; + + @Operation(summary = "*임시저장 아이템 리스트 조회", description = "User 토큰 필요") + @GetMapping("") + public ResponseEntity>> getTempItemList( + @CurrentUserId Long userId, Pageable pageable) { + PaginationCountResponse response = tempItemService.getTempItemList(userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*임시저장 아이템 갯수 조회", description = "User 토큰 필요") + @GetMapping("/count") + public ResponseEntity> getTempItemCount( + @CurrentUserId Long userId) { + TempItemCountResDto response = tempItemService.countTempItemCount(userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*Item 임시저장", description = "User 토큰 필요") + @PostMapping("") + public ResponseEntity> postTempItem(@CurrentUserId Long userId, + @RequestBody TempItemPostReqDto reqDto) { + TempItemPostResDto response = TempItemPostResDto.of(tempItemService.postTempItem(userId, reqDto)); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "임시저장 아이템 선택삭제", description = "User 토큰 필요") + @DeleteMapping("/{tempItemId}") + public ResponseEntity deleteTempItem(@PathVariable Long tempItemId) { + tempItemService.deleteTempItem(tempItemId); + return ResponseEntity.ok().body(SuccessResponse.create()); + } + + @Operation(summary = "*임시저장 아이템 전체삭제", description = "User 토큰 필요") + @DeleteMapping("") + public ResponseEntity deleteAllTempItem(@CurrentUserId Long userId) { + tempItemService.deleteAllTempItem(userId); + return ResponseEntity.ok().body(SuccessResponse.create()); + } +} diff --git a/src/main/java/com/sluv/server/domain/item/dto/HashtagPostResponseDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/HashtagPostResponseDto.java similarity index 87% rename from src/main/java/com/sluv/server/domain/item/dto/HashtagPostResponseDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/HashtagPostResponseDto.java index f3690b58..119d5e2e 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/HashtagPostResponseDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/HashtagPostResponseDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.item.entity.hashtag.Hashtag; +import com.sluv.domain.item.entity.hashtag.Hashtag; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/item/dto/HashtagRequestDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/HashtagRequestDto.java similarity index 89% rename from src/main/java/com/sluv/server/domain/item/dto/HashtagRequestDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/HashtagRequestDto.java index 4acbbea9..656d129c 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/HashtagRequestDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/HashtagRequestDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/item/dto/HashtagResponseDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/HashtagResponseDto.java similarity index 89% rename from src/main/java/com/sluv/server/domain/item/dto/HashtagResponseDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/HashtagResponseDto.java index 5222fa97..d6ed24ed 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/HashtagResponseDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/HashtagResponseDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.item.entity.hashtag.Hashtag; +import com.sluv.domain.item.entity.hashtag.Hashtag; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/item/dto/HotPlaceResDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/HotPlaceResDto.java similarity index 92% rename from src/main/java/com/sluv/server/domain/item/dto/HotPlaceResDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/HotPlaceResDto.java index 3861735b..9db03aa3 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/HotPlaceResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/HotPlaceResDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemCategoryChildResponseDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemCategoryChildResponseDto.java similarity index 87% rename from src/main/java/com/sluv/server/domain/item/dto/ItemCategoryChildResponseDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/ItemCategoryChildResponseDto.java index b6d69671..2ad1b522 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemCategoryChildResponseDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemCategoryChildResponseDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.item.entity.ItemCategory; +import com.sluv.domain.item.entity.ItemCategory; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemCategoryDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemCategoryDto.java similarity index 92% rename from src/main/java/com/sluv/server/domain/item/dto/ItemCategoryDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/ItemCategoryDto.java index 381bee23..3cb09df0 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemCategoryDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemCategoryDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.item.entity.ItemCategory; +import com.sluv.domain.item.entity.ItemCategory; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemCategoryParentResponseDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemCategoryParentResponseDto.java similarity index 91% rename from src/main/java/com/sluv/server/domain/item/dto/ItemCategoryParentResponseDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/ItemCategoryParentResponseDto.java index 45f68408..c2bf1d27 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemCategoryParentResponseDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemCategoryParentResponseDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.item.entity.ItemCategory; +import com.sluv.domain.item.entity.ItemCategory; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemDetailFixData.java b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemDetailFixData.java similarity index 53% rename from src/main/java/com/sluv/server/domain/item/dto/ItemDetailFixData.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/ItemDetailFixData.java index 35262e6a..8f7a8b0c 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemDetailFixData.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemDetailFixData.java @@ -1,13 +1,15 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.brand.dto.BrandSearchResDto; -import com.sluv.server.domain.brand.dto.NewBrandPostResDto; -import com.sluv.server.domain.brand.entity.NewBrand; -import com.sluv.server.domain.celeb.dto.CelebSearchResDto; -import com.sluv.server.domain.celeb.dto.NewCelebPostResDto; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.user.dto.UserInfoDto; +import com.sluv.api.brand.dto.response.BrandSearchResponse; +import com.sluv.api.brand.dto.response.NewBrandPostResponse; +import com.sluv.api.celeb.dto.response.CelebSearchResponse; +import com.sluv.api.celeb.dto.response.NewCelebPostResponse; +import com.sluv.domain.brand.entity.NewBrand; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.item.dto.ItemImgDto; +import com.sluv.domain.item.dto.ItemLinkDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.user.dto.UserInfoDto; import java.io.Serializable; import java.time.LocalDateTime; import java.util.List; @@ -21,14 +23,14 @@ @AllArgsConstructor @Builder public class ItemDetailFixData implements Serializable { - private List imgList; - private CelebSearchResDto celeb; - private NewCelebPostResDto newCeleb; + private List imgList; + private CelebSearchResponse celeb; + private NewCelebPostResponse newCeleb; private ItemCategoryDto category; private String itemName; - private BrandSearchResDto brand; - private NewBrandPostResDto newBrand; - private List linkList; + private BrandSearchResponse brand; + private NewBrandPostResponse newBrand; + private List linkList; private UserInfoDto writer; private LocalDateTime whenDiscovery; private String whereDiscovery; @@ -38,24 +40,24 @@ public class ItemDetailFixData implements Serializable { private String infoSource; private String color; - public static ItemDetailFixData of(Item item, CelebSearchResDto celeb, NewCeleb newCeleb, - BrandSearchResDto brand, NewBrand newBrand, ItemCategoryDto itemCategory, - UserInfoDto writerInfo, List imgList, - List linkList, + public static ItemDetailFixData of(Item item, CelebSearchResponse celeb, NewCeleb newCeleb, + BrandSearchResponse brand, NewBrand newBrand, ItemCategoryDto itemCategory, + UserInfoDto writerInfo, List imgList, + List linkList, List hashtagList ) { - NewCelebPostResDto newCelebPostResDto = newCeleb == null ? null : NewCelebPostResDto.of(newCeleb); - NewBrandPostResDto newBrandPostResDto = newBrand == null ? null : NewBrandPostResDto.of(newBrand); + NewCelebPostResponse newCelebPostResponse = newCeleb == null ? null : NewCelebPostResponse.of(newCeleb); + NewBrandPostResponse newBrandPostResponse = newBrand == null ? null : NewBrandPostResponse.of(newBrand); return ItemDetailFixData.builder() .imgList(imgList) .celeb(celeb) - .newCeleb(newCelebPostResDto) + .newCeleb(newCelebPostResponse) .category(itemCategory) .itemName(item.getName()) .brand(brand) - .newBrand(newBrandPostResDto) + .newBrand(newBrandPostResponse) .linkList(linkList) .writer(writerInfo) .whenDiscovery(item.getWhenDiscovery()) diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemDetailResDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemDetailResDto.java similarity index 77% rename from src/main/java/com/sluv/server/domain/item/dto/ItemDetailResDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/ItemDetailResDto.java index 24cfb0b3..5a1f14a2 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemDetailResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemDetailResDto.java @@ -1,11 +1,13 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.brand.dto.BrandSearchResDto; -import com.sluv.server.domain.brand.dto.NewBrandPostResDto; -import com.sluv.server.domain.celeb.dto.CelebSearchResDto; -import com.sluv.server.domain.celeb.dto.NewCelebPostResDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.user.dto.UserInfoDto; +import com.sluv.api.brand.dto.response.BrandSearchResponse; +import com.sluv.api.brand.dto.response.NewBrandPostResponse; +import com.sluv.api.celeb.dto.response.CelebSearchResponse; +import com.sluv.api.celeb.dto.response.NewCelebPostResponse; +import com.sluv.domain.item.dto.ItemImgDto; +import com.sluv.domain.item.dto.ItemLinkDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.user.dto.UserInfoDto; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.Size; import java.time.LocalDateTime; @@ -27,19 +29,19 @@ public class ItemDetailResDto { @Schema(description = "item 이미지 리스트") - private List imgList; + private List imgList; @Schema(description = "celeb") - private CelebSearchResDto celeb; + private CelebSearchResponse celeb; @Schema(description = "새로운 Celeb") - private NewCelebPostResDto newCeleb; + private NewCelebPostResponse newCeleb; @Schema(description = "아이템 카테고리") private ItemCategoryDto category; @Schema(description = "아이템명") private String itemName; @Schema(description = "브랜드") - private BrandSearchResDto brand; + private BrandSearchResponse brand; @Schema(description = "새로운 Brand") - private NewBrandPostResDto newBrand; + private NewBrandPostResponse newBrand; @Schema(description = "좋아요 수") private Integer likeNum; @Schema(description = "좋아요 여부") @@ -51,7 +53,7 @@ public class ItemDetailResDto { @Schema(description = "조회수") private Long viewNum; @Schema(description = "item 링크 리스트") - private List linkList; + private List linkList; @Schema(description = "게시글 작성자") private UserInfoDto writer; @Schema(description = "발견 시간 ex)2021-11-20T09:10:20") @@ -77,12 +79,12 @@ public class ItemDetailResDto { @Schema(description = "현재 유저가 작성한 글인지 판단") private Boolean hasMine; - public static ItemDetailResDto of(Item item, CelebSearchResDto celeb, NewCelebPostResDto newCeleb, - BrandSearchResDto brand, NewBrandPostResDto newBrand, + public static ItemDetailResDto of(Item item, CelebSearchResponse celeb, NewCelebPostResponse newCeleb, + BrandSearchResponse brand, NewBrandPostResponse newBrand, ItemCategoryDto itemCategory, Integer likeNum, Boolean likeStatus, Integer scrapNum, Boolean scrapStatus, Long viewNum, UserInfoDto writerInfo, Boolean followStatus, Boolean hasMine, - List imgList, List linkList, + List imgList, List linkList, List hashtagList ) { diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemEditReqDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemEditReqDto.java similarity index 80% rename from src/main/java/com/sluv/server/domain/item/dto/ItemEditReqDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/ItemEditReqDto.java index 0a7a0c60..db3e563c 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemEditReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemEditReqDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.item.enums.ItemEditReqReason; +import com.sluv.domain.item.enums.ItemEditReqReason; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemHashtagResponseDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemHashtagResponseDto.java similarity index 88% rename from src/main/java/com/sluv/server/domain/item/dto/ItemHashtagResponseDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/ItemHashtagResponseDto.java index 2dbb1fc1..1bef23dd 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemHashtagResponseDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemHashtagResponseDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.item.entity.hashtag.Hashtag; +import com.sluv.domain.item.entity.hashtag.Hashtag; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemKeywordSearchResDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemKeywordSearchResDto.java similarity index 93% rename from src/main/java/com/sluv/server/domain/item/dto/ItemKeywordSearchResDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/ItemKeywordSearchResDto.java index 3524d040..c4c80553 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemKeywordSearchResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemKeywordSearchResDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.item.entity.Item; +import com.sluv.domain.item.entity.Item; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemPostReqDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemPostReqDto.java similarity index 89% rename from src/main/java/com/sluv/server/domain/item/dto/ItemPostReqDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/ItemPostReqDto.java index c0a47465..54adbb82 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemPostReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemPostReqDto.java @@ -1,5 +1,7 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; +import com.sluv.domain.item.dto.ItemImgDto; +import com.sluv.domain.item.dto.ItemLinkDto; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -18,7 +20,7 @@ public class ItemPostReqDto { @Schema(description = "Item id(PK)") private Long id; @Schema(description = "item 이미지 리스트") - private List imgList; + private List imgList; @Schema(description = "celebId") private Long celebId; @Schema(description = "발견 시간 ex)2021-11-20T09:10:20") @@ -51,7 +53,7 @@ public class ItemPostReqDto { @Schema(description = "해쉬태그 Id 리스트") private List hashTagIdList; @Schema(description = "item 링크 리스트") - private List linkList; + private List linkList; @Schema(description = "추가정보를 발견한 출처") private String infoSource; diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemPostResDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemPostResDto.java similarity index 92% rename from src/main/java/com/sluv/server/domain/item/dto/ItemPostResDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/ItemPostResDto.java index 149cbdcd..2727d49d 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemPostResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemPostResDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemReportReqDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemReportReqDto.java similarity index 80% rename from src/main/java/com/sluv/server/domain/item/dto/ItemReportReqDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/ItemReportReqDto.java index 0af3231f..06052b7b 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemReportReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/ItemReportReqDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.item.enums.ItemReportReason; +import com.sluv.domain.item.enums.ItemReportReason; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/item/dto/PlaceRankReqDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/PlaceRankReqDto.java similarity index 85% rename from src/main/java/com/sluv/server/domain/item/dto/PlaceRankReqDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/PlaceRankReqDto.java index 8223fd15..66509ce9 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/PlaceRankReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/PlaceRankReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/src/main/java/com/sluv/server/domain/item/dto/PlaceRankResDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/PlaceRankResDto.java similarity index 84% rename from src/main/java/com/sluv/server/domain/item/dto/PlaceRankResDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/PlaceRankResDto.java index b75d0ffc..77875333 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/PlaceRankResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/PlaceRankResDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.item.entity.PlaceRank; +import com.sluv.domain.item.entity.PlaceRank; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/item/dto/TempItemCountResDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/TempItemCountResDto.java similarity index 92% rename from src/main/java/com/sluv/server/domain/item/dto/TempItemCountResDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/TempItemCountResDto.java index 6ebf3a66..894588f9 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/TempItemCountResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/TempItemCountResDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/item/dto/TempItemPostReqDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/TempItemPostReqDto.java similarity index 89% rename from src/main/java/com/sluv/server/domain/item/dto/TempItemPostReqDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/TempItemPostReqDto.java index 4c730fe8..7423d0b5 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/TempItemPostReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/TempItemPostReqDto.java @@ -1,5 +1,7 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; +import com.sluv.domain.item.dto.ItemImgDto; +import com.sluv.domain.item.dto.ItemLinkDto; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; import java.util.List; @@ -21,7 +23,7 @@ public class TempItemPostReqDto { @Schema(description = "tempItem id(PK)") private Long id; @Schema(description = "item 이미지 리스트") - private List imgList; + private List imgList; @Schema(description = "celebId") private Long celebId; @Schema(description = "발견 시간 ex)2021-11-20T09:10:20") @@ -43,7 +45,7 @@ public class TempItemPostReqDto { @Schema(description = "해쉬태그 Id 리스트") private List hashTagIdList; @Schema(description = "item 링크 리스트") - private List linkList; + private List linkList; @Schema(description = "추가정보를 발견한 출처") private String infoSource; diff --git a/src/main/java/com/sluv/server/domain/item/dto/TempItemPostResDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/TempItemPostResDto.java similarity index 92% rename from src/main/java/com/sluv/server/domain/item/dto/TempItemPostResDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/TempItemPostResDto.java index 3b807e0f..4407e317 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/TempItemPostResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/TempItemPostResDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/item/dto/TempItemResDto.java b/sluv-api/src/main/java/com/sluv/api/item/dto/TempItemResDto.java similarity index 77% rename from src/main/java/com/sluv/server/domain/item/dto/TempItemResDto.java rename to sluv-api/src/main/java/com/sluv/api/item/dto/TempItemResDto.java index 07368db2..3d0fe2ba 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/TempItemResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/item/dto/TempItemResDto.java @@ -1,10 +1,12 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.api.item.dto; -import com.sluv.server.domain.brand.dto.NewBrandPostResDto; -import com.sluv.server.domain.brand.entity.Brand; -import com.sluv.server.domain.celeb.dto.CelebDto; -import com.sluv.server.domain.celeb.dto.NewCelebPostResDto; -import com.sluv.server.domain.item.entity.TempItem; +import com.sluv.api.brand.dto.response.NewBrandPostResponse; +import com.sluv.api.celeb.dto.response.NewCelebPostResponse; +import com.sluv.domain.brand.entity.Brand; +import com.sluv.domain.celeb.dto.CelebDto; +import com.sluv.domain.item.dto.ItemImgDto; +import com.sluv.domain.item.dto.ItemLinkDto; +import com.sluv.domain.item.entity.TempItem; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; import java.util.List; @@ -25,7 +27,7 @@ public class TempItemResDto { @Schema(description = "item Id") private Long id; @Schema(description = "item 이미지 리스트") - private List imgList; + private List imgList; @Schema(description = "celeb") private CelebDto celeb; @Schema(description = "발견 시간 ex)2021-11-20T09:10:20") @@ -45,19 +47,19 @@ public class TempItemResDto { @Schema(description = "해쉬태그 리스트") private List hashTagList; @Schema(description = "item 링크 리스트 ") - private List linkList; + private List linkList; @Schema(description = "추가정보를 발견한 출처") private String infoSource; @Schema(description = "새로운 Celeb") - private NewCelebPostResDto newCeleb; + private NewCelebPostResponse newCeleb; @Schema(description = "새로운 Brand") - private NewBrandPostResDto newBrand; + private NewBrandPostResponse newBrand; @Schema(description = "최신 update 시점") private LocalDateTime updatedAt; - public static TempItemResDto of(TempItem tempItem, List imgList, List linkList, + public static TempItemResDto of(TempItem tempItem, List imgList, List linkList, List hashtagList ) { @@ -73,12 +75,12 @@ public static TempItemResDto of(TempItem tempItem, List imgList, ? tempItem.getBrand() : null; - NewCelebPostResDto newCeleb = tempItem.getNewCeleb() != null - ? NewCelebPostResDto.of(tempItem.getNewCeleb()) + NewCelebPostResponse newCeleb = tempItem.getNewCeleb() != null + ? NewCelebPostResponse.of(tempItem.getNewCeleb()) : null; - NewBrandPostResDto newBrand = tempItem.getNewBrand() != null - ? NewBrandPostResDto.of(tempItem.getNewBrand()) + NewBrandPostResponse newBrand = tempItem.getNewBrand() != null + ? NewBrandPostResponse.of(tempItem.getNewBrand()) : null; return TempItemResDto.builder() diff --git a/sluv-api/src/main/java/com/sluv/api/item/helper/HashtagHelper.java b/sluv-api/src/main/java/com/sluv/api/item/helper/HashtagHelper.java new file mode 100644 index 00000000..5dfa36ac --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/item/helper/HashtagHelper.java @@ -0,0 +1,14 @@ +package com.sluv.api.item.helper; + +import com.sluv.api.item.dto.HashtagResponseDto; +import com.sluv.domain.item.dto.hashtag.HashtagCountDto; +import org.springframework.stereotype.Component; + +@Component +public class HashtagHelper { + + public HashtagResponseDto convertHashtagCountDtoToHashtagResponseDto(HashtagCountDto dto) { + return HashtagResponseDto.of(dto.getHashtag(), dto.getCount()); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/item/helper/ItemHelper.java b/sluv-api/src/main/java/com/sluv/api/item/helper/ItemHelper.java new file mode 100644 index 00000000..3daadc4b --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/item/helper/ItemHelper.java @@ -0,0 +1,78 @@ +package com.sluv.api.item.helper; + +import com.sluv.api.comment.dto.reponse.CommentItemResponse; +import com.sluv.api.item.dto.ItemPostReqDto; +import com.sluv.api.item.dto.TempItemPostReqDto; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.closet.repository.ClosetRepository; +import com.sluv.domain.comment.entity.CommentItem; +import com.sluv.domain.item.dto.ItemSaveDto; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.dto.TempItemSaveDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemImg; +import com.sluv.domain.item.repository.ItemImgRepository; +import com.sluv.domain.item.repository.ItemRepository; +import com.sluv.domain.item.repository.ItemScrapRepository; +import com.sluv.domain.user.entity.User; +import java.util.ArrayList; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class ItemHelper { + + private final ItemImgRepository itemImgRepository; + private final ItemScrapRepository itemScrapRepository; + private final ClosetRepository closetRepository; + private final ItemRepository itemRepository; + + public ItemSimpleDto convertItemToSimpleResDto(Item item, User user) { + List closetList = closetRepository.findAllByUserId(user.getId()); +// itemRepository.getItemSimpleResDto(user, ) + return ItemSimpleDto.of(item, itemImgRepository.findMainImg(item.getId()), + itemScrapRepository.getItemScrapStatus(item, closetList)); + } + + /** + * CommentItem -> CommentItemResDto 변경하는 메소드 + * + * @param commentItem + * @return CommentItemResDto + */ + public CommentItemResponse getCommentItemResDto(CommentItem commentItem, User user) { + ItemImg mainImg = itemImgRepository.findMainImg(commentItem.getItem().getId()); + List closetList = new ArrayList<>(); + if (user != null) { + closetList = closetRepository.findAllByUserId(user.getId()); + } + Boolean itemScrapStatus = itemScrapRepository.getItemScrapStatus(commentItem.getItem(), closetList); + + return CommentItemResponse.of(commentItem, mainImg, itemScrapStatus); + } + + public ItemSaveDto convertItemPostReqDtoToItemSaveDto(ItemPostReqDto dto) { + return ItemSaveDto.builder() + .itemName(dto.getItemName()) + .additionalInfo(dto.getAdditionalInfo()) + .infoSource(dto.getInfoSource()) + .price(dto.getPrice()) + .whenDiscovery(dto.getWhenDiscovery()) + .whereDiscovery(dto.getWhereDiscovery()) + .build(); + } + + public TempItemSaveDto convertTempItemPostReqDtoToTempItemSaveDto(TempItemPostReqDto dto) { + return TempItemSaveDto.builder() + .itemName(dto.getItemName()) + .additionalInfo(dto.getAdditionalInfo()) + .infoSource(dto.getInfoSource()) + .price(dto.getPrice()) + .whenDiscovery(dto.getWhenDiscovery()) + .whereDiscovery(dto.getWhereDiscovery()) + .build(); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/item/service/HashtagService.java b/sluv-api/src/main/java/com/sluv/api/item/service/HashtagService.java new file mode 100644 index 00000000..958104cd --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/item/service/HashtagService.java @@ -0,0 +1,50 @@ +package com.sluv.api.item.service; + +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.item.dto.HashtagPostResponseDto; +import com.sluv.api.item.dto.HashtagRequestDto; +import com.sluv.api.item.dto.HashtagResponseDto; +import com.sluv.api.item.helper.HashtagHelper; +import com.sluv.domain.item.dto.hashtag.HashtagCountDto; +import com.sluv.domain.item.entity.hashtag.Hashtag; +import com.sluv.domain.item.service.hashtag.HashtagDomainService; +import java.util.List; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class HashtagService { + + private final HashtagDomainService hashtagDomainService; + private final HashtagHelper hashtagHelper; + + @Transactional(readOnly = true) + public PaginationResponse getHashtag(String name, Pageable pageable) { + Page hashtagPage = hashtagDomainService.findAllByContent(name, pageable); + List dtoList = hashtagPage + .stream().map(hashtagHelper::convertHashtagCountDtoToHashtagResponseDto).toList(); + return PaginationResponse.create(hashtagPage, dtoList); + } + + public HashtagPostResponseDto postHashtag(HashtagRequestDto requestDto) { + + // 해당 Hashtag가 있는지 검색 + Optional hashtag = hashtagDomainService.findByContent(requestDto.getHashtagContent()); + + //있다면 해당 Hashtag를 반환 + if (hashtag.isPresent()) { + return HashtagPostResponseDto.of(hashtag.get()); + } else { // 없다면 등록 후 반환 + Hashtag save = hashtagDomainService.saveHashtag(requestDto.getHashtagContent()); + return HashtagPostResponseDto.of(save); + } + + } + +} diff --git a/src/main/java/com/sluv/server/domain/item/service/ItemCacheService.java b/sluv-api/src/main/java/com/sluv/api/item/service/ItemCacheService.java similarity index 61% rename from src/main/java/com/sluv/server/domain/item/service/ItemCacheService.java rename to sluv-api/src/main/java/com/sluv/api/item/service/ItemCacheService.java index c33e8d7a..2c3fb321 100644 --- a/src/main/java/com/sluv/server/domain/item/service/ItemCacheService.java +++ b/sluv-api/src/main/java/com/sluv/api/item/service/ItemCacheService.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.item.service; +package com.sluv.api.item.service; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.global.cache.CacheService; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.service.ItemDomainService; +import com.sluv.infra.cache.CacheService; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Async; @@ -11,16 +11,17 @@ @Service @RequiredArgsConstructor public class ItemCacheService { - private final ItemRepository itemRepository; + private final ItemDomainService itemDomainService; private final CacheService cacheService; @Async(value = "asyncThreadPoolExecutor") public void deleteAllItemCacheByUserId(Long userId) { - List userItemIds = itemRepository.findAllByUserId(userId).stream() + List userItemIds = itemDomainService.findAllByUserId(userId).stream() .map(Item::getId) .toList(); userItemIds.forEach(cacheService::deleteItemDetailFixDataByItemId); } + } diff --git a/src/main/java/com/sluv/server/domain/item/service/ItemCategoryService.java b/sluv-api/src/main/java/com/sluv/api/item/service/ItemCategoryService.java similarity index 61% rename from src/main/java/com/sluv/server/domain/item/service/ItemCategoryService.java rename to sluv-api/src/main/java/com/sluv/api/item/service/ItemCategoryService.java index a98a9719..2df86558 100644 --- a/src/main/java/com/sluv/server/domain/item/service/ItemCategoryService.java +++ b/sluv-api/src/main/java/com/sluv/api/item/service/ItemCategoryService.java @@ -1,9 +1,9 @@ -package com.sluv.server.domain.item.service; +package com.sluv.api.item.service; -import com.sluv.server.domain.item.dto.ItemCategoryChildResponseDto; -import com.sluv.server.domain.item.dto.ItemCategoryParentResponseDto; -import com.sluv.server.domain.item.entity.ItemCategory; -import com.sluv.server.domain.item.repository.ItemCategoryRepository; +import com.sluv.api.item.dto.ItemCategoryChildResponseDto; +import com.sluv.api.item.dto.ItemCategoryParentResponseDto; +import com.sluv.domain.item.entity.ItemCategory; +import com.sluv.domain.item.service.ItemCategoryDomainService; import java.util.List; import java.util.Objects; import lombok.RequiredArgsConstructor; @@ -15,14 +15,14 @@ @RequiredArgsConstructor public class ItemCategoryService { - private final ItemCategoryRepository itemCategoryRepository; + private final ItemCategoryDomainService itemCategoryDomainService; @Transactional(readOnly = true) public List getItemCategory() { - List childList = itemCategoryRepository.findAllByParentNotNull(); + List childList = itemCategoryDomainService.findAllByParentNotNull(); - return itemCategoryRepository.findAllByParentNull() + return itemCategoryDomainService.findAllByParentNull() .stream().map(parent -> { List childDtoList = childList.stream() .filter(child -> Objects.equals(child.getParent().getId(), parent.getId())) @@ -32,4 +32,5 @@ public List getItemCategory() { }).toList(); } + } diff --git a/sluv-api/src/main/java/com/sluv/api/item/service/ItemEditReqService.java b/sluv-api/src/main/java/com/sluv/api/item/service/ItemEditReqService.java new file mode 100644 index 00000000..1f842c1c --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/item/service/ItemEditReqService.java @@ -0,0 +1,31 @@ +package com.sluv.api.item.service; + +import com.sluv.api.alarm.service.ItemAlarmService; +import com.sluv.api.item.dto.ItemEditReqDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemEditReq; +import com.sluv.domain.item.service.ItemDomainService; +import com.sluv.domain.item.service.ItemEditReqDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class ItemEditReqService { + private final ItemEditReqDomainService itemEditReqDomainService; + private final ItemDomainService itemDomainService; + private final ItemAlarmService itemAlarmService; + private final UserDomainService userDomainService; + + public void postItemEdit(Long userId, Long itemId, ItemEditReqDto dto) { + Item item = itemDomainService.findById(itemId); + User user = userDomainService.findById(userId); + ItemEditReq itemEditReq = itemEditReqDomainService.saveItemEditReq(user, item, dto.getReason(), + dto.getContent()); + itemAlarmService.sendAlarmAboutItemEdit(item.getId(), itemEditReq.getId(), user); + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/item/service/ItemReportService.java b/sluv-api/src/main/java/com/sluv/api/item/service/ItemReportService.java new file mode 100644 index 00000000..6ed207e7 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/item/service/ItemReportService.java @@ -0,0 +1,43 @@ +package com.sluv.api.item.service; + +import com.sluv.api.item.dto.ItemReportReqDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.exception.ItemReportDuplicateException; +import com.sluv.domain.item.service.ItemDomainService; +import com.sluv.domain.item.service.ItemReportDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class ItemReportService { + + private final ItemReportDomainService itemReportDomainService; + private final ItemDomainService itemDomainService; + + private final UserDomainService userDomainService; + + + public void postItemReport(Long userId, Long itemId, ItemReportReqDto dto) { + User user = userDomainService.findById(userId); + + // 신고대상 Item 검색. + Item item = itemDomainService.findById(itemId); + + // 신고 중복여부 확인 + boolean existence = itemReportDomainService.findExistence(user, item); + + // 중복 신고라면 Exception 발생 + if (existence) { + throw new ItemReportDuplicateException(); + } else { + // 중복이 아니라면 신고 접수 + itemReportDomainService.saveItemReport(item, user, dto.getReason(), dto.getContent()); + } + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/item/service/ItemService.java b/sluv-api/src/main/java/com/sluv/api/item/service/ItemService.java new file mode 100644 index 00000000..e23b1f38 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/item/service/ItemService.java @@ -0,0 +1,491 @@ +package com.sluv.api.item.service; + + +import com.sluv.api.alarm.service.ItemAlarmService; +import com.sluv.api.brand.dto.response.BrandSearchResponse; +import com.sluv.api.celeb.dto.response.CelebSearchResponse; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.item.dto.*; +import com.sluv.api.item.helper.ItemHelper; +import com.sluv.domain.brand.entity.Brand; +import com.sluv.domain.brand.entity.NewBrand; +import com.sluv.domain.brand.service.BrandDomainService; +import com.sluv.domain.brand.service.NewBrandDomainService; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.celeb.service.CelebDomainService; +import com.sluv.domain.celeb.service.NewCelebDomainService; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.closet.service.ClosetDomainService; +import com.sluv.domain.item.dto.ItemImgDto; +import com.sluv.domain.item.dto.ItemLinkDto; +import com.sluv.domain.item.dto.ItemSaveDto; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemCategory; +import com.sluv.domain.item.entity.hashtag.Hashtag; +import com.sluv.domain.item.enums.ItemStatus; +import com.sluv.domain.item.exception.ItemNotActiveException; +import com.sluv.domain.item.service.*; +import com.sluv.domain.item.service.hashtag.HashtagDomainService; +import com.sluv.domain.search.dto.SearchFilterReqDto; +import com.sluv.domain.user.dto.UserInfoDto; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.FollowDomainService; +import com.sluv.domain.user.service.UserDomainService; +import com.sluv.infra.ai.AiModelService; +import com.sluv.infra.cache.CacheService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import static com.sluv.domain.item.enums.ItemStatus.ACTIVE; + +@Service +@Slf4j +@RequiredArgsConstructor +public class ItemService { + private final ItemDomainService itemDomainService; + private final ItemImgDomainService itemImgDomainService; + private final ItemLinkDomainService itemLinkDomainService; + private final ItemHashtagDomainService itemHashtagDomainService; + private final HashtagDomainService hashtagDomainService; + private final CelebDomainService celebDomainService; + private final ItemCategoryDomainService itemCategoryDomainService; + private final BrandDomainService brandDomainService; + private final UserDomainService userDomainService; + private final RecentItemDomainService recentItemDomainService; + + private final NewBrandDomainService newBrandDomainService; + private final NewCelebDomainService newCelebDomainService; + + private final ItemLikeDomainService itemLikeDomainService; + private final FollowDomainService followDomainService; + private final ClosetDomainService closetDomainService; + private final ItemScrapDomainService itemScrapDomainService; + + private final AiModelService aiModelService; + private final CacheService cacheService; + private final ItemAlarmService itemAlarmService; + private final ItemHelper itemHelper; + + @Transactional + public ItemPostResDto postItem(Long userId, ItemPostReqDto reqDto) { + User user = userDomainService.findById(userId); + + if (reqDto.getId() != null) { + cacheService.deleteItemDetailFixDataByItemId(reqDto.getId()); + } + + // 추가될 Celeb 확인 + Celeb celeb = null; + if (reqDto.getCelebId() != null) { + celeb = celebDomainService.findById(reqDto.getCelebId()); + } + + // 추가될 Brand 확인 + Brand brand = null; + if (reqDto.getBrandId() != null) { + brand = brandDomainService.findById(reqDto.getBrandId()); + } + + // 추가될 NewCeleb 확인 + NewCeleb newCeleb = null; + if (reqDto.getNewCelebId() != null) { + newCeleb = newCelebDomainService.findById(reqDto.getNewCelebId()); + } + + // 추가될 NewBrand 확인 + NewBrand newBrand = null; + if (reqDto.getNewBrandId() != null) { + newBrand = newBrandDomainService.findById(reqDto.getNewBrandId()); + } + + // 추가될 Category 확인 + ItemCategory itemCategory = itemCategoryDomainService.findById(reqDto.getCategoryId()); + + // Item을 등록인지 수정인지 판단. + Item item = + reqDto.getId() != null ? itemDomainService.findById(reqDto.getId()) + : null; + + Item postItem; + ItemSaveDto itemSaveDto = itemHelper.convertItemPostReqDtoToItemSaveDto(reqDto); + // Item 수정이라면, 기존의 Item의 Id를 추가. + if (item != null) { + postItem = Item.toEntity(item.getId(), user, celeb, newCeleb, itemCategory, brand, newBrand, itemSaveDto, + item.getViewNum()); + } else { + // Item 생성 + postItem = Item.toEntity(user, celeb, newCeleb, itemCategory, brand, newBrand, itemSaveDto); + } + + // 완성된 Item save + Item newItem = itemDomainService.saveItem(postItem); + + // 기존의 Img, Link, Hashtag가 있다면 모두 삭제 + itemImgDomainService.deleteAllByItemId(newItem.getId()); + itemLinkDomainService.deleteAllByItemId(newItem.getId()); + itemHashtagDomainService.deleteAllByItemId(newItem.getId()); + + // ItemImg 테이블에 추가 +// reqDto.getImgList().stream().map(itemImg -> ItemImg.toEntity(newItem, itemImg)) +// .forEach(itemImgDomainService::saveItemImg); + reqDto.getImgList().forEach(itemImg -> itemImgDomainService.saveItemImg(newItem, itemImg)); + + // ItemLink 테이블에 추가 + if (reqDto.getLinkList() != null) { + reqDto.getLinkList().forEach(itemLink -> itemLinkDomainService.saveItemLink(newItem, itemLink)); + } + + // ItemHashtag 테이블에 추가 + if (reqDto.getHashTagIdList() != null) { + reqDto.getHashTagIdList().forEach(hashTag -> { + Hashtag hashtag = hashtagDomainService.findById(hashTag); + itemHashtagDomainService.saveItemHashtag(newItem, hashtag); + }); + } + + aiModelService.getItemColor(newItem); + + if (reqDto.getId() == null) { // 새 아이템 등록 시 + itemAlarmService.sendAlarmAboutFollowItem(user.getId(), newItem.getId()); + } + + return ItemPostResDto.of(newItem.getId()); + } + + @Transactional(readOnly = true) + public List getTopPlace() { + + return itemDomainService.findTopPlace().stream() + .map(HotPlaceResDto::of).toList(); + } + + @Transactional + public ItemDetailResDto getItemDetail(Long userId, Long itemId) { + + User user = userDomainService.findByIdOrNull(userId); + + // 1. Item 조회 + Item item = itemDomainService.findById(itemId); + + if (item.getItemStatus() != ACTIVE) { + log.error("ItemId: {}'s status: {}", itemId, item.getItemStatus()); + throw new ItemNotActiveException(); + } + + // 2. Item Detail 고정 데이터 조회 -> Cache Aside + ItemDetailFixData fixData = (ItemDetailFixData) cacheService.findItemDetailFixDataByItemId(itemId); + if (fixData == null) { + fixData = getItemDetailFixData(item); + cacheService.saveItemDetailFixData(itemId, fixData); + } + + // 3. 좋아요 수 + Integer likeNum = itemLikeDomainService.countByItemId(item.getId()); + + // 4. 스크랩 수 + Integer scrapNum = itemScrapDomainService.countByItemId(item.getId()); + + List closetList = new ArrayList<>(); + + if (user != null) { + // 5. 최근 본 아이템 등록 + recentItemDomainService.saveRecentItem(item, user); + + // 6. 조회수 + increaseViewNum(user.getId(), item); + + // 7. 스크랩 여부 + closetList = closetDomainService.findAllByUserId(user.getId()); + } + + boolean scrapStatus = itemScrapDomainService.getItemScrapStatus(item, closetList); + + // 8. 좋아요 여부 + boolean likeStatus = user != null && itemLikeDomainService.existsByUserIdAndItemId(user.getId(), itemId); + + // 9. 팔로우 여부 + boolean followStatus = followDomainService.getFollowStatus(user, fixData.getWriter().getId()); + + // 10. 본인의 게시글 여부 + boolean hasMine = user != null && item.getUser().getId().equals(user.getId()); + + // Dto 조립 + return ItemDetailResDto.of( + item, + fixData.getCeleb(), + fixData.getNewCeleb(), + fixData.getBrand(), + fixData.getNewBrand(), + fixData.getCategory(), + likeNum, + likeStatus, + scrapNum, + scrapStatus, + item.getViewNum(), + fixData.getWriter(), + followStatus, + hasMine, + fixData.getImgList(), + fixData.getLinkList(), + fixData.getHashTagList() + ); + } + + private void increaseViewNum(Long userId, Item item) { + boolean isExist = cacheService.existUserViewItemId(userId, item.getId()); + if (!isExist) { + cacheService.saveUserViewItemId(userId, item.getId()); + item.increaseViewNum(); + } + } + + // @Cacheable(cacheNames = "item", key = "#itemId") + public ItemDetailFixData getItemDetailFixData(Item item) { + Long itemId = item.getId(); + + // 1. Item Category + ItemCategoryDto category = ItemCategoryDto.of(item.getCategory()); + + // 2. Item Celeb + CelebSearchResponse celeb = item.getCeleb() != null + ? CelebSearchResponse.of(item.getCeleb()) + : null; + + // 3. Brand + BrandSearchResponse brand = item.getBrand() != null ? + BrandSearchResponse.of(item.getBrand()) + : null; + + // 4. 작성자 info + User writer = userDomainService.findByIdOrNull(item.getUser().getId()); + UserInfoDto writerInfo = UserInfoDto.of(writer); + + // 5. Item 이미지들 조회 + List imgList = itemImgDomainService.findAllByItemId(itemId) + .stream() + .map(ItemImgDto::of).toList(); + + // 6. Item 링크들 조회 + List linkList = itemLinkDomainService.findByItemId(itemId) + .stream() + .map(ItemLinkDto::of).toList(); + + // 7. Hashtag + List itemHashtags = itemHashtagDomainService.findAllByItemId(itemId) + .stream() + .map(itemHashtag -> + ItemHashtagResponseDto.of(itemHashtag.getHashtag()) + ).toList(); + + return ItemDetailFixData.of(item, celeb, item.getNewCeleb(), brand, item.getNewBrand(), category, writerInfo, + imgList, linkList, itemHashtags); + } + + @Transactional + public void postItemLike(Long userId, Long itemId) { + User user = userDomainService.findById(userId); + Item item = itemDomainService.findById(itemId); + + boolean likeExist = itemLikeDomainService.existsByUserIdAndItemId(user.getId(), itemId); + if (!likeExist) { + itemLikeDomainService.saveItemLike(item, user); + itemAlarmService.sendAlarmAboutItemLike(user.getId(), itemId); + } else { + itemLikeDomainService.deleteByUserIdAndItemId(user.getId(), itemId); + } + + } + + @Transactional + public void deleteItem(Long itemId) { + Item item = itemDomainService.findById(itemId); + + item.changeStatus(ItemStatus.DELETED); + itemDomainService.saveItem(item); + cacheService.deleteItemDetailFixDataByItemId(itemId); + } + + @Transactional(readOnly = true) + public PaginationResponse getRecentItem(Long userId, Pageable pageable) { + User user = userDomainService.findById(userId); + Page recentItemPage = itemDomainService.getRecentItem(user, pageable); + List itemSimpleDtos = itemDomainService.getItemSimpleDto(user, + recentItemPage.getContent()); + return PaginationResponse.create(recentItemPage, itemSimpleDtos); + + } + + @Transactional(readOnly = true) + public PaginationResponse getScrapItem(Long userId, Pageable pageable) { + User user = userDomainService.findById(userId); + // User, Closet, Item 조인하여 ItemPage 조회 + Page itemPage = itemDomainService.getAllScrapItem(user, pageable); + List itemSimpleDtos = itemDomainService.getItemSimpleDto(user, itemPage.getContent()); + return PaginationResponse.create(itemPage, itemSimpleDtos); + } + + @Transactional(readOnly = true) + public PaginationResponse getRecommendItem(Long userId, Pageable pageable) { + Page recommendItemPage = itemDomainService.getRecommendItemPage(pageable); + User user = userDomainService.findByIdOrNull(userId); + + List content = + itemDomainService.getItemSimpleDto(user, recommendItemPage.getContent()); + + return PaginationResponse.create(recommendItemPage, content); + } + + /** + * 핫한 셀럽들이 선택한 여름나기 아이템 조회 + */ + @Transactional(readOnly = true) + public PaginationResponse getSummerItem(Long userId, Pageable pageable, SearchFilterReqDto dto) { + // itemPage 조회 + Page itemPage = itemDomainService.getCelebSummerItem(pageable, dto); + User user = userDomainService.findByIdOrNull(userId); + // Content 조립 + List content = itemDomainService.getItemSimpleDto(user, itemPage.getContent()); + + return PaginationResponse.create(itemPage, content); + } + + /** + * 지금 당장 구매가능한 아이템 조회 + */ + @Transactional(readOnly = true) + public PaginationResponse getNowBuyItem(Long userId, Pageable pageable, SearchFilterReqDto dto) { + User user = userDomainService.findByIdOrNull(userId); + Page itemPage = itemDomainService.getNowBuyItem(pageable, dto); + List content = itemDomainService.getItemSimpleDto(user, itemPage.getContent()); + return PaginationResponse.create(itemPage, content); + } + + @Transactional(readOnly = true) + public PaginationResponse getNewItem(Long userId, Pageable pageable) { + User user = userDomainService.findByIdOrNull(userId); + + // itemPage 조회 + Page itemPage = itemDomainService.getNewItem(pageable); + + // Content 조립 + List content = itemDomainService.getItemSimpleDto(user, itemPage.getContent()); + + return PaginationResponse.create(itemPage, content); + } + + @Transactional(readOnly = true) + public PaginationResponse getLuxuryItem(Long userId, Pageable pageable, SearchFilterReqDto dto) { + User user = userDomainService.findByIdOrNull(userId); + Page itemPage = itemDomainService.getLuxuryItem(pageable, dto); + List content = itemDomainService.getItemSimpleDto(user, itemPage.getContent()); + return PaginationResponse.create(itemPage, content); + } + + @Transactional(readOnly = true) + public PaginationResponse getEfficientItem(Long userId, Pageable pageable, + SearchFilterReqDto filterReqDto) { + User user = userDomainService.findByIdOrNull(userId); + Page itemPage = itemDomainService.getEfficientItem(pageable, filterReqDto); + List content = itemDomainService.getItemSimpleDto(user, itemPage.getContent()); + return PaginationResponse.create(itemPage, content); + } + + @Transactional(readOnly = true) + public List getWeekHotItem(Long userId) { + User user = userDomainService.findByIdOrNull(userId); + List itemPage = itemDomainService.getWeekHotItem(); + return itemDomainService.getItemSimpleDto(user, itemPage); + } + + @Transactional(readOnly = true) + public List getDayHotItem(Long userId) { + User user = userDomainService.findByIdOrNull(userId); + List itemPage = itemDomainService.getDayHotItem(); + return itemDomainService.getItemSimpleDto(user, itemPage); + } + + /** + * 요즘 핫한 셀럽의 Item 조회 + */ + @Transactional(readOnly = true) + public PaginationResponse getHotCelebItem(Long userId, Pageable pageable, SearchFilterReqDto dto) { + User user = userDomainService.findByIdOrNull(userId); + Long celebId = 510L; + + Page itemPage = itemDomainService.getHotCelebItem(celebId, pageable, dto); + + List content = itemDomainService.getItemSimpleDto(user, itemPage.getContent()); + + return PaginationResponse.create(itemPage, content); + } + + @Transactional(readOnly = true) + public List getCurationItem(Long userId) { + User user = userDomainService.findByIdOrNull(userId); + List interestedCeleb; + if (user != null) { + interestedCeleb = celebDomainService.findInterestedCeleb(user); + } else { + interestedCeleb = celebDomainService.findTop10Celeb(); + } + List itemList = itemDomainService.getCurationItem(user, interestedCeleb); + + return itemDomainService.getItemSimpleDto(user, itemList); + } + + @Transactional(readOnly = true) + public List getHowAboutItem(Long userId) { + User user = userDomainService.findByIdOrNull(userId); + List items = itemDomainService.findAllByItemStatus(ACTIVE); + Collections.shuffle(items, new Random()); + return itemDomainService.getItemSimpleDto(user, items.subList(0, 4)); + } + + @Transactional(readOnly = true) + public List getSameCelebItems(Long userId, Long itemId) { + User user = userDomainService.findByIdOrNull(userId); + Item item = itemDomainService.getItemByIdWithCelebAndBrand(itemId); + List sameCelebItems; + if (item.getCeleb() != null) { + sameCelebItems = itemDomainService.findSameCelebItem(itemId, item.getCeleb().getId(), true); + } else { + sameCelebItems = itemDomainService.findSameCelebItem(itemId, item.getNewCeleb().getId(), false); + } + + return itemDomainService.getItemSimpleDto(user, sameCelebItems); + } + + @Transactional(readOnly = true) + public List getSameBrandItem(Long userId, Long itemId) { + User user = userDomainService.findByIdOrNull(userId); + Item item = itemDomainService.getItemByIdWithCelebAndBrand(itemId); + List sameBrandItems; + + if (item.getBrand() != null) { + sameBrandItems = itemDomainService.findSameBrandItem(itemId, item.getBrand().getId(), true); + } else { + sameBrandItems = itemDomainService.findSameBrandItem(itemId, item.getNewBrand().getId(), false); + } + + return itemDomainService.getItemSimpleDto(user, sameBrandItems); + } + + @Transactional(readOnly = true) + public List getTogetherScrapItem(Long userId, Long itemId) { + User user = userDomainService.findByIdOrNull(userId); + List recentAddClosets = closetDomainService.getRecentAddCloset(itemId); + List sameClosetItems = itemDomainService.getSameClosetItems(itemId, recentAddClosets); + return itemDomainService.getItemSimpleDto(user, sameClosetItems); + } +} diff --git a/src/main/java/com/sluv/server/domain/item/service/ItemWithdrawService.java b/sluv-api/src/main/java/com/sluv/api/item/service/ItemWithdrawService.java similarity index 63% rename from src/main/java/com/sluv/server/domain/item/service/ItemWithdrawService.java rename to sluv-api/src/main/java/com/sluv/api/item/service/ItemWithdrawService.java index 87c3f750..4bd9d594 100644 --- a/src/main/java/com/sluv/server/domain/item/service/ItemWithdrawService.java +++ b/sluv-api/src/main/java/com/sluv/api/item/service/ItemWithdrawService.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.service; +package com.sluv.api.item.service; -import com.sluv.server.domain.item.repository.RecentItemRepository; +import com.sluv.domain.item.service.RecentItemDomainService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -9,12 +9,12 @@ @RequiredArgsConstructor public class ItemWithdrawService { - private final RecentItemRepository recentItemRepository; + private final RecentItemDomainService recentItemDomainService; private final TempItemService tempItemService; @Transactional public void withdrawItemByUserId(Long userId) { - recentItemRepository.deleteAllByUserId(userId); + recentItemDomainService.deleteAllByUserId(userId); tempItemService.deleteAllTempItem(userId); } } diff --git a/sluv-api/src/main/java/com/sluv/api/item/service/PlaceRankService.java b/sluv-api/src/main/java/com/sluv/api/item/service/PlaceRankService.java new file mode 100644 index 00000000..296e4425 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/item/service/PlaceRankService.java @@ -0,0 +1,42 @@ +package com.sluv.api.item.service; + +import com.sluv.api.item.dto.PlaceRankReqDto; +import com.sluv.api.item.dto.PlaceRankResDto; +import com.sluv.domain.item.service.PlaceRankDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class PlaceRankService { + + private final PlaceRankDomainService placeRankDomainService; + private final UserDomainService userDomainService; + + public void postPlace(Long userId, PlaceRankReqDto dto) { + User user = userDomainService.findById(userId); + placeRankDomainService.savePlaceRank(user, dto.getPlaceName()); + + } + + public void deleteAllPlace(Long userId) { + placeRankDomainService.deleteAllByUserId(userId); + } + + public void deletePlace(Long userId, String placeName) { + placeRankDomainService.deleteByUserIdAndPlace(userId, placeName); + } + + @Transactional(readOnly = true) + public List getRecentPlaceTop20(Long userId) { + return placeRankDomainService.getRecentPlaceTop20(userId) + .stream() + .map(PlaceRankResDto::of) + .toList(); + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/item/service/TempItemService.java b/sluv-api/src/main/java/com/sluv/api/item/service/TempItemService.java new file mode 100644 index 00000000..a8549478 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/item/service/TempItemService.java @@ -0,0 +1,198 @@ +package com.sluv.api.item.service; + +import com.sluv.api.common.response.PaginationCountResponse; +import com.sluv.api.item.dto.ItemHashtagResponseDto; +import com.sluv.api.item.dto.TempItemCountResDto; +import com.sluv.api.item.dto.TempItemPostReqDto; +import com.sluv.api.item.dto.TempItemResDto; +import com.sluv.api.item.helper.ItemHelper; +import com.sluv.domain.brand.entity.Brand; +import com.sluv.domain.brand.entity.NewBrand; +import com.sluv.domain.brand.service.BrandDomainService; +import com.sluv.domain.brand.service.NewBrandDomainService; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.celeb.service.CelebDomainService; +import com.sluv.domain.celeb.service.NewCelebDomainService; +import com.sluv.domain.item.dto.ItemImgDto; +import com.sluv.domain.item.dto.ItemLinkDto; +import com.sluv.domain.item.dto.TempItemSaveDto; +import com.sluv.domain.item.entity.ItemCategory; +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.TempItemImg; +import com.sluv.domain.item.entity.TempItemLink; +import com.sluv.domain.item.entity.hashtag.Hashtag; +import com.sluv.domain.item.entity.hashtag.TempItemHashtag; +import com.sluv.domain.item.service.ItemCategoryDomainService; +import com.sluv.domain.item.service.TempItemDomainService; +import com.sluv.domain.item.service.TempItemImgDomainService; +import com.sluv.domain.item.service.TempItemLinkDomainService; +import com.sluv.domain.item.service.hashtag.HashtagDomainService; +import com.sluv.domain.item.service.hashtag.TempItemHashtagDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class TempItemService { + + private final UserDomainService userDomainService; + private final TempItemDomainService tempItemDomainService; + private final TempItemLinkDomainService tempItemLinkDomainService; + private final TempItemImgDomainService tempItemImgDomainService; + private final TempItemHashtagDomainService tempItemHashtagDomainService; + + private final HashtagDomainService hashtagDomainService; + private final CelebDomainService celebDomainService; + private final ItemCategoryDomainService itemCategoryDomainService; + private final BrandDomainService brandDomainService; + private final NewBrandDomainService newBrandDomainService; + private final NewCelebDomainService newCelebDomainService; + + private final ItemHelper itemHelper; + + + public Long postTempItem(Long userId, TempItemPostReqDto reqDto) { + User user = userDomainService.findById(userId); + Celeb celeb = reqDto.getCelebId() != null ? celebDomainService.findById(reqDto.getCelebId()) + : null; + Brand brand = reqDto.getBrandId() != null ? brandDomainService.findById(reqDto.getBrandId()) + : null; + NewCeleb newCeleb = reqDto.getNewCelebId() != null ? newCelebDomainService.findById(reqDto.getNewCelebId()) + : null; + + NewBrand newBrand = reqDto.getNewBrandId() != null ? newBrandDomainService.findById(reqDto.getNewBrandId()) + : null; + ItemCategory itemCategory = + reqDto.getCategoryId() != null ? itemCategoryDomainService.findById(reqDto.getCategoryId()) + : null; + + TempItem tempItem = null; + + if (reqDto.getId() != null) { + tempItem = tempItemDomainService.findByIdOrNull(reqDto.getId()); + } + + TempItemSaveDto tempItemSaveDto = itemHelper.convertTempItemPostReqDtoToTempItemSaveDto(reqDto); + + TempItem postTempItem; + if (tempItem != null) { + postTempItem = TempItem.toEntity(tempItem.getId(), user, celeb, newCeleb, itemCategory, brand, newBrand, + tempItemSaveDto); + } else { + postTempItem = TempItem.toEntity(user, celeb, newCeleb, itemCategory, brand, newBrand, tempItemSaveDto); + } + + TempItem saveTempItem = tempItemDomainService.saveTempItem(postTempItem); + + // ItemImg 테이블에 추가 + tempItemImgDomainService.deleteAllByTempItemId(postTempItem.getId()); + if (reqDto.getImgList() != null) { + reqDto.getImgList() + .forEach(tempItemImg -> tempItemImgDomainService.saveTempItemImg(saveTempItem, tempItemImg)); + } + + // ItemLink 테이블에 추가 + tempItemLinkDomainService.deleteAllByTempItemId(postTempItem.getId()); + if (reqDto.getLinkList() != null) { + reqDto.getLinkList() + .forEach(tempItemLink -> tempItemLinkDomainService.saveTempItemLink(saveTempItem, tempItemLink)); + } + + // ItemHashtag 테이블에 추가 + tempItemHashtagDomainService.deleteAllByTempItemId(postTempItem.getId()); + if (reqDto.getHashTagIdList() != null) { + reqDto.getHashTagIdList().forEach(hashTag -> { + Hashtag tag = hashtagDomainService.findById(hashTag); + tempItemHashtagDomainService.saveTempItemHashtag(saveTempItem, tag); + }); + } + + return saveTempItem.getId(); + } + + @Transactional(readOnly = true) + public PaginationCountResponse getTempItemList(Long userId, Pageable pageable) { + User user = userDomainService.findById(userId); + Page tempItemPage = tempItemDomainService.getTempItemList(user, pageable); + + List tempItemImages = tempItemImgDomainService.getTempItemImages(tempItemPage.getContent()); + List tempItemLinks = tempItemLinkDomainService.getTempItemLinks(tempItemPage.getContent()); + List tempItemHashtags = tempItemHashtagDomainService.getTempItemHashtags( + tempItemPage.getContent()); + + Map> tempItemImgMap = tempItemImages.stream().collect( + Collectors.groupingBy(ti -> ti.getTempItem().getId(), + Collectors.mapping(ItemImgDto::of, Collectors.toList()))); + + Map> tempItemLinkMap = tempItemLinks.stream().collect( + Collectors.groupingBy(tl -> tl.getTempItem().getId(), + Collectors.mapping(ItemLinkDto::of, Collectors.toList()))); + + Map> tempItemHashtagMap = tempItemHashtags.stream().collect( + Collectors.groupingBy(th -> th.getTempItem().getId(), + Collectors.mapping(TempItemHashtag::getHashtag, Collectors.toList()))); + + List dtos = tempItemPage.getContent().stream().map(ti -> { + List hashtags = null; + if (tempItemHashtagMap.get(ti.getId()) != null) { + hashtags = tempItemHashtagMap.get(ti.getId()).stream() + .map(ItemHashtagResponseDto::of).toList(); + } + return TempItemResDto.of(ti, tempItemImgMap.get(ti.getId()), tempItemLinkMap.get(ti.getId()), hashtags); + }).toList(); + + return new PaginationCountResponse<>( + tempItemPage.hasNext(), + tempItemPage.getNumber(), + dtos, + tempItemPage.getTotalElements()); + + + } + + public void deleteTempItem(Long tempItemId) { + // 관련된 삭제 + // 1. tempItemImg 삭제 + tempItemImgDomainService.deleteAllByTempItemId(tempItemId); + // 2. tempItemLink 삭제 + tempItemLinkDomainService.deleteAllByTempItemId(tempItemId); + // 3. tempItemHashtag 삭제 + tempItemHashtagDomainService.deleteAllByTempItemId(tempItemId); + + // tempItem 삭제 + tempItemDomainService.deleteById(tempItemId); + } + + public void deleteAllTempItem(Long userId) { + // 1. 해당 유저의 모든 TempItem 조회 + List tempItemList = tempItemDomainService.findAllExceptLast(userId); + + // 2. 모든 TempItem에 대한 관련된 삭제 + tempItemList.forEach(tempItem -> { + // 2-1. tempItemImg 삭제 + tempItemImgDomainService.deleteAllByTempItemId(tempItem.getId()); + // 2-2. tempItemLink 삭제ㅎ + tempItemLinkDomainService.deleteAllByTempItemId(tempItem.getId()); + // 2-3. tempItemHashtag 삭제 + tempItemHashtagDomainService.deleteAllByTempItemId(tempItem.getId()); + // 3. TempItem 삭제 + tempItemDomainService.deleteById(tempItem.getId()); + }); + + } + + public TempItemCountResDto countTempItemCount(Long userId) { + return TempItemCountResDto.of(tempItemDomainService.countByUserId(userId)); + } + +} diff --git a/src/main/java/com/sluv/server/domain/notice/controller/NoticeController.java b/sluv-api/src/main/java/com/sluv/api/notice/controller/NoticeController.java similarity index 53% rename from src/main/java/com/sluv/server/domain/notice/controller/NoticeController.java rename to sluv-api/src/main/java/com/sluv/api/notice/controller/NoticeController.java index 3eb9a570..1d278b21 100644 --- a/src/main/java/com/sluv/server/domain/notice/controller/NoticeController.java +++ b/sluv-api/src/main/java/com/sluv/api/notice/controller/NoticeController.java @@ -1,10 +1,10 @@ -package com.sluv.server.domain.notice.controller; +package com.sluv.api.notice.controller; -import com.sluv.server.domain.notice.dto.NoticeDetailResDto; -import com.sluv.server.domain.notice.dto.NoticeSimpleResDto; -import com.sluv.server.domain.notice.service.NoticeService; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.notice.dto.NoticeDetailResponse; +import com.sluv.api.notice.dto.NoticeSimpleResponse; +import com.sluv.api.notice.service.NoticeService; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; @@ -28,13 +28,11 @@ public class NoticeController { """ ) @GetMapping("") - public ResponseEntity>> getAllNotice(Pageable pageable) { + public ResponseEntity>> getAllNotice( + Pageable pageable) { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(noticeService.getAllNotice(pageable)) - .build() - ); + PaginationResponse response = noticeService.getAllNotice(pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation( @@ -45,13 +43,10 @@ public ResponseEntity>> """ ) @GetMapping("/{noticeId}") - public ResponseEntity> getNoticeDetail( + public ResponseEntity> getNoticeDetail( @PathVariable("noticeId") Long noticeId) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(noticeService.getNoticeDetail(noticeId)) - .build() - ); + NoticeDetailResponse response = noticeService.getNoticeDetail(noticeId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } } diff --git a/src/main/java/com/sluv/server/domain/notice/dto/NoticeDetailResDto.java b/sluv-api/src/main/java/com/sluv/api/notice/dto/NoticeDetailResponse.java similarity index 73% rename from src/main/java/com/sluv/server/domain/notice/dto/NoticeDetailResDto.java rename to sluv-api/src/main/java/com/sluv/api/notice/dto/NoticeDetailResponse.java index 4a949eac..f081150b 100644 --- a/src/main/java/com/sluv/server/domain/notice/dto/NoticeDetailResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/notice/dto/NoticeDetailResponse.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.notice.dto; +package com.sluv.api.notice.dto; -import com.sluv.server.domain.notice.entity.Notice; -import com.sluv.server.domain.notice.enums.NoticeType; +import com.sluv.domain.notice.entity.Notice; +import com.sluv.domain.notice.enums.NoticeType; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; import lombok.AllArgsConstructor; @@ -13,7 +13,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder -public class NoticeDetailResDto { +public class NoticeDetailResponse { @Schema(description = "공지사항 제목") private String title; @@ -24,9 +24,9 @@ public class NoticeDetailResDto { @Schema(description = "공지사항 타입") private NoticeType noticeType; - public static NoticeDetailResDto of(Notice notice) { + public static NoticeDetailResponse of(Notice notice) { - return NoticeDetailResDto.builder() + return NoticeDetailResponse.builder() .title(notice.getTitle()) .content(notice.getContent()) .createdAt(notice.getCreatedAt()) diff --git a/src/main/java/com/sluv/server/domain/notice/dto/NoticeSimpleResDto.java b/sluv-api/src/main/java/com/sluv/api/notice/dto/NoticeSimpleResponse.java similarity index 73% rename from src/main/java/com/sluv/server/domain/notice/dto/NoticeSimpleResDto.java rename to sluv-api/src/main/java/com/sluv/api/notice/dto/NoticeSimpleResponse.java index 517ada4d..63d2e476 100644 --- a/src/main/java/com/sluv/server/domain/notice/dto/NoticeSimpleResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/notice/dto/NoticeSimpleResponse.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.notice.dto; +package com.sluv.api.notice.dto; -import com.sluv.server.domain.notice.entity.Notice; -import com.sluv.server.domain.notice.enums.NoticeType; +import com.sluv.domain.notice.entity.Notice; +import com.sluv.domain.notice.enums.NoticeType; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; import lombok.AllArgsConstructor; @@ -13,7 +13,7 @@ @AllArgsConstructor @NoArgsConstructor @Builder -public class NoticeSimpleResDto { +public class NoticeSimpleResponse { @Schema(description = "공지사항 id") private Long id; @Schema(description = "공지사항 제목") @@ -23,9 +23,9 @@ public class NoticeSimpleResDto { @Schema(description = "공지사항 타입") private NoticeType noticeType; - public static NoticeSimpleResDto of(Notice notice) { + public static NoticeSimpleResponse of(Notice notice) { - return NoticeSimpleResDto.builder() + return NoticeSimpleResponse.builder() .id(notice.getId()) .title(notice.getTitle()) .createdAt(notice.getCreatedAt()) diff --git a/sluv-api/src/main/java/com/sluv/api/notice/service/NoticeService.java b/sluv-api/src/main/java/com/sluv/api/notice/service/NoticeService.java new file mode 100644 index 00000000..528ea8bc --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/notice/service/NoticeService.java @@ -0,0 +1,49 @@ +package com.sluv.api.notice.service; + +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.notice.dto.NoticeDetailResponse; +import com.sluv.api.notice.dto.NoticeSimpleResponse; +import com.sluv.domain.notice.entity.Notice; +import com.sluv.domain.notice.service.NoticeDomainService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class NoticeService { + + private final NoticeDomainService noticeDomainService; + + /** + * 공지사항 리스트 조회 + */ + @Transactional(readOnly = true) + public PaginationResponse getAllNotice(Pageable pageable) { + // 공지사항 리스트 Page 조회 + Page noticePage = noticeDomainService.getAllNotice(pageable); + + // Content가 될 Dto 제작 + List content = noticePage.stream() + .map(NoticeSimpleResponse::of) + .toList(); + + return PaginationResponse.create(noticePage, content); + } + + /** + * 공지사항 상세 조회 + */ + @Transactional(readOnly = true) + public NoticeDetailResponse getNoticeDetail(Long noticeId) { + + // noticeId에 해당하는 공지사항 조회 + Notice notice = noticeDomainService.findById(noticeId); + + return NoticeDetailResponse.of(notice); + } +} diff --git a/src/main/java/com/sluv/server/domain/question/controller/QuestionController.java b/sluv-api/src/main/java/com/sluv/api/question/controller/QuestionController.java similarity index 53% rename from src/main/java/com/sluv/server/domain/question/controller/QuestionController.java rename to sluv-api/src/main/java/com/sluv/api/question/controller/QuestionController.java index ebc34f8e..3d7e8d51 100644 --- a/src/main/java/com/sluv/server/domain/question/controller/QuestionController.java +++ b/sluv-api/src/main/java/com/sluv/api/question/controller/QuestionController.java @@ -1,29 +1,28 @@ -package com.sluv.server.domain.question.controller; - -import com.sluv.server.domain.question.dto.QuestionBuyPostReqDto; -import com.sluv.server.domain.question.dto.QuestionBuySimpleResDto; -import com.sluv.server.domain.question.dto.QuestionFindPostReqDto; -import com.sluv.server.domain.question.dto.QuestionGetDetailResDto; -import com.sluv.server.domain.question.dto.QuestionHomeResDto; -import com.sluv.server.domain.question.dto.QuestionHowaboutPostReqDto; -import com.sluv.server.domain.question.dto.QuestionPostResDto; -import com.sluv.server.domain.question.dto.QuestionRecommendPostReqDto; -import com.sluv.server.domain.question.dto.QuestionReportReqDto; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.question.dto.QuestionVoteReqDto; -import com.sluv.server.domain.question.exception.QuestionTypeNotFoundException; -import com.sluv.server.domain.question.service.QuestionService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; +package com.sluv.api.question.controller; + +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.api.question.dto.QuestionBuyPostReqDto; +import com.sluv.api.question.dto.QuestionBuySimpleResDto; +import com.sluv.api.question.dto.QuestionFindPostReqDto; +import com.sluv.api.question.dto.QuestionGetDetailResDto; +import com.sluv.api.question.dto.QuestionHomeResDto; +import com.sluv.api.question.dto.QuestionHowaboutPostReqDto; +import com.sluv.api.question.dto.QuestionPostResDto; +import com.sluv.api.question.dto.QuestionRecommendPostReqDto; +import com.sluv.api.question.dto.QuestionReportReqDto; +import com.sluv.api.question.dto.QuestionVoteReqDto; +import com.sluv.api.question.service.QuestionService; +import com.sluv.common.annotation.CurrentUserId; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import com.sluv.domain.question.exception.QuestionTypeNotFoundException; import io.swagger.v3.oas.annotations.Operation; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.lang.Nullable; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -42,52 +41,40 @@ public class QuestionController { @Operation(summary = "*찾아주세요 게시글 등록", description = "User 토큰 필요. 생성: id -> null. 수정: id -> 해당 Question Id") @PostMapping("/find") - public ResponseEntity> postFind(@AuthenticationPrincipal User user, + public ResponseEntity> postFind(@CurrentUserId Long userId, @RequestBody QuestionFindPostReqDto dto) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(questionService.postQuestionFind(user, dto)) - .build() - ); + QuestionPostResDto response = questionService.postQuestionFind(userId, dto); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*이중에뭐살까 게시글 등록", description = "User 토큰 필요. 생성: id -> null. 수정: id -> 해당 Question Id") @PostMapping("/buy") - public ResponseEntity> postBuy(@AuthenticationPrincipal User user, + public ResponseEntity> postBuy(@CurrentUserId Long userId, @RequestBody QuestionBuyPostReqDto dto) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(questionService.postQuestionBuy(user, dto)) - .build() - ); + QuestionPostResDto response = questionService.postQuestionBuy(userId, dto); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*이거어때 게시글 등록", description = "User 토큰 필요. 생성: id -> null. 수정: id -> 해당 Question Id") @PostMapping("/how-about") - public ResponseEntity> postHowabout(@AuthenticationPrincipal User user, + public ResponseEntity> postHowabout(@CurrentUserId Long userId, @RequestBody QuestionHowaboutPostReqDto dto) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(questionService.postQuestionHowabout(user, dto)) - .build() - ); + QuestionPostResDto response = questionService.postQuestionHowabout(userId, dto); + + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*추천해 줘 게시글 등록", description = "User 토큰 필요. 생성: id -> null. 수정: id -> 해당 Question Id") @PostMapping("/recommend") - public ResponseEntity> postRecommend(@AuthenticationPrincipal User user, + public ResponseEntity> postRecommend(@CurrentUserId Long userId, @RequestBody QuestionRecommendPostReqDto dto) { - - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(questionService.postQuestionRecommend(user, dto)) - .build() - ); + QuestionPostResDto response = questionService.postQuestionRecommend(userId, dto); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "Question 게시글 삭제", @@ -95,86 +82,69 @@ public ResponseEntity> postRecommend(@Au @DeleteMapping("/{questionId}") public ResponseEntity deleteQuestion(@PathVariable("questionId") Long questionId) { questionService.deleteQuestion(questionId); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*Question 게시글 좋아요", description = "User 토큰 필요") @PostMapping("/{questionId}/like") - public ResponseEntity postQuestionLike(@AuthenticationPrincipal User user, + public ResponseEntity postQuestionLike(@CurrentUserId Long userId, @PathVariable("questionId") Long questionId) { - questionService.postQuestionLike(user, questionId); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + questionService.postQuestionLike(userId, questionId); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*Question 게시글 신고", description = "User 토큰 필요. 중복 신고 시 [QuestionReportDuplicate] 예외 발생") @PostMapping("/{questionId}/report") - public ResponseEntity postQuestionReport(@AuthenticationPrincipal User user, + public ResponseEntity postQuestionReport(@CurrentUserId Long userId, @PathVariable("questionId") Long questionId, @RequestBody QuestionReportReqDto dto) { - questionService.postQuestionReport(user, questionId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + questionService.postQuestionReport(userId, questionId, dto); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*Question 게시글 상세조회", description = "User 토큰 필요") @GetMapping("/{questionId}") public ResponseEntity> postQuestionReport( - @AuthenticationPrincipal User user, @PathVariable("questionId") Long questionId) { + @CurrentUserId Long userId, @PathVariable("questionId") Long questionId) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(questionService.getQuestionDetail(user, questionId)) - .build() - ); + QuestionGetDetailResDto response = questionService.getQuestionDetail(userId, questionId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "*QuestionBuy 게시글 투표", description = "User 토큰 필요. 좋아요 시스템과 동일.") @PostMapping("/{questionId}/vote") - public ResponseEntity postQuestionVote(@AuthenticationPrincipal User user, + public ResponseEntity postQuestionVote(@CurrentUserId Long userId, @PathVariable("questionId") Long questionId, @RequestBody QuestionVoteReqDto dto) { - - questionService.postQuestionVote(user, questionId, dto); - - return ResponseEntity.ok().body( - new SuccessResponse() - ); + questionService.postQuestionVote(userId, questionId, dto); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*Question 기다리고 있어요", description = "qType에 따라 Question 타입 변경. questionId는 현재 Question은 제외하고 조회하기 위함.") @GetMapping("/wait") public ResponseEntity>> getWaitQuestionBuy( - @AuthenticationPrincipal User user, + @CurrentUserId Long userId, @RequestParam("questionId") Long questionId, @RequestParam("qType") String qType) { List result = switch (qType) { - case "Buy" -> questionService.getWaitQuestionBuy(user, questionId); - case "Find" -> questionService.getWaitQuestionFind(user, questionId); - case "How" -> questionService.getWaitQuestionHowabout(user, questionId); - case "Recommend" -> questionService.getWaitQuestionRecommend(user, questionId); + case "Buy" -> questionService.getWaitQuestionBuy(userId, questionId); + case "Find" -> questionService.getWaitQuestionFind(userId, questionId); + case "How" -> questionService.getWaitQuestionHowabout(userId, questionId); + case "Recommend" -> questionService.getWaitQuestionRecommend(userId, questionId); default -> throw new QuestionTypeNotFoundException(); }; - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(result) - .build() - ); + return ResponseEntity.ok().body(SuccessDataResponse.create(result)); } @Deprecated @Operation(summary = "Question 커뮤니티 리스트 조회", description = "Pagination 적용") @GetMapping("/list") - public ResponseEntity>> getQuestionList( + public ResponseEntity>> getQuestionList( @Nullable @RequestParam("qType") String qType, Pageable pageable) { - PaginationResDto result = switch (qType) { + PaginationResponse result = switch (qType) { case "Total" -> questionService.getTotalQuestionList(pageable); // case "Buy" -> questionService.getQuestionBuyList(null, pageable); case "Find" -> questionService.getQuestionFindList(null, pageable); @@ -183,36 +153,25 @@ public ResponseEntity default -> throw new QuestionTypeNotFoundException(); }; - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(result) - .build() - ); + return ResponseEntity.ok().body(SuccessDataResponse.create(result)); } @Operation(summary = "Question 커뮤니티 게시글 종합 검색", description = "Pagination 적용. 최신순으로 조회") @GetMapping("/total") - public ResponseEntity>> getQuestionTotalList( + public ResponseEntity>> getQuestionTotalList( Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(questionService.getTotalQuestionList(pageable)) - .build() - ); + PaginationResponse response = questionService.getTotalQuestionList(pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "QuestionFind 커뮤니티 게시글 검색", description = "Pagination 적용. Ordering: 최신순으로 조회. Filtering: celebId.") @GetMapping("/find") - public ResponseEntity>> getQuestionFindList( + public ResponseEntity>> getQuestionFindList( @Nullable @RequestParam("celebId") Long celebId, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(questionService.getQuestionFindList(celebId, pageable)) - .build() - ); + PaginationResponse response = questionService.getQuestionFindList(celebId, + pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation( @@ -228,64 +187,48 @@ public ResponseEntity """ ) @GetMapping("/buy") - public ResponseEntity>> getQuestionBuyList( - @AuthenticationPrincipal User user, @Nullable @RequestParam("voteStatus") String voteStatus, + public ResponseEntity>> getQuestionBuyList( + @CurrentUserId Long userId, @Nullable @RequestParam("voteStatus") String voteStatus, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(questionService.getQuestionBuyList(user, voteStatus, pageable)) - .build() - ); + PaginationResponse response = questionService.getQuestionBuyList(userId, + voteStatus, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "QuestionHowabout 커뮤니티 게시글 검색", description = "Pagination 적용. Ordering 최신순") @GetMapping("/howabout") - public ResponseEntity>> getQuestionHowaboutList( + public ResponseEntity>> getQuestionHowaboutList( Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(questionService.getQuestionHowaboutList(pageable)) - .build() - ); + PaginationResponse response = questionService.getQuestionHowaboutList( + pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "QuestionRecommend 커뮤니티 게시글 검색", description = "Pagination 적용. Ordering 최신순. Filtering 전체, 특정해시태그") @GetMapping("/recommend") - public ResponseEntity>> getQuestionRecommendList( + public ResponseEntity>> getQuestionRecommendList( @Nullable @RequestParam String hashtag, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(questionService.getQuestionRecommendList(hashtag, pageable)) - .build() - ); + PaginationResponse response = questionService.getQuestionRecommendList( + hashtag, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "일간 핫 커뮤니티 게시글 검색", description = " 10개 조회. Ordering 인기순(조회수 + 좋아요 수 + 댓글 수). 매일 00시 00분 00초를 기준으로 업데이트") @GetMapping("/dailyhot") public ResponseEntity>> getDailyHotQuestionList() { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(questionService.getDailyHotQuestionList()) - .build() - ); + List response = questionService.getDailyHotQuestionList(); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation(summary = "주간 핫 커뮤니티 게시글 검색", description = "Pagination 적용. Ordering 조회수 + 좋아요 수 + 댓글 수. Filtering 현재를 기점으로 일주일간 작성된 글") @GetMapping("/weeklyhot") - public ResponseEntity>> getWeeklyHotQuestionList( + public ResponseEntity>> getWeeklyHotQuestionList( Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(questionService.getWeeklyHotQuestionList(pageable)) - .build() - ); + PaginationResponse response = questionService.getWeeklyHotQuestionList( + pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } } diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionBuyPostReqDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionBuyPostReqDto.java similarity index 94% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionBuyPostReqDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionBuyPostReqDto.java index 0a84e51f..0e3b4007 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionBuyPostReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionBuyPostReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionBuySimpleResDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionBuySimpleResDto.java similarity index 84% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionBuySimpleResDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionBuySimpleResDto.java index 2e050536..8619de38 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionBuySimpleResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionBuySimpleResDto.java @@ -1,13 +1,13 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.entity.QuestionBuy; -import com.sluv.server.domain.question.entity.QuestionFind; -import com.sluv.server.domain.question.entity.QuestionHowabout; -import com.sluv.server.domain.question.entity.QuestionRecommend; -import com.sluv.server.domain.question.entity.QuestionVote; -import com.sluv.server.domain.user.dto.UserInfoDto; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.QuestionBuy; +import com.sluv.domain.question.entity.QuestionFind; +import com.sluv.domain.question.entity.QuestionHowabout; +import com.sluv.domain.question.entity.QuestionRecommend; +import com.sluv.domain.question.entity.QuestionVote; +import com.sluv.domain.user.dto.UserInfoDto; +import com.sluv.domain.user.entity.User; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; import java.util.List; diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionFindPostReqDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionFindPostReqDto.java similarity index 94% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionFindPostReqDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionFindPostReqDto.java index 4540f112..64230593 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionFindPostReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionFindPostReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionGetDetailResDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionGetDetailResDto.java similarity index 88% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionGetDetailResDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionGetDetailResDto.java index 442c2e11..2a581230 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionGetDetailResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionGetDetailResDto.java @@ -1,9 +1,9 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; -import com.sluv.server.domain.celeb.dto.CelebChipResDto; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.user.dto.UserInfoDto; -import com.sluv.server.domain.user.entity.User; +import com.sluv.api.celeb.dto.response.CelebChipResponse; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.user.dto.UserInfoDto; +import com.sluv.domain.user.entity.User; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; import java.util.List; @@ -53,9 +53,9 @@ public class QuestionGetDetailResDto { // Question Find @Schema(description = "게시글에 해당하는 Celeb") - private CelebChipResDto celeb; + private CelebChipResponse celeb; @Schema(description = "게시글에 해당하는 NewCeleb") - private CelebChipResDto newCeleb; + private CelebChipResponse newCeleb; // Question Recommend @Schema(description = "QuestionRecommend Category 리스트") @@ -64,7 +64,7 @@ public class QuestionGetDetailResDto { public static QuestionGetDetailResDto of(Question question, String qType, User writer, List imgList, List itemList, Long likeNum, Long commentNum, Boolean hasLike, Boolean hasMine, - CelebChipResDto celeb, CelebChipResDto newCeleb, + CelebChipResponse celeb, CelebChipResponse newCeleb, LocalDateTime voteEndTime, Long totalVoteNum, Long voteStatus, List recommendCategoryList) { diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionHomeResDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionHomeResDto.java similarity index 69% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionHomeResDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionHomeResDto.java index 4a586553..70abb777 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionHomeResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionHomeResDto.java @@ -1,12 +1,13 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.entity.QuestionBuy; -import com.sluv.server.domain.question.entity.QuestionFind; -import com.sluv.server.domain.question.entity.QuestionHowabout; -import com.sluv.server.domain.question.entity.QuestionRecommend; -import com.sluv.server.domain.user.dto.UserInfoDto; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.question.dto.QuestionImgSimpleDto; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.QuestionBuy; +import com.sluv.domain.question.entity.QuestionFind; +import com.sluv.domain.question.entity.QuestionHowabout; +import com.sluv.domain.question.entity.QuestionRecommend; +import com.sluv.domain.user.dto.UserInfoDto; +import com.sluv.domain.user.entity.User; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import lombok.AllArgsConstructor; @@ -26,9 +27,9 @@ public class QuestionHomeResDto { @Schema(description = "작성자 정보") private UserInfoDto user; @Schema(description = "Question 이미지") - private List imgList; + private List imgList; - public static QuestionHomeResDto of(Question question, User writer, List imgList) { + public static QuestionHomeResDto of(Question question, User writer, List imgList) { String qType = null; if (question instanceof QuestionBuy) { diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionHowaboutPostReqDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionHowaboutPostReqDto.java similarity index 94% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionHowaboutPostReqDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionHowaboutPostReqDto.java index 1c58182b..a0461d70 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionHowaboutPostReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionHowaboutPostReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionImgReqDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionImgReqDto.java similarity index 93% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionImgReqDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionImgReqDto.java index d9f38a0c..00196d1e 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionImgReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionImgReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionImgResDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionImgResDto.java similarity index 93% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionImgResDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionImgResDto.java index 542e792a..915ee98b 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionImgResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionImgResDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; -import com.sluv.server.domain.question.entity.QuestionImg; +import com.sluv.domain.question.entity.QuestionImg; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionItemReqDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionItemReqDto.java similarity index 93% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionItemReqDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionItemReqDto.java index 6aa73f19..b8cb133c 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionItemReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionItemReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionItemResDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionItemResDto.java similarity index 83% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionItemResDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionItemResDto.java index 9c5dc0a8..2aac2aa5 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionItemResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionItemResDto.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.question.entity.QuestionItem; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.question.entity.QuestionItem; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -14,7 +14,7 @@ @Builder public class QuestionItemResDto { @Schema(description = "Question Item") - private ItemSimpleResDto item; + private ItemSimpleDto item; @Schema(description = "Question Item 설명") private String description; @Schema(description = "투표 수") @@ -26,10 +26,10 @@ public class QuestionItemResDto { @Schema(description = "순서") private Integer sortOrder; - public static QuestionItemResDto of(QuestionItem questionItem, ItemSimpleResDto itemSimpleResDto, + public static QuestionItemResDto of(QuestionItem questionItem, ItemSimpleDto itemSimpleDto, QuestionVoteDataDto voteDataDto) { return QuestionItemResDto.builder() - .item(itemSimpleResDto) + .item(itemSimpleDto) .description(questionItem.getDescription()) .voteNum( voteDataDto != null diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionPostResDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionPostResDto.java similarity index 91% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionPostResDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionPostResDto.java index cadf3e9e..682f1682 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionPostResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionPostResDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionRecommendPostReqDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionRecommendPostReqDto.java similarity index 91% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionRecommendPostReqDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionRecommendPostReqDto.java index 89cce2b7..815573ce 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionRecommendPostReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionRecommendPostReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; @@ -6,7 +6,6 @@ import lombok.Data; import lombok.NoArgsConstructor; -import java.time.LocalDateTime; import java.util.List; @Data diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionReportReqDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionReportReqDto.java similarity index 70% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionReportReqDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionReportReqDto.java index 2da1f128..676ef1f7 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionReportReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionReportReqDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; -import com.sluv.server.domain.question.enums.QuestionReportReason; +import com.sluv.domain.question.enums.QuestionReportReason; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionVoteDataDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionVoteDataDto.java similarity index 92% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionVoteDataDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionVoteDataDto.java index 14cc75ed..a525611b 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionVoteDataDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionVoteDataDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionVoteReqDto.java b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionVoteReqDto.java similarity index 76% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionVoteReqDto.java rename to sluv-api/src/main/java/com/sluv/api/question/dto/QuestionVoteReqDto.java index 28b9f8dc..5baddd1b 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionVoteReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/question/dto/QuestionVoteReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.api.question.dto; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/question/mapper/QuestionDtoMapper.java b/sluv-api/src/main/java/com/sluv/api/question/mapper/QuestionDtoMapper.java similarity index 62% rename from src/main/java/com/sluv/server/domain/question/mapper/QuestionDtoMapper.java rename to sluv-api/src/main/java/com/sluv/api/question/mapper/QuestionDtoMapper.java index a5d380e5..1dfa2345 100644 --- a/src/main/java/com/sluv/server/domain/question/mapper/QuestionDtoMapper.java +++ b/sluv-api/src/main/java/com/sluv/api/question/mapper/QuestionDtoMapper.java @@ -1,23 +1,23 @@ -package com.sluv.server.domain.question.mapper; +package com.sluv.api.question.mapper; -import com.sluv.server.domain.comment.repository.CommentRepository; -import com.sluv.server.domain.item.entity.ItemImg; -import com.sluv.server.domain.item.repository.ItemImgRepository; -import com.sluv.server.domain.question.dto.QuestionImgSimpleResDto; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.entity.QuestionBuy; -import com.sluv.server.domain.question.entity.QuestionFind; -import com.sluv.server.domain.question.entity.QuestionHowabout; -import com.sluv.server.domain.question.entity.QuestionRecommend; -import com.sluv.server.domain.question.entity.QuestionRecommendCategory; -import com.sluv.server.domain.question.exception.QuestionTypeNotFoundException; -import com.sluv.server.domain.question.repository.QuestionImgRepository; -import com.sluv.server.domain.question.repository.QuestionItemRepository; -import com.sluv.server.domain.question.repository.QuestionLikeRepository; -import com.sluv.server.domain.question.repository.QuestionRecommendCategoryRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.repository.UserRepository; +import com.sluv.domain.comment.repository.CommentRepository; +import com.sluv.domain.item.entity.ItemImg; +import com.sluv.domain.item.repository.ItemImgRepository; +import com.sluv.domain.question.dto.QuestionImgSimpleDto; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.QuestionBuy; +import com.sluv.domain.question.entity.QuestionFind; +import com.sluv.domain.question.entity.QuestionHowabout; +import com.sluv.domain.question.entity.QuestionRecommend; +import com.sluv.domain.question.entity.QuestionRecommendCategory; +import com.sluv.domain.question.exception.QuestionTypeNotFoundException; +import com.sluv.domain.question.repository.QuestionImgRepository; +import com.sluv.domain.question.repository.QuestionItemRepository; +import com.sluv.domain.question.repository.QuestionLikeRepository; +import com.sluv.domain.question.repository.QuestionRecommendCategoryRepository; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.repository.UserRepository; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -36,20 +36,20 @@ public class QuestionDtoMapper { public QuestionSimpleResDto dtoBuildByQuestionType(Question question) { String qType = null; - List imgList = null; - List itemImgList = null; + List imgList = null; + List itemImgList = null; String celebName = null; List categoryList = null; if (question instanceof QuestionBuy) { // 1. question이 QuestionBuy 일 경우 // 이미지 DTO 생성 - List imgSimpleList = questionImgRepository.findAllByQuestionId(question.getId()) - .stream().map(QuestionImgSimpleResDto::of).toList(); + List imgSimpleList = questionImgRepository.findAllByQuestionId(question.getId()) + .stream().map(QuestionImgSimpleDto::of).toList(); // 아이템 이미지 DTO 생성 - List itemImgSimpleList = questionItemRepository.findAllByQuestionId( + List itemImgSimpleList = questionItemRepository.findAllByQuestionId( question.getId()).stream().map(questionItem -> { ItemImg mainImg = itemImgRepository.findMainImg(questionItem.getItem().getId()); - return QuestionImgSimpleResDto.of(mainImg); + return QuestionImgSimpleDto.of(mainImg); }).toList(); qType = "Buy"; diff --git a/src/main/java/com/sluv/server/domain/question/service/QuestionService.java b/sluv-api/src/main/java/com/sluv/api/question/service/QuestionService.java similarity index 53% rename from src/main/java/com/sluv/server/domain/question/service/QuestionService.java rename to sluv-api/src/main/java/com/sluv/api/question/service/QuestionService.java index 33ca5356..7cfaa043 100644 --- a/src/main/java/com/sluv/server/domain/question/service/QuestionService.java +++ b/sluv-api/src/main/java/com/sluv/api/question/service/QuestionService.java @@ -1,72 +1,32 @@ -package com.sluv.server.domain.question.service; - -import com.sluv.server.domain.alarm.service.QuestionAlarmService; -import com.sluv.server.domain.celeb.dto.CelebChipResDto; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.celeb.repository.CelebRepository; -import com.sluv.server.domain.celeb.repository.NewCelebRepository; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.closet.repository.ClosetRepository; -import com.sluv.server.domain.comment.repository.CommentRepository; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.ItemImg; -import com.sluv.server.domain.item.exception.ItemNotFoundException; -import com.sluv.server.domain.item.repository.ItemImgRepository; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.item.repository.ItemScrapRepository; -import com.sluv.server.domain.question.dto.QuestionBuyPostReqDto; -import com.sluv.server.domain.question.dto.QuestionBuySimpleResDto; -import com.sluv.server.domain.question.dto.QuestionFindPostReqDto; -import com.sluv.server.domain.question.dto.QuestionGetDetailResDto; -import com.sluv.server.domain.question.dto.QuestionHomeResDto; -import com.sluv.server.domain.question.dto.QuestionHowaboutPostReqDto; -import com.sluv.server.domain.question.dto.QuestionImgReqDto; -import com.sluv.server.domain.question.dto.QuestionImgResDto; -import com.sluv.server.domain.question.dto.QuestionImgSimpleResDto; -import com.sluv.server.domain.question.dto.QuestionItemReqDto; -import com.sluv.server.domain.question.dto.QuestionItemResDto; -import com.sluv.server.domain.question.dto.QuestionPostResDto; -import com.sluv.server.domain.question.dto.QuestionRecommendPostReqDto; -import com.sluv.server.domain.question.dto.QuestionReportReqDto; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.question.dto.QuestionVoteDataDto; -import com.sluv.server.domain.question.dto.QuestionVoteReqDto; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.entity.QuestionBuy; -import com.sluv.server.domain.question.entity.QuestionFind; -import com.sluv.server.domain.question.entity.QuestionHowabout; -import com.sluv.server.domain.question.entity.QuestionImg; -import com.sluv.server.domain.question.entity.QuestionItem; -import com.sluv.server.domain.question.entity.QuestionLike; -import com.sluv.server.domain.question.entity.QuestionRecommend; -import com.sluv.server.domain.question.entity.QuestionRecommendCategory; -import com.sluv.server.domain.question.entity.QuestionReport; -import com.sluv.server.domain.question.entity.QuestionVote; -import com.sluv.server.domain.question.entity.RecentQuestion; -import com.sluv.server.domain.question.enums.QuestionStatus; -import com.sluv.server.domain.question.exception.QuestionNotFoundException; -import com.sluv.server.domain.question.exception.QuestionReportDuplicateException; -import com.sluv.server.domain.question.exception.QuestionTypeNotFoundException; -import com.sluv.server.domain.question.repository.QuestionImgRepository; -import com.sluv.server.domain.question.repository.QuestionItemRepository; -import com.sluv.server.domain.question.repository.QuestionLikeRepository; -import com.sluv.server.domain.question.repository.QuestionRecommendCategoryRepository; -import com.sluv.server.domain.question.repository.QuestionReportRepository; -import com.sluv.server.domain.question.repository.QuestionRepository; -import com.sluv.server.domain.question.repository.QuestionVoteRepository; -import com.sluv.server.domain.question.repository.RecentQuestionRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.cache.CacheService; -import com.sluv.server.global.common.response.PaginationResDto; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; +package com.sluv.api.question.service; + +import com.sluv.api.alarm.service.QuestionAlarmService; +import com.sluv.api.celeb.dto.response.CelebChipResponse; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.question.dto.*; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.celeb.service.CelebDomainService; +import com.sluv.domain.celeb.service.NewCelebDomainService; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.closet.service.ClosetDomainService; +import com.sluv.domain.comment.service.CommentDomainService; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemImg; +import com.sluv.domain.item.service.ItemDomainService; +import com.sluv.domain.item.service.ItemImgDomainService; +import com.sluv.domain.item.service.ItemScrapDomainService; +import com.sluv.domain.question.dto.QuestionImgSimpleDto; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import com.sluv.domain.question.entity.*; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.question.exception.QuestionReportDuplicateException; +import com.sluv.domain.question.exception.QuestionTypeNotFoundException; +import com.sluv.domain.question.service.*; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import com.sluv.infra.cache.CacheService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -74,55 +34,60 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; +import java.util.*; + @Service @Slf4j @RequiredArgsConstructor public class QuestionService { - private final QuestionRepository questionRepository; - private final QuestionImgRepository questionImgRepository; - private final QuestionItemRepository questionItemRepository; - private final QuestionRecommendCategoryRepository questionRecommendCategoryRepository; - private final QuestionLikeRepository questionLikeRepository; - private final QuestionReportRepository questionReportRepository; - private final CommentRepository commentRepository; - private final ItemRepository itemRepository; - private final ItemImgRepository itemImgRepository; - private final CelebRepository celebRepository; - private final NewCelebRepository newCelebRepository; - private final RecentQuestionRepository recentQuestionRepository; - private final ItemScrapRepository itemScrapRepository; - private final ClosetRepository closetRepository; - private final QuestionVoteRepository questionVoteRepository; - private final UserRepository userRepository; + private final QuestionDomainService questionDomainService; + private final QuestionImgDomainService questionImgDomainService; + private final QuestionItemDomainService questionItemDomainService; + private final QuestionRecommendCategoryDomainService questionRecommendCategoryDomainService; + private final QuestionLikeDomainService questionLikeDomainService; + private final QuestionReportDomainService questionReportDomainService; + private final CommentDomainService commentDomainService; + private final ItemDomainService itemDomainService; + private final ItemImgDomainService itemImgDomainService; + private final CelebDomainService celebDomainService; + private final NewCelebDomainService newCelebDomainService; + private final RecentQuestionDomainService recentQuestionDomainService; + private final ItemScrapDomainService itemScrapDomainService; + private final ClosetDomainService closetDomainService; + private final QuestionVoteDomainService questionVoteDomainService; + private final UserDomainService userDomainService; private final CacheService cacheService; private final QuestionAlarmService questionAlarmService; @Transactional - public QuestionPostResDto postQuestionFind(User user, QuestionFindPostReqDto dto) { + public QuestionPostResDto postQuestionFind(Long userId, QuestionFindPostReqDto dto) { /** * 1. 생성 or 수정 * 2. QuestionFind 저장 * 3. QuestionImg 저장 * 4. QuestionItem 저장 */ + User user = userDomainService.findById(userId); log.info("찾아주세요 게시글 등록 or 수정 - 사용자 : {}, 질문 게시글 : {}, 질문 게시글 제목 : {}", user.getId(), dto.getId() == null ? null : dto.getId(), dto.getTitle()); // 1. 생성 or 수정 Celeb celeb = null; if (dto.getCelebId() != null) { - celeb = celebRepository.findById(dto.getCelebId()).orElse(null); + celeb = celebDomainService.findByIdOrNull(dto.getCelebId()); } NewCeleb newCeleb = null; if (dto.getNewCelebId() != null) { - newCeleb = newCelebRepository.findById(dto.getNewCelebId()).orElse(null); + newCeleb = newCelebDomainService.findByNewCelebIdOrNull(dto.getNewCelebId()); } - QuestionFind questionFind = QuestionFind.toEntity(user, dto, celeb, newCeleb); + QuestionFind questionFind = QuestionFind.toEntity(user, dto.getId(), dto.getTitle(), dto.getContent(), celeb, + newCeleb); // 2. QuestionFind 저장 - QuestionFind newQuestionFind = questionRepository.save(questionFind); + QuestionFind newQuestionFind = (QuestionFind) questionDomainService.saveQuestion(questionFind); // 3. QuestionImg 저장 postQuestionImgs(dto.getImgList(), newQuestionFind); @@ -135,21 +100,22 @@ public QuestionPostResDto postQuestionFind(User user, QuestionFindPostReqDto dto } @Transactional - public QuestionPostResDto postQuestionBuy(User user, QuestionBuyPostReqDto dto) { + public QuestionPostResDto postQuestionBuy(Long userId, QuestionBuyPostReqDto dto) { /** * 1. 생성 or 수정 * 2. QuestionBuy 저장 * 3. QuestionImg 저장 * 4. QuestionItem 저장 */ + User user = userDomainService.findById(userId); log.info("이 중에 뭐 살까 게시글 등록 or 수정 - 사용자 : {}, 질문 게시글 : {}, 질문 게시글 제목 : {}", user.getId(), dto.getId() == null ? null : dto.getId(), dto.getTitle()); // 1. 생성 or 수정 - QuestionBuy questionBuy = QuestionBuy.toEntity(user, dto); + QuestionBuy questionBuy = QuestionBuy.toEntity(user, dto.getId(), dto.getTitle(), dto.getVoteEndTime()); // 2. QuestionBuy 저장 - QuestionBuy newQuestionBuy = questionRepository.save(questionBuy); + QuestionBuy newQuestionBuy = (QuestionBuy) questionDomainService.saveQuestion(questionBuy); // 3. QuestionImg 저장 postQuestionImgs(dto.getImgList(), newQuestionBuy); @@ -161,22 +127,23 @@ public QuestionPostResDto postQuestionBuy(User user, QuestionBuyPostReqDto dto) } @Transactional - public QuestionPostResDto postQuestionHowabout(User user, QuestionHowaboutPostReqDto dto) { + public QuestionPostResDto postQuestionHowabout(Long userId, QuestionHowaboutPostReqDto dto) { /** * 1. 생성 or 수정 * 2. QuestionHowabout 저장 * 3. QuestionImg 저장 * 4. QuestionItem 저장 */ - + User user = userDomainService.findById(userId); log.info("이거 어때 게시글 등록 or 수정 - 사용자 : {}, 질문 게시글 : {}, 질문 게시글 제목 : {}", user.getId(), dto.getId() == null ? null : dto.getId(), dto.getTitle()); // 1. 생성 or 수정 - QuestionHowabout questionHowabout = QuestionHowabout.toEntity(user, dto); + QuestionHowabout questionHowabout = QuestionHowabout.toEntity(user, dto.getId(), dto.getTitle(), + dto.getContent()); // 2. QuestionHotabout 저장 - QuestionHowabout newQuestionHowabout = questionRepository.save(questionHowabout); + QuestionHowabout newQuestionHowabout = (QuestionHowabout) questionDomainService.saveQuestion(questionHowabout); // 3. QuestionImg 저장 postQuestionImgs(dto.getImgList(), newQuestionHowabout); @@ -188,7 +155,7 @@ public QuestionPostResDto postQuestionHowabout(User user, QuestionHowaboutPostRe } @Transactional - public QuestionPostResDto postQuestionRecommend(User user, QuestionRecommendPostReqDto dto) { + public QuestionPostResDto postQuestionRecommend(Long userId, QuestionRecommendPostReqDto dto) { /** * 1. 생성 or 수정 * 1. QuestionRecommend 저장 @@ -196,24 +163,27 @@ public QuestionPostResDto postQuestionRecommend(User user, QuestionRecommendPost * 3. QuestionImg 저장 * 4. QuestionItem 저장 */ + User user = userDomainService.findById(userId); log.info("추천해줘 게시글 등록 or 수정 - 사용자 : {}, 질문 게시글 : {}, 질문 게시글 제목 : {}", user.getId(), dto.getId() == null ? null : dto.getId(), dto.getTitle()); // 1. 생성 or 수정 - QuestionRecommend questionRecommend = QuestionRecommend.toEntity(user, dto); + QuestionRecommend questionRecommend = QuestionRecommend.toEntity(user, dto.getId(), dto.getTitle(), + dto.getContent()); // 2. QuestionRecommend 저장 - QuestionRecommend newQuestionRecommend = questionRepository.save(questionRecommend); + QuestionRecommend newQuestionRecommend = (QuestionRecommend) questionDomainService.saveQuestion( + questionRecommend); // 3. Recommend Category 저장 // Question에 대한 RecommendCategory 초기화 - questionRecommendCategoryRepository.deleteAllByQuestionId(newQuestionRecommend.getId()); + questionRecommendCategoryDomainService.deleteAllByQuestionId(newQuestionRecommend.getId()); - List recommendCategoryList = dto.getCategoryNameList().stream() + List recommendCategories = dto.getCategoryNameList().stream() .map(categoryName -> QuestionRecommendCategory.toEntity(newQuestionRecommend, categoryName) ).toList(); - questionRecommendCategoryRepository.saveAll(recommendCategoryList); + questionRecommendCategoryDomainService.saveAll(recommendCategories); // 4. QuestionImg 저장 @@ -230,15 +200,16 @@ public QuestionPostResDto postQuestionRecommend(User user, QuestionRecommendPost */ private void postQuestionImgs(List dtoList, Question question) { // Question에 대한 Img 초기화 - questionImgRepository.deleteAllByQuestionId(question.getId()); + questionImgDomainService.deleteAllByQuestionId(question.getId()); if (dtoList != null) { // Question Img들 추가 List imgList = dtoList.stream() - .map(imgDto -> QuestionImg.toEntity(question, imgDto)) + .map(imgDto -> QuestionImg.toEntity(question, imgDto.getImgUrl(), imgDto.getDescription(), + imgDto.getRepresentFlag(), imgDto.getSortOrder())) .toList(); - questionImgRepository.saveAll(imgList); + questionImgDomainService.saveAll(imgList); } } @@ -247,56 +218,57 @@ private void postQuestionImgs(List dtoList, Question question */ private void postQuestionItems(List dtoList, Question question) { // Question에 대한 Item 초기화 - questionItemRepository.deleteAllByQuestionId(question.getId()); + questionItemDomainService.deleteAllByQuestionId(question.getId()); if (dtoList != null) { // Question Item들 추가 - List itemList = dtoList.stream().map(itemDto -> { - Item item = itemRepository.findById(itemDto.getItemId()).orElseThrow(ItemNotFoundException::new); - return QuestionItem.toEntity(question, item, itemDto); + List items = dtoList.stream().map(itemDto -> { + Item item = itemDomainService.findById(itemDto.getItemId()); + return QuestionItem.toEntity(question, item, itemDto.getDescription(), itemDto.getRepresentFlag(), + itemDto.getSortOrder()); } ).toList(); - questionItemRepository.saveAll(itemList); + questionItemDomainService.saveAll(items); } } @Transactional public void deleteQuestion(Long questionId) { log.info("질문 게시글 삭제 - 질문 게시글 : {}", questionId); - Question question = questionRepository.findById(questionId).orElseThrow(QuestionNotFoundException::new); + Question question = questionDomainService.findById(questionId); question.changeQuestionStatus(QuestionStatus.DELETED); } @Transactional - public void postQuestionLike(User user, Long questionId) { + public void postQuestionLike(Long userId, Long questionId) { + User user = userDomainService.findById(userId); log.info("질문 게시글 좋아요 - 사용자 : {}, 질문 게시글 : {}", user.getId(), questionId); // 해당 유저의 Question 게시물 like 여부 검색 - Boolean likeStatus = questionLikeRepository.existsByQuestionIdAndUserId(questionId, user.getId()); - Question question = questionRepository.findById(questionId).orElseThrow(QuestionNotFoundException::new); + Boolean likeStatus = questionLikeDomainService.existsByQuestionIdAndUserId(questionId, user.getId()); + Question question = questionDomainService.findById(questionId); if (likeStatus) { // like가 있다면 삭제 - questionLikeRepository.deleteByQuestionIdAndUserId(questionId, user.getId()); + questionLikeDomainService.deleteByQuestionIdAndUserId(questionId, user.getId()); } else { // like가 없다면 등록 - questionLikeRepository.save(QuestionLike.toEntity(user, question)); + questionLikeDomainService.saveQuestionLike(user, question); questionAlarmService.sendAlarmAboutQuestionLike(user.getId(), question.getId()); } } @Transactional - public void postQuestionReport(User user, Long questionId, QuestionReportReqDto dto) { + public void postQuestionReport(Long userId, Long questionId, QuestionReportReqDto dto) { + User user = userDomainService.findById(userId); log.info("질문 게시글 신고 - 사용자 : {}, 질문 게시글 : {}, 사유 : {}", user.getId(), questionId, dto.getReason()); - Boolean reportExist = questionReportRepository.existsByQuestionIdAndReporterId(questionId, user.getId()); + Boolean reportExist = questionReportDomainService.existsByQuestionIdAndReporterId(questionId, user.getId()); if (!reportExist) { // 신고 내역이 없다면 신고 등록. - Question question = questionRepository.findById(questionId).orElseThrow(QuestionNotFoundException::new); + Question question = questionDomainService.findById(questionId); - questionReportRepository.save( - QuestionReport.toEntity(user, question, dto) - ); + questionReportDomainService.saveQuestionReport(user, question, dto.getReason(), dto.getContent()); } else { // 신고 내역이 있다면 중복 신고 방지. @@ -305,8 +277,9 @@ public void postQuestionReport(User user, Long questionId, QuestionReportReqDto } @Transactional - public QuestionGetDetailResDto getQuestionDetail(User nowUser, Long questionId) { - Question question = questionRepository.findById(questionId).orElseThrow(QuestionNotFoundException::new); + public QuestionGetDetailResDto getQuestionDetail(Long nowUserId, Long questionId) { + Question question = questionDomainService.findById(questionId); + User nowUser = userDomainService.findById(nowUserId); // Question Type 분류 String qType; @@ -327,10 +300,10 @@ public QuestionGetDetailResDto getQuestionDetail(User nowUser, Long questionId) } // 작성자 - User writer = userRepository.findById(question.getUser().getId()).orElse(null); + User writer = userDomainService.findByIdOrNull(question.getUser().getId()); // Question img List - List questionImgList = questionImgRepository.findAllByQuestionId(questionId). + List questionImgList = questionImgDomainService.findAllByQuestionId(questionId). stream() .map(questionImg -> { QuestionVoteDataDto voteDataDto = null; @@ -343,22 +316,22 @@ public QuestionGetDetailResDto getQuestionDetail(User nowUser, Long questionId) } ).toList(); - List closetList; + List closets; if (nowUser != null) { - closetList = closetRepository.findAllByUserId(nowUser.getId()); + closets = closetDomainService.findAllByUserId(nowUser.getId()); } else { - closetList = new ArrayList<>(); + closets = new ArrayList<>(); } // Question Item List - List questionItemList = questionItemRepository.findAllByQuestionId(questionId) + List questionItemList = questionItemDomainService.findAllByQuestionId(questionId) .stream() .map(questionItem -> { - ItemSimpleResDto itemSimpleResDto = ItemSimpleResDto.of( + ItemSimpleDto itemSimpleDto = ItemSimpleDto.of( questionItem.getItem(), - itemImgRepository.findMainImg(questionItem.getItem().getId()), - itemScrapRepository.getItemScrapStatus(questionItem.getItem(), closetList) + itemImgDomainService.findMainImg(questionItem.getItem().getId()), + itemScrapDomainService.getItemScrapStatus(questionItem.getItem(), closets) ); QuestionVoteDataDto questionVoteDataDto = null; // QuestionBuy일 경우 투표수 추가. @@ -366,21 +339,21 @@ public QuestionGetDetailResDto getQuestionDetail(User nowUser, Long questionId) questionVoteDataDto = getVoteData(questionId, (long) questionItem.getSortOrder()); } - return QuestionItemResDto.of(questionItem, itemSimpleResDto, questionVoteDataDto); + return QuestionItemResDto.of(questionItem, itemSimpleDto, questionVoteDataDto); }).toList(); // Question Like Num Count - Long questionLikeNum = questionLikeRepository.countByQuestionId(questionId); + Long questionLikeNum = questionLikeDomainService.countByQuestionId(questionId); // Question Comment Num Count - Long questionCommentNum = commentRepository.countByQuestionId(questionId); + Long questionCommentNum = commentDomainService.countByQuestionId(questionId); // hasLike 검색 Boolean currentUserLike = - nowUser != null && questionLikeRepository.existsByQuestionIdAndUserId(questionId, nowUser.getId()); + nowUser != null && questionLikeDomainService.existsByQuestionIdAndUserId(questionId, nowUser.getId()); - CelebChipResDto celeb = null; - CelebChipResDto newCeleb = null; + CelebChipResponse celeb = null; + CelebChipResponse newCeleb = null; LocalDateTime voteEndTime = null; Long totalVoteNum = null; Long voteStatus = null; @@ -390,32 +363,31 @@ public QuestionGetDetailResDto getQuestionDetail(User nowUser, Long questionId) case "Find" -> { QuestionFind questionFind = (QuestionFind) question; if (questionFind.getCeleb() != null) { - celeb = CelebChipResDto.of(questionFind.getCeleb()); + celeb = CelebChipResponse.of(questionFind.getCeleb()); } else { - newCeleb = CelebChipResDto.of(questionFind.getNewCeleb()); + newCeleb = CelebChipResponse.of(questionFind.getNewCeleb()); } } case "Buy" -> { QuestionBuy questionBuy = (QuestionBuy) question; QuestionVote questionVote = nowUser != null ? - questionVoteRepository.findByQuestionIdAndUserId(questionId, nowUser.getId()) - .orElse(null) + questionVoteDomainService.findByQuestionIdAndUserIdOrNull(questionId, nowUser.getId()) : null; voteEndTime = questionBuy.getVoteEndTime(); - totalVoteNum = questionVoteRepository.countByQuestionId(questionId); + totalVoteNum = questionVoteDomainService.countByQuestionId(questionId); voteStatus = questionVote != null ? questionVote.getVoteSortOrder() : null; } case "Recommend" -> - recommendCategoryList = questionRecommendCategoryRepository.findAllByQuestionId(questionId) + recommendCategoryList = questionRecommendCategoryDomainService.findAllByQuestionId(questionId) .stream().map(QuestionRecommendCategory::getName).toList(); } // RecentQuestion 등록 if (nowUser != null) { - recentQuestionRepository.save(RecentQuestion.toEntity(nowUser, qType, question)); + recentQuestionDomainService.saveRecentQuestion(nowUser, qType, question); // SearchNum 증가 increaseQuestionViewNum(nowUser.getId(), question); @@ -444,7 +416,7 @@ private void increaseQuestionViewNum(Long userId, Question question) { * builder에 VoteNum, VotePercent 탑재 */ private QuestionVoteDataDto getVoteData(Long questionId, Long sortOrder) { - List questionVotes = questionVoteRepository.findAllByQuestionId(questionId); + List questionVotes = questionVoteDomainService.findAllByQuestionId(questionId); // 해당 SortOrder의 투표 수 Long voteNum = 0L; @@ -474,28 +446,25 @@ private Double getVotePercent(Long voteNum, Long totalVoteNum) { * QuestionBuy 등록 및 취소 */ @Transactional - public void postQuestionVote(User user, Long questionId, QuestionVoteReqDto dto) { + public void postQuestionVote(Long userId, Long questionId, QuestionVoteReqDto dto) { + User user = userDomainService.findById(userId); log.info("질문 게시글 투표 - 사용자 : {}, 질문 게시글 : {}, 투표 : {}", user.getId(), questionId, dto.getVoteSortOrder()); - QuestionVote questionVote = questionVoteRepository.findByQuestionIdAndUserId(questionId, user.getId()) - .orElse(null); + QuestionVote questionVote = questionVoteDomainService.findByQuestionIdAndUserIdOrNull(questionId, user.getId()); if (questionVote == null) { // 투표 등록 // Question 검색 - Question question = questionRepository.findById(questionId) - .orElseThrow(QuestionNotFoundException::new); + Question question = questionDomainService.findById(questionId); // QuestionVote 생성 및 저장 - questionVoteRepository.save( - QuestionVote.toEntity(question, user, dto) - ); + questionVoteDomainService.saveQuestionVote(question, user, dto.getVoteSortOrder()); } else { // 투표 취소 // 해당 QuestionVote 삭제. - questionVoteRepository.deleteById(questionVote.getId()); + questionVoteDomainService.deleteById(questionVote.getId()); } } @@ -504,14 +473,14 @@ public void postQuestionVote(User user, Long questionId, QuestionVoteReqDto dto) * TODO 게시글과 같은 셀럽/같은 그룹 로직 추가해야함 (23.06.22) */ @Transactional(readOnly = true) - public List getWaitQuestionBuy(User user, Long questionId) { - - List interestedCeleb = new ArrayList<>(); + public List getWaitQuestionBuy(Long userId, Long questionId) { + User user = userDomainService.findById(userId); + List interestedCelebs = new ArrayList<>(); if (user != null) { - interestedCeleb = celebRepository.findInterestedCeleb(user); + interestedCelebs = celebDomainService.findInterestedCeleb(user); } - return questionRepository.getWaitQuestionBuy(user, questionId, interestedCeleb) + return questionDomainService.getWaitQuestionBuy(user, questionId, interestedCelebs) .stream() .map(questionBuy -> getQuestionSimpleResDto(questionBuy, "Buy")) .toList(); @@ -521,8 +490,9 @@ public List getWaitQuestionBuy(User user, Long questionId) * Wait QuestionRecommend 조회 */ @Transactional(readOnly = true) - public List getWaitQuestionRecommend(User user, Long questionId) { - return questionRepository.getWaitQuestionRecommend(user, questionId) + public List getWaitQuestionRecommend(Long userId, Long questionId) { + User user = userDomainService.findById(userId); + return questionDomainService.getWaitQuestionRecommend(user, questionId) .stream() .map(questionRecommend -> getQuestionSimpleResDto(questionRecommend, "Recommend")) .toList(); @@ -532,8 +502,9 @@ public List getWaitQuestionRecommend(User user, Long quest * Wait QuestionHowabout 조회 */ @Transactional(readOnly = true) - public List getWaitQuestionHowabout(User user, Long questionId) { - return questionRepository.getWaitQuestionHowabout(user, questionId) + public List getWaitQuestionHowabout(Long userId, Long questionId) { + User user = userDomainService.findById(userId); + return questionDomainService.getWaitQuestionHowabout(user, questionId) .stream() .map(questionHowabout -> getQuestionSimpleResDto(questionHowabout, "How")) .toList(); @@ -543,74 +514,74 @@ public List getWaitQuestionHowabout(User user, Long questi * Wait QuestionFind 조회 */ @Transactional(readOnly = true) - public List getWaitQuestionFind(User user, Long questionId) { - List interestedCeleb = new ArrayList<>(); + public List getWaitQuestionFind(Long userId, Long questionId) { + User user = userDomainService.findById(userId); + List interestedCelebs = new ArrayList<>(); if (user != null) { - interestedCeleb = celebRepository.findInterestedCeleb(user); + interestedCelebs = celebDomainService.findInterestedCeleb(user); } - return questionRepository.getWaitQuestionFind(user, questionId, interestedCeleb) + return questionDomainService.getWaitQuestionFind(user, questionId, interestedCelebs) .stream() .map(questionFind -> getQuestionSimpleResDto(questionFind, "Find")) .toList(); } public QuestionSimpleResDto getQuestionSimpleResDto(Question question, String qType) { - log.warn("아악2"); - - List imgList = new ArrayList<>(); - List itemImgList = new ArrayList<>(); + List imgList = new ArrayList<>(); + List itemImgList = new ArrayList<>(); String celebName = null; List categoryNameList = null; // if (!qType.equals("Buy")) { if (!(question instanceof QuestionBuy)) { // 이미지 URL - QuestionImg questionImg = questionImgRepository.findByQuestionIdAndRepresentFlag(question.getId(), true); + QuestionImg questionImg = questionImgDomainService.findByQuestionIdAndRepresentFlag(question.getId(), true); // 이미지 Dto로 변경 if (questionImg != null) { - imgList.add(QuestionImgSimpleResDto.of(questionImg)); + imgList.add(QuestionImgSimpleDto.of(questionImg)); } // 아이템 이미지 URL - QuestionItem questionItem = questionItemRepository.findByQuestionIdAndRepresentFlag(question.getId(), true); + QuestionItem questionItem = questionItemDomainService.findByQuestionIdAndRepresentFlag(question.getId(), + true); // 아이템 이미지 Dto로 변경 if (questionItem != null) { - ItemImg mainImg = itemImgRepository.findMainImg(questionItem.getItem().getId()); - imgList.add(QuestionImgSimpleResDto.of(mainImg)); + ItemImg mainImg = itemImgDomainService.findMainImg(questionItem.getItem().getId()); + imgList.add(QuestionImgSimpleDto.of(mainImg)); } } else { // 이미지 URL - imgList = questionImgRepository.findAllByQuestionId(question.getId()) + imgList = questionImgDomainService.findAllByQuestionId(question.getId()) .stream() - .map(QuestionImgSimpleResDto::of).toList(); + .map(QuestionImgSimpleDto::of).toList(); // 아이템 이미지 URL - itemImgList = questionItemRepository.findAllByQuestionId(question.getId()) + itemImgList = questionItemDomainService.findAllByQuestionId(question.getId()) .stream() .map(item -> { - ItemImg mainImg = itemImgRepository.findMainImg(item.getItem().getId()); - return QuestionImgSimpleResDto.of(mainImg); + ItemImg mainImg = itemImgDomainService.findMainImg(item.getItem().getId()); + return QuestionImgSimpleDto.of(mainImg); }).toList(); } // if (qType.equals("Recommend")) { if (question instanceof QuestionRecommend) { - categoryNameList = questionRecommendCategoryRepository.findAllByQuestionId(question.getId()).stream() + categoryNameList = questionRecommendCategoryDomainService.findAllByQuestionId(question.getId()).stream() .map(QuestionRecommendCategory::getName).toList(); } // Question 좋아요 수 - Long likeNum = questionLikeRepository.countByQuestionId(question.getId()); + Long likeNum = questionLikeDomainService.countByQuestionId(question.getId()); // Question 댓글 수 - Long commentNum = commentRepository.countByQuestionId(question.getId()); + Long commentNum = commentDomainService.countByQuestionId(question.getId()); - User writer = userRepository.findById(question.getUser().getId()).orElse(null); + User writer = userDomainService.findByIdOrNull(question.getUser().getId()); return QuestionSimpleResDto.of(question, writer, likeNum, commentNum, imgList, itemImgList, categoryNameList); @@ -620,8 +591,8 @@ public QuestionSimpleResDto getQuestionSimpleResDto(Question question, String qT * Question 리스트를 최신순으로 조회 */ @Transactional(readOnly = true) - public PaginationResDto getTotalQuestionList(Pageable pageable) { - Page questionPage = questionRepository.getTotalQuestionList(pageable); + public PaginationResponse getTotalQuestionList(Pageable pageable) { + Page questionPage = questionDomainService.getTotalQuestionList(pageable); List content = questionPage.stream().map(question -> { String qType; if (question instanceof QuestionBuy) { @@ -638,17 +609,18 @@ public PaginationResDto getTotalQuestionList(Pageable page return getQuestionSimpleResDto(question, qType); }).toList(); - return PaginationResDto.of(questionPage, content); + return PaginationResponse.create(questionPage, content); } @Transactional(readOnly = true) - public PaginationResDto getQuestionBuyList(User user, String voteStatus, - Pageable pageable) { - Page questionPage = questionRepository.getQuestionBuyList(voteStatus, pageable); + public PaginationResponse getQuestionBuyList(Long userId, String voteStatus, + Pageable pageable) { + User user = userDomainService.findById(userId); + Page questionPage = questionDomainService.getQuestionBuyList(voteStatus, pageable); List content = questionPage.stream().map(question -> { - List imgList = questionImgRepository.findAllByQuestionId(question.getId()) + List imgList = questionImgDomainService.findAllByQuestionId(question.getId()) .stream() .map(questionImg -> { QuestionVoteDataDto voteDataDto = getVoteData(questionImg.getQuestion().getId(), @@ -658,33 +630,32 @@ public PaginationResDto getQuestionBuyList(User user, S }).toList(); // 아이템 이미지 URL - List itemImgList = questionItemRepository.findAllByQuestionId(question.getId()) + List itemImgList = questionItemDomainService.findAllByQuestionId(question.getId()) .stream() .map(questionItem -> { - ItemSimpleResDto itemSimpleResDto = ItemSimpleResDto.of( + ItemSimpleDto itemSimpleDto = ItemSimpleDto.of( questionItem.getItem(), - itemImgRepository.findMainImg(questionItem.getItem().getId()), + itemImgDomainService.findMainImg(questionItem.getItem().getId()), null ); QuestionVoteDataDto questionVoteDataDto = getVoteData(questionItem.getQuestion().getId(), (long) questionItem.getSortOrder()); - return QuestionItemResDto.of(questionItem, itemSimpleResDto, questionVoteDataDto); + return QuestionItemResDto.of(questionItem, itemSimpleDto, questionVoteDataDto); }).toList(); Long voteCount = getTotalVoteCount(imgList, itemImgList); - QuestionVote questionVote = questionVoteRepository.findByQuestionIdAndUserId(question.getId(), user.getId()) - .orElse(null); + QuestionVote questionVote = questionVoteDomainService.findByQuestionIdAndUserIdOrNull(question.getId(), + user.getId()); - User writer = userRepository.findById(question.getUser().getId()) - .orElse(null); + User writer = userDomainService.findByIdOrNull(question.getUser().getId()); return QuestionBuySimpleResDto.of(user, question, writer, voteCount, imgList, itemImgList, question.getVoteEndTime(), questionVote); }).toList(); - return PaginationResDto.of(questionPage, content); + return PaginationResponse.create(questionPage, content); } private Long getTotalVoteCount(List imgList, List itemImgList) { @@ -705,35 +676,35 @@ private Long getTotalVoteCount(List imgList, List getQuestionFindList(Long celebId, Pageable pageable) { + public PaginationResponse getQuestionFindList(Long celebId, Pageable pageable) { - Page questionPage = questionRepository.getQuestionFindList(celebId, pageable); + Page questionPage = questionDomainService.getQuestionFindList(celebId, pageable); List content = questionPage.stream().map(question -> getQuestionSimpleResDto(question, "Find") ).toList(); - return PaginationResDto.of(questionPage, content); + return PaginationResponse.create(questionPage, content); } @Transactional(readOnly = true) - public PaginationResDto getQuestionHowaboutList(Pageable pageable) { - Page questionPage = questionRepository.getQuestionHowaboutList(pageable); + public PaginationResponse getQuestionHowaboutList(Pageable pageable) { + Page questionPage = questionDomainService.getQuestionHowaboutList(pageable); List content = questionPage.stream().map(question -> getQuestionSimpleResDto(question, "How") ).toList(); - return PaginationResDto.of(questionPage, content); + return PaginationResponse.create(questionPage, content); } @Transactional(readOnly = true) - public PaginationResDto getQuestionRecommendList(String hashtag, Pageable pageable) { - Page questionPage = questionRepository.getQuestionRecommendList(hashtag, pageable); + public PaginationResponse getQuestionRecommendList(String hashtag, Pageable pageable) { + Page questionPage = questionDomainService.getQuestionRecommendList(hashtag, pageable); List content = questionPage.stream().map(question -> getQuestionSimpleResDto(question, "Recommend") ).toList(); - return PaginationResDto.of(questionPage, content); + return PaginationResponse.create(questionPage, content); } private String getQuestionCelebName(QuestionFind questionFind) { @@ -749,11 +720,11 @@ private String getQuestionCelebName(QuestionFind questionFind) { */ @Transactional(readOnly = true) public List getDailyHotQuestionList() { - List dailyHoyQuestionList = questionRepository.getDailyHotQuestion(); + List dailyHoyQuestionList = questionDomainService.getDailyHotQuestion(); List result = dailyHoyQuestionList.stream().map(question -> { - List questionImgSimpleList = getQuestionImgSimpleList(question); - User writer = userRepository.findById(question.getUser().getId()).orElse(null); + List questionImgSimpleList = getQuestionImgSimpleList(question); + User writer = userDomainService.findByIdOrNull(question.getUser().getId()); return QuestionHomeResDto.of(question, writer, questionImgSimpleList); }).toList(); @@ -762,37 +733,38 @@ public List getDailyHotQuestionList() { } - private List getQuestionImgSimpleList(Question question) { + private List getQuestionImgSimpleList(Question question) { // Question이 QuestionBuy인 경우 모든 이미지를 순서대로 조회 if (question instanceof QuestionBuy) { - List result = new ArrayList<>(); + List result = new ArrayList<>(); - List questionImgList = questionImgRepository.findAllByQuestionId(question.getId()); - List questionItemImgList = questionItemRepository.findAllByQuestionId(question.getId()).stream() - .map(questionItem -> itemImgRepository.findMainImg(questionItem.getItem().getId())).toList(); + List questionImgList = questionImgDomainService.findAllByQuestionId(question.getId()); + List questionItemImgList = questionItemDomainService.findAllByQuestionId(question.getId()).stream() + .map(questionItem -> itemImgDomainService.findMainImg(questionItem.getItem().getId())).toList(); - questionImgList.forEach(questionImg -> result.add(QuestionImgSimpleResDto.of(questionImg))); - questionItemImgList.forEach(itemImg -> result.add(QuestionImgSimpleResDto.of(itemImg))); + questionImgList.forEach(questionImg -> result.add(QuestionImgSimpleDto.of(questionImg))); + questionItemImgList.forEach(itemImg -> result.add(QuestionImgSimpleDto.of(itemImg))); - result.sort(Comparator.comparing(QuestionImgSimpleResDto::getSortOrder)); + result.sort(Comparator.comparing(QuestionImgSimpleDto::getSortOrder)); return result; } else {// 그 외에는 대표이미지만 조화 - QuestionImg questionImg = questionImgRepository.findByQuestionIdAndRepresentFlag(question.getId(), true); - QuestionItem questionItem = questionItemRepository.findByQuestionIdAndRepresentFlag(question.getId(), true); + QuestionImg questionImg = questionImgDomainService.findByQuestionIdAndRepresentFlag(question.getId(), true); + QuestionItem questionItem = questionItemDomainService.findByQuestionIdAndRepresentFlag(question.getId(), + true); String imgUrl = null; if (questionImg != null) { imgUrl = questionImg.getImgUrl(); } else if (questionItem != null) { - imgUrl = itemImgRepository.findMainImg(questionItem.getItem().getId()).getItemImgUrl(); + imgUrl = itemImgDomainService.findMainImg(questionItem.getItem().getId()).getItemImgUrl(); } return imgUrl != null - ? Arrays.asList(new QuestionImgSimpleResDto(imgUrl, 0L)) + ? Arrays.asList(new QuestionImgSimpleDto(imgUrl, 0L)) : null; } } @@ -801,37 +773,37 @@ private List getQuestionImgSimpleList(Question question * 주간 Hot Question 조회 기능. */ @Transactional(readOnly = true) - public PaginationResDto getWeeklyHotQuestionList(Pageable pageable) { - Page page = questionRepository.getWeeklyHotQuestion(pageable); + public PaginationResponse getWeeklyHotQuestionList(Pageable pageable) { + Page page = questionDomainService.getWeeklyHotQuestion(pageable); List content = page.stream().map(question -> { List categoryList = null; if (question instanceof QuestionRecommend) { - categoryList = questionRecommendCategoryRepository.findAllByQuestionId(question.getId()) + categoryList = questionRecommendCategoryDomainService.findAllByQuestionId(question.getId()) .stream() .map(QuestionRecommendCategory::getName).toList(); } - List imgList = questionImgRepository.findAllByQuestionId(question.getId()) + List imgList = questionImgDomainService.findAllByQuestionId(question.getId()) .stream() - .map(QuestionImgSimpleResDto::of) + .map(QuestionImgSimpleDto::of) .toList(); - List itemImgList = questionItemRepository.findAllByQuestionId(question.getId()) + List itemImgList = questionItemDomainService.findAllByQuestionId(question.getId()) .stream() .map(questionItem -> - QuestionImgSimpleResDto.of(itemImgRepository.findMainImg(questionItem.getItem().getId())) + QuestionImgSimpleDto.of(itemImgDomainService.findMainImg(questionItem.getItem().getId())) ) .toList(); - Long commentNum = commentRepository.countByQuestionId(question.getId()); - Long likeNum = questionLikeRepository.countByQuestionId(question.getId()); - User writer = userRepository.findById(question.getUser().getId()).orElse(null); + Long commentNum = commentDomainService.countByQuestionId(question.getId()); + Long likeNum = questionLikeDomainService.countByQuestionId(question.getId()); + User writer = userDomainService.findByIdOrNull(question.getUser().getId()); return QuestionSimpleResDto.of(question, writer, likeNum, commentNum, imgList, itemImgList, categoryList); }).toList(); - return PaginationResDto.of(page, content); + return PaginationResponse.create(page, content); } } diff --git a/sluv-api/src/main/java/com/sluv/api/question/service/QuestionWithdrawService.java b/sluv-api/src/main/java/com/sluv/api/question/service/QuestionWithdrawService.java new file mode 100644 index 00000000..41b88d19 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/question/service/QuestionWithdrawService.java @@ -0,0 +1,16 @@ +package com.sluv.api.question.service; + +import com.sluv.domain.question.service.RecentQuestionDomainService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class QuestionWithdrawService { + private final RecentQuestionDomainService recentQuestionDomainService; + + public void withdrawQuestionByUserId(Long userId) { + recentQuestionDomainService.deleteAllByUserId(userId); + } + +} diff --git a/src/main/java/com/sluv/server/domain/search/controller/SearchController.java b/sluv-api/src/main/java/com/sluv/api/search/controller/SearchController.java similarity index 56% rename from src/main/java/com/sluv/server/domain/search/controller/SearchController.java rename to sluv-api/src/main/java/com/sluv/api/search/controller/SearchController.java index fbacebde..7cda34c2 100644 --- a/src/main/java/com/sluv/server/domain/search/controller/SearchController.java +++ b/sluv-api/src/main/java/com/sluv/api/search/controller/SearchController.java @@ -1,21 +1,21 @@ -package com.sluv.server.domain.search.controller; - -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.search.dto.RecentSearchChipResDto; -import com.sluv.server.domain.search.dto.SearchFilterReqDto; -import com.sluv.server.domain.search.dto.SearchItemCountResDto; -import com.sluv.server.domain.search.dto.SearchKeywordResDto; -import com.sluv.server.domain.search.dto.SearchKeywordTotalResDto; -import com.sluv.server.domain.search.dto.SearchTotalResDto; -import com.sluv.server.domain.search.service.SearchEngineService; -import com.sluv.server.domain.search.service.SearchEngineTotalService; -import com.sluv.server.domain.search.service.SearchService; -import com.sluv.server.domain.user.dto.UserSearchInfoDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; +package com.sluv.api.search.controller; + +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.api.search.dto.RecentSearchChipResDto; +import com.sluv.api.search.dto.SearchItemCountResDto; +import com.sluv.api.search.dto.SearchKeywordResDto; +import com.sluv.api.search.dto.SearchKeywordTotalResDto; +import com.sluv.api.search.dto.SearchTotalResDto; +import com.sluv.api.search.service.SearchEngineService; +import com.sluv.api.search.service.SearchEngineTotalService; +import com.sluv.api.search.service.SearchService; +import com.sluv.common.annotation.CurrentUserId; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import com.sluv.domain.search.dto.SearchFilterReqDto; +import com.sluv.domain.user.dto.UserSearchInfoDto; import io.swagger.v3.oas.annotations.Operation; import java.util.List; import java.util.concurrent.ExecutionException; @@ -23,7 +23,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.lang.Nullable; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -48,16 +47,16 @@ public class SearchController { """ ) @GetMapping("/item") - public ResponseEntity>> searchItem( - @AuthenticationPrincipal User user, + public ResponseEntity>> searchItem( + @CurrentUserId Long userId, @RequestParam("keyword") String keyword, SearchFilterReqDto dto, Pageable pageable) throws ExecutionException, InterruptedException { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(searchEngineService.getSearchItem(user, keyword, dto, pageable).get()) - .build() - ); + + PaginationResponse response = searchEngineService.getSearchItem(userId, + keyword, dto, pageable).get(); + + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation( @@ -72,16 +71,16 @@ public ResponseEntity>> s """ ) @GetMapping("/question") - public ResponseEntity>> searchQuestion( - @AuthenticationPrincipal User user, + public ResponseEntity>> searchQuestion( + @CurrentUserId Long userId, @RequestParam("keyword") String keyword, @Nullable @RequestParam("qtype") String qType, Pageable pageable) throws ExecutionException, InterruptedException { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(searchEngineService.getSearchQuestion(user, keyword, qType, pageable).get()) - .build() - ); + + PaginationResponse response = searchEngineService.getSearchQuestion( + userId, keyword, qType, pageable).get(); + + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation( @@ -94,15 +93,13 @@ public ResponseEntity """ ) @GetMapping("/user") - public ResponseEntity>> searchUser( - @AuthenticationPrincipal User user, + public ResponseEntity>> searchUser( + @CurrentUserId Long userId, @RequestParam("keyword") String keyword, Pageable pageable) throws ExecutionException, InterruptedException { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(searchEngineService.getSearchUser(user, keyword, pageable).get()) - .build() - ); + PaginationResponse response = searchEngineService.getSearchUser( + userId, keyword, pageable).get(); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation( @@ -115,14 +112,11 @@ public ResponseEntity>> """ ) @GetMapping("/total") - public ResponseEntity> searchTotal(@AuthenticationPrincipal User user, + public ResponseEntity> searchTotal(@CurrentUserId Long userId, @RequestParam("keyword") String keyword) throws ExecutionException, InterruptedException { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(searchEngineTotalService.getSearchTotal(user, keyword)) - .build() - ); + SearchTotalResDto response = searchEngineTotalService.getSearchTotal(userId, keyword); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation( @@ -135,11 +129,8 @@ public ResponseEntity> searchTotal(@Authe @GetMapping("/item/count") public ResponseEntity> searchItemCount( @RequestParam("keyword") String keyword, SearchFilterReqDto dto) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(searchEngineService.getSearchItemCount(keyword, dto)) - .build() - ); + SearchItemCountResDto response = searchEngineService.getSearchItemCount(keyword, dto); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation( @@ -151,12 +142,9 @@ public ResponseEntity> searchItemCoun ) @GetMapping("/recentSearch") public ResponseEntity>> getRecentSearch( - @AuthenticationPrincipal User user) { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(searchService.getRecentSearch(user)) - .build() - ); + @CurrentUserId Long userId) { + List response = searchService.getRecentSearch(userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation( @@ -169,11 +157,8 @@ public ResponseEntity>> getRece ) @GetMapping("/searchRank") public ResponseEntity>> getRecentSearch() { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(searchService.getSearchRank()) - .build() - ); + List response = searchService.getSearchRank(); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation( @@ -184,14 +169,11 @@ public ResponseEntity>> getRecentS """ ) @GetMapping("/keyword") - public ResponseEntity>> getSearchKeyword( + public ResponseEntity>> getSearchKeyword( @RequestParam("keyword") String keyword, Pageable pageable) { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(searchService.getSearchKeyword(keyword, pageable)) - .build() - ); + PaginationResponse response = searchService.getSearchKeyword(keyword, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } @Operation( @@ -202,12 +184,10 @@ public ResponseEntity> """ ) @DeleteMapping("/recentSearch") - public ResponseEntity deleteRecentSearch(@AuthenticationPrincipal User user, + public ResponseEntity deleteRecentSearch(@CurrentUserId Long userId, @RequestParam String keyword) { - searchService.deleteSearchKeyword(user, keyword); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + searchService.deleteSearchKeyword(userId, keyword); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation( @@ -218,22 +198,17 @@ public ResponseEntity deleteRecentSearch(@AuthenticationPrincip """ ) @DeleteMapping("/recentSearch/all") - public ResponseEntity deleteAllRecentSearch(@AuthenticationPrincipal User user) { - searchService.deleteAllSearchKeyword(user); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + public ResponseEntity deleteAllRecentSearch(@CurrentUserId Long userId) { + searchService.deleteAllSearchKeyword(userId); + return ResponseEntity.ok().body(SuccessResponse.create()); } @Operation(summary = "*검색어 기준 브랜드, 셀럽, 아이템 검색 ", description = "각 5개씩") @GetMapping("/allData") public ResponseEntity> getAllDateByKeyword( - @AuthenticationPrincipal User user, + @CurrentUserId Long userId, @RequestParam("keyword") String keyword) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(searchService.getAllDateByKeyword(user, keyword)) - .build() - ); + SearchKeywordTotalResDto response = searchService.getAllDateByKeyword(userId, keyword); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); } } diff --git a/src/main/java/com/sluv/server/domain/search/dto/RecentSearchChipResDto.java b/sluv-api/src/main/java/com/sluv/api/search/dto/RecentSearchChipResDto.java similarity index 92% rename from src/main/java/com/sluv/server/domain/search/dto/RecentSearchChipResDto.java rename to sluv-api/src/main/java/com/sluv/api/search/dto/RecentSearchChipResDto.java index f435e419..e3c8c4f1 100644 --- a/src/main/java/com/sluv/server/domain/search/dto/RecentSearchChipResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/search/dto/RecentSearchChipResDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.search.dto; +package com.sluv.api.search.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/search/dto/SearchItemCountResDto.java b/sluv-api/src/main/java/com/sluv/api/search/dto/SearchItemCountResDto.java similarity index 92% rename from src/main/java/com/sluv/server/domain/search/dto/SearchItemCountResDto.java rename to sluv-api/src/main/java/com/sluv/api/search/dto/SearchItemCountResDto.java index a79294bd..f331703d 100644 --- a/src/main/java/com/sluv/server/domain/search/dto/SearchItemCountResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/search/dto/SearchItemCountResDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.search.dto; +package com.sluv.api.search.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/search/dto/SearchKeywordResDto.java b/sluv-api/src/main/java/com/sluv/api/search/dto/SearchKeywordResDto.java similarity index 91% rename from src/main/java/com/sluv/server/domain/search/dto/SearchKeywordResDto.java rename to sluv-api/src/main/java/com/sluv/api/search/dto/SearchKeywordResDto.java index 1827350b..aebdd37b 100644 --- a/src/main/java/com/sluv/server/domain/search/dto/SearchKeywordResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/search/dto/SearchKeywordResDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.search.dto; +package com.sluv.api.search.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/search/dto/SearchKeywordTotalResDto.java b/sluv-api/src/main/java/com/sluv/api/search/dto/SearchKeywordTotalResDto.java similarity index 72% rename from src/main/java/com/sluv/server/domain/search/dto/SearchKeywordTotalResDto.java rename to sluv-api/src/main/java/com/sluv/api/search/dto/SearchKeywordTotalResDto.java index 1acb9c06..4388e71e 100644 --- a/src/main/java/com/sluv/server/domain/search/dto/SearchKeywordTotalResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/search/dto/SearchKeywordTotalResDto.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.search.dto; +package com.sluv.api.search.dto; -import com.sluv.server.domain.brand.dto.BrandSearchResDto; -import com.sluv.server.domain.celeb.dto.CelebSearchResDto; -import com.sluv.server.domain.item.dto.ItemKeywordSearchResDto; +import com.sluv.api.brand.dto.response.BrandSearchResponse; +import com.sluv.api.celeb.dto.response.CelebSearchResponse; +import com.sluv.api.item.dto.ItemKeywordSearchResDto; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import lombok.AllArgsConstructor; @@ -16,14 +16,14 @@ @Builder public class SearchKeywordTotalResDto { @Schema(description = "조회된 Celeb 리스트") - List celebList; + List celebList; @Schema(description = "조회된 Brand 리스트") - List brandList; + List brandList; @Schema(description = "조회된 Item 리스트") List itemList; - public static SearchKeywordTotalResDto of(List celebList, - List brandList, + public static SearchKeywordTotalResDto of(List celebList, + List brandList, List itemList) { return SearchKeywordTotalResDto.builder() .celebList(celebList) diff --git a/src/main/java/com/sluv/server/domain/search/dto/SearchTotalResDto.java b/sluv-api/src/main/java/com/sluv/api/search/dto/SearchTotalResDto.java similarity index 72% rename from src/main/java/com/sluv/server/domain/search/dto/SearchTotalResDto.java rename to sluv-api/src/main/java/com/sluv/api/search/dto/SearchTotalResDto.java index 78e8efba..5e21335f 100644 --- a/src/main/java/com/sluv/server/domain/search/dto/SearchTotalResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/search/dto/SearchTotalResDto.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.search.dto; +package com.sluv.api.search.dto; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.user.dto.UserSearchInfoDto; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import com.sluv.domain.user.dto.UserSearchInfoDto; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import lombok.AllArgsConstructor; @@ -16,13 +16,13 @@ @Builder public class SearchTotalResDto { @Schema(description = "조회된 item 리스트") - List itemList; + List itemList; @Schema(description = "조회된 Question 리스트") List questionList; @Schema(description = "조회된 User 리스트") List userList; - public static SearchTotalResDto of(List itemList, + public static SearchTotalResDto of(List itemList, List questionList, List userList) { return SearchTotalResDto.builder() diff --git a/src/main/java/com/sluv/server/domain/search/engine/DBSearchEngine.java b/sluv-api/src/main/java/com/sluv/api/search/engine/DBSearchEngine.java similarity index 84% rename from src/main/java/com/sluv/server/domain/search/engine/DBSearchEngine.java rename to sluv-api/src/main/java/com/sluv/api/search/engine/DBSearchEngine.java index 98d920d1..4ca184d6 100644 --- a/src/main/java/com/sluv/server/domain/search/engine/DBSearchEngine.java +++ b/sluv-api/src/main/java/com/sluv/api/search/engine/DBSearchEngine.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.search.engine; +package com.sluv.api.search.engine; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.repository.QuestionRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.repository.UserRepository; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.repository.ItemRepository; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.repository.QuestionRepository; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.repository.UserRepository; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; diff --git a/src/main/java/com/sluv/server/domain/search/engine/ELKSearchEngine.java b/sluv-api/src/main/java/com/sluv/api/search/engine/ELKSearchEngine.java similarity index 100% rename from src/main/java/com/sluv/server/domain/search/engine/ELKSearchEngine.java rename to sluv-api/src/main/java/com/sluv/api/search/engine/ELKSearchEngine.java diff --git a/src/main/java/com/sluv/server/domain/search/engine/SearchEngine.java b/sluv-api/src/main/java/com/sluv/api/search/engine/SearchEngine.java similarity index 85% rename from src/main/java/com/sluv/server/domain/search/engine/SearchEngine.java rename to sluv-api/src/main/java/com/sluv/api/search/engine/SearchEngine.java index a8830107..f77ff05e 100644 --- a/src/main/java/com/sluv/server/domain/search/engine/SearchEngine.java +++ b/sluv-api/src/main/java/com/sluv/api/search/engine/SearchEngine.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.search.engine; +package com.sluv.api.search.engine; import java.util.List; import org.springframework.stereotype.Service; diff --git a/sluv-api/src/main/java/com/sluv/api/search/service/SearchEngineService.java b/sluv-api/src/main/java/com/sluv/api/search/service/SearchEngineService.java new file mode 100644 index 00000000..0485a155 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/search/service/SearchEngineService.java @@ -0,0 +1,132 @@ +package com.sluv.api.search.service; + +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.question.service.QuestionService; +import com.sluv.api.search.dto.SearchItemCountResDto; +import com.sluv.api.search.engine.SearchEngine; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.service.ItemDomainService; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.exception.QuestionTypeNotFoundException; +import com.sluv.domain.question.service.QuestionDomainService; +import com.sluv.domain.search.dto.SearchFilterReqDto; +import com.sluv.domain.user.dto.UserSearchInfoDto; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.FollowDomainService; +import com.sluv.domain.user.service.UserDomainService; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class SearchEngineService { + + private final SearchEngine searchEngine; + + private final SearchService searchService; + private final QuestionService questionService; + + private final ItemDomainService itemDomainService; + private final UserDomainService userDomainService; + private final FollowDomainService followDomainService; + private final QuestionDomainService questionDomainService; + + @Transactional + @Async(value = "asyncThreadPoolExecutor") + public CompletableFuture> getSearchItem(Long userId, String keyword, + SearchFilterReqDto dto, + Pageable pageable) { + + User user = userDomainService.findById(userId); + + List searchItemIds = searchEngine.getSearchItemIds(keyword); + Page searchItemPage = itemDomainService.getSearchItem(searchItemIds, dto, pageable); + List content = itemDomainService.getItemSimpleDto(user, searchItemPage.getContent()); + + // 최근 검색 등록 + searchService.postRecentSearch(userId, keyword); + // 서치 데이터 등록 + searchService.postSearchData(keyword); + + return CompletableFuture.completedFuture(PaginationResponse.create(searchItemPage, content)); + } + + @Transactional + @Async(value = "asyncThreadPoolExecutor") + public CompletableFuture> getSearchQuestion(Long userId, String keyword, + String qType, + Pageable pageable) { + User user = userDomainService.findById(userId); + + List searchQuestionIds = searchEngine.getSearchQuestionIds(keyword); + Page searchQuestionPage; + // 조건에 맞는 Item Page 조회 + if (qType == null) { + searchQuestionPage = + questionDomainService.getSearchQuestion(searchQuestionIds, pageable); + } else if (qType.equals("Buy")) { + searchQuestionPage = + questionDomainService.getSearchQuestionBuy(searchQuestionIds, pageable); + } else if (qType.equals("Find")) { + searchQuestionPage = + questionDomainService.getSearchQuestionFind(searchQuestionIds, pageable); + } else if (qType.equals("How")) { + searchQuestionPage = + questionDomainService.getSearchQuestionHowabout(searchQuestionIds, pageable); + } else if (qType.equals("Recommend")) { + searchQuestionPage = + questionDomainService.getSearchQuestionRecommend(searchQuestionIds, pageable); + } else { + throw new QuestionTypeNotFoundException(); + } + + List content = searchQuestionPage.stream() + .map(question -> + questionService.getQuestionSimpleResDto((Question) question, qType) + ).toList(); + + // 최근 검색 등록 + searchService.postRecentSearch(userId, keyword); + + // 서치 데이터 등록 + searchService.postSearchData(keyword); + + return CompletableFuture.completedFuture(PaginationResponse.create(searchQuestionPage, content)); + + } + + @Async(value = "asyncThreadPoolExecutor") + public CompletableFuture> getSearchUser(Long userId, String keyword, + Pageable pageable) { + User user = userDomainService.findById(userId); + + List searchUserIds = searchEngine.getSearchUserIds(keyword); + Page searchUserPage = userDomainService.getSearchUser(searchUserIds, pageable); + List content = searchUserPage.stream().map(searchUser -> + UserSearchInfoDto.of(searchUser, followDomainService.getFollowStatus(user, searchUser.getId()), + Objects.equals(searchUser.getId(), user.getId())) + ).toList(); + + // 최근 검색 등록 + searchService.postRecentSearch(userId, keyword); + // 서치 데이터 등록 + searchService.postSearchData(keyword); + + return CompletableFuture.completedFuture(PaginationResponse.create(searchUserPage, content)); + } + + @Transactional + public SearchItemCountResDto getSearchItemCount(String keyword, SearchFilterReqDto dto) { + List itemIds = searchEngine.getSearchItemIds(keyword); + return SearchItemCountResDto.of(itemDomainService.getSearchItemCount(itemIds, dto)); + } +} diff --git a/src/main/java/com/sluv/server/domain/search/service/SearchEngineTotalService.java b/sluv-api/src/main/java/com/sluv/api/search/service/SearchEngineTotalService.java similarity index 64% rename from src/main/java/com/sluv/server/domain/search/service/SearchEngineTotalService.java rename to sluv-api/src/main/java/com/sluv/api/search/service/SearchEngineTotalService.java index e14147bb..a21eb0b2 100644 --- a/src/main/java/com/sluv/server/domain/search/service/SearchEngineTotalService.java +++ b/sluv-api/src/main/java/com/sluv/api/search/service/SearchEngineTotalService.java @@ -1,12 +1,11 @@ -package com.sluv.server.domain.search.service; - -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.search.dto.SearchFilterReqDto; -import com.sluv.server.domain.search.dto.SearchTotalResDto; -import com.sluv.server.domain.user.dto.UserSearchInfoDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationResDto; +package com.sluv.api.search.service; + +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.search.dto.SearchTotalResDto; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import com.sluv.domain.search.dto.SearchFilterReqDto; +import com.sluv.domain.user.dto.UserSearchInfoDto; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -27,7 +26,8 @@ public class SearchEngineTotalService { /** * 토탈 검색 with ElasticSearch */ - public SearchTotalResDto getSearchTotal(User user, String keyword) throws ExecutionException, InterruptedException { + public SearchTotalResDto getSearchTotal(Long userId, String keyword) + throws ExecutionException, InterruptedException { final int itemSize = 9; final int questionSize = 4; final int userSize = 10; @@ -38,26 +38,26 @@ public SearchTotalResDto getSearchTotal(User user, String keyword) throws Execut // Question 검색 -> 찾아주세요 -> 이거 어때 -> 이 중에 뭐 살까 -> 추천해 줘 순서 Pageable questionPageable = PageRequest.of(0, questionSize); - CompletableFuture> searchItem = searchEngineService.getSearchItem(user, + CompletableFuture> searchItem = searchEngineService.getSearchItem(userId, keyword, dto, itemPageable); - CompletableFuture> questionFind = searchEngineService.getSearchQuestion( - user, + CompletableFuture> questionFind = searchEngineService.getSearchQuestion( + userId, keyword, "Find", questionPageable); - CompletableFuture> questionHow = searchEngineService.getSearchQuestion( - user, + CompletableFuture> questionHow = searchEngineService.getSearchQuestion( + userId, keyword, "How", questionPageable); - CompletableFuture> questionBuy = searchEngineService.getSearchQuestion( - user, + CompletableFuture> questionBuy = searchEngineService.getSearchQuestion( + userId, keyword, "Buy", questionPageable); - CompletableFuture> questionRecommend = searchEngineService.getSearchQuestion( - user, keyword, "Recommend", questionPageable); + CompletableFuture> questionRecommend = searchEngineService.getSearchQuestion( + userId, keyword, "Recommend", questionPageable); // List result = searchService.getSearchQuestion(user, keyword, "Find", questionPageable).get().getContent().stream().toList(); // User 검색 Pageable userPageable = PageRequest.of(0, userSize); - CompletableFuture> searchUser = searchEngineService.getSearchUser(user, + CompletableFuture> searchUser = searchEngineService.getSearchUser(userId, keyword, userPageable); @@ -88,11 +88,11 @@ public SearchTotalResDto getSearchTotal(User user, String keyword) throws Execut } List resultQuestion = result; - List resultItem = searchItem.get().getContent(); + List resultItem = searchItem.get().getContent(); List resultUser = searchUser.get().getContent(); // 최근 검색 등록 - searchService.postRecentSearch(user, keyword); + searchService.postRecentSearch(userId, keyword); // 서치 데이터 등록 searchService.postSearchData(keyword); diff --git a/sluv-api/src/main/java/com/sluv/api/search/service/SearchService.java b/sluv-api/src/main/java/com/sluv/api/search/service/SearchService.java new file mode 100644 index 00000000..901687e7 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/search/service/SearchService.java @@ -0,0 +1,124 @@ +package com.sluv.api.search.service; + +import com.sluv.api.brand.dto.response.BrandSearchResponse; +import com.sluv.api.celeb.dto.response.CelebSearchResponse; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.item.dto.ItemKeywordSearchResDto; +import com.sluv.api.search.dto.RecentSearchChipResDto; +import com.sluv.api.search.dto.SearchKeywordResDto; +import com.sluv.api.search.dto.SearchKeywordTotalResDto; +import com.sluv.domain.brand.service.BrandDomainService; +import com.sluv.domain.celeb.service.CelebDomainService; +import com.sluv.domain.item.service.ItemDomainService; +import com.sluv.domain.search.entity.SearchData; +import com.sluv.domain.search.entity.SearchRank; +import com.sluv.domain.search.service.RecentSearchDomainService; +import com.sluv.domain.search.service.SearchDataDomainService; +import com.sluv.domain.search.service.SearchRankDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@RequiredArgsConstructor +public class SearchService { + + private final RecentSearchDomainService recentSearchDomainService; + private final SearchRankDomainService searchRankDomainService; + private final SearchDataDomainService searchDataDomainService; + private final CelebDomainService celebDomainService; + private final BrandDomainService brandDomainService; + private final ItemDomainService itemDomainService; + private final UserDomainService userDomainService; + + @Transactional(readOnly = true) + public List getRecentSearch(Long userId) { + User user = userDomainService.findById(userId); + List result = recentSearchDomainService.getRecentSearch(user) + .stream() + .map(recentSearch -> RecentSearchChipResDto.of(recentSearch.getSearchWord())) + .toList(); + + return result; + } + + @Transactional(readOnly = true) + public List getSearchRank() { + List searchRankList = searchRankDomainService.findAllByOrderBySearchCountDesc(); + return searchRankList + .stream() + .map(searchRank -> SearchKeywordResDto.of(searchRank.getSearchWord())) + .toList(); + } + + @Transactional(readOnly = true) + public PaginationResponse getSearchKeyword(String keyword, Pageable pageable) { + Page searchDataPage = searchDataDomainService.getSearchKeyword(keyword, pageable); + + List content = searchDataPage.stream() + .map(searchData -> SearchKeywordResDto.of(searchData.getSearchWord())) + .toList(); + + return PaginationResponse.create(searchDataPage, content); + } + + @Async + @Transactional + public void postRecentSearch(Long userId, String keyword) { + User user = userDomainService.findById(userId); + if (!keyword.isEmpty() && !keyword.isBlank()) { + log.info("Post RecentSearch -> User: {}, Keyword: {}", user.getId(), keyword); + recentSearchDomainService.saveRecentSearch(user, keyword); + } + } + + @Async + @Transactional + public void postSearchData(String keyword) { + if (!keyword.isEmpty() && !keyword.isBlank()) { + log.info("Post SearchData -> Keyword: {}", keyword); + searchDataDomainService.saveSearchData(keyword); + } + } + + /** + * 현재 유저의 RecentSearch 키워드 삭제 + */ + @Transactional + public void deleteSearchKeyword(Long userId, String keyword) { + log.info("Delete {}'s Recent Search Keyword: {} ", userId, keyword); + recentSearchDomainService.deleteByUserIdAndSearchWord(userId, keyword); + } + + @Transactional + public void deleteAllSearchKeyword(Long userId) { + log.info("Delete {}'s All Recent Search Keyword", userId); + recentSearchDomainService.deleteAllByUserId(userId); + } + + @Transactional(readOnly = true) + public SearchKeywordTotalResDto getAllDateByKeyword(Long userId, String keyword) { + // 1. 셀럽 2. 브랜드 3. 아이템 + List celebByContainKeyword = celebDomainService.getCelebByContainKeyword(keyword).stream() + .map(CelebSearchResponse::of) + .toList(); + + List brandByContainKeyword = brandDomainService.getBrandContainKeyword(keyword).stream() + .map(BrandSearchResponse::of) + .toList(); + + List itemByContainKeyword = itemDomainService.getItemContainKeyword(keyword).stream() + .map(ItemKeywordSearchResDto::of) + .toList(); + + return SearchKeywordTotalResDto.of(celebByContainKeyword, brandByContainKeyword, itemByContainKeyword); + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/search/utils/ElasticSearchConnectUtil.java b/sluv-api/src/main/java/com/sluv/api/search/utils/ElasticSearchConnectUtil.java new file mode 100644 index 00000000..a5557498 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/search/utils/ElasticSearchConnectUtil.java @@ -0,0 +1,81 @@ +//package com.sluv.api.search.utils; +// +//import com.fasterxml.jackson.databind.ObjectMapper; +//import java.util.Arrays; +//import java.util.List; +//import java.util.Objects; +//import lombok.extern.slf4j.Slf4j; +//import net.minidev.json.JSONArray; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.http.HttpEntity; +//import org.springframework.http.HttpHeaders; +//import org.springframework.http.HttpMethod; +//import org.springframework.http.ResponseEntity; +//import org.springframework.stereotype.Component; +//import org.springframework.util.MultiValueMap; +//import org.springframework.web.client.RestTemplate; +// +//@Component +//@Slf4j +//public class ElasticSearchConnectUtil { +// @Value("${spring.elasticsearch.uri}") +// private String ELASTIC_SEARCH_URI; +// +// /** +// * ElasticSearch API 호출 +// * +// * @param keyword +// * @param path +// * @return result Id List +// */ +// public List connectElasticSearch(String keyword, String path) { +// //요청 URL 조립 +// String requestUrl = ELASTIC_SEARCH_URI + path + "?searchTerm=" + keyword; +// +// // API 호출 +// return getElasticSearchResponse(requestUrl); +// } +// +// /** +// * ReqstTemplate로 다른 서버의 API 호출 +// * +// * @param requestUrl +// * @return ResponseEntity 결과 아이디 +// */ +// private List getElasticSearchResponse(String requestUrl) { +// // Header +// HttpHeaders headers = new HttpHeaders(); +// headers.add("Content-Type", "application/json"); +// +// // Request +// HttpEntity> request = new HttpEntity<>(headers); +// +// // RestTemplate +// log.info("Request: GET {}", requestUrl); +// RestTemplate rt = new RestTemplate(); +// ResponseEntity response = rt.exchange( +// requestUrl, +// HttpMethod.GET, +// request, +// JSONArray.class +// ); +// +// return jsonArrayToList(Objects.requireNonNull(response.getBody())); +// +// +// } +// +// private List jsonArrayToList(JSONArray jsonArray) { +// List list = null; +// try { +// ObjectMapper objectMapper = new ObjectMapper(); +// Long[] longArray = objectMapper.readValue(jsonArray.toString(), Long[].class); +// list = Arrays.stream(longArray).toList(); +// +// } catch (Exception e) { +// log.error("JSONArray To Long List Convert Error"); +// } +// return list; +// +// } +//} diff --git a/sluv-api/src/main/java/com/sluv/api/user/controller/FollowController.java b/sluv-api/src/main/java/com/sluv/api/user/controller/FollowController.java new file mode 100644 index 00000000..5d0d9a20 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/user/controller/FollowController.java @@ -0,0 +1,69 @@ +package com.sluv.api.user.controller; + +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.api.user.service.FollowService; +import com.sluv.common.annotation.CurrentUserId; +import com.sluv.domain.user.dto.UserSearchInfoDto; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Pageable; +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.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Slf4j +@RequestMapping("/app/user") +@RequiredArgsConstructor +public class FollowController { + + private final FollowService followService; + + @Operation(summary = "*특정 유저를 등록한 팔로워들 조회", description = "User 토큰 필요. Pagination 적용") + @GetMapping("/{userId}/follower") + public ResponseEntity>> getUserFollower( + @CurrentUserId Long userId, @PathVariable("userId") Long targetId, Pageable pageable) { + PaginationResponse response = followService.getUserFollower(userId, targetId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*특정 유저가 등록한 팔로잉 조회", description = "User 토큰 필요. Pagination 적용") + @GetMapping("/{userId}/following") + public ResponseEntity>> getUserFollowing( + @CurrentUserId Long userId, @PathVariable("userId") Long targetId, Pageable pageable) { + PaginationResponse response = followService.getUserFollowing(userId, targetId, + pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*현재 유저를 등록한 팔로워들 조회", description = "User 토큰 필요. Pagination 적용") + @GetMapping("/follower") + public ResponseEntity>> getNowUserFollower( + @CurrentUserId Long userId, Pageable pageable) { + PaginationResponse response = followService.getUserFollower(userId, userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*현재 유저가 등록한 팔로잉 조회", description = "User 토큰 필요. Pagination 적용") + @GetMapping("/following") + public ResponseEntity>> getNowUserFollowing( + @CurrentUserId Long userId, Pageable pageable) { + PaginationResponse response = followService.getUserFollowing(userId, userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*유저 팔로우/팔로잉", description = "User 토큰 필요") + @PostMapping("/{userId}/follow") + public ResponseEntity postUserFollow(@CurrentUserId Long userId, + @PathVariable(name = "userId") Long targetId) { + followService.postUserFollow(userId, targetId); + return ResponseEntity.ok().body(SuccessResponse.create()); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/user/controller/UserCelebController.java b/sluv-api/src/main/java/com/sluv/api/user/controller/UserCelebController.java new file mode 100644 index 00000000..8ee17d5b --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/user/controller/UserCelebController.java @@ -0,0 +1,73 @@ +package com.sluv.api.user.controller; + +import com.sluv.api.celeb.dto.request.InterestedCelebPostRequest; +import com.sluv.api.celeb.dto.response.InterestedCelebCategoryResponse; +import com.sluv.api.celeb.dto.response.InterestedCelebParentResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.api.user.service.UserCelebService; +import com.sluv.common.annotation.CurrentUserId; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@Slf4j +@RequestMapping("/app/user") +@RequiredArgsConstructor +public class UserCelebController { + + private final UserCelebService userCelebService; + + @Operation(summary = "*현재 유저의 관심 샐럽을 카테고리를 기준으로 조회", + description = "현재 유저를 기준으로 InterstedCeleb 테이블에서 일치하는 Celeb을 카테고리를 기준으로 검색") + @GetMapping("/celeb/category") + public ResponseEntity>> getInterestedCelebByCategory( + @CurrentUserId Long userId) { + List response = userCelebService.getInterestedCelebByCategory( + userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*현재 유저의 관심 샐럽을 등록순을 기준으로 조회", + description = "현재 유저를 기준으로 InterstedCeleb 테이블에서 일치하는 Celeb을 등록순을 기준으로 검색") + @GetMapping("/celeb") + public ResponseEntity>> getInterestedCelebByPostTime( + @CurrentUserId Long userId) { + List response = userCelebService.getInterestedCelebByPostTime( + userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "특정 유저의 관심 샐럽을 등록순을 기준으로 조회", + description = "특정 유저를 기준으로 InterstedCeleb 테이블에서 일치하는 Celeb을 등록순을 기준으로 검색") + @GetMapping("/{userId}/celeb") + public ResponseEntity>> getTargetUserInterestedCelebByPostTime( + @PathVariable("userId") Long userId) { + List response = userCelebService.getTargetUserInterestedCelebByPostTime( + userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*특정 유저의 관심 샐럽을 카테고리를 기준으로 조회", + description = "특정 유저를 기준으로 InterstedCeleb 테이블에서 일치하는 Celeb을 카테고리를 기준으로 검색") + @GetMapping("/{userId}/celeb/category") + public ResponseEntity>> getTargetUserInterestedCelebByCategory( + @PathVariable("userId") Long userId) { + List response = userCelebService.getTargetUserInterestedCelebByCategory( + userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*유저의 관심 셀럽 업데이트", description = "User 토큰 필요") + @PostMapping("/celeb") + public ResponseEntity postInterestedCeleb(@CurrentUserId Long userId + , @RequestBody InterestedCelebPostRequest dto) { + userCelebService.postInterestedCeleb(userId, dto); + return ResponseEntity.ok().body(SuccessResponse.create()); + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/user/controller/UserController.java b/sluv-api/src/main/java/com/sluv/api/user/controller/UserController.java new file mode 100644 index 00000000..073d3ea7 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/user/controller/UserController.java @@ -0,0 +1,177 @@ +package com.sluv.api.user.controller; + + +import com.sluv.api.closet.dto.response.ClosetResponse; +import com.sluv.api.comment.dto.reponse.CommentSimpleResponse; +import com.sluv.api.common.response.PaginationCountResponse; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.api.user.dto.UserMypageResDto; +import com.sluv.api.user.dto.UserProfileImgReqDto; +import com.sluv.api.user.dto.UserProfileReqDto; +import com.sluv.api.user.dto.UserSocialDto; +import com.sluv.api.user.dto.UserTermsResDto; +import com.sluv.api.user.dto.UserWithdrawReqDto; +import com.sluv.api.user.service.UserService; +import com.sluv.common.annotation.CurrentUserId; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import com.sluv.domain.user.dto.UserSearchInfoDto; +import io.swagger.v3.oas.annotations.Operation; +import jakarta.annotation.Nullable; +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@Slf4j +@RequestMapping("/app/user") +public class UserController { + private final UserService userService; + + @Operation( + summary = "*유저의 프로필 설정 및 수정", + description = "최초 회원 가입 시 유저의 프로필 설정 및 추후 유저의 프로필 수정" + + "\n User의 Status가 \"PENDING_PROFILE\" 일 경우 설정 후 Status를 \"PENDING_CELEB\"로 변경" + + "\n User의 Status가 \"ACTIVE\" 일 경우 프로필 정보만 수정" + + "\n (User Id Token 필요)" + + "\n \"PENDING_PROFILE\"로 등록 후 User Id Token이 발급되기 때문에 " + ) + @PostMapping("/profile") + public ResponseEntity postUserProfile(@CurrentUserId Long userId, + @RequestBody UserProfileReqDto dto) { + userService.postUserProfile(userId, dto); + return ResponseEntity.ok().body( + new SuccessResponse() + ); + } + + @Operation(summary = "특정 유저의 마이페이지 조회", description = "User 토큰 필요") + @GetMapping("/{userId}/mypage") + public ResponseEntity> getTargetUserMypage(@CurrentUserId Long userId, + @PathVariable("userId") Long targetId) { + UserMypageResDto response = userService.getUserMypage(userId, targetId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "현재 유저의 마이페이지 조회", description = "User 토큰 필요") + @GetMapping("/mypage") + public ResponseEntity> getUserMypage(@CurrentUserId Long userId) { + UserMypageResDto response = userService.getUserMypage(userId, null); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "특정 유저의 아이템 목록 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/{userId}/item") + public ResponseEntity>> getUserItem( + @CurrentUserId Long userId, @PathVariable("userId") Long targetId, Pageable pageable) { + PaginationResponse response = userService.getUserItem(userId, targetId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*특정 유저의 옷장 목록 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/{userId}/closet") + public ResponseEntity>> getUserCloset( + @CurrentUserId Long userId, @PathVariable("userId") Long targetId, Pageable pageable) { + PaginationResponse response = userService.getUserCloset(userId, targetId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*유저의 이메일, 소셜 종류 조회", description = "User 토큰 필요.") + @GetMapping("/social") + public ResponseEntity> getUserSocialData(@CurrentUserId Long userId) { + UserSocialDto response = userService.getUserSocialData(userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*유저의 프로필 이미지 수정", description = "User 토큰 필요. Pagination 적용.") + @PatchMapping("/profileImg") + public ResponseEntity patchUserProfileImg(@CurrentUserId Long userId, + @RequestBody UserProfileImgReqDto dto) { + + userService.patchUserProfileImg(userId, dto); + return ResponseEntity.ok().body(SuccessResponse.create()); + } + + @Operation(summary = "*유저의 프로필 이미지 삭제", description = "null로 변경. User 토큰 필요.") + @DeleteMapping("/profileImg") + public ResponseEntity deleteUserProfileImg(@CurrentUserId Long userId) { + + userService.deleteUserProfileImg(userId); + return ResponseEntity.ok().body(SuccessResponse.create()); + } + + @Operation(summary = "*유저가 작성한 Item 게시글 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/item") + public ResponseEntity>> getUserUploadItem( + @CurrentUserId Long userId, Pageable pageable) { + PaginationCountResponse response = userService.getUserUploadItem(userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*유저가 작성한 Question 게시글 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/question") + public ResponseEntity>> getUserUploadQuestion( + @CurrentUserId Long userId, Pageable pageable) { + + PaginationCountResponse response = userService.getUserUploadQuestion(userId, + pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*유저가 작성한 Comment 게시글 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/comment") + public ResponseEntity>> getUserUploadComment( + @CurrentUserId Long userId, Pageable pageable) { + PaginationCountResponse response = userService.getUserUploadComment(userId, + pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + /** + * 1. 팔로워수 2. 아이템 업로드 수 3. item Like 받은 수 4. question Like 받은 수 5. comment Like 받은 수 + */ + @Operation(summary = "*인기 스러버 조회", description = "User 토큰 필요. 정적으로 10개 검색") + @GetMapping("/hotSluver") + public ResponseEntity>> getHotSluver(@CurrentUserId Long userId, + @Nullable @RequestParam("celebId") Long celebId) { + log.info("이번주 인기 스러버 조회"); + List response = userService.getHotSluver(userId, celebId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*약관 동의", description = "광고성 정보 수신 및 마케팅 활용 동의") + @PostMapping("/terms") + public ResponseEntity> postTerms(@CurrentUserId Long userId) { + UserTermsResDto response = userService.postTerms(userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*약관 동의 상태 조회", description = "광고성 정보 수신 및 마케팅 활용 동의 상태 조회") + @GetMapping("/terms") + public ResponseEntity> getUserTermsStatus(@CurrentUserId Long userId) { + UserTermsResDto response = userService.findUserTermsStatus(userId); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*회원 탈퇴", description = "회원 탈퇴 기능") + @PostMapping("/withdraw") + public ResponseEntity withdrawUser(@CurrentUserId Long userId, + @RequestBody UserWithdrawReqDto dto) { + userService.withdrawUser(userId, dto); + return ResponseEntity.ok().body(SuccessResponse.create()); + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/user/controller/UserLikeController.java b/sluv-api/src/main/java/com/sluv/api/user/controller/UserLikeController.java new file mode 100644 index 00000000..d03e68d2 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/user/controller/UserLikeController.java @@ -0,0 +1,53 @@ +package com.sluv.api.user.controller; + +import com.sluv.api.comment.dto.reponse.CommentSimpleResponse; +import com.sluv.api.common.response.PaginationCountResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.user.service.UserLikeService; +import com.sluv.common.annotation.CurrentUserId; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Slf4j +@RequestMapping("/app/user") +@RequiredArgsConstructor +public class UserLikeController { + + private final UserLikeService userLikeService; + + @Operation(summary = "유저가 좋아요한 아이템 조회", description = "User 토큰 필요. Pagination 적용") + @GetMapping("/like/item") + public ResponseEntity>> getUserLikeItem( + @CurrentUserId Long userId, Pageable pageable) { + + PaginationCountResponse response = userLikeService.getUserLikeItem(userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "유저가 좋아요한 Question 게시글 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/like/question") + public ResponseEntity>> getUserLikeQuestion( + @CurrentUserId Long userId, Pageable pageable) { + PaginationCountResponse response = userLikeService.getUserLikeQuestion(userId, + pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "유저가 좋아요한 Comment 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/like/comment") + public ResponseEntity>> getUserLikeComment( + @CurrentUserId Long userId, Pageable pageable) { + PaginationCountResponse response = userLikeService.getUserLikeComment(userId, + pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/user/controller/UserRecentController.java b/sluv-api/src/main/java/com/sluv/api/user/controller/UserRecentController.java new file mode 100644 index 00000000..1a2544b8 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/user/controller/UserRecentController.java @@ -0,0 +1,41 @@ +package com.sluv.api.user.controller; + +import com.sluv.api.common.response.PaginationCountResponse; +import com.sluv.api.common.response.SuccessDataResponse; +import com.sluv.api.user.service.UserRecentService; +import com.sluv.common.annotation.CurrentUserId; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Slf4j +@RequestMapping("/app/user") +@RequiredArgsConstructor +public class UserRecentController { + private final UserRecentService userRecentService; + + @Operation(summary = "*유저의 최근 본 아이템 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/recent/item") + public ResponseEntity>> getUserRecentItem( + @CurrentUserId Long userId, Pageable pageable) { + PaginationCountResponse response = userRecentService.getUserRecentItem(userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } + + @Operation(summary = "*유저의 최근 본 Question 조회", description = "User 토큰 필요. Pagination 적용.") + @GetMapping("/recent/question") + public ResponseEntity>> getUserRecentQuestion( + @CurrentUserId Long userId, Pageable pageable) { + PaginationCountResponse response = userRecentService.getUserRecentQuestion( + userId, pageable); + return ResponseEntity.ok().body(SuccessDataResponse.create(response)); + } +} diff --git a/src/main/java/com/sluv/server/domain/user/controller/UserReportController.java b/sluv-api/src/main/java/com/sluv/api/user/controller/UserReportController.java similarity index 59% rename from src/main/java/com/sluv/server/domain/user/controller/UserReportController.java rename to sluv-api/src/main/java/com/sluv/api/user/controller/UserReportController.java index dc2f1526..f8028274 100644 --- a/src/main/java/com/sluv/server/domain/user/controller/UserReportController.java +++ b/sluv-api/src/main/java/com/sluv/api/user/controller/UserReportController.java @@ -1,14 +1,13 @@ -package com.sluv.server.domain.user.controller; +package com.sluv.api.user.controller; -import com.sluv.server.domain.user.dto.UserReportReqDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.service.UserReportService; -import com.sluv.server.global.common.response.SuccessResponse; +import com.sluv.api.common.response.SuccessResponse; +import com.sluv.api.user.dto.UserReportReqDto; +import com.sluv.api.user.service.UserReportService; +import com.sluv.common.annotation.CurrentUserId; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -25,12 +24,10 @@ public class UserReportController { @Operation(summary = "*유저 신고하기", description = "User 토큰 필요") @PostMapping("/{userId}/report") - public ResponseEntity postUserReport(@AuthenticationPrincipal User user, - @PathVariable(name = "userId") Long userId, + public ResponseEntity postUserReport(@CurrentUserId Long userId, + @PathVariable(name = "userId") Long targetId, @RequestBody UserReportReqDto dto) { - userReportService.postUserReport(user, userId, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); + userReportService.postUserReport(userId, targetId, dto); + return ResponseEntity.ok().body(SuccessResponse.create()); } } diff --git a/src/main/java/com/sluv/server/domain/user/dto/UserIdDto.java b/sluv-api/src/main/java/com/sluv/api/user/dto/UserIdDto.java similarity index 91% rename from src/main/java/com/sluv/server/domain/user/dto/UserIdDto.java rename to sluv-api/src/main/java/com/sluv/api/user/dto/UserIdDto.java index 29935ac7..342d05f0 100644 --- a/src/main/java/com/sluv/server/domain/user/dto/UserIdDto.java +++ b/sluv-api/src/main/java/com/sluv/api/user/dto/UserIdDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.user.dto; +package com.sluv.api.user.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/user/dto/UserMypageResDto.java b/sluv-api/src/main/java/com/sluv/api/user/dto/UserMypageResDto.java similarity index 93% rename from src/main/java/com/sluv/server/domain/user/dto/UserMypageResDto.java rename to sluv-api/src/main/java/com/sluv/api/user/dto/UserMypageResDto.java index 640aa35d..c9004304 100644 --- a/src/main/java/com/sluv/server/domain/user/dto/UserMypageResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/user/dto/UserMypageResDto.java @@ -1,6 +1,7 @@ -package com.sluv.server.domain.user.dto; +package com.sluv.api.user.dto; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.user.dto.UserInfoDto; +import com.sluv.domain.user.entity.User; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/user/dto/UserProfileImgReqDto.java b/sluv-api/src/main/java/com/sluv/api/user/dto/UserProfileImgReqDto.java similarity index 77% rename from src/main/java/com/sluv/server/domain/user/dto/UserProfileImgReqDto.java rename to sluv-api/src/main/java/com/sluv/api/user/dto/UserProfileImgReqDto.java index ba0a4719..91f4f748 100644 --- a/src/main/java/com/sluv/server/domain/user/dto/UserProfileImgReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/user/dto/UserProfileImgReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.user.dto; +package com.sluv.api.user.dto; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/user/dto/UserProfileReqDto.java b/sluv-api/src/main/java/com/sluv/api/user/dto/UserProfileReqDto.java similarity index 91% rename from src/main/java/com/sluv/server/domain/user/dto/UserProfileReqDto.java rename to sluv-api/src/main/java/com/sluv/api/user/dto/UserProfileReqDto.java index a22033b2..96dd606b 100644 --- a/src/main/java/com/sluv/server/domain/user/dto/UserProfileReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/user/dto/UserProfileReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.user.dto; +package com.sluv.api.user.dto; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.Size; diff --git a/src/main/java/com/sluv/server/domain/user/dto/UserReportReqDto.java b/sluv-api/src/main/java/com/sluv/api/user/dto/UserReportReqDto.java similarity index 80% rename from src/main/java/com/sluv/server/domain/user/dto/UserReportReqDto.java rename to sluv-api/src/main/java/com/sluv/api/user/dto/UserReportReqDto.java index ac8e32f0..e109b77c 100644 --- a/src/main/java/com/sluv/server/domain/user/dto/UserReportReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/user/dto/UserReportReqDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.user.dto; +package com.sluv.api.user.dto; -import com.sluv.server.domain.user.enums.UserReportReason; +import com.sluv.domain.user.enums.UserReportReason; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/user/dto/UserSocialDto.java b/sluv-api/src/main/java/com/sluv/api/user/dto/UserSocialDto.java similarity index 82% rename from src/main/java/com/sluv/server/domain/user/dto/UserSocialDto.java rename to sluv-api/src/main/java/com/sluv/api/user/dto/UserSocialDto.java index c51a3f80..70a694e9 100644 --- a/src/main/java/com/sluv/server/domain/user/dto/UserSocialDto.java +++ b/sluv-api/src/main/java/com/sluv/api/user/dto/UserSocialDto.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.user.dto; +package com.sluv.api.user.dto; -import com.sluv.server.domain.auth.enums.SnsType; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.auth.enums.SnsType; +import com.sluv.domain.user.entity.User; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/user/dto/UserTermsResDto.java b/sluv-api/src/main/java/com/sluv/api/user/dto/UserTermsResDto.java similarity index 86% rename from src/main/java/com/sluv/server/domain/user/dto/UserTermsResDto.java rename to sluv-api/src/main/java/com/sluv/api/user/dto/UserTermsResDto.java index f708662f..cf64e262 100644 --- a/src/main/java/com/sluv/server/domain/user/dto/UserTermsResDto.java +++ b/sluv-api/src/main/java/com/sluv/api/user/dto/UserTermsResDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.user.dto; +package com.sluv.api.user.dto; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.user.entity.User; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -20,4 +20,5 @@ public static UserTermsResDto of(User user) { .termsStatus(user.getTermsStatus()) .build(); } + } diff --git a/src/main/java/com/sluv/server/domain/user/dto/UserWithdrawReqDto.java b/sluv-api/src/main/java/com/sluv/api/user/dto/UserWithdrawReqDto.java similarity index 79% rename from src/main/java/com/sluv/server/domain/user/dto/UserWithdrawReqDto.java rename to sluv-api/src/main/java/com/sluv/api/user/dto/UserWithdrawReqDto.java index 42e14ad5..203a23ae 100644 --- a/src/main/java/com/sluv/server/domain/user/dto/UserWithdrawReqDto.java +++ b/sluv-api/src/main/java/com/sluv/api/user/dto/UserWithdrawReqDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.user.dto; +package com.sluv.api.user.dto; -import com.sluv.server.domain.user.enums.UserWithdrawReason; +import com.sluv.domain.user.enums.UserWithdrawReason; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/sluv-api/src/main/java/com/sluv/api/user/service/FollowService.java b/sluv-api/src/main/java/com/sluv/api/user/service/FollowService.java new file mode 100644 index 00000000..92f54b12 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/user/service/FollowService.java @@ -0,0 +1,72 @@ +package com.sluv.api.user.service; + +import com.sluv.api.alarm.service.UserAlarmService; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.domain.user.dto.UserSearchInfoDto; +import com.sluv.domain.user.entity.Follow; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.FollowDomainService; +import com.sluv.domain.user.service.UserDomainService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Slf4j +@RequiredArgsConstructor +public class FollowService { + + private final UserDomainService userDomainService; + private final FollowDomainService followDomainService; + private final UserAlarmService userAlarmService; + + @Transactional + public void postUserFollow(Long userId, Long targetId) { + User user = userDomainService.findById(userId); + // target이 될 유저 검색 + User targetUser = userDomainService.findById(targetId); + + // Follow 여부 확인. + Boolean followStatus = followDomainService.getFollowStatus(user, targetUser.getId()); + + if (followStatus) { + followDomainService.deleteFollow(user, targetUser); + } else { + // Follow 정보 등록. + followDomainService.saveFollow(Follow.toEntity(user, targetUser)); + userAlarmService.sendAlarmAboutFollow(user.getId(), targetUser.getId()); + } + + } + + @Transactional(readOnly = true) + public PaginationResponse getUserFollower(Long userId, Long targetId, Pageable pageable) { + User user = userDomainService.findById(userId); + // Follower 들 조회 + Page followerPage = userDomainService.getAllFollower(targetId, pageable); + + // UserSearchInfoDto로 가공 + List content = + followDomainService.getUserSearchInfoDto(user, followerPage.getContent(), "follower"); + + return PaginationResponse.create(followerPage, content); + } + + @Transactional(readOnly = true) + public PaginationResponse getUserFollowing(Long userId, Long targetId, Pageable pageable) { + User user = userDomainService.findById(userId); + + // Following 들 조회 + Page followerPage = userDomainService.getAllFollowing(targetId, pageable); + + // UserSearchInfoDto로 가공 + List content = + followDomainService.getUserSearchInfoDto(user, followerPage.getContent(), "followee"); + + return PaginationResponse.create(followerPage, content); + } +} diff --git a/src/main/java/com/sluv/server/domain/user/service/UserCelebService.java b/sluv-api/src/main/java/com/sluv/api/user/service/UserCelebService.java similarity index 55% rename from src/main/java/com/sluv/server/domain/user/service/UserCelebService.java rename to sluv-api/src/main/java/com/sluv/api/user/service/UserCelebService.java index 0dc8f02c..d1cafe02 100644 --- a/src/main/java/com/sluv/server/domain/user/service/UserCelebService.java +++ b/sluv-api/src/main/java/com/sluv/api/user/service/UserCelebService.java @@ -1,37 +1,36 @@ -package com.sluv.server.domain.user.service; - -import com.sluv.server.domain.celeb.dto.InterestedCelebCategoryResDto; -import com.sluv.server.domain.celeb.dto.InterestedCelebParentResDto; -import com.sluv.server.domain.celeb.dto.InterestedCelebPostReqDto; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.CelebCategory; -import com.sluv.server.domain.celeb.entity.InterestedCeleb; -import com.sluv.server.domain.celeb.exception.CelebNotFoundException; -import com.sluv.server.domain.celeb.repository.CelebCategoryRepository; -import com.sluv.server.domain.celeb.repository.CelebRepository; -import com.sluv.server.domain.celeb.repository.InterestedCelebRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.enums.UserStatus; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.discord.WebHookService; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; +package com.sluv.api.user.service; + +import com.sluv.api.celeb.dto.request.InterestedCelebPostRequest; +import com.sluv.api.celeb.dto.response.InterestedCelebCategoryResponse; +import com.sluv.api.celeb.dto.response.InterestedCelebParentResponse; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.CelebCategory; +import com.sluv.domain.celeb.entity.InterestedCeleb; +import com.sluv.domain.celeb.service.CelebCategoryDomainService; +import com.sluv.domain.celeb.service.CelebDomainService; +import com.sluv.domain.celeb.service.InterestedCelebDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.enums.UserStatus; +import com.sluv.domain.user.service.UserDomainService; +import com.sluv.infra.discord.WebHookService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; + @Service @Slf4j @RequiredArgsConstructor public class UserCelebService { - private final UserRepository userRepository; - private final CelebRepository celebRepository; - private final CelebCategoryRepository celebCategoryRepository; - private final InterestedCelebRepository interestedCelebRepository; + private final UserDomainService userDomainService; + private final CelebDomainService celebDomainService; + private final CelebCategoryDomainService celebCategoryDomainService; + private final InterestedCelebDomainService interestedCelebDomainService; private final WebHookService webHookService; @@ -39,16 +38,22 @@ public class UserCelebService { * User가 선택한 관심 셀럽을 검색 관심 샐럼의 상위 카테고리를 기준으로 묶어서 Response */ @Transactional(readOnly = true) - public List getInterestedCelebByCategory(User user) { - List interestedCelebList = celebRepository.findInterestedCeleb(user); + public List getInterestedCelebByCategory(Long userId) { + User user = userDomainService.findByIdOrNull(userId); + List interestedCelebList; + if (user != null) { + interestedCelebList = celebDomainService.findInterestedCeleb(user); + } else { + interestedCelebList = celebDomainService.findTop10Celeb(); + } - List categoryList = celebCategoryRepository.findAllByParentIdIsNull(); + List categoryList = celebCategoryDomainService.findAllByParentIdIsNull(); changeCategoryOrder(categoryList); return categoryList.stream() .map(category -> { // 카테고리별 InterestedCelebCategoryResDto 생성 List categoryFilterCeleb = getCategoryFilterCeleb(interestedCelebList, category); - return InterestedCelebCategoryResDto.of(category, + return InterestedCelebCategoryResponse.of(category, convertInterestedCelebParentResDto(categoryFilterCeleb)); }).toList(); } @@ -57,12 +62,12 @@ public List getInterestedCelebByCategory(User use * 특정 유저가 선택한 관심 Celeb을 조회 CelebCategory를 기준으로 그룹핑 유저가 등록한 순서대로 조회 */ @Transactional(readOnly = true) - public List getTargetUserInterestedCelebByPostTime(Long userId) { - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); + public List getTargetUserInterestedCelebByPostTime(Long userId) { + User user = userDomainService.findById(userId); - return celebRepository.findInterestedCeleb(user) + return celebDomainService.findInterestedCeleb(user) .stream() - .map(InterestedCelebParentResDto::of) + .map(InterestedCelebParentResponse::of) .toList(); } @@ -70,21 +75,22 @@ public List getTargetUserInterestedCelebByPostTime( * User가 선택한 관심 셀럽을 검색 관심 셀럽 선택순서를 기준으로 조회 */ @Transactional(readOnly = true) - public List getInterestedCelebByPostTime(User user) { - List dtos; + public List getInterestedCelebByPostTime(Long userId) { + User user = userDomainService.findByIdOrNull(userId); + List dtos; if (user != null) { - dtos = celebRepository.findInterestedCeleb(user) + dtos = celebDomainService.findInterestedCeleb(user) .stream() - .map(InterestedCelebParentResDto::of) + .map(InterestedCelebParentResponse::of) .toList(); } else { - dtos = celebRepository.findTop10Celeb() + dtos = celebDomainService.findTop10Celeb() .stream() .map(celeb -> { if (celeb.getParent() != null) { celeb = celeb.getParent(); } - return InterestedCelebParentResDto.of(celeb); + return InterestedCelebParentResponse.of(celeb); }) .distinct() .toList(); @@ -93,22 +99,23 @@ public List getInterestedCelebByPostTime(User user) } @Transactional - public void postInterestedCeleb(User user, InterestedCelebPostReqDto dto) { + public void postInterestedCeleb(Long userId, InterestedCelebPostRequest dto) { + User user = userDomainService.findById(userId); // 기존에 있는 해당 유저의 관심셀럽 초기화 if (user.getUserStatus().equals(UserStatus.ACTIVE)) { - interestedCelebRepository.deleteAllByUserId(user.getId()); + interestedCelebDomainService.deleteAllByUserId(user.getId()); } // 초기화 상태에서 다시 추가. List interestedCelebList = dto.getCelebIdList().stream() .map(celeb -> InterestedCeleb.toEntity(user, - celebRepository.findById(celeb).orElseThrow(CelebNotFoundException::new))).toList(); + celebDomainService.findById(celeb))).toList(); - interestedCelebRepository.saveAll(interestedCelebList); + interestedCelebDomainService.saveAll(interestedCelebList); if (user.getUserStatus().equals(UserStatus.PENDING_CELEB)) { user.changeUserStatus(UserStatus.ACTIVE); - userRepository.save(user); + userDomainService.saveUser(user); webHookService.sendSingupMessage(user); } } @@ -117,11 +124,11 @@ public void postInterestedCeleb(User user, InterestedCelebPostReqDto dto) { * 특정 유저가 선택한 관심 Celeb을 조회 CelebCategory를 기준으로 그룹핑 카테고리를 기준으로 조회 */ @Transactional(readOnly = true) - public List getTargetUserInterestedCelebByCategory(Long userId) { - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - List interestedCelebList = celebRepository.findInterestedCeleb(user); + public List getTargetUserInterestedCelebByCategory(Long userId) { + User user = userDomainService.findById(userId); + List interestedCelebList = celebDomainService.findInterestedCeleb(user); - List categoryList = celebCategoryRepository.findAllByParentIdIsNull(); + List categoryList = celebCategoryDomainService.findAllByParentIdIsNull(); categoryList.sort(Comparator.comparing(CelebCategory::getName)); changeCategoryOrder(categoryList); @@ -129,7 +136,7 @@ public List getTargetUserInterestedCelebByCategor // 카테고리별 InterestedCelebCategoryResDto 생성 .map(category -> { List categoryFilterCeleb = getCategoryFilterCeleb(interestedCelebList, category); - return InterestedCelebCategoryResDto.of(category, + return InterestedCelebCategoryResponse.of(category, convertInterestedCelebParentResDto(categoryFilterCeleb)); }).toList(); } @@ -160,7 +167,7 @@ private List getCategoryFilterCeleb(List celebList, CelebCategory /** * 관심셀럽 목록에서 category와 일치하는 Celeb을 분류 */ - private List convertInterestedCelebParentResDto(List celebList) { - return celebList.stream().map(InterestedCelebParentResDto::of).toList(); + private List convertInterestedCelebParentResDto(List celebList) { + return celebList.stream().map(InterestedCelebParentResponse::of).toList(); } } diff --git a/sluv-api/src/main/java/com/sluv/api/user/service/UserLikeService.java b/sluv-api/src/main/java/com/sluv/api/user/service/UserLikeService.java new file mode 100644 index 00000000..e960fafb --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/user/service/UserLikeService.java @@ -0,0 +1,75 @@ +package com.sluv.api.user.service; + +import com.sluv.api.comment.dto.reponse.CommentSimpleResponse; +import com.sluv.api.common.response.PaginationCountResponse; +import com.sluv.api.question.mapper.QuestionDtoMapper; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.service.CommentDomainService; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.service.ItemDomainService; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.service.QuestionDomainService; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Slf4j +@RequiredArgsConstructor +public class UserLikeService { + + private final UserDomainService userDomainService; + private final ItemDomainService itemDomainService; + private final QuestionDomainService questionDomainService; + private final CommentDomainService commentDomainService; + + private final QuestionDtoMapper questionDtoMapper; + + @Transactional(readOnly = true) + public PaginationCountResponse getUserLikeItem(Long userId, Pageable pageable) { + User user = userDomainService.findById(userId); + Page itemPage = itemDomainService.getAllByUserLikeItem(user, pageable); + + List content = itemDomainService.getItemSimpleDto(user, itemPage.getContent()); + + return new PaginationCountResponse<>(itemPage.hasNext(), itemPage.getNumber(), content, + itemPage.getTotalElements()); + } + + /** + * 유저가 좋아요한 Question 게시글 조회 + */ + @Transactional(readOnly = true) + public PaginationCountResponse getUserLikeQuestion(Long userId, Pageable pageable) { + User user = userDomainService.findById(userId); + Page questionPage = questionDomainService.getUserLikeQuestion(user, pageable); + + List content = questionPage.stream() + .map(questionDtoMapper::dtoBuildByQuestionType).toList(); + + return new PaginationCountResponse<>(questionPage.hasNext(), questionPage.getNumber(), content, + questionPage.getTotalElements()); + } + + /** + * 유저가 좋아요한 댓글 목록 조회 + */ + @Transactional(readOnly = true) + public PaginationCountResponse getUserLikeComment(Long userId, Pageable pageable) { + User user = userDomainService.findById(userId); + Page commentPage = commentDomainService.getUserAllLikeComment(user, pageable); + + List content = commentPage.stream().map(CommentSimpleResponse::of).toList(); + + return new PaginationCountResponse<>(commentPage.hasNext(), commentPage.getNumber(), content, + commentPage.getTotalElements()); + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/user/service/UserRecentService.java b/sluv-api/src/main/java/com/sluv/api/user/service/UserRecentService.java new file mode 100644 index 00000000..d1d07707 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/user/service/UserRecentService.java @@ -0,0 +1,104 @@ +package com.sluv.api.user.service; + +import com.sluv.api.common.response.PaginationCountResponse; +import com.sluv.domain.comment.service.CommentDomainService; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemImg; +import com.sluv.domain.item.service.ItemDomainService; +import com.sluv.domain.item.service.ItemImgDomainService; +import com.sluv.domain.question.dto.QuestionImgSimpleDto; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import com.sluv.domain.question.entity.*; +import com.sluv.domain.question.exception.QuestionTypeNotFoundException; +import com.sluv.domain.question.service.*; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.service.UserDomainService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@Slf4j +@RequiredArgsConstructor +public class UserRecentService { + + private final ItemDomainService itemDomainService; + private final ItemImgDomainService itemImgDomainService; + private final QuestionImgDomainService questionImgDomainService; + private final QuestionItemDomainService questionItemDomainService; + private final QuestionLikeDomainService questionLikeDomainService; + private final RecentQuestionDomainService recentQuestionDomainService; + private final QuestionRecommendCategoryDomainService questionRecommendCategoryDomainService; + private final CommentDomainService commentDomainService; + private final UserDomainService userDomainService; + + + @Transactional(readOnly = true) + public PaginationCountResponse getUserRecentItem(Long userId, Pageable pageable) { + User user = userDomainService.findById(userId); + + Page recentItemPage = itemDomainService.getUserAllRecentItem(user, pageable); + + List content = itemDomainService.getItemSimpleDto(user, recentItemPage.getContent()); + + return new PaginationCountResponse<>(recentItemPage.hasNext(), recentItemPage.getNumber(), content, + recentItemPage.getTotalElements()); + } + + @Transactional(readOnly = true) + public PaginationCountResponse getUserRecentQuestion(Long userId, Pageable pageable) { + User user = userDomainService.findById(userId); + + Page recentQuestionPage = recentQuestionDomainService.getUserAllRecentQuestion(user, pageable); + + List content = recentQuestionPage.stream().map(question -> { + List imgList = null; + List itemImgList = null; + List categoryList = null; + + if (question instanceof QuestionBuy) { + // 이미지 Dto 생성 + imgList = questionImgDomainService.findAllByQuestionId(question.getId()).stream() + .map(QuestionImgSimpleDto::of).toList(); + // 아이템 이미지 Dto 생성 + itemImgList = questionItemDomainService.findAllByQuestionId(question.getId()).stream() + .map(questionItem -> { + ItemImg mainImg = itemImgDomainService.findMainImg(questionItem.getItem().getId()); + return QuestionImgSimpleDto.of(mainImg); + }).toList(); + + } else if (question instanceof QuestionHowabout) { + + } else if (question instanceof QuestionRecommend) { + // Question 카테고리 + categoryList = questionRecommendCategoryDomainService.findAllByQuestionId(question.getId()).stream() + .map(QuestionRecommendCategory::getName).toList(); + } else if (question instanceof QuestionFind) { + + } else { + throw new QuestionTypeNotFoundException(); + } + + // Question 좋아요 수 + Long likeNum = questionLikeDomainService.countByQuestionId(question.getId()); + + // Question 댓글 수 + Long commentNum = commentDomainService.countByQuestionId(question.getId()); + + User writer = userDomainService.findByIdOrNull(question.getUser().getId()); + + return QuestionSimpleResDto.of(question, writer, likeNum, commentNum, imgList, itemImgList, categoryList); + + + }).toList(); + + return new PaginationCountResponse<>(recentQuestionPage.hasNext(), recentQuestionPage.getNumber(), content, + recentQuestionPage.getTotalElements()); + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/user/service/UserReportService.java b/sluv-api/src/main/java/com/sluv/api/user/service/UserReportService.java new file mode 100644 index 00000000..88b1c072 --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/user/service/UserReportService.java @@ -0,0 +1,36 @@ +package com.sluv.api.user.service; + +import com.sluv.api.user.dto.UserReportReqDto; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.exception.UserReportDuplicateException; +import com.sluv.domain.user.service.UserDomainService; +import com.sluv.domain.user.service.UserReportDomainService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class UserReportService { + + private final UserDomainService userDomainService; + private final UserReportDomainService userReportDomainService; + + @Transactional + public void postUserReport(Long userId, Long targetId, UserReportReqDto dto) { + // 피신고자 검색 + User user = userDomainService.findById(userId); + User target = userDomainService.findById(targetId); + + // 신고 중복여부 확인 + boolean existence = userReportDomainService.findExistence(user, target); + + // 중복 신고라면 Exception 발생 + if (existence) { + throw new UserReportDuplicateException(); + } else { + // 중복이 아니라면 신고 접수 + userReportDomainService.saveUserReport(user, target, dto.getReason(), dto.getContent()); + } + } +} diff --git a/sluv-api/src/main/java/com/sluv/api/user/service/UserService.java b/sluv-api/src/main/java/com/sluv/api/user/service/UserService.java new file mode 100644 index 00000000..8ebedabf --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/user/service/UserService.java @@ -0,0 +1,260 @@ +package com.sluv.api.user.service; + +import com.sluv.api.closet.dto.response.ClosetResponse; +import com.sluv.api.comment.dto.reponse.CommentSimpleResponse; +import com.sluv.api.common.response.PaginationCountResponse; +import com.sluv.api.common.response.PaginationResponse; +import com.sluv.api.item.helper.ItemHelper; +import com.sluv.api.item.service.ItemCacheService; +import com.sluv.api.item.service.TempItemService; +import com.sluv.api.question.mapper.QuestionDtoMapper; +import com.sluv.api.user.dto.*; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.closet.service.ClosetDomainService; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.enums.CommentStatus; +import com.sluv.domain.comment.service.CommentDomainService; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.enums.ItemStatus; +import com.sluv.domain.item.service.ItemDomainService; +import com.sluv.domain.item.service.ItemImgDomainService; +import com.sluv.domain.item.service.ItemScrapDomainService; +import com.sluv.domain.question.dto.QuestionSimpleResDto; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.question.service.QuestionDomainService; +import com.sluv.domain.user.dto.UserSearchInfoDto; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.enums.UserStatus; +import com.sluv.domain.user.exception.UserNicknameDuplicatedException; +import com.sluv.domain.user.service.FollowDomainService; +import com.sluv.domain.user.service.UserDomainService; +import com.sluv.domain.user.service.UserWithdrawDomainService; +import com.sluv.infra.discord.WebHookService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Objects; + + +@Service +@Slf4j +@Transactional +@RequiredArgsConstructor +public class UserService { + private final UserDomainService userDomainService; + private final FollowDomainService followDomainService; + private final ItemDomainService itemDomainService; + private final QuestionDomainService questionDomainService; + private final CommentDomainService commentDomainService; + private final ItemImgDomainService itemImgDomainService; + private final ItemScrapDomainService itemScrapDomainService; + private final ClosetDomainService closetDomainService; + private final UserWithdrawDomainService userWithdrawDomainService; + + private final ItemHelper itemHelper; + private final QuestionDtoMapper questionDtoMapper; + private final ItemCacheService itemCacheService; + private final WebHookService webHookService; + private final UserWithdrawDataService userWithdrawDataService; + private final TempItemService tempItemService; + + @Transactional + public void postUserProfile(Long userId, UserProfileReqDto dto) { + User currentUser = userDomainService.findById(userId); + itemCacheService.deleteAllItemCacheByUserId(userId); + // 닉네임 중복 검사 + Boolean nicknameExistsStatus = userDomainService.existsByNickname(dto.getNickName()); + if (nicknameExistsStatus) { + throw new UserNicknameDuplicatedException(); + } + + currentUser.changeNickname(dto.getNickName()); + currentUser.changeProfileImgUrl(dto.getImgUrl()); + + if (currentUser.getUserStatus().equals(UserStatus.PENDING_PROFILE)) { + currentUser.changeUserStatus(UserStatus.PENDING_CELEB); + } + } + + @Transactional(readOnly = true) + public UserMypageResDto getUserMypage(Long userId, Long targetId) { + User targetUser; + Long itemCount = null; + List imgList = null; + Long communityCount = null; + + User user = userDomainService.findById(userId); + + if (targetId == null) { // 현재 유저일때 + targetUser = user; + + Long questionNum = questionDomainService.countByUserIdAndQuestionStatus(targetUser.getId(), + QuestionStatus.ACTIVE); + Long commentNum = commentDomainService.countCommentByUserIdInActiveQuestion(targetUser.getId(), + CommentStatus.ACTIVE); + + communityCount = questionNum + commentNum; + + imgList = itemDomainService.getRecentTop2Item(targetUser).stream() + .map(item -> itemImgDomainService.findMainImg(item.getId()).getItemImgUrl()).toList(); + + itemCount = itemDomainService.countByUserIdAndItemStatus(targetUser.getId(), ItemStatus.ACTIVE); + + } else { // 특정 유저일때 + targetUser = userDomainService.findById(targetId); + } + + Boolean followStatus = followDomainService.getFollowStatus(user, targetUser.getId()); + Long followerCount = followDomainService.getFollowerCount(targetUser); + Long followingCount = followDomainService.getFollowingCount(targetUser); + + return UserMypageResDto.of(targetUser, followStatus, followerCount, followingCount, itemCount, imgList, + communityCount); + } + + @Transactional(readOnly = true) + public PaginationResponse getUserItem(Long userId, Long targetId, Pageable pageable) { + User user = userDomainService.findById(userId); + Page itemPage = itemDomainService.getUserAllItem(targetId, pageable); + + List content = itemPage.stream() + .map(item -> itemHelper.convertItemToSimpleResDto(item, user)) + .toList(); + + return PaginationResponse.create(itemPage, content); + } + + @Transactional(readOnly = true) + public PaginationResponse getUserCloset(Long userId, Long targetId, Pageable pageable) { + Page closetPage; + User user = userDomainService.findById(userId); + + // User 일치 여부에 따라 조회하는 Public Closet만 조회할지 결정 + if (user.getId().equals(targetId)) { + closetPage = closetDomainService.getUserAllCloset(targetId, pageable); + } else { + closetPage = closetDomainService.getUserAllPublicCloset(targetId, pageable); + } + + List content = closetPage.stream() + .map(closet -> ClosetResponse.of(closet, itemScrapDomainService.countByClosetId(closet.getId()))) + .toList(); + + return PaginationResponse.create(closetPage, content); + } + + public void patchUserProfileImg(Long userId, UserProfileImgReqDto dto) { + User user = userDomainService.findById(userId); + log.info("User Profile Img Change. User: {}", user.getId()); + log.info("Change URL: {}", dto.getImgUrl()); + user.changeProfileImgUrl(dto.getImgUrl()); + userDomainService.saveUser(user); + } + + public void deleteUserProfileImg(Long userId) { + User user = userDomainService.findById(userId); + log.info("User Profile Img Delete. User: {}", user.getId()); + user.changeProfileImgUrl(null); + userDomainService.saveUser(user); + } + + /** + * 현재 유저가 업로드한 아이템 조회 + */ + @Transactional(readOnly = true) + public PaginationCountResponse getUserUploadItem(Long userId, Pageable pageable) { + User user = userDomainService.findById(userId); + // 현재 유저가 업로드한 아이템 조회 + Page itemPage = itemDomainService.getUserAllItem(user.getId(), pageable); + // content 제작 + List content = itemPage.stream() + .map(item -> itemHelper.convertItemToSimpleResDto(item, user)).toList(); + + return new PaginationCountResponse<>(itemPage.hasNext(), itemPage.getNumber(), content, + itemPage.getTotalElements()); + } + + /** + * 현재 유저가 업로그한 Question 조회 + */ + @Transactional(readOnly = true) + public PaginationCountResponse getUserUploadQuestion(Long userId, Pageable pageable) { + User user = userDomainService.findById(userId); + Page questionPage = questionDomainService.getUserAllQuestion(user, pageable); + + List content = questionPage.stream() + .map(questionDtoMapper::dtoBuildByQuestionType) + .toList(); + + return new PaginationCountResponse<>(questionPage.hasNext(), questionPage.getNumber(), content, + questionPage.getTotalElements()); + } + + /** + * 현재 유저가 업로그한 Comment 조회 + */ + @Transactional(readOnly = true) + public PaginationCountResponse getUserUploadComment(Long userId, Pageable pageable) { + User user = userDomainService.findById(userId); + Page commentPage = commentDomainService.getUserAllComment(user, pageable); + + List content = commentPage.stream().map(CommentSimpleResponse::of).toList(); + + return new PaginationCountResponse<>(commentPage.hasNext(), commentPage.getNumber(), content, + commentPage.getTotalElements()); + } + + @Transactional(readOnly = true) + public List getHotSluver(Long userId, Long celebId) { + User user = userDomainService.findByIdOrNull(userId); + List userList = userDomainService.getHotSluver(celebId); + + return userList.stream() + .map(hotSluver -> { + boolean isMine = user != null && Objects.equals(hotSluver.getId(), user.getId()); + Boolean followStatus = followDomainService.getFollowStatus(user, hotSluver.getId()); + return UserSearchInfoDto.of(hotSluver, followStatus, isMine); + }).toList(); + } + + public UserTermsResDto postTerms(Long userId) { + User user = userDomainService.findById(userId); + user.changeTermStatus(!user.getTermsStatus()); + userDomainService.saveUser(user); + return UserTermsResDto.of(user); + } + + public void withdrawUser(Long userId, UserWithdrawReqDto dto) { + User user = userDomainService.findById(userId); + user.changeUserStatus(UserStatus.DELETED); + userDomainService.saveUser(user); + + userWithdrawDataService.withdrawItemByUserId(user.getId()); + userWithdrawDataService.withdrawQuestionByUserId(user.getId()); + userWithdrawDataService.withdrawFollowByUserId(user.getId()); + userWithdrawDataService.withdrawCelebByUserId(user.getId()); + userWithdrawDataService.withdrawUserByUserId(user.getId()); + + userWithdrawDomainService.saveUserWithdraw(user, dto.getReason(), dto.getContent()); + webHookService.sendWithdrawMessage(user); + + } + + public UserSocialDto getUserSocialData(Long userId) { + User user = userDomainService.findById(userId); + return UserSocialDto.of(user); + } + + public UserTermsResDto findUserTermsStatus(Long userId) { + User user = userDomainService.findById(userId); + return UserTermsResDto.of(user); + } + +} diff --git a/sluv-api/src/main/java/com/sluv/api/user/service/UserWithdrawDataService.java b/sluv-api/src/main/java/com/sluv/api/user/service/UserWithdrawDataService.java new file mode 100644 index 00000000..a485942d --- /dev/null +++ b/sluv-api/src/main/java/com/sluv/api/user/service/UserWithdrawDataService.java @@ -0,0 +1,55 @@ +package com.sluv.api.user.service; + +import com.sluv.api.item.service.TempItemService; +import com.sluv.domain.celeb.service.InterestedCelebDomainService; +import com.sluv.domain.item.service.RecentItemDomainService; +import com.sluv.domain.question.service.RecentQuestionDomainService; +import com.sluv.domain.user.service.FollowDomainService; +import com.sluv.domain.user.service.UserReportStackDomainService; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class UserWithdrawDataService { + private final UserReportStackDomainService userReportStackDomainService; + private final RecentItemDomainService recentItemDomainService; + private final TempItemService tempItemService; + private final RecentQuestionDomainService recentQuestionDomainService; + private final FollowDomainService followDomainService; + private final InterestedCelebDomainService interestedCelebDomainService; + + @Async + @Transactional + public void withdrawItemByUserId(Long userId) { + recentItemDomainService.deleteAllByUserId(userId); + tempItemService.deleteAllTempItem(userId); + } + + @Async + @Transactional + public void withdrawQuestionByUserId(Long userId) { + recentQuestionDomainService.deleteAllByUserId(userId); + } + + @Async + @Transactional + public void withdrawFollowByUserId(Long userId) { + followDomainService.deleteFolloweeByUserId(userId); + followDomainService.deleteFollowerByUserId(userId); + } + + @Async + @Transactional + public void withdrawCelebByUserId(Long userId) { + interestedCelebDomainService.deleteAllByUserId(userId); + } + + @Async + @Transactional + public void withdrawUserByUserId(Long userId) { + userReportStackDomainService.deleteAllByReportedId(userId); + } +} \ No newline at end of file diff --git a/sluv-api/src/main/resources/application.yml b/sluv-api/src/main/resources/application.yml new file mode 100644 index 00000000..a1de6bb1 --- /dev/null +++ b/sluv-api/src/main/resources/application.yml @@ -0,0 +1,38 @@ +spring: + application: + name: api + profiles: + include: + - domain + - common + - infra + active: dev + + security: + user: + name: user + password: 1234 +--- +spring: + config: + activate: + on-profile: prod + +--- +spring: + config: + activate: + on-profile: dev + +--- +spring: + config: + activate: + on-profile: local + +--- +spring: + config: + activate: + on-profile: test + diff --git a/sluv-api/src/main/resources/banner.txt b/sluv-api/src/main/resources/banner.txt new file mode 100644 index 00000000..8ff52204 --- /dev/null +++ b/sluv-api/src/main/resources/banner.txt @@ -0,0 +1,6 @@ + ____ _ _ _ + / ___|| |_ ___ __ / \ _ __ (_) + \___ \| | | | \ \ / /____ / _ \ | '_ \| | + ___) | | |_| |\ V /_____/ ___ \| |_) | | + |____/|_|\__,_| \_/ /_/ \_\ .__/|_| + |_| \ No newline at end of file diff --git a/sluv-api/src/test/java/com/sluv/api/ApiApplicationTests.java b/sluv-api/src/test/java/com/sluv/api/ApiApplicationTests.java new file mode 100644 index 00000000..a2abd8b3 --- /dev/null +++ b/sluv-api/src/test/java/com/sluv/api/ApiApplicationTests.java @@ -0,0 +1,14 @@ +package com.sluv.api; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +//@ActiveProfiles(value = "test") +class ApiApplicationTests { + + @Test + void contextLoads() { + } + +} \ No newline at end of file diff --git a/src/test/java/com/sluv/server/domain/brand/repository/BrandRepositoryTest.java b/sluv-api/src/test/java/com/sluv/api/domain/brand/repository/BrandRepositoryTest.java similarity index 100% rename from src/test/java/com/sluv/server/domain/brand/repository/BrandRepositoryTest.java rename to sluv-api/src/test/java/com/sluv/api/domain/brand/repository/BrandRepositoryTest.java diff --git a/src/test/java/com/sluv/server/domain/brand/service/BrandServiceTest.java b/sluv-api/src/test/java/com/sluv/api/domain/brand/service/BrandServiceTest.java similarity index 100% rename from src/test/java/com/sluv/server/domain/brand/service/BrandServiceTest.java rename to sluv-api/src/test/java/com/sluv/api/domain/brand/service/BrandServiceTest.java diff --git a/src/test/java/com/sluv/server/domain/brand/service/NewBrandServiceTest.java b/sluv-api/src/test/java/com/sluv/api/domain/brand/service/NewBrandServiceTest.java similarity index 100% rename from src/test/java/com/sluv/server/domain/brand/service/NewBrandServiceTest.java rename to sluv-api/src/test/java/com/sluv/api/domain/brand/service/NewBrandServiceTest.java diff --git a/src/test/java/com/sluv/server/domain/brand/service/RecentSelectBrandServiceTest.java b/sluv-api/src/test/java/com/sluv/api/domain/brand/service/RecentSelectBrandServiceTest.java similarity index 100% rename from src/test/java/com/sluv/server/domain/brand/service/RecentSelectBrandServiceTest.java rename to sluv-api/src/test/java/com/sluv/api/domain/brand/service/RecentSelectBrandServiceTest.java diff --git a/src/test/java/com/sluv/server/domain/closet/service/ClosetServiceTest.java b/sluv-api/src/test/java/com/sluv/api/domain/closet/service/ClosetServiceTest.java similarity index 100% rename from src/test/java/com/sluv/server/domain/closet/service/ClosetServiceTest.java rename to sluv-api/src/test/java/com/sluv/api/domain/closet/service/ClosetServiceTest.java diff --git a/src/test/java/com/sluv/server/domain/item/service/HashtagServiceTest.java b/sluv-api/src/test/java/com/sluv/api/domain/item/service/HashtagServiceTest.java similarity index 100% rename from src/test/java/com/sluv/server/domain/item/service/HashtagServiceTest.java rename to sluv-api/src/test/java/com/sluv/api/domain/item/service/HashtagServiceTest.java diff --git a/src/test/java/com/sluv/server/domain/item/service/ItemCategoryServiceTest.java b/sluv-api/src/test/java/com/sluv/api/domain/item/service/ItemCategoryServiceTest.java similarity index 100% rename from src/test/java/com/sluv/server/domain/item/service/ItemCategoryServiceTest.java rename to sluv-api/src/test/java/com/sluv/api/domain/item/service/ItemCategoryServiceTest.java diff --git a/src/test/java/com/sluv/server/domain/item/service/ItemServiceTest.java b/sluv-api/src/test/java/com/sluv/api/domain/item/service/ItemServiceTest.java similarity index 100% rename from src/test/java/com/sluv/server/domain/item/service/ItemServiceTest.java rename to sluv-api/src/test/java/com/sluv/api/domain/item/service/ItemServiceTest.java diff --git a/src/test/java/com/sluv/server/domain/notice/service/NoticeServiceTest.java b/sluv-api/src/test/java/com/sluv/api/domain/notice/service/NoticeServiceTest.java similarity index 100% rename from src/test/java/com/sluv/server/domain/notice/service/NoticeServiceTest.java rename to sluv-api/src/test/java/com/sluv/api/domain/notice/service/NoticeServiceTest.java diff --git a/src/test/java/com/sluv/server/domain/user/service/FollowServiceTest.java b/sluv-api/src/test/java/com/sluv/api/domain/user/service/FollowServiceTest.java similarity index 100% rename from src/test/java/com/sluv/server/domain/user/service/FollowServiceTest.java rename to sluv-api/src/test/java/com/sluv/api/domain/user/service/FollowServiceTest.java diff --git a/src/test/java/com/sluv/server/domain/user/service/UserReportServiceTest.java b/sluv-api/src/test/java/com/sluv/api/domain/user/service/UserReportServiceTest.java similarity index 100% rename from src/test/java/com/sluv/server/domain/user/service/UserReportServiceTest.java rename to sluv-api/src/test/java/com/sluv/api/domain/user/service/UserReportServiceTest.java diff --git a/src/test/java/com/sluv/server/fixture/BrandFixture.java b/sluv-api/src/test/java/com/sluv/api/fixture/BrandFixture.java similarity index 73% rename from src/test/java/com/sluv/server/fixture/BrandFixture.java rename to sluv-api/src/test/java/com/sluv/api/fixture/BrandFixture.java index 22b743fc..098a97ec 100644 --- a/src/test/java/com/sluv/server/fixture/BrandFixture.java +++ b/sluv-api/src/test/java/com/sluv/api/fixture/BrandFixture.java @@ -1,6 +1,6 @@ -package com.sluv.server.fixture; +package com.sluv.api.fixture; -import com.sluv.server.domain.brand.entity.Brand; +import com.sluv.domain.brand.entity.Brand; public class BrandFixture { diff --git a/src/test/java/com/sluv/server/fixture/CelebFixture.java b/sluv-api/src/test/java/com/sluv/api/fixture/CelebFixture.java similarity index 72% rename from src/test/java/com/sluv/server/fixture/CelebFixture.java rename to sluv-api/src/test/java/com/sluv/api/fixture/CelebFixture.java index 9f487a46..e8534320 100644 --- a/src/test/java/com/sluv/server/fixture/CelebFixture.java +++ b/sluv-api/src/test/java/com/sluv/api/fixture/CelebFixture.java @@ -1,11 +1,11 @@ -package com.sluv.server.fixture; +package com.sluv.api.fixture; -import static com.sluv.server.domain.celeb.enums.CelebStatus.ACTIVE; +import static com.sluv.domain.celeb.enums.CelebStatus.ACTIVE; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.CelebCategory; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.celeb.enums.NewCelebStatus; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.CelebCategory; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.celeb.enums.NewCelebStatus; public class CelebFixture { diff --git a/sluv-api/src/test/java/com/sluv/api/fixture/ClosetFixture.java b/sluv-api/src/test/java/com/sluv/api/fixture/ClosetFixture.java new file mode 100644 index 00000000..3c7710c2 --- /dev/null +++ b/sluv-api/src/test/java/com/sluv/api/fixture/ClosetFixture.java @@ -0,0 +1,25 @@ +package com.sluv.api.fixture; + +import static com.sluv.domain.closet.enums.ClosetStatus.PRIVATE; +import static com.sluv.domain.closet.enums.ClosetStatus.PUBLIC; + +import com.sluv.api.closet.dto.request.ClosetRequest; +import com.sluv.api.closet.mapper.ClosetMapper; +import com.sluv.domain.closet.dto.ClosetDomainDto; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.user.entity.User; + +public class ClosetFixture { + + public static Closet 공개_옷장_생성(User user, String name) { + ClosetRequest closetRequest = new ClosetRequest(name, null, PUBLIC, null); + ClosetDomainDto closetDomainDto = ClosetMapper.toClosetDomainDto(closetRequest); + return Closet.toEntity(user, closetDomainDto); + } + + public static Closet 비공개_옷장_생성(User user, String name) { + ClosetRequest closetRequest = new ClosetRequest(name, null, PRIVATE, null); + ClosetDomainDto closetDomainDto = ClosetMapper.toClosetDomainDto(closetRequest); + return Closet.toEntity(user, closetDomainDto); + } +} diff --git a/src/test/java/com/sluv/server/fixture/ItemFixture.java b/sluv-api/src/test/java/com/sluv/api/fixture/ItemFixture.java similarity index 72% rename from src/test/java/com/sluv/server/fixture/ItemFixture.java rename to sluv-api/src/test/java/com/sluv/api/fixture/ItemFixture.java index 11d54b67..c35500d3 100644 --- a/src/test/java/com/sluv/server/fixture/ItemFixture.java +++ b/sluv-api/src/test/java/com/sluv/api/fixture/ItemFixture.java @@ -1,14 +1,14 @@ -package com.sluv.server.fixture; +package com.sluv.api.fixture; -import static com.sluv.server.domain.item.enums.ItemStatus.ACTIVE; +import static com.sluv.domain.item.enums.ItemStatus.ACTIVE; -import com.sluv.server.domain.brand.entity.Brand; -import com.sluv.server.domain.brand.entity.NewBrand; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.ItemCategory; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.brand.entity.Brand; +import com.sluv.domain.brand.entity.NewBrand; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemCategory; +import com.sluv.domain.user.entity.User; import java.time.LocalDateTime; public class ItemFixture { diff --git a/src/test/java/com/sluv/server/fixture/NoticeFixture.java b/sluv-api/src/test/java/com/sluv/api/fixture/NoticeFixture.java similarity index 57% rename from src/test/java/com/sluv/server/fixture/NoticeFixture.java rename to sluv-api/src/test/java/com/sluv/api/fixture/NoticeFixture.java index 715843aa..91c895f7 100644 --- a/src/test/java/com/sluv/server/fixture/NoticeFixture.java +++ b/sluv-api/src/test/java/com/sluv/api/fixture/NoticeFixture.java @@ -1,9 +1,9 @@ -package com.sluv.server.fixture; +package com.sluv.api.fixture; -import static com.sluv.server.domain.notice.enums.NoticeStatus.ACTIVE; -import static com.sluv.server.domain.notice.enums.NoticeType.ETC; +import static com.sluv.domain.notice.enums.NoticeStatus.ACTIVE; +import static com.sluv.domain.notice.enums.NoticeType.ETC; -import com.sluv.server.domain.notice.entity.Notice; +import com.sluv.domain.notice.entity.Notice; public class NoticeFixture { diff --git a/src/test/java/com/sluv/server/fixture/UserFixture.java b/sluv-api/src/test/java/com/sluv/api/fixture/UserFixture.java similarity index 81% rename from src/test/java/com/sluv/server/fixture/UserFixture.java rename to sluv-api/src/test/java/com/sluv/api/fixture/UserFixture.java index f6a9e7bf..3592ae28 100644 --- a/src/test/java/com/sluv/server/fixture/UserFixture.java +++ b/sluv-api/src/test/java/com/sluv/api/fixture/UserFixture.java @@ -1,10 +1,10 @@ -package com.sluv.server.fixture; +package com.sluv.api.fixture; -import com.sluv.server.domain.auth.dto.SocialUserInfoDto; -import com.sluv.server.domain.auth.enums.SnsType; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.enums.UserAge; -import com.sluv.server.domain.user.enums.UserGender; +import com.sluv.domain.auth.dto.SocialUserInfoDto; +import com.sluv.domain.auth.enums.SnsType; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.enums.UserAge; +import com.sluv.domain.user.enums.UserGender; public class UserFixture { diff --git a/sluv-batch/Dockerfile b/sluv-batch/Dockerfile new file mode 100644 index 00000000..b8b5bd34 --- /dev/null +++ b/sluv-batch/Dockerfile @@ -0,0 +1,4 @@ +FROM eclipse-temurin:17-jdk +ARG JAR_FILE_PATH=build/libs/*.jar +COPY ${JAR_FILE_PATH} app.jar +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/sluv-batch/build.gradle b/sluv-batch/build.gradle new file mode 100644 index 00000000..3fd8e3d8 --- /dev/null +++ b/sluv-batch/build.gradle @@ -0,0 +1,24 @@ +plugins { + id 'java' +} + +group 'com.sluv' +version 'unspecified' + +repositories { + mavenCentral() +} + +bootJar.enabled = true + +jar.enabled = false + +dependencies { + implementation project(':sluv-domain') + implementation project(':sluv-common') + implementation project(':sluv-infra') +} + +tasks.named('test') { + dependsOn ':sluv-domain:test', ':sluv-common:test', ':sluv-infra:test' +} diff --git a/src/main/java/com/sluv/server/SluvServerApplication.java b/sluv-batch/src/main/java/com/sluv/batch/BatchApplication.java similarity index 77% rename from src/main/java/com/sluv/server/SluvServerApplication.java rename to sluv-batch/src/main/java/com/sluv/batch/BatchApplication.java index 9957ded1..84e69418 100644 --- a/src/main/java/com/sluv/server/SluvServerApplication.java +++ b/sluv-batch/src/main/java/com/sluv/batch/BatchApplication.java @@ -1,4 +1,4 @@ -package com.sluv.server; +package com.sluv.batch; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -10,10 +10,10 @@ @EnableJpaAuditing @EnableScheduling @EnableCaching -public class SluvServerApplication { +public class BatchApplication { public static void main(String[] args) { - SpringApplication.run(SluvServerApplication.class, args); + SpringApplication.run(BatchApplication.class, args); } } \ No newline at end of file diff --git a/sluv-batch/src/main/java/com/sluv/batch/config/ComponentConfig.java b/sluv-batch/src/main/java/com/sluv/batch/config/ComponentConfig.java new file mode 100644 index 00000000..f754e623 --- /dev/null +++ b/sluv-batch/src/main/java/com/sluv/batch/config/ComponentConfig.java @@ -0,0 +1,9 @@ +package com.sluv.batch.config; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackages = {"com.sluv.domain", "com.sluv.common", "com.sluv.infra"}) +public class ComponentConfig { +} diff --git a/src/main/java/com/sluv/server/domain/item/scheduler/ItemScheduler.java b/sluv-batch/src/main/java/com/sluv/batch/item/ItemScheduler.java similarity index 54% rename from src/main/java/com/sluv/server/domain/item/scheduler/ItemScheduler.java rename to sluv-batch/src/main/java/com/sluv/batch/item/ItemScheduler.java index 5f040f4c..77df42e3 100644 --- a/src/main/java/com/sluv/server/domain/item/scheduler/ItemScheduler.java +++ b/sluv-batch/src/main/java/com/sluv/batch/item/ItemScheduler.java @@ -1,36 +1,27 @@ -package com.sluv.server.domain.item.scheduler; - -import com.sluv.server.domain.item.entity.DayHotItem; -import com.sluv.server.domain.item.entity.EfficientItem; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.LuxuryItem; -import com.sluv.server.domain.item.entity.WeekHotItem; -import com.sluv.server.domain.item.repository.DayHotItemRepository; -import com.sluv.server.domain.item.repository.EfficientItemRepository; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.item.repository.LuxuryItemRepository; -import com.sluv.server.domain.item.repository.WeekHotItemRepository; -import java.util.Calendar; -import java.util.Collections; -import java.util.List; -import java.util.Random; +package com.sluv.batch.item; + +import com.sluv.domain.item.entity.*; +import com.sluv.domain.item.service.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; + +import java.util.Calendar; +import java.util.Collections; +import java.util.List; +import java.util.Random; @Component @Slf4j -@Transactional @RequiredArgsConstructor public class ItemScheduler { - private final LuxuryItemRepository luxuryItemRepository; - private final EfficientItemRepository efficientItemRepository; - private final WeekHotItemRepository weekHotItemRepository; - private final DayHotItemRepository dayHotItemRepository; - private final ItemRepository itemRepository; + private final LuxuryItemDomainService luxuryItemDomainService; + private final EfficientItemDomainService efficientItemDomainService; + private final WeekHotItemDomainService weekHotItemDomainService; + private final DayHotItemDomainService dayHotItemDomainService; + private final ItemDomainService itemDomainService; /** * 럭셔리 아이템 업데이트 @@ -40,15 +31,15 @@ public void updateLuxuryItem() { log.info("LuxuryItem Update Time: {}", Calendar.getInstance().getTime()); log.info("Delete Old LuxuryItem Data"); - luxuryItemRepository.deleteAll(); + luxuryItemDomainService.deleteAllLuxuryItem(); log.info("Get LuxuryItem. Time: {}", Calendar.getInstance().getTime()); - List newLuxuryItem = itemRepository.updateLuxuryItem(); + List newLuxuryItem = itemDomainService.getItemByOverPrice(500000); Collections.shuffle(newLuxuryItem, new Random()); log.info("Save LuxuryItem. Time: {}", Calendar.getInstance().getTime()); - newLuxuryItem.subList(0, 10).forEach(item -> luxuryItemRepository.save(LuxuryItem.toEntity(item))); + newLuxuryItem.subList(0, 10).forEach(item -> luxuryItemDomainService.save(LuxuryItem.toEntity(item))); } /** @@ -59,15 +50,15 @@ public void updateEfficientItem() { log.info("EfficientItem Update Time: {}", Calendar.getInstance().getTime()); log.info("Delete Old EfficientItem Data"); - efficientItemRepository.deleteAll(); + efficientItemDomainService.deleteAllEfficientItem(); log.info("Get EfficientItem. Time: {}", Calendar.getInstance().getTime()); - List newEfficientItem = itemRepository.updateEfficientItem(); + List newEfficientItem = itemDomainService.getItemByUnderPrice(100000); Collections.shuffle(newEfficientItem, new Random()); log.info("Save EfficientItem. Time: {}", Calendar.getInstance().getTime()); - newEfficientItem.subList(0, 10).forEach(item -> efficientItemRepository.save(EfficientItem.toEntity(item))); + newEfficientItem.subList(0, 10).forEach(item -> efficientItemDomainService.save(EfficientItem.toEntity(item))); } /** @@ -78,18 +69,14 @@ public void updateWeekHotItem() { log.info("WeekHotItem Update Time: {}", Calendar.getInstance().getTime()); log.info("Delete Old WeekHotItem Data"); - weekHotItemRepository.deleteAll(); + weekHotItemDomainService.deleteAllWeekHotItem(); log.info("Get WeekHotItem. Time: {}", Calendar.getInstance().getTime()); - List newWeekHotItem = itemRepository.updateWeekHotItem(); + List newWeekHotItem = itemDomainService.getPreviousWeekHotItem(); log.info("Save WeekHotItem. Time: {}", Calendar.getInstance().getTime()); - newWeekHotItem.forEach(item -> - weekHotItemRepository.save( - WeekHotItem.toEntity(item) - ) - ); + newWeekHotItem.forEach(item -> weekHotItemDomainService.save(WeekHotItem.toEntity(item))); } /** @@ -100,17 +87,13 @@ public void updateDayHotItem() { log.info("DayHotItem Update Time: {}", Calendar.getInstance().getTime()); log.info("Delete Old DayHotItem Data"); - dayHotItemRepository.deleteAll(); + dayHotItemDomainService.deleteAllDayHotItem(); log.info("Get DayHotItem. Time: {}", Calendar.getInstance().getTime()); - List newDayHotItem = itemRepository.updateDayHotItem(); + List newDayHotItem = itemDomainService.getYesterdayHotItem(); log.info("Save DayHotItem. Time: {}", Calendar.getInstance().getTime()); - newDayHotItem.forEach(item -> - dayHotItemRepository.save( - DayHotItem.toEntity(item) - ) - ); + newDayHotItem.forEach(item -> dayHotItemDomainService.save(DayHotItem.toEntity(item))); } } diff --git a/src/main/java/com/sluv/server/domain/question/scheduler/QuestionScheduler.java b/sluv-batch/src/main/java/com/sluv/batch/question/QuestionScheduler.java similarity index 71% rename from src/main/java/com/sluv/server/domain/question/scheduler/QuestionScheduler.java rename to sluv-batch/src/main/java/com/sluv/batch/question/QuestionScheduler.java index 24a26e77..3387330c 100644 --- a/src/main/java/com/sluv/server/domain/question/scheduler/QuestionScheduler.java +++ b/sluv-batch/src/main/java/com/sluv/batch/question/QuestionScheduler.java @@ -1,28 +1,26 @@ -package com.sluv.server.domain.question.scheduler; - -import com.sluv.server.domain.alarm.service.QuestionAlarmService; -import com.sluv.server.domain.question.entity.DailyHotQuestion; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.entity.QuestionBuy; -import com.sluv.server.domain.question.repository.DailyHotQuestionRepository; -import com.sluv.server.domain.question.repository.QuestionRepository; -import java.util.Calendar; -import java.util.List; +package com.sluv.batch.question; + +import com.sluv.domain.question.entity.DailyHotQuestion; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.QuestionBuy; +import com.sluv.domain.question.repository.DailyHotQuestionRepository; +import com.sluv.domain.question.repository.QuestionRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; + +import java.util.Calendar; +import java.util.List; @Component @Slf4j -@Transactional @RequiredArgsConstructor public class QuestionScheduler { private final DailyHotQuestionRepository dailyHotQuestionRepository; private final QuestionRepository questionRepository; - private final QuestionAlarmService questionAlarmService; +// private final QuestionAlarmService questionAlarmService; private static final int VOTE_END_CHECK_PERIOD = 60000; // 1분 @@ -56,7 +54,7 @@ public void checkQuestionVoteEnd() { log.info("QuestionVoteEnd Check Time: {}", Calendar.getInstance().getTime()); List endTimeBetweenNow = questionRepository.getEndTimeBetweenNow(VOTE_END_CHECK_PERIOD); endTimeBetweenNow.forEach(questionBuy -> System.out.println("dd: " + questionBuy.getId())); - endTimeBetweenNow.forEach(questionBuy -> questionAlarmService.sendAlarmAboutQuestionVote(questionBuy.getId())); +// endTimeBetweenNow.forEach(questionBuy -> questionAlarmService.sendAlarmAboutQuestionVote(questionBuy.getId())); } diff --git a/sluv-batch/src/main/java/com/sluv/batch/search/SearchScheduler.java b/sluv-batch/src/main/java/com/sluv/batch/search/SearchScheduler.java new file mode 100644 index 00000000..c5c16bb0 --- /dev/null +++ b/sluv-batch/src/main/java/com/sluv/batch/search/SearchScheduler.java @@ -0,0 +1,38 @@ +package com.sluv.batch.search; + +import com.sluv.domain.search.entity.SearchRank; +import com.sluv.domain.search.service.SearchDataDomainService; +import com.sluv.domain.search.service.SearchRankDomainService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.Calendar; +import java.util.List; + +@Component +@Slf4j +@RequiredArgsConstructor +public class SearchScheduler { + + private final SearchDataDomainService searchDataDomainService; + private final SearchRankDomainService searchRankDomainService; + + /** + * SearchRank 업데이트 + */ + @Scheduled(cron = "0 0 17 * * *") // 초 분 시 일 월 요일 + public void updateSearchRank() { + log.info("SearchRank Update Time: {}", Calendar.getInstance().getTime()); + + log.info("Delete Old SearchRank Data"); + searchRankDomainService.deleteAllSearchRank(); + + log.info("Get SearchData. Time: {}", Calendar.getInstance().getTime()); + List result = searchDataDomainService.getTopData(); + + log.info("Save SearchRank. Time: {}", Calendar.getInstance().getTime()); + searchRankDomainService.saveAllSearchRank(result); + } +} diff --git a/src/main/java/com/sluv/server/domain/user/scheduler/UserScheduler.java b/sluv-batch/src/main/java/com/sluv/batch/user/UserScheduler.java similarity index 85% rename from src/main/java/com/sluv/server/domain/user/scheduler/UserScheduler.java rename to sluv-batch/src/main/java/com/sluv/batch/user/UserScheduler.java index 6bd69a09..5d8c6fa0 100644 --- a/src/main/java/com/sluv/server/domain/user/scheduler/UserScheduler.java +++ b/sluv-batch/src/main/java/com/sluv/batch/user/UserScheduler.java @@ -1,15 +1,16 @@ -package com.sluv.server.domain.user.scheduler; +package com.sluv.batch.user; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.repository.UserRepository; -import java.util.Calendar; -import java.util.List; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; +import java.util.Calendar; +import java.util.List; + @Component @Slf4j @RequiredArgsConstructor diff --git a/src/main/java/com/sluv/server/domain/visit/scheduler/VisitScheduler.java b/sluv-batch/src/main/java/com/sluv/batch/visit/VisitScheduler.java similarity index 64% rename from src/main/java/com/sluv/server/domain/visit/scheduler/VisitScheduler.java rename to sluv-batch/src/main/java/com/sluv/batch/visit/VisitScheduler.java index 54eb5ee6..c8f1e66c 100644 --- a/src/main/java/com/sluv/server/domain/visit/scheduler/VisitScheduler.java +++ b/sluv-batch/src/main/java/com/sluv/batch/visit/VisitScheduler.java @@ -1,21 +1,19 @@ -package com.sluv.server.domain.visit.scheduler; +package com.sluv.batch.visit; -import com.sluv.server.domain.visit.entity.VisitHistory; -import com.sluv.server.domain.visit.repository.VisitHistoryRepository; -import com.sluv.server.global.cache.CacheService; -import java.time.LocalDateTime; +import com.sluv.domain.visit.service.VisitHistoryDomainService; +import com.sluv.infra.cache.CacheService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; @Component @Slf4j -@Transactional @RequiredArgsConstructor public class VisitScheduler { - private final VisitHistoryRepository visitHistoryRepository; + private final VisitHistoryDomainService visitHistoryDomainService; private final CacheService cacheService; /** @@ -29,7 +27,7 @@ public void updateDailyVisitantCount() { log.info("Save RecentDailyVisit. Time: {}", LocalDateTime.now()); - visitHistoryRepository.save(VisitHistory.of(now.minusDays(1), visitantCount)); + visitHistoryDomainService.saveVisitHistory(now.minusDays(1), visitantCount); cacheService.clearVisitantCount(); } diff --git a/sluv-batch/src/main/resources/application.yml b/sluv-batch/src/main/resources/application.yml new file mode 100644 index 00000000..9c18b472 --- /dev/null +++ b/sluv-batch/src/main/resources/application.yml @@ -0,0 +1,38 @@ +spring: + application: + name: batch + profiles: + include: + - domain + - common + - infra + active: dev + + security: + user: + name: user + password: 1234 +--- +spring: + config: + activate: + on-profile: prod + +--- +spring: + config: + activate: + on-profile: dev + +--- +spring: + config: + activate: + on-profile: local + +--- +spring: + config: + activate: + on-profile: test + diff --git a/sluv-batch/src/main/resources/banner.txt b/sluv-batch/src/main/resources/banner.txt new file mode 100644 index 00000000..59779554 --- /dev/null +++ b/sluv-batch/src/main/resources/banner.txt @@ -0,0 +1,5 @@ + ____ _ ____ _ _ + / ___|| |_ ___ __ | __ ) __ _| |_ ___| |__ + \___ \| | | | \ \ / /____| _ \ / _` | __/ __| '_ \ + ___) | | |_| |\ V /_____| |_) | (_| | || (__| | | | + |____/|_|\__,_| \_/ |____/ \__,_|\__\___|_| |_| \ No newline at end of file diff --git a/sluv-batch/src/test/java/com/sluv/batch/BatchApplicationTests.java b/sluv-batch/src/test/java/com/sluv/batch/BatchApplicationTests.java new file mode 100644 index 00000000..92006398 --- /dev/null +++ b/sluv-batch/src/test/java/com/sluv/batch/BatchApplicationTests.java @@ -0,0 +1,13 @@ +package com.sluv.batch; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class BatchApplicationTests { + + @Test + void contextLoads() { + } + +} \ No newline at end of file diff --git a/sluv-common/build.gradle b/sluv-common/build.gradle new file mode 100644 index 00000000..f0a61262 --- /dev/null +++ b/sluv-common/build.gradle @@ -0,0 +1,12 @@ +dependencies { + + // JWT + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' + implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' + implementation 'com.nimbusds:nimbus-jose-jwt:9.30.2' + + // Jasypt + implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5' + +} diff --git a/sluv-common/src/main/java/com/sluv/common/annotation/CurrentUserId.java b/sluv-common/src/main/java/com/sluv/common/annotation/CurrentUserId.java new file mode 100644 index 00000000..05937e9e --- /dev/null +++ b/sluv-common/src/main/java/com/sluv/common/annotation/CurrentUserId.java @@ -0,0 +1,9 @@ +package com.sluv.common.annotation; + +import java.lang.annotation.*; + +@Target({ElementType.PARAMETER, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface CurrentUserId { +} diff --git a/src/main/java/com/sluv/server/global/config/security/JasyptConfig.java b/sluv-common/src/main/java/com/sluv/common/config/JasyptConfig.java similarity index 86% rename from src/main/java/com/sluv/server/global/config/security/JasyptConfig.java rename to sluv-common/src/main/java/com/sluv/common/config/JasyptConfig.java index 316e8e56..f5e8e1ba 100644 --- a/src/main/java/com/sluv/server/global/config/security/JasyptConfig.java +++ b/sluv-common/src/main/java/com/sluv/common/config/JasyptConfig.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.config.security; +package com.sluv.common.config; import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties; import lombok.extern.slf4j.Slf4j; @@ -12,16 +12,18 @@ @Slf4j @EnableEncryptableProperties @Configuration +//@Import(EnableEncryptablePropertiesConfiguration.class) public class JasyptConfig { @Value("${jasypt.encryptor.password}") private String encryptKey; - @Bean(name = "jasyptStringEncryptor") + @Bean//(name = "jasyptStringEncryptor") public StringEncryptor stringEncryptor() { PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor(); SimpleStringPBEConfig config = new SimpleStringPBEConfig(); +// config.setPassword(encryptKey); // 암호화할 때 사용하는 키 config.setPassword(encryptKey); // 암호화할 때 사용하는 키 config.setAlgorithm("PBEWithMD5AndDES"); // 암호화 알고리즘 config.setKeyObtentionIterations("1000"); // 해싱 반복 횟수 diff --git a/sluv-common/src/main/java/com/sluv/common/constant/ConstantData.java b/sluv-common/src/main/java/com/sluv/common/constant/ConstantData.java new file mode 100644 index 00000000..c6bab048 --- /dev/null +++ b/sluv-common/src/main/java/com/sluv/common/constant/ConstantData.java @@ -0,0 +1,7 @@ +package com.sluv.common.constant; + +public class ConstantData { + public static final String TOKEN_TYPER = "Bearer"; + public static final String ACCESS_TOKEN_HEADER = "Authorization"; + public static final String ALARM_TITLE = "스럽"; +} diff --git a/sluv-common/src/main/java/com/sluv/common/exception/ApplicationException.java b/sluv-common/src/main/java/com/sluv/common/exception/ApplicationException.java new file mode 100644 index 00000000..79ca32be --- /dev/null +++ b/sluv-common/src/main/java/com/sluv/common/exception/ApplicationException.java @@ -0,0 +1,17 @@ +package com.sluv.common.exception; + +import lombok.Getter; + + +@Getter +public abstract class ApplicationException extends RuntimeException { + + private final int errorCode; + private final HttpStatusCode httpStatusCode; + + protected ApplicationException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(message); + this.errorCode = errorCode; + this.httpStatusCode = httpStatusCode; + } +} diff --git a/src/main/java/com/sluv/server/global/common/exception/ErrorCode.java b/sluv-common/src/main/java/com/sluv/common/exception/ErrorCode.java similarity index 90% rename from src/main/java/com/sluv/server/global/common/exception/ErrorCode.java rename to sluv-common/src/main/java/com/sluv/common/exception/ErrorCode.java index c6c71f02..3d2ef319 100644 --- a/src/main/java/com/sluv/server/global/common/exception/ErrorCode.java +++ b/sluv-common/src/main/java/com/sluv/common/exception/ErrorCode.java @@ -1,4 +1,5 @@ -package com.sluv.server.global.common.exception; +package com.sluv.common.exception; + import lombok.Getter; @Getter @@ -11,6 +12,7 @@ public enum ErrorCode { private final int code; private final String message; + ErrorCode(int code, String message) { this.code = code; this.message = message; diff --git a/sluv-common/src/main/java/com/sluv/common/exception/HttpStatusCode.java b/sluv-common/src/main/java/com/sluv/common/exception/HttpStatusCode.java new file mode 100644 index 00000000..f07a79e8 --- /dev/null +++ b/sluv-common/src/main/java/com/sluv/common/exception/HttpStatusCode.java @@ -0,0 +1,17 @@ +package com.sluv.common.exception; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum HttpStatusCode { + + BAD_REQUEST(400), + UNAUTHORIZED(401), + INTERNAL_SERVER_ERROR(500); + + private final int code; + + +} diff --git a/src/main/java/com/sluv/server/global/jwt/JwtProvider.java b/sluv-common/src/main/java/com/sluv/common/jwt/JwtProvider.java similarity index 60% rename from src/main/java/com/sluv/server/global/jwt/JwtProvider.java rename to sluv-common/src/main/java/com/sluv/common/jwt/JwtProvider.java index 216b0222..e476fea4 100644 --- a/src/main/java/com/sluv/server/global/jwt/JwtProvider.java +++ b/sluv-common/src/main/java/com/sluv/common/jwt/JwtProvider.java @@ -1,38 +1,26 @@ -package com.sluv.server.global.jwt; - - -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.jwt.exception.ExpiredTokenException; -import com.sluv.server.global.jwt.exception.InvalidateTokenException; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.MalformedJwtException; -import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.UnsupportedJwtException; +package com.sluv.common.jwt; + +import com.sluv.common.jwt.exception.ExpiredTokenException; +import com.sluv.common.jwt.exception.InvalidateTokenException; +import io.jsonwebtoken.*; import io.jsonwebtoken.security.Keys; import jakarta.annotation.PostConstruct; -import jakarta.servlet.http.HttpServletRequest; -import java.nio.charset.StandardCharsets; -import java.security.Key; -import java.util.Base64; -import java.util.Date; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.security.PublicKey; +import java.util.Base64; +import java.util.Date; + @Component @RequiredArgsConstructor @Slf4j public class JwtProvider { - private final UserRepository userRepository; @Value("${jwt.secret}") private String secretKey = "secretKey"; @@ -53,24 +41,14 @@ private Key getSigninKey(String secretKey) { return Keys.hmacShaKeyFor(keyBytes); } - public Authentication getAuthentication(String _token) { - String token = _token.split(tokenType + " ")[1]; - UserDetails user = userRepository.findById(Long.valueOf(this.getUserId(token).toString())) - .orElseThrow(UserNotFoundException::new); - - return new UsernamePasswordAuthenticationToken(user, "", user.getAuthorities()); - } /** * === user Access Token 생성 === * - * @param user * @return Access Token */ - public String createAccessToken(User user) { - Long id = user.getId(); - - Claims claims = Jwts.claims().setSubject(id.toString()); + public String createAccessToken(Long userId) { + Claims claims = Jwts.claims().setSubject(userId.toString()); Date now = new Date(); return Jwts.builder() @@ -96,16 +74,6 @@ public Long getUserId(String token) { return Long.valueOf(info); } - /** - * === HttpServletRequest에서 token 추출 === - * - * @param request - * @return token - */ - public String resolveToken(HttpServletRequest request) { - return request.getHeader("Authorization"); - } - /** * === token 만료 확인 === * @@ -115,7 +83,8 @@ public String resolveToken(HttpServletRequest request) { */ public boolean validateToken(String _token) { try { - String token = _token.split(tokenType + " ")[1]; +// String token = _token.split(tokenType + " ")[1]; + String token = _token.split("Bearer" + " ")[1]; Jwts.parserBuilder().setSigningKey(secretKey.getBytes()).build() .parseClaimsJws(token); return true; @@ -134,4 +103,12 @@ public boolean validateToken(String _token) { return false; } + + public Boolean checkClaimsJwsBodyIsNull(PublicKey publicKey, String identityToken) { + JwtParser parser = Jwts.parserBuilder() + .setSigningKey(publicKey) + .build(); + + return parser.parseClaimsJws(identityToken).getBody() == null; + } } diff --git a/src/main/java/com/sluv/server/global/jwt/exception/ExpiredTokenException.java b/sluv-common/src/main/java/com/sluv/common/jwt/exception/ExpiredTokenException.java similarity index 62% rename from src/main/java/com/sluv/server/global/jwt/exception/ExpiredTokenException.java rename to sluv-common/src/main/java/com/sluv/common/jwt/exception/ExpiredTokenException.java index 20df49f8..25e882b9 100644 --- a/src/main/java/com/sluv/server/global/jwt/exception/ExpiredTokenException.java +++ b/sluv-common/src/main/java/com/sluv/common/jwt/exception/ExpiredTokenException.java @@ -1,12 +1,12 @@ -package com.sluv.server.global.jwt.exception; +package com.sluv.common.jwt.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class ExpiredTokenException extends TokenException { private static final int ERROR_CODE = 4002; private static final String MESSAGE = "만료된 토큰입니다."; - private static final HttpStatus STATUS = HttpStatus.UNAUTHORIZED; + private static final HttpStatusCode STATUS = HttpStatusCode.UNAUTHORIZED; public ExpiredTokenException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/sluv-common/src/main/java/com/sluv/common/jwt/exception/HttpStatusCode.java b/sluv-common/src/main/java/com/sluv/common/jwt/exception/HttpStatusCode.java new file mode 100644 index 00000000..f5c1f4ee --- /dev/null +++ b/sluv-common/src/main/java/com/sluv/common/jwt/exception/HttpStatusCode.java @@ -0,0 +1,16 @@ +package com.sluv.common.jwt.exception; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum HttpStatusCode { + + BAD_REQUEST(400), + UNAUTHORIZED(401); + + private final int code; + + +} diff --git a/src/main/java/com/sluv/server/global/jwt/exception/InvalidateTokenException.java b/sluv-common/src/main/java/com/sluv/common/jwt/exception/InvalidateTokenException.java similarity index 62% rename from src/main/java/com/sluv/server/global/jwt/exception/InvalidateTokenException.java rename to sluv-common/src/main/java/com/sluv/common/jwt/exception/InvalidateTokenException.java index 696f1720..95cbdd03 100644 --- a/src/main/java/com/sluv/server/global/jwt/exception/InvalidateTokenException.java +++ b/sluv-common/src/main/java/com/sluv/common/jwt/exception/InvalidateTokenException.java @@ -1,12 +1,12 @@ -package com.sluv.server.global.jwt.exception; +package com.sluv.common.jwt.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class InvalidateTokenException extends TokenException { private static final int ERROR_CODE = 4001; private static final String MESSAGE = "잘못된 토큰입니다."; - private static final HttpStatus STATUS = HttpStatus.UNAUTHORIZED; + private static final HttpStatusCode STATUS = HttpStatusCode.UNAUTHORIZED; public InvalidateTokenException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/global/jwt/exception/NoAuthorizationTokenException.java b/sluv-common/src/main/java/com/sluv/common/jwt/exception/NoAuthorizationTokenException.java similarity index 63% rename from src/main/java/com/sluv/server/global/jwt/exception/NoAuthorizationTokenException.java rename to sluv-common/src/main/java/com/sluv/common/jwt/exception/NoAuthorizationTokenException.java index 29f265db..1bd18994 100644 --- a/src/main/java/com/sluv/server/global/jwt/exception/NoAuthorizationTokenException.java +++ b/sluv-common/src/main/java/com/sluv/common/jwt/exception/NoAuthorizationTokenException.java @@ -1,12 +1,12 @@ -package com.sluv.server.global.jwt.exception; +package com.sluv.common.jwt.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class NoAuthorizationTokenException extends TokenException { private static final int ERROR_CODE = 4000; private static final String MESSAGE = "토큰이 비어있습니다."; - private static final HttpStatus STATUS = HttpStatus.UNAUTHORIZED; + private static final HttpStatusCode STATUS = HttpStatusCode.UNAUTHORIZED; public NoAuthorizationTokenException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/sluv-common/src/main/java/com/sluv/common/jwt/exception/TokenException.java b/sluv-common/src/main/java/com/sluv/common/jwt/exception/TokenException.java new file mode 100644 index 00000000..d427bc8f --- /dev/null +++ b/sluv-common/src/main/java/com/sluv/common/jwt/exception/TokenException.java @@ -0,0 +1,10 @@ +package com.sluv.common.jwt.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class TokenException extends ApplicationException { + public TokenException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/sluv-common/src/main/resources/application-common.yml b/sluv-common/src/main/resources/application-common.yml new file mode 100644 index 00000000..2e0f613d --- /dev/null +++ b/sluv-common/src/main/resources/application-common.yml @@ -0,0 +1,36 @@ +spring: + application: + name: common + config: + import: optional:classpath:env/.env[.properties] + +jasypt: + encryptor: + bean: ${JASYPT_ENCRYPTOR_BEAN} + password: ${JASYPT_ENCRYPTOR_PASSWORD} + +jwt: + secret: ${JWT_SECRET} + expiration-seconds: ${JWT_EXPIRATION_SECONDS} + type: ${JWT_TYPE} + header: ${JWT_HEADER} + +--- +spring: + config: + activate: + on-profile: prod + +logging: + level: + org.hibernate.SQL: info + +--- +spring: + config: + activate: + on-profile: dev + +logging: + level: + org.hibernate.SQL: debug diff --git a/sluv-common/src/test/java/com/sluv/common/TestConfiguration.java b/sluv-common/src/test/java/com/sluv/common/TestConfiguration.java new file mode 100644 index 00000000..5765447d --- /dev/null +++ b/sluv-common/src/test/java/com/sluv/common/TestConfiguration.java @@ -0,0 +1,7 @@ +package com.sluv.common; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class TestConfiguration { +} diff --git a/sluv-domain/build.gradle b/sluv-domain/build.gradle new file mode 100644 index 00000000..227ab204 --- /dev/null +++ b/sluv-domain/build.gradle @@ -0,0 +1,39 @@ +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +dependencies { + + api 'org.springframework.boot:spring-boot-starter-data-jpa' + + // QueryDSL + implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' + annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta' + annotationProcessor 'jakarta.annotation:jakarta.annotation-api' + annotationProcessor 'jakarta.persistence:jakarta.persistence-api' + + //swagger + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.3' + + runtimeOnly 'com.mysql:mysql-connector-j' + + implementation project(':sluv-common') + +} + +// QueryDsl +def querydslDir = layout.buildDirectory.dir("generated/querydsl").get().asFile + +sourceSets { + main.java.srcDirs += [querydslDir] +} + +tasks.withType(JavaCompile) { + options.getGeneratedSourceOutputDirectory().set(file(querydslDir)) +} + +clean.doLast { + file(querydslDir).deleteDir() +} diff --git a/src/main/java/com/sluv/server/domain/admin/entity/Admin.java b/sluv-domain/src/main/java/com/sluv/domain/admin/entity/Admin.java similarity index 89% rename from src/main/java/com/sluv/server/domain/admin/entity/Admin.java rename to sluv-domain/src/main/java/com/sluv/domain/admin/entity/Admin.java index 7fb41a5d..24f353ee 100644 --- a/src/main/java/com/sluv/server/domain/admin/entity/Admin.java +++ b/sluv-domain/src/main/java/com/sluv/domain/admin/entity/Admin.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.admin.entity; +package com.sluv.domain.admin.entity; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/sluv-domain/src/main/java/com/sluv/domain/admin/exception/AdminException.java b/sluv-domain/src/main/java/com/sluv/domain/admin/exception/AdminException.java new file mode 100644 index 00000000..82bc7d9b --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/admin/exception/AdminException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.admin.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class AdminException extends ApplicationException { + public AdminException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/domain/admin/exception/AdminNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/admin/exception/AdminNotFoundException.java similarity index 62% rename from src/main/java/com/sluv/server/domain/admin/exception/AdminNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/admin/exception/AdminNotFoundException.java index d4c6851b..af486ceb 100644 --- a/src/main/java/com/sluv/server/domain/admin/exception/AdminNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/admin/exception/AdminNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.admin.exception; +package com.sluv.domain.admin.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class AdminNotFoundException extends AdminException { private static final int ERROR_CODE = 2026; private static final String MESSAGE = "존재하지 않는 Admin입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public AdminNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/admin/exception/AdminPasswordNotMatchException.java b/sluv-domain/src/main/java/com/sluv/domain/admin/exception/AdminPasswordNotMatchException.java similarity index 65% rename from src/main/java/com/sluv/server/domain/admin/exception/AdminPasswordNotMatchException.java rename to sluv-domain/src/main/java/com/sluv/domain/admin/exception/AdminPasswordNotMatchException.java index 17201bff..07dd3ecb 100644 --- a/src/main/java/com/sluv/server/domain/admin/exception/AdminPasswordNotMatchException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/admin/exception/AdminPasswordNotMatchException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.admin.exception; +package com.sluv.domain.admin.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class AdminPasswordNotMatchException extends AdminException { private static final int ERROR_CODE = 2027; private static final String MESSAGE = "Admin 비밀번호가 일치하지 않습니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public AdminPasswordNotMatchException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/admin/repository/AdminRepository.java b/sluv-domain/src/main/java/com/sluv/domain/admin/repository/AdminRepository.java similarity index 67% rename from src/main/java/com/sluv/server/domain/admin/repository/AdminRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/admin/repository/AdminRepository.java index 6c43d6d5..582ea8c7 100644 --- a/src/main/java/com/sluv/server/domain/admin/repository/AdminRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/admin/repository/AdminRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.admin.repository; +package com.sluv.domain.admin.repository; -import com.sluv.server.domain.admin.entity.Admin; +import com.sluv.domain.admin.entity.Admin; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/sluv-domain/src/main/java/com/sluv/domain/admin/service/AdminDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/admin/service/AdminDomainService.java new file mode 100644 index 00000000..7572eac0 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/admin/service/AdminDomainService.java @@ -0,0 +1,41 @@ +package com.sluv.domain.admin.service; + +//import com.sluv.common.jwt.JwtProvider; + +import com.sluv.domain.admin.entity.Admin; +import com.sluv.domain.admin.exception.AdminNotFoundException; +import com.sluv.domain.admin.exception.AdminPasswordNotMatchException; +import com.sluv.domain.admin.repository.AdminRepository; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.exception.UserNotFoundException; +import com.sluv.domain.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class AdminDomainService { + + private final AdminRepository adminRepository; + private final UserRepository userRepository; + +// private final JwtProvider jwtProvider; + + @Transactional(readOnly = true) + public String getAdminPasswordByEmail(String email) { + Admin admin = adminRepository.findByEmail(email).orElseThrow(AdminNotFoundException::new); + return admin.getPwd(); + } + + @Transactional(readOnly = true) + public String getUserTokenByAdmin(boolean isMatched, Long userId) { + if (!isMatched) { + throw new AdminPasswordNotMatchException(); + } + User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); +// return jwtProvider.createAccessToken(user.getId()); + return null; + } + +} diff --git a/src/main/java/com/sluv/server/domain/alarm/dto/AlarmElement.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/dto/AlarmElement.java similarity index 70% rename from src/main/java/com/sluv/server/domain/alarm/dto/AlarmElement.java rename to sluv-domain/src/main/java/com/sluv/domain/alarm/dto/AlarmElement.java index e2be5933..b537850a 100644 --- a/src/main/java/com/sluv/server/domain/alarm/dto/AlarmElement.java +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/dto/AlarmElement.java @@ -1,9 +1,9 @@ -package com.sluv.server.domain.alarm.dto; +package com.sluv.domain.alarm.dto; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.user.entity.User; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/com/sluv/server/domain/alarm/dto/AlarmImages.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/dto/AlarmImages.java similarity index 53% rename from src/main/java/com/sluv/server/domain/alarm/dto/AlarmImages.java rename to sluv-domain/src/main/java/com/sluv/domain/alarm/dto/AlarmImages.java index e7b52252..d34c0c6d 100644 --- a/src/main/java/com/sluv/server/domain/alarm/dto/AlarmImages.java +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/dto/AlarmImages.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.alarm.dto; +package com.sluv.domain.alarm.dto; -import com.sluv.server.domain.question.dto.QuestionImgSimpleResDto; +import com.sluv.domain.question.dto.QuestionImgSimpleDto; import java.util.List; import lombok.Builder; import lombok.Getter; @@ -9,11 +9,11 @@ @Builder public class AlarmImages { - private List images; + private List images; private String userImageUrl; - public static AlarmImages of(List images, String userImageUrl) { + public static AlarmImages of(List images, String userImageUrl) { return AlarmImages.builder() .images(images) .userImageUrl(userImageUrl) diff --git a/src/main/java/com/sluv/server/domain/alarm/entity/Alarm.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/entity/Alarm.java similarity index 78% rename from src/main/java/com/sluv/server/domain/alarm/entity/Alarm.java rename to sluv-domain/src/main/java/com/sluv/domain/alarm/entity/Alarm.java index 32d66ec2..bfe713cd 100644 --- a/src/main/java/com/sluv/server/domain/alarm/entity/Alarm.java +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/entity/Alarm.java @@ -1,15 +1,13 @@ -package com.sluv.server.domain.alarm.entity; - -import static com.sluv.server.domain.alarm.enums.AlarmStatus.ACTIVE; - -import com.sluv.server.domain.alarm.dto.AlarmElement; -import com.sluv.server.domain.alarm.enums.AlarmStatus; -import com.sluv.server.domain.alarm.enums.AlarmType; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +package com.sluv.domain.alarm.entity; + +import com.sluv.domain.alarm.dto.AlarmElement; +import com.sluv.domain.alarm.enums.AlarmStatus; +import com.sluv.domain.alarm.enums.AlarmType; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -77,7 +75,7 @@ public static Alarm toEntity(User user, String title, String body, AlarmType ala .question(alarmElement.getQuestion()) .comment(alarmElement.getComment()) .sender(alarmElement.getUser()) - .alarmStatus(ACTIVE) + .alarmStatus(AlarmStatus.ACTIVE) .build(); } diff --git a/src/main/java/com/sluv/server/domain/alarm/enums/AlarmMessage.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/enums/AlarmMessage.java similarity index 96% rename from src/main/java/com/sluv/server/domain/alarm/enums/AlarmMessage.java rename to sluv-domain/src/main/java/com/sluv/domain/alarm/enums/AlarmMessage.java index dba9152b..a6e8682c 100644 --- a/src/main/java/com/sluv/server/domain/alarm/enums/AlarmMessage.java +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/enums/AlarmMessage.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.alarm.enums; +package com.sluv.domain.alarm.enums; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/com/sluv/server/domain/alarm/enums/AlarmStatus.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/enums/AlarmStatus.java similarity index 58% rename from src/main/java/com/sluv/server/domain/alarm/enums/AlarmStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/alarm/enums/AlarmStatus.java index 9efe6be6..8bcea37d 100644 --- a/src/main/java/com/sluv/server/domain/alarm/enums/AlarmStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/enums/AlarmStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.alarm.enums; +package com.sluv.domain.alarm.enums; public enum AlarmStatus { ACTIVE, diff --git a/src/main/java/com/sluv/server/domain/alarm/enums/AlarmType.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/enums/AlarmType.java similarity index 88% rename from src/main/java/com/sluv/server/domain/alarm/enums/AlarmType.java rename to sluv-domain/src/main/java/com/sluv/domain/alarm/enums/AlarmType.java index 0d84aabc..e5a5ff37 100644 --- a/src/main/java/com/sluv/server/domain/alarm/enums/AlarmType.java +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/enums/AlarmType.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.alarm.enums; +package com.sluv.domain.alarm.enums; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/com/sluv/server/domain/alarm/exception/AlarmAccessDeniedException.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/exception/AlarmAccessDeniedException.java similarity index 64% rename from src/main/java/com/sluv/server/domain/alarm/exception/AlarmAccessDeniedException.java rename to sluv-domain/src/main/java/com/sluv/domain/alarm/exception/AlarmAccessDeniedException.java index 8d8752d3..ea29fe76 100644 --- a/src/main/java/com/sluv/server/domain/alarm/exception/AlarmAccessDeniedException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/exception/AlarmAccessDeniedException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.alarm.exception; +package com.sluv.domain.alarm.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class AlarmAccessDeniedException extends AlarmException { private static final int ERROR_CODE = 7001; private static final String MESSAGE = "알람의 사용자와 일치하지 않습니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public AlarmAccessDeniedException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/sluv-domain/src/main/java/com/sluv/domain/alarm/exception/AlarmException.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/exception/AlarmException.java new file mode 100644 index 00000000..25349f9d --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/exception/AlarmException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.alarm.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class AlarmException extends ApplicationException { + public AlarmException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/domain/alarm/exception/AlarmNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/exception/AlarmNotFoundException.java similarity index 62% rename from src/main/java/com/sluv/server/domain/alarm/exception/AlarmNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/alarm/exception/AlarmNotFoundException.java index a3aa96a1..23bb2fed 100644 --- a/src/main/java/com/sluv/server/domain/alarm/exception/AlarmNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/exception/AlarmNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.alarm.exception; +package com.sluv.domain.alarm.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class AlarmNotFoundException extends AlarmException { private static final int ERROR_CODE = 7000; private static final String MESSAGE = "존재하지 않는 알람입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public AlarmNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/alarm/repository/AlarmRepository.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/repository/AlarmRepository.java similarity index 53% rename from src/main/java/com/sluv/server/domain/alarm/repository/AlarmRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/alarm/repository/AlarmRepository.java index d1314957..c8b25592 100644 --- a/src/main/java/com/sluv/server/domain/alarm/repository/AlarmRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/repository/AlarmRepository.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.alarm.repository; +package com.sluv.domain.alarm.repository; -import com.sluv.server.domain.alarm.entity.Alarm; -import com.sluv.server.domain.alarm.repository.impl.AlarmRepositoryCustom; +import com.sluv.domain.alarm.entity.Alarm; +import com.sluv.domain.alarm.repository.impl.AlarmRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; public interface AlarmRepository extends JpaRepository, AlarmRepositoryCustom { diff --git a/src/main/java/com/sluv/server/domain/alarm/repository/impl/AlarmRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/repository/impl/AlarmRepositoryCustom.java similarity index 66% rename from src/main/java/com/sluv/server/domain/alarm/repository/impl/AlarmRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/alarm/repository/impl/AlarmRepositoryCustom.java index 545b5b82..4ce07db4 100644 --- a/src/main/java/com/sluv/server/domain/alarm/repository/impl/AlarmRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/repository/impl/AlarmRepositoryCustom.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.alarm.repository.impl; +package com.sluv.domain.alarm.repository.impl; -import com.sluv.server.domain.alarm.entity.Alarm; +import com.sluv.domain.alarm.entity.Alarm; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/sluv/server/domain/alarm/repository/impl/AlarmRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/repository/impl/AlarmRepositoryImpl.java similarity index 79% rename from src/main/java/com/sluv/server/domain/alarm/repository/impl/AlarmRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/alarm/repository/impl/AlarmRepositoryImpl.java index eae46e1d..a5554b76 100644 --- a/src/main/java/com/sluv/server/domain/alarm/repository/impl/AlarmRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/repository/impl/AlarmRepositoryImpl.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.alarm.repository.impl; +package com.sluv.domain.alarm.repository.impl; -import static com.sluv.server.domain.alarm.entity.QAlarm.alarm; -import static com.sluv.server.domain.alarm.enums.AlarmStatus.DELETED; +import static com.sluv.domain.alarm.entity.QAlarm.alarm; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.alarm.entity.Alarm; +import com.sluv.domain.alarm.entity.Alarm; +import com.sluv.domain.alarm.enums.AlarmStatus; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; @@ -20,13 +20,13 @@ public class AlarmRepositoryImpl implements AlarmRepositoryCustom { @Override public Page findAllByUserId(Long userId, Pageable pageable) { List fetch = jpaQueryFactory.selectFrom(alarm) - .where(alarm.user.id.eq(userId).and(alarm.alarmStatus.ne(DELETED))) + .where(alarm.user.id.eq(userId).and(alarm.alarmStatus.ne(AlarmStatus.DELETED))) .orderBy(alarm.createdAt.desc()) .fetch(); // Count Query JPAQuery countQuery = jpaQueryFactory.selectFrom(alarm) - .where(alarm.user.id.eq(userId).and(alarm.alarmStatus.ne(DELETED))) + .where(alarm.user.id.eq(userId).and(alarm.alarmStatus.ne(AlarmStatus.DELETED))) .orderBy(alarm.createdAt.desc()); return PageableExecutionUtils.getPage(fetch, pageable, () -> countQuery.stream().count()); diff --git a/sluv-domain/src/main/java/com/sluv/domain/alarm/service/AlarmDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/alarm/service/AlarmDomainService.java new file mode 100644 index 00000000..61c8fc2e --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/alarm/service/AlarmDomainService.java @@ -0,0 +1,69 @@ +package com.sluv.domain.alarm.service; + +import com.sluv.domain.alarm.dto.AlarmElement; +import com.sluv.domain.alarm.entity.Alarm; +import com.sluv.domain.alarm.enums.AlarmStatus; +import com.sluv.domain.alarm.enums.AlarmType; +import com.sluv.domain.alarm.exception.AlarmAccessDeniedException; +import com.sluv.domain.alarm.exception.AlarmNotFoundException; +import com.sluv.domain.alarm.repository.AlarmRepository; +import com.sluv.domain.user.entity.User; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class AlarmDomainService { + + private final AlarmRepository alarmRepository; + + @Transactional + public void saveAlarm(User user, String title, String body, AlarmType alarmType, AlarmElement alarmElement) { + alarmRepository.save(Alarm.toEntity(user, title, body, alarmType, alarmElement)); + } + + @Transactional + public void saveAllAlarm(List users, String title, String body, AlarmType alarmType, + AlarmElement alarmElement) { + + List alarms = new ArrayList<>(); + for (User user : users) { + alarms.add(Alarm.toEntity(user, title, body, alarmType, alarmElement)); + } + alarmRepository.saveAll(alarms); + } + + @Transactional + public void deleteAlarm(Long userId, Long alarmId) { + Alarm alarm = alarmRepository.findById(alarmId).orElseThrow(AlarmNotFoundException::new); + if (!alarm.getUser().getId().equals(userId)) { + throw new AlarmAccessDeniedException(); + } + alarmRepository.deleteById(alarmId); + } + + @Transactional + public void deleteAllAlarm(Long userId) { + alarmRepository.deleteAllByUserId(userId); + } + + @Transactional + public void patchAlarmStatusToRead(Long userId, Long alarmId) { + Alarm alarm = alarmRepository.findById(alarmId).orElseThrow(AlarmNotFoundException::new); + if (Objects.equals(alarm.getUser().getId(), userId)) { + alarm.changeStatus(AlarmStatus.READ); + } + } + + @Transactional(readOnly = true) + public Page findAllByUserId(Long userId, Pageable pageable) { + return alarmRepository.findAllByUserId(userId, pageable); + } + +} diff --git a/src/main/java/com/sluv/server/domain/auth/dto/SocialUserInfoDto.java b/sluv-domain/src/main/java/com/sluv/domain/auth/dto/SocialUserInfoDto.java similarity index 54% rename from src/main/java/com/sluv/server/domain/auth/dto/SocialUserInfoDto.java rename to sluv-domain/src/main/java/com/sluv/domain/auth/dto/SocialUserInfoDto.java index 6050c4f6..0db7207d 100644 --- a/src/main/java/com/sluv/server/domain/auth/dto/SocialUserInfoDto.java +++ b/sluv-domain/src/main/java/com/sluv/domain/auth/dto/SocialUserInfoDto.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.auth.dto; +package com.sluv.domain.auth.dto; -import com.sluv.server.domain.user.enums.UserAge; -import com.sluv.server.domain.user.enums.UserGender; -import io.swagger.v3.oas.annotations.media.Schema; +import com.sluv.domain.user.enums.UserAge; +import com.sluv.domain.user.enums.UserGender; import lombok.Builder; import lombok.Data; import lombok.Getter; @@ -10,13 +9,9 @@ @Data @Getter public class SocialUserInfoDto { - @Schema(description = "사용자의 Email") private String email; - @Schema(description = "사용자의 프로필 사진 URL") private String profileImgUrl; - @Schema(description = "사용자의 연령대") private UserAge ageRange; - @Schema(description = "사용자의 성별") private UserGender gender; @Builder @@ -26,4 +21,5 @@ public SocialUserInfoDto(String email, String profileImgUrl, UserAge ageRange, U this.ageRange = ageRange; this.gender = gender; } + } diff --git a/src/main/java/com/sluv/server/domain/auth/enums/SnsType.java b/sluv-domain/src/main/java/com/sluv/domain/auth/enums/SnsType.java similarity index 78% rename from src/main/java/com/sluv/server/domain/auth/enums/SnsType.java rename to sluv-domain/src/main/java/com/sluv/domain/auth/enums/SnsType.java index a9260cc0..c0edb338 100644 --- a/src/main/java/com/sluv/server/domain/auth/enums/SnsType.java +++ b/sluv-domain/src/main/java/com/sluv/domain/auth/enums/SnsType.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.auth.enums; +package com.sluv.domain.auth.enums; -import com.sluv.server.domain.auth.exception.NoSupportSocialTypeException; +import com.sluv.domain.auth.exception.NoSupportSocialTypeException; import io.swagger.v3.oas.annotations.media.Schema; @Schema(description = "SnsType") diff --git a/sluv-domain/src/main/java/com/sluv/domain/auth/exception/AuthException.java b/sluv-domain/src/main/java/com/sluv/domain/auth/exception/AuthException.java new file mode 100644 index 00000000..42eb2352 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/auth/exception/AuthException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.auth.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class AuthException extends ApplicationException { + public AuthException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/domain/auth/exception/NoSupportSocialTypeException.java b/sluv-domain/src/main/java/com/sluv/domain/auth/exception/NoSupportSocialTypeException.java similarity index 64% rename from src/main/java/com/sluv/server/domain/auth/exception/NoSupportSocialTypeException.java rename to sluv-domain/src/main/java/com/sluv/domain/auth/exception/NoSupportSocialTypeException.java index d49545a8..4c02c03f 100644 --- a/src/main/java/com/sluv/server/domain/auth/exception/NoSupportSocialTypeException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/auth/exception/NoSupportSocialTypeException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.auth.exception; +package com.sluv.domain.auth.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class NoSupportSocialTypeException extends AuthException { private static final int ERROR_CODE = 2001; private static final String MESSAGE = "지원하지 않는 SnsType입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public NoSupportSocialTypeException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/auth/exception/UserBlockedException.java b/sluv-domain/src/main/java/com/sluv/domain/auth/exception/UserBlockedException.java similarity index 61% rename from src/main/java/com/sluv/server/domain/auth/exception/UserBlockedException.java rename to sluv-domain/src/main/java/com/sluv/domain/auth/exception/UserBlockedException.java index 1ad31ddf..1242f5dd 100644 --- a/src/main/java/com/sluv/server/domain/auth/exception/UserBlockedException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/auth/exception/UserBlockedException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.auth.exception; +package com.sluv.domain.auth.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class UserBlockedException extends AuthException { private static final int ERROR_CODE = 2023; private static final String MESSAGE = "정지된 유저입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public UserBlockedException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/brand/entity/Brand.java b/sluv-domain/src/main/java/com/sluv/domain/brand/entity/Brand.java similarity index 61% rename from src/main/java/com/sluv/server/domain/brand/entity/Brand.java rename to sluv-domain/src/main/java/com/sluv/domain/brand/entity/Brand.java index a52ec821..2cb56091 100644 --- a/src/main/java/com/sluv/server/domain/brand/entity/Brand.java +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/entity/Brand.java @@ -1,7 +1,12 @@ -package com.sluv.server.domain.brand.entity; - -import com.sluv.server.global.common.entity.BaseEntity; -import jakarta.persistence.*; +package com.sluv.domain.brand.entity; + +import com.sluv.domain.common.entity.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; @@ -18,7 +23,8 @@ @Table(name = "brand") public class Brand extends BaseEntity { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "brand_id") private Long id; diff --git a/src/main/java/com/sluv/server/domain/brand/entity/NewBrand.java b/sluv-domain/src/main/java/com/sluv/domain/brand/entity/NewBrand.java similarity index 55% rename from src/main/java/com/sluv/server/domain/brand/entity/NewBrand.java rename to sluv-domain/src/main/java/com/sluv/domain/brand/entity/NewBrand.java index 7ba4fbf3..b7787a38 100644 --- a/src/main/java/com/sluv/server/domain/brand/entity/NewBrand.java +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/entity/NewBrand.java @@ -1,11 +1,15 @@ -package com.sluv.server.domain.brand.entity; +package com.sluv.domain.brand.entity; -import com.sluv.server.domain.brand.dto.NewBrandPostReqDto; -import com.sluv.server.domain.brand.enums.NewBrandStatus; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.enums.ItemStatus; -import com.sluv.server.global.common.entity.BaseEntity; -import jakarta.persistence.*; +import com.sluv.domain.brand.enums.NewBrandStatus; +import com.sluv.domain.common.entity.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; @@ -13,9 +17,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import java.util.ArrayList; -import java.util.List; - @Entity @Getter @NoArgsConstructor @@ -24,7 +25,8 @@ @Table(name = "new_brand") public class NewBrand extends BaseEntity { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "new_brand_id") private Long id; @@ -36,9 +38,9 @@ public class NewBrand extends BaseEntity { @Column(length = 45, columnDefinition = "varchar(45) default 'ACTIVE'") private NewBrandStatus newBrandStatus; - public static NewBrand toEntity(NewBrandPostReqDto newBrandPostReqDto){ + public static NewBrand toEntity(String newBrandName) { return NewBrand.builder() - .brandName(newBrandPostReqDto.getNewBrandName()) + .brandName(newBrandName) .newBrandStatus(NewBrandStatus.ACTIVE) .build(); } diff --git a/src/main/java/com/sluv/server/domain/brand/entity/RecentSelectBrand.java b/sluv-domain/src/main/java/com/sluv/domain/brand/entity/RecentSelectBrand.java similarity index 62% rename from src/main/java/com/sluv/server/domain/brand/entity/RecentSelectBrand.java rename to sluv-domain/src/main/java/com/sluv/domain/brand/entity/RecentSelectBrand.java index 9e8c82e1..e6007260 100644 --- a/src/main/java/com/sluv/server/domain/brand/entity/RecentSelectBrand.java +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/entity/RecentSelectBrand.java @@ -1,8 +1,16 @@ -package com.sluv.server.domain.brand.entity; +package com.sluv.domain.brand.entity; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; -import jakarta.persistence.*; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.entity.User; +import jakarta.persistence.Column; +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.Table; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; @@ -17,7 +25,8 @@ @Table(name = "recent_select_brand") public class RecentSelectBrand extends BaseEntity { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "recent_select_brand_id") private Long id; @@ -34,7 +43,7 @@ public class RecentSelectBrand extends BaseEntity { @NotNull private User user; - public static RecentSelectBrand toEntity(Brand brand, NewBrand newBrand, User user){ + public static RecentSelectBrand toEntity(Brand brand, NewBrand newBrand, User user) { return RecentSelectBrand.builder() .brand(brand) .newBrand(newBrand) diff --git a/src/main/java/com/sluv/server/domain/brand/enums/NewBrandStatus.java b/sluv-domain/src/main/java/com/sluv/domain/brand/enums/NewBrandStatus.java similarity index 61% rename from src/main/java/com/sluv/server/domain/brand/enums/NewBrandStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/brand/enums/NewBrandStatus.java index dbcc790e..8e729a3e 100644 --- a/src/main/java/com/sluv/server/domain/brand/enums/NewBrandStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/enums/NewBrandStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.brand.enums; +package com.sluv.domain.brand.enums; public enum NewBrandStatus { ACTIVE, diff --git a/sluv-domain/src/main/java/com/sluv/domain/brand/exception/BrandException.java b/sluv-domain/src/main/java/com/sluv/domain/brand/exception/BrandException.java new file mode 100644 index 00000000..9003691b --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/exception/BrandException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.brand.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class BrandException extends ApplicationException { + public BrandException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/domain/brand/exception/BrandNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/brand/exception/BrandNotFoundException.java similarity index 63% rename from src/main/java/com/sluv/server/domain/brand/exception/BrandNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/brand/exception/BrandNotFoundException.java index 9b9d2ba6..3e2c841e 100644 --- a/src/main/java/com/sluv/server/domain/brand/exception/BrandNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/exception/BrandNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.brand.exception; +package com.sluv.domain.brand.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class BrandNotFoundException extends BrandException { private static final int ERROR_CODE = 2006; private static final String MESSAGE = "존재하지 않는 브랜드입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public BrandNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/brand/exception/NewBrandNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/brand/exception/NewBrandNotFoundException.java similarity index 64% rename from src/main/java/com/sluv/server/domain/brand/exception/NewBrandNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/brand/exception/NewBrandNotFoundException.java index 8c4f9336..3185fb72 100644 --- a/src/main/java/com/sluv/server/domain/brand/exception/NewBrandNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/exception/NewBrandNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.brand.exception; +package com.sluv.domain.brand.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class NewBrandNotFoundException extends BrandException { private static final int ERROR_CODE = 2007; private static final String MESSAGE = "존재하지 않는 New 브랜드입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public NewBrandNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/sluv-domain/src/main/java/com/sluv/domain/brand/repository/BrandRepository.java b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/BrandRepository.java new file mode 100644 index 00000000..5c7dc880 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/BrandRepository.java @@ -0,0 +1,8 @@ +package com.sluv.domain.brand.repository; + +import com.sluv.domain.brand.entity.Brand; +import com.sluv.domain.brand.repository.impl.BrandRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BrandRepository extends JpaRepository, BrandRepositoryCustom { +} diff --git a/src/main/java/com/sluv/server/domain/brand/repository/NewBrandRepository.java b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/NewBrandRepository.java similarity index 69% rename from src/main/java/com/sluv/server/domain/brand/repository/NewBrandRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/brand/repository/NewBrandRepository.java index c9e7fe41..f45e90eb 100644 --- a/src/main/java/com/sluv/server/domain/brand/repository/NewBrandRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/NewBrandRepository.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.brand.repository; - -import com.sluv.server.domain.brand.entity.NewBrand; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.brand.repository; +import com.sluv.domain.brand.entity.NewBrand; import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; public interface NewBrandRepository extends JpaRepository { Optional findByBrandName(String newBrandName); diff --git a/src/main/java/com/sluv/server/domain/brand/repository/RecentSelectBrandRepository.java b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/RecentSelectBrandRepository.java similarity index 53% rename from src/main/java/com/sluv/server/domain/brand/repository/RecentSelectBrandRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/brand/repository/RecentSelectBrandRepository.java index 7fad0c88..05c4f9b6 100644 --- a/src/main/java/com/sluv/server/domain/brand/repository/RecentSelectBrandRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/RecentSelectBrandRepository.java @@ -1,10 +1,11 @@ -package com.sluv.server.domain.brand.repository; +package com.sluv.domain.brand.repository; -import com.sluv.server.domain.brand.entity.RecentSelectBrand; -import com.sluv.server.domain.brand.repository.impl.RecentSelectBrandRepositoryCustom; +import com.sluv.domain.brand.entity.RecentSelectBrand; +import com.sluv.domain.brand.repository.impl.RecentSelectBrandRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; -public interface RecentSelectBrandRepository extends JpaRepository, RecentSelectBrandRepositoryCustom { +public interface RecentSelectBrandRepository extends JpaRepository, + RecentSelectBrandRepositoryCustom { void deleteAllByUserId(Long id); void deleteByUserIdAndBrandId(Long userId, Long brandId); diff --git a/src/main/java/com/sluv/server/domain/brand/repository/impl/BrandRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/BrandRepositoryCustom.java similarity index 76% rename from src/main/java/com/sluv/server/domain/brand/repository/impl/BrandRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/BrandRepositoryCustom.java index e8749a24..f9f8bcca 100644 --- a/src/main/java/com/sluv/server/domain/brand/repository/impl/BrandRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/BrandRepositoryCustom.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.brand.repository.impl; +package com.sluv.domain.brand.repository.impl; -import com.sluv.server.domain.brand.entity.Brand; +import com.sluv.domain.brand.entity.Brand; import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/sluv/server/domain/brand/repository/impl/BrandRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/BrandRepositoryImpl.java similarity index 88% rename from src/main/java/com/sluv/server/domain/brand/repository/impl/BrandRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/BrandRepositoryImpl.java index 86f269a2..97911f79 100644 --- a/src/main/java/com/sluv/server/domain/brand/repository/impl/BrandRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/BrandRepositoryImpl.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.brand.repository.impl; +package com.sluv.domain.brand.repository.impl; -import static com.sluv.server.domain.brand.entity.QBrand.brand; -import static com.sluv.server.domain.brand.entity.QRecentSelectBrand.recentSelectBrand; +import static com.sluv.domain.brand.entity.QBrand.brand; +import static com.sluv.domain.brand.entity.QRecentSelectBrand.recentSelectBrand; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.brand.entity.Brand; +import com.sluv.domain.brand.entity.Brand; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; diff --git a/sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/RecentSelectBrandRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/RecentSelectBrandRepositoryCustom.java new file mode 100644 index 00000000..19747573 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/RecentSelectBrandRepositoryCustom.java @@ -0,0 +1,9 @@ +package com.sluv.domain.brand.repository.impl; + +import com.sluv.domain.brand.entity.RecentSelectBrand; +import com.sluv.domain.user.entity.User; +import java.util.List; + +public interface RecentSelectBrandRepositoryCustom { + List getRecentSelectBrandTop20(User user); +} diff --git a/src/main/java/com/sluv/server/domain/brand/repository/impl/RecentSelectBrandRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/RecentSelectBrandRepositoryImpl.java similarity index 70% rename from src/main/java/com/sluv/server/domain/brand/repository/impl/RecentSelectBrandRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/RecentSelectBrandRepositoryImpl.java index abd24759..c2fadd06 100644 --- a/src/main/java/com/sluv/server/domain/brand/repository/impl/RecentSelectBrandRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/repository/impl/RecentSelectBrandRepositoryImpl.java @@ -1,12 +1,12 @@ -package com.sluv.server.domain.brand.repository.impl; +package com.sluv.domain.brand.repository.impl; -import static com.sluv.server.domain.brand.entity.QBrand.brand; -import static com.sluv.server.domain.brand.entity.QNewBrand.newBrand; -import static com.sluv.server.domain.brand.entity.QRecentSelectBrand.recentSelectBrand; +import static com.sluv.domain.brand.entity.QBrand.brand; +import static com.sluv.domain.brand.entity.QNewBrand.newBrand; +import static com.sluv.domain.brand.entity.QRecentSelectBrand.recentSelectBrand; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.brand.entity.RecentSelectBrand; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.brand.entity.RecentSelectBrand; +import com.sluv.domain.user.entity.User; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/sluv-domain/src/main/java/com/sluv/domain/brand/service/BrandDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/brand/service/BrandDomainService.java new file mode 100644 index 00000000..be3c833a --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/service/BrandDomainService.java @@ -0,0 +1,47 @@ +package com.sluv.domain.brand.service; + +import com.sluv.domain.brand.entity.Brand; +import com.sluv.domain.brand.exception.BrandNotFoundException; +import com.sluv.domain.brand.repository.BrandRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class BrandDomainService { + private final BrandRepository brandRepository; + + + @Transactional(readOnly = true) + public Page findByAllBrandKrOrBrandEnStartingWith(String brandName, Pageable pageable) { + return brandRepository.findByAllBrandKrOrBrandEnStartingWith(brandName, pageable); + } + + @Transactional(readOnly = true) + public List findTopBrand() { + return brandRepository.findTop10By(); + } + + @Transactional(readOnly = true) + public Brand findByIdOrNull(Long brandId) { + if (brandId == null) { + return null; + } + return brandRepository.findById(brandId).orElseThrow(BrandNotFoundException::new); + } + + @Transactional(readOnly = true) + public Brand findById(Long brandId) { + return brandRepository.findById(brandId).orElseThrow(BrandNotFoundException::new); + } + + @Transactional(readOnly = true) + public List getBrandContainKeyword(String keyword) { + return brandRepository.getBrandContainKeyword(keyword); + } +} + diff --git a/sluv-domain/src/main/java/com/sluv/domain/brand/service/NewBrandDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/brand/service/NewBrandDomainService.java new file mode 100644 index 00000000..59b5fcc8 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/service/NewBrandDomainService.java @@ -0,0 +1,39 @@ +package com.sluv.domain.brand.service; + +import com.sluv.domain.brand.entity.NewBrand; +import com.sluv.domain.brand.exception.NewBrandNotFoundException; +import com.sluv.domain.brand.repository.NewBrandRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class NewBrandDomainService { + + private final NewBrandRepository newBrandRepository; + + @Transactional + public NewBrand findByBrandName(String newBrandName) { + return newBrandRepository.findByBrandName(newBrandName).orElse(null); + } + + @Transactional + public NewBrand saveNewBrand(NewBrand newBrand) { + return newBrandRepository.save(newBrand); + } + + @Transactional(readOnly = true) + public NewBrand findByIdOrNull(Long newBrandId) { + if (newBrandId == null) { + return null; + } + return newBrandRepository.findById(newBrandId).orElseThrow(NewBrandNotFoundException::new); + } + + @Transactional(readOnly = true) + public NewBrand findById(Long newBrandId) { + return newBrandRepository.findById(newBrandId).orElseThrow(NewBrandNotFoundException::new); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/brand/service/RecentSelectBrandDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/brand/service/RecentSelectBrandDomainService.java new file mode 100644 index 00000000..75243241 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/brand/service/RecentSelectBrandDomainService.java @@ -0,0 +1,44 @@ +package com.sluv.domain.brand.service; + +import com.sluv.domain.brand.entity.RecentSelectBrand; +import com.sluv.domain.brand.repository.RecentSelectBrandRepository; +import com.sluv.domain.user.entity.User; +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Slf4j +@RequiredArgsConstructor +public class RecentSelectBrandDomainService { + + private final RecentSelectBrandRepository recentSelectBrandRepository; + + @Transactional + public RecentSelectBrand saveRecentSelectBrand(RecentSelectBrand recentSelectBrand) { + return recentSelectBrandRepository.save(recentSelectBrand); + } + + @Transactional + public void deleteAllByUserId(Long userId) { + recentSelectBrandRepository.deleteAllByUserId(userId); + } + + @Transactional + public void deleteByUserIdAndBrandId(Long userId, Long brandId) { + recentSelectBrandRepository.deleteByUserIdAndBrandId(userId, brandId); + } + + @Transactional + public void deleteByUserIdAndNewBrandId(Long userId, Long brandId) { + recentSelectBrandRepository.deleteByUserIdAndNewBrandId(userId, brandId); + } + + @Transactional(readOnly = true) + public List getRecentSelectBrandTop20(User user) { + return recentSelectBrandRepository.getRecentSelectBrandTop20(user); + } + +} diff --git a/src/main/java/com/sluv/server/domain/celeb/dto/CelebDto.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/dto/CelebDto.java similarity index 95% rename from src/main/java/com/sluv/server/domain/celeb/dto/CelebDto.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/dto/CelebDto.java index 97aaf94b..96070445 100644 --- a/src/main/java/com/sluv/server/domain/celeb/dto/CelebDto.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/dto/CelebDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.celeb.dto; +package com.sluv.domain.celeb.dto; -import com.sluv.server.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.Celeb; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/celeb/entity/Celeb.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/Celeb.java similarity index 93% rename from src/main/java/com/sluv/server/domain/celeb/entity/Celeb.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/entity/Celeb.java index 174e7d48..e7a9251b 100644 --- a/src/main/java/com/sluv/server/domain/celeb/entity/Celeb.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/Celeb.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.celeb.entity; +package com.sluv.domain.celeb.entity; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.sluv.server.domain.celeb.enums.CelebStatus; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.celeb.enums.CelebStatus; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; diff --git a/src/main/java/com/sluv/server/domain/celeb/entity/CelebActivity.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/CelebActivity.java similarity index 89% rename from src/main/java/com/sluv/server/domain/celeb/entity/CelebActivity.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/entity/CelebActivity.java index 5054d990..b770ecb7 100644 --- a/src/main/java/com/sluv/server/domain/celeb/entity/CelebActivity.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/CelebActivity.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.celeb.entity; +package com.sluv.domain.celeb.entity; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/celeb/entity/CelebCategory.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/CelebCategory.java similarity index 91% rename from src/main/java/com/sluv/server/domain/celeb/entity/CelebCategory.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/entity/CelebCategory.java index 3a4491bb..cc49b326 100644 --- a/src/main/java/com/sluv/server/domain/celeb/entity/CelebCategory.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/CelebCategory.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.celeb.entity; +package com.sluv.domain.celeb.entity; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/celeb/entity/InterestedCeleb.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/InterestedCeleb.java similarity index 88% rename from src/main/java/com/sluv/server/domain/celeb/entity/InterestedCeleb.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/entity/InterestedCeleb.java index e5cf61a8..c919a1c6 100644 --- a/src/main/java/com/sluv/server/domain/celeb/entity/InterestedCeleb.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/InterestedCeleb.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.celeb.entity; +package com.sluv.domain.celeb.entity; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/celeb/entity/NewCeleb.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/NewCeleb.java similarity index 76% rename from src/main/java/com/sluv/server/domain/celeb/entity/NewCeleb.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/entity/NewCeleb.java index e17579c3..d6a5ff02 100644 --- a/src/main/java/com/sluv/server/domain/celeb/entity/NewCeleb.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/NewCeleb.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.celeb.entity; +package com.sluv.domain.celeb.entity; -import com.sluv.server.domain.celeb.dto.NewCelebPostReqDto; -import com.sluv.server.domain.celeb.enums.NewCelebStatus; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.celeb.enums.NewCelebStatus; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -39,9 +38,9 @@ public class NewCeleb extends BaseEntity { @Column(length = 45, columnDefinition = "varchar(45) default 'ACTIVE'") private NewCelebStatus newCelebStatus; - public static NewCeleb toEntity(NewCelebPostReqDto dto) { + public static NewCeleb toEntity(String name) { return NewCeleb.builder() - .celebName(dto.getNewCelebName()) + .celebName(name) .newCelebStatus(NewCelebStatus.ACTIVE) .build(); } diff --git a/src/main/java/com/sluv/server/domain/celeb/entity/RecentSelectCeleb.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/RecentSelectCeleb.java similarity index 73% rename from src/main/java/com/sluv/server/domain/celeb/entity/RecentSelectCeleb.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/entity/RecentSelectCeleb.java index 17972a9d..56819b60 100644 --- a/src/main/java/com/sluv/server/domain/celeb/entity/RecentSelectCeleb.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/entity/RecentSelectCeleb.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.celeb.entity; +package com.sluv.domain.celeb.entity; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -43,4 +43,12 @@ public class RecentSelectCeleb extends BaseEntity { @NotNull private User user; + public static RecentSelectCeleb toEntity(User user, Celeb celeb, NewCeleb newCeleb) { + return RecentSelectCeleb.builder() + .celeb(celeb) + .newCeleb(newCeleb) + .user(user) + .build(); + } + } diff --git a/src/main/java/com/sluv/server/domain/celeb/enums/CelebStatus.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/enums/CelebStatus.java similarity index 54% rename from src/main/java/com/sluv/server/domain/celeb/enums/CelebStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/enums/CelebStatus.java index c2133bab..cabcfb0a 100644 --- a/src/main/java/com/sluv/server/domain/celeb/enums/CelebStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/enums/CelebStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.celeb.enums; +package com.sluv.domain.celeb.enums; public enum CelebStatus { ACTIVE, diff --git a/src/main/java/com/sluv/server/domain/celeb/enums/NewCelebStatus.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/enums/NewCelebStatus.java similarity index 61% rename from src/main/java/com/sluv/server/domain/celeb/enums/NewCelebStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/enums/NewCelebStatus.java index 93226a66..8b2d79a9 100644 --- a/src/main/java/com/sluv/server/domain/celeb/enums/NewCelebStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/enums/NewCelebStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.celeb.enums; +package com.sluv.domain.celeb.enums; public enum NewCelebStatus { ACTIVE, diff --git a/sluv-domain/src/main/java/com/sluv/domain/celeb/exception/CelebException.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/exception/CelebException.java new file mode 100644 index 00000000..b9804e23 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/exception/CelebException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.celeb.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class CelebException extends ApplicationException { + public CelebException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/domain/celeb/exception/CelebNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/exception/CelebNotFoundException.java similarity index 62% rename from src/main/java/com/sluv/server/domain/celeb/exception/CelebNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/exception/CelebNotFoundException.java index 2a19cc4a..e7d906b4 100644 --- a/src/main/java/com/sluv/server/domain/celeb/exception/CelebNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/exception/CelebNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.celeb.exception; +package com.sluv.domain.celeb.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class CelebNotFoundException extends CelebException { private static final int ERROR_CODE = 2002; private static final String MESSAGE = "존재하지 않는 셀럽입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public CelebNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/celeb/exception/NewCelebNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/exception/NewCelebNotFoundException.java similarity index 63% rename from src/main/java/com/sluv/server/domain/celeb/exception/NewCelebNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/exception/NewCelebNotFoundException.java index 213e8d36..d84ca9a1 100644 --- a/src/main/java/com/sluv/server/domain/celeb/exception/NewCelebNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/exception/NewCelebNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.celeb.exception; +package com.sluv.domain.celeb.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class NewCelebNotFoundException extends CelebException { private static final int ERROR_CODE = 2005; private static final String MESSAGE = "존재하지 않는 New 셀럽입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public NewCelebNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/CelebActivityRepository.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/CelebActivityRepository.java new file mode 100644 index 00000000..26a7b928 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/CelebActivityRepository.java @@ -0,0 +1,8 @@ +package com.sluv.domain.celeb.repository; + +import com.sluv.domain.celeb.entity.CelebActivity; +import com.sluv.domain.celeb.repository.Impl.CelebActivityRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CelebActivityRepository extends JpaRepository, CelebActivityRepositoryCustom { +} diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/CelebCategoryRepository.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/CelebCategoryRepository.java similarity index 67% rename from src/main/java/com/sluv/server/domain/celeb/repository/CelebCategoryRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/repository/CelebCategoryRepository.java index 19adc6f0..75dc1f88 100644 --- a/src/main/java/com/sluv/server/domain/celeb/repository/CelebCategoryRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/CelebCategoryRepository.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.celeb.repository; - -import com.sluv.server.domain.celeb.entity.CelebCategory; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.celeb.repository; +import com.sluv.domain.celeb.entity.CelebCategory; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface CelebCategoryRepository extends JpaRepository { List findAllByParentIdIsNull(); diff --git a/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/CelebRepository.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/CelebRepository.java new file mode 100644 index 00000000..2f86e830 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/CelebRepository.java @@ -0,0 +1,9 @@ +package com.sluv.domain.celeb.repository; + +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.repository.Impl.CelebRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; + + +public interface CelebRepository extends JpaRepository, CelebRepositoryCustom { +} \ No newline at end of file diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebActivityRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebActivityRepositoryCustom.java similarity index 53% rename from src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebActivityRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebActivityRepositoryCustom.java index 220c7a9c..ff5164d0 100644 --- a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebActivityRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebActivityRepositoryCustom.java @@ -1,7 +1,6 @@ -package com.sluv.server.domain.celeb.repository.Impl; - -import com.sluv.server.domain.celeb.entity.CelebActivity; +package com.sluv.domain.celeb.repository.Impl; +import com.sluv.domain.celeb.entity.CelebActivity; import java.util.List; public interface CelebActivityRepositoryCustom { diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebActivityRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebActivityRepositoryImpl.java similarity index 75% rename from src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebActivityRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebActivityRepositoryImpl.java index f0c50c08..1a82a589 100644 --- a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebActivityRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebActivityRepositoryImpl.java @@ -1,9 +1,9 @@ -package com.sluv.server.domain.celeb.repository.Impl; +package com.sluv.domain.celeb.repository.Impl; -import static com.sluv.server.domain.celeb.entity.QCelebActivity.celebActivity; +import static com.sluv.domain.celeb.entity.QCelebActivity.celebActivity; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.celeb.entity.CelebActivity; +import com.sluv.domain.celeb.entity.CelebActivity; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebRepositoryCustom.java similarity index 74% rename from src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebRepositoryCustom.java index 07c24f12..01f3676c 100644 --- a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebRepositoryCustom.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.celeb.repository.Impl; +package com.sluv.domain.celeb.repository.Impl; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.CelebCategory; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.CelebCategory; +import com.sluv.domain.user.entity.User; import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebRepositoryImpl.java similarity index 92% rename from src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebRepositoryImpl.java index 5da5b96f..706374dd 100644 --- a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/CelebRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/CelebRepositoryImpl.java @@ -1,19 +1,19 @@ -package com.sluv.server.domain.celeb.repository.Impl; +package com.sluv.domain.celeb.repository.Impl; -import static com.sluv.server.domain.celeb.entity.QCeleb.celeb; -import static com.sluv.server.domain.celeb.entity.QCelebCategory.celebCategory; -import static com.sluv.server.domain.celeb.entity.QInterestedCeleb.interestedCeleb; -import static com.sluv.server.domain.celeb.entity.QRecentSelectCeleb.recentSelectCeleb; +import static com.sluv.domain.celeb.entity.QCeleb.celeb; +import static com.sluv.domain.celeb.entity.QCelebCategory.celebCategory; +import static com.sluv.domain.celeb.entity.QInterestedCeleb.interestedCeleb; +import static com.sluv.domain.celeb.entity.QRecentSelectCeleb.recentSelectCeleb; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.CelebCategory; -import com.sluv.server.domain.celeb.entity.InterestedCeleb; -import com.sluv.server.domain.celeb.entity.QCeleb; -import com.sluv.server.domain.celeb.entity.QCelebCategory; -import com.sluv.server.domain.celeb.entity.RecentSelectCeleb; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.CelebCategory; +import com.sluv.domain.celeb.entity.InterestedCeleb; +import com.sluv.domain.celeb.entity.QCeleb; +import com.sluv.domain.celeb.entity.QCelebCategory; +import com.sluv.domain.celeb.entity.RecentSelectCeleb; +import com.sluv.domain.user.entity.User; import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/RecentSelectCelebRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/RecentSelectCelebRepositoryCustom.java new file mode 100644 index 00000000..89be8f7f --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/RecentSelectCelebRepositoryCustom.java @@ -0,0 +1,10 @@ +package com.sluv.domain.celeb.repository.Impl; + +import com.sluv.domain.celeb.entity.RecentSelectCeleb; +import com.sluv.domain.user.entity.User; +import java.util.List; + +public interface RecentSelectCelebRepositoryCustom { + + List getRecentSelectCelebTop20(User user); +} diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/RecentSelectCelebRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/RecentSelectCelebRepositoryImpl.java similarity index 68% rename from src/main/java/com/sluv/server/domain/celeb/repository/Impl/RecentSelectCelebRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/RecentSelectCelebRepositoryImpl.java index 2090ea40..ab6b3b2a 100644 --- a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/RecentSelectCelebRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/Impl/RecentSelectCelebRepositoryImpl.java @@ -1,13 +1,13 @@ -package com.sluv.server.domain.celeb.repository.Impl; +package com.sluv.domain.celeb.repository.Impl; -import static com.sluv.server.domain.celeb.entity.QCeleb.celeb; -import static com.sluv.server.domain.celeb.entity.QNewCeleb.newCeleb; -import static com.sluv.server.domain.celeb.entity.QRecentSelectCeleb.recentSelectCeleb; +import static com.sluv.domain.celeb.entity.QCeleb.celeb; +import static com.sluv.domain.celeb.entity.QNewCeleb.newCeleb; +import static com.sluv.domain.celeb.entity.QRecentSelectCeleb.recentSelectCeleb; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.celeb.entity.QCeleb; -import com.sluv.server.domain.celeb.entity.RecentSelectCeleb; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.celeb.entity.QCeleb; +import com.sluv.domain.celeb.entity.RecentSelectCeleb; +import com.sluv.domain.user.entity.User; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/InterestedCelebRepository.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/InterestedCelebRepository.java similarity index 71% rename from src/main/java/com/sluv/server/domain/celeb/repository/InterestedCelebRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/repository/InterestedCelebRepository.java index 98c1458c..b54794dd 100644 --- a/src/main/java/com/sluv/server/domain/celeb/repository/InterestedCelebRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/InterestedCelebRepository.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.celeb.repository; - -import com.sluv.server.domain.celeb.entity.InterestedCeleb; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.celeb.repository; +import com.sluv.domain.celeb.entity.InterestedCeleb; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface InterestedCelebRepository extends JpaRepository { void deleteAllByUserId(Long userId); diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/NewCelebRepository.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/NewCelebRepository.java similarity index 65% rename from src/main/java/com/sluv/server/domain/celeb/repository/NewCelebRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/repository/NewCelebRepository.java index 5bfa27ba..ea2f6ba5 100644 --- a/src/main/java/com/sluv/server/domain/celeb/repository/NewCelebRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/NewCelebRepository.java @@ -1,11 +1,12 @@ -package com.sluv.server.domain.celeb.repository; +package com.sluv.domain.celeb.repository; -import com.sluv.server.domain.celeb.entity.NewCeleb; +import com.sluv.domain.celeb.entity.NewCeleb; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.Optional; +public interface NewCelebRepository extends JpaRepository { + ; -public interface NewCelebRepository extends JpaRepository{ ; Optional findByCelebName(String newCelebName); } \ No newline at end of file diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/RecentSelectCelebRepository.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/RecentSelectCelebRepository.java similarity index 53% rename from src/main/java/com/sluv/server/domain/celeb/repository/RecentSelectCelebRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/repository/RecentSelectCelebRepository.java index 9e3f3b81..2a0442f7 100644 --- a/src/main/java/com/sluv/server/domain/celeb/repository/RecentSelectCelebRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/repository/RecentSelectCelebRepository.java @@ -1,10 +1,11 @@ -package com.sluv.server.domain.celeb.repository; +package com.sluv.domain.celeb.repository; -import com.sluv.server.domain.celeb.entity.RecentSelectCeleb; -import com.sluv.server.domain.celeb.repository.Impl.RecentSelectCelebRepositoryCustom; +import com.sluv.domain.celeb.entity.RecentSelectCeleb; +import com.sluv.domain.celeb.repository.Impl.RecentSelectCelebRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; -public interface RecentSelectCelebRepository extends JpaRepository, RecentSelectCelebRepositoryCustom { +public interface RecentSelectCelebRepository extends JpaRepository, + RecentSelectCelebRepositoryCustom { void deleteAllByUserId(Long id); void deleteByUserIdAndCelebId(Long userId, Long celebId); diff --git a/src/main/java/com/sluv/server/domain/celeb/service/CelebActivityService.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebActivityDomainService.java similarity index 51% rename from src/main/java/com/sluv/server/domain/celeb/service/CelebActivityService.java rename to sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebActivityDomainService.java index b8923f19..1f84c10f 100644 --- a/src/main/java/com/sluv/server/domain/celeb/service/CelebActivityService.java +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebActivityDomainService.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.celeb.service; +package com.sluv.domain.celeb.service; -import com.sluv.server.domain.celeb.dto.CelebActivityResDto; -import com.sluv.server.domain.celeb.repository.CelebActivityRepository; +import com.sluv.domain.celeb.entity.CelebActivity; +import com.sluv.domain.celeb.repository.CelebActivityRepository; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -9,14 +9,13 @@ @Service @RequiredArgsConstructor -public class CelebActivityService { +public class CelebActivityDomainService { + private final CelebActivityRepository celebActivityRepository; @Transactional(readOnly = true) - public List getCelebActivity(Long celebId) { - - return celebActivityRepository.findAllByCelebId(celebId).stream() - .map(CelebActivityResDto::of) - .toList(); + public List findAllByCelebId(Long celebId) { + return celebActivityRepository.findAllByCelebId(celebId); } + } diff --git a/sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebCategoryDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebCategoryDomainService.java new file mode 100644 index 00000000..0e7bb38b --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebCategoryDomainService.java @@ -0,0 +1,21 @@ +package com.sluv.domain.celeb.service; + +import com.sluv.domain.celeb.entity.CelebCategory; +import com.sluv.domain.celeb.repository.CelebCategoryRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class CelebCategoryDomainService { + + private final CelebCategoryRepository celebCategoryRepository; + + @Transactional(readOnly = true) + public List findAllByParentIdIsNull() { + return celebCategoryRepository.findAllByParentIdIsNull(); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebDomainService.java new file mode 100644 index 00000000..080aa35a --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/CelebDomainService.java @@ -0,0 +1,66 @@ +package com.sluv.domain.celeb.service; + +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.CelebCategory; +import com.sluv.domain.celeb.exception.CelebNotFoundException; +import com.sluv.domain.celeb.repository.CelebRepository; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class CelebDomainService { + + private final CelebRepository celebRepository; + + @Transactional(readOnly = true) + public Page searchCeleb(String celebName, Pageable pageable) { + return celebRepository.searchCeleb(celebName, pageable); + } + + @Transactional(readOnly = true) + public List findTop10Celeb() { + return celebRepository.findTop10Celeb(); + } + + @Transactional(readOnly = true) + public Celeb findByIdOrNull(Long celebId) { + return celebRepository.findById(celebId).orElse(null); + } + + @Transactional(readOnly = true) + public List getCelebByCategory(CelebCategory category) { + return celebRepository.getCelebByCategory(category); + } + + @Transactional(readOnly = true) + public List searchInterestedCelebByParent(String celebName) { + return celebRepository.searchInterestedCelebByParent(celebName); + } + + @Transactional(readOnly = true) + public List searchInterestedCelebByChild(String celebName) { + return celebRepository.searchInterestedCelebByChild(celebName); + } + + @Transactional(readOnly = true) + public List findInterestedCeleb(User user) { + return celebRepository.findInterestedCeleb(user); + } + + @Transactional(readOnly = true) + public Celeb findById(Long celebId) { + return celebRepository.findById(celebId).orElseThrow(CelebNotFoundException::new); + } + + @Transactional(readOnly = true) + public List getCelebByContainKeyword(String keyword) { + return celebRepository.getCelebByContainKeyword(keyword); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/celeb/service/InterestedCelebDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/InterestedCelebDomainService.java new file mode 100644 index 00000000..9f86abd6 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/InterestedCelebDomainService.java @@ -0,0 +1,25 @@ +package com.sluv.domain.celeb.service; + +import com.sluv.domain.celeb.entity.InterestedCeleb; +import com.sluv.domain.celeb.repository.InterestedCelebRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class InterestedCelebDomainService { + + private final InterestedCelebRepository interestedCelebRepository; + + @Transactional + public void deleteAllByUserId(Long userId) { + interestedCelebRepository.deleteAllByUserId(userId); + } + + @Transactional + public void saveAll(List interestedCelebList) { + interestedCelebRepository.saveAll(interestedCelebList); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/celeb/service/NewCelebDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/NewCelebDomainService.java new file mode 100644 index 00000000..54f0ccd3 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/NewCelebDomainService.java @@ -0,0 +1,35 @@ +package com.sluv.domain.celeb.service; + +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.celeb.exception.NewCelebNotFoundException; +import com.sluv.domain.celeb.repository.NewCelebRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class NewCelebDomainService { + + private final NewCelebRepository newCelebRepository; + + @Transactional(readOnly = true) + public NewCeleb findByCelebNameOrNull(String newCelebName) { + return newCelebRepository.findByCelebName(newCelebName).orElse(null); + } + + @Transactional + public NewCeleb saveNewCelebByName(NewCeleb newCeleb) { + return newCelebRepository.save(newCeleb); + } + + @Transactional(readOnly = true) + public NewCeleb findByNewCelebIdOrNull(Long newCelebId) { + return newCelebRepository.findById(newCelebId).orElseThrow(null); + } + + @Transactional(readOnly = true) + public NewCeleb findById(Long newCelebId) { + return newCelebRepository.findById(newCelebId).orElseThrow(NewCelebNotFoundException::new); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/celeb/service/RecentSelectCelebDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/RecentSelectCelebDomainService.java new file mode 100644 index 00000000..6202829f --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/celeb/service/RecentSelectCelebDomainService.java @@ -0,0 +1,42 @@ +package com.sluv.domain.celeb.service; + +import com.sluv.domain.celeb.entity.RecentSelectCeleb; +import com.sluv.domain.celeb.repository.RecentSelectCelebRepository; +import com.sluv.domain.user.entity.User; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class RecentSelectCelebDomainService { + + private final RecentSelectCelebRepository recentSelectCelebRepository; + + @Transactional(readOnly = true) + public List getRecentSelectCelebTop20(User user) { + return recentSelectCelebRepository.getRecentSelectCelebTop20(user); + } + + @Transactional + public RecentSelectCeleb saveRecentSelectCeleb(RecentSelectCeleb recentSelectCeleb) { + return recentSelectCelebRepository.save(recentSelectCeleb); + } + + @Transactional + public void deleteAllByUserId(Long userId) { + recentSelectCelebRepository.deleteAllByUserId(userId); + } + + @Transactional + public void deleteByUserIdAndCelebId(Long userId, Long celebId) { + recentSelectCelebRepository.deleteByUserIdAndCelebId(userId, celebId); + } + + @Transactional + public void deleteByUserIdAndNewCelebId(Long userId, Long celebId) { + recentSelectCelebRepository.deleteByUserIdAndNewCelebId(userId, celebId); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/closet/dto/ClosetCountDto.java b/sluv-domain/src/main/java/com/sluv/domain/closet/dto/ClosetCountDto.java new file mode 100644 index 00000000..bb6c42c4 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/dto/ClosetCountDto.java @@ -0,0 +1,14 @@ +package com.sluv.domain.closet.dto; + +import com.sluv.domain.closet.entity.Closet; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ClosetCountDto { + + private Closet closet; + private Long itemCount; + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/closet/dto/ClosetDomainDto.java b/sluv-domain/src/main/java/com/sluv/domain/closet/dto/ClosetDomainDto.java new file mode 100644 index 00000000..484dd5fe --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/dto/ClosetDomainDto.java @@ -0,0 +1,29 @@ +package com.sluv.domain.closet.dto; + +import com.sluv.domain.closet.enums.ClosetColor; +import com.sluv.domain.closet.enums.ClosetStatus; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class ClosetDomainDto { + private String name; + private String coverImgUrl; + private ClosetStatus closetStatus; + private ClosetColor colorScheme; + + public static ClosetDomainDto of(String name, String coverImgUrl, ClosetStatus closetStatus, + ClosetColor colorScheme) { + return ClosetDomainDto.builder() + .name(name) + .coverImgUrl(coverImgUrl) + .closetStatus(closetStatus) + .colorScheme(colorScheme) + .build(); + } + +} diff --git a/src/main/java/com/sluv/server/domain/closet/entity/Closet.java b/sluv-domain/src/main/java/com/sluv/domain/closet/entity/Closet.java similarity index 67% rename from src/main/java/com/sluv/server/domain/closet/entity/Closet.java rename to sluv-domain/src/main/java/com/sluv/domain/closet/entity/Closet.java index dc0afe7a..f2015fb2 100644 --- a/src/main/java/com/sluv/server/domain/closet/entity/Closet.java +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/entity/Closet.java @@ -1,10 +1,11 @@ -package com.sluv.server.domain.closet.entity; +package com.sluv.domain.closet.entity; -import com.sluv.server.domain.closet.dto.ClosetReqDto; -import com.sluv.server.domain.closet.enums.ClosetColor; -import com.sluv.server.domain.closet.enums.ClosetStatus; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.closet.dto.ClosetDomainDto; +import com.sluv.domain.closet.enums.ClosetColor; +import com.sluv.domain.closet.enums.ClosetStatus; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.item.entity.ItemScrap; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -15,9 +16,11 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -60,14 +63,17 @@ public class Closet extends BaseEntity { @Column(length = 45, columnDefinition = "varchar(45) default 'PUBLIC'") private ClosetStatus closetStatus; - public void changeCloset(ClosetReqDto dto) { + @OneToMany(fetch = FetchType.LAZY) + private List itemScraps; + + public void changeCloset(ClosetDomainDto dto) { this.name = dto.getName(); this.coverImgUrl = dto.getCoverImgUrl(); this.color = dto.getColorScheme(); this.closetStatus = dto.getClosetStatus(); } - public static Closet toEntity(User user, ClosetReqDto dto) { + public static Closet toEntity(User user, ClosetDomainDto dto) { return Closet.builder() .user(user) .name(dto.getName()) @@ -77,4 +83,16 @@ public static Closet toEntity(User user, ClosetReqDto dto) { .closetStatus(dto.getClosetStatus()) .build(); } + + public static Closet createBasic(User user) { + return Closet.builder() + .user(user) + .name("기본 옷장") + .coverImgUrl(null) + .basicFlag(true) + .color(ClosetColor.PURPLE) + .closetStatus(ClosetStatus.PRIVATE) + .build(); + } + } diff --git a/src/main/java/com/sluv/server/domain/closet/enums/ClosetColor.java b/sluv-domain/src/main/java/com/sluv/domain/closet/enums/ClosetColor.java similarity index 67% rename from src/main/java/com/sluv/server/domain/closet/enums/ClosetColor.java rename to sluv-domain/src/main/java/com/sluv/domain/closet/enums/ClosetColor.java index 712a1a8f..a4d1e803 100644 --- a/src/main/java/com/sluv/server/domain/closet/enums/ClosetColor.java +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/enums/ClosetColor.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.closet.enums; +package com.sluv.domain.closet.enums; public enum ClosetColor { PURPLE, diff --git a/src/main/java/com/sluv/server/domain/closet/enums/ClosetStatus.java b/sluv-domain/src/main/java/com/sluv/domain/closet/enums/ClosetStatus.java similarity index 54% rename from src/main/java/com/sluv/server/domain/closet/enums/ClosetStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/closet/enums/ClosetStatus.java index 2496e30c..0f540181 100644 --- a/src/main/java/com/sluv/server/domain/closet/enums/ClosetStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/enums/ClosetStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.closet.enums; +package com.sluv.domain.closet.enums; public enum ClosetStatus { PUBLIC, diff --git a/src/main/java/com/sluv/server/domain/closet/exception/BasicClosetDeleteException.java b/sluv-domain/src/main/java/com/sluv/domain/closet/exception/BasicClosetDeleteException.java similarity index 64% rename from src/main/java/com/sluv/server/domain/closet/exception/BasicClosetDeleteException.java rename to sluv-domain/src/main/java/com/sluv/domain/closet/exception/BasicClosetDeleteException.java index 279a29f5..7a0f627a 100644 --- a/src/main/java/com/sluv/server/domain/closet/exception/BasicClosetDeleteException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/exception/BasicClosetDeleteException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.closet.exception; +package com.sluv.domain.closet.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class BasicClosetDeleteException extends ClosetException { private static final int ERROR_CODE = 2019; private static final String MESSAGE = "기본 Closet은 삭제할 수 없습니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public BasicClosetDeleteException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/sluv-domain/src/main/java/com/sluv/domain/closet/exception/ClosetException.java b/sluv-domain/src/main/java/com/sluv/domain/closet/exception/ClosetException.java new file mode 100644 index 00000000..8780dae7 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/exception/ClosetException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.closet.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class ClosetException extends ApplicationException { + public ClosetException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/domain/closet/exception/ClosetNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/closet/exception/ClosetNotFoundException.java similarity index 63% rename from src/main/java/com/sluv/server/domain/closet/exception/ClosetNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/closet/exception/ClosetNotFoundException.java index a5dcf37f..d8c8425b 100644 --- a/src/main/java/com/sluv/server/domain/closet/exception/ClosetNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/exception/ClosetNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.closet.exception; +package com.sluv.domain.closet.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class ClosetNotFoundException extends ClosetException { private static final int ERROR_CODE = 2018; private static final String MESSAGE = "존재하지 않는 Closet입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public ClosetNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/closet/repository/ClosetRepository.java b/sluv-domain/src/main/java/com/sluv/domain/closet/repository/ClosetRepository.java similarity index 59% rename from src/main/java/com/sluv/server/domain/closet/repository/ClosetRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/closet/repository/ClosetRepository.java index b7b4cb48..1dbf0c34 100644 --- a/src/main/java/com/sluv/server/domain/closet/repository/ClosetRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/repository/ClosetRepository.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.closet.repository; +package com.sluv.domain.closet.repository; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.closet.repository.impl.ClosetRepositoryCustom; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.closet.repository.impl.ClosetRepositoryCustom; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/sluv/server/domain/closet/repository/impl/ClosetRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/closet/repository/impl/ClosetRepositoryCustom.java similarity index 61% rename from src/main/java/com/sluv/server/domain/closet/repository/impl/ClosetRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/closet/repository/impl/ClosetRepositoryCustom.java index ec1802d8..bed5fde4 100644 --- a/src/main/java/com/sluv/server/domain/closet/repository/impl/ClosetRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/repository/impl/ClosetRepositoryCustom.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.closet.repository.impl; +package com.sluv.domain.closet.repository.impl; -import com.sluv.server.domain.closet.dto.ClosetResDto; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.closet.dto.ClosetCountDto; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.user.entity.User; import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -14,7 +14,7 @@ public interface ClosetRepositoryCustom { Page getUserAllPublicCloset(Long userId, Pageable pageable); - List getUserClosetList(User user); + List getUserClosetList(User user); Boolean checkDuplicate(String name, Long closetId); diff --git a/src/main/java/com/sluv/server/domain/closet/repository/impl/ClosetRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/closet/repository/impl/ClosetRepositoryImpl.java similarity index 84% rename from src/main/java/com/sluv/server/domain/closet/repository/impl/ClosetRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/closet/repository/impl/ClosetRepositoryImpl.java index d1e1aab9..12f1a98d 100644 --- a/src/main/java/com/sluv/server/domain/closet/repository/impl/ClosetRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/repository/impl/ClosetRepositoryImpl.java @@ -1,15 +1,15 @@ -package com.sluv.server.domain.closet.repository.impl; +package com.sluv.domain.closet.repository.impl; -import static com.sluv.server.domain.closet.entity.QCloset.closet; -import static com.sluv.server.domain.item.entity.QItemScrap.itemScrap; +import static com.sluv.domain.closet.entity.QCloset.closet; +import static com.sluv.domain.item.entity.QItemScrap.itemScrap; import com.querydsl.core.Tuple; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.closet.dto.ClosetResDto; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.closet.enums.ClosetStatus; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.closet.dto.ClosetCountDto; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.closet.enums.ClosetStatus; +import com.sluv.domain.user.entity.User; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; @@ -75,7 +75,7 @@ public Page getUserAllPublicCloset(Long userId, Pageable pageable) { } @Override - public List getUserClosetList(User user) { + public List getUserClosetList(User user) { List content = jpaQueryFactory.select(closet, itemScrap.count()) .from(closet) .leftJoin(itemScrap).on(itemScrap.closet.eq(closet)) @@ -84,7 +84,7 @@ public List getUserClosetList(User user) { .fetch(); return content.stream() - .map(tuple -> ClosetResDto.of(tuple.get(closet), tuple.get(itemScrap.count()))) + .map(tuple -> new ClosetCountDto(tuple.get(closet), tuple.get(itemScrap.count()))) .toList(); } diff --git a/sluv-domain/src/main/java/com/sluv/domain/closet/service/ClosetDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/closet/service/ClosetDomainService.java new file mode 100644 index 00000000..2a10082e --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/closet/service/ClosetDomainService.java @@ -0,0 +1,83 @@ +package com.sluv.domain.closet.service; + +import com.sluv.domain.closet.dto.ClosetCountDto; +import com.sluv.domain.closet.dto.ClosetDomainDto; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.closet.exception.ClosetNotFoundException; +import com.sluv.domain.closet.repository.ClosetRepository; +import com.sluv.domain.user.entity.User; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ClosetDomainService { + + private final ClosetRepository closetRepository; + + @Transactional(readOnly = true) + public Long countByUserId(Long userId) { + return closetRepository.countByUserId(userId); + } + + @Transactional(readOnly = true) + public List getUserClosetList(User user) { + return closetRepository.getUserClosetList(user); + } + + @Transactional(readOnly = true) + public Boolean checkDuplicate(String name, Long closetId) { + return closetRepository.checkDuplicate(name, closetId); + } + + @Transactional + public void saveBasicCloset(User user) { + Closet basicCloset = Closet.createBasic(user); + closetRepository.save(basicCloset); + } + + @Transactional(readOnly = true) + public Closet findById(Long closetId) { + return closetRepository.findById(closetId).orElseThrow(ClosetNotFoundException::new); + } + + @Transactional + public void changeClosetData(Closet closet, ClosetDomainDto dto) { + closet.changeCloset(dto); + closetRepository.save(closet); + } + + @Transactional + public void deleteById(Long userId) { + closetRepository.deleteById(userId); + } + + @Transactional(readOnly = true) + public List findAllByUserId(Long userId) { + return closetRepository.findAllByUserId(userId); + } + + @Transactional(readOnly = true) + public Page getUserAllCloset(Long userId, Pageable pageable) { + return closetRepository.getUserAllCloset(userId, pageable); + } + + @Transactional(readOnly = true) + public Page getUserAllPublicCloset(Long userId, Pageable pageable) { + return closetRepository.getUserAllPublicCloset(userId, pageable); + } + + @Transactional + public void saveCloset(Closet closet) { + closetRepository.save(closet); + } + + @Transactional(readOnly = true) + public List getRecentAddCloset(Long itemId) { + return closetRepository.getRecentAddCloset(itemId); + } +} diff --git a/src/main/java/com/sluv/server/domain/comment/dto/CommentImgDto.java b/sluv-domain/src/main/java/com/sluv/domain/comment/dto/CommentImgDto.java similarity index 86% rename from src/main/java/com/sluv/server/domain/comment/dto/CommentImgDto.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/dto/CommentImgDto.java index c297ffa5..f4c90b73 100644 --- a/src/main/java/com/sluv/server/domain/comment/dto/CommentImgDto.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/dto/CommentImgDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.comment.dto; +package com.sluv.domain.comment.dto; -import com.sluv.server.domain.comment.entity.CommentImg; +import com.sluv.domain.comment.entity.CommentImg; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/comment/entity/Comment.java b/sluv-domain/src/main/java/com/sluv/domain/comment/entity/Comment.java similarity index 89% rename from src/main/java/com/sluv/server/domain/comment/entity/Comment.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/entity/Comment.java index 9c6f33e0..b0a6f5a2 100644 --- a/src/main/java/com/sluv/server/domain/comment/entity/Comment.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/entity/Comment.java @@ -1,9 +1,9 @@ -package com.sluv.server.domain.comment.entity; +package com.sluv.domain.comment.entity; -import com.sluv.server.domain.comment.enums.CommentStatus; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.comment.enums.CommentStatus; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; diff --git a/src/main/java/com/sluv/server/domain/comment/entity/CommentImg.java b/sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentImg.java similarity index 88% rename from src/main/java/com/sluv/server/domain/comment/entity/CommentImg.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentImg.java index 60b4f416..e6088e9e 100644 --- a/src/main/java/com/sluv/server/domain/comment/entity/CommentImg.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentImg.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.comment.entity; +package com.sluv.domain.comment.entity; -import com.sluv.server.domain.comment.dto.CommentImgDto; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.comment.dto.CommentImgDto; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/comment/entity/CommentItem.java b/sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentItem.java similarity index 80% rename from src/main/java/com/sluv/server/domain/comment/entity/CommentItem.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentItem.java index 6c89bf65..6eca07e4 100644 --- a/src/main/java/com/sluv/server/domain/comment/entity/CommentItem.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentItem.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.comment.entity; +package com.sluv.domain.comment.entity; -import com.sluv.server.domain.comment.dto.CommentItemReqDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.item.entity.Item; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -43,11 +42,11 @@ public class CommentItem extends BaseEntity { private Integer sortOrder; - public static CommentItem toEntity(Comment comment, Item item, CommentItemReqDto dto) { + public static CommentItem toEntity(Comment comment, Item item, Integer sortOrder) { return CommentItem.builder() .comment(comment) .item(item) - .sortOrder(dto.getSortOrder()) + .sortOrder(sortOrder) .build(); } } diff --git a/src/main/java/com/sluv/server/domain/comment/entity/CommentLike.java b/sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentLike.java similarity index 88% rename from src/main/java/com/sluv/server/domain/comment/entity/CommentLike.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentLike.java index 63a91b23..c9e7fb2f 100644 --- a/src/main/java/com/sluv/server/domain/comment/entity/CommentLike.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentLike.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.comment.entity; +package com.sluv.domain.comment.entity; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/comment/entity/CommentReport.java b/sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentReport.java similarity index 78% rename from src/main/java/com/sluv/server/domain/comment/entity/CommentReport.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentReport.java index f1747648..b131b2a8 100644 --- a/src/main/java/com/sluv/server/domain/comment/entity/CommentReport.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/entity/CommentReport.java @@ -1,10 +1,9 @@ -package com.sluv.server.domain.comment.entity; +package com.sluv.domain.comment.entity; -import com.sluv.server.domain.comment.dto.CommentReportPostReqDto; -import com.sluv.server.domain.comment.enums.CommentReportReason; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; -import com.sluv.server.global.common.enums.ReportStatus; +import com.sluv.domain.comment.enums.CommentReportReason; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.common.enums.ReportStatus; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -57,12 +56,13 @@ public class CommentReport extends BaseEntity { @Column(length = 45, columnDefinition = "varchar(45) default 'WAITING'") private ReportStatus reportStatus; - public static CommentReport toEntity(Comment comment, User user, CommentReportPostReqDto dto) { + public static CommentReport toEntity(Comment comment, User user, + CommentReportReason reason, String content) { return CommentReport.builder() .comment(comment) .reporter(user) - .commentReportReason(dto.getReason()) - .content(dto.getContent()) + .commentReportReason(reason) + .content(content) .reportStatus(ReportStatus.WAITING) .build(); } diff --git a/src/main/java/com/sluv/server/domain/comment/enums/CommentReportReason.java b/sluv-domain/src/main/java/com/sluv/domain/comment/enums/CommentReportReason.java similarity index 74% rename from src/main/java/com/sluv/server/domain/comment/enums/CommentReportReason.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/enums/CommentReportReason.java index 7e86a131..e6ee7077 100644 --- a/src/main/java/com/sluv/server/domain/comment/enums/CommentReportReason.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/enums/CommentReportReason.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.comment.enums; +package com.sluv.domain.comment.enums; public enum CommentReportReason { SPAM_OR_AD, diff --git a/src/main/java/com/sluv/server/domain/comment/enums/CommentStatus.java b/sluv-domain/src/main/java/com/sluv/domain/comment/enums/CommentStatus.java similarity index 54% rename from src/main/java/com/sluv/server/domain/comment/enums/CommentStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/enums/CommentStatus.java index 2b514b47..ce08ad00 100644 --- a/src/main/java/com/sluv/server/domain/comment/enums/CommentStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/enums/CommentStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.comment.enums; +package com.sluv.domain.comment.enums; public enum CommentStatus { ACTIVE, diff --git a/sluv-domain/src/main/java/com/sluv/domain/comment/exception/CommentException.java b/sluv-domain/src/main/java/com/sluv/domain/comment/exception/CommentException.java new file mode 100644 index 00000000..9323d785 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/exception/CommentException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.comment.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class CommentException extends ApplicationException { + public CommentException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/domain/comment/exception/CommentNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/comment/exception/CommentNotFoundException.java similarity index 63% rename from src/main/java/com/sluv/server/domain/comment/exception/CommentNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/exception/CommentNotFoundException.java index 35ab9774..373c4e1f 100644 --- a/src/main/java/com/sluv/server/domain/comment/exception/CommentNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/exception/CommentNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.comment.exception; +package com.sluv.domain.comment.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class CommentNotFoundException extends CommentException { private static final int ERROR_CODE = 2014; private static final String MESSAGE = "존재하지 않는 Comment입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public CommentNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/comment/exception/CommentReportDuplicateException.java b/sluv-domain/src/main/java/com/sluv/domain/comment/exception/CommentReportDuplicateException.java similarity index 64% rename from src/main/java/com/sluv/server/domain/comment/exception/CommentReportDuplicateException.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/exception/CommentReportDuplicateException.java index 157d014e..c0e413d4 100644 --- a/src/main/java/com/sluv/server/domain/comment/exception/CommentReportDuplicateException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/exception/CommentReportDuplicateException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.comment.exception; +package com.sluv.domain.comment.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class CommentReportDuplicateException extends CommentException { private static final int ERROR_CODE = 2016; private static final String MESSAGE = "중복된 댓글 신고입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public CommentReportDuplicateException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/comment/repository/CommentImgRepository.java b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentImgRepository.java similarity index 71% rename from src/main/java/com/sluv/server/domain/comment/repository/CommentImgRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentImgRepository.java index cc3de587..64e2410f 100644 --- a/src/main/java/com/sluv/server/domain/comment/repository/CommentImgRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentImgRepository.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.comment.repository; - -import com.sluv.server.domain.comment.entity.CommentImg; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.comment.repository; +import com.sluv.domain.comment.entity.CommentImg; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface CommentImgRepository extends JpaRepository { void deleteAllByCommentId(Long commentId); diff --git a/src/main/java/com/sluv/server/domain/comment/repository/CommentItemRepository.java b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentItemRepository.java similarity index 71% rename from src/main/java/com/sluv/server/domain/comment/repository/CommentItemRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentItemRepository.java index e4b145dd..194847fe 100644 --- a/src/main/java/com/sluv/server/domain/comment/repository/CommentItemRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentItemRepository.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.comment.repository; - -import com.sluv.server.domain.comment.entity.CommentItem; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.comment.repository; +import com.sluv.domain.comment.entity.CommentItem; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface CommentItemRepository extends JpaRepository { void deleteAllByCommentId(Long commentId); + List findAllByCommentId(Long id); } diff --git a/src/main/java/com/sluv/server/domain/comment/repository/CommentLikeRepository.java b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentLikeRepository.java similarity index 74% rename from src/main/java/com/sluv/server/domain/comment/repository/CommentLikeRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentLikeRepository.java index 2c647585..398285b9 100644 --- a/src/main/java/com/sluv/server/domain/comment/repository/CommentLikeRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentLikeRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.comment.repository; +package com.sluv.domain.comment.repository; -import com.sluv.server.domain.comment.entity.CommentLike; +import com.sluv.domain.comment.entity.CommentLike; import org.springframework.data.jpa.repository.JpaRepository; public interface CommentLikeRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/comment/repository/CommentReportRepository.java b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentReportRepository.java similarity index 66% rename from src/main/java/com/sluv/server/domain/comment/repository/CommentReportRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentReportRepository.java index 259941ea..b8d54d12 100644 --- a/src/main/java/com/sluv/server/domain/comment/repository/CommentReportRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentReportRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.comment.repository; +package com.sluv.domain.comment.repository; -import com.sluv.server.domain.comment.entity.CommentReport; +import com.sluv.domain.comment.entity.CommentReport; import org.springframework.data.jpa.repository.JpaRepository; public interface CommentReportRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/comment/repository/CommentRepository.java b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentRepository.java similarity index 58% rename from src/main/java/com/sluv/server/domain/comment/repository/CommentRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentRepository.java index 37c2ff14..1739a1c9 100644 --- a/src/main/java/com/sluv/server/domain/comment/repository/CommentRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/CommentRepository.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.comment.repository; +package com.sluv.domain.comment.repository; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.repository.impl.CommentRepositoryCustom; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.repository.impl.CommentRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; public interface CommentRepository extends JpaRepository, CommentRepositoryCustom { diff --git a/src/main/java/com/sluv/server/domain/comment/repository/impl/CommentRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/impl/CommentRepositoryCustom.java similarity index 70% rename from src/main/java/com/sluv/server/domain/comment/repository/impl/CommentRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/repository/impl/CommentRepositoryCustom.java index a6b79951..9281c271 100644 --- a/src/main/java/com/sluv/server/domain/comment/repository/impl/CommentRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/impl/CommentRepositoryCustom.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.comment.repository.impl; +package com.sluv.domain.comment.repository.impl; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.enums.CommentStatus; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.enums.CommentStatus; +import com.sluv.domain.user.entity.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/sluv/server/domain/comment/repository/impl/CommentRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/impl/CommentRepositoryImpl.java similarity index 92% rename from src/main/java/com/sluv/server/domain/comment/repository/impl/CommentRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/comment/repository/impl/CommentRepositoryImpl.java index 3ba595af..8d24f366 100644 --- a/src/main/java/com/sluv/server/domain/comment/repository/impl/CommentRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/repository/impl/CommentRepositoryImpl.java @@ -1,14 +1,14 @@ -package com.sluv.server.domain.comment.repository.impl; +package com.sluv.domain.comment.repository.impl; -import static com.sluv.server.domain.comment.entity.QComment.comment; -import static com.sluv.server.domain.comment.entity.QCommentLike.commentLike; +import static com.sluv.domain.comment.entity.QComment.comment; +import static com.sluv.domain.comment.entity.QCommentLike.commentLike; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.enums.CommentStatus; -import com.sluv.server.domain.question.enums.QuestionStatus; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.enums.CommentStatus; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.user.entity.User; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; diff --git a/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentDomainService.java new file mode 100644 index 00000000..30e2bfa1 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentDomainService.java @@ -0,0 +1,78 @@ +package com.sluv.domain.comment.service; + +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.enums.CommentStatus; +import com.sluv.domain.comment.exception.CommentNotFoundException; +import com.sluv.domain.comment.repository.CommentRepository; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class CommentDomainService { + + private final CommentRepository commentRepository; + + @Transactional(readOnly = true) + public Comment findById(Long commentId) { + return commentRepository.findById(commentId).orElseThrow(CommentNotFoundException::new); + } + + @Transactional(readOnly = true) + public Page getUserAllLikeComment(User user, Pageable pageable) { + return commentRepository.getUserAllLikeComment(user, pageable); + } + + @Transactional(readOnly = true) + public Long countByQuestionId(Long questionId) { + return commentRepository.countByQuestionId(questionId); + } + + @Transactional(readOnly = true) + public Long countCommentByUserIdInActiveQuestion(Long questionId, CommentStatus commentStatus) { + return commentRepository.countCommentByUserIdInActiveQuestion(questionId, commentStatus); + } + + @Transactional(readOnly = true) + public Page getUserAllComment(User user, Pageable pageable) { + return commentRepository.getUserAllComment(user, pageable); + } + + @Transactional(readOnly = true) + public Page getAllQuestionComment(Long questionId, Pageable pageable) { + return commentRepository.getAllQuestionComment(questionId, pageable); + } + + @Transactional(readOnly = true) + public Page getAllSubComment(Long commentId, Pageable pageable) { + return commentRepository.getAllSubComment(commentId, pageable); + } + + @Transactional + public Comment saveComment(User user, Question question, String content) { + Comment comment = Comment.toEntity(user, question, content); + return commentRepository.save(comment); + } + + @Transactional + public Comment saveSubComment(User user, Question question, String content, Comment parentComment) { + Comment comment = Comment.toEntity(user, question, content, parentComment); + return commentRepository.save(comment); + } + + @Transactional + public void deleteById(Long commentId) { + commentRepository.deleteById(commentId); + } + + @Transactional + public void deleteAllByParentId(Long parentId) { + commentRepository.deleteAllByParentId(parentId); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentImgDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentImgDomainService.java new file mode 100644 index 00000000..4fd3a75d --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentImgDomainService.java @@ -0,0 +1,26 @@ +package com.sluv.domain.comment.service; + +import com.sluv.domain.comment.entity.CommentImg; +import com.sluv.domain.comment.repository.CommentImgRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class CommentImgDomainService { + + private final CommentImgRepository commentImgRepository; + + @Transactional + public void saveAll(List imgList) { + commentImgRepository.saveAll(imgList); + } + + @Transactional + public void deleteAllByCommentId(Long commentId) { + commentImgRepository.deleteAllByCommentId(commentId); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentLikeDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentLikeDomainService.java new file mode 100644 index 00000000..1250f68e --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentLikeDomainService.java @@ -0,0 +1,33 @@ +package com.sluv.domain.comment.service; + +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.entity.CommentLike; +import com.sluv.domain.comment.repository.CommentLikeRepository; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class CommentLikeDomainService { + + private final CommentLikeRepository commentLikeRepository; + + @Transactional(readOnly = true) + public Boolean existsByUserIdAndCommentId(Long userId, Long commentId) { + return commentLikeRepository.existsByUserIdAndCommentId(userId, commentId); + } + + @Transactional + public void saveCommentLike(User user, Comment comment) { + CommentLike commentLike = CommentLike.toEntity(user, comment); + commentLikeRepository.save(commentLike); + } + + @Transactional + public void deleteByUserIdAndCommentId(Long userId, Long commentId) { + commentLikeRepository.deleteByUserIdAndCommentId(userId, commentId); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentReportDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentReportDomainService.java new file mode 100644 index 00000000..b566cb71 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/comment/service/CommentReportDomainService.java @@ -0,0 +1,29 @@ +package com.sluv.domain.comment.service; + +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.entity.CommentReport; +import com.sluv.domain.comment.enums.CommentReportReason; +import com.sluv.domain.comment.repository.CommentReportRepository; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class CommentReportDomainService { + + private final CommentReportRepository commentReportRepository; + + @Transactional(readOnly = true) + public Boolean existsByReporterIdAndCommentId(Long reporterId, Long commentId) { + return commentReportRepository.existsByReporterIdAndCommentId(reporterId, commentId); + } + + @Transactional + public void saveCommentReport(Comment comment, User user, CommentReportReason reason, String content) { + CommentReport commentReport = CommentReport.toEntity(comment, user, reason, content); + commentReportRepository.save(commentReport); + } + +} diff --git a/src/main/java/com/sluv/server/global/common/entity/BaseEntity.java b/sluv-domain/src/main/java/com/sluv/domain/common/entity/BaseEntity.java similarity index 79% rename from src/main/java/com/sluv/server/global/common/entity/BaseEntity.java rename to sluv-domain/src/main/java/com/sluv/domain/common/entity/BaseEntity.java index a3c86be5..0178c82b 100644 --- a/src/main/java/com/sluv/server/global/common/entity/BaseEntity.java +++ b/sluv-domain/src/main/java/com/sluv/domain/common/entity/BaseEntity.java @@ -1,9 +1,10 @@ -package com.sluv.server.global.common.entity; - -import java.time.LocalDateTime; +package com.sluv.domain.common.entity; import com.fasterxml.jackson.annotation.JsonIgnore; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import java.time.LocalDateTime; import lombok.Getter; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; diff --git a/src/main/java/com/sluv/server/global/common/enums/ItemImgOrLinkStatus.java b/sluv-domain/src/main/java/com/sluv/domain/common/enums/ItemImgOrLinkStatus.java similarity index 57% rename from src/main/java/com/sluv/server/global/common/enums/ItemImgOrLinkStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/common/enums/ItemImgOrLinkStatus.java index bbd58647..5d546f96 100644 --- a/src/main/java/com/sluv/server/global/common/enums/ItemImgOrLinkStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/common/enums/ItemImgOrLinkStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.common.enums; +package com.sluv.domain.common.enums; public enum ItemImgOrLinkStatus { ACTIVE, diff --git a/src/main/java/com/sluv/server/global/common/enums/ReportStatus.java b/sluv-domain/src/main/java/com/sluv/domain/common/enums/ReportStatus.java similarity index 55% rename from src/main/java/com/sluv/server/global/common/enums/ReportStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/common/enums/ReportStatus.java index 9e6bc1ad..6ea0c6a6 100644 --- a/src/main/java/com/sluv/server/global/common/enums/ReportStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/common/enums/ReportStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.common.enums; +package com.sluv.domain.common.enums; public enum ReportStatus { WAITING, diff --git a/sluv-domain/src/main/java/com/sluv/domain/config/JpaConfig.java b/sluv-domain/src/main/java/com/sluv/domain/config/JpaConfig.java new file mode 100644 index 00000000..7e1f6b16 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/config/JpaConfig.java @@ -0,0 +1,13 @@ +package com.sluv.domain.config; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@Configuration +@ComponentScan(basePackages = {"com.sluv.domain"}) +@EntityScan(basePackages = {"com.sluv.domain"}) +@EnableJpaRepositories(basePackages = {"com.sluv.domain"}) +public class JpaConfig { +} diff --git a/src/main/java/com/sluv/server/global/config/QueryDslConfig.java b/sluv-domain/src/main/java/com/sluv/domain/config/QueryDslConfig.java similarity index 92% rename from src/main/java/com/sluv/server/global/config/QueryDslConfig.java rename to sluv-domain/src/main/java/com/sluv/domain/config/QueryDslConfig.java index fe4aa0a6..83e8f17c 100644 --- a/src/main/java/com/sluv/server/global/config/QueryDslConfig.java +++ b/sluv-domain/src/main/java/com/sluv/domain/config/QueryDslConfig.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.config; +package com.sluv.domain.config; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemImgResDto.java b/sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemImgDto.java similarity index 68% rename from src/main/java/com/sluv/server/domain/item/dto/ItemImgResDto.java rename to sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemImgDto.java index 9a295136..97cc5f87 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemImgResDto.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemImgDto.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.domain.item.dto; -import com.sluv.server.domain.item.entity.ItemImg; -import com.sluv.server.domain.item.entity.TempItemImg; +import com.sluv.domain.item.entity.ItemImg; +import com.sluv.domain.item.entity.TempItemImg; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; import lombok.AllArgsConstructor; @@ -11,7 +11,7 @@ @Data @AllArgsConstructor @Builder -public class ItemImgResDto implements Serializable { +public class ItemImgDto implements Serializable { @Schema(description = "아이템 이미지 URL") private String imgUrl; @Schema(description = "대표 이미지 여부(true or false)") @@ -19,16 +19,16 @@ public class ItemImgResDto implements Serializable { @Schema(description = "이미지 순서") private Integer sortOrder; - public static ItemImgResDto of(ItemImg itemImg) { - return ItemImgResDto.builder() + public static ItemImgDto of(ItemImg itemImg) { + return ItemImgDto.builder() .imgUrl(itemImg.getItemImgUrl()) .representFlag(itemImg.getRepresentFlag()) .sortOrder(itemImg.getSortOrder()) .build(); } - public static ItemImgResDto of(TempItemImg tempItemImg) { - return ItemImgResDto.builder() + public static ItemImgDto of(TempItemImg tempItemImg) { + return ItemImgDto.builder() .imgUrl(tempItemImg.getTempItemImgUrl()) .representFlag(tempItemImg.getRepresentFlag()) .sortOrder(tempItemImg.getSortOrder()) diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemLinkResDto.java b/sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemLinkDto.java similarity index 61% rename from src/main/java/com/sluv/server/domain/item/dto/ItemLinkResDto.java rename to sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemLinkDto.java index c9770eb7..8474e615 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemLinkResDto.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemLinkDto.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.domain.item.dto; -import com.sluv.server.domain.item.entity.ItemLink; -import com.sluv.server.domain.item.entity.TempItemLink; +import com.sluv.domain.item.entity.ItemLink; +import com.sluv.domain.item.entity.TempItemLink; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; import lombok.AllArgsConstructor; @@ -11,22 +11,22 @@ @Data @AllArgsConstructor @Builder -public class ItemLinkResDto implements Serializable { +public class ItemLinkDto implements Serializable { @Schema(description = "아이템 링크 URL") private String itemLinkUrl; @Schema(description = "아이템 링크 이름") private String linkName; - public static ItemLinkResDto of(ItemLink itemLink) { - return ItemLinkResDto.builder() + public static ItemLinkDto of(ItemLink itemLink) { + return ItemLinkDto.builder() .itemLinkUrl(itemLink.getItemLinkUrl()) .linkName(itemLink.getLinkName()) .build(); } - public static ItemLinkResDto of(TempItemLink tempItemLink) { - return ItemLinkResDto.builder() + public static ItemLinkDto of(TempItemLink tempItemLink) { + return ItemLinkDto.builder() .itemLinkUrl(tempItemLink.getTempItemLinkUrl()) .linkName(tempItemLink.getLinkName()) .build(); diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemSaveDto.java b/sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemSaveDto.java new file mode 100644 index 00000000..7982a71e --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemSaveDto.java @@ -0,0 +1,21 @@ +package com.sluv.domain.item.dto; + +import java.time.LocalDateTime; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class ItemSaveDto { + + private LocalDateTime whenDiscovery; + private String whereDiscovery; + private String itemName; + private Integer price; + private String additionalInfo; + private String infoSource; + +} diff --git a/src/main/java/com/sluv/server/domain/item/dto/ItemSimpleResDto.java b/sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemSimpleDto.java similarity index 84% rename from src/main/java/com/sluv/server/domain/item/dto/ItemSimpleResDto.java rename to sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemSimpleDto.java index 94792740..36ce9d32 100644 --- a/src/main/java/com/sluv/server/domain/item/dto/ItemSimpleResDto.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/dto/ItemSimpleDto.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.item.dto; +package com.sluv.domain.item.dto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.ItemImg; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemImg; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -12,7 +12,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class ItemSimpleResDto { +public class ItemSimpleDto { /** * Item 세부 검색 시 하단에 등장하는 연관 Item 정보를 전달 */ @@ -29,8 +29,8 @@ public class ItemSimpleResDto { @Schema(description = "스크랩 여부") private Boolean scrapStatus; - public static ItemSimpleResDto of(Item item, ItemImg mainImg, Boolean scrapStatus) { - return ItemSimpleResDto.builder() + public static ItemSimpleDto of(Item item, ItemImg mainImg, Boolean scrapStatus) { + return ItemSimpleDto.builder() .itemId(item.getId()) .imgUrl(mainImg.getItemImgUrl()) .brandName( diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/dto/TempItemSaveDto.java b/sluv-domain/src/main/java/com/sluv/domain/item/dto/TempItemSaveDto.java new file mode 100644 index 00000000..a25d7fd7 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/dto/TempItemSaveDto.java @@ -0,0 +1,21 @@ +package com.sluv.domain.item.dto; + +import java.time.LocalDateTime; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class TempItemSaveDto { + + private LocalDateTime whenDiscovery; + private String whereDiscovery; + private String itemName; + private Integer price; + private String additionalInfo; + private String infoSource; + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/dto/hashtag/HashtagCountDto.java b/sluv-domain/src/main/java/com/sluv/domain/item/dto/hashtag/HashtagCountDto.java new file mode 100644 index 00000000..b1296337 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/dto/hashtag/HashtagCountDto.java @@ -0,0 +1,24 @@ +package com.sluv.domain.item.dto.hashtag; + +import com.sluv.domain.item.entity.hashtag.Hashtag; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class HashtagCountDto { + + private Hashtag hashtag; + private Long count; + + public static HashtagCountDto of(Hashtag hashtag, Long count) { + return HashtagCountDto.builder() + .hashtag(hashtag) + .count(count) + .build(); + } + +} diff --git a/src/main/java/com/sluv/server/domain/item/entity/DayHotItem.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/DayHotItem.java similarity index 61% rename from src/main/java/com/sluv/server/domain/item/entity/DayHotItem.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/DayHotItem.java index 41b98ac6..d12382a1 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/DayHotItem.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/DayHotItem.java @@ -1,7 +1,15 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.global.common.entity.BaseEntity; -import jakarta.persistence.*; +import com.sluv.domain.common.entity.BaseEntity; +import jakarta.persistence.Column; +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.Table; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/item/entity/EfficientItem.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/EfficientItem.java similarity index 91% rename from src/main/java/com/sluv/server/domain/item/entity/EfficientItem.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/EfficientItem.java index 806f6a0b..df1d4208 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/EfficientItem.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/EfficientItem.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/item/entity/Item.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/Item.java similarity index 87% rename from src/main/java/com/sluv/server/domain/item/entity/Item.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/Item.java index 9dc02c94..ab0ce158 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/Item.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/Item.java @@ -1,13 +1,13 @@ -package com.sluv.server.domain.item.entity; - -import com.sluv.server.domain.brand.entity.Brand; -import com.sluv.server.domain.brand.entity.NewBrand; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.item.dto.ItemPostReqDto; -import com.sluv.server.domain.item.enums.ItemStatus; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +package com.sluv.domain.item.entity; + +import com.sluv.domain.brand.entity.Brand; +import com.sluv.domain.brand.entity.NewBrand; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.item.dto.ItemSaveDto; +import com.sluv.domain.item.enums.ItemStatus; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -100,7 +100,7 @@ public class Item extends BaseEntity { */ public static Item toEntity(User user, Celeb celeb, NewCeleb newCeleb, ItemCategory itemCategory, Brand brand, NewBrand newBrand, - ItemPostReqDto dto) { + ItemSaveDto dto) { return Item.builder() .user(user) .celeb(celeb) @@ -123,7 +123,7 @@ public static Item toEntity(User user, Celeb celeb, NewCeleb newCeleb, */ public static Item toEntity(Long id, User user, Celeb celeb, NewCeleb newCeleb, ItemCategory itemCategory, Brand brand, NewBrand newBrand, - ItemPostReqDto dto, Long viewNum) { + ItemSaveDto dto, Long viewNum) { return Item.builder() .id(id) .user(user) diff --git a/src/main/java/com/sluv/server/domain/item/entity/ItemCategory.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemCategory.java similarity index 90% rename from src/main/java/com/sluv/server/domain/item/entity/ItemCategory.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemCategory.java index 8660b862..6b014c95 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/ItemCategory.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemCategory.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/item/entity/ItemEditReq.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemEditReq.java similarity index 79% rename from src/main/java/com/sluv/server/domain/item/entity/ItemEditReq.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemEditReq.java index 882bd6b7..af61fbfa 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/ItemEditReq.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemEditReq.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.domain.item.dto.ItemEditReqDto; -import com.sluv.server.domain.item.enums.ItemEditReqReason; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.item.enums.ItemEditReqReason; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -52,12 +51,12 @@ public class ItemEditReq extends BaseEntity { @Size(max = 1002) private String content; - public static ItemEditReq toEntity(User user, Item item, ItemEditReqDto dto) { + public static ItemEditReq toEntity(User user, Item item, ItemEditReqReason reason, String content) { return ItemEditReq.builder() .requester(user) .item(item) - .itemEditReqReason(dto.getReason()) - .content(dto.getContent()) + .itemEditReqReason(reason) + .content(content) .build(); } } diff --git a/src/main/java/com/sluv/server/domain/item/entity/ItemImg.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemImg.java similarity index 85% rename from src/main/java/com/sluv/server/domain/item/entity/ItemImg.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemImg.java index 11c0bed4..e9d29808 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/ItemImg.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemImg.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.domain.item.dto.ItemImgResDto; -import com.sluv.server.global.common.entity.BaseEntity; -import com.sluv.server.global.common.enums.ItemImgOrLinkStatus; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.common.enums.ItemImgOrLinkStatus; +import com.sluv.domain.item.dto.ItemImgDto; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -55,7 +55,7 @@ public class ItemImg extends BaseEntity { private Integer sortOrder; - public static ItemImg toEntity(Item item, ItemImgResDto dto) { + public static ItemImg toEntity(Item item, ItemImgDto dto) { return ItemImg.builder() .item(item) .itemImgUrl(dto.getImgUrl()) diff --git a/src/main/java/com/sluv/server/domain/item/entity/ItemLike.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemLike.java similarity index 88% rename from src/main/java/com/sluv/server/domain/item/entity/ItemLike.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemLike.java index 7c55de38..9b7a491f 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/ItemLike.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemLike.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/item/entity/ItemLink.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemLink.java similarity index 82% rename from src/main/java/com/sluv/server/domain/item/entity/ItemLink.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemLink.java index 3a362ee8..eedbbe71 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/ItemLink.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemLink.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.domain.item.dto.ItemLinkResDto; -import com.sluv.server.global.common.entity.BaseEntity; -import com.sluv.server.global.common.enums.ItemImgOrLinkStatus; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.common.enums.ItemImgOrLinkStatus; +import com.sluv.domain.item.dto.ItemLinkDto; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -53,11 +53,12 @@ public class ItemLink extends BaseEntity { private ItemImgOrLinkStatus itemImgOrLinkStatus = ItemImgOrLinkStatus.ACTIVE; - public static ItemLink toEntity(Item item, ItemLinkResDto dto) { + public static ItemLink toEntity(Item item, ItemLinkDto dto) { return ItemLink.builder() .item(item) .linkName(dto.getLinkName()) .itemLinkUrl(dto.getItemLinkUrl()) + .itemImgOrLinkStatus(ItemImgOrLinkStatus.ACTIVE) .build(); } } diff --git a/src/main/java/com/sluv/server/domain/item/entity/ItemReport.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemReport.java similarity index 78% rename from src/main/java/com/sluv/server/domain/item/entity/ItemReport.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemReport.java index fb30b2bf..b8d0e03b 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/ItemReport.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemReport.java @@ -1,10 +1,9 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.domain.item.dto.ItemReportReqDto; -import com.sluv.server.domain.item.enums.ItemReportReason; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; -import com.sluv.server.global.common.enums.ReportStatus; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.common.enums.ReportStatus; +import com.sluv.domain.item.enums.ItemReportReason; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -57,12 +56,13 @@ public class ItemReport extends BaseEntity { @Enumerated(EnumType.STRING) private ReportStatus reportStatus = ReportStatus.WAITING; - public static ItemReport toEntity(Item item, User user, ItemReportReqDto dto) { + public static ItemReport toEntity(Item item, User user, ItemReportReason reason, String content) { return ItemReport.builder() .item(item) .reporter(user) - .itemReportReason(dto.getReason()) - .content(dto.getContent()) + .itemReportReason(reason) + .content(content) .build(); } + } diff --git a/src/main/java/com/sluv/server/domain/item/entity/ItemScrap.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemScrap.java similarity index 89% rename from src/main/java/com/sluv/server/domain/item/entity/ItemScrap.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemScrap.java index a29235bb..b1e392de 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/ItemScrap.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/ItemScrap.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/item/entity/LuxuryItem.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/LuxuryItem.java similarity index 91% rename from src/main/java/com/sluv/server/domain/item/entity/LuxuryItem.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/LuxuryItem.java index 93810d99..c8625359 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/LuxuryItem.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/LuxuryItem.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/item/entity/PlaceRank.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/PlaceRank.java similarity index 77% rename from src/main/java/com/sluv/server/domain/item/entity/PlaceRank.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/PlaceRank.java index 42048114..377facc4 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/PlaceRank.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/PlaceRank.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.domain.item.dto.PlaceRankReqDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -41,10 +40,10 @@ public class PlaceRank extends BaseEntity { @Size(max = 255) private String place; - public static PlaceRank toEntity(User user, PlaceRankReqDto dto) { + public static PlaceRank toEntity(User user, String placeName) { return PlaceRank.builder() .user(user) - .place(dto.getPlaceName()) + .place(placeName) .build(); } } diff --git a/src/main/java/com/sluv/server/domain/item/entity/RecentItem.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/RecentItem.java similarity index 88% rename from src/main/java/com/sluv/server/domain/item/entity/RecentItem.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/RecentItem.java index c0be8034..38bea82a 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/RecentItem.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/RecentItem.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/item/entity/TempItem.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/TempItem.java similarity index 85% rename from src/main/java/com/sluv/server/domain/item/entity/TempItem.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/TempItem.java index 607a80b5..648aca95 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/TempItem.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/TempItem.java @@ -1,13 +1,13 @@ -package com.sluv.server.domain.item.entity; - -import com.sluv.server.domain.brand.entity.Brand; -import com.sluv.server.domain.brand.entity.NewBrand; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.item.dto.TempItemPostReqDto; -import com.sluv.server.domain.item.enums.ItemStatus; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +package com.sluv.domain.item.entity; + +import com.sluv.domain.brand.entity.Brand; +import com.sluv.domain.brand.entity.NewBrand; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.item.dto.TempItemSaveDto; +import com.sluv.domain.item.enums.ItemStatus; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -89,7 +89,7 @@ public class TempItem extends BaseEntity { public static TempItem toEntity(User user, Celeb celeb, NewCeleb newCeleb, ItemCategory category, Brand brand, NewBrand newBrand, - TempItemPostReqDto dto) { + TempItemSaveDto dto) { return TempItem.builder() .user(user) .celeb(celeb) @@ -108,7 +108,7 @@ public static TempItem toEntity(User user, Celeb celeb, NewCeleb newCeleb, public static TempItem toEntity(Long id, User user, Celeb celeb, NewCeleb newCeleb, ItemCategory category, Brand brand, NewBrand newBrand, - TempItemPostReqDto dto) { + TempItemSaveDto dto) { return TempItem.builder() .id(id) .user(user) diff --git a/src/main/java/com/sluv/server/domain/item/entity/TempItemImg.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/TempItemImg.java similarity index 88% rename from src/main/java/com/sluv/server/domain/item/entity/TempItemImg.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/TempItemImg.java index 58c1e098..ad5bd12e 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/TempItemImg.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/TempItemImg.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.domain.item.dto.ItemImgResDto; -import com.sluv.server.global.common.entity.BaseEntity; -import com.sluv.server.global.common.enums.ItemImgOrLinkStatus; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.common.enums.ItemImgOrLinkStatus; +import com.sluv.domain.item.dto.ItemImgDto; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -54,7 +54,7 @@ public class TempItemImg extends BaseEntity { private Integer sortOrder; - public static TempItemImg toEntity(TempItem tempItem, ItemImgResDto dto) { + public static TempItemImg toEntity(TempItem tempItem, ItemImgDto dto) { return TempItemImg.builder() .tempItem(tempItem) .tempItemImgUrl(dto.getImgUrl()) diff --git a/src/main/java/com/sluv/server/domain/item/entity/TempItemLink.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/TempItemLink.java similarity index 87% rename from src/main/java/com/sluv/server/domain/item/entity/TempItemLink.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/TempItemLink.java index a301ff19..5ef7f0cb 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/TempItemLink.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/TempItemLink.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.domain.item.dto.ItemLinkResDto; -import com.sluv.server.global.common.entity.BaseEntity; -import com.sluv.server.global.common.enums.ItemImgOrLinkStatus; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.common.enums.ItemImgOrLinkStatus; +import com.sluv.domain.item.dto.ItemLinkDto; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -49,7 +49,7 @@ public class TempItemLink extends BaseEntity { @Column(length = 45, columnDefinition = "varchar(45) default 'ACTIVE'") private ItemImgOrLinkStatus itemImgOrLinkStatus = ItemImgOrLinkStatus.ACTIVE; - public static TempItemLink toEntity(TempItem tempItem, ItemLinkResDto dto) { + public static TempItemLink toEntity(TempItem tempItem, ItemLinkDto dto) { return TempItemLink.builder() .tempItem(tempItem) .linkName(dto.getLinkName()) diff --git a/src/main/java/com/sluv/server/domain/item/entity/WeekHotItem.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/WeekHotItem.java similarity index 62% rename from src/main/java/com/sluv/server/domain/item/entity/WeekHotItem.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/WeekHotItem.java index 611eea2a..c15ad69f 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/WeekHotItem.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/WeekHotItem.java @@ -1,7 +1,15 @@ -package com.sluv.server.domain.item.entity; +package com.sluv.domain.item.entity; -import com.sluv.server.global.common.entity.BaseEntity; -import jakarta.persistence.*; +import com.sluv.domain.common.entity.BaseEntity; +import jakarta.persistence.Column; +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.Table; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/item/entity/hashtag/Hashtag.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/Hashtag.java similarity index 92% rename from src/main/java/com/sluv/server/domain/item/entity/hashtag/Hashtag.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/Hashtag.java index 0cc6d0b0..3f6142b0 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/hashtag/Hashtag.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/Hashtag.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.entity.hashtag; +package com.sluv.domain.item.entity.hashtag; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; diff --git a/src/main/java/com/sluv/server/domain/item/entity/hashtag/HashtagStatus.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/HashtagStatus.java similarity index 51% rename from src/main/java/com/sluv/server/domain/item/entity/hashtag/HashtagStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/HashtagStatus.java index e5d68c71..a18d7086 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/hashtag/HashtagStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/HashtagStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.item.entity.hashtag; +package com.sluv.domain.item.entity.hashtag; public enum HashtagStatus { ACTIVE, diff --git a/src/main/java/com/sluv/server/domain/item/entity/hashtag/ItemHashtag.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/ItemHashtag.java similarity index 88% rename from src/main/java/com/sluv/server/domain/item/entity/hashtag/ItemHashtag.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/ItemHashtag.java index 89cef961..e8b1e2d0 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/hashtag/ItemHashtag.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/ItemHashtag.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.item.entity.hashtag; +package com.sluv.domain.item.entity.hashtag; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.item.entity.Item; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/item/entity/hashtag/TempItemHashtag.java b/sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/TempItemHashtag.java similarity index 88% rename from src/main/java/com/sluv/server/domain/item/entity/hashtag/TempItemHashtag.java rename to sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/TempItemHashtag.java index 203032e7..6bbf8389 100644 --- a/src/main/java/com/sluv/server/domain/item/entity/hashtag/TempItemHashtag.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/entity/hashtag/TempItemHashtag.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.item.entity.hashtag; +package com.sluv.domain.item.entity.hashtag; -import com.sluv.server.domain.item.entity.TempItem; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.item.entity.TempItem; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/item/enums/ItemEditReqReason.java b/sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemEditReqReason.java similarity index 80% rename from src/main/java/com/sluv/server/domain/item/enums/ItemEditReqReason.java rename to sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemEditReqReason.java index d12d479a..0a640503 100644 --- a/src/main/java/com/sluv/server/domain/item/enums/ItemEditReqReason.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemEditReqReason.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.item.enums; +package com.sluv.domain.item.enums; public enum ItemEditReqReason { WRONG_CELEB, diff --git a/src/main/java/com/sluv/server/domain/item/enums/ItemNumberConfig.java b/sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemNumberConfig.java similarity index 83% rename from src/main/java/com/sluv/server/domain/item/enums/ItemNumberConfig.java rename to sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemNumberConfig.java index 5e7b5673..568681ae 100644 --- a/src/main/java/com/sluv/server/domain/item/enums/ItemNumberConfig.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemNumberConfig.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.item.enums; +package com.sluv.domain.item.enums; import lombok.Getter; diff --git a/src/main/java/com/sluv/server/domain/item/enums/ItemReportReason.java b/sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemReportReason.java similarity index 75% rename from src/main/java/com/sluv/server/domain/item/enums/ItemReportReason.java rename to sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemReportReason.java index 7c3c4af9..771e6f85 100644 --- a/src/main/java/com/sluv/server/domain/item/enums/ItemReportReason.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemReportReason.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.item.enums; +package com.sluv.domain.item.enums; public enum ItemReportReason { SPAM_OR_AD, diff --git a/src/main/java/com/sluv/server/domain/item/enums/ItemStatus.java b/sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemStatus.java similarity index 60% rename from src/main/java/com/sluv/server/domain/item/enums/ItemStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemStatus.java index 7944eaf2..aa942f83 100644 --- a/src/main/java/com/sluv/server/domain/item/enums/ItemStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/enums/ItemStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.item.enums; +package com.sluv.domain.item.enums; public enum ItemStatus { ACTIVE, diff --git a/src/main/java/com/sluv/server/domain/item/exception/ItemCategoryNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemCategoryNotFoundException.java similarity index 65% rename from src/main/java/com/sluv/server/domain/item/exception/ItemCategoryNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemCategoryNotFoundException.java index 40f5d159..4d23aa9f 100644 --- a/src/main/java/com/sluv/server/domain/item/exception/ItemCategoryNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemCategoryNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.item.exception; +package com.sluv.domain.item.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class ItemCategoryNotFoundException extends ItemException { private static final int ERROR_CODE = 2003; private static final String MESSAGE = "존재하지 않는 아이템 카테고리입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public ItemCategoryNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemException.java b/sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemException.java new file mode 100644 index 00000000..1668bd63 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.item.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class ItemException extends ApplicationException { + public ItemException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/domain/item/exception/ItemNotActiveException.java b/sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemNotActiveException.java similarity index 63% rename from src/main/java/com/sluv/server/domain/item/exception/ItemNotActiveException.java rename to sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemNotActiveException.java index 76ea3fe4..e316be57 100644 --- a/src/main/java/com/sluv/server/domain/item/exception/ItemNotActiveException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemNotActiveException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.item.exception; +package com.sluv.domain.item.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class ItemNotActiveException extends ItemException { private static final int ERROR_CODE = 2025; private static final String MESSAGE = "ACTIVE 상태의 Item이 아닙니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public ItemNotActiveException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/item/exception/ItemNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemNotFoundException.java similarity index 62% rename from src/main/java/com/sluv/server/domain/item/exception/ItemNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemNotFoundException.java index d9f0c031..807f424f 100644 --- a/src/main/java/com/sluv/server/domain/item/exception/ItemNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.item.exception; +package com.sluv.domain.item.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class ItemNotFoundException extends ItemException { private static final int ERROR_CODE = 2009; private static final String MESSAGE = "존재하지 않는 Item입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public ItemNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/item/exception/ItemReportDuplicateException.java b/sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemReportDuplicateException.java similarity index 64% rename from src/main/java/com/sluv/server/domain/item/exception/ItemReportDuplicateException.java rename to sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemReportDuplicateException.java index d7c44e44..4a8db125 100644 --- a/src/main/java/com/sluv/server/domain/item/exception/ItemReportDuplicateException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/exception/ItemReportDuplicateException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.item.exception; +package com.sluv.domain.item.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class ItemReportDuplicateException extends ItemException { private static final int ERROR_CODE = 2011; private static final String MESSAGE = "중복된 아이템 게시글 신고입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public ItemReportDuplicateException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/item/exception/StandardNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/item/exception/StandardNotFoundException.java similarity index 63% rename from src/main/java/com/sluv/server/domain/item/exception/StandardNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/item/exception/StandardNotFoundException.java index 74cea659..64d2f5f7 100644 --- a/src/main/java/com/sluv/server/domain/item/exception/StandardNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/exception/StandardNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.item.exception; +package com.sluv.domain.item.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class StandardNotFoundException extends ItemException { private static final int ERROR_CODE = 2021; private static final String MESSAGE = "존재하지 않는 Standard입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public StandardNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/item/exception/TempItemNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/item/exception/TempItemNotFoundException.java similarity index 63% rename from src/main/java/com/sluv/server/domain/item/exception/TempItemNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/item/exception/TempItemNotFoundException.java index 6dadbd62..e5a425f4 100644 --- a/src/main/java/com/sluv/server/domain/item/exception/TempItemNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/exception/TempItemNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.item.exception; +package com.sluv.domain.item.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class TempItemNotFoundException extends ItemException { private static final int ERROR_CODE = 2008; private static final String MESSAGE = "존재하지 않는 Temp Item입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public TempItemNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/exception/hashtag/HashtagException.java b/sluv-domain/src/main/java/com/sluv/domain/item/exception/hashtag/HashtagException.java new file mode 100644 index 00000000..b23e5e53 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/exception/hashtag/HashtagException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.item.exception.hashtag; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class HashtagException extends ApplicationException { + public HashtagException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/domain/item/exception/hashtag/HashtagNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/item/exception/hashtag/HashtagNotFoundException.java similarity index 62% rename from src/main/java/com/sluv/server/domain/item/exception/hashtag/HashtagNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/item/exception/hashtag/HashtagNotFoundException.java index 298b2e45..81f0b8f9 100644 --- a/src/main/java/com/sluv/server/domain/item/exception/hashtag/HashtagNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/exception/hashtag/HashtagNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.item.exception.hashtag; +package com.sluv.domain.item.exception.hashtag; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class HashtagNotFoundException extends HashtagException { private static final int ERROR_CODE = 2029; private static final String MESSAGE = "존재하지 않는 Hashtag입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public HashtagNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/item/repository/DayHotItemRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/DayHotItemRepository.java similarity index 58% rename from src/main/java/com/sluv/server/domain/item/repository/DayHotItemRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/DayHotItemRepository.java index 50cf7737..867cb0bb 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/DayHotItemRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/DayHotItemRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.repository; +package com.sluv.domain.item.repository; -import com.sluv.server.domain.item.entity.DayHotItem; +import com.sluv.domain.item.entity.DayHotItem; import org.springframework.data.jpa.repository.JpaRepository; public interface DayHotItemRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/item/repository/EfficientItemRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/EfficientItemRepository.java similarity index 59% rename from src/main/java/com/sluv/server/domain/item/repository/EfficientItemRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/EfficientItemRepository.java index 5a648483..349a7520 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/EfficientItemRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/EfficientItemRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.repository; +package com.sluv.domain.item.repository; -import com.sluv.server.domain.item.entity.EfficientItem; +import com.sluv.domain.item.entity.EfficientItem; import org.springframework.data.jpa.repository.JpaRepository; public interface EfficientItemRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/item/repository/ItemCategoryRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemCategoryRepository.java similarity index 72% rename from src/main/java/com/sluv/server/domain/item/repository/ItemCategoryRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemCategoryRepository.java index 08257778..cc46d006 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/ItemCategoryRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemCategoryRepository.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.item.repository; - -import com.sluv.server.domain.item.entity.ItemCategory; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.item.repository; +import com.sluv.domain.item.entity.ItemCategory; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface ItemCategoryRepository extends JpaRepository { List findAllByParentNotNull(); diff --git a/src/main/java/com/sluv/server/domain/item/repository/ItemEditReqRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemEditReqRepository.java similarity index 58% rename from src/main/java/com/sluv/server/domain/item/repository/ItemEditReqRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemEditReqRepository.java index 556687a5..64699ab0 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/ItemEditReqRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemEditReqRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.repository; +package com.sluv.domain.item.repository; -import com.sluv.server.domain.item.entity.ItemEditReq; +import com.sluv.domain.item.entity.ItemEditReq; import org.springframework.data.jpa.repository.JpaRepository; public interface ItemEditReqRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/item/repository/ItemImgRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemImgRepository.java similarity index 61% rename from src/main/java/com/sluv/server/domain/item/repository/ItemImgRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemImgRepository.java index 870a6520..cda96446 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/ItemImgRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemImgRepository.java @@ -1,10 +1,9 @@ -package com.sluv.server.domain.item.repository; - -import com.sluv.server.domain.item.entity.ItemImg; -import com.sluv.server.domain.item.repository.impl.ItemImgRepositoryCustom; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.item.repository; +import com.sluv.domain.item.entity.ItemImg; +import com.sluv.domain.item.repository.impl.ItemImgRepositoryCustom; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface ItemImgRepository extends JpaRepository, ItemImgRepositoryCustom { List findAllByItemId(Long itemId); diff --git a/src/main/java/com/sluv/server/domain/item/repository/ItemLikeRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemLikeRepository.java similarity index 74% rename from src/main/java/com/sluv/server/domain/item/repository/ItemLikeRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemLikeRepository.java index 392d7074..ddd081a6 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/ItemLikeRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemLikeRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.repository; +package com.sluv.domain.item.repository; -import com.sluv.server.domain.item.entity.ItemLike; +import com.sluv.domain.item.entity.ItemLike; import org.springframework.data.jpa.repository.JpaRepository; public interface ItemLikeRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/item/repository/ItemLinkRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemLinkRepository.java similarity index 66% rename from src/main/java/com/sluv/server/domain/item/repository/ItemLinkRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemLinkRepository.java index db609f8d..d8ac5c4f 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/ItemLinkRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemLinkRepository.java @@ -1,12 +1,13 @@ -package com.sluv.server.domain.item.repository; - -import com.sluv.server.domain.item.entity.ItemLink; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.item.repository; +import com.sluv.domain.item.entity.ItemLink; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface ItemLinkRepository extends JpaRepository { List findByItemId(Long itemId); void deleteAllByItemId(Long itemId); + + Integer countByItemId(Long itemId); } diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemReportRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemReportRepository.java new file mode 100644 index 00000000..aef15974 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemReportRepository.java @@ -0,0 +1,9 @@ +package com.sluv.domain.item.repository; + +import com.sluv.domain.item.entity.ItemReport; +import com.sluv.domain.item.repository.impl.ItemReportRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ItemReportRepository extends JpaRepository, ItemReportRepositoryCustom { + +} diff --git a/src/main/java/com/sluv/server/domain/item/repository/ItemRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemRepository.java similarity index 61% rename from src/main/java/com/sluv/server/domain/item/repository/ItemRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemRepository.java index d480b330..c6c3a8f0 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/ItemRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemRepository.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.item.repository; +package com.sluv.domain.item.repository; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.enums.ItemStatus; -import com.sluv.server.domain.item.repository.impl.ItemRepositoryCustom; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.enums.ItemStatus; +import com.sluv.domain.item.repository.impl.ItemRepositoryCustom; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/sluv/server/domain/item/repository/ItemScrapRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemScrapRepository.java similarity index 70% rename from src/main/java/com/sluv/server/domain/item/repository/ItemScrapRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemScrapRepository.java index af002d99..cc901db5 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/ItemScrapRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/ItemScrapRepository.java @@ -1,11 +1,9 @@ -package com.sluv.server.domain.item.repository; +package com.sluv.domain.item.repository; -import com.sluv.server.domain.item.entity.ItemScrap; -import com.sluv.server.domain.item.repository.impl.ItemScrapRepositoryCustom; +import com.sluv.domain.item.entity.ItemScrap; +import com.sluv.domain.item.repository.impl.ItemScrapRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.List; - public interface ItemScrapRepository extends JpaRepository, ItemScrapRepositoryCustom { void deleteAllByClosetId(Long id); diff --git a/src/main/java/com/sluv/server/domain/item/repository/LuxuryItemRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/LuxuryItemRepository.java similarity index 58% rename from src/main/java/com/sluv/server/domain/item/repository/LuxuryItemRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/LuxuryItemRepository.java index e7f8ff1e..019f1152 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/LuxuryItemRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/LuxuryItemRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.repository; +package com.sluv.domain.item.repository; -import com.sluv.server.domain.item.entity.LuxuryItem; +import com.sluv.domain.item.entity.LuxuryItem; import org.springframework.data.jpa.repository.JpaRepository; public interface LuxuryItemRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/item/repository/PlaceRankRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/PlaceRankRepository.java similarity index 51% rename from src/main/java/com/sluv/server/domain/item/repository/PlaceRankRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/PlaceRankRepository.java index cc061ad8..23c396d5 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/PlaceRankRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/PlaceRankRepository.java @@ -1,12 +1,9 @@ -package com.sluv.server.domain.item.repository; +package com.sluv.domain.item.repository; -import com.sluv.server.domain.item.entity.PlaceRank; -import com.sluv.server.domain.item.repository.impl.PlaceRankRepositoryCustom; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.item.entity.PlaceRank; +import com.sluv.domain.item.repository.impl.PlaceRankRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.Arrays; - public interface PlaceRankRepository extends JpaRepository, PlaceRankRepositoryCustom { void deleteAllByUserId(Long id); diff --git a/src/main/java/com/sluv/server/domain/item/repository/RecentItemRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/RecentItemRepository.java similarity index 54% rename from src/main/java/com/sluv/server/domain/item/repository/RecentItemRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/RecentItemRepository.java index 90874035..5d6789a8 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/RecentItemRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/RecentItemRepository.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.item.repository; +package com.sluv.domain.item.repository; -import com.sluv.server.domain.item.entity.RecentItem; -import com.sluv.server.domain.item.repository.impl.RecentItemRepositoryCustom; +import com.sluv.domain.item.entity.RecentItem; +import com.sluv.domain.item.repository.impl.RecentItemRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; public interface RecentItemRepository extends JpaRepository, RecentItemRepositoryCustom { diff --git a/src/main/java/com/sluv/server/domain/item/repository/TempItemImgRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/TempItemImgRepository.java similarity index 50% rename from src/main/java/com/sluv/server/domain/item/repository/TempItemImgRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/TempItemImgRepository.java index 457a643b..b326d806 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/TempItemImgRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/TempItemImgRepository.java @@ -1,12 +1,12 @@ -package com.sluv.server.domain.item.repository; - -import com.sluv.server.domain.item.entity.TempItem; -import com.sluv.server.domain.item.entity.TempItemImg; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.item.repository; +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.TempItemImg; +import com.sluv.domain.item.repository.impl.TempItemImgRepositoryCustom; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; -public interface TempItemImgRepository extends JpaRepository { +public interface TempItemImgRepository extends JpaRepository, TempItemImgRepositoryCustom { List findAllByTempItem(TempItem tempItem); void deleteAllByTempItemId(Long id); diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/TempItemLinkRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/TempItemLinkRepository.java new file mode 100644 index 00000000..d1b416d0 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/TempItemLinkRepository.java @@ -0,0 +1,13 @@ +package com.sluv.domain.item.repository; + +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.TempItemLink; +import com.sluv.domain.item.repository.impl.TempItemLinkRepositoryCustom; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TempItemLinkRepository extends JpaRepository, TempItemLinkRepositoryCustom { + List findAllByTempItem(TempItem tempItem); + + void deleteAllByTempItemId(Long id); +} diff --git a/src/main/java/com/sluv/server/domain/item/repository/TempItemRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/TempItemRepository.java similarity index 57% rename from src/main/java/com/sluv/server/domain/item/repository/TempItemRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/TempItemRepository.java index ae1161e7..c8f05845 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/TempItemRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/TempItemRepository.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.item.repository; +package com.sluv.domain.item.repository; -import com.sluv.server.domain.item.entity.TempItem; -import com.sluv.server.domain.item.repository.impl.TempItemRepositoryCustom; +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.repository.impl.TempItemRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; public interface TempItemRepository extends JpaRepository, TempItemRepositoryCustom { diff --git a/src/main/java/com/sluv/server/domain/item/repository/WeekHotItemRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/WeekHotItemRepository.java similarity index 58% rename from src/main/java/com/sluv/server/domain/item/repository/WeekHotItemRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/WeekHotItemRepository.java index 5a06c00b..c6192237 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/WeekHotItemRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/WeekHotItemRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.item.repository; +package com.sluv.domain.item.repository; -import com.sluv.server.domain.item.entity.WeekHotItem; +import com.sluv.domain.item.entity.WeekHotItem; import org.springframework.data.jpa.repository.JpaRepository; public interface WeekHotItemRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/item/repository/hashtag/HashtagRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/HashtagRepository.java similarity index 55% rename from src/main/java/com/sluv/server/domain/item/repository/hashtag/HashtagRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/HashtagRepository.java index 1dabb1a2..e245a173 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/hashtag/HashtagRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/HashtagRepository.java @@ -1,10 +1,9 @@ -package com.sluv.server.domain.item.repository.hashtag; - -import com.sluv.server.domain.item.entity.hashtag.Hashtag; -import com.sluv.server.domain.item.repository.hashtag.impl.HashtagRepositoryCustom; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.item.repository.hashtag; +import com.sluv.domain.item.entity.hashtag.Hashtag; +import com.sluv.domain.item.repository.hashtag.impl.HashtagRepositoryCustom; import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; public interface HashtagRepository extends JpaRepository, HashtagRepositoryCustom { diff --git a/src/main/java/com/sluv/server/domain/item/repository/hashtag/ItemHashtagRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/ItemHashtagRepository.java similarity index 68% rename from src/main/java/com/sluv/server/domain/item/repository/hashtag/ItemHashtagRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/ItemHashtagRepository.java index 23f70e47..d74780ee 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/hashtag/ItemHashtagRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/ItemHashtagRepository.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.item.repository.hashtag; - -import com.sluv.server.domain.item.entity.hashtag.ItemHashtag; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.item.repository.hashtag; +import com.sluv.domain.item.entity.hashtag.ItemHashtag; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface ItemHashtagRepository extends JpaRepository { List findAllByItemId(Long itemId); diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/TempItemHashtagRepository.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/TempItemHashtagRepository.java new file mode 100644 index 00000000..018aa97c --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/TempItemHashtagRepository.java @@ -0,0 +1,14 @@ +package com.sluv.domain.item.repository.hashtag; + +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.hashtag.TempItemHashtag; +import com.sluv.domain.item.repository.hashtag.impl.TempItemHashtagRepositoryCustom; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TempItemHashtagRepository extends JpaRepository, + TempItemHashtagRepositoryCustom { + List findAllByTempItem(TempItem tempItem); + + void deleteAllByTempItemId(Long id); +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/HashtagRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/HashtagRepositoryCustom.java new file mode 100644 index 00000000..3c729618 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/HashtagRepositoryCustom.java @@ -0,0 +1,9 @@ +package com.sluv.domain.item.repository.hashtag.impl; + +import com.sluv.domain.item.dto.hashtag.HashtagCountDto; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public interface HashtagRepositoryCustom { + Page findAllByContent(String name, Pageable pageable); +} diff --git a/src/main/java/com/sluv/server/domain/item/repository/hashtag/impl/HashtagRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/HashtagRepositoryImpl.java similarity index 75% rename from src/main/java/com/sluv/server/domain/item/repository/hashtag/impl/HashtagRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/HashtagRepositoryImpl.java index fd167de7..e90ab228 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/hashtag/impl/HashtagRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/HashtagRepositoryImpl.java @@ -1,11 +1,13 @@ -package com.sluv.server.domain.item.repository.hashtag.impl; +package com.sluv.domain.item.repository.hashtag.impl; -import static com.sluv.server.domain.item.entity.hashtag.QItemHashtag.itemHashtag; +import static com.sluv.domain.item.entity.hashtag.QItemHashtag.itemHashtag; import com.querydsl.core.Tuple; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.item.entity.hashtag.HashtagStatus; +import com.sluv.domain.item.dto.hashtag.HashtagCountDto; +import com.sluv.domain.item.entity.hashtag.Hashtag; +import com.sluv.domain.item.entity.hashtag.HashtagStatus; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; @@ -18,7 +20,7 @@ public class HashtagRepositoryImpl implements HashtagRepositoryCustom { private final JPAQueryFactory jpaQueryFactory; @Override - public Page findAllByContent(String name, Pageable pageable) { + public Page findAllByContent(String name, Pageable pageable) { List content; // 미입력 시 @@ -52,6 +54,9 @@ public Page findAllByContent(String name, Pageable pageable) { .groupBy(itemHashtag.hashtag) .orderBy(itemHashtag.hashtag.count().desc()); - return PageableExecutionUtils.getPage(content, pageable, () -> countContent.fetch().size()); + List dtoContent = content.stream() + .map(tuple -> HashtagCountDto.of(tuple.get(0, Hashtag.class), tuple.get(1, Long.class))) + .toList(); + return PageableExecutionUtils.getPage(dtoContent, pageable, () -> countContent.fetch().size()); } } diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/TempItemHashtagRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/TempItemHashtagRepositoryCustom.java new file mode 100644 index 00000000..e0f39bf1 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/TempItemHashtagRepositoryCustom.java @@ -0,0 +1,9 @@ +package com.sluv.domain.item.repository.hashtag.impl; + +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.hashtag.TempItemHashtag; +import java.util.List; + +public interface TempItemHashtagRepositoryCustom { + List findAllByTempItems(List tempItems); +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/TempItemHashtagRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/TempItemHashtagRepositoryImpl.java new file mode 100644 index 00000000..7dc71c66 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/hashtag/impl/TempItemHashtagRepositoryImpl.java @@ -0,0 +1,23 @@ +package com.sluv.domain.item.repository.hashtag.impl; + +import static com.sluv.domain.item.entity.hashtag.QTempItemHashtag.tempItemHashtag; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.hashtag.TempItemHashtag; +import java.util.List; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class TempItemHashtagRepositoryImpl implements TempItemHashtagRepositoryCustom { + + private final JPAQueryFactory jpaQueryFactory; + + @Override + public List findAllByTempItems(List tempItems) { + List itemItemIds = tempItems.stream().map(TempItem::getId).toList(); + return jpaQueryFactory.selectFrom(tempItemHashtag) + .where(tempItemHashtag.tempItem.id.in(itemItemIds)) + .fetch(); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemImgRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemImgRepositoryCustom.java new file mode 100644 index 00000000..7bb46cc4 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemImgRepositoryCustom.java @@ -0,0 +1,7 @@ +package com.sluv.domain.item.repository.impl; + +import com.sluv.domain.item.entity.ItemImg; + +public interface ItemImgRepositoryCustom { + ItemImg findMainImg(Long itemId); +} \ No newline at end of file diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemImgRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemImgRepositoryImpl.java similarity index 75% rename from src/main/java/com/sluv/server/domain/item/repository/impl/ItemImgRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemImgRepositoryImpl.java index 010183a2..0cd84142 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemImgRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemImgRepositoryImpl.java @@ -1,9 +1,9 @@ -package com.sluv.server.domain.item.repository.impl; +package com.sluv.domain.item.repository.impl; -import static com.sluv.server.domain.item.entity.QItemImg.itemImg; +import static com.sluv.domain.item.entity.QItemImg.itemImg; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.item.entity.ItemImg; +import com.sluv.domain.item.entity.ItemImg; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemReportRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemReportRepositoryCustom.java new file mode 100644 index 00000000..30effe76 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemReportRepositoryCustom.java @@ -0,0 +1,8 @@ +package com.sluv.domain.item.repository.impl; + +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.user.entity.User; + +public interface ItemReportRepositoryCustom { + Boolean findExistence(User user, Item target); +} diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemReportRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemReportRepositoryImpl.java similarity index 71% rename from src/main/java/com/sluv/server/domain/item/repository/impl/ItemReportRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemReportRepositoryImpl.java index 55d5bf8f..f1305f04 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemReportRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemReportRepositoryImpl.java @@ -1,10 +1,10 @@ -package com.sluv.server.domain.item.repository.impl; +package com.sluv.domain.item.repository.impl; -import static com.sluv.server.domain.item.entity.QItemReport.itemReport; +import static com.sluv.domain.item.entity.QItemReport.itemReport; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.user.entity.User; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemRepositoryCustom.java similarity index 73% rename from src/main/java/com/sluv/server/domain/item/repository/impl/ItemRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemRepositoryCustom.java index 1ea4495a..b41c3e12 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemRepositoryCustom.java @@ -1,15 +1,16 @@ -package com.sluv.server.domain.item.repository.impl; - -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.search.dto.SearchFilterReqDto; -import com.sluv.server.domain.user.entity.User; -import java.util.List; +package com.sluv.domain.item.repository.impl; + +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.search.dto.SearchFilterReqDto; +import com.sluv.domain.user.entity.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import java.util.List; + public interface ItemRepositoryCustom { List findTopPlace(); @@ -21,7 +22,7 @@ public interface ItemRepositoryCustom { Page getAllScrapItem(User user, Pageable pageable); - Page getClosetItems(Closet closet, Pageable pageable); + Page getClosetItems(Closet closet, Pageable pageable); List getSameClosetItems(Long itemId, List closetList); @@ -45,19 +46,19 @@ public interface ItemRepositoryCustom { Page getLuxuryItem(Pageable pageable, SearchFilterReqDto dto); - List updateLuxuryItem(); + List getItemByOverPrice(int price); Page getEfficientItem(Pageable pageable, SearchFilterReqDto filterReqDto); - List updateEfficientItem(); + List getItemByUnderPrice(int price); - List updateWeekHotItem(); + List getPreviousWeekHotItem(); List getWeekHotItem(); List getDayHotItem(); - List updateDayHotItem(); + List getYesterdayHotItem(); Page getHotCelebItem(Long celebId, Pageable pageable, SearchFilterReqDto dto); @@ -65,7 +66,7 @@ public interface ItemRepositoryCustom { List getHowAboutItem(User user, List interestedCeleb); - List getItemSimpleResDto(User user, List items); + List getItemSimpleDto(User user, List items); Page getUserAllRecentItem(User user, Pageable pageable); diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemRepositoryImpl.java similarity index 86% rename from src/main/java/com/sluv/server/domain/item/repository/impl/ItemRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemRepositoryImpl.java index 9101a722..b0a21dc0 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemRepositoryImpl.java @@ -1,41 +1,29 @@ -package com.sluv.server.domain.item.repository.impl; - -import static com.sluv.server.domain.brand.entity.QBrand.brand; -import static com.sluv.server.domain.brand.entity.QNewBrand.newBrand; -import static com.sluv.server.domain.celeb.entity.QCeleb.celeb; -import static com.sluv.server.domain.celeb.entity.QInterestedCeleb.interestedCeleb; -import static com.sluv.server.domain.celeb.entity.QNewCeleb.newCeleb; -import static com.sluv.server.domain.closet.entity.QCloset.closet; -import static com.sluv.server.domain.item.entity.QDayHotItem.dayHotItem; -import static com.sluv.server.domain.item.entity.QEfficientItem.efficientItem; -import static com.sluv.server.domain.item.entity.QItem.item; -import static com.sluv.server.domain.item.entity.QItemCategory.itemCategory; -import static com.sluv.server.domain.item.entity.QItemImg.itemImg; -import static com.sluv.server.domain.item.entity.QItemLike.itemLike; -import static com.sluv.server.domain.item.entity.QItemLink.itemLink; -import static com.sluv.server.domain.item.entity.QItemScrap.itemScrap; -import static com.sluv.server.domain.item.entity.QLuxuryItem.luxuryItem; -import static com.sluv.server.domain.item.entity.QRecentItem.recentItem; -import static com.sluv.server.domain.item.entity.QWeekHotItem.weekHotItem; -import static com.sluv.server.domain.item.enums.ItemNumberConfig.이_아이템은_어때요_개수; -import static com.sluv.server.domain.item.enums.ItemStatus.ACTIVE; -import static com.sluv.server.domain.user.entity.QUser.user; +package com.sluv.domain.item.repository.impl; import com.querydsl.core.Tuple; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.QCeleb; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.QItemCategory; -import com.sluv.server.domain.item.entity.RecentItem; -import com.sluv.server.domain.search.dto.SearchFilterReqDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.enums.UserStatus; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.QCeleb; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.QItemCategory; +import com.sluv.domain.item.entity.RecentItem; +import com.sluv.domain.item.enums.ItemNumberConfig; +import com.sluv.domain.item.enums.ItemStatus; +import com.sluv.domain.search.dto.SearchFilterReqDto; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.enums.UserStatus; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.support.PageableExecutionUtils; + import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -43,12 +31,25 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.support.PageableExecutionUtils; + +import static com.sluv.domain.brand.entity.QBrand.brand; +import static com.sluv.domain.brand.entity.QNewBrand.newBrand; +import static com.sluv.domain.celeb.entity.QCeleb.celeb; +import static com.sluv.domain.celeb.entity.QInterestedCeleb.interestedCeleb; +import static com.sluv.domain.celeb.entity.QNewCeleb.newCeleb; +import static com.sluv.domain.closet.entity.QCloset.closet; +import static com.sluv.domain.item.entity.QDayHotItem.dayHotItem; +import static com.sluv.domain.item.entity.QEfficientItem.efficientItem; +import static com.sluv.domain.item.entity.QItem.item; +import static com.sluv.domain.item.entity.QItemCategory.itemCategory; +import static com.sluv.domain.item.entity.QItemImg.itemImg; +import static com.sluv.domain.item.entity.QItemLike.itemLike; +import static com.sluv.domain.item.entity.QItemLink.itemLink; +import static com.sluv.domain.item.entity.QItemScrap.itemScrap; +import static com.sluv.domain.item.entity.QLuxuryItem.luxuryItem; +import static com.sluv.domain.item.entity.QRecentItem.recentItem; +import static com.sluv.domain.item.entity.QWeekHotItem.weekHotItem; +import static com.sluv.domain.user.entity.QUser.user; @Slf4j @RequiredArgsConstructor @@ -69,7 +70,8 @@ public List findTopPlace() { @Override public List findSameCelebItem(Long itemId, Long celebId, boolean celebJudge) { return jpaQueryFactory.selectFrom(item) - .where(getSameCelebId(celebId, celebJudge).and(item.id.ne(itemId)).and(item.itemStatus.eq(ACTIVE))) + .where(getSameCelebId(celebId, celebJudge).and(item.id.ne(itemId)).and(item.itemStatus.eq( + ItemStatus.ACTIVE))) .limit(10) .orderBy(item.createdAt.desc()) .fetch(); @@ -86,7 +88,8 @@ private BooleanExpression getSameCelebId(Long celebId, boolean celebJudge) { @Override public List findSameBrandItem(Long itemId, Long brandId, boolean brandJudge) { return jpaQueryFactory.selectFrom(item) - .where(getSameBrandId(brandId, brandJudge).and(item.id.ne(itemId)).and(item.itemStatus.eq(ACTIVE))) + .where(getSameBrandId(brandId, brandJudge).and(item.id.ne(itemId)).and(item.itemStatus.eq( + ItemStatus.ACTIVE))) .limit(10) .orderBy(item.createdAt.desc()) .fetch(); @@ -107,7 +110,7 @@ public Page getRecentItem(User user, Pageable pageable) { List content = jpaQueryFactory.select(item) .from(recentItem) .leftJoin(recentItem.item, item) - .where(recentItem.user.eq(user).and(item.itemStatus.eq(ACTIVE))) + .where(recentItem.user.eq(user).and(item.itemStatus.eq(ItemStatus.ACTIVE))) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .groupBy(item) @@ -133,7 +136,7 @@ public Page getAllScrapItem(User _user, Pageable pageable) { .from(itemScrap) .leftJoin(itemScrap.closet, closet) .leftJoin(closet.user, user) - .where(closet.user.eq(_user).and(item.itemStatus.eq(ACTIVE))) + .where(closet.user.eq(_user).and(item.itemStatus.eq(ItemStatus.ACTIVE))) .orderBy(itemScrap.createdAt.desc()) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -151,7 +154,7 @@ public Page getAllScrapItem(User _user, Pageable pageable) { } @Override - public Page getClosetItems(Closet closets, Pageable pageable) { + public Page getClosetItems(Closet closets, Pageable pageable) { // List content = jpaQueryFactory.select(item) // .from(itemScrap) // .leftJoin(itemScrap.item, item) @@ -169,7 +172,7 @@ public Page getClosetItems(Closet closets, Pageable pageable) .leftJoin(itemScrap).on(itemScrap.item.eq(item).and(itemScrap.closet.in(closets))).fetchJoin() .where(itemScrap.closet.eq(closets) .and(itemImg.representFlag.eq(true)) - .and(item.itemStatus.eq(ACTIVE)) + .and(item.itemStatus.eq(ItemStatus.ACTIVE)) ) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -185,12 +188,12 @@ public Page getClosetItems(Closet closets, Pageable pageable) .leftJoin(itemScrap).on(itemScrap.item.eq(item).and(itemScrap.closet.in(closets))).fetchJoin() .where(itemScrap.closet.eq(closets) .and(itemImg.representFlag.eq(true)) - .and(item.itemStatus.eq(ACTIVE)) + .and(item.itemStatus.eq(ItemStatus.ACTIVE)) ) .orderBy(itemScrap.createdAt.desc()); return PageableExecutionUtils.getPage(content.stream() - .map(tuple -> ItemSimpleResDto.of(tuple.get(item), tuple.get(itemImg), tuple.get(itemScrap) != null)) + .map(tuple -> ItemSimpleDto.of(tuple.get(item), tuple.get(itemImg), tuple.get(itemScrap) != null)) .toList(), pageable, () -> countJPAQuery.fetch().size()); } @@ -199,7 +202,8 @@ public List getSameClosetItems(Long itemId, List closetList) { return jpaQueryFactory.select(item) .from(itemScrap) .leftJoin(itemScrap.item, item) - .where(itemScrap.closet.in(closetList).and(item.id.ne(itemId)).and(item.itemStatus.eq(ACTIVE))) + .where(itemScrap.closet.in(closetList).and(item.id.ne(itemId)) + .and(item.itemStatus.eq(ItemStatus.ACTIVE))) .groupBy(item) .orderBy(itemScrap.createdAt.max().desc()) .limit(10) @@ -217,7 +221,7 @@ public Page getSearchItem(List itemIdList, SearchFilterReqDto dto, P .leftJoin(itemLike).on(itemLike.item.eq(item)) .leftJoin(itemScrap).on(itemScrap.item.eq(item)) .groupBy(item) - .where(item.id.in(itemIdList).and(item.itemStatus.eq(ACTIVE))) + .where(item.id.in(itemIdList).and(item.itemStatus.eq(ItemStatus.ACTIVE))) .orderBy(getSearchItemOrder(pageable.getSort())); // Filter 조건 추가 addFilterWhere(query, dto); @@ -233,7 +237,7 @@ public Page getSearchItem(List itemIdList, SearchFilterReqDto dto, P .leftJoin(itemLike).on(itemLike.item.eq(item)) .leftJoin(itemScrap).on(itemScrap.item.eq(item)) .groupBy(item) - .where(item.id.in(itemIdList).and(item.itemStatus.eq(ACTIVE))) + .where(item.id.in(itemIdList).and(item.itemStatus.eq(ItemStatus.ACTIVE))) .orderBy(getSearchItemOrder(pageable.getSort())); return PageableExecutionUtils.getPage(content, pageable, () -> countQuery.fetch().size()); @@ -250,7 +254,7 @@ public Page getRecommendItemPage(Pageable pageable) { .limit(pageable.getPageSize()) .orderBy(itemLike.count().add(itemScrap.count()).add(item.viewNum).desc()) .orderBy(item.whenDiscovery.desc()) - .where(item.itemStatus.eq(ACTIVE)) + .where(item.itemStatus.eq(ItemStatus.ACTIVE)) .fetch(); // Count Query @@ -261,7 +265,7 @@ public Page getRecommendItemPage(Pageable pageable) { .groupBy(item) .orderBy(itemLike.count().add(itemScrap.count()).add(item.viewNum).desc()) .orderBy(item.whenDiscovery.desc()) - .where(item.itemStatus.eq(ACTIVE)); + .where(item.itemStatus.eq(ItemStatus.ACTIVE)); return PageableExecutionUtils.getPage(content, pageable, () -> countJPAQuery.fetch().size()); } @@ -361,7 +365,7 @@ public List getRecentTop2Item(User targetUser) { return jpaQueryFactory.selectFrom(item) .where(item.user.eq(targetUser) - .and(item.itemStatus.eq(ACTIVE)) + .and(item.itemStatus.eq(ItemStatus.ACTIVE)) ) .limit(2) .orderBy(item.id.desc()) @@ -374,7 +378,7 @@ public List getRecentTop2Item(User targetUser) { @Override public Page getUserAllItem(Long userId, Pageable pageable) { List content = jpaQueryFactory.selectFrom(item) - .where(item.user.id.eq(userId).and(item.itemStatus.eq(ACTIVE))) + .where(item.user.id.eq(userId).and(item.itemStatus.eq(ItemStatus.ACTIVE))) .orderBy(item.id.desc()) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -382,7 +386,7 @@ public Page getUserAllItem(Long userId, Pageable pageable) { // Count Query JPAQuery query = jpaQueryFactory.selectFrom(item) - .where(item.user.id.eq(userId).and(item.itemStatus.eq(ACTIVE))) + .where(item.user.id.eq(userId).and(item.itemStatus.eq(ItemStatus.ACTIVE))) .orderBy(item.id.desc()); return PageableExecutionUtils.getPage(content, pageable, () -> query.fetch().size()); @@ -395,7 +399,7 @@ public Page getUserAllItem(Long userId, Pageable pageable) { public Page getAllByUserLikeItem(User user, Pageable pageable) { List content = jpaQueryFactory.select(item) .from(itemLike) - .where(itemLike.user.eq(user).and(itemLike.item.itemStatus.eq(ACTIVE))) + .where(itemLike.user.eq(user).and(itemLike.item.itemStatus.eq(ItemStatus.ACTIVE))) .orderBy(itemLike.id.desc()) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -405,7 +409,7 @@ public Page getAllByUserLikeItem(User user, Pageable pageable) { JPAQuery query = jpaQueryFactory.select(item) .from(itemLike) .leftJoin(item).on(itemLike.item.eq(item)) - .where(itemLike.user.eq(user).and(itemLike.item.itemStatus.eq(ACTIVE))) + .where(itemLike.user.eq(user).and(itemLike.item.itemStatus.eq(ItemStatus.ACTIVE))) .orderBy(itemLike.id.desc()); return PageableExecutionUtils.getPage(content, pageable, () -> query.fetch().size()); @@ -428,7 +432,7 @@ public Page getCelebSummerItem(Pageable pageable, SearchFilterReqDto dto) JPAQuery query = jpaQueryFactory.selectFrom(item) .where(item.category.id.in(categortIdList) - .and(item.itemStatus.eq(ACTIVE)) + .and(item.itemStatus.eq(ItemStatus.ACTIVE)) ) .orderBy(getSearchItemOrder(pageable.getSort())); // Filter 추가 @@ -442,7 +446,7 @@ public Page getCelebSummerItem(Pageable pageable, SearchFilterReqDto dto) // Count Query JPAQuery countQuery = jpaQueryFactory.selectFrom(item) .where(item.category.id.in(categortIdList) - .and(item.itemStatus.eq(ACTIVE)) + .and(item.itemStatus.eq(ItemStatus.ACTIVE)) ) .orderBy(getSearchItemOrder(pageable.getSort())); // Filter 추가 @@ -459,7 +463,7 @@ public Page getNowBuyItem(Pageable pageable, SearchFilterReqDto dto) { log.info("지금 당장 구매 가능한 아이템 조회 Query"); JPAQuery query = jpaQueryFactory.selectFrom(item) .leftJoin(itemLink).on(itemLink.item.eq(item)) - .where(item.itemStatus.eq(ACTIVE).and(itemLink.item.isNotNull())) + .where(item.itemStatus.eq(ItemStatus.ACTIVE).and(itemLink.item.isNotNull())) .groupBy(item) .orderBy(item.createdAt.desc()); // Filter 추가 @@ -474,7 +478,7 @@ public Page getNowBuyItem(Pageable pageable, SearchFilterReqDto dto) { // Count Query JPAQuery countQuery = jpaQueryFactory.selectFrom(item) .leftJoin(itemLink).on(itemLink.item.eq(item)) - .where(item.itemStatus.eq(ACTIVE).and(itemLink.item.isNotNull())) + .where(item.itemStatus.eq(ItemStatus.ACTIVE).and(itemLink.item.isNotNull())) .groupBy(item) .orderBy(item.createdAt.desc()); // Filter 추가 @@ -492,7 +496,7 @@ public Page getNewItem(Pageable pageable) { LocalDateTime nowTime = LocalDateTime.now(); List content = jpaQueryFactory.selectFrom(item) - .where(item.itemStatus.eq(ACTIVE) + .where(item.itemStatus.eq(ItemStatus.ACTIVE) // .and(item.createdAt.between(nowTime.minusHours(1L), nowTime)) ) .orderBy(item.whenDiscovery.desc()) @@ -502,7 +506,7 @@ public Page getNewItem(Pageable pageable) { // Count Query JPAQuery countQuery = jpaQueryFactory.selectFrom(item) - .where(item.itemStatus.eq(ACTIVE) + .where(item.itemStatus.eq(ItemStatus.ACTIVE) // .and(item.createdAt.between(nowTime.minusHours(1L), nowTime)) ) .orderBy(item.whenDiscovery.desc()); @@ -522,7 +526,7 @@ public Page getLuxuryItem(Pageable pageable, SearchFilterReqDto dto) { .leftJoin(item).on(luxuryItem.item.eq(item)) .leftJoin(itemLike).on(itemLike.item.eq(item)) .leftJoin(itemScrap).on(itemScrap.item.eq(item)) - .where(item.itemStatus.eq(ACTIVE)) + .where(item.itemStatus.eq(ItemStatus.ACTIVE)) .groupBy(item); addFilterWhere(query, dto); @@ -539,7 +543,7 @@ public Page getLuxuryItem(Pageable pageable, SearchFilterReqDto dto) { .leftJoin(item).on(luxuryItem.item.eq(item)) .leftJoin(itemLike).on(itemLike.item.eq(item)) .leftJoin(itemScrap).on(itemScrap.item.eq(item)) - .where(item.itemStatus.eq(ACTIVE)) + .where(item.itemStatus.eq(ItemStatus.ACTIVE)) .groupBy(item); addFilterWhere(countQuery, dto); @@ -553,10 +557,10 @@ public Page getLuxuryItem(Pageable pageable, SearchFilterReqDto dto) { * 럭셔리 아이템 업데이트 */ @Override - public List updateLuxuryItem() { + public List getItemByOverPrice(int price) { return jpaQueryFactory.select(item) .from(item) - .where(item.itemStatus.eq(ACTIVE).and(item.price.goe(500000))) + .where(item.itemStatus.eq(ItemStatus.ACTIVE).and(item.price.goe(price))) .fetch(); } @@ -571,7 +575,7 @@ public Page getEfficientItem(Pageable pageable, SearchFilterReqDto filterR .leftJoin(item).on(efficientItem.item.eq(item)) .leftJoin(itemLike).on(itemLike.item.eq(item)) .leftJoin(itemScrap).on(itemScrap.item.eq(item)) - .where(item.itemStatus.eq(ACTIVE)) + .where(item.itemStatus.eq(ItemStatus.ACTIVE)) .groupBy(item); addFilterWhere(query, filterReqDto); @@ -587,7 +591,7 @@ public Page getEfficientItem(Pageable pageable, SearchFilterReqDto filterR .leftJoin(item).on(efficientItem.item.eq(item)) .leftJoin(itemLike).on(itemLike.item.eq(item)).fetchJoin() .leftJoin(itemScrap).on(itemScrap.item.eq(item)).fetchJoin() - .where(item.itemStatus.eq(ACTIVE)) + .where(item.itemStatus.eq(ItemStatus.ACTIVE)) .groupBy(item); addFilterWhere(countQuery, filterReqDto); @@ -599,11 +603,11 @@ public Page getEfficientItem(Pageable pageable, SearchFilterReqDto filterR * 가성비 선물 아이템 업데이트 */ @Override - public List updateEfficientItem() { + public List getItemByUnderPrice(int price) { return jpaQueryFactory.select(item) .from(item) - .where(item.itemStatus.eq(ACTIVE) - .and(item.price.between(0, 100000)) + .where(item.itemStatus.eq(ItemStatus.ACTIVE) + .and(item.price.between(0, price)) ) .fetch(); } @@ -612,11 +616,11 @@ public List updateEfficientItem() { * 주간 HOT 셀럽 아이템 업데이트 */ @Override - public List updateWeekHotItem() { + public List getPreviousWeekHotItem() { return jpaQueryFactory.selectFrom(item) .leftJoin(itemLike).on(itemLike.item.eq(item)) .leftJoin(itemScrap).on(itemScrap.item.eq(item)) - .where(item.itemStatus.eq(ACTIVE)) + .where(item.itemStatus.eq(ItemStatus.ACTIVE)) .orderBy(itemLike.count().add(itemScrap.count()).add(item.viewNum).desc()) .groupBy(item) .limit(21) @@ -632,7 +636,7 @@ public List getWeekHotItem() { return jpaQueryFactory.select(item) .from(weekHotItem) .leftJoin(item).on(weekHotItem.item.eq(item)).fetchJoin() - .where(item.itemStatus.eq(ACTIVE)) + .where(item.itemStatus.eq(ItemStatus.ACTIVE)) .fetch(); } @@ -645,7 +649,7 @@ public List getDayHotItem() { return jpaQueryFactory.select(item) .from(dayHotItem) .leftJoin(item).on(dayHotItem.item.eq(item)).fetchJoin() - .where(item.itemStatus.eq(ACTIVE)) + .where(item.itemStatus.eq(ItemStatus.ACTIVE)) .fetch(); } @@ -653,11 +657,11 @@ public List getDayHotItem() { * 일간 HOT 셀럽 아이템 업데이트 */ @Override - public List updateDayHotItem() { + public List getYesterdayHotItem() { return jpaQueryFactory.selectFrom(item) .leftJoin(itemLike).on(itemLike.item.eq(item)) .leftJoin(itemScrap).on(itemScrap.item.eq(item)) - .where(item.itemStatus.eq(ACTIVE)) + .where(item.itemStatus.eq(ItemStatus.ACTIVE)) .orderBy(itemLike.count().add(itemScrap.count()).add(item.viewNum).desc()) .groupBy(item) .limit(21) @@ -672,7 +676,7 @@ public Page getHotCelebItem(Long celebId, Pageable pageable, SearchFilterR JPAQuery query = jpaQueryFactory.selectFrom(item) .leftJoin(itemLike).on(itemLike.item.eq(item)) .leftJoin(itemScrap).on(itemScrap.item.eq(item)) - .where(item.itemStatus.eq(ACTIVE) + .where(item.itemStatus.eq(ItemStatus.ACTIVE) .and(item.celeb.id.eq(celebId) .or(item.celeb.parent.id.eq(celebId)) .or(item.newCeleb.id.eq(celebId)) @@ -692,7 +696,7 @@ public Page getHotCelebItem(Long celebId, Pageable pageable, SearchFilterR JPAQuery countQuery = jpaQueryFactory.selectFrom(item) .leftJoin(itemLike).on(itemLike.item.eq(item)) .leftJoin(itemScrap).on(itemScrap.item.eq(item)) - .where(item.itemStatus.eq(ACTIVE) + .where(item.itemStatus.eq(ItemStatus.ACTIVE) .and(item.celeb.id.eq(celebId) .or(item.celeb.parent.id.eq(celebId)) .or(item.newCeleb.id.eq(celebId)) @@ -718,7 +722,7 @@ public List getCurationItem(User user, List interestedCeleb) { List content = jpaQueryFactory.selectFrom(item) .leftJoin(itemLike).on(itemLike.item.eq(item)) .leftJoin(itemScrap).on(itemScrap.item.eq(item)) - .where(item.itemStatus.eq(ACTIVE) + .where(item.itemStatus.eq(ItemStatus.ACTIVE) .and(item.celeb.in(interestedCeleb) .or(item.celeb.parent.in(interestedCeleb))) .and(item.createdAt.year().eq(now.getYear())) @@ -744,7 +748,7 @@ public List getCurationItem(User user, List interestedCeleb) { private List getRecentPostItemsNotInContent(List content, int count) { return jpaQueryFactory.selectFrom(item) - .where(item.itemStatus.eq(ACTIVE) + .where(item.itemStatus.eq(ItemStatus.ACTIVE) .and(item.notIn(content)) ) .orderBy(item.createdAt.desc()) @@ -770,17 +774,17 @@ public List getHowAboutItem(User _user, List interestedCelebList) { .from(itemLike) .leftJoin(itemLike.item, item) .where(itemLike.user.in(userList) - .and(item.itemStatus.eq(ACTIVE)) + .and(item.itemStatus.eq(ItemStatus.ACTIVE)) ) .orderBy(itemLike.count().desc()) .groupBy(item) - .limit(이_아이템은_어때요_개수.getNumber()) + .limit(ItemNumberConfig.이_아이템은_어때요_개수.getNumber()) .fetch(); } @Override - public List getItemSimpleResDto(User user, List items) { + public List getItemSimpleDto(User user, List items) { List closets = new ArrayList<>(); if (user != null) { @@ -801,13 +805,13 @@ public List getItemSimpleResDto(User user, List items) { .fetch(); List itemIds = items.stream().map(Item::getId).toList(); - List content = fetch.stream() - .map(tuple -> ItemSimpleResDto.of(tuple.get(item), tuple.get(itemImg), + List content = fetch.stream() + .map(tuple -> ItemSimpleDto.of(tuple.get(item), tuple.get(itemImg), tuple.get(itemScrap) != null)) .toList(); - Map contentMap = content.stream() - .collect(Collectors.toMap(ItemSimpleResDto::getItemId, Function.identity())); + Map contentMap = content.stream() + .collect(Collectors.toMap(ItemSimpleDto::getItemId, Function.identity())); return itemIds.stream() .map(contentMap::get) @@ -818,7 +822,7 @@ public List getItemSimpleResDto(User user, List items) { public Page getUserAllRecentItem(User user, Pageable pageable) { List fetch = jpaQueryFactory.selectFrom(recentItem) .leftJoin(recentItem.item, item).fetchJoin() - .where(recentItem.user.eq(user).and(recentItem.item.itemStatus.eq(ACTIVE))) + .where(recentItem.user.eq(user).and(recentItem.item.itemStatus.eq(ItemStatus.ACTIVE))) .orderBy(recentItem.createdAt.max().desc()) .groupBy(recentItem.item) .offset(pageable.getOffset()) @@ -826,7 +830,7 @@ public Page getUserAllRecentItem(User user, Pageable pageable) { .fetch(); JPAQuery query = jpaQueryFactory.selectFrom(recentItem) - .where(recentItem.user.eq(user).and(recentItem.item.itemStatus.eq(ACTIVE))) + .where(recentItem.user.eq(user).and(recentItem.item.itemStatus.eq(ItemStatus.ACTIVE))) .groupBy(recentItem.item) .orderBy(recentItem.createdAt.max().desc()); diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemScrapRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemScrapRepositoryCustom.java new file mode 100644 index 00000000..d15ed933 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemScrapRepositoryCustom.java @@ -0,0 +1,9 @@ +package com.sluv.domain.item.repository.impl; + +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.item.entity.Item; +import java.util.List; + +public interface ItemScrapRepositoryCustom { + Boolean getItemScrapStatus(Item item, List closetList); +} diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemScrapRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemScrapRepositoryImpl.java similarity index 71% rename from src/main/java/com/sluv/server/domain/item/repository/impl/ItemScrapRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemScrapRepositoryImpl.java index 305adfdf..b628ac63 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemScrapRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/ItemScrapRepositoryImpl.java @@ -1,10 +1,10 @@ -package com.sluv.server.domain.item.repository.impl; +package com.sluv.domain.item.repository.impl; -import static com.sluv.server.domain.item.entity.QItemScrap.itemScrap; +import static com.sluv.domain.item.entity.QItemScrap.itemScrap; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.item.entity.Item; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.item.entity.Item; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/PlaceRankRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/PlaceRankRepositoryCustom.java new file mode 100644 index 00000000..256ee8fe --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/PlaceRankRepositoryCustom.java @@ -0,0 +1,8 @@ +package com.sluv.domain.item.repository.impl; + +import com.sluv.domain.item.entity.PlaceRank; +import java.util.List; + +public interface PlaceRankRepositoryCustom { + List getRecentPlaceTop20(Long userId); +} diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/PlaceRankRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/PlaceRankRepositoryImpl.java similarity index 59% rename from src/main/java/com/sluv/server/domain/item/repository/impl/PlaceRankRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/PlaceRankRepositoryImpl.java index ec99257d..5e4e84d0 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/PlaceRankRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/PlaceRankRepositoryImpl.java @@ -1,10 +1,9 @@ -package com.sluv.server.domain.item.repository.impl; +package com.sluv.domain.item.repository.impl; -import static com.sluv.server.domain.item.entity.QPlaceRank.placeRank; +import static com.sluv.domain.item.entity.QPlaceRank.placeRank; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.item.entity.PlaceRank; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.item.entity.PlaceRank; import java.util.List; import lombok.RequiredArgsConstructor; @@ -14,10 +13,10 @@ public class PlaceRankRepositoryImpl implements PlaceRankRepositoryCustom { private final JPAQueryFactory jpaQueryFactory; @Override - public List getRecentPlaceTop20(User user) { + public List getRecentPlaceTop20(Long userId) { return jpaQueryFactory.selectFrom(placeRank) - .where(placeRank.user.eq(user)) + .where(placeRank.user.id.eq(userId)) .groupBy(placeRank.place) .limit(20) .orderBy(placeRank.createdAt.max().desc()) diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/RecentItemRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/RecentItemRepositoryCustom.java similarity index 58% rename from src/main/java/com/sluv/server/domain/item/repository/impl/RecentItemRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/RecentItemRepositoryCustom.java index 0e93fe7b..551600e1 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/RecentItemRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/RecentItemRepositoryCustom.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.item.repository.impl; +package com.sluv.domain.item.repository.impl; -import com.sluv.server.domain.item.entity.RecentItem; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.item.entity.RecentItem; +import com.sluv.domain.user.entity.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/RecentItemRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/RecentItemRepositoryImpl.java similarity index 84% rename from src/main/java/com/sluv/server/domain/item/repository/impl/RecentItemRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/RecentItemRepositoryImpl.java index 05e5f402..2e2e175b 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/RecentItemRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/RecentItemRepositoryImpl.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.item.repository.impl; +package com.sluv.domain.item.repository.impl; -import static com.sluv.server.domain.item.entity.QRecentItem.recentItem; +import static com.sluv.domain.item.entity.QRecentItem.recentItem; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.item.entity.RecentItem; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.item.entity.RecentItem; +import com.sluv.domain.user.entity.User; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemImgRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemImgRepositoryCustom.java new file mode 100644 index 00000000..584cebd2 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemImgRepositoryCustom.java @@ -0,0 +1,9 @@ +package com.sluv.domain.item.repository.impl; + +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.TempItemImg; +import java.util.List; + +public interface TempItemImgRepositoryCustom { + List findAllByTempItems(List tempItems); +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemImgRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemImgRepositoryImpl.java new file mode 100644 index 00000000..544248d3 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemImgRepositoryImpl.java @@ -0,0 +1,24 @@ +package com.sluv.domain.item.repository.impl; + +import static com.sluv.domain.item.entity.QTempItemImg.tempItemImg; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.TempItemImg; +import java.util.List; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class TempItemImgRepositoryImpl implements TempItemImgRepositoryCustom { + + private final JPAQueryFactory jpaQueryFactory; + + @Override + public List findAllByTempItems(List tempItems) { + List itemItemIds = tempItems.stream().map(TempItem::getId).toList(); + return jpaQueryFactory.selectFrom(tempItemImg) + .where(tempItemImg.tempItem.id.in(itemItemIds)) + .fetch(); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemLinkRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemLinkRepositoryCustom.java new file mode 100644 index 00000000..c7adb1a3 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemLinkRepositoryCustom.java @@ -0,0 +1,9 @@ +package com.sluv.domain.item.repository.impl; + +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.TempItemLink; +import java.util.List; + +public interface TempItemLinkRepositoryCustom { + List findAllByTempItems(List tempItems); +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemLinkRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemLinkRepositoryImpl.java new file mode 100644 index 00000000..9f44c734 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemLinkRepositoryImpl.java @@ -0,0 +1,23 @@ +package com.sluv.domain.item.repository.impl; + +import static com.sluv.domain.item.entity.QTempItemLink.tempItemLink; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.TempItemLink; +import java.util.List; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class TempItemLinkRepositoryImpl implements TempItemLinkRepositoryCustom { + + private final JPAQueryFactory jpaQueryFactory; + + @Override + public List findAllByTempItems(List tempItems) { + List tempItemIds = tempItems.stream().map(TempItem::getId).toList(); + return jpaQueryFactory.selectFrom(tempItemLink) + .where(tempItemLink.tempItem.id.in(tempItemIds)) + .fetch(); + } +} diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/TempItemRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemRepositoryCustom.java similarity index 56% rename from src/main/java/com/sluv/server/domain/item/repository/impl/TempItemRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemRepositoryCustom.java index c94eced6..199139c6 100644 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/TempItemRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemRepositoryCustom.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.item.repository.impl; +package com.sluv.domain.item.repository.impl; -import com.sluv.server.domain.item.dto.TempItemResDto; -import com.sluv.server.domain.item.entity.TempItem; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.user.entity.User; import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -13,5 +12,4 @@ public interface TempItemRepositoryCustom { List findAllExceptLast(Long userId); - List getTempItemResDto(List content); } diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemRepositoryImpl.java new file mode 100644 index 00000000..0767667e --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/repository/impl/TempItemRepositoryImpl.java @@ -0,0 +1,57 @@ +package com.sluv.domain.item.repository.impl; + +import static com.sluv.domain.brand.entity.QBrand.brand; +import static com.sluv.domain.brand.entity.QNewBrand.newBrand; +import static com.sluv.domain.celeb.entity.QCeleb.celeb; +import static com.sluv.domain.celeb.entity.QCelebCategory.celebCategory; +import static com.sluv.domain.celeb.entity.QNewCeleb.newCeleb; +import static com.sluv.domain.item.entity.QItemCategory.itemCategory; +import static com.sluv.domain.item.entity.QTempItem.tempItem; + +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; +import com.sluv.domain.celeb.entity.QCeleb; +import com.sluv.domain.celeb.entity.QCelebCategory; +import com.sluv.domain.item.entity.QItemCategory; +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.user.entity.User; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.support.PageableExecutionUtils; + +@RequiredArgsConstructor +public class TempItemRepositoryImpl implements TempItemRepositoryCustom { + + private final JPAQueryFactory jpaQueryFactory; + + @Override + public Page getTempItemList(User user, Pageable pageable) { + QCeleb parent = new QCeleb("parent"); + QCelebCategory parentCelebCategory = new QCelebCategory("parentCelebCategory"); + QItemCategory parentItemCategory = new QItemCategory("parentItemCategory"); + + List content = jpaQueryFactory.selectFrom(tempItem).leftJoin(tempItem.celeb, celeb).fetchJoin() + .leftJoin(celeb.parent, parent).fetchJoin().leftJoin(celeb.celebCategory, celebCategory).fetchJoin() + .leftJoin(celebCategory.parent, parentCelebCategory).fetchJoin() + .leftJoin(tempItem.category, itemCategory).fetchJoin().leftJoin(itemCategory.parent, parentItemCategory) + .fetchJoin().leftJoin(tempItem.brand, brand).fetchJoin().leftJoin(tempItem.newCeleb, newCeleb) + .fetchJoin().leftJoin(tempItem.newBrand, newBrand).fetchJoin().where(tempItem.user.eq(user)) + .offset(pageable.getOffset()).limit(pageable.getPageSize()).orderBy(tempItem.updatedAt.desc()).fetch(); + + JPAQuery countContent = jpaQueryFactory.selectFrom(tempItem).where(tempItem.user.eq(user)); + + return PageableExecutionUtils.getPage(content, pageable, () -> countContent.fetch().size()); + } + + @Override + public List findAllExceptLast(Long userId) { + + return jpaQueryFactory.selectFrom(tempItem) + .where(tempItem.user.id.eq(userId)) + .orderBy(tempItem.updatedAt.desc()) + .offset(1).fetch(); + } +} + diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/DayHotItemDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/DayHotItemDomainService.java new file mode 100644 index 00000000..29f0105f --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/DayHotItemDomainService.java @@ -0,0 +1,25 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.DayHotItem; +import com.sluv.domain.item.repository.DayHotItemRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class DayHotItemDomainService { + + private final DayHotItemRepository dayHotItemRepository; + + @Transactional + public void deleteAllDayHotItem() { + dayHotItemRepository.deleteAll(); + } + + @Transactional + public void save(DayHotItem dayHotItem) { + dayHotItemRepository.save(dayHotItem); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/EfficientItemDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/EfficientItemDomainService.java new file mode 100644 index 00000000..ed482a8c --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/EfficientItemDomainService.java @@ -0,0 +1,26 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.EfficientItem; +import com.sluv.domain.item.repository.EfficientItemRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class EfficientItemDomainService { + + private final EfficientItemRepository efficientItemRepository; + + + @Transactional + public void deleteAllEfficientItem() { + efficientItemRepository.deleteAll(); + } + + @Transactional + public void save(EfficientItem efficientItem) { + efficientItemRepository.save(efficientItem); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemCategoryDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemCategoryDomainService.java new file mode 100644 index 00000000..16ccf40a --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemCategoryDomainService.java @@ -0,0 +1,32 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.ItemCategory; +import com.sluv.domain.item.exception.ItemCategoryNotFoundException; +import com.sluv.domain.item.repository.ItemCategoryRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ItemCategoryDomainService { + + private final ItemCategoryRepository itemCategoryRepository; + + @Transactional(readOnly = true) + public ItemCategory findById(Long categoryId) { + return itemCategoryRepository.findById(categoryId).orElseThrow(ItemCategoryNotFoundException::new); + } + + @Transactional(readOnly = true) + public List findAllByParentNotNull() { + return itemCategoryRepository.findAllByParentNotNull(); + } + + @Transactional(readOnly = true) + public List findAllByParentNull() { + return itemCategoryRepository.findAllByParentNull(); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemDomainService.java new file mode 100644 index 00000000..fe81806b --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemDomainService.java @@ -0,0 +1,200 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.item.dto.ItemSimpleDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.enums.ItemStatus; +import com.sluv.domain.item.exception.ItemNotFoundException; +import com.sluv.domain.item.repository.ItemRepository; +import com.sluv.domain.search.dto.SearchFilterReqDto; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class ItemDomainService { + + private final ItemRepository itemRepository; + + @Transactional(readOnly = true) + public Item findById(Long itemId) { + return itemRepository.findById(itemId).orElseThrow(ItemNotFoundException::new); + } + + @Transactional(readOnly = true) + public Page getAllByUserLikeItem(User user, Pageable pageable) { + return itemRepository.getAllByUserLikeItem(user, pageable); + } + + @Transactional(readOnly = true) + public List getItemSimpleDto(User user, List content) { + return itemRepository.getItemSimpleDto(user, content); + } + + @Transactional(readOnly = true) + public Page getUserAllRecentItem(User user, Pageable pageable) { + return itemRepository.getUserAllRecentItem(user, pageable); + } + + @Transactional(readOnly = true) + public List getRecentTop2Item(User targetUser) { + return itemRepository.getRecentTop2Item(targetUser); + } + + @Transactional(readOnly = true) + public Long countByUserIdAndItemStatus(Long userId, ItemStatus itemStatus) { + return itemRepository.countByUserIdAndItemStatus(userId, itemStatus); + } + + @Transactional(readOnly = true) + public Page getUserAllItem(Long userId, Pageable pageable) { + return itemRepository.getUserAllItem(userId, pageable); + } + + @Transactional(readOnly = true) + public Page getClosetItems(Closet closet, Pageable pageable) { + return itemRepository.getClosetItems(closet, pageable); + } + + @Transactional(readOnly = true) + public List findAllByUserId(Long userId) { + return itemRepository.findAllByUserId(userId); + } + + @Transactional(readOnly = true) + public List findTopPlace() { + return itemRepository.findTopPlace(); + } + + @Transactional(readOnly = true) + public Page getRecentItem(User user, Pageable pageable) { + return itemRepository.getRecentItem(user, pageable); + } + + @Transactional(readOnly = true) + public Page getAllScrapItem(User user, Pageable pageable) { + return itemRepository.getAllScrapItem(user, pageable); + } + + @Transactional(readOnly = true) + public Page getRecommendItemPage(Pageable pageable) { + return itemRepository.getRecommendItemPage(pageable); + } + + @Transactional(readOnly = true) + public Page getNewItem(Pageable pageable) { + return itemRepository.getNewItem(pageable); + } + + @Transactional(readOnly = true) + public List getWeekHotItem() { + return itemRepository.getWeekHotItem(); + } + + @Transactional(readOnly = true) + public List getDayHotItem() { + return itemRepository.getDayHotItem(); + } + + @Transactional(readOnly = true) + public List getCurationItem(User user, List interestedCeleb) { + return itemRepository.getCurationItem(user, interestedCeleb); + } + + @Transactional(readOnly = true) + public List findAllByItemStatus(ItemStatus itemStatus) { + return itemRepository.findAllByItemStatus(itemStatus); + } + + @Transactional(readOnly = true) + public Item getItemByIdWithCelebAndBrand(Long itemId) { + return itemRepository.getItemByIdWithCelebAndBrand(itemId); + } + + @Transactional(readOnly = true) + public List findSameCelebItem(Long itemId, Long celebId, boolean flag) { + return itemRepository.findSameCelebItem(itemId, celebId, flag); + } + + @Transactional(readOnly = true) + public List findSameBrandItem(Long itemId, Long brandId, boolean flag) { + return itemRepository.findSameBrandItem(itemId, brandId, flag); + } + + @Transactional(readOnly = true) + public List getSameClosetItems(Long itemId, List recentAddClosets) { + return itemRepository.getSameClosetItems(itemId, recentAddClosets); + } + + @Transactional + public Item saveItem(Item postItem) { + return itemRepository.save(postItem); + } + + @Transactional(readOnly = true) + public Page getLuxuryItem(Pageable pageable, SearchFilterReqDto dto) { + return itemRepository.getLuxuryItem(pageable, dto); + } + + @Transactional(readOnly = true) + public Page getEfficientItem(Pageable pageable, SearchFilterReqDto filterReqDto) { + return itemRepository.getEfficientItem(pageable, filterReqDto); + } + + @Transactional(readOnly = true) + public Page getHotCelebItem(Long celebId, Pageable pageable, SearchFilterReqDto dto) { + return itemRepository.getHotCelebItem(celebId, pageable, dto); + } + + @Transactional(readOnly = true) + public Page getNowBuyItem(Pageable pageable, SearchFilterReqDto dto) { + return itemRepository.getNowBuyItem(pageable, dto); + } + + @Transactional(readOnly = true) + public Page getCelebSummerItem(Pageable pageable, SearchFilterReqDto dto) { + return itemRepository.getCelebSummerItem(pageable, dto); + } + + @Transactional(readOnly = true) + public Page getSearchItem(List searchItemIds, SearchFilterReqDto dto, Pageable pageable) { + return itemRepository.getSearchItem(searchItemIds, dto, pageable); + } + + @Transactional(readOnly = true) + public Long getSearchItemCount(List itemIds, SearchFilterReqDto dto) { + return itemRepository.getSearchItemCount(itemIds, dto); + } + + @Transactional(readOnly = true) + public List getItemContainKeyword(String keyword) { + return itemRepository.getItemContainKeyword(keyword); + } + + @Transactional(readOnly = true) + public List getItemByOverPrice(int price) { + return itemRepository.getItemByOverPrice(price); + } + + @Transactional(readOnly = true) + public List getItemByUnderPrice(int price) { + return itemRepository.getItemByUnderPrice(price); + } + + @Transactional(readOnly = true) + public List getPreviousWeekHotItem() { + return itemRepository.getPreviousWeekHotItem(); + } + + @Transactional(readOnly = true) + public List getYesterdayHotItem() { + return itemRepository.getYesterdayHotItem(); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemEditReqDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemEditReqDomainService.java new file mode 100644 index 00000000..a47c93a8 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemEditReqDomainService.java @@ -0,0 +1,24 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemEditReq; +import com.sluv.domain.item.enums.ItemEditReqReason; +import com.sluv.domain.item.repository.ItemEditReqRepository; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ItemEditReqDomainService { + + private final ItemEditReqRepository itemEditReqRepository; + + @Transactional + public ItemEditReq saveItemEditReq(User user, Item item, ItemEditReqReason reason, String content) { + ItemEditReq itemEditReq = ItemEditReq.toEntity(user, item, reason, content); + return itemEditReqRepository.save(itemEditReq); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemHashtagDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemHashtagDomainService.java new file mode 100644 index 00000000..687377c1 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemHashtagDomainService.java @@ -0,0 +1,33 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.hashtag.Hashtag; +import com.sluv.domain.item.entity.hashtag.ItemHashtag; +import com.sluv.domain.item.repository.hashtag.ItemHashtagRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ItemHashtagDomainService { + + private final ItemHashtagRepository itemHashtagRepository; + + @Transactional + public void deleteAllByItemId(Long itemId) { + itemHashtagRepository.deleteAllByItemId(itemId); + } + + @Transactional(readOnly = true) + public List findAllByItemId(Long itemId) { + return itemHashtagRepository.findAllByItemId(itemId); + } + + @Transactional + public void saveItemHashtag(Item newItem, Hashtag hashtag) { + ItemHashtag itemHashtag = ItemHashtag.toEntity(newItem, hashtag); + itemHashtagRepository.save(itemHashtag); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemImgDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemImgDomainService.java new file mode 100644 index 00000000..8c7cc34d --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemImgDomainService.java @@ -0,0 +1,38 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.dto.ItemImgDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemImg; +import com.sluv.domain.item.repository.ItemImgRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ItemImgDomainService { + + private final ItemImgRepository itemImgRepository; + + @Transactional(readOnly = true) + public ItemImg findMainImg(Long itemId) { + return itemImgRepository.findMainImg(itemId); + } + + @Transactional + public void deleteAllByItemId(Long itemId) { + itemImgRepository.deleteAllByItemId(itemId); + } + + @Transactional + public void saveItemImg(Item item, ItemImgDto dto) { + ItemImg itemImg = ItemImg.toEntity(item, dto); + itemImgRepository.save(itemImg); + } + + @Transactional(readOnly = true) + public List findAllByItemId(Long itemId) { + return itemImgRepository.findAllByItemId(itemId); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemLikeDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemLikeDomainService.java new file mode 100644 index 00000000..80cea177 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemLikeDomainService.java @@ -0,0 +1,37 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemLike; +import com.sluv.domain.item.repository.ItemLikeRepository; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ItemLikeDomainService { + + private final ItemLikeRepository itemLikeRepository; + + @Transactional(readOnly = true) + public boolean existsByUserIdAndItemId(Long userId, Long itemId) { + return itemLikeRepository.existsByUserIdAndItemId(userId, itemId); + } + + @Transactional(readOnly = true) + public Integer countByItemId(Long itemId) { + return itemLikeRepository.countByItemId(itemId); + } + + @Transactional + public void saveItemLike(Item item, User user) { + ItemLike itemLike = ItemLike.toEntity(item, user); + itemLikeRepository.save(itemLike); + } + + @Transactional + public void deleteByUserIdAndItemId(Long userId, Long itemId) { + itemLikeRepository.deleteByUserIdAndItemId(userId, itemId); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemLinkDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemLinkDomainService.java new file mode 100644 index 00000000..1fe3af7d --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemLinkDomainService.java @@ -0,0 +1,33 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.dto.ItemLinkDto; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemLink; +import com.sluv.domain.item.repository.ItemLinkRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ItemLinkDomainService { + + private final ItemLinkRepository itemLinkRepository; + + @Transactional + public void deleteAllByItemId(Long itemId) { + itemLinkRepository.deleteAllByItemId(itemId); + } + + @Transactional(readOnly = true) + public List findByItemId(Long itemId) { + return itemLinkRepository.findByItemId(itemId); + } + + @Transactional + public void saveItemLink(Item newItem, ItemLinkDto dto) { + ItemLink itemLink = ItemLink.toEntity(newItem, dto); + itemLinkRepository.save(itemLink); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemReportDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemReportDomainService.java new file mode 100644 index 00000000..f4004e13 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemReportDomainService.java @@ -0,0 +1,30 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemReport; +import com.sluv.domain.item.enums.ItemReportReason; +import com.sluv.domain.item.repository.ItemReportRepository; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ItemReportDomainService { + + private final ItemReportRepository itemReportRepository; + + @Transactional(readOnly = true) + public boolean findExistence(User user, Item item) { + return itemReportRepository.findExistence(user, item); + } + + + @Transactional + public void saveItemReport(Item item, User user, ItemReportReason reason, String content) { + ItemReport itemReport = ItemReport.toEntity(item, user, reason, content); + itemReportRepository.save(itemReport); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemScrapDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemScrapDomainService.java new file mode 100644 index 00000000..37ef5ac3 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/ItemScrapDomainService.java @@ -0,0 +1,53 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.closet.entity.Closet; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemScrap; +import com.sluv.domain.item.repository.ItemScrapRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ItemScrapDomainService { + + private final ItemScrapRepository itemScrapRepository; + + @Transactional + public void deleteAllByClosetId(Long closetId) { + itemScrapRepository.deleteAllByClosetId(closetId); + } + + @Transactional + public ItemScrap saveItemScrap(Item item, Closet closet) { + ItemScrap itemScrap = ItemScrap.toEntity(item, closet); + return itemScrapRepository.save(itemScrap); + } + + @Transactional + public void deleteByClosetIdAndItemId(Long closetId, Long itemId) { + itemScrapRepository.deleteByClosetIdAndItemId(closetId, itemId); + } + + @Transactional(readOnly = true) + public ItemScrap findByClosetIdAndItemId(Long fromClosetId, Long itemId) { + return itemScrapRepository.findByClosetIdAndItemId(fromClosetId, itemId); + } + + @Transactional(readOnly = true) + public Long countByClosetId(Long closetId) { + return itemScrapRepository.countByClosetId(closetId); + } + + @Transactional(readOnly = true) + public Boolean getItemScrapStatus(Item item, List closets) { + return itemScrapRepository.getItemScrapStatus(item, closets); + } + + @Transactional(readOnly = true) + public Integer countByItemId(Long itemId) { + return itemScrapRepository.countByItemId(itemId); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/LuxuryItemDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/LuxuryItemDomainService.java new file mode 100644 index 00000000..26845e6a --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/LuxuryItemDomainService.java @@ -0,0 +1,25 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.LuxuryItem; +import com.sluv.domain.item.repository.LuxuryItemRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class LuxuryItemDomainService { + + private final LuxuryItemRepository luxuryItemRepository; + + + @Transactional + public void deleteAllLuxuryItem() { + luxuryItemRepository.deleteAll(); + } + + @Transactional + public void save(LuxuryItem entity) { + luxuryItemRepository.save(entity); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/PlaceRankDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/PlaceRankDomainService.java new file mode 100644 index 00000000..db1f8550 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/PlaceRankDomainService.java @@ -0,0 +1,38 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.PlaceRank; +import com.sluv.domain.item.repository.PlaceRankRepository; +import com.sluv.domain.user.entity.User; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class PlaceRankDomainService { + + private final PlaceRankRepository placeRankRepository; + + @Transactional + public void savePlaceRank(User user, String placeName) { + PlaceRank placeRank = PlaceRank.toEntity(user, placeName); + placeRankRepository.save(placeRank); + } + + @Transactional + public void deleteAllByUserId(Long userId) { + placeRankRepository.deleteAllByUserId(userId); + } + + @Transactional + public void deleteByUserIdAndPlace(Long userId, String placeName) { + placeRankRepository.deleteByUserIdAndPlace(userId, placeName); + } + + @Transactional(readOnly = true) + public List getRecentPlaceTop20(Long userId) { + return placeRankRepository.getRecentPlaceTop20(userId); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/RecentItemDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/RecentItemDomainService.java new file mode 100644 index 00000000..c61e34f6 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/RecentItemDomainService.java @@ -0,0 +1,27 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.RecentItem; +import com.sluv.domain.item.repository.RecentItemRepository; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class RecentItemDomainService { + + private final RecentItemRepository recentItemRepository; + + @Transactional + public void deleteAllByUserId(Long userId) { + recentItemRepository.deleteAllByUserId(userId); + } + + @Transactional + public void saveRecentItem(Item item, User user) { + RecentItem recentItem = RecentItem.of(item, user); + recentItemRepository.save(recentItem); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemDomainService.java new file mode 100644 index 00000000..96a702e4 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemDomainService.java @@ -0,0 +1,49 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.repository.TempItemRepository; +import com.sluv.domain.user.entity.User; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class TempItemDomainService { + + private final TempItemRepository tempItemRepository; + + @Transactional(readOnly = true) + public TempItem findByIdOrNull(Long tempItemId) { + return tempItemRepository.findById(tempItemId).orElse(null); + } + + @Transactional(readOnly = true) + public Page getTempItemList(User user, Pageable pageable) { + return tempItemRepository.getTempItemList(user, pageable); + } + + @Transactional + public void deleteById(Long tempItemId) { + tempItemRepository.deleteById(tempItemId); + } + + @Transactional(readOnly = true) + public List findAllExceptLast(Long userId) { + return tempItemRepository.findAllExceptLast(userId); + } + + @Transactional(readOnly = true) + public Long countByUserId(Long userId) { + return tempItemRepository.countByUserId(userId); + } + + @Transactional + public TempItem saveTempItem(TempItem postTempItem) { + return tempItemRepository.save(postTempItem); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemImgDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemImgDomainService.java new file mode 100644 index 00000000..ba7ee523 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemImgDomainService.java @@ -0,0 +1,34 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.dto.ItemImgDto; +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.TempItemImg; +import com.sluv.domain.item.repository.TempItemImgRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class TempItemImgDomainService { + + private final TempItemImgRepository tempItemImgRepository; + + @Transactional + public void deleteAllByTempItemId(Long tempItemId) { + tempItemImgRepository.deleteAllByTempItemId(tempItemId); + } + + @Transactional + public void saveTempItemImg(TempItem saveTempItem, ItemImgDto itemImgDto) { + TempItemImg tempItemImg = TempItemImg.toEntity(saveTempItem, itemImgDto); + tempItemImgRepository.save(tempItemImg); + } + + @Transactional + public List getTempItemImages(List tempItems) { + return tempItemImgRepository.findAllByTempItems(tempItems); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemLinkDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemLinkDomainService.java new file mode 100644 index 00000000..2c0b31ac --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/TempItemLinkDomainService.java @@ -0,0 +1,33 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.dto.ItemLinkDto; +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.TempItemLink; +import com.sluv.domain.item.repository.TempItemLinkRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class TempItemLinkDomainService { + + private final TempItemLinkRepository tempItemLinkRepository; + + @Transactional + public void deleteAllByTempItemId(Long tempItemId) { + tempItemLinkRepository.deleteAllByTempItemId(tempItemId); + } + + @Transactional + public void saveTempItemLink(TempItem saveTempItem, ItemLinkDto itemLinkDto) { + TempItemLink tempItemLink = TempItemLink.toEntity(saveTempItem, itemLinkDto); + tempItemLinkRepository.save(tempItemLink); + } + + @Transactional(readOnly = true) + public List getTempItemLinks(List tempItems) { + return tempItemLinkRepository.findAllByTempItems(tempItems); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/WeekHotItemDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/WeekHotItemDomainService.java new file mode 100644 index 00000000..a099fd98 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/WeekHotItemDomainService.java @@ -0,0 +1,25 @@ +package com.sluv.domain.item.service; + +import com.sluv.domain.item.entity.WeekHotItem; +import com.sluv.domain.item.repository.WeekHotItemRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class WeekHotItemDomainService { + + private final WeekHotItemRepository weekHotItemRepository; + + @Transactional + public void deleteAllWeekHotItem() { + weekHotItemRepository.deleteAll(); + } + + @Transactional + public void save(WeekHotItem weekHotItem) { + weekHotItemRepository.save(weekHotItem); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/hashtag/HashtagDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/hashtag/HashtagDomainService.java new file mode 100644 index 00000000..5ca6cf72 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/hashtag/HashtagDomainService.java @@ -0,0 +1,40 @@ +package com.sluv.domain.item.service.hashtag; + +import com.sluv.domain.item.dto.hashtag.HashtagCountDto; +import com.sluv.domain.item.entity.hashtag.Hashtag; +import com.sluv.domain.item.exception.hashtag.HashtagNotFoundException; +import com.sluv.domain.item.repository.hashtag.HashtagRepository; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class HashtagDomainService { + + private final HashtagRepository hashtagRepository; + + @Transactional(readOnly = true) + public Hashtag findById(Long hashTagId) { + return hashtagRepository.findById(hashTagId).orElseThrow(HashtagNotFoundException::new); + } + + @Transactional(readOnly = true) + public Page findAllByContent(String name, Pageable pageable) { + return hashtagRepository.findAllByContent(name, pageable); + } + + @Transactional(readOnly = true) + public Optional findByContent(String hashtagContent) { + return hashtagRepository.findByContent(hashtagContent); + } + + @Transactional + public Hashtag saveHashtag(String hashtagContent) { + Hashtag hashtag = Hashtag.toEntity(hashtagContent); + return hashtagRepository.save(hashtag); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/item/service/hashtag/TempItemHashtagDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/item/service/hashtag/TempItemHashtagDomainService.java new file mode 100644 index 00000000..f721e8ec --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/item/service/hashtag/TempItemHashtagDomainService.java @@ -0,0 +1,33 @@ +package com.sluv.domain.item.service.hashtag; + +import com.sluv.domain.item.entity.TempItem; +import com.sluv.domain.item.entity.hashtag.Hashtag; +import com.sluv.domain.item.entity.hashtag.TempItemHashtag; +import com.sluv.domain.item.repository.hashtag.TempItemHashtagRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class TempItemHashtagDomainService { + + private final TempItemHashtagRepository tempItemHashtagRepository; + + @Transactional + public void deleteAllByTempItemId(Long tempItemId) { + tempItemHashtagRepository.deleteAllByTempItemId(tempItemId); + } + + @Transactional + public void saveTempItemHashtag(TempItem saveTempItem, Hashtag tag) { + TempItemHashtag tempItemHashtag = TempItemHashtag.toEntity(saveTempItem, tag); + tempItemHashtagRepository.save(tempItemHashtag); + } + + @Transactional(readOnly = true) + public List getTempItemHashtags(List tempItems) { + return tempItemHashtagRepository.findAllByTempItems(tempItems); + } +} diff --git a/src/main/java/com/sluv/server/domain/notice/entity/Notice.java b/sluv-domain/src/main/java/com/sluv/domain/notice/entity/Notice.java similarity index 85% rename from src/main/java/com/sluv/server/domain/notice/entity/Notice.java rename to sluv-domain/src/main/java/com/sluv/domain/notice/entity/Notice.java index c1c342e6..b963750d 100644 --- a/src/main/java/com/sluv/server/domain/notice/entity/Notice.java +++ b/sluv-domain/src/main/java/com/sluv/domain/notice/entity/Notice.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.notice.entity; +package com.sluv.domain.notice.entity; -import com.sluv.server.domain.notice.enums.NoticeStatus; -import com.sluv.server.domain.notice.enums.NoticeType; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.notice.enums.NoticeStatus; +import com.sluv.domain.notice.enums.NoticeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; diff --git a/src/main/java/com/sluv/server/domain/notice/enums/NoticeStatus.java b/sluv-domain/src/main/java/com/sluv/domain/notice/enums/NoticeStatus.java similarity index 59% rename from src/main/java/com/sluv/server/domain/notice/enums/NoticeStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/notice/enums/NoticeStatus.java index a0e25be1..87597369 100644 --- a/src/main/java/com/sluv/server/domain/notice/enums/NoticeStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/notice/enums/NoticeStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.notice.enums; +package com.sluv.domain.notice.enums; public enum NoticeStatus { READY, diff --git a/sluv-domain/src/main/java/com/sluv/domain/notice/enums/NoticeType.java b/sluv-domain/src/main/java/com/sluv/domain/notice/enums/NoticeType.java new file mode 100644 index 00000000..6489abca --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/notice/enums/NoticeType.java @@ -0,0 +1,5 @@ +package com.sluv.domain.notice.enums; + +public enum NoticeType { + ETC +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/notice/exception/NoticeException.java b/sluv-domain/src/main/java/com/sluv/domain/notice/exception/NoticeException.java new file mode 100644 index 00000000..15f53b10 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/notice/exception/NoticeException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.notice.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class NoticeException extends ApplicationException { + public NoticeException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/notice/exception/NoticeNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/notice/exception/NoticeNotFoundException.java new file mode 100644 index 00000000..c29c0fe5 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/notice/exception/NoticeNotFoundException.java @@ -0,0 +1,14 @@ +package com.sluv.domain.notice.exception; + +import com.sluv.common.exception.HttpStatusCode; + +public class NoticeNotFoundException extends NoticeException { + + private static final int ERROR_CODE = 2024; + private static final String MESSAGE = "존재하지 않는 Notice입니다."; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; + + public NoticeNotFoundException() { + super(ERROR_CODE, STATUS, MESSAGE); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/notice/repository/NoticeRepository.java b/sluv-domain/src/main/java/com/sluv/domain/notice/repository/NoticeRepository.java new file mode 100644 index 00000000..1358d643 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/notice/repository/NoticeRepository.java @@ -0,0 +1,8 @@ +package com.sluv.domain.notice.repository; + +import com.sluv.domain.notice.entity.Notice; +import com.sluv.domain.notice.repository.impl.NoticeRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface NoticeRepository extends JpaRepository, NoticeRepositoryCustom { +} diff --git a/src/main/java/com/sluv/server/domain/notice/repository/impl/NoticeRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/notice/repository/impl/NoticeRepositoryCustom.java similarity index 63% rename from src/main/java/com/sluv/server/domain/notice/repository/impl/NoticeRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/notice/repository/impl/NoticeRepositoryCustom.java index 64ef11d5..fa6ca8c6 100644 --- a/src/main/java/com/sluv/server/domain/notice/repository/impl/NoticeRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/notice/repository/impl/NoticeRepositoryCustom.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.notice.repository.impl; +package com.sluv.domain.notice.repository.impl; -import com.sluv.server.domain.notice.entity.Notice; +import com.sluv.domain.notice.entity.Notice; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/sluv/server/domain/notice/repository/impl/NoticeRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/notice/repository/impl/NoticeRepositoryImpl.java similarity index 85% rename from src/main/java/com/sluv/server/domain/notice/repository/impl/NoticeRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/notice/repository/impl/NoticeRepositoryImpl.java index cb611068..ac4e6022 100644 --- a/src/main/java/com/sluv/server/domain/notice/repository/impl/NoticeRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/notice/repository/impl/NoticeRepositoryImpl.java @@ -1,10 +1,10 @@ -package com.sluv.server.domain.notice.repository.impl; +package com.sluv.domain.notice.repository.impl; -import static com.sluv.server.domain.notice.entity.QNotice.notice; +import static com.sluv.domain.notice.entity.QNotice.notice; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.notice.entity.Notice; +import com.sluv.domain.notice.entity.Notice; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; diff --git a/sluv-domain/src/main/java/com/sluv/domain/notice/service/NoticeDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/notice/service/NoticeDomainService.java new file mode 100644 index 00000000..b4770610 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/notice/service/NoticeDomainService.java @@ -0,0 +1,28 @@ +package com.sluv.domain.notice.service; + +import com.sluv.domain.notice.entity.Notice; +import com.sluv.domain.notice.exception.NoticeNotFoundException; +import com.sluv.domain.notice.repository.NoticeRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class NoticeDomainService { + + private final NoticeRepository noticeRepository; + + @Transactional(readOnly = true) + public Page getAllNotice(Pageable pageable) { + return noticeRepository.getAllNotice(pageable); + } + + @Transactional(readOnly = true) + public Notice findById(Long noticeId) { + return noticeRepository.findById(noticeId).orElseThrow(NoticeNotFoundException::new); + } + +} diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionImgSimpleResDto.java b/sluv-domain/src/main/java/com/sluv/domain/question/dto/QuestionImgSimpleDto.java similarity index 60% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionImgSimpleResDto.java rename to sluv-domain/src/main/java/com/sluv/domain/question/dto/QuestionImgSimpleDto.java index ea7aecd9..e6023f1b 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionImgSimpleResDto.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/dto/QuestionImgSimpleDto.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.domain.question.dto; -import com.sluv.server.domain.item.entity.ItemImg; -import com.sluv.server.domain.question.entity.QuestionImg; +import com.sluv.domain.item.entity.ItemImg; +import com.sluv.domain.question.entity.QuestionImg; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -12,21 +12,21 @@ @NoArgsConstructor @AllArgsConstructor @Builder -public class QuestionImgSimpleResDto { +public class QuestionImgSimpleDto { @Schema(description = "이미지 URL") private String imgUrl; @Schema(description = "이미지 순서") private Long sortOrder; - public static QuestionImgSimpleResDto of(QuestionImg questionImg) { - return QuestionImgSimpleResDto.builder() + public static QuestionImgSimpleDto of(QuestionImg questionImg) { + return QuestionImgSimpleDto.builder() .imgUrl(questionImg.getImgUrl()) .sortOrder((long) questionImg.getSortOrder()) .build(); } - public static QuestionImgSimpleResDto of(ItemImg itemImg) { - return QuestionImgSimpleResDto.builder() + public static QuestionImgSimpleDto of(ItemImg itemImg) { + return QuestionImgSimpleDto.builder() .imgUrl(itemImg.getItemImgUrl()) .sortOrder((long) itemImg.getSortOrder()) .build(); diff --git a/src/main/java/com/sluv/server/domain/question/dto/QuestionSimpleResDto.java b/sluv-domain/src/main/java/com/sluv/domain/question/dto/QuestionSimpleResDto.java similarity index 83% rename from src/main/java/com/sluv/server/domain/question/dto/QuestionSimpleResDto.java rename to sluv-domain/src/main/java/com/sluv/domain/question/dto/QuestionSimpleResDto.java index e57d732f..6f357f8e 100644 --- a/src/main/java/com/sluv/server/domain/question/dto/QuestionSimpleResDto.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/dto/QuestionSimpleResDto.java @@ -1,12 +1,12 @@ -package com.sluv.server.domain.question.dto; +package com.sluv.domain.question.dto; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.entity.QuestionBuy; -import com.sluv.server.domain.question.entity.QuestionFind; -import com.sluv.server.domain.question.entity.QuestionHowabout; -import com.sluv.server.domain.question.entity.QuestionRecommend; -import com.sluv.server.domain.user.dto.UserInfoDto; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.QuestionBuy; +import com.sluv.domain.question.entity.QuestionFind; +import com.sluv.domain.question.entity.QuestionHowabout; +import com.sluv.domain.question.entity.QuestionRecommend; +import com.sluv.domain.user.dto.UserInfoDto; +import com.sluv.domain.user.entity.User; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; import lombok.AllArgsConstructor; @@ -42,17 +42,17 @@ public class QuestionSimpleResDto { //이 중에 뭐 살까 @Schema(description = "QuestionBuy 게시글 이미지 URL 리스트") - private List imgList; + private List imgList; @Schema(description = "QuestionBuy 게시글 아이템 대표 이미지 URL 리스트") - private List itemImgList; + private List itemImgList; //추천해 줘 @Schema(description = "QuestionRecommend 게시글 카테고리 리스트") private List categoryName; public static QuestionSimpleResDto of(Question question, User writer, Long likeNum, Long commentNum, - List imgList, - List itemImgList, + List imgList, + List itemImgList, List categoryName) { String celebName = null; diff --git a/src/main/java/com/sluv/server/domain/question/entity/DailyHotQuestion.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/DailyHotQuestion.java similarity index 63% rename from src/main/java/com/sluv/server/domain/question/entity/DailyHotQuestion.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/DailyHotQuestion.java index fc0a4a7a..d09ef56c 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/DailyHotQuestion.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/DailyHotQuestion.java @@ -1,9 +1,15 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.item.entity.DayHotItem; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.global.common.entity.BaseEntity; -import jakarta.persistence.*; +import com.sluv.domain.common.entity.BaseEntity; +import jakarta.persistence.Column; +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.Table; import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/question/entity/Question.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/Question.java similarity index 91% rename from src/main/java/com/sluv/server/domain/question/entity/Question.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/Question.java index c31f2503..b6d27c49 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/Question.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/Question.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.question.enums.QuestionStatus; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.DiscriminatorColumn; import jakarta.persistence.Entity; diff --git a/src/main/java/com/sluv/server/domain/question/entity/QuestionBuy.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionBuy.java similarity index 62% rename from src/main/java/com/sluv/server/domain/question/entity/QuestionBuy.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionBuy.java index 172c5c7a..2f920b4a 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/QuestionBuy.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionBuy.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.question.dto.QuestionBuyPostReqDto; -import com.sluv.server.domain.question.enums.QuestionStatus; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.user.entity.User; import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.Entity; import java.time.LocalDateTime; @@ -27,18 +26,17 @@ public QuestionBuy(Long id, User user, String title, String content, Long search this.voteEndTime = voteEndTime; } - public static QuestionBuy toEntity(User user, QuestionBuyPostReqDto postReqDto) { + public static QuestionBuy toEntity(User user, Long questionId, String title, LocalDateTime voteEndTime) { QuestionBuyBuilder builder = QuestionBuy.builder(); - if (postReqDto.getId() != null) { - builder - .id(postReqDto.getId()); + if (questionId != null) { + builder.id(questionId); } return builder .user(user) - .title(postReqDto.getTitle()) - .voteEndTime(postReqDto.getVoteEndTime()) + .title(title) + .voteEndTime(voteEndTime) .questionStatus(QuestionStatus.ACTIVE) .build(); } diff --git a/src/main/java/com/sluv/server/domain/question/entity/QuestionFind.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionFind.java similarity index 66% rename from src/main/java/com/sluv/server/domain/question/entity/QuestionFind.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionFind.java index 0c87252a..c6345701 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/QuestionFind.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionFind.java @@ -1,10 +1,9 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.question.dto.QuestionFindPostReqDto; -import com.sluv.server.domain.question.enums.QuestionStatus; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.user.entity.User; import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -37,18 +36,19 @@ public QuestionFind(Long id, User user, String title, String content, Long searc this.newCeleb = newCeleb; } - public static QuestionFind toEntity(User user, QuestionFindPostReqDto postReqDto, Celeb celeb, NewCeleb newCeleb) { + public static QuestionFind toEntity(User user, Long questionId, String title, String content, Celeb celeb, + NewCeleb newCeleb) { QuestionFindBuilder builder = QuestionFind.builder(); - if (postReqDto.getId() != null) { + if (questionId != null) { builder - .id(postReqDto.getId()); + .id(questionId); } return builder .user(user) - .title(postReqDto.getTitle()) - .content(postReqDto.getContent()) + .title(title) + .content(content) .celeb(celeb) .newCeleb(newCeleb) .questionStatus(QuestionStatus.ACTIVE) diff --git a/src/main/java/com/sluv/server/domain/question/entity/QuestionHowabout.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionHowabout.java similarity index 57% rename from src/main/java/com/sluv/server/domain/question/entity/QuestionHowabout.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionHowabout.java index 9d13f2e4..3cc00f93 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/QuestionHowabout.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionHowabout.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.question.dto.QuestionHowaboutPostReqDto; -import com.sluv.server.domain.question.enums.QuestionStatus; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.user.entity.User; import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.Entity; import lombok.Builder; @@ -20,18 +19,17 @@ public QuestionHowabout(Long id, User user, String title, String content, Long s super(id, user, title, content, searchNum, questionStatus); } - public static QuestionHowabout toEntity(User user, QuestionHowaboutPostReqDto postReqDto) { + public static QuestionHowabout toEntity(User user, Long questionId, String title, String content) { QuestionHowaboutBuilder builder = QuestionHowabout.builder(); - if (postReqDto.getId() != null) { - builder - .id(postReqDto.getId()); + if (questionId != null) { + builder.id(questionId); } return builder .user(user) - .title(postReqDto.getTitle()) - .content(postReqDto.getContent()) + .title(title) + .content(content) .questionStatus(QuestionStatus.ACTIVE) .build(); } diff --git a/src/main/java/com/sluv/server/domain/question/entity/QuestionImg.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionImg.java similarity index 75% rename from src/main/java/com/sluv/server/domain/question/entity/QuestionImg.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionImg.java index e09815aa..3a01c5ec 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/QuestionImg.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionImg.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.question.dto.QuestionImgReqDto; -import com.sluv.server.global.common.entity.BaseEntity; -import com.sluv.server.global.common.enums.ItemImgOrLinkStatus; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.common.enums.ItemImgOrLinkStatus; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -58,13 +57,14 @@ public class QuestionImg extends BaseEntity { @Column(name = "img_status", columnDefinition = "varchar(45) default 'ACTIVE'") private ItemImgOrLinkStatus itemImgOrLinkStatus = ItemImgOrLinkStatus.ACTIVE; - public static QuestionImg toEntity(Question question, QuestionImgReqDto reqDto) { + public static QuestionImg toEntity(Question question, String imgUrl, String description, Boolean flag, + Integer sortOrder) { return QuestionImg.builder() .question(question) - .imgUrl(reqDto.getImgUrl()) - .description(reqDto.getDescription()) - .representFlag(reqDto.getRepresentFlag()) - .sortOrder(reqDto.getSortOrder()) + .imgUrl(imgUrl) + .description(description) + .representFlag(flag) + .sortOrder(sortOrder) .build(); } } diff --git a/src/main/java/com/sluv/server/domain/question/entity/QuestionItem.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionItem.java similarity index 77% rename from src/main/java/com/sluv/server/domain/question/entity/QuestionItem.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionItem.java index 345a90eb..b3368b10 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/QuestionItem.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionItem.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.question.dto.QuestionItemReqDto; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.item.entity.Item; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -51,13 +50,14 @@ public class QuestionItem extends BaseEntity { private Integer sortOrder; - public static QuestionItem toEntity(Question question, Item item, QuestionItemReqDto reqDto) { + public static QuestionItem toEntity(Question question, Item item, String description, Boolean flag, + Integer sortOrder) { return QuestionItem.builder() .question(question) .item(item) - .description(reqDto.getDescription()) - .representFlag(reqDto.getRepresentFlag()) - .sortOrder(reqDto.getSortOrder()) + .description(description) + .representFlag(flag) + .sortOrder(sortOrder) .build(); } } diff --git a/src/main/java/com/sluv/server/domain/question/entity/QuestionLike.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionLike.java similarity index 88% rename from src/main/java/com/sluv/server/domain/question/entity/QuestionLike.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionLike.java index 81cf729c..6a4fc802 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/QuestionLike.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionLike.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/question/entity/QuestionRecommend.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionRecommend.java similarity index 60% rename from src/main/java/com/sluv/server/domain/question/entity/QuestionRecommend.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionRecommend.java index 540745f1..9a91b08c 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/QuestionRecommend.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionRecommend.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.question.dto.QuestionRecommendPostReqDto; -import com.sluv.server.domain.question.enums.QuestionStatus; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.user.entity.User; import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.Entity; import lombok.Builder; @@ -20,18 +19,18 @@ public QuestionRecommend(Long id, User user, String title, String content, Long super(id, user, title, content, searchNum, questionStatus); } - public static QuestionRecommend toEntity(User user, QuestionRecommendPostReqDto postReqDto) { + public static QuestionRecommend toEntity(User user, Long questionId, String title, String content) { QuestionRecommendBuilder builder = QuestionRecommend.builder(); - if (postReqDto.getId() != null) { + if (questionId != null) { builder - .id(postReqDto.getId()); + .id(questionId); } return builder .user(user) - .title(postReqDto.getTitle()) - .content(postReqDto.getContent()) + .title(title) + .content(content) .questionStatus(QuestionStatus.ACTIVE) .build(); } diff --git a/src/main/java/com/sluv/server/domain/question/entity/QuestionRecommendCategory.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionRecommendCategory.java similarity index 92% rename from src/main/java/com/sluv/server/domain/question/entity/QuestionRecommendCategory.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionRecommendCategory.java index c0153879..7c4a4fe3 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/QuestionRecommendCategory.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionRecommendCategory.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/question/entity/QuestionReport.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionReport.java similarity index 78% rename from src/main/java/com/sluv/server/domain/question/entity/QuestionReport.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionReport.java index e76ecc22..595e10d3 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/QuestionReport.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionReport.java @@ -1,10 +1,9 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.question.dto.QuestionReportReqDto; -import com.sluv.server.domain.question.enums.QuestionReportReason; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; -import com.sluv.server.global.common.enums.ReportStatus; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.common.enums.ReportStatus; +import com.sluv.domain.question.enums.QuestionReportReason; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -59,12 +58,13 @@ public class QuestionReport extends BaseEntity { private ReportStatus reportStatus = ReportStatus.WAITING; - public static QuestionReport toEntity(User user, Question question, QuestionReportReqDto dto) { + public static QuestionReport toEntity(User user, Question question, + QuestionReportReason reason, String content) { return QuestionReport.builder() .reporter(user) .question(question) - .questionReportReason(dto.getReason()) - .content(dto.getContent()) + .questionReportReason(reason) + .content(content) .build(); } } diff --git a/src/main/java/com/sluv/server/domain/question/entity/QuestionVote.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionVote.java similarity index 79% rename from src/main/java/com/sluv/server/domain/question/entity/QuestionVote.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionVote.java index 639095e8..2ff3d3b8 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/QuestionVote.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/QuestionVote.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.question.dto.QuestionVoteReqDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -40,11 +39,11 @@ public class QuestionVote extends BaseEntity { private Long voteSortOrder; - public static QuestionVote toEntity(Question question, User user, QuestionVoteReqDto dto) { + public static QuestionVote toEntity(Question question, User user, Long voteSortOrder) { return QuestionVote.builder() .question(question) .user(user) - .voteSortOrder(dto.getVoteSortOrder()) + .voteSortOrder(voteSortOrder) .build(); } diff --git a/src/main/java/com/sluv/server/domain/question/entity/RecentQuestion.java b/sluv-domain/src/main/java/com/sluv/domain/question/entity/RecentQuestion.java similarity index 89% rename from src/main/java/com/sluv/server/domain/question/entity/RecentQuestion.java rename to sluv-domain/src/main/java/com/sluv/domain/question/entity/RecentQuestion.java index 13d5aa33..fc2d0b86 100644 --- a/src/main/java/com/sluv/server/domain/question/entity/RecentQuestion.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/entity/RecentQuestion.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.question.entity; +package com.sluv.domain.question.entity; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/question/enums/QuestionReportReason.java b/sluv-domain/src/main/java/com/sluv/domain/question/enums/QuestionReportReason.java similarity index 73% rename from src/main/java/com/sluv/server/domain/question/enums/QuestionReportReason.java rename to sluv-domain/src/main/java/com/sluv/domain/question/enums/QuestionReportReason.java index 93027372..6920feea 100644 --- a/src/main/java/com/sluv/server/domain/question/enums/QuestionReportReason.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/enums/QuestionReportReason.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.question.enums; +package com.sluv.domain.question.enums; public enum QuestionReportReason { SPAM_OR_AD, diff --git a/src/main/java/com/sluv/server/domain/question/enums/QuestionStatus.java b/sluv-domain/src/main/java/com/sluv/domain/question/enums/QuestionStatus.java similarity index 59% rename from src/main/java/com/sluv/server/domain/question/enums/QuestionStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/question/enums/QuestionStatus.java index 20bec9ae..c1ebc828 100644 --- a/src/main/java/com/sluv/server/domain/question/enums/QuestionStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/enums/QuestionStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.question.enums; +package com.sluv.domain.question.enums; public enum QuestionStatus { ACTIVE, diff --git a/sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionException.java b/sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionException.java new file mode 100644 index 00000000..5084d40b --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.question.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class QuestionException extends ApplicationException { + public QuestionException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/domain/question/exception/QuestionNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionNotFoundException.java similarity index 56% rename from src/main/java/com/sluv/server/domain/question/exception/QuestionNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionNotFoundException.java index 937aec44..26ae834d 100644 --- a/src/main/java/com/sluv/server/domain/question/exception/QuestionNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionNotFoundException.java @@ -1,14 +1,13 @@ -package com.sluv.server.domain.question.exception; +package com.sluv.domain.question.exception; -import com.sluv.server.domain.item.exception.ItemException; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class QuestionNotFoundException extends QuestionException { private static final int ERROR_CODE = 2012; private static final String MESSAGE = "존재하지 않는 Question입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public QuestionNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); } -} +} \ No newline at end of file diff --git a/src/main/java/com/sluv/server/domain/question/exception/QuestionReportDuplicateException.java b/sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionReportDuplicateException.java similarity index 58% rename from src/main/java/com/sluv/server/domain/question/exception/QuestionReportDuplicateException.java rename to sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionReportDuplicateException.java index 89cece93..9165ac0a 100644 --- a/src/main/java/com/sluv/server/domain/question/exception/QuestionReportDuplicateException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionReportDuplicateException.java @@ -1,12 +1,11 @@ -package com.sluv.server.domain.question.exception; +package com.sluv.domain.question.exception; -import com.sluv.server.domain.item.exception.ItemException; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class QuestionReportDuplicateException extends QuestionException { private static final int ERROR_CODE = 2013; private static final String MESSAGE = "중복된 Question 게시글 신고입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public QuestionReportDuplicateException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/question/exception/QuestionTypeNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionTypeNotFoundException.java similarity index 64% rename from src/main/java/com/sluv/server/domain/question/exception/QuestionTypeNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionTypeNotFoundException.java index 18802b9b..ead859f8 100644 --- a/src/main/java/com/sluv/server/domain/question/exception/QuestionTypeNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/exception/QuestionTypeNotFoundException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.question.exception; +package com.sluv.domain.question.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class QuestionTypeNotFoundException extends QuestionException { private static final int ERROR_CODE = 2020; private static final String MESSAGE = "존재하지 않는 Question 타입입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public QuestionTypeNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/question/repository/DailyHotQuestionRepository.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/DailyHotQuestionRepository.java similarity index 57% rename from src/main/java/com/sluv/server/domain/question/repository/DailyHotQuestionRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/DailyHotQuestionRepository.java index 6b829e63..1c15a1f2 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/DailyHotQuestionRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/DailyHotQuestionRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.question.repository; +package com.sluv.domain.question.repository; -import com.sluv.server.domain.question.entity.DailyHotQuestion; +import com.sluv.domain.question.entity.DailyHotQuestion; import org.springframework.data.jpa.repository.JpaRepository; public interface DailyHotQuestionRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/question/repository/QuestionImgRepository.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionImgRepository.java similarity index 78% rename from src/main/java/com/sluv/server/domain/question/repository/QuestionImgRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionImgRepository.java index 74f4daf9..6b3690f2 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/QuestionImgRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionImgRepository.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.question.repository; - -import com.sluv.server.domain.question.entity.QuestionImg; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.question.repository; +import com.sluv.domain.question.entity.QuestionImg; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface QuestionImgRepository extends JpaRepository { void deleteAllByQuestionId(Long id); diff --git a/src/main/java/com/sluv/server/domain/question/repository/QuestionItemRepository.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionItemRepository.java similarity index 78% rename from src/main/java/com/sluv/server/domain/question/repository/QuestionItemRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionItemRepository.java index 8c593b24..6cfbab5f 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/QuestionItemRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionItemRepository.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.question.repository; - -import com.sluv.server.domain.question.entity.QuestionItem; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.question.repository; +import com.sluv.domain.question.entity.QuestionItem; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface QuestionItemRepository extends JpaRepository { void deleteAllByQuestionId(Long id); diff --git a/src/main/java/com/sluv/server/domain/question/repository/QuestionLikeRepository.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionLikeRepository.java similarity index 74% rename from src/main/java/com/sluv/server/domain/question/repository/QuestionLikeRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionLikeRepository.java index 5851143a..853f750b 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/QuestionLikeRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionLikeRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.question.repository; +package com.sluv.domain.question.repository; -import com.sluv.server.domain.question.entity.QuestionLike; +import com.sluv.domain.question.entity.QuestionLike; import org.springframework.data.jpa.repository.JpaRepository; public interface QuestionLikeRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/question/repository/QuestionRecommendCategoryRepository.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionRecommendCategoryRepository.java similarity index 74% rename from src/main/java/com/sluv/server/domain/question/repository/QuestionRecommendCategoryRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionRecommendCategoryRepository.java index 7bea748a..bf93b478 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/QuestionRecommendCategoryRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionRecommendCategoryRepository.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.question.repository; - -import com.sluv.server.domain.question.entity.QuestionRecommendCategory; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.question.repository; +import com.sluv.domain.question.entity.QuestionRecommendCategory; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface QuestionRecommendCategoryRepository extends JpaRepository { void deleteAllByQuestionId(Long id); diff --git a/src/main/java/com/sluv/server/domain/question/repository/QuestionReportRepository.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionReportRepository.java similarity index 67% rename from src/main/java/com/sluv/server/domain/question/repository/QuestionReportRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionReportRepository.java index 20adb574..98e03b8f 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/QuestionReportRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionReportRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.question.repository; +package com.sluv.domain.question.repository; -import com.sluv.server.domain.question.entity.QuestionReport; +import com.sluv.domain.question.entity.QuestionReport; import org.springframework.data.jpa.repository.JpaRepository; public interface QuestionReportRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/question/repository/QuestionRepository.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionRepository.java similarity index 50% rename from src/main/java/com/sluv/server/domain/question/repository/QuestionRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionRepository.java index c2df1811..e6174c13 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/QuestionRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionRepository.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.question.repository; +package com.sluv.domain.question.repository; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.enums.QuestionStatus; -import com.sluv.server.domain.question.repository.impl.QuestionRepositoryCustom; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.question.repository.impl.QuestionRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; public interface QuestionRepository extends JpaRepository, QuestionRepositoryCustom { diff --git a/src/main/java/com/sluv/server/domain/question/repository/QuestionVoteRepository.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionVoteRepository.java similarity index 82% rename from src/main/java/com/sluv/server/domain/question/repository/QuestionVoteRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionVoteRepository.java index 14597c32..c6bacd42 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/QuestionVoteRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/QuestionVoteRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.question.repository; +package com.sluv.domain.question.repository; -import com.sluv.server.domain.question.entity.QuestionVote; +import com.sluv.domain.question.entity.QuestionVote; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/sluv/server/domain/question/repository/RecentQuestionRepository.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/RecentQuestionRepository.java similarity index 53% rename from src/main/java/com/sluv/server/domain/question/repository/RecentQuestionRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/RecentQuestionRepository.java index 68ba235d..4e8bb7ae 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/RecentQuestionRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/RecentQuestionRepository.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.question.repository; +package com.sluv.domain.question.repository; -import com.sluv.server.domain.question.entity.RecentQuestion; -import com.sluv.server.domain.question.repository.impl.RecentQuestionRepositoryCustom; +import com.sluv.domain.question.entity.RecentQuestion; +import com.sluv.domain.question.repository.impl.RecentQuestionRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; public interface RecentQuestionRepository extends JpaRepository, RecentQuestionRepositoryCustom { diff --git a/src/main/java/com/sluv/server/domain/question/repository/impl/QuestionRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/QuestionRepositoryCustom.java similarity index 79% rename from src/main/java/com/sluv/server/domain/question/repository/impl/QuestionRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/QuestionRepositoryCustom.java index 5185a883..f510fd72 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/impl/QuestionRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/QuestionRepositoryCustom.java @@ -1,12 +1,12 @@ -package com.sluv.server.domain.question.repository.impl; - -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.entity.QuestionBuy; -import com.sluv.server.domain.question.entity.QuestionFind; -import com.sluv.server.domain.question.entity.QuestionHowabout; -import com.sluv.server.domain.question.entity.QuestionRecommend; -import com.sluv.server.domain.user.entity.User; +package com.sluv.domain.question.repository.impl; + +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.QuestionBuy; +import com.sluv.domain.question.entity.QuestionFind; +import com.sluv.domain.question.entity.QuestionHowabout; +import com.sluv.domain.question.entity.QuestionRecommend; +import com.sluv.domain.user.entity.User; import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/sluv/server/domain/question/repository/impl/QuestionRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/QuestionRepositoryImpl.java similarity index 85% rename from src/main/java/com/sluv/server/domain/question/repository/impl/QuestionRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/QuestionRepositoryImpl.java index 94e0d44a..52ef68f5 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/impl/QuestionRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/QuestionRepositoryImpl.java @@ -1,17 +1,16 @@ -package com.sluv.server.domain.question.repository.impl; - -import static com.sluv.server.domain.celeb.entity.QCeleb.celeb; -import static com.sluv.server.domain.celeb.entity.QNewCeleb.newCeleb; -import static com.sluv.server.domain.comment.entity.QComment.comment; -import static com.sluv.server.domain.question.entity.QDailyHotQuestion.dailyHotQuestion; -import static com.sluv.server.domain.question.entity.QQuestion.question; -import static com.sluv.server.domain.question.entity.QQuestionBuy.questionBuy; -import static com.sluv.server.domain.question.entity.QQuestionFind.questionFind; -import static com.sluv.server.domain.question.entity.QQuestionHowabout.questionHowabout; -import static com.sluv.server.domain.question.entity.QQuestionLike.questionLike; -import static com.sluv.server.domain.question.entity.QQuestionRecommend.questionRecommend; -import static com.sluv.server.domain.question.entity.QQuestionRecommendCategory.questionRecommendCategory; -import static com.sluv.server.domain.question.enums.QuestionStatus.ACTIVE; +package com.sluv.domain.question.repository.impl; + +import static com.sluv.domain.celeb.entity.QCeleb.celeb; +import static com.sluv.domain.celeb.entity.QNewCeleb.newCeleb; +import static com.sluv.domain.comment.entity.QComment.comment; +import static com.sluv.domain.question.entity.QDailyHotQuestion.dailyHotQuestion; +import static com.sluv.domain.question.entity.QQuestion.question; +import static com.sluv.domain.question.entity.QQuestionBuy.questionBuy; +import static com.sluv.domain.question.entity.QQuestionFind.questionFind; +import static com.sluv.domain.question.entity.QQuestionHowabout.questionHowabout; +import static com.sluv.domain.question.entity.QQuestionLike.questionLike; +import static com.sluv.domain.question.entity.QQuestionRecommend.questionRecommend; +import static com.sluv.domain.question.entity.QQuestionRecommendCategory.questionRecommendCategory; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.types.Order; @@ -21,15 +20,15 @@ import com.querydsl.core.types.dsl.Expressions; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.QCeleb; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.entity.QuestionBuy; -import com.sluv.server.domain.question.entity.QuestionFind; -import com.sluv.server.domain.question.entity.QuestionHowabout; -import com.sluv.server.domain.question.entity.QuestionRecommend; -import com.sluv.server.domain.user.entity.User; -import com.ulisesbocchio.jasyptspringboot.util.Collections; +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.celeb.entity.QCeleb; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.QuestionBuy; +import com.sluv.domain.question.entity.QuestionFind; +import com.sluv.domain.question.entity.QuestionHowabout; +import com.sluv.domain.question.entity.QuestionRecommend; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.user.entity.User; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -39,6 +38,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; + @RequiredArgsConstructor public class QuestionRepositoryImpl implements QuestionRepositoryCustom { private final JPAQueryFactory jpaQueryFactory; @@ -47,7 +47,7 @@ public class QuestionRepositoryImpl implements QuestionRepositoryCustom { public Page getSearchQuestionBuy(List questionIdList, Pageable pageable) { List content = jpaQueryFactory.selectFrom(questionBuy) .where(questionBuy.id.in(questionIdList) - .and(questionBuy.questionStatus.eq(ACTIVE)) + .and(questionBuy.questionStatus.eq(QuestionStatus.ACTIVE)) ) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -57,7 +57,7 @@ public Page getSearchQuestionBuy(List questionIdList, Pageabl //Count Query JPAQuery countJPAQuery = jpaQueryFactory.selectFrom(questionBuy) .where(questionBuy.id.in(questionIdList) - .and(questionBuy.questionStatus.eq(ACTIVE)) + .and(questionBuy.questionStatus.eq(QuestionStatus.ACTIVE)) ) .orderBy(questionBuy.createdAt.desc());// 추구 후현 @@ -68,7 +68,7 @@ public Page getSearchQuestionBuy(List questionIdList, Pageabl public Page getSearchQuestionFind(List questionIdList, Pageable pageable) { List content = jpaQueryFactory.selectFrom(questionFind) .where(questionFind.id.in(questionIdList) - .and(questionFind.questionStatus.eq(ACTIVE)) + .and(questionFind.questionStatus.eq(QuestionStatus.ACTIVE)) ) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -78,7 +78,7 @@ public Page getSearchQuestionFind(List questionIdList, Pagea //Count Query JPAQuery countJPAQuery = jpaQueryFactory.selectFrom(questionFind) .where(questionFind.id.in(questionIdList) - .and(questionFind.questionStatus.eq(ACTIVE)) + .and(questionFind.questionStatus.eq(QuestionStatus.ACTIVE)) ) .orderBy(questionFind.createdAt.desc());// 추구 후현 @@ -89,7 +89,7 @@ public Page getSearchQuestionFind(List questionIdList, Pagea public Page getSearchQuestionHowabout(List questionIdList, Pageable pageable) { List content = jpaQueryFactory.selectFrom(questionHowabout) .where(questionHowabout.id.in(questionIdList) - .and(questionHowabout.questionStatus.eq(ACTIVE)) + .and(questionHowabout.questionStatus.eq(QuestionStatus.ACTIVE)) ) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -99,7 +99,7 @@ public Page getSearchQuestionHowabout(List questionIdLis //Count Query JPAQuery countJPAQuery = jpaQueryFactory.selectFrom(questionHowabout) .where(questionHowabout.id.in(questionIdList) - .and(questionHowabout.questionStatus.eq(ACTIVE)) + .and(questionHowabout.questionStatus.eq(QuestionStatus.ACTIVE)) ) .orderBy(questionHowabout.createdAt.desc());// 추구 후현 @@ -110,7 +110,7 @@ public Page getSearchQuestionHowabout(List questionIdLis public Page getSearchQuestionRecommend(List questionIdList, Pageable pageable) { List content = jpaQueryFactory.selectFrom(questionRecommend) .where(questionRecommend.id.in(questionIdList) - .and(questionRecommend.questionStatus.eq(ACTIVE)) + .and(questionRecommend.questionStatus.eq(QuestionStatus.ACTIVE)) ) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -120,7 +120,7 @@ public Page getSearchQuestionRecommend(List questionIdL //Count Query JPAQuery countJPAQuery = jpaQueryFactory.selectFrom(questionRecommend) .where(questionRecommend.id.in(questionIdList) - .and(questionRecommend.questionStatus.eq(ACTIVE)) + .and(questionRecommend.questionStatus.eq(QuestionStatus.ACTIVE)) ) .orderBy(questionRecommend.createdAt.desc());// 추구 후현 @@ -135,7 +135,7 @@ public List getWaitQuestionBuy(User user, Long questionId, List getWaitQuestionRecommend(User user, Long question return jpaQueryFactory.select(questionRecommend) .from(questionRecommend) .where(questionRecommend.id.ne(questionId) - .and(questionRecommend.questionStatus.eq(ACTIVE)) + .and(questionRecommend.questionStatus.eq(QuestionStatus.ACTIVE)) .and(getUserNeOrNullInQuestion(questionRecommend, user)) .and(questionRecommend.commentList.size().eq(0)) ) @@ -169,7 +169,7 @@ public List getWaitQuestionHowabout(User user, Long questionId return jpaQueryFactory.select(questionHowabout) .from(questionHowabout) .where(questionHowabout.id.ne(questionId) - .and(questionHowabout.questionStatus.eq(ACTIVE)) + .and(questionHowabout.questionStatus.eq(QuestionStatus.ACTIVE)) .and(getUserNeOrNullInQuestion(questionHowabout, user)) .and(questionHowabout.commentList.size().eq(0)) ) @@ -188,7 +188,7 @@ public List getWaitQuestionFind(User user, Long questionId, List getUserLikeQuestion(User user, Pageable pageable) { .from(questionLike) .leftJoin(questionLike.question, question) .where(questionLike.user.eq(user) - .and(question.questionStatus.eq(ACTIVE)) + .and(question.questionStatus.eq(QuestionStatus.ACTIVE)) ) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -225,7 +225,7 @@ public Page getUserLikeQuestion(User user, Pageable pageable) { .from(questionLike) .leftJoin(questionLike.question, question) .where(questionLike.user.eq(user) - .and(question.questionStatus.eq(ACTIVE)) + .and(question.questionStatus.eq(QuestionStatus.ACTIVE)) ) .orderBy(questionLike.createdAt.desc()); @@ -239,7 +239,7 @@ public Page getUserLikeQuestion(User user, Pageable pageable) { public Page getUserAllQuestion(User user, Pageable pageable) { List content = jpaQueryFactory.selectFrom(question) .where(question.user.eq(user) - .and(question.questionStatus.eq(ACTIVE)) + .and(question.questionStatus.eq(QuestionStatus.ACTIVE)) ) .orderBy(question.createdAt.desc()) .offset(pageable.getOffset()) @@ -249,7 +249,7 @@ public Page getUserAllQuestion(User user, Pageable pageable) { // Count Query JPAQuery query = jpaQueryFactory.selectFrom(question) .where(question.user.eq(user) - .and(question.questionStatus.eq(ACTIVE)) + .and(question.questionStatus.eq(QuestionStatus.ACTIVE)) ) .orderBy(question.createdAt.desc()); @@ -259,7 +259,7 @@ public Page getUserAllQuestion(User user, Pageable pageable) { @Override public Page getTotalQuestionList(Pageable pageable) { List content = jpaQueryFactory.selectFrom(question) - .where(question.questionStatus.eq(ACTIVE)) + .where(question.questionStatus.eq(QuestionStatus.ACTIVE)) .orderBy(question.createdAt.desc()) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -267,7 +267,7 @@ public Page getTotalQuestionList(Pageable pageable) { // Count Query JPAQuery query = jpaQueryFactory.selectFrom(question) - .where(question.questionStatus.eq(ACTIVE)) + .where(question.questionStatus.eq(QuestionStatus.ACTIVE)) .orderBy(question.createdAt.desc()); return PageableExecutionUtils.getPage(content, pageable, () -> query.fetch().size()); @@ -325,7 +325,7 @@ public Page getQuestionFindList(Long celebId, Pageable pageable) { @Override public Page getQuestionHowaboutList(Pageable pageable) { List content = jpaQueryFactory.selectFrom(questionHowabout) - .where(questionHowabout.questionStatus.eq(ACTIVE)) + .where(questionHowabout.questionStatus.eq(QuestionStatus.ACTIVE)) .orderBy(questionHowabout.createdAt.desc()) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -333,7 +333,7 @@ public Page getQuestionHowaboutList(Pageable pageable) { // Count Query JPAQuery query = jpaQueryFactory.selectFrom(questionHowabout) - .where(questionHowabout.questionStatus.eq(ACTIVE)) + .where(questionHowabout.questionStatus.eq(QuestionStatus.ACTIVE)) .orderBy(questionHowabout.createdAt.desc()); return PageableExecutionUtils.getPage(content, pageable, () -> query.fetch().size()); @@ -363,7 +363,7 @@ public Page getQuestionRecommendList(String hashtag, Pageable public Page getSearchQuestion(List questionIdList, Pageable pageable) { List content = jpaQueryFactory.selectFrom(question) .where(question.id.in(questionIdList) - .and(question.questionStatus.eq(ACTIVE)) + .and(question.questionStatus.eq(QuestionStatus.ACTIVE)) ) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -373,7 +373,7 @@ public Page getSearchQuestion(List questionIdList, Pageable page //Count Query JPAQuery countJPAQuery = jpaQueryFactory.selectFrom(question) .where(question.id.in(questionIdList) - .and(question.questionStatus.eq(ACTIVE)) + .and(question.questionStatus.eq(QuestionStatus.ACTIVE)) ) .orderBy(question.createdAt.desc());// 추구 후현 @@ -381,7 +381,7 @@ public Page getSearchQuestion(List questionIdList, Pageable page } private BooleanExpression getQuestionBuyFiltering(String voteStatus) { - BooleanExpression predicate = questionBuy.questionStatus.eq(ACTIVE); + BooleanExpression predicate = questionBuy.questionStatus.eq(QuestionStatus.ACTIVE); LocalDateTime now = LocalDateTime.now(); if (voteStatus == null) { return predicate; @@ -397,7 +397,7 @@ private BooleanExpression getQuestionBuyFiltering(String voteStatus) { } private BooleanExpression getQuestionFindFiltering(Long celebId) { - BooleanExpression predicate = questionFind.questionStatus.eq(ACTIVE); + BooleanExpression predicate = questionFind.questionStatus.eq(QuestionStatus.ACTIVE); if (celebId == null) { return predicate; } else { @@ -425,7 +425,7 @@ private JPAQuery getQuestionRecommendTable(String hashtag) { } private BooleanExpression getQuestionRecommendFiltering(String hashtag) { - BooleanExpression predicate = questionRecommend.questionStatus.eq(ACTIVE); + BooleanExpression predicate = questionRecommend.questionStatus.eq(QuestionStatus.ACTIVE); if (hashtag == null) { return predicate; } else { @@ -460,7 +460,7 @@ public List updateDailyHotQuestion() { .leftJoin(questionLike).on(questionLike.question.id.eq(question.id)) .leftJoin(comment).on(comment.question.id.eq(question.id)) .groupBy(question) - .where(question.questionStatus.eq(ACTIVE)) + .where(question.questionStatus.eq(QuestionStatus.ACTIVE)) .orderBy(questionLike.count().add(comment.count()).add(question.searchNum).desc()) .limit(10) .fetch(); @@ -478,7 +478,7 @@ public Page getWeeklyHotQuestion(Pageable pageable) { .leftJoin(questionLike).on(questionLike.question.id.eq(question.id)) .leftJoin(comment).on(comment.question.id.eq(question.id)) .where( - question.questionStatus.eq(ACTIVE) + question.questionStatus.eq(QuestionStatus.ACTIVE) .and(question.createdAt.between(now.minusDays(7).toLocalDate().atStartOfDay(), now.toLocalDate().atStartOfDay())) @@ -495,7 +495,7 @@ public Page getWeeklyHotQuestion(Pageable pageable) { .leftJoin(questionLike).on(questionLike.question.id.eq(question.id)) .leftJoin(comment).on(comment.question.id.eq(question.id)) .where( - question.questionStatus.eq(ACTIVE) + question.questionStatus.eq(QuestionStatus.ACTIVE) .and(question.createdAt.between(now.minusDays(7).toLocalDate().atStartOfDay(), now.toLocalDate().atStartOfDay())) ) @@ -509,7 +509,7 @@ public List getDailyHotQuestion() { return jpaQueryFactory.select(question) .from(dailyHotQuestion) .leftJoin(question).on(dailyHotQuestion.question.eq(question)).fetchJoin() - .where(question.questionStatus.eq(ACTIVE)) + .where(question.questionStatus.eq(QuestionStatus.ACTIVE)) .fetch(); } @@ -530,7 +530,9 @@ public List getSearchQuestionIds(String word) { .or(questionFind.newCeleb.celebName.like("%" + word + "%")) ).fetch().stream().map(question -> (Question) question).toList(); - return Collections.concat(content, questionFindContent); +// return Collections.concat(content, questionFindContent); + content.addAll(questionFindContent); + return content; } @Override @@ -539,7 +541,7 @@ public List getEndTimeBetweenNow(int voteEndCheckPeriod) { LocalDateTime now = LocalDateTime.now(); return jpaQueryFactory.selectFrom(questionBuy) - .where(questionBuy.questionStatus.eq(ACTIVE) + .where(questionBuy.questionStatus.eq(QuestionStatus.ACTIVE) .and(questionBuy.voteEndTime.between(now.minusMinutes(periodToMinutes), now)) ) .fetch(); diff --git a/src/main/java/com/sluv/server/domain/question/repository/impl/RecentQuestionRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/RecentQuestionRepositoryCustom.java similarity index 58% rename from src/main/java/com/sluv/server/domain/question/repository/impl/RecentQuestionRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/RecentQuestionRepositoryCustom.java index d5aebeda..db3d52ea 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/impl/RecentQuestionRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/RecentQuestionRepositoryCustom.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.question.repository.impl; +package com.sluv.domain.question.repository.impl; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.user.entity.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/sluv/server/domain/question/repository/impl/RecentQuestionRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/RecentQuestionRepositoryImpl.java similarity index 83% rename from src/main/java/com/sluv/server/domain/question/repository/impl/RecentQuestionRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/RecentQuestionRepositoryImpl.java index 9268afb8..df41ffb4 100644 --- a/src/main/java/com/sluv/server/domain/question/repository/impl/RecentQuestionRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/question/repository/impl/RecentQuestionRepositoryImpl.java @@ -1,13 +1,13 @@ -package com.sluv.server.domain.question.repository.impl; +package com.sluv.domain.question.repository.impl; -import static com.sluv.server.domain.question.entity.QRecentQuestion.recentQuestion; +import static com.sluv.domain.question.entity.QRecentQuestion.recentQuestion; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.question.entity.QQuestion; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.enums.QuestionStatus; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.question.entity.QQuestion; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.user.entity.User; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; diff --git a/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionDomainService.java new file mode 100644 index 00000000..ff08982b --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionDomainService.java @@ -0,0 +1,131 @@ +package com.sluv.domain.question.service; + +import com.sluv.domain.celeb.entity.Celeb; +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.QuestionBuy; +import com.sluv.domain.question.entity.QuestionFind; +import com.sluv.domain.question.entity.QuestionHowabout; +import com.sluv.domain.question.entity.QuestionRecommend; +import com.sluv.domain.question.enums.QuestionStatus; +import com.sluv.domain.question.exception.QuestionNotFoundException; +import com.sluv.domain.question.repository.QuestionRepository; +import com.sluv.domain.user.entity.User; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class QuestionDomainService { + + private final QuestionRepository questionRepository; + + + @Transactional(readOnly = true) + public Question findById(Long questionId) { + return questionRepository.findById(questionId).orElseThrow(QuestionNotFoundException::new); + } + + @Transactional + public Page getUserLikeQuestion(User user, Pageable pageable) { + return questionRepository.getUserLikeQuestion(user, pageable); + } + + @Transactional(readOnly = true) + public Long countByUserIdAndQuestionStatus(Long questionId, QuestionStatus questionStatus) { + return questionRepository.countByUserIdAndQuestionStatus(questionId, questionStatus); + } + + @Transactional(readOnly = true) + public Page getUserAllQuestion(User user, Pageable pageable) { + return questionRepository.getUserAllQuestion(user, pageable); + } + + @Transactional + public Question saveQuestion(Question question) { + return questionRepository.save(question); + } + + @Transactional(readOnly = true) + public List getWaitQuestionBuy(User user, Long questionId, List interestedCelebs) { + return questionRepository.getWaitQuestionBuy(user, questionId, interestedCelebs); + } + + @Transactional(readOnly = true) + public List getWaitQuestionRecommend(User user, Long questionId) { + return questionRepository.getWaitQuestionRecommend(user, questionId); + } + + @Transactional(readOnly = true) + public List getWaitQuestionHowabout(User user, Long questionId) { + return questionRepository.getWaitQuestionHowabout(user, questionId); + } + + @Transactional(readOnly = true) + public List getWaitQuestionFind(User user, Long questionId, List interestedCelebs) { + return questionRepository.getWaitQuestionFind(user, questionId, interestedCelebs); + } + + @Transactional(readOnly = true) + public Page getTotalQuestionList(Pageable pageable) { + return questionRepository.getTotalQuestionList(pageable); + } + + @Transactional(readOnly = true) + public Page getQuestionBuyList(String voteStatus, Pageable pageable) { + return questionRepository.getQuestionBuyList(voteStatus, pageable); + } + + @Transactional(readOnly = true) + public Page getQuestionFindList(Long celebId, Pageable pageable) { + return questionRepository.getQuestionFindList(celebId, pageable); + } + + @Transactional(readOnly = true) + public Page getQuestionHowaboutList(Pageable pageable) { + return questionRepository.getQuestionHowaboutList(pageable); + } + + @Transactional(readOnly = true) + public Page getQuestionRecommendList(String hashtag, Pageable pageable) { + return questionRepository.getQuestionRecommendList(hashtag, pageable); + } + + @Transactional(readOnly = true) + public List getDailyHotQuestion() { + return questionRepository.getDailyHotQuestion(); + } + + @Transactional(readOnly = true) + public Page getSearchQuestion(List searchQuestionIds, Pageable pageable) { + return questionRepository.getSearchQuestion(searchQuestionIds, pageable); + } + + @Transactional(readOnly = true) + public Page getSearchQuestionBuy(List searchQuestionIds, Pageable pageable) { + return questionRepository.getSearchQuestionBuy(searchQuestionIds, pageable); + } + + @Transactional(readOnly = true) + public Page getSearchQuestionFind(List searchQuestionIds, Pageable pageable) { + return questionRepository.getSearchQuestionFind(searchQuestionIds, pageable); + } + + @Transactional(readOnly = true) + public Page getSearchQuestionHowabout(List searchQuestionIds, Pageable pageable) { + return questionRepository.getSearchQuestionHowabout(searchQuestionIds, pageable); + } + + @Transactional(readOnly = true) + public Page getSearchQuestionRecommend(List searchQuestionIds, Pageable pageable) { + return questionRepository.getSearchQuestionRecommend(searchQuestionIds, pageable); + } + + @Transactional(readOnly = true) + public Page getWeeklyHotQuestion(Pageable pageable) { + return questionRepository.getWeeklyHotQuestion(pageable); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionImgDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionImgDomainService.java new file mode 100644 index 00000000..a9268e3b --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionImgDomainService.java @@ -0,0 +1,36 @@ +package com.sluv.domain.question.service; + +import com.sluv.domain.question.entity.QuestionImg; +import com.sluv.domain.question.repository.QuestionImgRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class QuestionImgDomainService { + + private final QuestionImgRepository questionImgRepository; + + @Transactional(readOnly = true) + public List findAllByQuestionId(Long questionId) { + return questionImgRepository.findAllByQuestionId(questionId); + } + + @Transactional + public void deleteAllByQuestionId(Long questionId) { + questionImgRepository.deleteAllByQuestionId(questionId); + } + + @Transactional + public void saveAll(List images) { + questionImgRepository.saveAll(images); + } + + @Transactional(readOnly = true) + public QuestionImg findByQuestionIdAndRepresentFlag(Long questionId, boolean flag) { + return questionImgRepository.findByQuestionIdAndRepresentFlag(questionId, flag); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionItemDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionItemDomainService.java new file mode 100644 index 00000000..5f1e7eb9 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionItemDomainService.java @@ -0,0 +1,35 @@ +package com.sluv.domain.question.service; + +import com.sluv.domain.question.entity.QuestionItem; +import com.sluv.domain.question.repository.QuestionItemRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class QuestionItemDomainService { + + private final QuestionItemRepository questionItemRepository; + + @Transactional(readOnly = true) + public List findAllByQuestionId(Long questionId) { + return questionItemRepository.findAllByQuestionId(questionId); + } + + @Transactional + public void deleteAllByQuestionId(Long questionId) { + questionItemRepository.deleteAllByQuestionId(questionId); + } + + @Transactional + public void saveAll(List items) { + questionItemRepository.saveAll(items); + } + + @Transactional(readOnly = true) + public QuestionItem findByQuestionIdAndRepresentFlag(Long questionId, boolean flag) { + return questionItemRepository.findByQuestionIdAndRepresentFlag(questionId, flag); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionLikeDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionLikeDomainService.java new file mode 100644 index 00000000..9dc9223a --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionLikeDomainService.java @@ -0,0 +1,38 @@ +package com.sluv.domain.question.service; + +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.QuestionLike; +import com.sluv.domain.question.repository.QuestionLikeRepository; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class QuestionLikeDomainService { + + private final QuestionLikeRepository questionLikeRepository; + + @Transactional(readOnly = true) + public Long countByQuestionId(Long questionId) { + return questionLikeRepository.countByQuestionId(questionId); + } + + @Transactional(readOnly = true) + public Boolean existsByQuestionIdAndUserId(Long questionId, Long userId) { + return questionLikeRepository.existsByQuestionIdAndUserId(questionId, userId); + } + + @Transactional + public void deleteByQuestionIdAndUserId(Long questionId, Long userId) { + questionLikeRepository.deleteByQuestionIdAndUserId(questionId, userId); + } + + @Transactional + public QuestionLike saveQuestionLike(User user, Question question) { + QuestionLike questionLike = QuestionLike.toEntity(user, question); + return questionLikeRepository.save(questionLike); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionRecommendCategoryDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionRecommendCategoryDomainService.java new file mode 100644 index 00000000..87b4e568 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionRecommendCategoryDomainService.java @@ -0,0 +1,30 @@ +package com.sluv.domain.question.service; + +import com.sluv.domain.question.entity.QuestionRecommendCategory; +import com.sluv.domain.question.repository.QuestionRecommendCategoryRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class QuestionRecommendCategoryDomainService { + + private final QuestionRecommendCategoryRepository questionRecommendCategoryRepository; + + @Transactional(readOnly = true) + public List findAllByQuestionId(Long questionId) { + return questionRecommendCategoryRepository.findAllByQuestionId(questionId); + } + + @Transactional + public void deleteAllByQuestionId(Long questionId) { + questionRecommendCategoryRepository.deleteAllByQuestionId(questionId); + } + + @Transactional + public void saveAll(List recommendCategories) { + questionRecommendCategoryRepository.saveAll(recommendCategories); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionReportDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionReportDomainService.java new file mode 100644 index 00000000..ef65c762 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionReportDomainService.java @@ -0,0 +1,29 @@ +package com.sluv.domain.question.service; + +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.QuestionReport; +import com.sluv.domain.question.enums.QuestionReportReason; +import com.sluv.domain.question.repository.QuestionReportRepository; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class QuestionReportDomainService { + + private final QuestionReportRepository questionReportRepository; + + @Transactional(readOnly = true) + public Boolean existsByQuestionIdAndReporterId(Long questionId, Long reporterId) { + return questionReportRepository.existsByQuestionIdAndReporterId(questionId, reporterId); + } + + @Transactional + public QuestionReport saveQuestionReport(User user, Question question, QuestionReportReason reason, + String content) { + QuestionReport questionReport = QuestionReport.toEntity(user, question, reason, content); + return questionReportRepository.save(questionReport); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionVoteDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionVoteDomainService.java new file mode 100644 index 00000000..dd67046b --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/question/service/QuestionVoteDomainService.java @@ -0,0 +1,44 @@ +package com.sluv.domain.question.service; + +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.QuestionVote; +import com.sluv.domain.question.repository.QuestionVoteRepository; +import com.sluv.domain.user.entity.User; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class QuestionVoteDomainService { + + private final QuestionVoteRepository questionVoteRepository; + + @Transactional(readOnly = true) + public QuestionVote findByQuestionIdAndUserIdOrNull(Long questionId, Long userId) { + return questionVoteRepository.findByQuestionIdAndUserId(questionId, userId).orElse(null); + } + + @Transactional(readOnly = true) + public Long countByQuestionId(Long questionId) { + return questionVoteRepository.countByQuestionId(questionId); + } + + @Transactional(readOnly = true) + public List findAllByQuestionId(Long questionId) { + return questionVoteRepository.findAllByQuestionId(questionId); + } + + @Transactional + public void deleteById(Long questionVoteId) { + questionVoteRepository.deleteById(questionVoteId); + } + + @Transactional + public QuestionVote saveQuestionVote(Question question, User user, Long voteSortOrder) { + QuestionVote questionVote = QuestionVote.toEntity(question, user, voteSortOrder); + return questionVoteRepository.save(questionVote); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/question/service/RecentQuestionDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/question/service/RecentQuestionDomainService.java new file mode 100644 index 00000000..9b301dd7 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/question/service/RecentQuestionDomainService.java @@ -0,0 +1,35 @@ +package com.sluv.domain.question.service; + +import com.sluv.domain.question.entity.Question; +import com.sluv.domain.question.entity.RecentQuestion; +import com.sluv.domain.question.repository.RecentQuestionRepository; +import com.sluv.domain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class RecentQuestionDomainService { + + private final RecentQuestionRepository recentQuestionRepository; + + @Transactional(readOnly = true) + public Page getUserAllRecentQuestion(User user, Pageable pageable) { + return recentQuestionRepository.getUserAllRecentQuestion(user, pageable); + } + + @Transactional + public void deleteAllByUserId(Long userId) { + recentQuestionRepository.deleteAllByUserId(userId); + } + + @Transactional + public RecentQuestion saveRecentQuestion(User nowUser, String qType, Question question) { + RecentQuestion recentQuestion = RecentQuestion.toEntity(nowUser, qType, question); + return recentQuestionRepository.save(recentQuestion); + } + +} diff --git a/src/main/java/com/sluv/server/domain/search/dto/SearchFilterReqDto.java b/sluv-domain/src/main/java/com/sluv/domain/search/dto/SearchFilterReqDto.java similarity index 93% rename from src/main/java/com/sluv/server/domain/search/dto/SearchFilterReqDto.java rename to sluv-domain/src/main/java/com/sluv/domain/search/dto/SearchFilterReqDto.java index 094f87f0..c95e63ce 100644 --- a/src/main/java/com/sluv/server/domain/search/dto/SearchFilterReqDto.java +++ b/sluv-domain/src/main/java/com/sluv/domain/search/dto/SearchFilterReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.search.dto; +package com.sluv.domain.search.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/search/entity/RecentSearch.java b/sluv-domain/src/main/java/com/sluv/domain/search/entity/RecentSearch.java similarity index 88% rename from src/main/java/com/sluv/server/domain/search/entity/RecentSearch.java rename to sluv-domain/src/main/java/com/sluv/domain/search/entity/RecentSearch.java index 188c7065..7cd54341 100644 --- a/src/main/java/com/sluv/server/domain/search/entity/RecentSearch.java +++ b/sluv-domain/src/main/java/com/sluv/domain/search/entity/RecentSearch.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.search.entity; +package com.sluv.domain.search.entity; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.entity.User; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/search/entity/SearchData.java b/sluv-domain/src/main/java/com/sluv/domain/search/entity/SearchData.java similarity index 89% rename from src/main/java/com/sluv/server/domain/search/entity/SearchData.java rename to sluv-domain/src/main/java/com/sluv/domain/search/entity/SearchData.java index 566dffc9..42e44e67 100644 --- a/src/main/java/com/sluv/server/domain/search/entity/SearchData.java +++ b/sluv-domain/src/main/java/com/sluv/domain/search/entity/SearchData.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.search.entity; +package com.sluv.domain.search.entity; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/src/main/java/com/sluv/server/domain/search/entity/SearchRank.java b/sluv-domain/src/main/java/com/sluv/domain/search/entity/SearchRank.java similarity index 88% rename from src/main/java/com/sluv/server/domain/search/entity/SearchRank.java rename to sluv-domain/src/main/java/com/sluv/domain/search/entity/SearchRank.java index ed31d3de..fbe87497 100644 --- a/src/main/java/com/sluv/server/domain/search/entity/SearchRank.java +++ b/sluv-domain/src/main/java/com/sluv/domain/search/entity/SearchRank.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.search.entity; +package com.sluv.domain.search.entity; -import com.sluv.server.domain.search.enums.SearchRankStatus; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.search.enums.SearchRankStatus; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; diff --git a/src/main/java/com/sluv/server/domain/search/enums/SearchRankStatus.java b/sluv-domain/src/main/java/com/sluv/domain/search/enums/SearchRankStatus.java similarity index 56% rename from src/main/java/com/sluv/server/domain/search/enums/SearchRankStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/search/enums/SearchRankStatus.java index 9c642d79..c7f3cf40 100644 --- a/src/main/java/com/sluv/server/domain/search/enums/SearchRankStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/search/enums/SearchRankStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.search.enums; +package com.sluv.domain.search.enums; public enum SearchRankStatus { TODAY, diff --git a/src/main/java/com/sluv/server/domain/search/repository/RecentSearchRepository.java b/sluv-domain/src/main/java/com/sluv/domain/search/repository/RecentSearchRepository.java similarity index 59% rename from src/main/java/com/sluv/server/domain/search/repository/RecentSearchRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/search/repository/RecentSearchRepository.java index 6cf4eb66..759e76e4 100644 --- a/src/main/java/com/sluv/server/domain/search/repository/RecentSearchRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/search/repository/RecentSearchRepository.java @@ -1,7 +1,7 @@ -package com.sluv.server.domain.search.repository; +package com.sluv.domain.search.repository; -import com.sluv.server.domain.search.entity.RecentSearch; -import com.sluv.server.domain.search.repository.impl.RecentSearchRepositoryCustom; +import com.sluv.domain.search.entity.RecentSearch; +import com.sluv.domain.search.repository.impl.RecentSearchRepositoryCustom; import org.springframework.data.jpa.repository.JpaRepository; public interface RecentSearchRepository extends JpaRepository, RecentSearchRepositoryCustom { diff --git a/sluv-domain/src/main/java/com/sluv/domain/search/repository/SearchDataRepository.java b/sluv-domain/src/main/java/com/sluv/domain/search/repository/SearchDataRepository.java new file mode 100644 index 00000000..eb2b8e72 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/search/repository/SearchDataRepository.java @@ -0,0 +1,8 @@ +package com.sluv.domain.search.repository; + +import com.sluv.domain.search.entity.SearchData; +import com.sluv.domain.search.repository.impl.SearchDataRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SearchDataRepository extends JpaRepository, SearchDataRepositoryCustom { +} diff --git a/src/main/java/com/sluv/server/domain/search/repository/SearchRankRepository.java b/sluv-domain/src/main/java/com/sluv/domain/search/repository/SearchRankRepository.java similarity index 67% rename from src/main/java/com/sluv/server/domain/search/repository/SearchRankRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/search/repository/SearchRankRepository.java index 7f9726ac..cb995c41 100644 --- a/src/main/java/com/sluv/server/domain/search/repository/SearchRankRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/search/repository/SearchRankRepository.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.search.repository; - -import com.sluv.server.domain.search.entity.SearchRank; -import org.springframework.data.jpa.repository.JpaRepository; +package com.sluv.domain.search.repository; +import com.sluv.domain.search.entity.SearchRank; import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; public interface SearchRankRepository extends JpaRepository { List findAllByOrderBySearchCountDesc(); diff --git a/sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/RecentSearchRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/RecentSearchRepositoryCustom.java new file mode 100644 index 00000000..2e1faca8 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/RecentSearchRepositoryCustom.java @@ -0,0 +1,9 @@ +package com.sluv.domain.search.repository.impl; + +import com.sluv.domain.search.entity.RecentSearch; +import com.sluv.domain.user.entity.User; +import java.util.List; + +public interface RecentSearchRepositoryCustom { + List getRecentSearch(User user); +} diff --git a/src/main/java/com/sluv/server/domain/search/repository/impl/RecentSearchRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/RecentSearchRepositoryImpl.java similarity index 73% rename from src/main/java/com/sluv/server/domain/search/repository/impl/RecentSearchRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/RecentSearchRepositoryImpl.java index d3f25ec6..2fc9ea61 100644 --- a/src/main/java/com/sluv/server/domain/search/repository/impl/RecentSearchRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/RecentSearchRepositoryImpl.java @@ -1,10 +1,10 @@ -package com.sluv.server.domain.search.repository.impl; +package com.sluv.domain.search.repository.impl; -import static com.sluv.server.domain.search.entity.QRecentSearch.recentSearch; +import static com.sluv.domain.search.entity.QRecentSearch.recentSearch; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.search.entity.RecentSearch; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.search.entity.RecentSearch; +import com.sluv.domain.user.entity.User; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/search/repository/impl/SearchDataRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/SearchDataRepositoryCustom.java similarity index 73% rename from src/main/java/com/sluv/server/domain/search/repository/impl/SearchDataRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/SearchDataRepositoryCustom.java index f91cc944..d016b7dc 100644 --- a/src/main/java/com/sluv/server/domain/search/repository/impl/SearchDataRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/SearchDataRepositoryCustom.java @@ -1,12 +1,11 @@ -package com.sluv.server.domain.search.repository.impl; +package com.sluv.domain.search.repository.impl; import com.querydsl.core.Tuple; -import com.sluv.server.domain.search.entity.SearchData; +import com.sluv.domain.search.entity.SearchData; +import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import java.util.List; - public interface SearchDataRepositoryCustom { List getTopData(); diff --git a/src/main/java/com/sluv/server/domain/search/repository/impl/SearchDataRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/SearchDataRepositoryImpl.java similarity index 89% rename from src/main/java/com/sluv/server/domain/search/repository/impl/SearchDataRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/SearchDataRepositoryImpl.java index 7f53de23..6b790ee9 100644 --- a/src/main/java/com/sluv/server/domain/search/repository/impl/SearchDataRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/search/repository/impl/SearchDataRepositoryImpl.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.search.repository.impl; +package com.sluv.domain.search.repository.impl; -import static com.sluv.server.domain.search.entity.QSearchData.searchData; +import static com.sluv.domain.search.entity.QSearchData.searchData; import com.querydsl.core.Tuple; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.search.entity.SearchData; +import com.sluv.domain.search.entity.SearchData; import java.time.LocalDateTime; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/sluv-domain/src/main/java/com/sluv/domain/search/service/RecentSearchDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/search/service/RecentSearchDomainService.java new file mode 100644 index 00000000..69a099e4 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/search/service/RecentSearchDomainService.java @@ -0,0 +1,37 @@ +package com.sluv.domain.search.service; + +import com.sluv.domain.search.entity.RecentSearch; +import com.sluv.domain.search.repository.RecentSearchRepository; +import com.sluv.domain.user.entity.User; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class RecentSearchDomainService { + + private final RecentSearchRepository recentSearchRepository; + + @Transactional(readOnly = true) + public List getRecentSearch(User user) { + return recentSearchRepository.getRecentSearch(user); + } + + @Transactional + public void saveRecentSearch(User user, String keyword) { + RecentSearch recentSearch = RecentSearch.of(user, keyword); + recentSearchRepository.save(recentSearch); + } + + @Transactional + public void deleteByUserIdAndSearchWord(Long userId, String keyword) { + recentSearchRepository.deleteByUserIdAndSearchWord(userId, keyword); + } + + @Transactional + public void deleteAllByUserId(Long userId) { + recentSearchRepository.deleteAllByUserId(userId); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/search/service/SearchDataDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/search/service/SearchDataDomainService.java new file mode 100644 index 00000000..4fc07b72 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/search/service/SearchDataDomainService.java @@ -0,0 +1,41 @@ +package com.sluv.domain.search.service; + +import com.querydsl.core.Tuple; +import com.sluv.domain.search.entity.SearchData; +import com.sluv.domain.search.entity.SearchRank; +import com.sluv.domain.search.repository.SearchDataRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class SearchDataDomainService { + + private final SearchDataRepository searchDataRepository; + + @Transactional(readOnly = true) + public Page getSearchKeyword(String keyword, Pageable pageable) { + return searchDataRepository.getSearchKeyword(keyword, pageable); + } + + @Transactional + public void saveSearchData(String keyword) { + SearchData searchData = SearchData.of(keyword); + searchDataRepository.save(searchData); + } + + @Transactional(readOnly = true) + public List getTopData() { + List topData = searchDataRepository.getTopData(); + return topData.stream().map(data -> + SearchRank.of( + data.get(1, Long.class), + data.get(0, SearchData.class).getSearchWord() + )).toList(); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/search/service/SearchRankDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/search/service/SearchRankDomainService.java new file mode 100644 index 00000000..04c74aa1 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/search/service/SearchRankDomainService.java @@ -0,0 +1,31 @@ +package com.sluv.domain.search.service; + +import com.sluv.domain.search.entity.SearchRank; +import com.sluv.domain.search.repository.SearchRankRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class SearchRankDomainService { + + private final SearchRankRepository searchRankRepository; + + @Transactional(readOnly = true) + public List findAllByOrderBySearchCountDesc() { + return searchRankRepository.findAllByOrderBySearchCountDesc(); + } + + @Transactional + public void deleteAllSearchRank() { + searchRankRepository.deleteAll(); + } + + @Transactional + public void saveAllSearchRank(List result) { + searchRankRepository.saveAll(result); + } +} diff --git a/src/main/java/com/sluv/server/domain/user/dto/UserInfoDto.java b/sluv-domain/src/main/java/com/sluv/domain/user/dto/UserInfoDto.java similarity index 91% rename from src/main/java/com/sluv/server/domain/user/dto/UserInfoDto.java rename to sluv-domain/src/main/java/com/sluv/domain/user/dto/UserInfoDto.java index d989d970..3f040959 100644 --- a/src/main/java/com/sluv/server/domain/user/dto/UserInfoDto.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/dto/UserInfoDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.user.dto; +package com.sluv.domain.user.dto; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.user.entity.User; import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/sluv/server/domain/user/dto/UserSearchInfoDto.java b/sluv-domain/src/main/java/com/sluv/domain/user/dto/UserSearchInfoDto.java similarity index 92% rename from src/main/java/com/sluv/server/domain/user/dto/UserSearchInfoDto.java rename to sluv-domain/src/main/java/com/sluv/domain/user/dto/UserSearchInfoDto.java index f5e7b28d..ed8a7972 100644 --- a/src/main/java/com/sluv/server/domain/user/dto/UserSearchInfoDto.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/dto/UserSearchInfoDto.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.user.dto; +package com.sluv.domain.user.dto; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.user.entity.User; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/domain/user/entity/Follow.java b/sluv-domain/src/main/java/com/sluv/domain/user/entity/Follow.java similarity index 92% rename from src/main/java/com/sluv/server/domain/user/entity/Follow.java rename to sluv-domain/src/main/java/com/sluv/domain/user/entity/Follow.java index 65c5a191..6687f1d4 100644 --- a/src/main/java/com/sluv/server/domain/user/entity/Follow.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/entity/Follow.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.user.entity; +package com.sluv.domain.user.entity; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/user/entity/User.java b/sluv-domain/src/main/java/com/sluv/domain/user/entity/User.java similarity index 75% rename from src/main/java/com/sluv/server/domain/user/entity/User.java rename to sluv-domain/src/main/java/com/sluv/domain/user/entity/User.java index 7a2947ad..23e96473 100644 --- a/src/main/java/com/sluv/server/domain/user/entity/User.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/entity/User.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.user.entity; - -import com.sluv.server.domain.auth.dto.SocialUserInfoDto; -import com.sluv.server.domain.auth.enums.SnsType; -import com.sluv.server.domain.user.enums.UserAge; -import com.sluv.server.domain.user.enums.UserGender; -import com.sluv.server.domain.user.enums.UserStatus; -import com.sluv.server.global.common.entity.BaseEntity; +package com.sluv.domain.user.entity; + +import com.sluv.domain.auth.dto.SocialUserInfoDto; +import com.sluv.domain.auth.enums.SnsType; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.enums.UserAge; +import com.sluv.domain.user.enums.UserGender; +import com.sluv.domain.user.enums.UserStatus; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -16,14 +16,11 @@ import jakarta.persistence.Table; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import java.util.Collection; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import org.hibernate.annotations.DynamicInsert; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; @Entity @@ -33,7 +30,7 @@ @Builder @DynamicInsert @Table(name = "user") -public class User extends BaseEntity implements UserDetails { +public class User extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -130,39 +127,4 @@ public void changeAlarmStatus(Boolean alarmStatus) { this.alarmStatus = alarmStatus; } - @Override - public Collection getAuthorities() { - return null; - } - - @Override - public String getPassword() { - return null; - } - - @Override - public String getUsername() { - return null; - } - - @Override - public boolean isAccountNonExpired() { - return false; - } - - @Override - public boolean isAccountNonLocked() { - return false; - } - - @Override - public boolean isCredentialsNonExpired() { - return false; - } - - @Override - public boolean isEnabled() { - return false; - - } } diff --git a/src/main/java/com/sluv/server/domain/user/entity/UserReport.java b/sluv-domain/src/main/java/com/sluv/domain/user/entity/UserReport.java similarity index 80% rename from src/main/java/com/sluv/server/domain/user/entity/UserReport.java rename to sluv-domain/src/main/java/com/sluv/domain/user/entity/UserReport.java index 63c6bad8..3a16ab02 100644 --- a/src/main/java/com/sluv/server/domain/user/entity/UserReport.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/entity/UserReport.java @@ -1,9 +1,8 @@ -package com.sluv.server.domain.user.entity; +package com.sluv.domain.user.entity; -import com.sluv.server.domain.user.dto.UserReportReqDto; -import com.sluv.server.domain.user.enums.UserReportReason; -import com.sluv.server.global.common.entity.BaseEntity; -import com.sluv.server.global.common.enums.ReportStatus; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.common.enums.ReportStatus; +import com.sluv.domain.user.enums.UserReportReason; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -56,12 +55,12 @@ public class UserReport extends BaseEntity { @Column(length = 45, columnDefinition = "varchar(45) default 'WAITING'") private ReportStatus reportStatus; - public static UserReport toEntity(User reporter, User target, UserReportReqDto dto) { + public static UserReport toEntity(User reporter, User target, UserReportReason reason, String content) { return UserReport.builder() .reporter(reporter) .reported(target) - .userReportReason(dto.getReason()) - .content(dto.getContent()) + .userReportReason(reason) + .content(content) .reportStatus(ReportStatus.WAITING) .build(); } diff --git a/src/main/java/com/sluv/server/domain/user/entity/UserReportStack.java b/sluv-domain/src/main/java/com/sluv/domain/user/entity/UserReportStack.java similarity index 90% rename from src/main/java/com/sluv/server/domain/user/entity/UserReportStack.java rename to sluv-domain/src/main/java/com/sluv/domain/user/entity/UserReportStack.java index 8014622d..749736e3 100644 --- a/src/main/java/com/sluv/server/domain/user/entity/UserReportStack.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/entity/UserReportStack.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.user.entity; +package com.sluv.domain.user.entity; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/sluv/server/domain/user/entity/UserWithdraw.java b/sluv-domain/src/main/java/com/sluv/domain/user/entity/UserWithdraw.java similarity index 79% rename from src/main/java/com/sluv/server/domain/user/entity/UserWithdraw.java rename to sluv-domain/src/main/java/com/sluv/domain/user/entity/UserWithdraw.java index 87e3c1fd..8d65840d 100644 --- a/src/main/java/com/sluv/server/domain/user/entity/UserWithdraw.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/entity/UserWithdraw.java @@ -1,8 +1,7 @@ -package com.sluv.server.domain.user.entity; +package com.sluv.domain.user.entity; -import com.sluv.server.domain.user.dto.UserWithdrawReqDto; -import com.sluv.server.domain.user.enums.UserWithdrawReason; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; +import com.sluv.domain.user.enums.UserWithdrawReason; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -46,11 +45,11 @@ public class UserWithdraw extends BaseEntity { @Column(name = "content") private String content; - public static UserWithdraw toEntity(User user, UserWithdrawReqDto dto) { + public static UserWithdraw toEntity(User user, UserWithdrawReason reason, String content) { return UserWithdraw.builder() .user(user) - .userWithdrawReason(dto.getReason()) - .content(dto.getContent()) + .userWithdrawReason(reason) + .content(content) .build(); } } diff --git a/src/main/java/com/sluv/server/domain/user/enums/UserAge.java b/sluv-domain/src/main/java/com/sluv/domain/user/enums/UserAge.java similarity index 89% rename from src/main/java/com/sluv/server/domain/user/enums/UserAge.java rename to sluv-domain/src/main/java/com/sluv/domain/user/enums/UserAge.java index 1c6c669a..6212cbd1 100644 --- a/src/main/java/com/sluv/server/domain/user/enums/UserAge.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/enums/UserAge.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.user.enums; +package com.sluv.domain.user.enums; public enum UserAge { UNKNOWN(-1), diff --git a/src/main/java/com/sluv/server/domain/user/enums/UserGender.java b/sluv-domain/src/main/java/com/sluv/domain/user/enums/UserGender.java similarity index 55% rename from src/main/java/com/sluv/server/domain/user/enums/UserGender.java rename to sluv-domain/src/main/java/com/sluv/domain/user/enums/UserGender.java index fe357427..3bb23f97 100644 --- a/src/main/java/com/sluv/server/domain/user/enums/UserGender.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/enums/UserGender.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.user.enums; +package com.sluv.domain.user.enums; public enum UserGender { MALE, FEMALE, UNKNOWN diff --git a/src/main/java/com/sluv/server/domain/user/enums/UserReportReason.java b/sluv-domain/src/main/java/com/sluv/domain/user/enums/UserReportReason.java similarity index 76% rename from src/main/java/com/sluv/server/domain/user/enums/UserReportReason.java rename to sluv-domain/src/main/java/com/sluv/domain/user/enums/UserReportReason.java index 07509640..77fd31f8 100644 --- a/src/main/java/com/sluv/server/domain/user/enums/UserReportReason.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/enums/UserReportReason.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.user.enums; +package com.sluv.domain.user.enums; public enum UserReportReason { SELLER, diff --git a/src/main/java/com/sluv/server/domain/user/enums/UserStatus.java b/sluv-domain/src/main/java/com/sluv/domain/user/enums/UserStatus.java similarity index 71% rename from src/main/java/com/sluv/server/domain/user/enums/UserStatus.java rename to sluv-domain/src/main/java/com/sluv/domain/user/enums/UserStatus.java index 072ce58a..ab5601a1 100644 --- a/src/main/java/com/sluv/server/domain/user/enums/UserStatus.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/enums/UserStatus.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.user.enums; +package com.sluv.domain.user.enums; public enum UserStatus { ACTIVE, diff --git a/src/main/java/com/sluv/server/domain/user/enums/UserWithdrawReason.java b/sluv-domain/src/main/java/com/sluv/domain/user/enums/UserWithdrawReason.java similarity index 69% rename from src/main/java/com/sluv/server/domain/user/enums/UserWithdrawReason.java rename to sluv-domain/src/main/java/com/sluv/domain/user/enums/UserWithdrawReason.java index a77e238e..d4fbc67a 100644 --- a/src/main/java/com/sluv/server/domain/user/enums/UserWithdrawReason.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/enums/UserWithdrawReason.java @@ -1,4 +1,4 @@ -package com.sluv.server.domain.user.enums; +package com.sluv.domain.user.enums; public enum UserWithdrawReason { NO_INFO, diff --git a/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserException.java b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserException.java new file mode 100644 index 00000000..80bc7d4e --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserException.java @@ -0,0 +1,10 @@ +package com.sluv.domain.user.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class UserException extends ApplicationException { + public UserException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/domain/user/exception/UserNicknameDuplicatedException.java b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNicknameDuplicatedException.java similarity index 64% rename from src/main/java/com/sluv/server/domain/user/exception/UserNicknameDuplicatedException.java rename to sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNicknameDuplicatedException.java index d5abd53b..d40a93c4 100644 --- a/src/main/java/com/sluv/server/domain/user/exception/UserNicknameDuplicatedException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNicknameDuplicatedException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.user.exception; +package com.sluv.domain.user.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class UserNicknameDuplicatedException extends UserException { private static final int ERROR_CODE = 2017; private static final String MESSAGE = "중복된 유저 닉네임입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public UserNicknameDuplicatedException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/user/exception/UserNoFCMException.java b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNoFCMException.java similarity index 61% rename from src/main/java/com/sluv/server/domain/user/exception/UserNoFCMException.java rename to sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNoFCMException.java index 1c4a1723..b9994564 100644 --- a/src/main/java/com/sluv/server/domain/user/exception/UserNoFCMException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNoFCMException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.user.exception; +package com.sluv.domain.user.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class UserNoFCMException extends UserException { private static final int ERROR_CODE = 2030; private static final String MESSAGE = "FCM 토큰이 없습니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public UserNoFCMException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/user/exception/UserNotFoundException.java b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNotFoundException.java similarity index 56% rename from src/main/java/com/sluv/server/domain/user/exception/UserNotFoundException.java rename to sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNotFoundException.java index aa4eb269..c12b389c 100644 --- a/src/main/java/com/sluv/server/domain/user/exception/UserNotFoundException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNotFoundException.java @@ -1,12 +1,11 @@ -package com.sluv.server.domain.user.exception; +package com.sluv.domain.user.exception; -import com.sluv.server.domain.auth.exception.AuthException; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class UserNotFoundException extends UserException { private static final int ERROR_CODE = 2000; private static final String MESSAGE = "존재하지 않는 유저입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public UserNotFoundException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/user/exception/UserNotMatchedException.java b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNotMatchedException.java similarity index 57% rename from src/main/java/com/sluv/server/domain/user/exception/UserNotMatchedException.java rename to sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNotMatchedException.java index ec3781d6..1a67af9a 100644 --- a/src/main/java/com/sluv/server/domain/user/exception/UserNotMatchedException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserNotMatchedException.java @@ -1,12 +1,11 @@ -package com.sluv.server.domain.user.exception; +package com.sluv.domain.user.exception; -import com.sluv.server.domain.auth.exception.AuthException; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class UserNotMatchedException extends UserException { private static final int ERROR_CODE = 2015; private static final String MESSAGE = "유저 정보가 일치하지 않습니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public UserNotMatchedException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/domain/user/exception/UserReportDuplicateException.java b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserReportDuplicateException.java similarity index 63% rename from src/main/java/com/sluv/server/domain/user/exception/UserReportDuplicateException.java rename to sluv-domain/src/main/java/com/sluv/domain/user/exception/UserReportDuplicateException.java index 88075482..072c969f 100644 --- a/src/main/java/com/sluv/server/domain/user/exception/UserReportDuplicateException.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/exception/UserReportDuplicateException.java @@ -1,11 +1,11 @@ -package com.sluv.server.domain.user.exception; +package com.sluv.domain.user.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class UserReportDuplicateException extends UserException { private static final int ERROR_CODE = 2010; private static final String MESSAGE = "중복된 유저 신고입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; + private static final HttpStatusCode STATUS = HttpStatusCode.BAD_REQUEST; public UserReportDuplicateException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/sluv-domain/src/main/java/com/sluv/domain/user/repository/FollowRepository.java b/sluv-domain/src/main/java/com/sluv/domain/user/repository/FollowRepository.java new file mode 100644 index 00000000..23a8eb84 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/user/repository/FollowRepository.java @@ -0,0 +1,8 @@ +package com.sluv.domain.user.repository; + +import com.sluv.domain.user.entity.Follow; +import com.sluv.domain.user.repository.impl.FollowRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FollowRepository extends JpaRepository, FollowRepositoryCustom { +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/user/repository/UserReportRepository.java b/sluv-domain/src/main/java/com/sluv/domain/user/repository/UserReportRepository.java new file mode 100644 index 00000000..4d8fbc79 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/user/repository/UserReportRepository.java @@ -0,0 +1,8 @@ +package com.sluv.domain.user.repository; + +import com.sluv.domain.user.entity.UserReport; +import com.sluv.domain.user.repository.impl.UserReportRepositoryCustom; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserReportRepository extends JpaRepository, UserReportRepositoryCustom { +} diff --git a/src/main/java/com/sluv/server/domain/user/repository/UserReportStackRepository.java b/sluv-domain/src/main/java/com/sluv/domain/user/repository/UserReportStackRepository.java similarity index 65% rename from src/main/java/com/sluv/server/domain/user/repository/UserReportStackRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/user/repository/UserReportStackRepository.java index 5feae133..b438468c 100644 --- a/src/main/java/com/sluv/server/domain/user/repository/UserReportStackRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/repository/UserReportStackRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.user.repository; +package com.sluv.domain.user.repository; -import com.sluv.server.domain.user.entity.UserReportStack; +import com.sluv.domain.user.entity.UserReportStack; import org.springframework.data.jpa.repository.JpaRepository; public interface UserReportStackRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/user/repository/UserRepository.java b/sluv-domain/src/main/java/com/sluv/domain/user/repository/UserRepository.java similarity index 59% rename from src/main/java/com/sluv/server/domain/user/repository/UserRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/user/repository/UserRepository.java index 42c8cd24..b72a91b9 100644 --- a/src/main/java/com/sluv/server/domain/user/repository/UserRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/repository/UserRepository.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.user.repository; +package com.sluv.domain.user.repository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.enums.UserStatus; -import com.sluv.server.domain.user.repository.impl.UserRepositoryCustom; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.enums.UserStatus; +import com.sluv.domain.user.repository.impl.UserRepositoryCustom; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/sluv/server/domain/user/repository/UserWithdrawRepository.java b/sluv-domain/src/main/java/com/sluv/domain/user/repository/UserWithdrawRepository.java similarity index 59% rename from src/main/java/com/sluv/server/domain/user/repository/UserWithdrawRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/user/repository/UserWithdrawRepository.java index 4624dd2a..6a3d6834 100644 --- a/src/main/java/com/sluv/server/domain/user/repository/UserWithdrawRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/repository/UserWithdrawRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.user.repository; +package com.sluv.domain.user.repository; -import com.sluv.server.domain.user.entity.UserWithdraw; +import com.sluv.domain.user.entity.UserWithdraw; import org.springframework.data.jpa.repository.JpaRepository; public interface UserWithdrawRepository extends JpaRepository { diff --git a/src/main/java/com/sluv/server/domain/user/repository/impl/FollowRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/FollowRepositoryCustom.java similarity index 71% rename from src/main/java/com/sluv/server/domain/user/repository/impl/FollowRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/FollowRepositoryCustom.java index 8d952862..2aa9e154 100644 --- a/src/main/java/com/sluv/server/domain/user/repository/impl/FollowRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/FollowRepositoryCustom.java @@ -1,8 +1,8 @@ -package com.sluv.server.domain.user.repository.impl; +package com.sluv.domain.user.repository.impl; -import com.sluv.server.domain.user.dto.UserSearchInfoDto; -import com.sluv.server.domain.user.entity.Follow; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.user.dto.UserSearchInfoDto; +import com.sluv.domain.user.entity.Follow; +import com.sluv.domain.user.entity.User; import java.util.List; public interface FollowRepositoryCustom { diff --git a/src/main/java/com/sluv/server/domain/user/repository/impl/FollowRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/FollowRepositoryImpl.java similarity index 88% rename from src/main/java/com/sluv/server/domain/user/repository/impl/FollowRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/FollowRepositoryImpl.java index 82a2e811..a904d9dd 100644 --- a/src/main/java/com/sluv/server/domain/user/repository/impl/FollowRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/FollowRepositoryImpl.java @@ -1,13 +1,13 @@ -package com.sluv.server.domain.user.repository.impl; +package com.sluv.domain.user.repository.impl; -import static com.sluv.server.domain.user.entity.QFollow.follow; -import static com.sluv.server.domain.user.entity.QUser.user; +import static com.sluv.domain.user.entity.QFollow.follow; +import static com.sluv.domain.user.entity.QUser.user; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.user.dto.UserSearchInfoDto; -import com.sluv.server.domain.user.entity.Follow; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.enums.UserStatus; +import com.sluv.domain.user.dto.UserSearchInfoDto; +import com.sluv.domain.user.entity.Follow; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.enums.UserStatus; import java.util.List; import java.util.Map; import java.util.Objects; diff --git a/src/main/java/com/sluv/server/domain/user/repository/impl/UserReportRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserReportRepositoryCustom.java similarity index 58% rename from src/main/java/com/sluv/server/domain/user/repository/impl/UserReportRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserReportRepositoryCustom.java index da59a5c2..bb87c3f1 100644 --- a/src/main/java/com/sluv/server/domain/user/repository/impl/UserReportRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserReportRepositoryCustom.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.user.repository.impl; +package com.sluv.domain.user.repository.impl; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.user.entity.User; public interface UserReportRepositoryCustom { Boolean findExistence(User user, User target); diff --git a/src/main/java/com/sluv/server/domain/user/repository/impl/UserReportRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserReportRepositoryImpl.java similarity index 85% rename from src/main/java/com/sluv/server/domain/user/repository/impl/UserReportRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserReportRepositoryImpl.java index 66352e56..fc9b71d1 100644 --- a/src/main/java/com/sluv/server/domain/user/repository/impl/UserReportRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserReportRepositoryImpl.java @@ -1,9 +1,9 @@ -package com.sluv.server.domain.user.repository.impl; +package com.sluv.domain.user.repository.impl; -import static com.sluv.server.domain.user.entity.QUserReport.userReport; +import static com.sluv.domain.user.entity.QUserReport.userReport; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.user.entity.User; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor diff --git a/src/main/java/com/sluv/server/domain/user/repository/impl/UserRepositoryCustom.java b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserRepositoryCustom.java similarity index 84% rename from src/main/java/com/sluv/server/domain/user/repository/impl/UserRepositoryCustom.java rename to sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserRepositoryCustom.java index 7acb400d..60f7cdc8 100644 --- a/src/main/java/com/sluv/server/domain/user/repository/impl/UserRepositoryCustom.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserRepositoryCustom.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.user.repository.impl; +package com.sluv.domain.user.repository.impl; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.user.entity.User; import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/sluv/server/domain/user/repository/impl/UserRepositoryImpl.java b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserRepositoryImpl.java similarity index 90% rename from src/main/java/com/sluv/server/domain/user/repository/impl/UserRepositoryImpl.java rename to sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserRepositoryImpl.java index 9e172669..bb23cce8 100644 --- a/src/main/java/com/sluv/server/domain/user/repository/impl/UserRepositoryImpl.java +++ b/sluv-domain/src/main/java/com/sluv/domain/user/repository/impl/UserRepositoryImpl.java @@ -1,18 +1,18 @@ -package com.sluv.server.domain.user.repository.impl; +package com.sluv.domain.user.repository.impl; -import static com.sluv.server.domain.celeb.entity.QInterestedCeleb.interestedCeleb; -import static com.sluv.server.domain.item.entity.QItem.item; -import static com.sluv.server.domain.item.entity.QItemLike.itemLike; -import static com.sluv.server.domain.user.entity.QFollow.follow; -import static com.sluv.server.domain.user.entity.QUser.user; -import static com.sluv.server.domain.user.enums.UserStatus.ACTIVE; -import static com.sluv.server.domain.user.enums.UserStatus.DELETED; +import static com.sluv.domain.celeb.entity.QInterestedCeleb.interestedCeleb; +import static com.sluv.domain.item.entity.QItem.item; +import static com.sluv.domain.item.entity.QItemLike.itemLike; +import static com.sluv.domain.user.entity.QFollow.follow; +import static com.sluv.domain.user.entity.QUser.user; +import static com.sluv.domain.user.enums.UserStatus.ACTIVE; +import static com.sluv.domain.user.enums.UserStatus.DELETED; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.item.enums.ItemStatus; -import com.sluv.server.domain.user.entity.Follow; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.item.enums.ItemStatus; +import com.sluv.domain.user.entity.Follow; +import com.sluv.domain.user.entity.User; import java.time.LocalDateTime; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/sluv-domain/src/main/java/com/sluv/domain/user/service/FollowDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/user/service/FollowDomainService.java new file mode 100644 index 00000000..c4509702 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/user/service/FollowDomainService.java @@ -0,0 +1,62 @@ +package com.sluv.domain.user.service; + +import com.sluv.domain.user.dto.UserSearchInfoDto; +import com.sluv.domain.user.entity.Follow; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.repository.FollowRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class FollowDomainService { + + private final FollowRepository followRepository; + + @Transactional(readOnly = true) + public List getAllFollower(Long userId) { + return followRepository.getAllFollower(userId); + } + + @Transactional(readOnly = true) + public Boolean getFollowStatus(User user, Long targetUserId) { + return followRepository.getFollowStatus(user, targetUserId); + } + + @Transactional + public void deleteFollow(User user, User targetUser) { + followRepository.deleteFollow(user, targetUser); + } + + @Transactional + public Follow saveFollow(Follow follow) { + return followRepository.save(follow); + } + + @Transactional(readOnly = true) + public List getUserSearchInfoDto(User user, List content, String follower) { + return followRepository.getUserSearchInfoDto(user, content, follower); + } + + @Transactional(readOnly = true) + public Long getFollowerCount(User targetUser) { + return followRepository.getFollowerCount(targetUser); + } + + @Transactional(readOnly = true) + public Long getFollowingCount(User targetUser) { + return followRepository.getFollowingCount(targetUser); + } + + @Transactional + public void deleteFolloweeByUserId(Long userId) { + followRepository.deleteFolloweeByUserId(userId); + } + + @Transactional + public void deleteFollowerByUserId(Long userId) { + followRepository.deleteFollowerByUserId(userId); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/user/service/UserDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/user/service/UserDomainService.java new file mode 100644 index 00000000..b4bb49f0 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/user/service/UserDomainService.java @@ -0,0 +1,72 @@ +package com.sluv.domain.user.service; + +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.exception.UserNotFoundException; +import com.sluv.domain.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class UserDomainService { + + private final UserRepository userRepository; + + @Transactional(readOnly = true) + public User findById(Long userId) { + return userRepository.findById(userId).orElseThrow(UserNotFoundException::new); + } + + @Transactional(readOnly = true) + public Page getAllFollower(Long targetId, Pageable pageable) { + return userRepository.getAllFollower(targetId, pageable); + } + + @Transactional(readOnly = true) + public Page getAllFollowing(Long userId, Pageable pageable) { + return userRepository.getAllFollowing(userId, pageable); + } + + @Transactional + public User createUser(User user) { + return userRepository.save(user); + } + + @Transactional + public User saveUser(User user) { + return userRepository.save(user); + } + + @Transactional(readOnly = true) + public User findByIdOrNull(Long userId) { + if (userId == null) { + return null; + } + return userRepository.findById(userId).orElse(null); + } + + @Transactional(readOnly = true) + public Boolean existsByNickname(String nickName) { + return userRepository.existsByNickname(nickName); + } + + @Transactional(readOnly = true) + public List getHotSluver(Long celebId) { + return userRepository.getHotSluver(celebId); + } + + @Transactional(readOnly = true) + public Page getSearchUser(List searchUserIds, Pageable pageable) { + return userRepository.getSearchUser(searchUserIds, pageable); + } + + @Transactional(readOnly = true) + public User findByEmailOrNull(String email) { + return userRepository.findByEmail(email).orElse(null); + } +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/user/service/UserReportDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/user/service/UserReportDomainService.java new file mode 100644 index 00000000..5015d678 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/user/service/UserReportDomainService.java @@ -0,0 +1,27 @@ +package com.sluv.domain.user.service; + +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.entity.UserReport; +import com.sluv.domain.user.enums.UserReportReason; +import com.sluv.domain.user.repository.UserReportRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class UserReportDomainService { + + private final UserReportRepository userReportRepository; + + public boolean findExistence(User user, User target) { + return userReportRepository.findExistence(user, target); + } + + @Transactional + public void saveUserReport(User user, User target, UserReportReason reason, String content) { + UserReport userReport = UserReport.toEntity(user, target, reason, content); + userReportRepository.save(userReport); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/user/service/UserReportStackDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/user/service/UserReportStackDomainService.java new file mode 100644 index 00000000..0f6af707 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/user/service/UserReportStackDomainService.java @@ -0,0 +1,19 @@ +package com.sluv.domain.user.service; + +import com.sluv.domain.user.repository.UserReportStackRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class UserReportStackDomainService { + + private final UserReportStackRepository userReportStackRepository; + + @Transactional + public void deleteAllByReportedId(Long userId) { + userReportStackRepository.deleteAllByReportedId(userId); + } + +} diff --git a/sluv-domain/src/main/java/com/sluv/domain/user/service/UserWithdrawDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/user/service/UserWithdrawDomainService.java new file mode 100644 index 00000000..89ae8745 --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/user/service/UserWithdrawDomainService.java @@ -0,0 +1,22 @@ +package com.sluv.domain.user.service; + +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.entity.UserWithdraw; +import com.sluv.domain.user.enums.UserWithdrawReason; +import com.sluv.domain.user.repository.UserWithdrawRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class UserWithdrawDomainService { + + private final UserWithdrawRepository userWithdrawRepository; + + @Transactional + public void saveUserWithdraw(User user, UserWithdrawReason reason, String content) { + UserWithdraw userWithdraw = UserWithdraw.toEntity(user, reason, content); + userWithdrawRepository.save(userWithdraw); + } +} \ No newline at end of file diff --git a/src/main/java/com/sluv/server/domain/visit/entity/VisitHistory.java b/sluv-domain/src/main/java/com/sluv/domain/visit/entity/VisitHistory.java similarity index 89% rename from src/main/java/com/sluv/server/domain/visit/entity/VisitHistory.java rename to sluv-domain/src/main/java/com/sluv/domain/visit/entity/VisitHistory.java index 102bad01..da2e3ac6 100644 --- a/src/main/java/com/sluv/server/domain/visit/entity/VisitHistory.java +++ b/sluv-domain/src/main/java/com/sluv/domain/visit/entity/VisitHistory.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.visit.entity; +package com.sluv.domain.visit.entity; -import com.sluv.server.global.common.entity.BaseEntity; +import com.sluv.domain.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/src/main/java/com/sluv/server/domain/visit/repository/VisitHistoryRepository.java b/sluv-domain/src/main/java/com/sluv/domain/visit/repository/VisitHistoryRepository.java similarity index 58% rename from src/main/java/com/sluv/server/domain/visit/repository/VisitHistoryRepository.java rename to sluv-domain/src/main/java/com/sluv/domain/visit/repository/VisitHistoryRepository.java index 54e50d44..c62cea11 100644 --- a/src/main/java/com/sluv/server/domain/visit/repository/VisitHistoryRepository.java +++ b/sluv-domain/src/main/java/com/sluv/domain/visit/repository/VisitHistoryRepository.java @@ -1,6 +1,6 @@ -package com.sluv.server.domain.visit.repository; +package com.sluv.domain.visit.repository; -import com.sluv.server.domain.visit.entity.VisitHistory; +import com.sluv.domain.visit.entity.VisitHistory; import org.springframework.data.jpa.repository.JpaRepository; public interface VisitHistoryRepository extends JpaRepository { diff --git a/sluv-domain/src/main/java/com/sluv/domain/visit/service/VisitHistoryDomainService.java b/sluv-domain/src/main/java/com/sluv/domain/visit/service/VisitHistoryDomainService.java new file mode 100644 index 00000000..96553a2a --- /dev/null +++ b/sluv-domain/src/main/java/com/sluv/domain/visit/service/VisitHistoryDomainService.java @@ -0,0 +1,22 @@ +package com.sluv.domain.visit.service; + +import com.sluv.domain.visit.entity.VisitHistory; +import com.sluv.domain.visit.repository.VisitHistoryRepository; +import java.time.LocalDateTime; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class VisitHistoryDomainService { + + private final VisitHistoryRepository visitHistoryRepository; + + @Transactional + public void saveVisitHistory(LocalDateTime localDateTime, Long visitantCount) { + VisitHistory visitHistory = VisitHistory.of(localDateTime, visitantCount); + visitHistoryRepository.save(visitHistory); + } + +} diff --git a/sluv-domain/src/main/resources/application-domain.yml b/sluv-domain/src/main/resources/application-domain.yml new file mode 100644 index 00000000..b23d4a3f --- /dev/null +++ b/sluv-domain/src/main/resources/application-domain.yml @@ -0,0 +1,47 @@ +spring: + application: + name: domain + config: + import: optional:classpath:env/.env[.properties] + +--- +spring: + config: + activate: + on-profile: prod + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://${DB_HOST}:${DB_PORT}/${PROD_DB_NAME}?characterEncoding=UTF-8&serverTimezone=UTC + username: ${DB_USERNAME} + password: ${DB_PASSWORD} + + +--- +spring: + config: + activate: + on-profile: dev + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://${DB_HOST}:${DB_PORT}/${DEV_DB_NAME}?characterEncoding=UTF-8&serverTimezone=UTC + username: ${DB_USERNAME} + password: ${DB_PASSWORD} + jpa: + properties: + hibernate: + format_sql: true + +#--- +#spring: +# config: +# activate: +# on-profile: test +# datasource: +# driver-class-name: com.mysql.cj.jdbc.Driver +# url: jdbc:mysql://${DB_HOST}:${DB_PORT}/ENC(Q3zrPgD4jx+CdAN+KXksBBie7qoPJFFF)?characterEncoding=UTF-8&serverTimezone=UTC +# username: ${DB_USERNAME} +# password: ${DB_PASSWORD} +# jpa: +# properties: +# hibernate: +# format_sql: true \ No newline at end of file diff --git a/sluv-infra/build.gradle b/sluv-infra/build.gradle new file mode 100644 index 00000000..06d1c487 --- /dev/null +++ b/sluv-infra/build.gradle @@ -0,0 +1,20 @@ +dependencies { + + // Oauth + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + implementation 'com.google.api-client:google-api-client:2.2.0' + implementation 'com.google.auth:google-auth-library-oauth2-http:1.16.0' + + // AWS S3 + implementation 'com.amazonaws:aws-java-sdk-s3:1.12.232' + + // FCM + implementation 'com.google.firebase:firebase-admin:9.1.1' + + // Redis + implementation 'org.springframework.boot:spring-boot-starter-data-redis' + + implementation project(':sluv-domain') + api project(':sluv-common') + +} diff --git a/src/main/java/com/sluv/server/global/ai/AiModelRepository.java b/sluv-infra/src/main/java/com/sluv/infra/ai/AiModelRepository.java similarity index 81% rename from src/main/java/com/sluv/server/global/ai/AiModelRepository.java rename to sluv-infra/src/main/java/com/sluv/infra/ai/AiModelRepository.java index d77cdfba..818308b4 100644 --- a/src/main/java/com/sluv/server/global/ai/AiModelRepository.java +++ b/sluv-infra/src/main/java/com/sluv/infra/ai/AiModelRepository.java @@ -1,21 +1,17 @@ -package com.sluv.server.global.ai; +package com.sluv.infra.ai; -import com.sluv.server.global.ai.dto.CommentCleanBotReqDto; -import com.sluv.server.global.ai.dto.ItemColorCheckReqDto; +import com.sluv.infra.ai.dto.CommentCleanBotReqDto; +import com.sluv.infra.ai.dto.ItemColorCheckReqDto; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; import org.springframework.stereotype.Repository; import org.springframework.web.client.RestTemplate; @Repository @Slf4j public class AiModelRepository { - @Value("${spring.ai-model.uri}") + @Value("${ai-model.uri}") private String URL; public boolean isMaliciousComment(String comment) { diff --git a/src/main/java/com/sluv/server/global/ai/AiModelService.java b/sluv-infra/src/main/java/com/sluv/infra/ai/AiModelService.java similarity index 63% rename from src/main/java/com/sluv/server/global/ai/AiModelService.java rename to sluv-infra/src/main/java/com/sluv/infra/ai/AiModelService.java index 9d4eb360..b82a2298 100644 --- a/src/main/java/com/sluv/server/global/ai/AiModelService.java +++ b/sluv-infra/src/main/java/com/sluv/infra/ai/AiModelService.java @@ -1,13 +1,12 @@ -package com.sluv.server.global.ai; - -import com.sluv.server.domain.alarm.service.CommentAlarmService; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.enums.CommentStatus; -import com.sluv.server.domain.comment.repository.CommentRepository; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.ItemImg; -import com.sluv.server.domain.item.repository.ItemImgRepository; -import com.sluv.server.domain.item.repository.ItemRepository; +package com.sluv.infra.ai; + +import com.sluv.domain.comment.entity.Comment; +import com.sluv.domain.comment.enums.CommentStatus; +import com.sluv.domain.comment.repository.CommentRepository; +import com.sluv.domain.item.entity.Item; +import com.sluv.domain.item.entity.ItemImg; +import com.sluv.domain.item.repository.ItemImgRepository; +import com.sluv.domain.item.repository.ItemRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; @@ -22,7 +21,6 @@ public class AiModelService { private final ItemRepository itemRepository; private final ItemImgRepository itemImgRepository; - private final CommentAlarmService commentAlarmService; @Async(value = "asyncThreadPoolExecutor") public void censorComment(Comment comment) { @@ -31,7 +29,7 @@ public void censorComment(Comment comment) { if (isMalicious) { comment.changeStatus(CommentStatus.BLOCKED); commentRepository.save(comment); - commentAlarmService.sendAlarmAboutReportByAI(comment.getId(), null); +// commentAlarmService.sendAlarmAboutReportByAI(comment.getId(), null); } } diff --git a/src/main/java/com/sluv/server/global/ai/dto/CommentCleanBotReqDto.java b/sluv-infra/src/main/java/com/sluv/infra/ai/dto/CommentCleanBotReqDto.java similarity index 91% rename from src/main/java/com/sluv/server/global/ai/dto/CommentCleanBotReqDto.java rename to sluv-infra/src/main/java/com/sluv/infra/ai/dto/CommentCleanBotReqDto.java index 16ca6cd8..576719e7 100644 --- a/src/main/java/com/sluv/server/global/ai/dto/CommentCleanBotReqDto.java +++ b/sluv-infra/src/main/java/com/sluv/infra/ai/dto/CommentCleanBotReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.ai.dto; +package com.sluv.infra.ai.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/global/ai/dto/ItemColorCheckReqDto.java b/sluv-infra/src/main/java/com/sluv/infra/ai/dto/ItemColorCheckReqDto.java similarity index 91% rename from src/main/java/com/sluv/server/global/ai/dto/ItemColorCheckReqDto.java rename to sluv-infra/src/main/java/com/sluv/infra/ai/dto/ItemColorCheckReqDto.java index 56a4283a..4c93ae3e 100644 --- a/src/main/java/com/sluv/server/global/ai/dto/ItemColorCheckReqDto.java +++ b/sluv-infra/src/main/java/com/sluv/infra/ai/dto/ItemColorCheckReqDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.ai.dto; +package com.sluv.infra.ai.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/global/cache/CacheService.java b/sluv-infra/src/main/java/com/sluv/infra/cache/CacheService.java similarity index 60% rename from src/main/java/com/sluv/server/global/cache/CacheService.java rename to sluv-infra/src/main/java/com/sluv/infra/cache/CacheService.java index f6ec4fa2..0e7fb64e 100644 --- a/src/main/java/com/sluv/server/global/cache/CacheService.java +++ b/sluv-infra/src/main/java/com/sluv/infra/cache/CacheService.java @@ -1,19 +1,22 @@ -package com.sluv.server.global.cache; +package com.sluv.infra.cache; -import com.sluv.server.domain.item.dto.ItemDetailFixData; import org.springframework.stereotype.Service; @Service -public interface CacheService { +public interface CacheService { void visitMember(Long memberId); Long getVisitantCount(); void clearVisitantCount(); - void saveItemDetailFixData(Long itemId, ItemDetailFixData itemDetailFixData); + // + void saveItemDetailFixData(Long itemId, T itemDetailFixData); - ItemDetailFixData findItemDetailFixDataByItemId(Long itemId); + T findItemDetailFixDataByItemId(Long itemId); +// void saveItemDetailFixData(Long itemId, T itemDetailFixData); +// +// findItemDetailFixDataByItemId(Long itemId); void deleteItemDetailFixDataByItemId(Long itemId); diff --git a/src/main/java/com/sluv/server/global/cache/RedisService.java b/sluv-infra/src/main/java/com/sluv/infra/cache/RedisService.java similarity index 80% rename from src/main/java/com/sluv/server/global/cache/RedisService.java rename to sluv-infra/src/main/java/com/sluv/infra/cache/RedisService.java index dbef1a2b..ef8d7e32 100644 --- a/src/main/java/com/sluv/server/global/cache/RedisService.java +++ b/sluv-infra/src/main/java/com/sluv/infra/cache/RedisService.java @@ -1,7 +1,6 @@ -package com.sluv.server.global.cache; +package com.sluv.infra.cache; -import com.sluv.server.domain.item.dto.ItemDetailFixData; import java.util.Calendar; import java.util.Date; import java.util.concurrent.TimeUnit; @@ -14,10 +13,10 @@ @Service @RequiredArgsConstructor -public class RedisService implements CacheService { +public class RedisService implements CacheService { private final RedisTemplate redisStringLongTemplate; - private final RedisTemplate redisStringItemDetailFixDataTemplate; + private final RedisTemplate redisStringItemDetailFixDataTemplate; private final String VISITANT_KEY = "visitant"; @Async(value = "redisThreadPoolExecutor") @@ -40,21 +39,21 @@ public void clearVisitantCount() { @Async(value = "redisThreadPoolExecutor") @Override - public void saveItemDetailFixData(Long itemId, ItemDetailFixData itemDetailFixData) { - ValueOperations itemDetailFixDataCache = redisStringItemDetailFixDataTemplate.opsForValue(); + public void saveItemDetailFixData(Long itemId, T itemDetailFixData) { + ValueOperations itemDetailFixDataCache = redisStringItemDetailFixDataTemplate.opsForValue(); itemDetailFixDataCache.set("item:" + itemId, itemDetailFixData, 1, TimeUnit.HOURS); } @Override - public ItemDetailFixData findItemDetailFixDataByItemId(Long itemId) { - ValueOperations itemDetailFixDataCache = redisStringItemDetailFixDataTemplate.opsForValue(); + public T findItemDetailFixDataByItemId(Long itemId) { + ValueOperations itemDetailFixDataCache = redisStringItemDetailFixDataTemplate.opsForValue(); return itemDetailFixDataCache.get("item:" + itemId); } @Async(value = "redisThreadPoolExecutor") @Override public void deleteItemDetailFixDataByItemId(Long itemId) { - ValueOperations itemDetailFixDataCache = redisStringItemDetailFixDataTemplate.opsForValue(); + ValueOperations itemDetailFixDataCache = redisStringItemDetailFixDataTemplate.opsForValue(); itemDetailFixDataCache.getAndDelete("item:" + itemId); } diff --git a/src/main/java/com/sluv/server/global/config/FcmConfig.java b/sluv-infra/src/main/java/com/sluv/infra/config/FcmConfig.java similarity index 97% rename from src/main/java/com/sluv/server/global/config/FcmConfig.java rename to sluv-infra/src/main/java/com/sluv/infra/config/FcmConfig.java index a7e26a0b..c07db1b1 100644 --- a/src/main/java/com/sluv/server/global/config/FcmConfig.java +++ b/sluv-infra/src/main/java/com/sluv/infra/config/FcmConfig.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.config; +package com.sluv.infra.config; import com.google.auth.oauth2.GoogleCredentials; import com.google.firebase.FirebaseApp; diff --git a/src/main/java/com/sluv/server/global/config/RedisConfig.java b/sluv-infra/src/main/java/com/sluv/infra/config/RedisConfig.java similarity index 97% rename from src/main/java/com/sluv/server/global/config/RedisConfig.java rename to sluv-infra/src/main/java/com/sluv/infra/config/RedisConfig.java index c09b2a52..cb672f19 100644 --- a/src/main/java/com/sluv/server/global/config/RedisConfig.java +++ b/sluv-infra/src/main/java/com/sluv/infra/config/RedisConfig.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.config; +package com.sluv.infra.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; diff --git a/src/main/java/com/sluv/server/global/discord/DiscordWebHookConnector.java b/sluv-infra/src/main/java/com/sluv/infra/discord/DiscordWebHookConnector.java similarity index 96% rename from src/main/java/com/sluv/server/global/discord/DiscordWebHookConnector.java rename to sluv-infra/src/main/java/com/sluv/infra/discord/DiscordWebHookConnector.java index 0945c514..da6a310f 100644 --- a/src/main/java/com/sluv/server/global/discord/DiscordWebHookConnector.java +++ b/sluv-infra/src/main/java/com/sluv/infra/discord/DiscordWebHookConnector.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.discord; +package com.sluv.infra.discord; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/src/main/java/com/sluv/server/global/discord/DiscordWebHookException.java b/sluv-infra/src/main/java/com/sluv/infra/discord/DiscordWebHookException.java similarity index 63% rename from src/main/java/com/sluv/server/global/discord/DiscordWebHookException.java rename to sluv-infra/src/main/java/com/sluv/infra/discord/DiscordWebHookException.java index 6803257e..55595823 100644 --- a/src/main/java/com/sluv/server/global/discord/DiscordWebHookException.java +++ b/sluv-infra/src/main/java/com/sluv/infra/discord/DiscordWebHookException.java @@ -1,11 +1,11 @@ -package com.sluv.server.global.discord; +package com.sluv.infra.discord; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class DiscordWebHookException extends WebHookException { private static final int ERROR_CODE = 6000; private static final String MESSAGE = "Discord WebHook 전송에 실패했습니다."; - private static final HttpStatus STATUS = HttpStatus.INTERNAL_SERVER_ERROR; + private static final HttpStatusCode STATUS = HttpStatusCode.INTERNAL_SERVER_ERROR; public DiscordWebHookException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/global/discord/DiscordWebHookService.java b/sluv-infra/src/main/java/com/sluv/infra/discord/DiscordWebHookService.java similarity index 94% rename from src/main/java/com/sluv/server/global/discord/DiscordWebHookService.java rename to sluv-infra/src/main/java/com/sluv/infra/discord/DiscordWebHookService.java index 63237e18..3e052647 100644 --- a/src/main/java/com/sluv/server/global/discord/DiscordWebHookService.java +++ b/sluv-infra/src/main/java/com/sluv/infra/discord/DiscordWebHookService.java @@ -1,10 +1,10 @@ -package com.sluv.server.global.discord; +package com.sluv.infra.discord; -import com.sluv.server.domain.brand.entity.NewBrand; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.enums.UserStatus; -import com.sluv.server.domain.user.repository.UserRepository; +import com.sluv.domain.brand.entity.NewBrand; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.enums.UserStatus; +import com.sluv.domain.user.repository.UserRepository; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; diff --git a/sluv-infra/src/main/java/com/sluv/infra/discord/WebHookException.java b/sluv-infra/src/main/java/com/sluv/infra/discord/WebHookException.java new file mode 100644 index 00000000..2bcc0aef --- /dev/null +++ b/sluv-infra/src/main/java/com/sluv/infra/discord/WebHookException.java @@ -0,0 +1,10 @@ +package com.sluv.infra.discord; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class WebHookException extends ApplicationException { + public WebHookException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} diff --git a/src/main/java/com/sluv/server/global/discord/WebHookMessage.java b/sluv-infra/src/main/java/com/sluv/infra/discord/WebHookMessage.java similarity index 55% rename from src/main/java/com/sluv/server/global/discord/WebHookMessage.java rename to sluv-infra/src/main/java/com/sluv/infra/discord/WebHookMessage.java index ffe26a75..9c166426 100644 --- a/src/main/java/com/sluv/server/global/discord/WebHookMessage.java +++ b/sluv-infra/src/main/java/com/sluv/infra/discord/WebHookMessage.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.discord; +package com.sluv.infra.discord; public record WebHookMessage(String content) { } diff --git a/src/main/java/com/sluv/server/global/discord/WebHookService.java b/sluv-infra/src/main/java/com/sluv/infra/discord/WebHookService.java similarity index 54% rename from src/main/java/com/sluv/server/global/discord/WebHookService.java rename to sluv-infra/src/main/java/com/sluv/infra/discord/WebHookService.java index 400d69cd..974cf984 100644 --- a/src/main/java/com/sluv/server/global/discord/WebHookService.java +++ b/sluv-infra/src/main/java/com/sluv/infra/discord/WebHookService.java @@ -1,8 +1,8 @@ -package com.sluv.server.global.discord; +package com.sluv.infra.discord; -import com.sluv.server.domain.brand.entity.NewBrand; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.user.entity.User; +import com.sluv.domain.brand.entity.NewBrand; +import com.sluv.domain.celeb.entity.NewCeleb; +import com.sluv.domain.user.entity.User; public interface WebHookService { void sendSingupMessage(User user); diff --git a/src/main/java/com/sluv/server/global/firebase/FcmNotificationService.java b/sluv-infra/src/main/java/com/sluv/infra/firebase/FcmNotificationService.java similarity index 88% rename from src/main/java/com/sluv/server/global/firebase/FcmNotificationService.java rename to sluv-infra/src/main/java/com/sluv/infra/firebase/FcmNotificationService.java index c774f5c3..a7f1e412 100644 --- a/src/main/java/com/sluv/server/global/firebase/FcmNotificationService.java +++ b/sluv-infra/src/main/java/com/sluv/infra/firebase/FcmNotificationService.java @@ -1,15 +1,15 @@ -package com.sluv.server.global.firebase; +package com.sluv.infra.firebase; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.FirebaseMessagingException; import com.google.firebase.messaging.Message; import com.google.firebase.messaging.Message.Builder; import com.google.firebase.messaging.Notification; -import com.sluv.server.domain.alarm.enums.AlarmType; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.firebase.exception.FcmConnectException; +import com.sluv.domain.alarm.enums.AlarmType; +import com.sluv.domain.user.entity.User; +import com.sluv.domain.user.exception.UserNotFoundException; +import com.sluv.domain.user.repository.UserRepository; +import com.sluv.infra.firebase.exception.FcmConnectException; import java.util.HashMap; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/sluv/server/global/firebase/exception/FcmAccessTokenInvalidateException.java b/sluv-infra/src/main/java/com/sluv/infra/firebase/exception/FcmAccessTokenInvalidateException.java similarity index 63% rename from src/main/java/com/sluv/server/global/firebase/exception/FcmAccessTokenInvalidateException.java rename to sluv-infra/src/main/java/com/sluv/infra/firebase/exception/FcmAccessTokenInvalidateException.java index c9ea5a3d..e68f68d4 100644 --- a/src/main/java/com/sluv/server/global/firebase/exception/FcmAccessTokenInvalidateException.java +++ b/sluv-infra/src/main/java/com/sluv/infra/firebase/exception/FcmAccessTokenInvalidateException.java @@ -1,12 +1,12 @@ -package com.sluv.server.global.firebase.exception; +package com.sluv.infra.firebase.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class FcmAccessTokenInvalidateException extends FcmException { private static final int ERROR_CODE = 2028; private static final String MESSAGE = "잘못된 FCM 토큰입니다."; - private static final HttpStatus STATUS = HttpStatus.UNAUTHORIZED; + private static final HttpStatusCode STATUS = HttpStatusCode.UNAUTHORIZED; public FcmAccessTokenInvalidateException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/src/main/java/com/sluv/server/global/firebase/exception/FcmConnectException.java b/sluv-infra/src/main/java/com/sluv/infra/firebase/exception/FcmConnectException.java similarity index 61% rename from src/main/java/com/sluv/server/global/firebase/exception/FcmConnectException.java rename to sluv-infra/src/main/java/com/sluv/infra/firebase/exception/FcmConnectException.java index 4df97e91..98c8587a 100644 --- a/src/main/java/com/sluv/server/global/firebase/exception/FcmConnectException.java +++ b/sluv-infra/src/main/java/com/sluv/infra/firebase/exception/FcmConnectException.java @@ -1,12 +1,12 @@ -package com.sluv.server.global.firebase.exception; +package com.sluv.infra.firebase.exception; -import org.springframework.http.HttpStatus; +import com.sluv.common.exception.HttpStatusCode; public class FcmConnectException extends FcmException { private static final int ERROR_CODE = 2022; private static final String MESSAGE = "Firebase connection 에러입니다."; - private static final HttpStatus STATUS = HttpStatus.UNAUTHORIZED; + private static final HttpStatusCode STATUS = HttpStatusCode.UNAUTHORIZED; public FcmConnectException() { super(ERROR_CODE, STATUS, MESSAGE); diff --git a/sluv-infra/src/main/java/com/sluv/infra/firebase/exception/FcmException.java b/sluv-infra/src/main/java/com/sluv/infra/firebase/exception/FcmException.java new file mode 100644 index 00000000..f6863aae --- /dev/null +++ b/sluv-infra/src/main/java/com/sluv/infra/firebase/exception/FcmException.java @@ -0,0 +1,10 @@ +package com.sluv.infra.firebase.exception; + +import com.sluv.common.exception.ApplicationException; +import com.sluv.common.exception.HttpStatusCode; + +public abstract class FcmException extends ApplicationException { + public FcmException(int errorCode, HttpStatusCode httpStatusCode, String message) { + super(errorCode, httpStatusCode, message); + } +} \ No newline at end of file diff --git a/sluv-infra/src/main/java/com/sluv/infra/oauth/apple/ApplePlatformClient.java b/sluv-infra/src/main/java/com/sluv/infra/oauth/apple/ApplePlatformClient.java new file mode 100644 index 00000000..f9f2f217 --- /dev/null +++ b/sluv-infra/src/main/java/com/sluv/infra/oauth/apple/ApplePlatformClient.java @@ -0,0 +1,148 @@ +package com.sluv.infra.oauth.apple; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.sluv.common.jwt.JwtProvider; +import com.sluv.common.jwt.exception.ExpiredTokenException; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.math.BigInteger; +import java.net.HttpURLConnection; +import java.net.URL; +import java.security.KeyFactory; +import java.security.PublicKey; +import java.security.spec.RSAPublicKeySpec; +import java.util.Base64; + +@Component +@RequiredArgsConstructor +public class ApplePlatformClient { + + @Value("${apple.clientId}") + private String CLIENT_ID; + + @Value("${apple.openKey}") + private String APPLE_OPEN_KEY; + + @Value("${apple.iss}") + private String ISS_URL; + + private final ObjectMapper objectMapper = new ObjectMapper(); + + private final JwtProvider jwtProvider; + + /** + * == identitiyToken이 유효한 토큰인지 확인 == + * + * @param identityToken + * @return 유효 여부 + * @throws Exception + */ + public boolean verifyIdToken(String identityToken) throws Exception { + String[] pieces = identityToken.split("\\."); + if (pieces.length != 3) { + return false; + } + String header = new String(Base64.getUrlDecoder().decode(pieces[0])); + String payload = new String(Base64.getUrlDecoder().decode(pieces[1])); + + JsonNode headerNode = objectMapper.readTree(header); + JsonNode payloadNode = objectMapper.readTree(payload); + + String algorithm = headerNode.get("alg").asText(); + + String idKid = headerNode.get("kid").asText(); + + if (!algorithm.equals("RS256")) { + return false; + } + // 원래 처리해야하는데 왜 우리 토큰엔 없죠...? - JunKer +// String nonce = payloadNode.get("nonce").asText(); +// if (!nonce.equals(this.nonce)) { +// return false; +// } + String iss = payloadNode.get("iss").asText(); + if (!iss.equals(ISS_URL)) { + return false; + } + + String aud = payloadNode.get("aud").asText(); + if (!aud.equals(this.CLIENT_ID)) { + return false; + } + + long exp = payloadNode.get("exp").asLong(); + if (exp < System.currentTimeMillis() / 1000) { + throw new ExpiredTokenException(); + } + + if (getPublicKeyFromPEM(identityToken, idKid)) { + return false; + } + + return true; + + } + + /** + * == idToken이 검증된 토큰인지 확인 == + * + * @param identityToken + * @param identityKid + * @return + * @throws Exception + */ + public Boolean getPublicKeyFromPEM(String identityToken, String identityKid) throws Exception { + JsonNode correctKey = getApplePublicKey(identityKid); + String tN = correctKey.get("n").asText(); + String tE = correctKey.get("e").asText(); + String kty = correctKey.get("kty").asText(); + + byte[] nBytes = Base64.getUrlDecoder().decode(tN); + byte[] eBytes = Base64.getUrlDecoder().decode(tE); + + BigInteger n = new BigInteger(1, nBytes); + BigInteger e = new BigInteger(1, eBytes); + + RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(n, e); + KeyFactory keyFactory = KeyFactory.getInstance(kty); + PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); + + return jwtProvider.checkClaimsJwsBodyIsNull(publicKey, identityToken); + } + + /** + * == Apple에게 공개키를 요청 == + * + * @param identityKid + * @return 알맞는 공개키의 JsonNode + * @throws Exception + */ + + private JsonNode getApplePublicKey(String identityKid) throws Exception { + URL url = new URL(APPLE_OPEN_KEY); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.connect(); + + JsonNode jsonNode = objectMapper.readTree(connection.getInputStream()); + JsonNode keysNode = jsonNode.get("keys"); + + JsonNode correctKey = null; + + for (JsonNode keyNode : keysNode) { + String kid = keyNode.get("kid").asText(); + if (kid.equals(identityKid)) { + correctKey = keyNode; + break; + } + } + + return correctKey; + + } + +} diff --git a/src/main/java/com/sluv/server/domain/auth/service/GoogleUserService.java b/sluv-infra/src/main/java/com/sluv/infra/oauth/google/GooglePlatformClient.java similarity index 62% rename from src/main/java/com/sluv/server/domain/auth/service/GoogleUserService.java rename to sluv-infra/src/main/java/com/sluv/infra/oauth/google/GooglePlatformClient.java index debfe032..a3300366 100644 --- a/src/main/java/com/sluv/server/domain/auth/service/GoogleUserService.java +++ b/sluv-infra/src/main/java/com/sluv/infra/oauth/google/GooglePlatformClient.java @@ -1,30 +1,19 @@ -package com.sluv.server.domain.auth.service; - -import static com.sluv.server.domain.auth.enums.SnsType.GOOGLE; +package com.sluv.infra.oauth.google; import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.gson.GsonFactory; -import com.sluv.server.domain.auth.dto.AuthRequestDto; -import com.sluv.server.domain.auth.dto.SocialUserInfoDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.enums.UserAge; -import com.sluv.server.domain.user.enums.UserGender; -import com.sluv.server.global.jwt.exception.InvalidateTokenException; +import com.sluv.common.jwt.exception.InvalidateTokenException; +import com.sluv.domain.auth.dto.SocialUserInfoDto; +import com.sluv.domain.user.enums.UserAge; +import com.sluv.domain.user.enums.UserGender; import java.util.Arrays; -import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - - -@Service -@RequiredArgsConstructor -public class GoogleUserService { - - private final AuthService authService; +import org.springframework.stereotype.Component; +@Component +public class GooglePlatformClient { @Value("${spring.security.oauth2.client.android}") private String CLIENT_ANDROID; @@ -32,17 +21,6 @@ public class GoogleUserService { @Value("${spring.security.oauth2.client.apple}") private String CLIENT_APPLE; - @Transactional - public User googleLogin(AuthRequestDto request) { - String idToken = request.getAccessToken(); - - // 1. idToken 검증 - SocialUserInfoDto verifiedIdToken = verifyIdToken(idToken); - - // 2. user 정보로 DB 탐색 및 등록 - return authService.getOrCreateUser(verifiedIdToken, GOOGLE, request.getFcm()); - } - /** * == 프론트에서 준 idToken의 유효성 검사 * @@ -50,7 +28,7 @@ public User googleLogin(AuthRequestDto request) { * @return SocialUserInfoDto * @throws InvalidateTokenException */ - private SocialUserInfoDto verifyIdToken(String idToken) { + public SocialUserInfoDto verifyIdToken(String idToken) { GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), GsonFactory.getDefaultInstance()).setAudience(Arrays.asList(CLIENT_ANDROID, CLIENT_APPLE)).build(); diff --git a/src/main/java/com/sluv/server/domain/auth/service/KakaoUserService.java b/sluv-infra/src/main/java/com/sluv/infra/oauth/kakao/KakaoPlatformClient.java similarity index 77% rename from src/main/java/com/sluv/server/domain/auth/service/KakaoUserService.java rename to sluv-infra/src/main/java/com/sluv/infra/oauth/kakao/KakaoPlatformClient.java index 3a8c240c..fdaec5cd 100644 --- a/src/main/java/com/sluv/server/domain/auth/service/KakaoUserService.java +++ b/sluv-infra/src/main/java/com/sluv/infra/oauth/kakao/KakaoPlatformClient.java @@ -1,40 +1,22 @@ -package com.sluv.server.domain.auth.service; - -import static com.sluv.server.domain.auth.enums.SnsType.KAKAO; +package com.sluv.infra.oauth.kakao; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.sluv.server.domain.auth.dto.AuthRequestDto; -import com.sluv.server.domain.auth.dto.SocialUserInfoDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.enums.UserAge; -import com.sluv.server.domain.user.enums.UserGender; -import com.sluv.server.global.jwt.exception.InvalidateTokenException; -import lombok.RequiredArgsConstructor; +import com.sluv.common.jwt.exception.InvalidateTokenException; +import com.sluv.domain.auth.dto.SocialUserInfoDto; +import com.sluv.domain.user.enums.UserAge; +import com.sluv.domain.user.enums.UserGender; 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.stereotype.Component; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; - -@Service -@RequiredArgsConstructor -public class KakaoUserService { - - private final AuthService authService; - - public User kakaoLogin(AuthRequestDto request) throws JsonProcessingException { - String accessToken = request.getAccessToken(); - // 1. accessToken으로 user 정보 요청 - SocialUserInfoDto userInfo = getKakaoUserInfo(accessToken); - - // 2. user 정보로 DB 탐색 및 등록 - return authService.getOrCreateUser(userInfo, KAKAO, request.getFcm()); - } +@Component +public class KakaoPlatformClient { /** * == Front에서 준 accessToken으로 KAKAO에게 유저 정보 요청 == @@ -43,7 +25,7 @@ public User kakaoLogin(AuthRequestDto request) throws JsonProcessingException { * @return 유저 정보 * @throws JsonProcessingException, , BaseException(JWT_AUTHENTICATION_FAILED) */ - private SocialUserInfoDto getKakaoUserInfo(String accessToken) throws JsonProcessingException { + public SocialUserInfoDto getKakaoUserInfo(String accessToken) throws JsonProcessingException { HttpHeaders headers = new HttpHeaders(); headers.add("Authorization", "Bearer " + accessToken); @@ -144,5 +126,4 @@ private static UserAge getUserAge(UserAge userGender, String age) { } return userGender; } - } diff --git a/src/main/java/com/sluv/server/global/s3/AWSS3Service.java b/sluv-infra/src/main/java/com/sluv/infra/s3/AWSS3Service.java similarity index 82% rename from src/main/java/com/sluv/server/global/s3/AWSS3Service.java rename to sluv-infra/src/main/java/com/sluv/infra/s3/AWSS3Service.java index 57bd764f..0f0a4da7 100644 --- a/src/main/java/com/sluv/server/global/s3/AWSS3Service.java +++ b/sluv-infra/src/main/java/com/sluv/infra/s3/AWSS3Service.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.s3; +package com.sluv.infra.s3; import com.amazonaws.HttpMethod; import com.amazonaws.services.s3.AmazonS3; @@ -22,10 +22,10 @@ public class AWSS3Service { private final AmazonS3 amazonS3; @Value("${aws.s3.bucketName}") - private String bucketName; + private String BUCKET_NAME; @Value("${aws.s3.baseUrl}") - private String baseUrl = ""; + private String BASE_URL = ""; /** * user profile item image 커뮤니티 이미지 클로젯 커버 @@ -36,7 +36,7 @@ public PreSingedUrlResDto forUserProfile(ImgExtension imgExtension) { log.info(fileName); URL url = amazonS3.generatePresignedUrl( - getGeneratePreSignedUrlRequest(bucketName, fileName, fixedExtension)); + getGeneratePreSignedUrlRequest(BUCKET_NAME, fileName, fixedExtension)); return PreSingedUrlResDto.builder() .preSignedUrl(url.toString()) .key(fileName) @@ -49,7 +49,7 @@ public PreSingedUrlResDto forItem(ImgExtension imgExtension) { log.info(fileName); URL url = amazonS3.generatePresignedUrl( - getGeneratePreSignedUrlRequest(bucketName, fileName, fixedExtension)); + getGeneratePreSignedUrlRequest(BUCKET_NAME, fileName, fixedExtension)); log.info("URL: {}", url.toString()); return PreSingedUrlResDto.builder() .preSignedUrl(url.toString()) @@ -63,7 +63,7 @@ public PreSingedUrlResDto forCommunityPost(ImgExtension imgExtension) { log.info(fileName); URL url = amazonS3.generatePresignedUrl( - getGeneratePreSignedUrlRequest(bucketName, fileName, fixedExtension)); + getGeneratePreSignedUrlRequest(BUCKET_NAME, fileName, fixedExtension)); return PreSingedUrlResDto.builder() .preSignedUrl(url.toString()) .key(fileName) @@ -76,7 +76,7 @@ public PreSingedUrlResDto forCommunityComment(ImgExtension imgExtension) { log.info(fileName); URL url = amazonS3.generatePresignedUrl( - getGeneratePreSignedUrlRequest(bucketName, fileName, fixedExtension)); + getGeneratePreSignedUrlRequest(BUCKET_NAME, fileName, fixedExtension)); return PreSingedUrlResDto.builder() .preSignedUrl(url.toString()) .key(fileName) @@ -89,7 +89,7 @@ public PreSingedUrlResDto forCloset(ImgExtension imgExtension) { log.info(fileName); URL url = amazonS3.generatePresignedUrl( - getGeneratePreSignedUrlRequest(bucketName, fileName, fixedExtension)); + getGeneratePreSignedUrlRequest(BUCKET_NAME, fileName, fixedExtension)); log.info("URL: {}", url.toString()); return PreSingedUrlResDto.builder() @@ -100,27 +100,27 @@ public PreSingedUrlResDto forCloset(ImgExtension imgExtension) { // 유저 프로필 private String getForUserProfileFileName(String imgExtension) { - return baseUrl + "/user/profile/" + UUID.randomUUID() + "." + imgExtension; + return BASE_URL + "/user/profile/" + UUID.randomUUID() + "." + imgExtension; } // 아이템 이미지 private String getForItemFileName(String imgExtension) { - return baseUrl + "/item/" + UUID.randomUUID() + "." + imgExtension; + return BASE_URL + "/item/" + UUID.randomUUID() + "." + imgExtension; } // 커뮤니티 게시글 이미지 private String getForCommunityPostFileName(String imgExtension) { - return baseUrl + "/community/post/" + UUID.randomUUID() + "." + imgExtension; + return BASE_URL + "/community/post/" + UUID.randomUUID() + "." + imgExtension; } // 커뮤니티 댓글 이미지 private String getForCommunityCommentFileName(String imgExtension) { - return baseUrl + "/community/comment/" + UUID.randomUUID() + "." + imgExtension; + return BASE_URL + "/community/comment/" + UUID.randomUUID() + "." + imgExtension; } //클로젯 커버 private String getForClosetFileName(String imgExtension) { - return baseUrl + "/closet/" + UUID.randomUUID() + "." + imgExtension; + return BASE_URL + "/closet/" + UUID.randomUUID() + "." + imgExtension; } private GeneratePresignedUrlRequest getGeneratePreSignedUrlRequest(String bucket, String fileName, diff --git a/src/main/java/com/sluv/server/global/s3/ImgExtension.java b/sluv-infra/src/main/java/com/sluv/infra/s3/ImgExtension.java similarity index 87% rename from src/main/java/com/sluv/server/global/s3/ImgExtension.java rename to sluv-infra/src/main/java/com/sluv/infra/s3/ImgExtension.java index 98e0fa12..fd84b2cd 100644 --- a/src/main/java/com/sluv/server/global/s3/ImgExtension.java +++ b/sluv-infra/src/main/java/com/sluv/infra/s3/ImgExtension.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.s3; +package com.sluv.infra.s3; import lombok.Getter; diff --git a/src/main/java/com/sluv/server/global/s3/PreSingedUrlResDto.java b/sluv-infra/src/main/java/com/sluv/infra/s3/PreSingedUrlResDto.java similarity index 88% rename from src/main/java/com/sluv/server/global/s3/PreSingedUrlResDto.java rename to sluv-infra/src/main/java/com/sluv/infra/s3/PreSingedUrlResDto.java index 5732f425..e93e209e 100644 --- a/src/main/java/com/sluv/server/global/s3/PreSingedUrlResDto.java +++ b/sluv-infra/src/main/java/com/sluv/infra/s3/PreSingedUrlResDto.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.s3; +package com.sluv.infra.s3; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/sluv/server/global/s3/S3Config.java b/sluv-infra/src/main/java/com/sluv/infra/s3/S3Config.java similarity index 85% rename from src/main/java/com/sluv/server/global/s3/S3Config.java rename to sluv-infra/src/main/java/com/sluv/infra/s3/S3Config.java index ff9bfab5..5a142bbc 100644 --- a/src/main/java/com/sluv/server/global/s3/S3Config.java +++ b/sluv-infra/src/main/java/com/sluv/infra/s3/S3Config.java @@ -1,4 +1,4 @@ -package com.sluv.server.global.s3; +package com.sluv.infra.s3; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSStaticCredentialsProvider; @@ -13,17 +13,17 @@ @Configuration public class S3Config { @Value("${aws.s3.accessKey}") - private String accessKey; + private String ACCESS_KEY; @Value("${aws.s3.secretKey}") - private String secretKey; + private String SECERET_KEY; @Value("${aws.s3.region}") - private String region; + private String REGION; @Bean public AmazonS3 getS3ClientBean() { - AWSCredentials credentials = new BasicAWSCredentials(this.accessKey, this.secretKey); + AWSCredentials credentials = new BasicAWSCredentials(this.ACCESS_KEY, this.SECERET_KEY); return AmazonS3ClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(credentials)) .withRegion(Regions.AP_NORTHEAST_2) diff --git a/sluv-infra/src/main/resources/application-infra.yml b/sluv-infra/src/main/resources/application-infra.yml new file mode 100644 index 00000000..821ee430 --- /dev/null +++ b/sluv-infra/src/main/resources/application-infra.yml @@ -0,0 +1,49 @@ +spring: + application: + name: infra + config: + import: optional:classpath:env/.env[.properties] + data: + redis: + port: ${REDIS_PORT} + host: ${REDIS_HOST} + password: ${REDIS_PASSWORD} + repositories: + enabled: false + + security: + oauth2: + client: + android: ${OAUTH_ANDROID} + apple: ${OAUTH_APPLE} + +elasticsearch: + uri: ${ELASTICSEARCH_HOST} + +ai-model: + uri: ${AI_HOST}:${AI_PORT} + +apple: + # nonce: 1 + clientId: ${APPLE_CLIENT_ID} + openKey: ${APPLE_OPEN_KEY} + iss: ${APPLE_ISS} + +aws: + s3: + accessKey: ${AWS_S3_ACCESS_KEY} + secretKey: ${AWS_S3_SECRET_KEY} + region: ${AWS_S3_REGION} + bucketName: ${AWS_S3_BUCKET_NAME} + baseUrl: ${AWS_S3_BASE_URL} + +discord: + webhook: + signup: ${DISCORD_WEBHOOK_SIGNUP} + withdraw: ${DISCORD_WEBHOOK_WITHDRAW} + new-brand: ${DISCORD_WEBHOOK_NEW_BRAND} + new-celeb: ${DISCORD_WEBHOOK_NEW_CELEB} + +fcm: + key: + path: ${FCM_KEY_PATH} diff --git a/src/main/java/com/sluv/server/domain/admin/controller/AdminController.java b/src/main/java/com/sluv/server/domain/admin/controller/AdminController.java deleted file mode 100644 index 5122b332..00000000 --- a/src/main/java/com/sluv/server/domain/admin/controller/AdminController.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.sluv.server.domain.admin.controller; - -import com.sluv.server.domain.admin.dto.AdminReqDto; -import com.sluv.server.domain.admin.dto.AdminResDto; -import com.sluv.server.domain.admin.dto.AdminUserTokenReqDto; -import com.sluv.server.domain.admin.dto.AdminUserTokenResDto; -import com.sluv.server.domain.admin.service.AdminService; -import com.sluv.server.global.common.response.SuccessDataResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/admin") -@RequiredArgsConstructor -public class AdminController { - private final AdminService adminService; - - @PostMapping("/token") - public ResponseEntity> getUserTokenByAdmin( - @RequestBody AdminUserTokenReqDto dto) { - - return ResponseEntity.ok().body(SuccessDataResponse.builder() - .result(adminService.getUserTokenByAdmin(dto.getEmail(), dto.getPassword(), dto.getUserId())) - .build() - ); - } - - @PostMapping("") - public ResponseEntity> saveAdmin( - @RequestBody AdminReqDto dto) { - - return ResponseEntity.ok().body(SuccessDataResponse.builder() - .result(adminService.getAdminData(dto.getEmail(), dto.getPassword())) - .build() - ); - } - -} diff --git a/src/main/java/com/sluv/server/domain/admin/exception/AdminException.java b/src/main/java/com/sluv/server/domain/admin/exception/AdminException.java deleted file mode 100644 index 695646f2..00000000 --- a/src/main/java/com/sluv/server/domain/admin/exception/AdminException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.admin.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class AdminException extends ApplicationException { - public AdminException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/admin/service/AdminService.java b/src/main/java/com/sluv/server/domain/admin/service/AdminService.java deleted file mode 100644 index 47ab25c3..00000000 --- a/src/main/java/com/sluv/server/domain/admin/service/AdminService.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.sluv.server.domain.admin.service; - -import com.sluv.server.domain.admin.dto.AdminResDto; -import com.sluv.server.domain.admin.dto.AdminUserTokenResDto; -import com.sluv.server.domain.admin.entity.Admin; -import com.sluv.server.domain.admin.exception.AdminNotFoundException; -import com.sluv.server.domain.admin.exception.AdminPasswordNotMatchException; -import com.sluv.server.domain.admin.repository.AdminRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.common.utils.PasswordEncoderUtil; -import com.sluv.server.global.jwt.JwtProvider; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class AdminService { - - private final AdminRepository adminRepository; - private final UserRepository userRepository; - - private final JwtProvider jwtProvider; - private final PasswordEncoderUtil passwordEncoderUtil; - - @Transactional(readOnly = true) - public AdminUserTokenResDto getUserTokenByAdmin(String email, String password, Long userId) { - Admin admin = adminRepository.findByEmail(email).orElseThrow(AdminNotFoundException::new); - System.out.println(password); - boolean isMatched = passwordEncoderUtil.matches(password, admin.getPwd()); - - System.out.println(isMatched); - if (!isMatched) { - throw new AdminPasswordNotMatchException(); - } - - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - String accessToken = jwtProvider.createAccessToken(user); - - return AdminUserTokenResDto.from(accessToken); - } - - public AdminResDto getAdminData(String email, String password) { - String encodedPassword = passwordEncoderUtil.encodePassword(password); - return AdminResDto.of(email, encodedPassword); - } -} diff --git a/src/main/java/com/sluv/server/domain/alarm/controller/AlarmController.java b/src/main/java/com/sluv/server/domain/alarm/controller/AlarmController.java deleted file mode 100644 index bee41a7d..00000000 --- a/src/main/java/com/sluv/server/domain/alarm/controller/AlarmController.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.sluv.server.domain.alarm.controller; - -import com.sluv.server.domain.alarm.dto.AlarmResponse; -import com.sluv.server.domain.alarm.service.AlarmService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Pageable; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RequestMapping("/app/alarm") -@RestController -@RequiredArgsConstructor -public class AlarmController { - - private final AlarmService alarmService; - - @GetMapping("") - public ResponseEntity>> getAlarms( - @AuthenticationPrincipal User user, Pageable pageable) { - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(alarmService.getAlarmsByUserId(user.getId(), pageable)) - .build() - ); - } - - @PatchMapping("/read") - public ResponseEntity pathAlarmStatusToRead(@AuthenticationPrincipal User user, - @RequestParam Long alarmId) { - alarmService.patchAlarmStatusToRead(user, alarmId); - return ResponseEntity.ok().body(new SuccessResponse()); - } - - @DeleteMapping("/{alarmId}") - public ResponseEntity deleteAlarm(@AuthenticationPrincipal User user, - @PathVariable("alarmId") Long alarmId) { - alarmService.deleteAlarm(user, alarmId); - return ResponseEntity.ok().body(new SuccessResponse()); - } - - @DeleteMapping("/all") - public ResponseEntity deleteAllAlarm(@AuthenticationPrincipal User user) { - alarmService.deleteAllAlarm(user); - return ResponseEntity.ok().body(new SuccessResponse()); - } - -} diff --git a/src/main/java/com/sluv/server/domain/alarm/exception/AlarmException.java b/src/main/java/com/sluv/server/domain/alarm/exception/AlarmException.java deleted file mode 100644 index bab936c5..00000000 --- a/src/main/java/com/sluv/server/domain/alarm/exception/AlarmException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.alarm.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class AlarmException extends ApplicationException { - public AlarmException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/alarm/service/AlarmService.java b/src/main/java/com/sluv/server/domain/alarm/service/AlarmService.java deleted file mode 100644 index 93e737cc..00000000 --- a/src/main/java/com/sluv/server/domain/alarm/service/AlarmService.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.sluv.server.domain.alarm.service; - -import static com.sluv.server.domain.alarm.enums.AlarmStatus.READ; - -import com.sluv.server.domain.alarm.dto.AlarmElement; -import com.sluv.server.domain.alarm.dto.AlarmImages; -import com.sluv.server.domain.alarm.dto.AlarmResponse; -import com.sluv.server.domain.alarm.entity.Alarm; -import com.sluv.server.domain.alarm.enums.AlarmType; -import com.sluv.server.domain.alarm.exception.AlarmAccessDeniedException; -import com.sluv.server.domain.alarm.exception.AlarmNotFoundException; -import com.sluv.server.domain.alarm.repository.AlarmRepository; -import com.sluv.server.domain.item.entity.ItemImg; -import com.sluv.server.domain.item.repository.ItemImgRepository; -import com.sluv.server.domain.question.dto.QuestionImgSimpleResDto; -import com.sluv.server.domain.question.repository.QuestionImgRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationResDto; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional -@RequiredArgsConstructor -public class AlarmService { - - private final AlarmRepository alarmRepository; - private final ItemImgRepository itemImgRepository; - private final QuestionImgRepository questionImgRepository; - - public void saveAlarm(User user, String title, String body, AlarmType alarmType, AlarmElement alarmElement) { - alarmRepository.save(Alarm.toEntity(user, title, body, alarmType, alarmElement)); - } - - public void saveAllAlarm(List users, String title, String body, AlarmType alarmType, - AlarmElement alarmElement) { - - List alarms = new ArrayList<>(); - for (User user : users) { - alarms.add(Alarm.toEntity(user, title, body, alarmType, alarmElement)); - } - alarmRepository.saveAll(alarms); - } - - @Transactional(readOnly = true) - public PaginationResDto getAlarmsByUserId(Long userId, Pageable pageable) { - Page alarmPage = alarmRepository.findAllByUserId(userId, pageable); - List content = alarmPage.stream().map(alarm -> AlarmResponse.of(alarm, getAlarmImages(alarm))) - .toList(); - return PaginationResDto.of(alarmPage, content); - } - - private AlarmImages getAlarmImages(Alarm alarm) { - List images = new ArrayList<>(); - String useImageUrl = null; - - if (alarm.getSender() != null) { - useImageUrl = alarm.getSender().getProfileImgUrl(); - } - - if (alarm.getItem() != null) { - ItemImg mainImg = itemImgRepository.findMainImg(alarm.getItem().getId()); - images.add(QuestionImgSimpleResDto.of(mainImg)); - } - - if (alarm.getQuestion() != null) { - images = questionImgRepository.findAllByQuestionId(alarm.getQuestion().getId()) - .stream() - .map(QuestionImgSimpleResDto::of) - .toList(); - } - - return AlarmImages.of(images, useImageUrl); - } - - public void deleteAlarm(User user, Long alarmId) { - Alarm alarm = alarmRepository.findById(alarmId).orElseThrow(AlarmNotFoundException::new); - if (!alarm.getUser().getId().equals(user.getId())) { - throw new AlarmAccessDeniedException(); - } - alarmRepository.deleteById(alarmId); - } - - public void deleteAllAlarm(User user) { - alarmRepository.deleteAllByUserId(user.getId()); - } - - public void patchAlarmStatusToRead(User user, Long alarmId) { - Alarm alarm = alarmRepository.findById(alarmId).orElseThrow(AlarmNotFoundException::new); - if (Objects.equals(alarm.getUser().getId(), user.getId())) { - alarm.changeStatus(READ); - } - } - -} diff --git a/src/main/java/com/sluv/server/domain/auth/controller/AuthController.java b/src/main/java/com/sluv/server/domain/auth/controller/AuthController.java deleted file mode 100644 index c6cb74da..00000000 --- a/src/main/java/com/sluv/server/domain/auth/controller/AuthController.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.sluv.server.domain.auth.controller; - -import com.sluv.server.domain.auth.dto.AuthRequestDto; -import com.sluv.server.domain.auth.dto.AuthResponseDto; -import com.sluv.server.domain.auth.dto.AutoLoginRequestDto; -import com.sluv.server.domain.auth.dto.AutoLoginResponseDto; -import com.sluv.server.domain.auth.enums.SnsType; -import com.sluv.server.domain.auth.service.AppleUserService; -import com.sluv.server.domain.auth.service.AuthService; -import com.sluv.server.domain.auth.service.GoogleUserService; -import com.sluv.server.domain.auth.service.KakaoUserService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.cache.CacheService; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; -import io.swagger.v3.oas.annotations.Operation; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/app/auth") -@RequiredArgsConstructor -public class AuthController { - - private final KakaoUserService kakaoUserService; - private final GoogleUserService googleUserService; - private final AppleUserService appleUserService; - private final AuthService authService; - private final CacheService cacheService; - - - @Operation(summary = "소셜 로그인", description = "KAKAO:[AccessToken], GOOGLE, APPLE: [IdToken]") - @PostMapping("/social-login") - public ResponseEntity> socialLogin(@RequestBody AuthRequestDto request) - throws Exception { - User loginUser = null; - - SnsType userSnsType = SnsType.fromString(request.getSnsType()); - - switch (userSnsType) { - case KAKAO -> loginUser = kakaoUserService.kakaoLogin(request); - case GOOGLE -> loginUser = googleUserService.googleLogin(request); - case APPLE -> loginUser = appleUserService.appleLogin(request); - } - cacheService.visitMember(loginUser.getId()); - AuthResponseDto authResponseDto = authService.getAuthResDto(loginUser); - - return ResponseEntity.ok().body(SuccessDataResponse.builder() - .result(authResponseDto) - .build() - ); - } - - @Operation(summary = "*자동 로그인", description = "토큰 만료 시 error code : 4002") - @GetMapping("/auto-login") - public ResponseEntity> autoLogin(@AuthenticationPrincipal User user) { - cacheService.visitMember(user.getId()); -// authService.checkFcm(user.getId()); FCM 확인 로직 잠시 제거 24.08.06 - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(AutoLoginResponseDto.of(user)) - .build() - ); - } - - @Operation(summary = "*FCM 토큰 갱신", description = "FCM 토큰을 갱신") - @PostMapping("/fcm") - public ResponseEntity changeFcm(@AuthenticationPrincipal User user, - @RequestBody AutoLoginRequestDto dto) { - authService.changeFcm(user.getId(), dto.getFcm()); - return ResponseEntity.ok().body(new SuccessResponse()); - } -} diff --git a/src/main/java/com/sluv/server/domain/auth/dto/AuthResponseDto.java b/src/main/java/com/sluv/server/domain/auth/dto/AuthResponseDto.java deleted file mode 100644 index 3bd6a0e5..00000000 --- a/src/main/java/com/sluv/server/domain/auth/dto/AuthResponseDto.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.sluv.server.domain.auth.dto; - -import com.sluv.server.domain.user.enums.UserStatus; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Schema(description = "유저토큰 응답") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class AuthResponseDto { - @Schema(description = "유저 엑세스 토큰") - private String token; - @Schema(description = "유저 Status") - private UserStatus userStatus; -} diff --git a/src/main/java/com/sluv/server/domain/auth/dto/AutoLoginRequestDto.java b/src/main/java/com/sluv/server/domain/auth/dto/AutoLoginRequestDto.java deleted file mode 100644 index 46b3f93f..00000000 --- a/src/main/java/com/sluv/server/domain/auth/dto/AutoLoginRequestDto.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.sluv.server.domain.auth.dto; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Data -public class AutoLoginRequestDto { - - @Schema(description = "FCM 토큰") - private String fcm; -} diff --git a/src/main/java/com/sluv/server/domain/auth/exception/AuthException.java b/src/main/java/com/sluv/server/domain/auth/exception/AuthException.java deleted file mode 100644 index abf286f4..00000000 --- a/src/main/java/com/sluv/server/domain/auth/exception/AuthException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.auth.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class AuthException extends ApplicationException { - public AuthException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/auth/service/AppleUserService.java b/src/main/java/com/sluv/server/domain/auth/service/AppleUserService.java deleted file mode 100644 index a6dc95ee..00000000 --- a/src/main/java/com/sluv/server/domain/auth/service/AppleUserService.java +++ /dev/null @@ -1,249 +0,0 @@ -package com.sluv.server.domain.auth.service; - -import static com.sluv.server.domain.auth.enums.SnsType.APPLE; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.sluv.server.domain.auth.dto.AuthRequestDto; -import com.sluv.server.domain.auth.dto.SocialUserInfoDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.enums.UserAge; -import com.sluv.server.domain.user.enums.UserGender; -import com.sluv.server.global.jwt.exception.ExpiredTokenException; -import com.sluv.server.global.jwt.exception.InvalidateTokenException; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.JwtParser; -import io.jsonwebtoken.Jwts; -import java.math.BigInteger; -import java.net.HttpURLConnection; -import java.net.URL; -import java.security.KeyFactory; -import java.security.PublicKey; -import java.security.spec.RSAPublicKeySpec; -import java.util.Base64; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - - -@Service -@RequiredArgsConstructor -public class AppleUserService { - - private final AuthService authService; - - private final ObjectMapper objectMapper = new ObjectMapper(); - @Value("${apple.clientId}") - private String clientId; - - @Value("${apple.openKey}") - private String appleOpenKeys; - - @Value("${apple.iss}") - private String issUrl; - - public User appleLogin(AuthRequestDto request) throws Exception { - String identityToken = request.getAccessToken(); - - // 1. 검증 - if (!verifyIdToken(identityToken)) { - throw new InvalidateTokenException(); - } - - // 2. UserIngoDto 생성 - SocialUserInfoDto userInfo = getAppleUserInfo(identityToken); - - // 3. idToken의 정보로 DB 탐색 및 등록 - return authService.getOrCreateUser(userInfo, APPLE, request.getFcm()); - } - - /** - * == identitiyToken이 유효한 토큰인지 확인 == - * - * @param identityToken - * @return 유효 여부 - * @throws Exception - */ - private boolean verifyIdToken(String identityToken) throws Exception { - String[] pieces = identityToken.split("\\."); - if (pieces.length != 3) { - return false; - } - String header = new String(Base64.getUrlDecoder().decode(pieces[0])); - String payload = new String(Base64.getUrlDecoder().decode(pieces[1])); - - JsonNode headerNode = objectMapper.readTree(header); - JsonNode payloadNode = objectMapper.readTree(payload); - - String algorithm = headerNode.get("alg").asText(); - - String idKid = headerNode.get("kid").asText(); - - if (!algorithm.equals("RS256")) { - return false; - } - // 원래 처리해야하는데 왜 우리 토큰엔 없죠...? - JunKer -// String nonce = payloadNode.get("nonce").asText(); -// if (!nonce.equals(this.nonce)) { -// return false; -// } - String iss = payloadNode.get("iss").asText(); - if (!iss.equals(issUrl)) { - return false; - } - - String aud = payloadNode.get("aud").asText(); - if (!aud.equals(this.clientId)) { - return false; - } - - long exp = payloadNode.get("exp").asLong(); - if (exp < System.currentTimeMillis() / 1000) { - throw new ExpiredTokenException(); - } - - if (getPublicKeyFromPEM(identityToken, idKid) == null) { - return false; - } - - return true; - - } - - /** - * == idToken이 검증된 토큰인지 확인 == - * - * @param identityToken - * @param identityKid - * @return - * @throws Exception - */ - public Claims getPublicKeyFromPEM(String identityToken, String identityKid) throws Exception { - JsonNode correctKey = getApplePublicKey(identityKid); - String tN = correctKey.get("n").asText(); - String tE = correctKey.get("e").asText(); - String kty = correctKey.get("kty").asText(); - - byte[] nBytes = Base64.getUrlDecoder().decode(tN); - byte[] eBytes = Base64.getUrlDecoder().decode(tE); - - BigInteger n = new BigInteger(1, nBytes); - BigInteger e = new BigInteger(1, eBytes); - - RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(n, e); - KeyFactory keyFactory = KeyFactory.getInstance(kty); - PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); - - JwtParser parser = Jwts.parserBuilder() - .setSigningKey(publicKey) - .build(); - - return parser.parseClaimsJws(identityToken).getBody(); - } - - /** - * == Apple에게 공개키를 요청 == - * - * @param identityKid - * @return 알맞는 공개키의 JsonNode - * @throws Exception - */ - - private JsonNode getApplePublicKey(String identityKid) throws Exception { - URL url = new URL(appleOpenKeys); - - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.connect(); - - JsonNode jsonNode = objectMapper.readTree(connection.getInputStream()); - JsonNode keysNode = jsonNode.get("keys"); - - JsonNode correctKey = null; - - for (JsonNode keyNode : keysNode) { - String kid = keyNode.get("kid").asText(); - if (kid.equals(identityKid)) { - correctKey = keyNode; - break; - } - } - - return correctKey; - - } - - /** - * identityToken의 정보 SocialUserDto로 변환 - * - * @param identityToken - * @return SocialUserInfoDto - * @throws JsonProcessingException - */ - - private SocialUserInfoDto getAppleUserInfo(String identityToken) throws JsonProcessingException { - String[] pieces = identityToken.split("\\."); - String payload = new String(Base64.getUrlDecoder().decode(pieces[1])); - - JsonNode jsonNode = objectMapper.readTree(payload); - - String email = jsonNode.get("email").asText(); - - String profileImgUrl; - try { - profileImgUrl = jsonNode.get("picture").asText(); - } catch (Exception e) { - profileImgUrl = null; - } - - String gender; - - try { - gender = jsonNode.get("gender").asText(); - } catch (Exception e) { - gender = null; - } - - String ageRange; - try { - ageRange = jsonNode.get("birthdate").asText(); - } catch (Exception e) { - ageRange = null; - } - - return SocialUserInfoDto.builder() - .email(email) - .profileImgUrl(profileImgUrl) - .gender(convertGender(gender)) - .ageRange(convertAge(ageRange)) - .build(); - } - - private UserGender convertGender(String gender) { - UserGender userGender = UserGender.UNKNOWN; - if (gender != null) { - if (gender.equals("male")) { - userGender = UserGender.MALE; - } - if (gender.equals("female")) { - userGender = UserGender.FEMALE; - } - } - return userGender; - } - - private UserAge convertAge(String age) { - UserAge userGender = UserAge.UNKNOWN; - if (age != null) { - int startAge = Integer.parseInt(age.split("-")[0]); - for (UserAge value : UserAge.values()) { - if (startAge == value.getStartAge()) { - userGender = value; - break; - } - } - } - return userGender; - } -} diff --git a/src/main/java/com/sluv/server/domain/auth/service/AuthService.java b/src/main/java/com/sluv/server/domain/auth/service/AuthService.java deleted file mode 100644 index 12d70a88..00000000 --- a/src/main/java/com/sluv/server/domain/auth/service/AuthService.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.sluv.server.domain.auth.service; - -import com.sluv.server.domain.auth.dto.AuthResponseDto; -import com.sluv.server.domain.auth.dto.SocialUserInfoDto; -import com.sluv.server.domain.auth.enums.SnsType; -import com.sluv.server.domain.closet.service.ClosetService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNoFCMException; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.jwt.JwtProvider; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class AuthService { - - private final JwtProvider jwtProvider; - private final UserRepository userRepository; - - private final ClosetService closetService; - - public AuthResponseDto getAuthResDto(User user) { - - return AuthResponseDto.builder() - .token(jwtProvider.createAccessToken(user)) - .userStatus(user.getUserStatus()) - .build(); - } - - public User getOrCreateUser(SocialUserInfoDto userInfoDto, SnsType snsType, String fcm) { - User user = userRepository.findByEmail(userInfoDto.getEmail()).orElse(null); - - if (user == null) { - user = userRepository.save(User.toEntity(userInfoDto, snsType, fcm)); - - // 생성과 동시에 기본 Closet 생성 - closetService.postBasicCloset(user); - } - - changeFcm(user.getId(), fcm); - - return user; - } - - public void checkFcm(Long userId) { - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - if (user.getFcmToken() == null) { - throw new UserNoFCMException(); - } - } - - public void changeFcm(Long userId, String fcmToken) { - User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - user.changeFcmToken(fcmToken); - userRepository.save(user); - } -} diff --git a/src/main/java/com/sluv/server/domain/brand/controller/NewBrandController.java b/src/main/java/com/sluv/server/domain/brand/controller/NewBrandController.java deleted file mode 100644 index ef989a57..00000000 --- a/src/main/java/com/sluv/server/domain/brand/controller/NewBrandController.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.sluv.server.domain.brand.controller; - -import com.sluv.server.domain.brand.dto.NewBrandPostReqDto; -import com.sluv.server.domain.brand.dto.NewBrandPostResDto; -import com.sluv.server.domain.brand.service.NewBrandService; -import com.sluv.server.global.common.response.SuccessDataResponse; -import io.swagger.v3.oas.annotations.Operation; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@Slf4j -@RequiredArgsConstructor -@RequestMapping("/app/newBrand") -public class NewBrandController { - private final NewBrandService newBrandService; - - - @Operation(summary = "NewBrand 등록", description = "새로운 NewBrand를 등록한다.") - @PostMapping("") - public ResponseEntity> postNewBrand(@RequestBody NewBrandPostReqDto dto) { - log.info("NewBrand 등록. NewBrand Name:{}", dto.getNewBrandName()); - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(newBrandService.postNewBrand(dto)) - .build() - ); - } -} diff --git a/src/main/java/com/sluv/server/domain/brand/exception/BrandException.java b/src/main/java/com/sluv/server/domain/brand/exception/BrandException.java deleted file mode 100644 index fcdd7d7e..00000000 --- a/src/main/java/com/sluv/server/domain/brand/exception/BrandException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.brand.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class BrandException extends ApplicationException { - public BrandException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/brand/repository/BrandRepository.java b/src/main/java/com/sluv/server/domain/brand/repository/BrandRepository.java deleted file mode 100644 index 326d1ec0..00000000 --- a/src/main/java/com/sluv/server/domain/brand/repository/BrandRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sluv.server.domain.brand.repository; - -import com.sluv.server.domain.brand.entity.Brand; -import com.sluv.server.domain.brand.repository.impl.BrandRepositoryCustom; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface BrandRepository extends JpaRepository, BrandRepositoryCustom { -} diff --git a/src/main/java/com/sluv/server/domain/brand/repository/impl/RecentSelectBrandRepositoryCustom.java b/src/main/java/com/sluv/server/domain/brand/repository/impl/RecentSelectBrandRepositoryCustom.java deleted file mode 100644 index 9feed1e8..00000000 --- a/src/main/java/com/sluv/server/domain/brand/repository/impl/RecentSelectBrandRepositoryCustom.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.brand.repository.impl; - -import com.sluv.server.domain.brand.entity.RecentSelectBrand; -import com.sluv.server.domain.user.entity.User; - -import java.util.List; - -public interface RecentSelectBrandRepositoryCustom { - List getRecentSelectBrandTop20(User user); -} diff --git a/src/main/java/com/sluv/server/domain/brand/service/BrandService.java b/src/main/java/com/sluv/server/domain/brand/service/BrandService.java deleted file mode 100644 index 7a54e7c9..00000000 --- a/src/main/java/com/sluv/server/domain/brand/service/BrandService.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.sluv.server.domain.brand.service; - -import com.sluv.server.domain.brand.dto.BrandSearchResDto; -import com.sluv.server.domain.brand.dto.RecentSelectBrandResDto; -import com.sluv.server.domain.brand.entity.Brand; -import com.sluv.server.domain.brand.entity.RecentSelectBrand; -import com.sluv.server.domain.brand.repository.BrandRepository; -import com.sluv.server.domain.brand.repository.RecentSelectBrandRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationResDto; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class BrandService { - private final BrandRepository brandRepository; - private final RecentSelectBrandRepository recentSelectBrandRepository; - - - @Transactional(readOnly = true) - public PaginationResDto findAllBrand(String brandName, Pageable pageable) { - Page brandPage = brandRepository.findByAllBrandKrOrBrandEnStartingWith(brandName, pageable); - - List dtoList = brandPage.stream() - .map(BrandSearchResDto::of) - .toList(); - - return PaginationResDto.of(brandPage, dtoList); - } - - @Transactional(readOnly = true) - public List findTopBrand() { - return brandRepository.findTop10By() - .stream() - .map(BrandSearchResDto::of) - .toList(); - } - - @Transactional(readOnly = true) - public List findRecentSelectBrand(User user) { - - List recentSelectBrandList = recentSelectBrandRepository.getRecentSelectBrandTop20(user); - - return recentSelectBrandList.stream() - .map(RecentSelectBrandResDto::of) - .toList(); - } -} - diff --git a/src/main/java/com/sluv/server/domain/brand/service/NewBrandService.java b/src/main/java/com/sluv/server/domain/brand/service/NewBrandService.java deleted file mode 100644 index 86e98d9f..00000000 --- a/src/main/java/com/sluv/server/domain/brand/service/NewBrandService.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.sluv.server.domain.brand.service; - -import com.sluv.server.domain.brand.dto.NewBrandPostReqDto; -import com.sluv.server.domain.brand.dto.NewBrandPostResDto; -import com.sluv.server.domain.brand.entity.NewBrand; -import com.sluv.server.domain.brand.repository.NewBrandRepository; -import com.sluv.server.global.discord.WebHookService; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class NewBrandService { - private final NewBrandRepository newBrandRepository; - private final WebHookService webHookService; - - @Transactional - public NewBrandPostResDto postNewBrand(NewBrandPostReqDto dto) { - NewBrand newBrand = newBrandRepository.findByBrandName(dto.getNewBrandName()).orElse(null); - - if (newBrand == null) { - newBrand = newBrandRepository.save(NewBrand.toEntity(dto)); - webHookService.sendCreateNewBrandMessage(newBrand); - } - - return NewBrandPostResDto.of(newBrand); - } - - -} diff --git a/src/main/java/com/sluv/server/domain/brand/service/RecentSelectBrandService.java b/src/main/java/com/sluv/server/domain/brand/service/RecentSelectBrandService.java deleted file mode 100644 index 1dcc5e3b..00000000 --- a/src/main/java/com/sluv/server/domain/brand/service/RecentSelectBrandService.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.sluv.server.domain.brand.service; - -import com.sluv.server.domain.brand.dto.RecentSelectBrandReqDto; -import com.sluv.server.domain.brand.entity.Brand; -import com.sluv.server.domain.brand.entity.NewBrand; -import com.sluv.server.domain.brand.entity.RecentSelectBrand; -import com.sluv.server.domain.brand.exception.BrandNotFoundException; -import com.sluv.server.domain.brand.exception.NewBrandNotFoundException; -import com.sluv.server.domain.brand.repository.BrandRepository; -import com.sluv.server.domain.brand.repository.NewBrandRepository; -import com.sluv.server.domain.brand.repository.RecentSelectBrandRepository; -import com.sluv.server.domain.user.entity.User; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Slf4j -@RequiredArgsConstructor -public class RecentSelectBrandService { - private final BrandRepository brandRepository; - private final NewBrandRepository newBrandRepository; - private final RecentSelectBrandRepository recentSelectBrandRepository; - - @Transactional - public void postRecentSelectBrand(User user, RecentSelectBrandReqDto dto) { - Brand brand = dto.getBrandId() != null - ? brandRepository.findById(dto.getBrandId()) - .orElseThrow(BrandNotFoundException::new) - : null; - - NewBrand newBrand = dto.getNewBrandId() != null - ? newBrandRepository.findById(dto.getNewBrandId()) - .orElseThrow(NewBrandNotFoundException::new) - : null; - - recentSelectBrandRepository.save( - RecentSelectBrand.toEntity(brand, newBrand, user) - ); - } - - @Transactional - public void deleteAllRecentSelectBrand(User user) { - recentSelectBrandRepository.deleteAllByUserId(user.getId()); - } - - @Transactional - public void deleteRecentSelectBrand(User user, Long brandId, String flag) { - if (flag.equals("Y")) { - recentSelectBrandRepository.deleteByUserIdAndBrandId(user.getId(), brandId); - } else { - recentSelectBrandRepository.deleteByUserIdAndNewBrandId(user.getId(), brandId); - } - } -} diff --git a/src/main/java/com/sluv/server/domain/celeb/exception/CelebException.java b/src/main/java/com/sluv/server/domain/celeb/exception/CelebException.java deleted file mode 100644 index 99c53667..00000000 --- a/src/main/java/com/sluv/server/domain/celeb/exception/CelebException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.celeb.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class CelebException extends ApplicationException { - public CelebException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/celeb/handler/CelebHandler.java b/src/main/java/com/sluv/server/domain/celeb/handler/CelebHandler.java deleted file mode 100644 index 580da955..00000000 --- a/src/main/java/com/sluv/server/domain/celeb/handler/CelebHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.sluv.server.domain.celeb.handler; - -import com.sluv.server.domain.celeb.dto.CelebSearchResDto; -import com.sluv.server.domain.celeb.entity.Celeb; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - -@Component -@RequiredArgsConstructor -public class CelebHandler { - - /** - * Celeb 리스트를 CelebSearchResDto 리스트로 변경 - */ - public List convertCelebSearchResDto(List celebList) { - return celebList.stream() - .map(CelebSearchResDto::of) - .toList(); - } -} diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/CelebActivityRepository.java b/src/main/java/com/sluv/server/domain/celeb/repository/CelebActivityRepository.java deleted file mode 100644 index 7c55bd1d..00000000 --- a/src/main/java/com/sluv/server/domain/celeb/repository/CelebActivityRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.celeb.repository; - -import com.sluv.server.domain.celeb.entity.CelebActivity; -import com.sluv.server.domain.celeb.repository.Impl.CelebActivityRepositoryCustom; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface CelebActivityRepository extends JpaRepository, CelebActivityRepositoryCustom { -} diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/CelebRepository.java b/src/main/java/com/sluv/server/domain/celeb/repository/CelebRepository.java deleted file mode 100644 index 550e9f16..00000000 --- a/src/main/java/com/sluv/server/domain/celeb/repository/CelebRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.sluv.server.domain.celeb.repository; - -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.repository.Impl.CelebRepositoryCustom; -import org.springframework.data.jpa.repository.JpaRepository; - - -public interface CelebRepository extends JpaRepository, CelebRepositoryCustom { -} \ No newline at end of file diff --git a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/RecentSelectCelebRepositoryCustom.java b/src/main/java/com/sluv/server/domain/celeb/repository/Impl/RecentSelectCelebRepositoryCustom.java deleted file mode 100644 index 2de344d8..00000000 --- a/src/main/java/com/sluv/server/domain/celeb/repository/Impl/RecentSelectCelebRepositoryCustom.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.sluv.server.domain.celeb.repository.Impl; - -import com.sluv.server.domain.celeb.entity.RecentSelectCeleb; -import com.sluv.server.domain.user.entity.User; - -import java.util.List; - -public interface RecentSelectCelebRepositoryCustom { - - List getRecentSelectCelebTop20(User user); -} diff --git a/src/main/java/com/sluv/server/domain/celeb/service/CelebService.java b/src/main/java/com/sluv/server/domain/celeb/service/CelebService.java deleted file mode 100644 index 3824f7d1..00000000 --- a/src/main/java/com/sluv/server/domain/celeb/service/CelebService.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.sluv.server.domain.celeb.service; - -import com.sluv.server.domain.celeb.dto.CelebChipResDto; -import com.sluv.server.domain.celeb.dto.CelebSearchByCategoryResDto; -import com.sluv.server.domain.celeb.dto.CelebSearchResDto; -import com.sluv.server.domain.celeb.dto.RecentSelectCelebResDto; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.CelebCategory; -import com.sluv.server.domain.celeb.entity.RecentSelectCeleb; -import com.sluv.server.domain.celeb.handler.CelebHandler; -import com.sluv.server.domain.celeb.repository.CelebCategoryRepository; -import com.sluv.server.domain.celeb.repository.CelebRepository; -import com.sluv.server.domain.celeb.repository.RecentSelectCelebRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationResDto; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Stream; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class CelebService { - - private final CelebRepository celebRepository; - private final RecentSelectCelebRepository recentSearchCelebRepository; - private final CelebCategoryRepository celebCategoryRepository; - private final CelebHandler celebHandler; - - @Transactional(readOnly = true) - public PaginationResDto searchCeleb(String celebName, Pageable pageable) { - - Page celebPage = celebRepository.searchCeleb(celebName, pageable); - - return PaginationResDto.of(celebPage, celebHandler.convertCelebSearchResDto(celebPage.toList())); - - } - - @Transactional(readOnly = true) - public List getUserRecentSelectCeleb(User user) { - List recentSelectCelebList = recentSearchCelebRepository.getRecentSelectCelebTop20(user); - - return recentSelectCelebList - .stream() - .map(RecentSelectCelebResDto::of) - .toList(); - } - - @Transactional(readOnly = true) - public List getTop10Celeb() { - return celebHandler.convertCelebSearchResDto(celebRepository.findTop10Celeb()); - } - - @Transactional(readOnly = true) - public List getCelebByCategory() { - // Parent Id가 null인 CelebCategory를 모두 조회 - List categoryList = celebCategoryRepository.findAllByParentIdIsNull(); - changeCategoryOrder(categoryList); - - return categoryList.stream() - // 카테고리별 CelebSearchByCategoryResDto 생성 - .map(category -> CelebSearchByCategoryResDto.of(category, - celebRepository.getCelebByCategory(category) - .stream() - // 셀럽별 CelebChipResDto 생성 - .map(CelebChipResDto::of) - .toList() - ) - ).toList(); - - } - - /** - * 가수 -> 배우 -> 방송인 -> 스포츠인 -> 인플루언서 순서로 변 - */ - - private void changeCategoryOrder(List categoryList) { - categoryList.sort(Comparator.comparing(CelebCategory::getName)); - - CelebCategory tempCategory = categoryList.get(1); - categoryList.set(1, categoryList.get(2)); - categoryList.set(2, tempCategory); - } - - @Transactional(readOnly = true) - public List searchInterestedCelebByName(String celebName) { - // 1. Parent Celeb과 일치 - List celebByParent = celebRepository.searchInterestedCelebByParent(celebName); - - // 2. Child Celeb과 일치 - List celebByChild = celebRepository.searchInterestedCelebByChild(celebName); - - // 1 + 2 를 합친 Celeb - List celebList = Stream.concat(celebByParent.stream(), celebByChild.stream()).distinct().toList(); - - // Celeb의 모든 카테고리 조회 - List celebCategoryList = celebCategoryRepository.findAllByParentIdIsNull(); - - // Category별 맞는 celeb들을 골라내서 조립. - return celebCategoryList.stream() - // 카테고리별 분류 - .map(category -> { - List eachCategoryCeleb = - // 카테고리에 맞는 셀럽 filtering - celebList.stream().filter(celeb -> { - // ParentCategory가 있다면 ParentCategory. 없다면, CelebCategory. - CelebCategory tempCategory = celeb.getCelebCategory().getParent() != null - ? celeb.getCelebCategory().getParent() - : celeb.getCelebCategory(); - - return tempCategory == category; - // Category에 맞게 분류된 celeb을 Dto로 변경 - }).map(CelebChipResDto::of) - // 가나다 순으로 정렬 - .sorted(Comparator.comparing(CelebChipResDto::getCelebName)) - .toList(); - - return CelebSearchByCategoryResDto.of(category, eachCategoryCeleb); - }) - .toList(); - } - -} diff --git a/src/main/java/com/sluv/server/domain/celeb/service/NewCelebService.java b/src/main/java/com/sluv/server/domain/celeb/service/NewCelebService.java deleted file mode 100644 index eb71d632..00000000 --- a/src/main/java/com/sluv/server/domain/celeb/service/NewCelebService.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sluv.server.domain.celeb.service; - -import com.sluv.server.domain.celeb.dto.NewCelebPostReqDto; -import com.sluv.server.domain.celeb.dto.NewCelebPostResDto; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.celeb.repository.NewCelebRepository; -import com.sluv.server.global.discord.WebHookService; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class NewCelebService { - - private final NewCelebRepository newCelebRepository; - private final WebHookService webHookService; - - @Transactional - public NewCelebPostResDto postNewCeleb(NewCelebPostReqDto dto) { - NewCeleb newCeleb = newCelebRepository.findByCelebName(dto.getNewCelebName()).orElse(null); - - if (newCeleb == null) { - newCeleb = newCelebRepository.save(NewCeleb.toEntity(dto)); - webHookService.sendCreateNewCelebMessage(newCeleb); - } - - return NewCelebPostResDto.of(newCeleb); - } -} diff --git a/src/main/java/com/sluv/server/domain/celeb/service/RecentSelectCelebService.java b/src/main/java/com/sluv/server/domain/celeb/service/RecentSelectCelebService.java deleted file mode 100644 index 8bd8b5cc..00000000 --- a/src/main/java/com/sluv/server/domain/celeb/service/RecentSelectCelebService.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.sluv.server.domain.celeb.service; - -import com.sluv.server.domain.celeb.dto.RecentSelectCelebReqDto; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.celeb.entity.RecentSelectCeleb; -import com.sluv.server.domain.celeb.exception.CelebNotFoundException; -import com.sluv.server.domain.celeb.exception.NewCelebNotFoundException; -import com.sluv.server.domain.celeb.repository.CelebRepository; -import com.sluv.server.domain.celeb.repository.NewCelebRepository; -import com.sluv.server.domain.celeb.repository.RecentSelectCelebRepository; -import com.sluv.server.domain.user.entity.User; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class RecentSelectCelebService { - private final CelebRepository celebRepository; - private final NewCelebRepository newCelebRepository; - private final RecentSelectCelebRepository recentSelectCelebRepository; - - @Transactional - public void postRecentSelectCeleb(User user, RecentSelectCelebReqDto dto) { - Celeb celeb = dto.getCelebId() != null - ? celebRepository.findById(dto.getCelebId()) - .orElseThrow(CelebNotFoundException::new) - : null; - - NewCeleb newCeleb = dto.getNewCelebId() != null - ? newCelebRepository.findById(dto.getNewCelebId()) - .orElseThrow(NewCelebNotFoundException::new) - : null; - - recentSelectCelebRepository.save( - RecentSelectCeleb.builder() - .celeb(celeb) - .newCeleb(newCeleb) - .user(user) - .build() - ); - } - - @Transactional - public void deleteAllRecentSelectCeleb(User user) { - recentSelectCelebRepository.deleteAllByUserId(user.getId()); - } - - @Transactional - public void deleteRecentSelectCeleb(User user, Long celebId, String flag) { - if (flag.equals("Y")) { - recentSelectCelebRepository.deleteByUserIdAndCelebId(user.getId(), celebId); - } else { - recentSelectCelebRepository.deleteByUserIdAndNewCelebId(user.getId(), celebId); - } - } -} diff --git a/src/main/java/com/sluv/server/domain/closet/dto/ClosetListCountResDto.java b/src/main/java/com/sluv/server/domain/closet/dto/ClosetListCountResDto.java deleted file mode 100644 index fe65c714..00000000 --- a/src/main/java/com/sluv/server/domain/closet/dto/ClosetListCountResDto.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.sluv.server.domain.closet.dto; - -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class ClosetListCountResDto { - Long closetCount; - List closetList; - - public static ClosetListCountResDto of(Long closetCount, List closetList) { - return ClosetListCountResDto.builder() - .closetCount(closetCount) - .closetList(closetList) - .build(); - } -} diff --git a/src/main/java/com/sluv/server/domain/closet/dto/ClosetNameCheckResDto.java b/src/main/java/com/sluv/server/domain/closet/dto/ClosetNameCheckResDto.java deleted file mode 100644 index d5d07461..00000000 --- a/src/main/java/com/sluv/server/domain/closet/dto/ClosetNameCheckResDto.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.sluv.server.domain.closet.dto; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@AllArgsConstructor -@NoArgsConstructor -@Builder -public class ClosetNameCheckResDto { - @Schema(description = "Closet의 이름이 중복인지 확인") - Boolean isDuplicated; - - public static ClosetNameCheckResDto of(Boolean checkStatus) { - return ClosetNameCheckResDto.builder() - .isDuplicated(checkStatus) - .build(); - } -} diff --git a/src/main/java/com/sluv/server/domain/closet/exception/ClosetException.java b/src/main/java/com/sluv/server/domain/closet/exception/ClosetException.java deleted file mode 100644 index 8d68e835..00000000 --- a/src/main/java/com/sluv/server/domain/closet/exception/ClosetException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.closet.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class ClosetException extends ApplicationException { - public ClosetException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/closet/service/ClosetItemService.java b/src/main/java/com/sluv/server/domain/closet/service/ClosetItemService.java deleted file mode 100644 index 67620c15..00000000 --- a/src/main/java/com/sluv/server/domain/closet/service/ClosetItemService.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.sluv.server.domain.closet.service; - -import com.sluv.server.domain.closet.dto.ClosetDetailResDto; -import com.sluv.server.domain.closet.dto.ClosetItemSelectReqDto; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.closet.enums.ClosetStatus; -import com.sluv.server.domain.closet.exception.ClosetNotFoundException; -import com.sluv.server.domain.closet.repository.ClosetRepository; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.ItemScrap; -import com.sluv.server.domain.item.exception.ItemNotFoundException; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.item.repository.ItemScrapRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNotMatchedException; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@RequiredArgsConstructor -@Slf4j -@Service -public class ClosetItemService { - private final ItemRepository itemRepository; - private final ItemScrapRepository itemScrapRepository; - private final ClosetRepository closetRepository; - - /** - * 옷장 상세 조회 - */ - @Transactional(readOnly = true) - public ClosetDetailResDto getClosetDetails(User user, Long closetId, Pageable pageable) { - Closet closet = closetRepository.findById(closetId).orElseThrow(ClosetNotFoundException::new); - if (closet.getClosetStatus().equals(ClosetStatus.PRIVATE) && !closet.getUser().getId().equals(user.getId())) { - log.info("User did Not Matched. User Id: {}, Closet Owner Id : {}", user.getId(), - closet.getUser().getId()); - throw new UserNotMatchedException(); - } - Page itemPage = itemRepository.getClosetItems(closet, pageable); - return ClosetDetailResDto.of(itemPage, closet); - } - - /** - * 아이템 스크랩 - */ - @Transactional - public void postItemScrapToCloset(User user, Long itemId, Long closetId) { - Item item = itemRepository.findById(itemId).orElseThrow(ItemNotFoundException::new); - Closet closet = closetRepository.findById(closetId).orElseThrow(ClosetNotFoundException::new); - - if (!closet.getUser().getId().equals(user.getId())) { - log.info("User did Not Matched. User Id: {}, Closet Owner Id : {}", user.getId(), closet.getUser().getId()); - throw new UserNotMatchedException(); - } - - log.info("Save ItemScrap with item Id: {}, Closet Id {}", item.getId(), closet.getId()); - ItemScrap saveItemScrap = itemScrapRepository.save( - ItemScrap.toEntity(item, closet) - ); - log.info("Save Success with ItemScrap Id: {}", saveItemScrap.getId()); - - - } - - /** - * 아이템 스크랩 취소 - */ - @Transactional - public void deleteItemScrapFromCloset(User user, Long itemId) { - List closetList = closetRepository.findAllByUserId(user.getId()); - - log.info("DELETE ItemScrap {}", itemId); - closetList.forEach(closet -> { - itemScrapRepository.deleteByClosetIdAndItemId(closet.getId(), itemId); - }); - } - - /** - * 옷장에서 선택한 아이템 삭제 - */ - @Transactional - public void removeSelectItemInCloset(User user, Long closetId, ClosetItemSelectReqDto dto) { - Closet closet = closetRepository.findById(closetId).orElseThrow(ClosetNotFoundException::new); - - if (!closet.getUser().getId().equals(user.getId())) { - log.info("User did Not Matched. User Id: {}, Closet Owner Id : {}", user.getId(), closet.getUser().getId()); - throw new UserNotMatchedException(); - } - - dto.getItemList().forEach(itemId -> { - log.info("Delete Item {}, from Closet {}", itemId, closet.getId()); - itemScrapRepository.deleteByClosetIdAndItemId(closet.getId(), itemId); - }); - - } - - - /** - * 특정 옷장에 있는 아이템을 다른 옷장으로 이동 - */ - @Transactional - public void moveItemInCloset(User user, Long fromClosetId, Long toClosetId, ClosetItemSelectReqDto dto) { - Closet fromCloset = closetRepository.findById(fromClosetId).orElseThrow(ClosetNotFoundException::new); - Closet toCloset = closetRepository.findById(toClosetId).orElseThrow(ClosetNotFoundException::new); - - // fromCloset과 현재 유저 일치 비교 - if (!fromCloset.getUser().getId().equals(user.getId())) { - log.info("User did Not Matched. User Id: {}, fromCloset Owner Id : {}", user.getId(), - fromCloset.getUser().getId()); - throw new UserNotMatchedException(); - } - - // toCloset과 현재 유저 일치 비교 - if (!toCloset.getUser().getId().equals(user.getId())) { - log.info("User did Not Matched. User Id: {}, toCloset Owner Id : {}", user.getId(), - toCloset.getUser().getId()); - throw new UserNotMatchedException(); - } - - // Target ItemScrap 모두 조회 - List itemScrapList = dto.getItemList() - .stream() - .map(itemId -> - itemScrapRepository.findByClosetIdAndItemId(fromClosetId, itemId) - ).toList(); - - // Target ItemScrap의 Closet을 toCloset으로 모두 변경 - itemScrapList.forEach(itemScrap -> - itemScrap.changeCloset(toCloset) - ); - - } -} diff --git a/src/main/java/com/sluv/server/domain/closet/service/ClosetService.java b/src/main/java/com/sluv/server/domain/closet/service/ClosetService.java deleted file mode 100644 index 12e03df8..00000000 --- a/src/main/java/com/sluv/server/domain/closet/service/ClosetService.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.sluv.server.domain.closet.service; - -import com.sluv.server.domain.closet.dto.ClosetListCountResDto; -import com.sluv.server.domain.closet.dto.ClosetNameCheckResDto; -import com.sluv.server.domain.closet.dto.ClosetReqDto; -import com.sluv.server.domain.closet.dto.ClosetResDto; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.closet.enums.ClosetColor; -import com.sluv.server.domain.closet.enums.ClosetStatus; -import com.sluv.server.domain.closet.exception.BasicClosetDeleteException; -import com.sluv.server.domain.closet.exception.ClosetNotFoundException; -import com.sluv.server.domain.closet.repository.ClosetRepository; -import com.sluv.server.domain.item.repository.ItemScrapRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNotMatchedException; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Slf4j -@RequiredArgsConstructor -public class ClosetService { - private final ClosetRepository closetRepository; - private final ItemScrapRepository itemScrapRepository; - - /** - * 유저의 옷장 목록 조회 - */ - @Transactional(readOnly = true) - public ClosetListCountResDto getClosetList(User user) { - List closetResDtos = closetRepository.getUserClosetList(user); - return ClosetListCountResDto.of(closetRepository.countByUserId(user.getId()), closetResDtos); - } - - /** - * 옷장 생성 전 이름 중복 체크 - */ - @Transactional(readOnly = true) - public ClosetNameCheckResDto checkClosetNameDuplicated(String name, Long closetId) { - Boolean isDuplicated = closetRepository.checkDuplicate(name, closetId); - - return ClosetNameCheckResDto.of(isDuplicated); - } - - /** - * 신규 유저 생성 시 기본 옷장 생성 - */ - @Transactional - public void postBasicCloset(User user) { - Closet basicCloset = Closet.builder() - .user(user) - .name("기본 옷장") - .coverImgUrl(null) - .basicFlag(true) - .color(ClosetColor.PURPLE) - .closetStatus(ClosetStatus.PRIVATE) - .build(); - - closetRepository.save(basicCloset); - } - - /** - * 옷장 생성 - */ - @Transactional - public void postCloset(User user, ClosetReqDto dto) { - log.info("옷장 생성 - 사용자: {}, 이름: {}", user.getId(), dto.getName()); - closetRepository.save( - Closet.toEntity(user, dto) - ); - } - - /** - * 옷장 정보 변경 - */ - @Transactional - public void patchCloset(User user, Long closetId, ClosetReqDto dto) { - Closet closet = closetRepository.findById(closetId).orElseThrow(ClosetNotFoundException::new); - log.info("옷장 변경 - 사용자: {} ", user.getId()); - if (!closet.getUser().getId().equals(user.getId())) { - log.info("옷장 변경 실패 - 사용자: {}, 옷장 주인: {}", user.getId(), closet.getUser().getId()); - throw new UserNotMatchedException(); - } - closet.changeCloset(dto); - } - - /** - * 옷장 삭제 - */ - @Transactional - public void deleteCloset(User user, Long closetId) { - Closet closet = closetRepository.findById(closetId).orElseThrow(ClosetNotFoundException::new); - - // 현재 유저와 Closet Owner 비교 - if (!closet.getUser().getId().equals(user.getId())) { - log.info("User did Not Matched. User Id: {}, Closet Owner Id : {}", user.getId(), closet.getUser().getId()); - throw new UserNotMatchedException(); - } - // 기본 Closet 여부 확인 - if (closet.getBasicFlag()) { - log.info("Closet Id {} is Basic Closet", closet.getId()); - throw new BasicClosetDeleteException(); - } - - log.info("ItemScrap Delete By Closet Id: {}", closet.getId()); - itemScrapRepository.deleteAllByClosetId(closet.getId()); - - log.info("Delete Closet Id: {}", closet.getId()); - closetRepository.deleteById(closet.getId()); - } - -} diff --git a/src/main/java/com/sluv/server/domain/comment/dto/CommentItemResDto.java b/src/main/java/com/sluv/server/domain/comment/dto/CommentItemResDto.java deleted file mode 100644 index 408888c3..00000000 --- a/src/main/java/com/sluv/server/domain/comment/dto/CommentItemResDto.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.sluv.server.domain.comment.dto; - -import com.sluv.server.domain.comment.entity.CommentItem; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.entity.ItemImg; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class CommentItemResDto { - @Schema(description = "Comment 아이템 정보") - private ItemSimpleResDto item; - @Schema(description = "Comment 아이템 순서") - private Integer sortOrder; - - public static CommentItemResDto of(CommentItem commentItem, ItemImg mainImg, Boolean scrapStatus) { - - ItemSimpleResDto itemSimpleResDto = ItemSimpleResDto.of(commentItem.getItem(), mainImg, scrapStatus); - - return CommentItemResDto.builder() - .item(itemSimpleResDto) - .sortOrder(commentItem.getSortOrder()) - .build(); - } -} diff --git a/src/main/java/com/sluv/server/domain/comment/dto/SubCommentPageResDto.java b/src/main/java/com/sluv/server/domain/comment/dto/SubCommentPageResDto.java deleted file mode 100644 index 1aa6d509..00000000 --- a/src/main/java/com/sluv/server/domain/comment/dto/SubCommentPageResDto.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.sluv.server.domain.comment.dto; - -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.global.common.response.PaginationResDto; -import java.util.List; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; -import org.springframework.data.domain.Page; - -@NoArgsConstructor -@Getter -@SuperBuilder -public class SubCommentPageResDto extends PaginationResDto { - private Long restCommentNum; - - public static SubCommentPageResDto of(Page commentPage, List content, - long restCommentNum) { - return SubCommentPageResDto.builder() - .hasNext(commentPage.hasNext()) - .page(commentPage.getNumber()) - .content(content) - .restCommentNum(restCommentNum) - .build(); - } -} diff --git a/src/main/java/com/sluv/server/domain/comment/exception/CommentException.java b/src/main/java/com/sluv/server/domain/comment/exception/CommentException.java deleted file mode 100644 index 82047e73..00000000 --- a/src/main/java/com/sluv/server/domain/comment/exception/CommentException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.comment.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class CommentException extends ApplicationException { - public CommentException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/comment/service/CommentReportService.java b/src/main/java/com/sluv/server/domain/comment/service/CommentReportService.java deleted file mode 100644 index 3b048b5b..00000000 --- a/src/main/java/com/sluv/server/domain/comment/service/CommentReportService.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.sluv.server.domain.comment.service; - -import com.sluv.server.domain.comment.dto.CommentReportPostReqDto; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.entity.CommentReport; -import com.sluv.server.domain.comment.exception.CommentNotFoundException; -import com.sluv.server.domain.comment.exception.CommentReportDuplicateException; -import com.sluv.server.domain.comment.repository.CommentReportRepository; -import com.sluv.server.domain.comment.repository.CommentRepository; -import com.sluv.server.domain.user.entity.User; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Slf4j -@RequiredArgsConstructor -public class CommentReportService { - private final CommentRepository commentRepository; - private final CommentReportRepository commentReportRepository; - - /** - * 댓글 신고 - */ - @Transactional - public void postCommentReport(User user, Long commentId, CommentReportPostReqDto dto) { - log.info("댓글 신고 - 사용자 : {}, 신고 댓글 : {}", user.getId(), commentId); - Boolean reportStatus = commentReportRepository.existsByReporterIdAndCommentId(user.getId(), commentId); - - if (reportStatus) { - throw new CommentReportDuplicateException(); - } - - Comment comment = commentRepository.findById(commentId).orElseThrow(CommentNotFoundException::new); - commentReportRepository.save( - CommentReport.toEntity(comment, user, dto) - ); - } - - -} diff --git a/src/main/java/com/sluv/server/domain/comment/service/CommentService.java b/src/main/java/com/sluv/server/domain/comment/service/CommentService.java deleted file mode 100644 index 2f2d13a8..00000000 --- a/src/main/java/com/sluv/server/domain/comment/service/CommentService.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.sluv.server.domain.comment.service; - -import com.sluv.server.domain.alarm.service.CommentAlarmService; -import com.sluv.server.domain.comment.dto.CommentPostReqDto; -import com.sluv.server.domain.comment.dto.CommentResDto; -import com.sluv.server.domain.comment.dto.SubCommentPageResDto; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.entity.CommentLike; -import com.sluv.server.domain.comment.exception.CommentNotFoundException; -import com.sluv.server.domain.comment.handler.CommentHelper; -import com.sluv.server.domain.comment.manager.CommentImgManager; -import com.sluv.server.domain.comment.manager.CommentItemManager; -import com.sluv.server.domain.comment.repository.CommentLikeRepository; -import com.sluv.server.domain.comment.repository.CommentRepository; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.exception.QuestionNotFoundException; -import com.sluv.server.domain.question.repository.QuestionRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNotMatchedException; -import com.sluv.server.global.ai.AiModelService; -import com.sluv.server.global.common.response.PaginationResDto; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Slf4j -@RequiredArgsConstructor -public class CommentService { - private final QuestionRepository questionRepository; - private final CommentRepository commentRepository; - private final CommentLikeRepository commentLikeRepository; - private final AiModelService aiModelService; - private final CommentHelper commentHelper; - private final CommentItemManager commentItemManager; - private final CommentImgManager commentImgManager; - - private final CommentAlarmService commentAlarmService; - - /** - * 댓글 조회 - */ - @Transactional(readOnly = true) - public PaginationResDto getComment(User user, Long questionId, Pageable pageable) { - // 해당 페이지 검색 - Page commentPage = commentRepository.getAllQuestionComment(questionId, pageable); - - // Content 제작 - List content = commentHelper.getCommentResDtos(user, commentPage.getContent()); - - return PaginationResDto.of(commentPage, content); - } - - /** - * 댓글 상세 조회 - */ - @Transactional(readOnly = true) - public CommentResDto getCommentDetail(User user, Long commentId) { - // 댓글 조회 - Comment comment = commentRepository.findById(commentId) - .orElseThrow(CommentNotFoundException::new); - - // Content 제작 - List content = commentHelper.getCommentResDtos(user, List.of(comment)); - - return content.get(0); - - } - - /** - * 대댓글 조회 - */ - @Transactional(readOnly = true) - public SubCommentPageResDto getSubComment(User user, Long commentId, Pageable pageable) { - // 대댓글 페이지 검색 - Page commentPage = commentRepository.getAllSubComment(commentId, pageable); - - // Content 제작 - List content = commentHelper.getCommentResDtos(user, commentPage.getContent()); - - // 남은 댓글 수. 총 댓글 수 - ((현재 페이지 +1)*페이지당 size)가 0보다 작으면 0, 아닐 경우 해당 값 - long restCommentNum = - commentPage.getTotalElements() - ((long) (commentPage.getNumber() + 1) * commentPage.getSize()) >= 0 - ? commentPage.getTotalElements() - ((long) (commentPage.getNumber() + 1) - * commentPage.getSize()) - : 0; - - return SubCommentPageResDto.of(commentPage, content, restCommentNum); - - } - - /** - * 댓글 등록 - */ - @Transactional - public void postComment(User user, Long questionId, CommentPostReqDto dto) { - log.info("댓글 등록 - 사용자 : {}, 질문 게시글 : {}, 댓글 내용 {}", user.getId(), questionId, dto.getContent()); - Question question = questionRepository.findById(questionId).orElseThrow(QuestionNotFoundException::new); - - Comment comment = commentRepository.save(Comment.toEntity(user, question, dto.getContent())); - commentItemManager.saveCommentItem(dto, comment); - commentImgManager.saveCommentImg(dto, comment); - - aiModelService.censorComment(comment); - commentAlarmService.sendAlarmAboutComment(user.getId(), comment.getId(), user); - - } - - /** - * 대댓글 등록 - */ - @Transactional - public void postSubComment(User user, Long questionId, Long commentId, CommentPostReqDto dto) { - log.info("대댓글 등록 - 사용자 : {}, 질문 게시글 : {}, 상위 댓글 : {}, 댓글 내용 {}", - user.getId(), questionId, commentId, dto.getContent()); - - Question question = questionRepository.findById(questionId).orElseThrow(QuestionNotFoundException::new); - - // Parent Comment 조회 - Comment parentComment = commentRepository.findById(commentId).orElseThrow(CommentNotFoundException::new); - - Comment comment = commentRepository.save(Comment.toEntity(user, question, dto.getContent(), parentComment)); - commentItemManager.saveCommentItem(dto, comment); - commentImgManager.saveCommentImg(dto, comment); - - aiModelService.censorComment(comment); - commentAlarmService.sendAlarmAboutComment(user.getId(), comment.getId(), user); - commentAlarmService.sendAlarmAboutSubComment(user.getId(), comment.getId(), user); - } - - /** - * 댓글 수정 - */ - @Transactional - public void putComment(User user, Long commentId, CommentPostReqDto dto) { - /** - * 1. Comment의 content 수정 - * 2. Comment와 관련된 img 초기화 후 재등록 - * 3. Comment와 관련된 item 초기화 후 재등록 - */ - log.info("댓글 수정 - 사용자 : {}. 댓글 : {}", user.getId(), commentId); - Comment comment = commentRepository.findById(commentId).orElseThrow(CommentNotFoundException::new); - - if (!comment.getUser().getId().equals(user.getId())) { - throw new UserNotMatchedException(); - } - // content 변경 - comment.changeContent(dto.getContent()); - - commentItemManager.saveCommentItem(dto, comment); - commentImgManager.saveCommentImg(dto, comment); - aiModelService.censorComment(comment); - - } - - /** - * 댓글 삭제 - */ - @Transactional - public void deleteComment(User user, Long commentId) { - log.info("댓글 삭제 - 사용자 : {}, 댓글 : {}", user.getId(), commentId); - Comment comment = commentRepository.findById(commentId).orElseThrow(CommentNotFoundException::new); - - // comment 작성자와 현재 User가 불일치 시 예외 처리 - if (!comment.getUser().getId().equals(user.getId())) { - throw new UserNotMatchedException(); - } - - // Target Comment 제거 - commentRepository.deleteById(commentId); - - // Target의 대댓글 제거 - commentRepository.deleteAllByParentId(commentId); - - } - - /** - * 댓글 좋아요 - */ - @Transactional - public void postCommentLike(User user, Long commentId) { - log.info("댓글 삭제 - 사용자 : {}, 댓글 : {}", user.getId(), commentId); - Boolean commentListStatus = commentLikeRepository.existsByUserIdAndCommentId(user.getId(), commentId); - - if (!commentListStatus) { - Comment comment = commentRepository.findById(commentId).orElseThrow(CommentNotFoundException::new); - commentLikeRepository.save(CommentLike.toEntity(user, comment)); - commentAlarmService.sendAlarmAboutCommentLike(user.getId(), comment.getId()); - } else { - commentLikeRepository.deleteByUserIdAndCommentId(user.getId(), commentId); - } - } - - -} diff --git a/src/main/java/com/sluv/server/domain/item/controller/ItemController.java b/src/main/java/com/sluv/server/domain/item/controller/ItemController.java deleted file mode 100644 index 6f225f62..00000000 --- a/src/main/java/com/sluv/server/domain/item/controller/ItemController.java +++ /dev/null @@ -1,310 +0,0 @@ -package com.sluv.server.domain.item.controller; - -import com.sluv.server.domain.item.dto.ItemDetailResDto; -import com.sluv.server.domain.item.dto.ItemPostReqDto; -import com.sluv.server.domain.item.dto.ItemPostResDto; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.exception.StandardNotFoundException; -import com.sluv.server.domain.item.service.ItemService; -import com.sluv.server.domain.search.dto.SearchFilterReqDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; -import io.swagger.v3.oas.annotations.Operation; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Pageable; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequiredArgsConstructor -@RequestMapping("/app/item") -@Slf4j -public class ItemController { - - private final ItemService itemService; - - /** - * 아이템 상세조회 - */ - @Operation(summary = "*특정 아이템 게시글 상세조회", description = "User 토큰 필요") - @GetMapping("/{itemId}") - public ResponseEntity> getItemDetail(@AuthenticationPrincipal User user, - @PathVariable("itemId") Long itemId) { - - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(itemService.getItemDetail(user, itemId)) - .build() - ); - } - - /** - * 같은 셀럽 아이템 리스트 -> 10개 같은 브랜드 아이템 리스트 -> 10개 - */ - @Operation(summary = "*같은 셀럽 아이템 리스트 조회", description = "User 토큰 필요") - @GetMapping("/sameCelebItem") - public ResponseEntity>> getSameCelebItem( - @AuthenticationPrincipal User user, @RequestParam("itemId") Long itemId) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getSameCelebItems(user, itemId)) - .build() - ); - } - - /** - * 같은 브랜드의 아이템 -> 브랜드를 기준으로 최신 아이템 검색 -> 10개 - */ - @Operation(summary = "*같은 브랜드의 아이템 리스트 조회", description = "User 토큰 필요") - @GetMapping("/sameBrandItem") - public ResponseEntity>> getSameBrandItem( - @AuthenticationPrincipal User user, @RequestParam("itemId") Long itemId) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getSameBrandItem(user, itemId)) - .build() - ); - } - - /** - * 함께 스크랩한 아이템 -> 10개 - */ - @Operation(summary = "*함께 스크랩한 아이템 리스트 조회", description = "User 토큰 필요") - @GetMapping("/togetherScrap") - public ResponseEntity>> getTogetherScrapItem( - @AuthenticationPrincipal User user, - @RequestParam("itemId") Long itemId) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getTogetherScrapItem(user, itemId)) - .build() - ); - } - - @Operation(summary = "*최근 본 아이템 조회", description = "User 토큰 필요. Pagination 적용. 최근 본 순서로 정렬.") - @GetMapping("/recent") - public ResponseEntity>> getRecentItem( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getRecentItem(user, pageable)) - .build() - ); - } - - @Operation(summary = "*찜한 아이템 조회", description = "User 토큰 필요. Pagination 적용. 스크랩한 최신순으로 정렬.") - @GetMapping("/scrap") - public ResponseEntity>> getScrapItem( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getScrapItem(user, pageable)) - .build() - ); - } - - @Operation(summary = "*아이템 등록 및 수정", description = "User 토큰 필요") - @PostMapping("") - public ResponseEntity> postItem(@AuthenticationPrincipal User user, - @RequestBody ItemPostReqDto reqDto) { - - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(itemService.postItem(user, reqDto)) - .build() - ); - } - - @Operation(summary = "아이템 게시글 좋아요", description = "User 토큰 필요") - @PostMapping("/{itemId}/like") - public ResponseEntity postItemLike(@AuthenticationPrincipal User user, - @PathVariable("itemId") Long itemId) { - itemService.postItemLike(user, itemId); - return ResponseEntity.ok().body( - new SuccessResponse() - ); - } - - @Operation(summary = "아이템 게시글 삭제") - @DeleteMapping("/{itemId}") - public ResponseEntity deleteItem(@PathVariable("itemId") Long itemId) { - itemService.deleteItem(itemId); - return ResponseEntity.ok().body( - new SuccessResponse() - ); - } - - /* 홈페이지 기능 */ - - /** - * 초반: 좋아요 수, 스크랩 수, 조회수를 모두 합산하여 높은 순서 + 착용 최신순으로 정렬 후반: 유저별 검색기록, 관심셀럽을 기준으로 조회 - */ - @Operation(summary = "*유저별 추천 인기 아이템 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/recommend") - public ResponseEntity>> getRecommendItem( - @AuthenticationPrincipal User user, Pageable pageable) { - log.info("유저별 추천 인기 아이템 조회"); - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getRecommendItem(user, pageable)) - .build() - ); - } - - @Operation(summary = "*핫한 셀럽들이 선택한 여름나기 아이템 조회", - description = "User 토큰 필요. Pagination 적용. Ordering -> 최신순, 인기순, 저가순, 고가순. Filtering -> Price, Color.") - @GetMapping("/summer") - public ResponseEntity>> getSummerItem( - @AuthenticationPrincipal User user, - Pageable pageable, - SearchFilterReqDto dto) { - log.info("핫한 셀럽들이 선택한 여름나기 아이템 조회"); - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getSummerItem(user, pageable, dto)) - .build() - ); - } - - @Operation(summary = "*지금 당장 구매가능한 아이템 조회", - description = "User 토큰 필요. Pagination 적용. Filtering -> Category, Price, Color") - @GetMapping("/nowBuy") - public ResponseEntity>> getNowBuyItem( - @AuthenticationPrincipal User user, - Pageable pageable, - SearchFilterReqDto dto) { - log.info("지금 당장 구매가능한 아이템 조회"); - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getNowBuyItem(user, pageable, dto)) - .build() - ); - } - - @Operation(summary = "*실시간 뉴 아이템 조회", description = "WhenDiscovery 기준 아이템 조회. User 토큰 필요. Pagination 적용.") - @GetMapping("/new") - public ResponseEntity>> getNewItem( - @AuthenticationPrincipal User user, - Pageable pageable) { - log.info("최신 등록 아이템 조회"); - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getNewItem(user, pageable)) - .build() - ); - } - - @Operation(summary = "*주목해야할 럭셔리 무드 아이템 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/luxury") - public ResponseEntity>> getLuxuryItem( - @AuthenticationPrincipal User user, - Pageable pageable, - SearchFilterReqDto dto) { - log.info("주목해야할 럭셔리 무드 아이템 조회"); - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getLuxuryItem(user, pageable, dto)) - .build() - ); - } - - @Operation(summary = "*가성비 좋은 선물 아이템 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/efficient") - public ResponseEntity>> getEfficientItem( - @AuthenticationPrincipal User user, - Pageable pageable, - SearchFilterReqDto filterReqDto) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getEfficientItem(user, pageable, filterReqDto)) - .build() - ); - } - - @Deprecated - @Operation(summary = "*일간/주간 HOT 아이템 조회", description = "User 토큰 필요. 정적으로 21개 조회.") - @GetMapping("/hotItem") - public ResponseEntity>> getHotItem(@AuthenticationPrincipal User user, - @RequestParam("standard") String standard) { - log.info("일간 주간 핫 아이템 조회: {}", standard); - List result; - if (standard.equals("주간")) { - result = itemService.getWeekHotItem(user); - } else if (standard.equals("일간")) { - result = itemService.getDayHotItem(user); - } else { - throw new StandardNotFoundException(); - } - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(result) - .build() - ); - } - - /** - * 셀럽 변경은 백오피스 개발시 다시 적용 예정 - */ - @Operation(summary = "*요즘 Hot Celeb의 아이템 조회", - description = "User 토큰 필요. Pagination 적용. Filtering 적용. Ordering 적용.") - @GetMapping("/hotCeleb") - public ResponseEntity>> getHotCelebItem( - @AuthenticationPrincipal User user, Pageable pageable, SearchFilterReqDto dto) { - log.info("요즘 핫셀럽 아이템 조회"); - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getHotCelebItem(user, pageable, dto)) - .build() - ); - } - - /** - * 현재 실시간 -> 24시간 기준 추가 예정 10개가 안되면 최신순으로 랜덤으로 채우기 - */ - @Operation(summary = "*큐레이션 아이템 조회", - description = "오늘 올라온 관심 셀럽의 아이템을 인기 순으로 검색. User 토큰 필요. 정적으로 10개.") - @GetMapping("/curation") - public ResponseEntity>> getCurationItem( - @AuthenticationPrincipal User user) { - log.info("큐레이션 아이템 조회"); - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getCurationItem(user)) - .build() - ); - } - - /** - * 전체 아이템 중 랜덤으로 4개 조회, 홈 회면 접속 할 때마다 리프레쉬 - */ - @Operation(summary = "*이 아이템은 어때요 아이템 조회", description = "User 토큰 필요.") - @GetMapping("/howabout") - public ResponseEntity>> getHowAboutItem( - @AuthenticationPrincipal User user) { - log.info("이 아이템은 어때요 아이템 조회"); - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(itemService.getHowAboutItem(user)) - .build() - ); - } -} diff --git a/src/main/java/com/sluv/server/domain/item/controller/TempItemController.java b/src/main/java/com/sluv/server/domain/item/controller/TempItemController.java deleted file mode 100644 index eefea485..00000000 --- a/src/main/java/com/sluv/server/domain/item/controller/TempItemController.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.sluv.server.domain.item.controller; - -import com.sluv.server.domain.item.dto.TempItemCountResDto; -import com.sluv.server.domain.item.dto.TempItemPostReqDto; -import com.sluv.server.domain.item.dto.TempItemPostResDto; -import com.sluv.server.domain.item.dto.TempItemResDto; -import com.sluv.server.domain.item.service.TempItemService; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationCountResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; -import io.swagger.v3.oas.annotations.Operation; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Pageable; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequiredArgsConstructor -@RequestMapping("/app/item/temp") -@Slf4j -public class TempItemController { - private final TempItemService tempItemService; - - @Operation(summary = "*임시저장 아이템 리스트 조회", description = "User 토큰 필요") - @GetMapping("") - public ResponseEntity>> getTempItemList( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(tempItemService.getTempItemList(user, pageable)) - .build() - ); - } - - @Operation(summary = "*임시저장 아이템 갯수 조회", description = "User 토큰 필요") - @GetMapping("/count") - public ResponseEntity> getTempItemCount( - @AuthenticationPrincipal User user) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(tempItemService.countTempItemCount(user)) - .build() - ); - } - - @Operation(summary = "*Item 임시저장", description = "User 토큰 필요") - @PostMapping("") - public ResponseEntity> postTempItem(@AuthenticationPrincipal User user, - @RequestBody TempItemPostReqDto reqDto) { - - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result( - TempItemPostResDto.of( - tempItemService.postTempItem(user, reqDto) - ) - ) - .build() - ); - } - - @Operation(summary = "임시저장 아이템 선택삭제", description = "User 토큰 필요") - @DeleteMapping("/{tempItemId}") - public ResponseEntity deleteTempItem(@PathVariable Long tempItemId) { - tempItemService.deleteTempItem(tempItemId); - return ResponseEntity.ok().body(new SuccessResponse()); - } - - @Operation(summary = "*임시저장 아이템 전체삭제", description = "User 토큰 필요") - @DeleteMapping("") - public ResponseEntity deleteAllTempItem(@AuthenticationPrincipal User user) { - tempItemService.deleteAllTempItem(user.getId()); - return ResponseEntity.ok().body(new SuccessResponse()); - } -} diff --git a/src/main/java/com/sluv/server/domain/item/exception/ItemException.java b/src/main/java/com/sluv/server/domain/item/exception/ItemException.java deleted file mode 100644 index 00e6140b..00000000 --- a/src/main/java/com/sluv/server/domain/item/exception/ItemException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.item.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class ItemException extends ApplicationException { - public ItemException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/item/exception/hashtag/HashtagException.java b/src/main/java/com/sluv/server/domain/item/exception/hashtag/HashtagException.java deleted file mode 100644 index 9e7ddcaf..00000000 --- a/src/main/java/com/sluv/server/domain/item/exception/hashtag/HashtagException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.item.exception.hashtag; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class HashtagException extends ApplicationException { - public HashtagException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/item/helper/ItemHelper.java b/src/main/java/com/sluv/server/domain/item/helper/ItemHelper.java deleted file mode 100644 index 8acf8f74..00000000 --- a/src/main/java/com/sluv/server/domain/item/helper/ItemHelper.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.sluv.server.domain.item.helper; - -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.closet.repository.ClosetRepository; -import com.sluv.server.domain.comment.dto.CommentItemResDto; -import com.sluv.server.domain.comment.entity.CommentItem; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.ItemImg; -import com.sluv.server.domain.item.repository.ItemImgRepository; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.item.repository.ItemScrapRepository; -import com.sluv.server.domain.user.entity.User; -import java.util.ArrayList; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - -@Component -@RequiredArgsConstructor -public class ItemHelper { - - private final ItemImgRepository itemImgRepository; - private final ItemScrapRepository itemScrapRepository; - private final ClosetRepository closetRepository; - private final ItemRepository itemRepository; - - public ItemSimpleResDto convertItemToSimpleResDto(Item item, User user) { - List closetList = closetRepository.findAllByUserId(user.getId()); -// itemRepository.getItemSimpleResDto(user, ) - return ItemSimpleResDto.of(item, itemImgRepository.findMainImg(item.getId()), - itemScrapRepository.getItemScrapStatus(item, closetList)); - } - - /** - * CommentItem -> CommentItemResDto 변경하는 메소드 - * - * @param commentItem - * @return CommentItemResDto - */ - public CommentItemResDto getCommentItemResDto(CommentItem commentItem, User user) { - ItemImg mainImg = itemImgRepository.findMainImg(commentItem.getItem().getId()); - List closetList = new ArrayList<>(); - if (user != null) { - closetList = closetRepository.findAllByUserId(user.getId()); - } - Boolean itemScrapStatus = itemScrapRepository.getItemScrapStatus(commentItem.getItem(), closetList); - - return CommentItemResDto.of(commentItem, mainImg, itemScrapStatus); - } -} diff --git a/src/main/java/com/sluv/server/domain/item/repository/ItemReportRepository.java b/src/main/java/com/sluv/server/domain/item/repository/ItemReportRepository.java deleted file mode 100644 index da5b119f..00000000 --- a/src/main/java/com/sluv/server/domain/item/repository/ItemReportRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.sluv.server.domain.item.repository; - -import com.sluv.server.domain.item.entity.ItemReport; -import com.sluv.server.domain.item.repository.impl.ItemReportRepositoryCustom; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface ItemReportRepository extends JpaRepository, ItemReportRepositoryCustom { - -} diff --git a/src/main/java/com/sluv/server/domain/item/repository/TempItemLinkRepository.java b/src/main/java/com/sluv/server/domain/item/repository/TempItemLinkRepository.java deleted file mode 100644 index 2a69b58b..00000000 --- a/src/main/java/com/sluv/server/domain/item/repository/TempItemLinkRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.sluv.server.domain.item.repository; - -import com.sluv.server.domain.item.entity.TempItem; -import com.sluv.server.domain.item.entity.TempItemLink; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface TempItemLinkRepository extends JpaRepository { - List findAllByTempItem(TempItem tempItem); - - void deleteAllByTempItemId(Long id); -} diff --git a/src/main/java/com/sluv/server/domain/item/repository/hashtag/TempItemHashtagRepository.java b/src/main/java/com/sluv/server/domain/item/repository/hashtag/TempItemHashtagRepository.java deleted file mode 100644 index 91baddcc..00000000 --- a/src/main/java/com/sluv/server/domain/item/repository/hashtag/TempItemHashtagRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.sluv.server.domain.item.repository.hashtag; - -import com.sluv.server.domain.item.entity.TempItem; -import com.sluv.server.domain.item.entity.hashtag.TempItemHashtag; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface TempItemHashtagRepository extends JpaRepository { - List findAllByTempItem(TempItem tempItem); - - void deleteAllByTempItemId(Long id); -} diff --git a/src/main/java/com/sluv/server/domain/item/repository/hashtag/impl/HashtagRepositoryCustom.java b/src/main/java/com/sluv/server/domain/item/repository/hashtag/impl/HashtagRepositoryCustom.java deleted file mode 100644 index 289d22d2..00000000 --- a/src/main/java/com/sluv/server/domain/item/repository/hashtag/impl/HashtagRepositoryCustom.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.sluv.server.domain.item.repository.hashtag.impl; - -import com.querydsl.core.Tuple; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -public interface HashtagRepositoryCustom { - Page findAllByContent(String name, Pageable pageable); -} diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemImgRepositoryCustom.java b/src/main/java/com/sluv/server/domain/item/repository/impl/ItemImgRepositoryCustom.java deleted file mode 100644 index 91d811de..00000000 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemImgRepositoryCustom.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.sluv.server.domain.item.repository.impl; - -import com.sluv.server.domain.item.entity.ItemImg; - -public interface ItemImgRepositoryCustom { - ItemImg findMainImg(Long itemId); -} diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemReportRepositoryCustom.java b/src/main/java/com/sluv/server/domain/item/repository/impl/ItemReportRepositoryCustom.java deleted file mode 100644 index 7a6e9202..00000000 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemReportRepositoryCustom.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sluv.server.domain.item.repository.impl; - -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.user.entity.User; - -public interface ItemReportRepositoryCustom { - Boolean findExistence(User user, Item target); -} diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemScrapRepositoryCustom.java b/src/main/java/com/sluv/server/domain/item/repository/impl/ItemScrapRepositoryCustom.java deleted file mode 100644 index 1f524509..00000000 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/ItemScrapRepositoryCustom.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.sluv.server.domain.item.repository.impl; - -import com.querydsl.core.types.dsl.BooleanExpression; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.item.entity.Item; - -import java.util.List; - -public interface ItemScrapRepositoryCustom { - Boolean getItemScrapStatus(Item item, List closetList); -} diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/PlaceRankRepositoryCustom.java b/src/main/java/com/sluv/server/domain/item/repository/impl/PlaceRankRepositoryCustom.java deleted file mode 100644 index b8b88739..00000000 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/PlaceRankRepositoryCustom.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.item.repository.impl; - -import com.sluv.server.domain.item.entity.PlaceRank; -import com.sluv.server.domain.user.entity.User; - -import java.util.List; - -public interface PlaceRankRepositoryCustom { - List getRecentPlaceTop20(User user); -} diff --git a/src/main/java/com/sluv/server/domain/item/repository/impl/TempItemRepositoryImpl.java b/src/main/java/com/sluv/server/domain/item/repository/impl/TempItemRepositoryImpl.java deleted file mode 100644 index 7f644975..00000000 --- a/src/main/java/com/sluv/server/domain/item/repository/impl/TempItemRepositoryImpl.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.sluv.server.domain.item.repository.impl; - -import static com.sluv.server.domain.brand.entity.QBrand.brand; -import static com.sluv.server.domain.brand.entity.QNewBrand.newBrand; -import static com.sluv.server.domain.celeb.entity.QCeleb.celeb; -import static com.sluv.server.domain.celeb.entity.QCelebCategory.celebCategory; -import static com.sluv.server.domain.celeb.entity.QNewCeleb.newCeleb; -import static com.sluv.server.domain.item.entity.QItemCategory.itemCategory; -import static com.sluv.server.domain.item.entity.QTempItem.tempItem; -import static com.sluv.server.domain.item.entity.QTempItemImg.tempItemImg; -import static com.sluv.server.domain.item.entity.QTempItemLink.tempItemLink; -import static com.sluv.server.domain.item.entity.hashtag.QHashtag.hashtag; -import static com.sluv.server.domain.item.entity.hashtag.QTempItemHashtag.tempItemHashtag; - -import com.querydsl.jpa.impl.JPAQuery; -import com.querydsl.jpa.impl.JPAQueryFactory; -import com.sluv.server.domain.celeb.entity.QCeleb; -import com.sluv.server.domain.celeb.entity.QCelebCategory; -import com.sluv.server.domain.item.dto.ItemHashtagResponseDto; -import com.sluv.server.domain.item.dto.ItemImgResDto; -import com.sluv.server.domain.item.dto.ItemLinkResDto; -import com.sluv.server.domain.item.dto.TempItemResDto; -import com.sluv.server.domain.item.entity.QItemCategory; -import com.sluv.server.domain.item.entity.TempItem; -import com.sluv.server.domain.item.entity.TempItemImg; -import com.sluv.server.domain.item.entity.TempItemLink; -import com.sluv.server.domain.item.entity.hashtag.Hashtag; -import com.sluv.server.domain.item.entity.hashtag.TempItemHashtag; -import com.sluv.server.domain.user.entity.User; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.support.PageableExecutionUtils; - -@RequiredArgsConstructor -public class TempItemRepositoryImpl implements TempItemRepositoryCustom { - - private final JPAQueryFactory jpaQueryFactory; - - @Override - public Page getTempItemList(User user, Pageable pageable) { - QCeleb parent = new QCeleb("parent"); - QCelebCategory parentCelebCategory = new QCelebCategory("parentCelebCategory"); - QItemCategory parentItemCategory = new QItemCategory("parentItemCategory"); - - List content = jpaQueryFactory.selectFrom(tempItem).leftJoin(tempItem.celeb, celeb).fetchJoin() - .leftJoin(celeb.parent, parent).fetchJoin().leftJoin(celeb.celebCategory, celebCategory).fetchJoin() - .leftJoin(celebCategory.parent, parentCelebCategory).fetchJoin() - .leftJoin(tempItem.category, itemCategory).fetchJoin().leftJoin(itemCategory.parent, parentItemCategory) - .fetchJoin().leftJoin(tempItem.brand, brand).fetchJoin().leftJoin(tempItem.newCeleb, newCeleb) - .fetchJoin().leftJoin(tempItem.newBrand, newBrand).fetchJoin().where(tempItem.user.eq(user)) - .offset(pageable.getOffset()).limit(pageable.getPageSize()).orderBy(tempItem.updatedAt.desc()).fetch(); - - JPAQuery countContent = jpaQueryFactory.selectFrom(tempItem).where(tempItem.user.eq(user)); - - return PageableExecutionUtils.getPage(content, pageable, () -> countContent.fetch().size()); - } - - @Override - public List findAllExceptLast(Long userId) { - - return jpaQueryFactory.selectFrom(tempItem) - .where(tempItem.user.id.eq(userId)) - .orderBy(tempItem.updatedAt.desc()) - .offset(1).fetch(); - } - - @Override - public List getTempItemResDto(List content) { - List tempItemIds = content.stream().map(TempItem::getId).toList(); - List tempItemImgs = jpaQueryFactory.selectFrom(tempItemImg) - .where(tempItemImg.tempItem.id.in(tempItemIds)).fetch(); - - List tempItemLinks = jpaQueryFactory.selectFrom(tempItemLink) - .where(tempItemLink.tempItem.id.in(tempItemIds)).fetch(); - - List tempItemHashtags = jpaQueryFactory.selectFrom(tempItemHashtag) - .leftJoin(tempItemHashtag.hashtag, hashtag).fetchJoin() - .where(tempItemHashtag.tempItem.id.in(tempItemIds)).fetch(); - - Map> tempItemImgMap = tempItemImgs.stream().collect( - Collectors.groupingBy(ti -> ti.getTempItem().getId(), - Collectors.mapping(ItemImgResDto::of, Collectors.toList()))); - - Map> tempItemLinkMap = tempItemLinks.stream().collect( - Collectors.groupingBy(tl -> tl.getTempItem().getId(), - Collectors.mapping(ItemLinkResDto::of, Collectors.toList()))); - - Map> tempItemHashtagMap = tempItemHashtags.stream().collect( - Collectors.groupingBy(th -> th.getTempItem().getId(), - Collectors.mapping(TempItemHashtag::getHashtag, Collectors.toList()))); - - return content.stream().map(ti -> { - List hashtags = null; - if (tempItemHashtagMap.get(ti.getId()) != null) { - hashtags = tempItemHashtagMap.get(ti.getId()).stream() - .map(ItemHashtagResponseDto::of).toList(); - } - return TempItemResDto.of(ti, tempItemImgMap.get(ti.getId()), tempItemLinkMap.get(ti.getId()), hashtags); - }).toList(); - } -} - diff --git a/src/main/java/com/sluv/server/domain/item/service/HashtagService.java b/src/main/java/com/sluv/server/domain/item/service/HashtagService.java deleted file mode 100644 index 3ecab174..00000000 --- a/src/main/java/com/sluv/server/domain/item/service/HashtagService.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.sluv.server.domain.item.service; - -import com.querydsl.core.Tuple; -import com.sluv.server.domain.item.dto.HashtagPostResponseDto; -import com.sluv.server.domain.item.dto.HashtagRequestDto; -import com.sluv.server.domain.item.dto.HashtagResponseDto; -import com.sluv.server.domain.item.entity.hashtag.Hashtag; -import com.sluv.server.domain.item.repository.hashtag.HashtagRepository; -import com.sluv.server.global.common.response.PaginationResDto; -import java.util.List; -import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional -@RequiredArgsConstructor -public class HashtagService { - - private final HashtagRepository hashtagRepository; - - @Transactional(readOnly = true) - public PaginationResDto getHashtag(String name, Pageable pageable) { - Page hashtagPage = hashtagRepository.findAllByContent(name, pageable); - List dtoList = hashtagPage - .stream().map(data -> - HashtagResponseDto.of(data.get(0, Hashtag.class), data.get(1, Long.class)) - ).toList(); - - return PaginationResDto.of(hashtagPage, dtoList); - } - - public HashtagPostResponseDto postHashtag(HashtagRequestDto requestDto) { - - // 해당 Hashtag가 있는지 검색 - Optional hashtag = hashtagRepository.findByContent(requestDto.getHashtagContent()); - - //있다면 해당 Hashtag를 반환 - if (hashtag.isPresent()) { - return HashtagPostResponseDto.of(hashtag.get()); - } else { // 없다면 등록 후 반환 - Hashtag save = hashtagRepository.save(Hashtag.toEntity(requestDto.getHashtagContent())); - return HashtagPostResponseDto.of(save); - } - - } - -} diff --git a/src/main/java/com/sluv/server/domain/item/service/ItemEditReqService.java b/src/main/java/com/sluv/server/domain/item/service/ItemEditReqService.java deleted file mode 100644 index dbcb3a48..00000000 --- a/src/main/java/com/sluv/server/domain/item/service/ItemEditReqService.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.sluv.server.domain.item.service; - -import com.sluv.server.domain.alarm.service.ItemAlarmService; -import com.sluv.server.domain.item.dto.ItemEditReqDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.ItemEditReq; -import com.sluv.server.domain.item.exception.ItemNotFoundException; -import com.sluv.server.domain.item.repository.ItemEditReqRepository; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.user.entity.User; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional -@RequiredArgsConstructor -public class ItemEditReqService { - private final ItemEditReqRepository itemEditReqRepository; - private final ItemRepository itemRepository; - private final ItemAlarmService itemAlarmService; - - public void postItemEdit(User user, Long itemId, ItemEditReqDto dto) { - Item item = itemRepository.findById(itemId).orElseThrow(ItemNotFoundException::new); - ItemEditReq itemEditReq = itemEditReqRepository.save(ItemEditReq.toEntity(user, item, dto)); - itemAlarmService.sendAlarmAboutItemEdit(item.getId(), itemEditReq.getId(), user); - - } -} diff --git a/src/main/java/com/sluv/server/domain/item/service/ItemReportService.java b/src/main/java/com/sluv/server/domain/item/service/ItemReportService.java deleted file mode 100644 index 336978bb..00000000 --- a/src/main/java/com/sluv/server/domain/item/service/ItemReportService.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.sluv.server.domain.item.service; - -import com.sluv.server.domain.item.dto.ItemReportReqDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.ItemReport; -import com.sluv.server.domain.item.exception.ItemNotFoundException; -import com.sluv.server.domain.item.exception.ItemReportDuplicateException; -import com.sluv.server.domain.item.repository.ItemReportRepository; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.user.entity.User; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional -@RequiredArgsConstructor -public class ItemReportService { - private final ItemReportRepository itemReportRepository; - private final ItemRepository itemRepository; - - - public void postItemReport(User user, Long itemId, ItemReportReqDto dto) { - // 신고대상 Item 검색. - Item item = itemRepository.findById(itemId).orElseThrow(ItemNotFoundException::new); - - // 신고 중복여부 확인 - boolean existence = itemReportRepository.findExistence(user, item); - - // 중복 신고라면 Exception 발생 - if (existence) { - throw new ItemReportDuplicateException(); - } else { - // 중복이 아니라면 신고 접수 - itemReportRepository.save(ItemReport.toEntity(item, user, dto)); - } - } -} diff --git a/src/main/java/com/sluv/server/domain/item/service/ItemService.java b/src/main/java/com/sluv/server/domain/item/service/ItemService.java deleted file mode 100644 index 73430715..00000000 --- a/src/main/java/com/sluv/server/domain/item/service/ItemService.java +++ /dev/null @@ -1,509 +0,0 @@ -package com.sluv.server.domain.item.service; - -import static com.sluv.server.domain.item.enums.ItemStatus.ACTIVE; - -import com.sluv.server.domain.alarm.service.ItemAlarmService; -import com.sluv.server.domain.brand.dto.BrandSearchResDto; -import com.sluv.server.domain.brand.entity.Brand; -import com.sluv.server.domain.brand.entity.NewBrand; -import com.sluv.server.domain.brand.exception.BrandNotFoundException; -import com.sluv.server.domain.brand.exception.NewBrandNotFoundException; -import com.sluv.server.domain.brand.repository.BrandRepository; -import com.sluv.server.domain.brand.repository.NewBrandRepository; -import com.sluv.server.domain.celeb.dto.CelebSearchResDto; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.celeb.exception.CelebNotFoundException; -import com.sluv.server.domain.celeb.exception.NewCelebNotFoundException; -import com.sluv.server.domain.celeb.repository.CelebRepository; -import com.sluv.server.domain.celeb.repository.NewCelebRepository; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.closet.repository.ClosetRepository; -import com.sluv.server.domain.item.dto.HotPlaceResDto; -import com.sluv.server.domain.item.dto.ItemCategoryDto; -import com.sluv.server.domain.item.dto.ItemDetailFixData; -import com.sluv.server.domain.item.dto.ItemDetailResDto; -import com.sluv.server.domain.item.dto.ItemHashtagResponseDto; -import com.sluv.server.domain.item.dto.ItemImgResDto; -import com.sluv.server.domain.item.dto.ItemLinkResDto; -import com.sluv.server.domain.item.dto.ItemPostReqDto; -import com.sluv.server.domain.item.dto.ItemPostResDto; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.ItemCategory; -import com.sluv.server.domain.item.entity.ItemImg; -import com.sluv.server.domain.item.entity.ItemLike; -import com.sluv.server.domain.item.entity.ItemLink; -import com.sluv.server.domain.item.entity.RecentItem; -import com.sluv.server.domain.item.entity.hashtag.ItemHashtag; -import com.sluv.server.domain.item.enums.ItemStatus; -import com.sluv.server.domain.item.exception.ItemCategoryNotFoundException; -import com.sluv.server.domain.item.exception.ItemNotActiveException; -import com.sluv.server.domain.item.exception.ItemNotFoundException; -import com.sluv.server.domain.item.exception.hashtag.HashtagNotFoundException; -import com.sluv.server.domain.item.repository.ItemCategoryRepository; -import com.sluv.server.domain.item.repository.ItemImgRepository; -import com.sluv.server.domain.item.repository.ItemLikeRepository; -import com.sluv.server.domain.item.repository.ItemLinkRepository; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.item.repository.ItemScrapRepository; -import com.sluv.server.domain.item.repository.RecentItemRepository; -import com.sluv.server.domain.item.repository.hashtag.HashtagRepository; -import com.sluv.server.domain.item.repository.hashtag.ItemHashtagRepository; -import com.sluv.server.domain.search.dto.SearchFilterReqDto; -import com.sluv.server.domain.user.dto.UserInfoDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.repository.FollowRepository; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.ai.AiModelService; -import com.sluv.server.global.cache.CacheService; -import com.sluv.server.global.common.enums.ItemImgOrLinkStatus; -import com.sluv.server.global.common.response.PaginationResDto; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Random; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Slf4j -@RequiredArgsConstructor -public class ItemService { - private final ItemRepository itemRepository; - private final ItemImgRepository itemImgRepository; - private final ItemLinkRepository itemLinkRepository; - private final ItemHashtagRepository itemHashtagRepository; - private final HashtagRepository hashtagRepository; - private final CelebRepository celebRepository; - private final ItemCategoryRepository itemCategoryRepository; - private final BrandRepository brandRepository; - private final UserRepository userRepository; - private final RecentItemRepository recentItemRepository; - - private final NewBrandRepository newBrandRepository; - private final NewCelebRepository newCelebRepository; - - private final ItemLikeRepository itemLikeRepository; - private final FollowRepository followRepository; - private final ClosetRepository closetRepository; - private final ItemScrapRepository itemScrapRepository; - - private final AiModelService aiModelService; - private final CacheService cacheService; - private final ItemAlarmService itemAlarmService; - - @Transactional - public ItemPostResDto postItem(User user, ItemPostReqDto reqDto) { - - if (reqDto.getId() != null) { - cacheService.deleteItemDetailFixDataByItemId(reqDto.getId()); - } - - // 추가될 Celeb 확인 - Celeb celeb = null; - if (reqDto.getCelebId() != null) { - celeb = celebRepository.findById(reqDto.getCelebId()) - .orElseThrow(CelebNotFoundException::new); - } - - // 추가될 Brand 확인 - Brand brand = null; - if (reqDto.getBrandId() != null) { - brand = brandRepository.findById(reqDto.getBrandId()) - .orElseThrow(BrandNotFoundException::new); - } - - // 추가될 NewCeleb 확인 - NewCeleb newCeleb = null; - if (reqDto.getNewCelebId() != null) { - newCeleb = newCelebRepository.findById(reqDto.getNewCelebId()) - .orElseThrow(NewCelebNotFoundException::new); - } - - // 추가될 NewBrand 확인 - NewBrand newBrand = null; - if (reqDto.getNewBrandId() != null) { - newBrand = newBrandRepository.findById(reqDto.getNewBrandId()) - .orElseThrow(NewBrandNotFoundException::new); - } - - // 추가될 Category 확인 - ItemCategory itemCategory = itemCategoryRepository.findById(reqDto.getCategoryId()) - .orElseThrow(ItemCategoryNotFoundException::new); - - // Item을 등록인지 수정인지 판단. - Item item = - reqDto.getId() != null ? itemRepository.findById(reqDto.getId()).orElseThrow(ItemNotFoundException::new) - : null; - - Item postItem; - // Item 수정이라면, 기존의 Item의 Id를 추가. - if (item != null) { - postItem = Item.toEntity(item.getId(), user, celeb, newCeleb, itemCategory, brand, newBrand, reqDto, - item.getViewNum()); - } else { - // Item 생성 - postItem = Item.toEntity(user, celeb, newCeleb, itemCategory, brand, newBrand, reqDto); - } - - // 완성된 Item save - Item newItem = itemRepository.save(postItem); - - // 기존의 Img, Link, Hashtag가 있다면 모두 삭제 - itemImgRepository.deleteAllByItemId(newItem.getId()); - itemLinkRepository.deleteAllByItemId(newItem.getId()); - itemHashtagRepository.deleteAllByItemId(newItem.getId()); - - // ItemImg 테이블에 추가 - reqDto.getImgList().stream() - .map(itemImg -> - ItemImg.toEntity(newItem, itemImg) - ).forEach(itemImgRepository::save); - - // ItemLink 테이블에 추가 - if (reqDto.getLinkList() != null) { - reqDto.getLinkList().stream() - .map(itemLink -> - ItemLink.builder() - .item(newItem) - .linkName(itemLink.getLinkName()) - .itemLinkUrl(itemLink.getItemLinkUrl()) - .itemImgOrLinkStatus(ItemImgOrLinkStatus.ACTIVE) - .build() - - ).forEach(itemLinkRepository::save); - } - - // ItemHashtag 테이블에 추가 - if (reqDto.getHashTagIdList() != null) { - reqDto.getHashTagIdList().stream().map(hashTag -> - - ItemHashtag.toEntity( - newItem, - hashtagRepository.findById(hashTag) - .orElseThrow(HashtagNotFoundException::new) - ) - ).forEach(itemHashtagRepository::save); - } - - aiModelService.getItemColor(newItem); - - if (reqDto.getId() == null) { // 새 아이템 등록 시 - itemAlarmService.sendAlarmAboutFollowItem(user.getId(), newItem.getId()); - } - - return ItemPostResDto.of(newItem.getId()); - } - - @Transactional(readOnly = true) - public List getTopPlace() { - - return itemRepository.findTopPlace().stream() - .map(HotPlaceResDto::of).toList(); - } - - @Transactional - public ItemDetailResDto getItemDetail(User user, Long itemId) { - // 1. Item 조회 - Item item = itemRepository.findById(itemId) - .orElseThrow(ItemNotFoundException::new); - - if (item.getItemStatus() != ACTIVE) { - log.error("ItemId: {}'s status: {}", itemId, item.getItemStatus()); - throw new ItemNotActiveException(); - } - - // 2. Item Detail 고정 데이터 조회 -> Cache Aside - ItemDetailFixData fixData = cacheService.findItemDetailFixDataByItemId(itemId); - if (fixData == null) { - fixData = getItemDetailFixData(item); - cacheService.saveItemDetailFixData(itemId, fixData); - } - - // 3. 좋아요 수 - Integer likeNum = itemLikeRepository.countByItemId(item.getId()); - - // 4. 스크랩 수 - Integer scrapNum = itemScrapRepository.countByItemId(item.getId()); - - List closetList = new ArrayList<>(); - - if (user != null) { - // 5. 최근 본 아이템 등록 - recentItemRepository.save(RecentItem.of(item, user)); - - // 6. 조회수 - increaseViewNum(user.getId(), item); - - // 7. 스크랩 여부 - closetList = closetRepository.findAllByUserId(user.getId()); - } - - boolean scrapStatus = itemScrapRepository.getItemScrapStatus(item, closetList); - - // 8. 좋아요 여부 - boolean likeStatus = user != null && itemLikeRepository.existsByUserIdAndItemId(user.getId(), itemId); - - // 9. 팔로우 여부 - boolean followStatus = followRepository.getFollowStatus(user, fixData.getWriter().getId()); - - // 10. 본인의 게시글 여부 - boolean hasMine = user != null && item.getUser().getId().equals(user.getId()); - - // Dto 조립 - return ItemDetailResDto.of( - item, - fixData.getCeleb(), - fixData.getNewCeleb(), - fixData.getBrand(), - fixData.getNewBrand(), - fixData.getCategory(), - likeNum, - likeStatus, - scrapNum, - scrapStatus, - item.getViewNum(), - fixData.getWriter(), - followStatus, - hasMine, - fixData.getImgList(), - fixData.getLinkList(), - fixData.getHashTagList() - ); - } - - private void increaseViewNum(Long userId, Item item) { - boolean isExist = cacheService.existUserViewItemId(userId, item.getId()); - if (!isExist) { - cacheService.saveUserViewItemId(userId, item.getId()); - item.increaseViewNum(); - } - } - - // @Cacheable(cacheNames = "item", key = "#itemId") - public ItemDetailFixData getItemDetailFixData(Item item) { - Long itemId = item.getId(); - - // 1. Item Category - ItemCategoryDto category = ItemCategoryDto.of(item.getCategory()); - - // 2. Item Celeb - CelebSearchResDto celeb = item.getCeleb() != null - ? CelebSearchResDto.of(item.getCeleb()) - : null; - - // 3. Brand - BrandSearchResDto brand = item.getBrand() != null ? - BrandSearchResDto.of(item.getBrand()) - : null; - - // 4. 작성자 info - User writer = userRepository.findById(item.getUser().getId()) - .orElse(null); - UserInfoDto writerInfo = UserInfoDto.of(writer); - - // 5. Item 이미지들 조회 - List imgList = itemImgRepository.findAllByItemId(itemId) - .stream() - .map(ItemImgResDto::of).toList(); - - // 6. Item 링크들 조회 - List linkList = itemLinkRepository.findByItemId(itemId) - .stream() - .map(ItemLinkResDto::of).toList(); - - // 7. Hashtag - List itemHashtags = itemHashtagRepository.findAllByItemId(itemId) - .stream() - .map(itemHashtag -> - ItemHashtagResponseDto.of(itemHashtag.getHashtag()) - ).toList(); - - return ItemDetailFixData.of(item, celeb, item.getNewCeleb(), brand, item.getNewBrand(), category, writerInfo, - imgList, linkList, itemHashtags); - } - - @Transactional - public void postItemLike(User user, Long itemId) { - Item item = itemRepository.findById(itemId).orElseThrow(ItemNotFoundException::new); - - boolean likeExist = itemLikeRepository.existsByUserIdAndItemId(user.getId(), itemId); - if (!likeExist) { - itemLikeRepository.save(ItemLike.toEntity(item, user)); - itemAlarmService.sendAlarmAboutItemLike(user.getId(), itemId); - } else { - itemLikeRepository.deleteByUserIdAndItemId(user.getId(), itemId); - } - - } - - @Transactional - public void deleteItem(Long itemId) { - Item item = itemRepository.findById(itemId).orElseThrow(ItemNotFoundException::new); - - item.changeStatus(ItemStatus.DELETED); - itemRepository.save(item); - cacheService.deleteItemDetailFixDataByItemId(itemId); - } - - @Transactional(readOnly = true) - public PaginationResDto getRecentItem(User user, Pageable pageable) { - Page recentItemPage = itemRepository.getRecentItem(user, pageable); - List itemSimpleResDtos = itemRepository.getItemSimpleResDto(user, - recentItemPage.getContent()); - return PaginationResDto.of(recentItemPage, itemSimpleResDtos); - - } - - @Transactional(readOnly = true) - public PaginationResDto getScrapItem(User user, Pageable pageable) { - // User, Closet, Item 조인하여 ItemPage 조회 - Page itemPage = itemRepository.getAllScrapItem(user, pageable); - List itemSimpleResDtos = itemRepository.getItemSimpleResDto(user, itemPage.getContent()); - return PaginationResDto.of(itemPage, itemSimpleResDtos); - } - - @Transactional(readOnly = true) - public PaginationResDto getRecommendItem(User user, Pageable pageable) { - Page recommendItemPage = itemRepository.getRecommendItemPage(pageable); - - List content = - itemRepository.getItemSimpleResDto(user, recommendItemPage.getContent()); - - return PaginationResDto.of(recommendItemPage, content); - } - - /** - * 핫한 셀럽들이 선택한 여름나기 아이템 조회 - */ - @Transactional(readOnly = true) - public PaginationResDto getSummerItem(User user, Pageable pageable, SearchFilterReqDto dto) { - // itemPage 조회 - Page itemPage = itemRepository.getCelebSummerItem(pageable, dto); - // Content 조립 - List content = itemRepository.getItemSimpleResDto(user, itemPage.getContent()); - - return PaginationResDto.of(itemPage, content); - } - - /** - * 지금 당장 구매가능한 아이템 조회 - */ - @Transactional(readOnly = true) - public PaginationResDto getNowBuyItem(User user, Pageable pageable, SearchFilterReqDto dto) { - Page itemPage = itemRepository.getNowBuyItem(pageable, dto); - List content = itemRepository.getItemSimpleResDto(user, itemPage.getContent()); - return PaginationResDto.of(itemPage, content); - } - - @Transactional(readOnly = true) - public PaginationResDto getNewItem(User user, Pageable pageable) { - // itemPage 조회 - Page itemPage = itemRepository.getNewItem(pageable); - - // Content 조립 - List content = itemRepository.getItemSimpleResDto(user, itemPage.getContent()); - - return PaginationResDto.of(itemPage, content); - } - - @Transactional(readOnly = true) - public PaginationResDto getLuxuryItem(User user, Pageable pageable, SearchFilterReqDto dto) { - Page itemPage = itemRepository.getLuxuryItem(pageable, dto); - List content = itemRepository.getItemSimpleResDto(user, itemPage.getContent()); - return PaginationResDto.of(itemPage, content); - } - - @Transactional(readOnly = true) - public PaginationResDto getEfficientItem(User user, Pageable pageable, - SearchFilterReqDto filterReqDto) { - Page itemPage = itemRepository.getEfficientItem(pageable, filterReqDto); - List content = itemRepository.getItemSimpleResDto(user, itemPage.getContent()); - return PaginationResDto.of(itemPage, content); - } - - @Transactional(readOnly = true) - public List getWeekHotItem(User user) { - List itemPage = itemRepository.getWeekHotItem(); - return itemRepository.getItemSimpleResDto(user, itemPage); - } - - @Transactional(readOnly = true) - public List getDayHotItem(User user) { - List itemPage = itemRepository.getDayHotItem(); - return itemRepository.getItemSimpleResDto(user, itemPage); - } - - /** - * 요즘 핫한 셀럽의 Item 조회 - */ - @Transactional(readOnly = true) - public PaginationResDto getHotCelebItem(User user, Pageable pageable, SearchFilterReqDto dto) { - Long celebId = 510L; - - Page itemPage = itemRepository.getHotCelebItem(celebId, pageable, dto); - - List content = itemRepository.getItemSimpleResDto(user, itemPage.getContent()); - - return PaginationResDto.of(itemPage, content); - } - - @Transactional(readOnly = true) - public List getCurationItem(User user) { - List interestedCeleb; - if (user != null) { - interestedCeleb = celebRepository.findInterestedCeleb(user); - } else { - interestedCeleb = celebRepository.findTop10Celeb(); - } - List itemList = itemRepository.getCurationItem(user, interestedCeleb); - - return itemRepository.getItemSimpleResDto(user, itemList); - } - - @Transactional(readOnly = true) - public List getHowAboutItem(User user) { - List items = itemRepository.findAllByItemStatus(ACTIVE); - Collections.shuffle(items, new Random()); - return itemRepository.getItemSimpleResDto(user, items.subList(0, 4)); - } - - @Transactional(readOnly = true) - public List getSameCelebItems(User user, Long itemId) { - Item item = itemRepository.getItemByIdWithCelebAndBrand(itemId); - List sameCelebItems; - if (item.getCeleb() != null) { - sameCelebItems = itemRepository.findSameCelebItem(itemId, item.getCeleb().getId(), true); - } else { - sameCelebItems = itemRepository.findSameCelebItem(itemId, item.getNewCeleb().getId(), false); - } - - return itemRepository.getItemSimpleResDto(user, sameCelebItems); - } - - @Transactional(readOnly = true) - public List getSameBrandItem(User user, Long itemId) { - Item item = itemRepository.getItemByIdWithCelebAndBrand(itemId); - List sameBrandItems; - - if (item.getBrand() != null) { - sameBrandItems = itemRepository.findSameBrandItem(itemId, item.getBrand().getId(), true); - } else { - sameBrandItems = itemRepository.findSameBrandItem(itemId, item.getNewBrand().getId(), false); - } - - return itemRepository.getItemSimpleResDto(user, sameBrandItems); - } - - @Transactional(readOnly = true) - public List getTogetherScrapItem(User user, Long itemId) { - List recentAddClosetList = closetRepository.getRecentAddCloset(itemId); - List sameClosetItems = itemRepository.getSameClosetItems(itemId, recentAddClosetList); - return itemRepository.getItemSimpleResDto(user, sameClosetItems); - } -} diff --git a/src/main/java/com/sluv/server/domain/item/service/PlaceRankService.java b/src/main/java/com/sluv/server/domain/item/service/PlaceRankService.java deleted file mode 100644 index a84ab637..00000000 --- a/src/main/java/com/sluv/server/domain/item/service/PlaceRankService.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.sluv.server.domain.item.service; - -import com.sluv.server.domain.item.dto.PlaceRankReqDto; -import com.sluv.server.domain.item.dto.PlaceRankResDto; -import com.sluv.server.domain.item.entity.PlaceRank; -import com.sluv.server.domain.item.repository.PlaceRankRepository; -import com.sluv.server.domain.user.entity.User; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional -@RequiredArgsConstructor -public class PlaceRankService { - private final PlaceRankRepository placeRankRepository; - - public void postPlace(User user, PlaceRankReqDto dto) { - placeRankRepository.save( - PlaceRank.toEntity(user, dto) - ); - - } - - public void deleteAllPlace(User user) { - placeRankRepository.deleteAllByUserId(user.getId()); - } - - public void deletePlace(User user, String placeName) { - placeRankRepository.deleteByUserIdAndPlace(user.getId(), placeName); - } - - @Transactional(readOnly = true) - public List getRecentPlaceTop20(User user) { - return placeRankRepository.getRecentPlaceTop20(user) - .stream() - .map(PlaceRankResDto::of).toList(); - } -} diff --git a/src/main/java/com/sluv/server/domain/item/service/TempItemService.java b/src/main/java/com/sluv/server/domain/item/service/TempItemService.java deleted file mode 100644 index c01f293c..00000000 --- a/src/main/java/com/sluv/server/domain/item/service/TempItemService.java +++ /dev/null @@ -1,174 +0,0 @@ -package com.sluv.server.domain.item.service; - -import com.sluv.server.domain.brand.entity.Brand; -import com.sluv.server.domain.brand.entity.NewBrand; -import com.sluv.server.domain.brand.exception.BrandNotFoundException; -import com.sluv.server.domain.brand.exception.NewBrandNotFoundException; -import com.sluv.server.domain.brand.repository.BrandRepository; -import com.sluv.server.domain.brand.repository.NewBrandRepository; -import com.sluv.server.domain.celeb.entity.Celeb; -import com.sluv.server.domain.celeb.entity.NewCeleb; -import com.sluv.server.domain.celeb.exception.CelebNotFoundException; -import com.sluv.server.domain.celeb.exception.NewCelebNotFoundException; -import com.sluv.server.domain.celeb.repository.CelebRepository; -import com.sluv.server.domain.celeb.repository.NewCelebRepository; -import com.sluv.server.domain.item.dto.TempItemCountResDto; -import com.sluv.server.domain.item.dto.TempItemPostReqDto; -import com.sluv.server.domain.item.dto.TempItemResDto; -import com.sluv.server.domain.item.entity.ItemCategory; -import com.sluv.server.domain.item.entity.TempItem; -import com.sluv.server.domain.item.entity.TempItemImg; -import com.sluv.server.domain.item.entity.TempItemLink; -import com.sluv.server.domain.item.entity.hashtag.Hashtag; -import com.sluv.server.domain.item.entity.hashtag.TempItemHashtag; -import com.sluv.server.domain.item.exception.ItemCategoryNotFoundException; -import com.sluv.server.domain.item.exception.hashtag.HashtagNotFoundException; -import com.sluv.server.domain.item.repository.ItemCategoryRepository; -import com.sluv.server.domain.item.repository.TempItemImgRepository; -import com.sluv.server.domain.item.repository.TempItemLinkRepository; -import com.sluv.server.domain.item.repository.TempItemRepository; -import com.sluv.server.domain.item.repository.hashtag.HashtagRepository; -import com.sluv.server.domain.item.repository.hashtag.TempItemHashtagRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationCountResDto; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional -@RequiredArgsConstructor -public class TempItemService { - private final TempItemRepository tempItemRepository; - - private final TempItemLinkRepository tempItemLinkRepository; - private final TempItemImgRepository tempItemImgRepository; - private final TempItemHashtagRepository tempItemHashtagRepository; - - private final HashtagRepository hashtagRepository; - private final CelebRepository celebRepository; - private final ItemCategoryRepository itemCategoryRepository; - private final BrandRepository brandRepository; - private final NewBrandRepository newBrandRepository; - private final NewCelebRepository newCelebRepository; - - - public Long postTempItem(User user, TempItemPostReqDto reqDto) { - Celeb celeb = reqDto.getCelebId() != null ? celebRepository.findById(reqDto.getCelebId()) - .orElseThrow(CelebNotFoundException::new) - : null; - Brand brand = reqDto.getBrandId() != null ? brandRepository.findById(reqDto.getBrandId()) - .orElseThrow(BrandNotFoundException::new) - : null; - NewCeleb newCeleb = reqDto.getNewCelebId() != null ? newCelebRepository.findById(reqDto.getNewCelebId()) - .orElseThrow(NewCelebNotFoundException::new) - : null; - - NewBrand newBrand = reqDto.getNewBrandId() != null ? newBrandRepository.findById(reqDto.getNewBrandId()) - .orElseThrow(NewBrandNotFoundException::new) - : null; - ItemCategory itemCategory = - reqDto.getCategoryId() != null ? itemCategoryRepository.findById(reqDto.getCategoryId()) - .orElseThrow(ItemCategoryNotFoundException::new) - : null; - TempItem tempItem = null; - - if (reqDto.getId() != null) { - tempItem = tempItemRepository.findById(reqDto.getId()) - .orElse(null); - } - - TempItem postTempItem; - if (tempItem != null) { - postTempItem = TempItem.toEntity(tempItem.getId(), user, celeb, newCeleb, itemCategory, brand, newBrand, - reqDto); - } else { - postTempItem = TempItem.toEntity(user, celeb, newCeleb, itemCategory, brand, newBrand, reqDto); - } - - TempItem saveTempItem = tempItemRepository.save(postTempItem); - - // ItemImg 테이블에 추가 - tempItemImgRepository.deleteAllByTempItemId(postTempItem.getId()); - if (reqDto.getImgList() != null) { - reqDto.getImgList().stream() - .map(tempItemImg -> - TempItemImg.toEntity(saveTempItem, tempItemImg) - ).forEach(tempItemImgRepository::save); - - } - - // ItemLink 테이블에 추가 - tempItemLinkRepository.deleteAllByTempItemId(postTempItem.getId()); - if (reqDto.getLinkList() != null) { - reqDto.getLinkList().stream() - .map(tempItemLink -> - TempItemLink.toEntity(saveTempItem, tempItemLink) - ).forEach(tempItemLinkRepository::save); - } - - // ItemHashtag 테이블에 추가 - tempItemHashtagRepository.deleteAllByTempItemId(postTempItem.getId()); - if (reqDto.getHashTagIdList() != null) { - reqDto.getHashTagIdList().stream().map(hashTag -> { - Hashtag tag = hashtagRepository.findById(hashTag).orElseThrow(HashtagNotFoundException::new); - return TempItemHashtag.toEntity(saveTempItem, tag); - }).forEach(tempItemHashtagRepository::save); - } - - return saveTempItem.getId(); - } - - @Transactional(readOnly = true) - public PaginationCountResDto getTempItemList(User user, Pageable pageable) { - Page tempItemPage = tempItemRepository.getTempItemList(user, pageable); - - List dtoList = tempItemRepository.getTempItemResDto(tempItemPage.getContent()); - - return new PaginationCountResDto<>( - tempItemPage.hasNext(), - tempItemPage.getNumber(), - dtoList, - tempItemPage.getTotalElements()); - - - } - - public void deleteTempItem(Long tempItemId) { - // 관련된 삭제 - // 1. tempItemImg 삭제 - tempItemImgRepository.deleteAllByTempItemId(tempItemId); - // 2. tempItemLink 삭제 - tempItemLinkRepository.deleteAllByTempItemId(tempItemId); - // 3. tempItemHashtag 삭제 - tempItemHashtagRepository.deleteAllByTempItemId(tempItemId); - - // tempItem 삭제 - tempItemRepository.deleteById(tempItemId); - } - - public void deleteAllTempItem(Long userId) { - // 1. 해당 유저의 모든 TempItem 조회 - List tempItemList = tempItemRepository.findAllExceptLast(userId); - - // 2. 모든 TempItem에 대한 관련된 삭제 - tempItemList.forEach(tempItem -> { - // 2-1. tempItemImg 삭제 - tempItemImgRepository.deleteAllByTempItemId(tempItem.getId()); - // 2-2. tempItemLink 삭제ㅎ - tempItemLinkRepository.deleteAllByTempItemId(tempItem.getId()); - // 2-3. tempItemHashtag 삭제 - tempItemHashtagRepository.deleteAllByTempItemId(tempItem.getId()); - // 3. TempItem 삭제 - tempItemRepository.deleteById(tempItem.getId()); - }); - - } - - public TempItemCountResDto countTempItemCount(User user) { - return TempItemCountResDto.of(tempItemRepository.countByUserId(user.getId())); - } -} diff --git a/src/main/java/com/sluv/server/domain/notice/enums/NoticeType.java b/src/main/java/com/sluv/server/domain/notice/enums/NoticeType.java deleted file mode 100644 index 357fda64..00000000 --- a/src/main/java/com/sluv/server/domain/notice/enums/NoticeType.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.sluv.server.domain.notice.enums; - -public enum NoticeType { - ETC -} diff --git a/src/main/java/com/sluv/server/domain/notice/exception/NoticeException.java b/src/main/java/com/sluv/server/domain/notice/exception/NoticeException.java deleted file mode 100644 index 11fb8369..00000000 --- a/src/main/java/com/sluv/server/domain/notice/exception/NoticeException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.notice.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class NoticeException extends ApplicationException { - public NoticeException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/notice/exception/NoticeNotFoundException.java b/src/main/java/com/sluv/server/domain/notice/exception/NoticeNotFoundException.java deleted file mode 100644 index 9705ca4c..00000000 --- a/src/main/java/com/sluv/server/domain/notice/exception/NoticeNotFoundException.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.sluv.server.domain.notice.exception; - -import org.springframework.http.HttpStatus; - -public class NoticeNotFoundException extends NoticeException{ - - private static final int ERROR_CODE = 2024; - private static final String MESSAGE = "존재하지 않는 Notice입니다."; - private static final HttpStatus STATUS = HttpStatus.BAD_REQUEST; - - public NoticeNotFoundException() { - super(ERROR_CODE, STATUS, MESSAGE); - } -} diff --git a/src/main/java/com/sluv/server/domain/notice/repository/NoticeRepository.java b/src/main/java/com/sluv/server/domain/notice/repository/NoticeRepository.java deleted file mode 100644 index bfe4cc81..00000000 --- a/src/main/java/com/sluv/server/domain/notice/repository/NoticeRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sluv.server.domain.notice.repository; - -import com.sluv.server.domain.notice.entity.Notice; -import com.sluv.server.domain.notice.repository.impl.NoticeRepositoryCustom; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface NoticeRepository extends JpaRepository, NoticeRepositoryCustom { -} diff --git a/src/main/java/com/sluv/server/domain/notice/service/NoticeService.java b/src/main/java/com/sluv/server/domain/notice/service/NoticeService.java deleted file mode 100644 index a74f3e78..00000000 --- a/src/main/java/com/sluv/server/domain/notice/service/NoticeService.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.sluv.server.domain.notice.service; - -import com.sluv.server.domain.notice.dto.NoticeDetailResDto; -import com.sluv.server.domain.notice.dto.NoticeSimpleResDto; -import com.sluv.server.domain.notice.entity.Notice; -import com.sluv.server.domain.notice.exception.NoticeNotFoundException; -import com.sluv.server.domain.notice.repository.NoticeRepository; -import com.sluv.server.global.common.response.PaginationResDto; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Transactional -@RequiredArgsConstructor -public class NoticeService { - private final NoticeRepository noticeRepository; - - /** - * 공지사항 리스트 조회 - */ - @Transactional(readOnly = true) - public PaginationResDto getAllNotice(Pageable pageable) { - // 공지사항 리스트 Page 조회 - Page noticePage = noticeRepository.getAllNotice(pageable); - - // Content가 될 Dto 제작 - List content = noticePage.stream() - .map(NoticeSimpleResDto::of) - .toList(); - - return PaginationResDto.of(noticePage, content); - } - - /** - * 공지사항 상세 조회 - */ - @Transactional(readOnly = true) - public NoticeDetailResDto getNoticeDetail(Long noticeId) { - - // noticeId에 해당하는 공지사항 조회 - Notice notice = noticeRepository.findById(noticeId).orElseThrow(NoticeNotFoundException::new); - - return NoticeDetailResDto.of(notice); - } -} diff --git a/src/main/java/com/sluv/server/domain/question/exception/QuestionException.java b/src/main/java/com/sluv/server/domain/question/exception/QuestionException.java deleted file mode 100644 index 77ff9088..00000000 --- a/src/main/java/com/sluv/server/domain/question/exception/QuestionException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.question.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class QuestionException extends ApplicationException { - public QuestionException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/question/service/QuestionWithdrawService.java b/src/main/java/com/sluv/server/domain/question/service/QuestionWithdrawService.java deleted file mode 100644 index b41e4002..00000000 --- a/src/main/java/com/sluv/server/domain/question/service/QuestionWithdrawService.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sluv.server.domain.question.service; - -import com.sluv.server.domain.question.repository.RecentQuestionRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class QuestionWithdrawService { - private final RecentQuestionRepository recentQuestionRepository; - - public void withdrawQuestionByUserId(Long userId) { - recentQuestionRepository.deleteAllByUserId(userId); - } -} diff --git a/src/main/java/com/sluv/server/domain/search/repository/SearchDataRepository.java b/src/main/java/com/sluv/server/domain/search/repository/SearchDataRepository.java deleted file mode 100644 index 90b75d24..00000000 --- a/src/main/java/com/sluv/server/domain/search/repository/SearchDataRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sluv.server.domain.search.repository; - -import com.sluv.server.domain.search.entity.SearchData; -import com.sluv.server.domain.search.repository.impl.SearchDataRepositoryCustom; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface SearchDataRepository extends JpaRepository, SearchDataRepositoryCustom { -} diff --git a/src/main/java/com/sluv/server/domain/search/repository/impl/RecentSearchRepositoryCustom.java b/src/main/java/com/sluv/server/domain/search/repository/impl/RecentSearchRepositoryCustom.java deleted file mode 100644 index a17ed87a..00000000 --- a/src/main/java/com/sluv/server/domain/search/repository/impl/RecentSearchRepositoryCustom.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.search.repository.impl; - -import com.sluv.server.domain.search.entity.RecentSearch; -import com.sluv.server.domain.user.entity.User; - -import java.util.List; - -public interface RecentSearchRepositoryCustom { - List getRecentSearch(User user); -} diff --git a/src/main/java/com/sluv/server/domain/search/scheduler/SearchScheduler.java b/src/main/java/com/sluv/server/domain/search/scheduler/SearchScheduler.java deleted file mode 100644 index 63fbb31f..00000000 --- a/src/main/java/com/sluv/server/domain/search/scheduler/SearchScheduler.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.sluv.server.domain.search.scheduler; - -import com.querydsl.core.Tuple; -import com.sluv.server.domain.search.entity.SearchData; -import com.sluv.server.domain.search.entity.SearchRank; -import com.sluv.server.domain.search.repository.SearchDataRepository; -import com.sluv.server.domain.search.repository.SearchRankRepository; -import java.util.Calendar; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; - -@Component -@Slf4j -@Transactional -@RequiredArgsConstructor -public class SearchScheduler { - - private final SearchDataRepository searchDataRepository; - private final SearchRankRepository searchRankRepository; - - /** - * SearchRank 업데이트 - */ - @Scheduled(cron = "0 0 17 * * *") // 초 분 시 일 월 요일 - public void updateSearchRank() { - log.info("SearchRank Update Time: {}", Calendar.getInstance().getTime()); - - log.info("Delete Old SearchRank Data"); - searchRankRepository.deleteAll(); - - log.info("Get SearchData. Time: {}", Calendar.getInstance().getTime()); - List topData = searchDataRepository.getTopData(); - - List result = topData.stream().map(data -> - SearchRank.of( - data.get(1, Long.class), - data.get(0, SearchData.class).getSearchWord() - ) - ).toList(); - - log.info("Save SearchRank. Time: {}", Calendar.getInstance().getTime()); - searchRankRepository.saveAll(result); - } -} diff --git a/src/main/java/com/sluv/server/domain/search/service/SearchEngineService.java b/src/main/java/com/sluv/server/domain/search/service/SearchEngineService.java deleted file mode 100644 index 0ea142ea..00000000 --- a/src/main/java/com/sluv/server/domain/search/service/SearchEngineService.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.sluv.server.domain.search.service; - -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.exception.QuestionTypeNotFoundException; -import com.sluv.server.domain.question.repository.QuestionRepository; -import com.sluv.server.domain.question.service.QuestionService; -import com.sluv.server.domain.search.dto.SearchFilterReqDto; -import com.sluv.server.domain.search.dto.SearchItemCountResDto; -import com.sluv.server.domain.search.engine.SearchEngine; -import com.sluv.server.domain.user.dto.UserSearchInfoDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.repository.FollowRepository; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.common.response.PaginationResDto; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class SearchEngineService { - - private final SearchEngine searchEngine; - - private final SearchService searchService; - private final QuestionService questionService; - - private final ItemRepository itemRepository; - private final UserRepository userRepository; - private final FollowRepository followRepository; - private final QuestionRepository questionRepository; - - @Transactional - @Async(value = "asyncThreadPoolExecutor") - public CompletableFuture> getSearchItem(User user, String keyword, - SearchFilterReqDto dto, - Pageable pageable) { - - List searchItemIds = searchEngine.getSearchItemIds(keyword); - Page searchItemPage = itemRepository.getSearchItem(searchItemIds, dto, pageable); - List content = itemRepository.getItemSimpleResDto(user, searchItemPage.getContent()); - - // 최근 검색 등록 - searchService.postRecentSearch(user, keyword); - // 서치 데이터 등록 - searchService.postSearchData(keyword); - - return CompletableFuture.completedFuture(PaginationResDto.of(searchItemPage, content)); - } - - @Transactional - @Async(value = "asyncThreadPoolExecutor") - public CompletableFuture> getSearchQuestion(User user, String keyword, - String qType, - Pageable pageable) { - List searchQuestionIds = searchEngine.getSearchQuestionIds(keyword); - Page searchQuestionPage; - // 조건에 맞는 Item Page 조회 - if (qType == null) { - searchQuestionPage = - questionRepository.getSearchQuestion(searchQuestionIds, pageable); - } else if (qType.equals("Buy")) { - searchQuestionPage = - questionRepository.getSearchQuestionBuy(searchQuestionIds, pageable); - } else if (qType.equals("Find")) { - searchQuestionPage = - questionRepository.getSearchQuestionFind(searchQuestionIds, pageable); - } else if (qType.equals("How")) { - searchQuestionPage = - questionRepository.getSearchQuestionHowabout(searchQuestionIds, pageable); - } else if (qType.equals("Recommend")) { - searchQuestionPage = - questionRepository.getSearchQuestionRecommend(searchQuestionIds, pageable); - } else { - throw new QuestionTypeNotFoundException(); - } - - List content = searchQuestionPage.stream() - .map(question -> - questionService.getQuestionSimpleResDto((Question) question, qType) - ).toList(); - - // 최근 검색 등록 - searchService.postRecentSearch(user, keyword); - - // 서치 데이터 등록 - searchService.postSearchData(keyword); - - return CompletableFuture.completedFuture(PaginationResDto.of(searchQuestionPage, content)); - - } - - @Async(value = "asyncThreadPoolExecutor") - public CompletableFuture> getSearchUser(User user, String keyword, - Pageable pageable) { - List searchUserIds = searchEngine.getSearchUserIds(keyword); - Page searchUserPage = userRepository.getSearchUser(searchUserIds, pageable); - List content = searchUserPage.stream().map(searchUser -> - UserSearchInfoDto.of(searchUser, followRepository.getFollowStatus(user, searchUser.getId()), - Objects.equals(searchUser.getId(), user.getId())) - ).toList(); - - // 최근 검색 등록 - searchService.postRecentSearch(user, keyword); - // 서치 데이터 등록 - searchService.postSearchData(keyword); - - return CompletableFuture.completedFuture(PaginationResDto.of(searchUserPage, content)); - } - - @Transactional - public SearchItemCountResDto getSearchItemCount(String keyword, SearchFilterReqDto dto) { - List itemIdList = searchEngine.getSearchItemIds(keyword); - return SearchItemCountResDto.of(itemRepository.getSearchItemCount(itemIdList, dto)); - } -} diff --git a/src/main/java/com/sluv/server/domain/search/service/SearchService.java b/src/main/java/com/sluv/server/domain/search/service/SearchService.java deleted file mode 100644 index 520c6552..00000000 --- a/src/main/java/com/sluv/server/domain/search/service/SearchService.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.sluv.server.domain.search.service; - -import com.sluv.server.domain.brand.dto.BrandSearchResDto; -import com.sluv.server.domain.brand.repository.BrandRepository; -import com.sluv.server.domain.celeb.dto.CelebSearchResDto; -import com.sluv.server.domain.celeb.repository.CelebRepository; -import com.sluv.server.domain.item.dto.ItemKeywordSearchResDto; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.search.dto.RecentSearchChipResDto; -import com.sluv.server.domain.search.dto.SearchKeywordResDto; -import com.sluv.server.domain.search.dto.SearchKeywordTotalResDto; -import com.sluv.server.domain.search.entity.RecentSearch; -import com.sluv.server.domain.search.entity.SearchData; -import com.sluv.server.domain.search.entity.SearchRank; -import com.sluv.server.domain.search.repository.RecentSearchRepository; -import com.sluv.server.domain.search.repository.SearchDataRepository; -import com.sluv.server.domain.search.repository.SearchRankRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationResDto; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Slf4j -@Service -@RequiredArgsConstructor -public class SearchService { - - private final RecentSearchRepository recentSearchRepository; - private final SearchRankRepository searchRankRepository; - private final SearchDataRepository searchDataRepository; - private final CelebRepository celebRepository; - private final BrandRepository brandRepository; - private final ItemRepository itemRepository; - - @Transactional(readOnly = true) - public List getRecentSearch(User user) { - List result - = recentSearchRepository.getRecentSearch(user) - .stream() - .map(recentSearch -> RecentSearchChipResDto.of(recentSearch.getSearchWord())) - .toList(); - - return result; - } - - @Transactional(readOnly = true) - public List getSearchRank() { - List searchRankList = searchRankRepository.findAllByOrderBySearchCountDesc(); - return searchRankList - .stream() - .map(searchRank -> SearchKeywordResDto.of(searchRank.getSearchWord())) - .toList(); - } - - @Transactional(readOnly = true) - public PaginationResDto getSearchKeyword(String keyword, Pageable pageable) { - Page searchDataPage = searchDataRepository.getSearchKeyword(keyword, pageable); - - List content = searchDataPage.stream() - .map(searchData -> SearchKeywordResDto.of(searchData.getSearchWord())) - .toList(); - - return PaginationResDto.of(searchDataPage, content); - } - - @Async - @Transactional - public void postRecentSearch(User user, String keyword) { - if (!keyword.isEmpty() && !keyword.isBlank()) { - RecentSearch recentSearch = RecentSearch.of(user, keyword); - log.info("Post RecentSearch -> User: {}, Keyword: {}", user.getId(), keyword); - recentSearchRepository.save(recentSearch); - } - } - - @Async - @Transactional - public void postSearchData(String keyword) { - if (!keyword.isEmpty() && !keyword.isBlank()) { - SearchData searchData = SearchData.of(keyword); - log.info("Post SearchData -> Keyword: {}", keyword); - searchDataRepository.save(searchData); - } - } - - /** - * 현재 유저의 RecentSearch 키워드 삭제 - */ - @Transactional - public void deleteSearchKeyword(User user, String keyword) { - log.info("Delete {}'s Recent Search Keyword: {} ", user.getId(), keyword); - recentSearchRepository.deleteByUserIdAndSearchWord(user.getId(), keyword); - } - - @Transactional - public void deleteAllSearchKeyword(User user) { - log.info("Delete {}'s All Recent Search Keyword", user.getId()); - recentSearchRepository.deleteAllByUserId(user.getId()); - } - - @Transactional(readOnly = true) - public SearchKeywordTotalResDto getAllDateByKeyword(User user, String keyword) { - // 1. 셀럽 2. 브랜드 3. 아이템 - List celebByContainKeyword = celebRepository.getCelebByContainKeyword(keyword).stream() - .map(CelebSearchResDto::of) - .toList(); - - List brandByContainKeyword = brandRepository.getBrandContainKeyword(keyword).stream() - .map(BrandSearchResDto::of) - .toList(); - - List itemByContainKeyword = itemRepository.getItemContainKeyword(keyword).stream() - .map(ItemKeywordSearchResDto::of) - .toList(); - - return SearchKeywordTotalResDto.of(celebByContainKeyword, brandByContainKeyword, itemByContainKeyword); - } -} diff --git a/src/main/java/com/sluv/server/domain/search/utils/ElasticSearchConnectUtil.java b/src/main/java/com/sluv/server/domain/search/utils/ElasticSearchConnectUtil.java deleted file mode 100644 index 9f2ac782..00000000 --- a/src/main/java/com/sluv/server/domain/search/utils/ElasticSearchConnectUtil.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.sluv.server.domain.search.utils; - -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import lombok.extern.slf4j.Slf4j; -import net.minidev.json.JSONArray; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Component; -import org.springframework.util.MultiValueMap; -import org.springframework.web.client.RestTemplate; - -@Component -@Slf4j -public class ElasticSearchConnectUtil { - @Value("${spring.elasticsearch.uri}") - private String ELASTIC_SEARCH_URI; - - /** - * ElasticSearch API 호출 - * - * @param keyword - * @param path - * @return result Id List - */ - public List connectElasticSearch(String keyword, String path) { - //요청 URL 조립 - String requestUrl = ELASTIC_SEARCH_URI + path + "?searchTerm=" + keyword; - - // API 호출 - return getElasticSearchResponse(requestUrl); - } - - /** - * ReqstTemplate로 다른 서버의 API 호출 - * - * @param requestUrl - * @return ResponseEntity 결과 아이디 - */ - private List getElasticSearchResponse(String requestUrl) { - // Header - HttpHeaders headers = new HttpHeaders(); - headers.add("Content-Type", "application/json"); - - // Request - HttpEntity> request = new HttpEntity<>(headers); - - // RestTemplate - log.info("Request: GET {}", requestUrl); - RestTemplate rt = new RestTemplate(); - ResponseEntity response = rt.exchange( - requestUrl, - HttpMethod.GET, - request, - JSONArray.class - ); - - return jsonArrayToList(Objects.requireNonNull(response.getBody())); - - - } - - private List jsonArrayToList(JSONArray jsonArray) { - List list = null; - try { - ObjectMapper objectMapper = new ObjectMapper(); - Long[] longArray = objectMapper.readValue(jsonArray.toString(), Long[].class); - list = Arrays.stream(longArray).toList(); - - } catch (Exception e) { - log.error("JSONArray To Long List Convert Error"); - } - return list; - - } -} diff --git a/src/main/java/com/sluv/server/domain/user/controller/FollowController.java b/src/main/java/com/sluv/server/domain/user/controller/FollowController.java deleted file mode 100644 index 634e5325..00000000 --- a/src/main/java/com/sluv/server/domain/user/controller/FollowController.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.sluv.server.domain.user.controller; - -import com.sluv.server.domain.user.dto.UserSearchInfoDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.service.FollowService; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; -import io.swagger.v3.oas.annotations.Operation; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Pageable; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@Slf4j -@RequestMapping("/app/user") -@RequiredArgsConstructor -public class FollowController { - - private final FollowService followService; - - @Operation(summary = "*특정 유저를 등록한 팔로워들 조회", description = "User 토큰 필요. Pagination 적용") - @GetMapping("/{userId}/follower") - public ResponseEntity>> getUserFollower( - @AuthenticationPrincipal User user, @PathVariable("userId") Long userId, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(followService.getUserFollower(user, userId, pageable)) - .build() - ); - } - - @Operation(summary = "*특정 유저가 등록한 팔로잉 조회", description = "User 토큰 필요. Pagination 적용") - @GetMapping("/{userId}/following") - public ResponseEntity>> getUserFollowing( - @AuthenticationPrincipal User user, @PathVariable("userId") Long userId, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(followService.getUserFollowing(user, userId, pageable)) - .build() - ); - } - - @Operation(summary = "*현재 유저를 등록한 팔로워들 조회", description = "User 토큰 필요. Pagination 적용") - @GetMapping("/follower") - public ResponseEntity>> getNowUserFollower( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(followService.getUserFollower(user, user.getId(), pageable)) - .build() - ); - } - - @Operation(summary = "*현재 유저가 등록한 팔로잉 조회", description = "User 토큰 필요. Pagination 적용") - @GetMapping("/following") - public ResponseEntity>> getNowUserFollowing( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(followService.getUserFollowing(user, user.getId(), pageable)) - .build() - ); - } - - @Operation(summary = "*유저 팔로우/팔로잉", description = "User 토큰 필요") - @PostMapping("/{userId}/follow") - public ResponseEntity postUserFollow(@AuthenticationPrincipal User user, - @PathVariable(name = "userId") Long userId) { - followService.postUserFollow(user, userId); - return ResponseEntity.ok().body( - new SuccessResponse() - ); - } - -} diff --git a/src/main/java/com/sluv/server/domain/user/controller/UserCelebController.java b/src/main/java/com/sluv/server/domain/user/controller/UserCelebController.java deleted file mode 100644 index 0c949ce0..00000000 --- a/src/main/java/com/sluv/server/domain/user/controller/UserCelebController.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.sluv.server.domain.user.controller; - -import com.sluv.server.domain.celeb.dto.InterestedCelebCategoryResDto; -import com.sluv.server.domain.celeb.dto.InterestedCelebParentResDto; -import com.sluv.server.domain.celeb.dto.InterestedCelebPostReqDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.service.UserCelebService; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; -import io.swagger.v3.oas.annotations.Operation; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@Slf4j -@RequestMapping("/app/user") -@RequiredArgsConstructor -public class UserCelebController { - private final UserCelebService userCelebService; - - @Operation(summary = "*현재 유저의 관심 샐럽을 카테고리를 기준으로 조회", - description = "현재 유저를 기준으로 InterstedCeleb 테이블에서 일치하는 Celeb을 카테고리를 기준으로 검색") - @GetMapping("/celeb/category") - public ResponseEntity>> getInterestedCelebByCategory( - @AuthenticationPrincipal User user) { - - return ResponseEntity.ok().body(SuccessDataResponse.>builder() - .result(userCelebService.getInterestedCelebByCategory(user)) - .build()); - } - - @Operation(summary = "*현재 유저의 관심 샐럽을 등록순을 기준으로 조회", - description = "현재 유저를 기준으로 InterstedCeleb 테이블에서 일치하는 Celeb을 등록순을 기준으로 검색") - @GetMapping("/celeb") - public ResponseEntity>> getInterestedCelebByPostTime( - @AuthenticationPrincipal User user) { - - return ResponseEntity.ok().body(SuccessDataResponse.>builder() - .result(userCelebService.getInterestedCelebByPostTime(user)) - .build()); - } - - @Operation(summary = "특정 유저의 관심 샐럽을 등록순을 기준으로 조회", - description = "특정 유저를 기준으로 InterstedCeleb 테이블에서 일치하는 Celeb을 등록순을 기준으로 검색") - @GetMapping("/{userId}/celeb") - public ResponseEntity>> getTargetUserInterestedCelebByPostTime( - @PathVariable("userId") Long userId) { - - return ResponseEntity.ok().body(SuccessDataResponse.>builder() - .result(userCelebService.getTargetUserInterestedCelebByPostTime(userId)) - .build()); - } - - @Operation(summary = "*특정 유저의 관심 샐럽을 카테고리를 기준으로 조회", - description = "특정 유저를 기준으로 InterstedCeleb 테이블에서 일치하는 Celeb을 카테고리를 기준으로 검색") - @GetMapping("/{userId}/celeb/category") - public ResponseEntity>> getTargetUserInterestedCelebByCategory( - @PathVariable("userId") Long userId) { - - return ResponseEntity.ok().body(SuccessDataResponse.>builder() - .result(userCelebService.getTargetUserInterestedCelebByCategory(userId)) - .build()); - } - - @Operation(summary = "*유저의 관심 셀럽 업데이트", description = "User 토큰 필요") - @PostMapping("/celeb") - public ResponseEntity postInterestedCeleb(@AuthenticationPrincipal User user, - @RequestBody InterestedCelebPostReqDto dto) { - userCelebService.postInterestedCeleb(user, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); - } -} diff --git a/src/main/java/com/sluv/server/domain/user/controller/UserController.java b/src/main/java/com/sluv/server/domain/user/controller/UserController.java deleted file mode 100644 index e3a185ba..00000000 --- a/src/main/java/com/sluv/server/domain/user/controller/UserController.java +++ /dev/null @@ -1,222 +0,0 @@ -package com.sluv.server.domain.user.controller; - - -import com.sluv.server.domain.closet.dto.ClosetResDto; -import com.sluv.server.domain.comment.dto.CommentSimpleResDto; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.user.dto.UserMypageResDto; -import com.sluv.server.domain.user.dto.UserProfileImgReqDto; -import com.sluv.server.domain.user.dto.UserProfileReqDto; -import com.sluv.server.domain.user.dto.UserSearchInfoDto; -import com.sluv.server.domain.user.dto.UserSocialDto; -import com.sluv.server.domain.user.dto.UserTermsResDto; -import com.sluv.server.domain.user.dto.UserWithdrawReqDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.service.UserService; -import com.sluv.server.global.common.response.PaginationCountResDto; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; -import com.sluv.server.global.common.response.SuccessResponse; -import io.swagger.v3.oas.annotations.Operation; -import jakarta.annotation.Nullable; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Pageable; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequiredArgsConstructor -@Slf4j -@RequestMapping("/app/user") -public class UserController { - private final UserService userService; - - @Operation( - summary = "*유저의 프로필 설정 및 수정", - description = "최초 회원 가입 시 유저의 프로필 설정 및 추후 유저의 프로필 수정" + - "\n User의 Status가 \"PENDING_PROFILE\" 일 경우 설정 후 Status를 \"PENDING_CELEB\"로 변경" + - "\n User의 Status가 \"ACTIVE\" 일 경우 프로필 정보만 수정" + - "\n (User Id Token 필요)" + - "\n \"PENDING_PROFILE\"로 등록 후 User Id Token이 발급되기 때문에 " - ) - @PostMapping("/profile") - public ResponseEntity postUserProfile(@AuthenticationPrincipal User user, - @RequestBody UserProfileReqDto dto) { - userService.postUserProfile(user, dto); - return ResponseEntity.ok().body( - new SuccessResponse() - ); - } - - @Operation(summary = "특정 유저의 마이페이지 조회", description = "User 토큰 필요") - @GetMapping("/{userId}/mypage") - public ResponseEntity> getTargetUserMypage(@AuthenticationPrincipal User user, - @PathVariable("userId") Long userId) { - - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(userService.getUserMypage(user, userId)) - .build() - ); - } - - @Operation(summary = "현재 유저의 마이페이지 조회", description = "User 토큰 필요") - @GetMapping("/mypage") - public ResponseEntity> getUserMypage(@AuthenticationPrincipal User user) { - - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(userService.getUserMypage(user, null)) - .build() - ); - } - - @Operation(summary = "특정 유저의 아이템 목록 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/{userId}/item") - public ResponseEntity>> getUserItem( - @AuthenticationPrincipal User user, @PathVariable("userId") Long userId, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(userService.getUserItem(user, userId, pageable)) - .build() - ); - } - - @Operation(summary = "*특정 유저의 옷장 목록 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/{userId}/closet") - public ResponseEntity>> getUserCloset( - @AuthenticationPrincipal User user, @PathVariable("userId") Long userId, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(userService.getUserCloset(user, userId, pageable)) - .build() - ); - } - - @Operation(summary = "*유저의 이메일, 소셜 종류 조회", description = "User 토큰 필요.") - @GetMapping("/social") - public ResponseEntity> getUserSocialData(@AuthenticationPrincipal User user) { - - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(userService.getUserSocialData(user)) - .build() - ); - } - - @Operation(summary = "*유저의 프로필 이미지 수정", description = "User 토큰 필요. Pagination 적용.") - @PatchMapping("/profileImg") - public ResponseEntity patchUserProfileImg(@AuthenticationPrincipal User user, - @RequestBody UserProfileImgReqDto dto) { - - userService.patchUserProfileImg(user, dto); - - return ResponseEntity.ok().body( - new SuccessResponse() - ); - } - - @Operation(summary = "*유저의 프로필 이미지 삭제", description = "null로 변경. User 토큰 필요.") - @DeleteMapping("/profileImg") - public ResponseEntity deleteUserProfileImg(@AuthenticationPrincipal User user) { - - userService.deleteUserProfileImg(user); - - return ResponseEntity.ok().body( - new SuccessResponse() - ); - } - - @Operation(summary = "*유저가 작성한 Item 게시글 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/item") - public ResponseEntity>> getUserUploadItem( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(userService.getUserUploadItem(user, pageable)) - .build() - ); - } - - @Operation(summary = "*유저가 작성한 Question 게시글 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/question") - public ResponseEntity>> getUserUploadQuestion( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(userService.getUserUploadQuestion(user, pageable)) - .build() - ); - } - - @Operation(summary = "*유저가 작성한 Comment 게시글 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/comment") - public ResponseEntity>> getUserUploadComment( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(userService.getUserUploadComment(user, pageable)) - .build() - ); - } - - /** - * 1. 팔로워수 2. 아이템 업로드 수 3. item Like 받은 수 4. question Like 받은 수 5. comment Like 받은 수 - */ - @Operation(summary = "*인기 스러버 조회", description = "User 토큰 필요. 정적으로 10개 검색") - @GetMapping("/hotSluver") - public ResponseEntity>> getHotSluver(@AuthenticationPrincipal User user, - @Nullable @RequestParam("celebId") Long celebId) { - log.info("이번주 인기 스러버 조회"); - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(userService.getHotSluver(user, celebId)) - .build() - ); - } - - @Operation(summary = "*약관 동의", description = "광고성 정보 수신 및 마케팅 활용 동의") - @PostMapping("/terms") - public ResponseEntity> postTerms(@AuthenticationPrincipal User user) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(userService.postTerms(user)) - .build() - ); - } - - @Operation(summary = "*약관 동의 상태 조회", description = "광고성 정보 수신 및 마케팅 활용 동의 상태 조회") - @GetMapping("/terms") - public ResponseEntity> getUserTermsStatus(@AuthenticationPrincipal User user) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result(UserTermsResDto.of(user)) - .build() - ); - } - - @Operation(summary = "*회원 탈퇴", description = "회원 탈퇴 기능") - @PostMapping("/withdraw") - public ResponseEntity withdrawUser(@AuthenticationPrincipal User user, - @RequestBody UserWithdrawReqDto dto) { - userService.withdrawUser(user, dto); - return ResponseEntity.ok().body(new SuccessResponse()); - } -} diff --git a/src/main/java/com/sluv/server/domain/user/controller/UserLikeController.java b/src/main/java/com/sluv/server/domain/user/controller/UserLikeController.java deleted file mode 100644 index 07fb73a0..00000000 --- a/src/main/java/com/sluv/server/domain/user/controller/UserLikeController.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.sluv.server.domain.user.controller; - -import com.sluv.server.domain.comment.dto.CommentSimpleResDto; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.service.UserLikeService; -import com.sluv.server.global.common.response.PaginationCountResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; -import io.swagger.v3.oas.annotations.Operation; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Pageable; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@Slf4j -@RequestMapping("/app/user") -@RequiredArgsConstructor -public class UserLikeController { - - private final UserLikeService userLikeService; - - @Operation(summary = "유저가 좋아요한 아이템 조회", description = "User 토큰 필요. Pagination 적용") - @GetMapping("/like/item") - public ResponseEntity>> getUserLikeItem( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(userLikeService.getUserLikeItem(user, pageable)) - .build() - ); - } - - @Operation(summary = "유저가 좋아요한 Question 게시글 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/like/question") - public ResponseEntity>> getUserLikeQuestion( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(userLikeService.getUserLikeQuestion(user, pageable)) - .build() - ); - } - - @Operation(summary = "유저가 좋아요한 Comment 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/like/comment") - public ResponseEntity>> getUserLikeComment( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(userLikeService.getUserLikeComment(user, pageable)) - .build() - ); - } -} diff --git a/src/main/java/com/sluv/server/domain/user/controller/UserRecentController.java b/src/main/java/com/sluv/server/domain/user/controller/UserRecentController.java deleted file mode 100644 index 6e08ccf7..00000000 --- a/src/main/java/com/sluv/server/domain/user/controller/UserRecentController.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.sluv.server.domain.user.controller; - -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.service.UserRecentService; -import com.sluv.server.global.common.response.PaginationCountResDto; -import com.sluv.server.global.common.response.SuccessDataResponse; -import io.swagger.v3.oas.annotations.Operation; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Pageable; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@Slf4j -@RequestMapping("/app/user") -@RequiredArgsConstructor -public class UserRecentController { - private final UserRecentService userRecentService; - - @Operation(summary = "*유저의 최근 본 아이템 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/recent/item") - public ResponseEntity>> getUserRecentItem( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(userRecentService.getUserRecentItem(user, pageable)) - .build() - ); - } - - @Operation(summary = "*유저의 최근 본 Question 조회", description = "User 토큰 필요. Pagination 적용.") - @GetMapping("/recent/question") - public ResponseEntity>> getUserRecentQuestion( - @AuthenticationPrincipal User user, Pageable pageable) { - - return ResponseEntity.ok().body( - SuccessDataResponse.>builder() - .result(userRecentService.getUserRecentQuestion(user, pageable)) - .build() - ); - } -} diff --git a/src/main/java/com/sluv/server/domain/user/enums/SnsType.java b/src/main/java/com/sluv/server/domain/user/enums/SnsType.java deleted file mode 100644 index 4acaa97e..00000000 --- a/src/main/java/com/sluv/server/domain/user/enums/SnsType.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.sluv.server.domain.user.enums; - -public enum SnsType { - KAKAO, - GOOGLE, - APPLE; -} diff --git a/src/main/java/com/sluv/server/domain/user/exception/UserException.java b/src/main/java/com/sluv/server/domain/user/exception/UserException.java deleted file mode 100644 index bbe9e9ec..00000000 --- a/src/main/java/com/sluv/server/domain/user/exception/UserException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.domain.user.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class UserException extends ApplicationException { - public UserException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/domain/user/repository/FollowRepository.java b/src/main/java/com/sluv/server/domain/user/repository/FollowRepository.java deleted file mode 100644 index 1dd8c384..00000000 --- a/src/main/java/com/sluv/server/domain/user/repository/FollowRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sluv.server.domain.user.repository; - -import com.sluv.server.domain.user.entity.Follow; -import com.sluv.server.domain.user.repository.impl.FollowRepositoryCustom; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface FollowRepository extends JpaRepository, FollowRepositoryCustom { -} diff --git a/src/main/java/com/sluv/server/domain/user/repository/UserReportRepository.java b/src/main/java/com/sluv/server/domain/user/repository/UserReportRepository.java deleted file mode 100644 index 968c62ec..00000000 --- a/src/main/java/com/sluv/server/domain/user/repository/UserReportRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.sluv.server.domain.user.repository; - -import com.sluv.server.domain.user.entity.UserReport; -import com.sluv.server.domain.user.repository.impl.UserReportRepositoryCustom; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface UserReportRepository extends JpaRepository, UserReportRepositoryCustom { -} diff --git a/src/main/java/com/sluv/server/domain/user/service/FollowService.java b/src/main/java/com/sluv/server/domain/user/service/FollowService.java deleted file mode 100644 index 8440a2dc..00000000 --- a/src/main/java/com/sluv/server/domain/user/service/FollowService.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.sluv.server.domain.user.service; - -import com.sluv.server.domain.alarm.service.UserAlarmService; -import com.sluv.server.domain.user.dto.UserSearchInfoDto; -import com.sluv.server.domain.user.entity.Follow; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.repository.FollowRepository; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.common.response.PaginationResDto; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Slf4j -@RequiredArgsConstructor -public class FollowService { - - private final UserRepository userRepository; - private final FollowRepository followRepository; - - private final UserAlarmService userAlarmService; - - @Transactional - public void postUserFollow(User user, Long userId) { - // target이 될 유저 검색 - User targetUser = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - - // Follow 여부 확인. - Boolean followStatus = followRepository.getFollowStatus(user, targetUser.getId()); - - if (followStatus) { - followRepository.deleteFollow(user, targetUser); - } else { - // Follow 정보 등록. - followRepository.save(Follow.toEntity(user, targetUser)); - userAlarmService.sendAlarmAboutFollow(user.getId(), targetUser.getId()); - } - - } - - @Transactional(readOnly = true) - public PaginationResDto getUserFollower(User user, Long userId, Pageable pageable) { - // Follower 들 조회 - Page followerPage = userRepository.getAllFollower(userId, pageable); - - // UserSearchInfoDto로 가공 - List content = - followRepository.getUserSearchInfoDto(user, followerPage.getContent(), "follower"); - - return PaginationResDto.of(followerPage, content); - } - - @Transactional(readOnly = true) - public PaginationResDto getUserFollowing(User user, Long userId, Pageable pageable) { - // Following 들 조회 - Page followerPage = userRepository.getAllFollowing(userId, pageable); - - // UserSearchInfoDto로 가공 - List content = - followRepository.getUserSearchInfoDto(user, followerPage.getContent(), "followee"); - - return PaginationResDto.of(followerPage, content); - } -} diff --git a/src/main/java/com/sluv/server/domain/user/service/UserLikeService.java b/src/main/java/com/sluv/server/domain/user/service/UserLikeService.java deleted file mode 100644 index a681cb80..00000000 --- a/src/main/java/com/sluv/server/domain/user/service/UserLikeService.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.sluv.server.domain.user.service; - -import com.sluv.server.domain.comment.dto.CommentSimpleResDto; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.repository.CommentRepository; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.mapper.QuestionDtoMapper; -import com.sluv.server.domain.question.repository.QuestionRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.global.common.response.PaginationCountResDto; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Slf4j -@RequiredArgsConstructor -public class UserLikeService { - - private final ItemRepository itemRepository; - private final QuestionRepository questionRepository; - private final CommentRepository commentRepository; - private final QuestionDtoMapper questionDtoMapper; - - @Transactional(readOnly = true) - public PaginationCountResDto getUserLikeItem(User user, Pageable pageable) { - Page itemPage = itemRepository.getAllByUserLikeItem(user, pageable); - - List content = itemRepository.getItemSimpleResDto(user, itemPage.getContent()); - - return new PaginationCountResDto<>(itemPage.hasNext(), itemPage.getNumber(), content, - itemPage.getTotalElements()); - } - - /** - * 유저가 좋아요한 Question 게시글 조회 - */ - @Transactional(readOnly = true) - public PaginationCountResDto getUserLikeQuestion(User user, Pageable pageable) { - Page questionPage = questionRepository.getUserLikeQuestion(user, pageable); - - List content = questionPage.stream() - .map(questionDtoMapper::dtoBuildByQuestionType).toList(); - - return new PaginationCountResDto<>(questionPage.hasNext(), questionPage.getNumber(), content, - questionPage.getTotalElements()); - } - - /** - * 유저가 좋아요한 댓글 목록 조회 - */ - @Transactional(readOnly = true) - public PaginationCountResDto getUserLikeComment(User user, Pageable pageable) { - Page commentPage = commentRepository.getUserAllLikeComment(user, pageable); - - List content = commentPage.stream().map(CommentSimpleResDto::of).toList(); - - return new PaginationCountResDto<>(commentPage.hasNext(), commentPage.getNumber(), content, - commentPage.getTotalElements()); - } -} diff --git a/src/main/java/com/sluv/server/domain/user/service/UserRecentService.java b/src/main/java/com/sluv/server/domain/user/service/UserRecentService.java deleted file mode 100644 index 4dbf6a6b..00000000 --- a/src/main/java/com/sluv/server/domain/user/service/UserRecentService.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.sluv.server.domain.user.service; - -import com.sluv.server.domain.comment.repository.CommentRepository; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.entity.ItemImg; -import com.sluv.server.domain.item.repository.ItemImgRepository; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.question.dto.QuestionImgSimpleResDto; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.entity.QuestionBuy; -import com.sluv.server.domain.question.entity.QuestionFind; -import com.sluv.server.domain.question.entity.QuestionHowabout; -import com.sluv.server.domain.question.entity.QuestionRecommend; -import com.sluv.server.domain.question.entity.QuestionRecommendCategory; -import com.sluv.server.domain.question.exception.QuestionTypeNotFoundException; -import com.sluv.server.domain.question.repository.QuestionImgRepository; -import com.sluv.server.domain.question.repository.QuestionItemRepository; -import com.sluv.server.domain.question.repository.QuestionLikeRepository; -import com.sluv.server.domain.question.repository.QuestionRecommendCategoryRepository; -import com.sluv.server.domain.question.repository.RecentQuestionRepository; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.global.common.response.PaginationCountResDto; -import java.util.List; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@Slf4j -@RequiredArgsConstructor -public class UserRecentService { - - private final ItemRepository itemRepository; - private final ItemImgRepository itemImgRepository; - private final QuestionImgRepository questionImgRepository; - private final QuestionItemRepository questionItemRepository; - private final QuestionLikeRepository questionLikeRepository; - private final RecentQuestionRepository recentQuestionRepository; - private final QuestionRecommendCategoryRepository questionRecommendCategoryRepository; - private final CommentRepository commentRepository; - private final UserRepository userRepository; - - - @Transactional(readOnly = true) - public PaginationCountResDto getUserRecentItem(User user, Pageable pageable) { - - Page recentItemPage = itemRepository.getUserAllRecentItem(user, pageable); - - List content = itemRepository.getItemSimpleResDto(user, recentItemPage.getContent()); - - return new PaginationCountResDto<>(recentItemPage.hasNext(), recentItemPage.getNumber(), content, - recentItemPage.getTotalElements()); - } - - @Transactional(readOnly = true) - public PaginationCountResDto getUserRecentQuestion(User user, Pageable pageable) { - - Page recentQuestionPage = recentQuestionRepository.getUserAllRecentQuestion(user, pageable); - - List content = recentQuestionPage.stream().map(question -> { - List imgList = null; - List itemImgList = null; - List categoryList = null; - - if (question instanceof QuestionBuy) { - // 이미지 Dto 생성 - imgList = questionImgRepository.findAllByQuestionId(question.getId()).stream() - .map(QuestionImgSimpleResDto::of).toList(); - // 아이템 이미지 Dto 생성 - itemImgList = questionItemRepository.findAllByQuestionId(question.getId()).stream() - .map(questionItem -> { - ItemImg mainImg = itemImgRepository.findMainImg(questionItem.getItem().getId()); - return QuestionImgSimpleResDto.of(mainImg); - }).toList(); - - } else if (question instanceof QuestionHowabout) { - - } else if (question instanceof QuestionRecommend) { - // Question 카테고리 - categoryList = questionRecommendCategoryRepository.findAllByQuestionId(question.getId()).stream() - .map(QuestionRecommendCategory::getName).toList(); - } else if (question instanceof QuestionFind) { - - } else { - throw new QuestionTypeNotFoundException(); - } - - // Question 좋아요 수 - Long likeNum = questionLikeRepository.countByQuestionId(question.getId()); - - // Question 댓글 수 - Long commentNum = commentRepository.countByQuestionId(question.getId()); - - User writer = userRepository.findById(question.getUser().getId()).orElse(null); - - return QuestionSimpleResDto.of(question, writer, likeNum, commentNum, imgList, itemImgList, categoryList); - - - }).toList(); - - return new PaginationCountResDto<>(recentQuestionPage.hasNext(), recentQuestionPage.getNumber(), content, - recentQuestionPage.getTotalElements()); - } -} diff --git a/src/main/java/com/sluv/server/domain/user/service/UserReportService.java b/src/main/java/com/sluv/server/domain/user/service/UserReportService.java deleted file mode 100644 index 42aba1a9..00000000 --- a/src/main/java/com/sluv/server/domain/user/service/UserReportService.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.sluv.server.domain.user.service; - -import com.sluv.server.domain.user.dto.UserReportReqDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.entity.UserReport; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.exception.UserReportDuplicateException; -import com.sluv.server.domain.user.repository.UserReportRepository; -import com.sluv.server.domain.user.repository.UserRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class UserReportService { - private final UserRepository userRepository; - private final UserReportRepository userReportRepository; - - @Transactional - public void postUserReport(User user, Long userId, UserReportReqDto dto) { - // 피신고자 검색 - User target = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - - // 신고 중복여부 확인 - boolean existence = userReportRepository.findExistence(user, target); - - // 중복 신고라면 Exception 발생 - if (existence) { - throw new UserReportDuplicateException(); - } else { - // 중복이 아니라면 신고 접수 - userReportRepository.save( - UserReport.toEntity(user, target, dto) - ); - } - } -} diff --git a/src/main/java/com/sluv/server/domain/user/service/UserService.java b/src/main/java/com/sluv/server/domain/user/service/UserService.java deleted file mode 100644 index 654aefef..00000000 --- a/src/main/java/com/sluv/server/domain/user/service/UserService.java +++ /dev/null @@ -1,246 +0,0 @@ -package com.sluv.server.domain.user.service; - -import com.sluv.server.domain.closet.dto.ClosetResDto; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.closet.repository.ClosetRepository; -import com.sluv.server.domain.comment.dto.CommentSimpleResDto; -import com.sluv.server.domain.comment.entity.Comment; -import com.sluv.server.domain.comment.enums.CommentStatus; -import com.sluv.server.domain.comment.repository.CommentRepository; -import com.sluv.server.domain.item.dto.ItemSimpleResDto; -import com.sluv.server.domain.item.entity.Item; -import com.sluv.server.domain.item.enums.ItemStatus; -import com.sluv.server.domain.item.helper.ItemHelper; -import com.sluv.server.domain.item.repository.ItemImgRepository; -import com.sluv.server.domain.item.repository.ItemRepository; -import com.sluv.server.domain.item.repository.ItemScrapRepository; -import com.sluv.server.domain.item.service.ItemCacheService; -import com.sluv.server.domain.item.service.TempItemService; -import com.sluv.server.domain.question.dto.QuestionSimpleResDto; -import com.sluv.server.domain.question.entity.Question; -import com.sluv.server.domain.question.enums.QuestionStatus; -import com.sluv.server.domain.question.mapper.QuestionDtoMapper; -import com.sluv.server.domain.question.repository.QuestionRepository; -import com.sluv.server.domain.user.dto.UserMypageResDto; -import com.sluv.server.domain.user.dto.UserProfileImgReqDto; -import com.sluv.server.domain.user.dto.UserProfileReqDto; -import com.sluv.server.domain.user.dto.UserSearchInfoDto; -import com.sluv.server.domain.user.dto.UserSocialDto; -import com.sluv.server.domain.user.dto.UserTermsResDto; -import com.sluv.server.domain.user.dto.UserWithdrawReqDto; -import com.sluv.server.domain.user.entity.User; -import com.sluv.server.domain.user.entity.UserWithdraw; -import com.sluv.server.domain.user.enums.UserStatus; -import com.sluv.server.domain.user.exception.UserNicknameDuplicatedException; -import com.sluv.server.domain.user.exception.UserNotFoundException; -import com.sluv.server.domain.user.repository.FollowRepository; -import com.sluv.server.domain.user.repository.UserRepository; -import com.sluv.server.domain.user.repository.UserWithdrawRepository; -import com.sluv.server.global.common.response.PaginationCountResDto; -import com.sluv.server.global.common.response.PaginationResDto; -import com.sluv.server.global.discord.WebHookService; -import java.util.List; -import java.util.Objects; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - - -@Service -@Slf4j -@Transactional -@RequiredArgsConstructor -public class UserService { - private final UserRepository userRepository; - private final FollowRepository followRepository; - private final ItemRepository itemRepository; - private final QuestionRepository questionRepository; - private final CommentRepository commentRepository; - private final ItemImgRepository itemImgRepository; - private final ItemScrapRepository itemScrapRepository; - private final ClosetRepository closetRepository; - private final UserWithdrawRepository userWithdrawRepository; - - private final ItemHelper itemHelper; - private final QuestionDtoMapper questionDtoMapper; - private final ItemCacheService itemCacheService; - private final WebHookService webHookService; - private final UserWithdrawDataService userWithdrawDataService; - private final TempItemService tempItemService; - - @Transactional - public void postUserProfile(User user, UserProfileReqDto dto) { - User currentUser = userRepository.findById(user.getId()).orElseThrow(UserNotFoundException::new); - itemCacheService.deleteAllItemCacheByUserId(user.getId()); - // 닉네임 중복 검사 - Boolean nicknameExistsStatus = userRepository.existsByNickname(dto.getNickName()); - if (nicknameExistsStatus) { - throw new UserNicknameDuplicatedException(); - } - - currentUser.changeNickname(dto.getNickName()); - currentUser.changeProfileImgUrl(dto.getImgUrl()); - - if (currentUser.getUserStatus().equals(UserStatus.PENDING_PROFILE)) { - currentUser.changeUserStatus(UserStatus.PENDING_CELEB); - } - } - - @Transactional(readOnly = true) - public UserMypageResDto getUserMypage(User user, Long userId) { - User targetUser; - Long itemCount = null; - List imgList = null; - Long communityCount = null; - - if (userId == null) { // 현재 유저일때 - targetUser = user; - - Long questionNum = questionRepository.countByUserIdAndQuestionStatus(targetUser.getId(), - QuestionStatus.ACTIVE); - Long commentNum = commentRepository.countCommentByUserIdInActiveQuestion(targetUser.getId(), - CommentStatus.ACTIVE); - - communityCount = questionNum + commentNum; - - imgList = itemRepository.getRecentTop2Item(targetUser).stream() - .map(item -> itemImgRepository.findMainImg(item.getId()).getItemImgUrl()).toList(); - - itemCount = itemRepository.countByUserIdAndItemStatus(targetUser.getId(), ItemStatus.ACTIVE); - - } else { // 특정 유저일때 - targetUser = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); - } - - Boolean followStatus = followRepository.getFollowStatus(user, targetUser.getId()); - Long followerCount = followRepository.getFollowerCount(targetUser); - Long followingCount = followRepository.getFollowingCount(targetUser); - - return UserMypageResDto.of(targetUser, followStatus, followerCount, followingCount, itemCount, imgList, - communityCount); - } - - @Transactional(readOnly = true) - public PaginationResDto getUserItem(User user, Long userId, Pageable pageable) { - Page itemPage = itemRepository.getUserAllItem(userId, pageable); - - List content = itemPage.stream() - .map(item -> itemHelper.convertItemToSimpleResDto(item, user)) - .toList(); - - return PaginationResDto.of(itemPage, content); - } - - @Transactional(readOnly = true) - public PaginationResDto getUserCloset(User user, Long userId, Pageable pageable) { - Page closetPage; - - // User 일치 여부에 따라 조회하는 Public Closet만 조회할지 결정 - if (user.getId().equals(userId)) { - closetPage = closetRepository.getUserAllCloset(userId, pageable); - } else { - closetPage = closetRepository.getUserAllPublicCloset(userId, pageable); - } - - List content = closetPage.stream() - .map(closet -> ClosetResDto.of(closet, itemScrapRepository.countByClosetId(closet.getId()))).toList(); - - return PaginationResDto.of(closetPage, content); - } - - public void patchUserProfileImg(User user, UserProfileImgReqDto dto) { - log.info("User Profile Img Change. User: {}", user.getId()); - log.info("Change URL: {}", dto.getImgUrl()); - user.changeProfileImgUrl(dto.getImgUrl()); - userRepository.save(user); - } - - public void deleteUserProfileImg(User user) { - log.info("User Profile Img Delete. User: {}", user.getId()); - user.changeProfileImgUrl(null); - userRepository.save(user); - } - - /** - * 현재 유저가 업로드한 아이템 조회 - */ - @Transactional(readOnly = true) - public PaginationCountResDto getUserUploadItem(User user, Pageable pageable) { - // 현재 유저가 업로드한 아이템 조회 - Page itemPage = itemRepository.getUserAllItem(user.getId(), pageable); - // content 제작 - List content = itemPage.stream() - .map(item -> itemHelper.convertItemToSimpleResDto(item, user)).toList(); - - return new PaginationCountResDto<>(itemPage.hasNext(), itemPage.getNumber(), content, - itemPage.getTotalElements()); - } - - /** - * 현재 유저가 업로그한 Question 조회 - */ - @Transactional(readOnly = true) - public PaginationCountResDto getUserUploadQuestion(User user, Pageable pageable) { - Page questionPage = questionRepository.getUserAllQuestion(user, pageable); - - List content = questionPage.stream() - .map(questionDtoMapper::dtoBuildByQuestionType) - .toList(); - - return new PaginationCountResDto<>(questionPage.hasNext(), questionPage.getNumber(), content, - questionPage.getTotalElements()); - } - - /** - * 현재 유저가 업로그한 Comment 조회 - */ - @Transactional(readOnly = true) - public PaginationCountResDto getUserUploadComment(User user, Pageable pageable) { - Page commentPage = commentRepository.getUserAllComment(user, pageable); - - List content = commentPage.stream().map(CommentSimpleResDto::of).toList(); - - return new PaginationCountResDto<>(commentPage.hasNext(), commentPage.getNumber(), content, - commentPage.getTotalElements()); - } - - @Transactional(readOnly = true) - public List getHotSluver(User user, Long celebId) { - List userList = userRepository.getHotSluver(celebId); - - return userList.stream() - .map(hotSluver -> { - boolean isMine = user != null && Objects.equals(hotSluver.getId(), user.getId()); - Boolean followStatus = followRepository.getFollowStatus(user, hotSluver.getId()); - return UserSearchInfoDto.of(hotSluver, followStatus, isMine); - }).toList(); - } - - public UserTermsResDto postTerms(User user) { - user.changeTermStatus(!user.getTermsStatus()); - userRepository.save(user); - return UserTermsResDto.of(user); - } - - public void withdrawUser(User user, UserWithdrawReqDto dto) { - user.changeUserStatus(UserStatus.DELETED); - userRepository.save(user); - - userWithdrawDataService.withdrawItemByUserId(user.getId()); - userWithdrawDataService.withdrawQuestionByUserId(user.getId()); - userWithdrawDataService.withdrawFollowByUserId(user.getId()); - userWithdrawDataService.withdrawCelebByUserId(user.getId()); - userWithdrawDataService.withdrawUserByUserId(user.getId()); - - userWithdrawRepository.save(UserWithdraw.toEntity(user, dto)); - webHookService.sendWithdrawMessage(user); - - } - - public UserSocialDto getUserSocialData(User user) { - return UserSocialDto.of(user); - } -} diff --git a/src/main/java/com/sluv/server/domain/user/service/UserWithdrawDataService.java b/src/main/java/com/sluv/server/domain/user/service/UserWithdrawDataService.java deleted file mode 100644 index 9b7a970c..00000000 --- a/src/main/java/com/sluv/server/domain/user/service/UserWithdrawDataService.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.sluv.server.domain.user.service; - -import com.sluv.server.domain.celeb.repository.InterestedCelebRepository; -import com.sluv.server.domain.item.repository.RecentItemRepository; -import com.sluv.server.domain.item.service.TempItemService; -import com.sluv.server.domain.question.repository.RecentQuestionRepository; -import com.sluv.server.domain.user.repository.FollowRepository; -import com.sluv.server.domain.user.repository.UserReportStackRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class UserWithdrawDataService { - private final UserReportStackRepository userReportStackRepository; - private final RecentItemRepository recentItemRepository; - private final TempItemService tempItemService; - private final RecentQuestionRepository recentQuestionRepository; - private final FollowRepository followRepository; - private final InterestedCelebRepository interestedCelebRepository; - - @Async - @Transactional - public void withdrawItemByUserId(Long userId) { - recentItemRepository.deleteAllByUserId(userId); - tempItemService.deleteAllTempItem(userId); - } - - @Async - @Transactional - public void withdrawQuestionByUserId(Long userId) { - recentQuestionRepository.deleteAllByUserId(userId); - } - - @Async - @Transactional - public void withdrawFollowByUserId(Long userId) { - followRepository.deleteFolloweeByUserId(userId); - followRepository.deleteFollowerByUserId(userId); - } - - @Async - @Transactional - public void withdrawCelebByUserId(Long userId) { - interestedCelebRepository.deleteAllByUserId(userId); - } - - @Async - @Transactional - public void withdrawUserByUserId(Long userId) { - userReportStackRepository.deleteAllByReportedId(userId); - } -} \ No newline at end of file diff --git a/src/main/java/com/sluv/server/global/common/exception/ApplicationException.java b/src/main/java/com/sluv/server/global/common/exception/ApplicationException.java deleted file mode 100644 index 2a7d8d5a..00000000 --- a/src/main/java/com/sluv/server/global/common/exception/ApplicationException.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.sluv.server.global.common.exception; - -import lombok.Getter;import org.springframework.http.HttpStatus; - - -@Getter -public abstract class ApplicationException extends RuntimeException{ - - private final int errorCode; - private final HttpStatus httpStatus; - - protected ApplicationException(int errorCode, HttpStatus httpStatus, String message){ - super(message); - this.errorCode = errorCode; - this.httpStatus = httpStatus; - } -} diff --git a/src/main/java/com/sluv/server/global/discord/WebHookException.java b/src/main/java/com/sluv/server/global/discord/WebHookException.java deleted file mode 100644 index ba0d8ca7..00000000 --- a/src/main/java/com/sluv/server/global/discord/WebHookException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.global.discord; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class WebHookException extends ApplicationException { - public WebHookException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/global/firebase/exception/FcmException.java b/src/main/java/com/sluv/server/global/firebase/exception/FcmException.java deleted file mode 100644 index 1019062b..00000000 --- a/src/main/java/com/sluv/server/global/firebase/exception/FcmException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.global.firebase.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class FcmException extends ApplicationException { - public FcmException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} \ No newline at end of file diff --git a/src/main/java/com/sluv/server/global/jwt/exception/TokenException.java b/src/main/java/com/sluv/server/global/jwt/exception/TokenException.java deleted file mode 100644 index f7d89d8e..00000000 --- a/src/main/java/com/sluv/server/global/jwt/exception/TokenException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.sluv.server.global.jwt.exception; - -import com.sluv.server.global.common.exception.ApplicationException; -import org.springframework.http.HttpStatus; - -public abstract class TokenException extends ApplicationException { - public TokenException(int errorCode, HttpStatus httpStatus, String message) { - super(errorCode, httpStatus, message); - } -} diff --git a/src/main/java/com/sluv/server/global/jwt/filter/JwtAuthenticationFilter.java b/src/main/java/com/sluv/server/global/jwt/filter/JwtAuthenticationFilter.java deleted file mode 100644 index 47791d80..00000000 --- a/src/main/java/com/sluv/server/global/jwt/filter/JwtAuthenticationFilter.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.sluv.server.global.jwt.filter; - -import com.sluv.server.global.jwt.JwtProvider; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import lombok.RequiredArgsConstructor; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.filter.OncePerRequestFilter; - -@RequiredArgsConstructor -public class JwtAuthenticationFilter extends OncePerRequestFilter { - private final JwtProvider jwtProvider; - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - String token = jwtProvider.resolveToken(request); - - if (token != null && jwtProvider.validateToken(token)) { - Authentication authentication = jwtProvider.getAuthentication(token); - SecurityContextHolder.getContext().setAuthentication(authentication); - } - - filterChain.doFilter(request, response); - } -} diff --git a/src/main/java/com/sluv/server/global/s3/AWSS3Controller.java b/src/main/java/com/sluv/server/global/s3/AWSS3Controller.java deleted file mode 100644 index 7a8c288f..00000000 --- a/src/main/java/com/sluv/server/global/s3/AWSS3Controller.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.sluv.server.global.s3; - -import com.sluv.server.global.common.response.ErrorResponse; -import com.sluv.server.global.common.response.SuccessDataResponse; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.responses.ApiResponses; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequiredArgsConstructor -@RequestMapping("/app/s3/pre-signed-url") -public class AWSS3Controller { - private final AWSS3Service awss3Service; - - @Operation( - summary = "user 프로필 이미지 업로드", - description = "user 프로필 이미지 업로드" + - "\n imgExtension: 이미지 확장자" - ) - @ApiResponses(value = { - @ApiResponse(responseCode = "1000", description = "요청성공"), - @ApiResponse(responseCode = "5000", description = "서버내부 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode = "5001", description = "DB 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - @PostMapping("/user") - public ResponseEntity> getUserProfileUrl( - @RequestParam ImgExtension imgExtension) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result( - awss3Service.forUserProfile(imgExtension) - ) - .build() - ); - } - - @Operation( - summary = "아이템 이미지 업로드", - description = "아이템 이미지 업로드" + - "\n imgExtension: 이미지 확장자" - ) - @ApiResponses(value = { - @ApiResponse(responseCode = "1000", description = "요청성공"), - @ApiResponse(responseCode = "5000", description = "서버내부 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode = "5001", description = "DB 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - @PostMapping("/item") - public ResponseEntity> getItemImgUrl( - @RequestParam ImgExtension imgExtension) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result( - awss3Service.forItem(imgExtension) - ) - .build() - ); - } - - @Operation( - summary = "커뮤니티 게시글 이미지 업로드", - description = "커뮤니티 게시글 이미지 업로드" + - "\n imgExtension: 이미지 확장자" - ) - @ApiResponses(value = { - @ApiResponse(responseCode = "1000", description = "요청성공"), - @ApiResponse(responseCode = "5000", description = "서버내부 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode = "5001", description = "DB 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - @PostMapping("/question") - public ResponseEntity> getQuestionImgUrl( - @RequestParam ImgExtension imgExtension) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result( - awss3Service.forCommunityPost(imgExtension) - ) - .build() - ); - } - - @Operation( - summary = "커뮤니티 댓글 이미지 업로드", - description = "커뮤니티 댓글 이미지 업로드" + - "\n imgExtension: 이미지 확장자" - ) - @ApiResponses(value = { - @ApiResponse(responseCode = "1000", description = "요청성공"), - @ApiResponse(responseCode = "5000", description = "서버내부 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode = "5001", description = "DB 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - @PostMapping("/comment") - public ResponseEntity> getCommentImgUrl( - @RequestParam ImgExtension imgExtension) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result( - awss3Service.forCommunityComment(imgExtension) - ) - .build() - ); - } - - @Operation( - summary = "옷장 이미지 업로드", - description = "옷장 이미지 업로드" + - "\n imgExtension: 이미지 확장자" - ) - @ApiResponses(value = { - @ApiResponse(responseCode = "1000", description = "요청성공"), - @ApiResponse(responseCode = "5000", description = "서버내부 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), - @ApiResponse(responseCode = "5001", description = "DB 에러", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) - }) - @PostMapping("/closet") - public ResponseEntity> getClosetImgUrl( - @RequestParam ImgExtension imgExtension) { - return ResponseEntity.ok().body( - SuccessDataResponse.builder() - .result( - awss3Service.forCloset(imgExtension) - ) - .build() - ); - } -} diff --git a/src/main/resources b/src/main/resources deleted file mode 160000 index ae80ecf2..00000000 --- a/src/main/resources +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ae80ecf24234c95a4d997247fe0646d0557f261f diff --git a/src/test/java/com/sluv/server/fixture/ClosetFixture.java b/src/test/java/com/sluv/server/fixture/ClosetFixture.java deleted file mode 100644 index 9a151f9c..00000000 --- a/src/test/java/com/sluv/server/fixture/ClosetFixture.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.sluv.server.fixture; - -import static com.sluv.server.domain.closet.enums.ClosetStatus.PRIVATE; -import static com.sluv.server.domain.closet.enums.ClosetStatus.PUBLIC; - -import com.sluv.server.domain.closet.dto.ClosetReqDto; -import com.sluv.server.domain.closet.entity.Closet; -import com.sluv.server.domain.user.entity.User; - -public class ClosetFixture { - - public static Closet 공개_옷장_생성(User user, String name) { - ClosetReqDto closetReqDto = new ClosetReqDto(name, null, PUBLIC, null); - return Closet.toEntity(user, closetReqDto); - } - - public static Closet 비공개_옷장_생성(User user, String name) { - ClosetReqDto closetReqDto = new ClosetReqDto(name, null, PRIVATE, null); - return Closet.toEntity(user, closetReqDto); - } -} From 10a372349c3ed3b02e53f397ad2e0a61e33e2eb1 Mon Sep 17 00:00:00 2001 From: KJBig Date: Thu, 26 Sep 2024 15:18:10 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat=20:=20Github=20Actions=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 모듈별로 관리. --- .github/workflows/admin-ci-cd.yml | 89 ++++++++++ .../{mulit-ci-cd.yml => api-ci-cd.yml} | 25 +-- .github/workflows/batch-ci-cd.yml | 89 ++++++++++ .github/workflows/dev-ci-cd.yml | 166 +++++++++--------- .github/workflows/prod-ci-cd.yml | 166 +++++++++--------- 5 files changed, 358 insertions(+), 177 deletions(-) create mode 100644 .github/workflows/admin-ci-cd.yml rename .github/workflows/{mulit-ci-cd.yml => api-ci-cd.yml} (75%) create mode 100644 .github/workflows/batch-ci-cd.yml diff --git a/.github/workflows/admin-ci-cd.yml b/.github/workflows/admin-ci-cd.yml new file mode 100644 index 00000000..29ba0582 --- /dev/null +++ b/.github/workflows/admin-ci-cd.yml @@ -0,0 +1,89 @@ +name: Admin-Module CI/CD + +on: + push: + branches: [ main, develop ] + paths: + - 'sluv-admin/**' + - 'sluv-domain/**' + - 'sluv-common/**' + - 'sluv-infra/**' + +jobs: + admin-ci-cd: + runs-on: ubuntu-latest + steps: + - name: Checkout Latest Repo + uses: actions/checkout@v3 + with: + token: ${{ secrets.TOKEN_OF_GITHUB }} + submodules: true + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew :sluv-admin:clean :sluv-admin:build + + - name: Docker build + run: | + docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} + docker build -t sluv-springboot-${{ github.ref_name }}-admin-module sluv-admin/. + docker tag sluv-springboot-${{ github.ref_name }}-admin-module sluv2323/sluv-springboot-${{ github.ref_name }}-admin-module:latest + docker push sluv2323/sluv-springboot-${{ github.ref_name }}-admin-module:latest + + - name: Get timestamp + uses: gerred/actions/current-time@master + id: current-time + + - name: Run string replace + uses: frabert/replace-string-action@master + id: format-time + with: + pattern: '[:\.]+' + string: "${{ steps.current-time.outputs.time }}" + replace-with: '-' + flags: 'g' + + + - name: Deploy to Local Server + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.LOCAL_SERVER_HOST }} + username: ${{ secrets.LOCAL_SERVER_USER }} + password: ${{ secrets.LOCAL_SERVER_SSH_PASSWORD }} + script: | + echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S chmod +x /home/sluv/dev-server/dev-deploy-script.sh + echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S /home/sluv/dev-server/dev-deploy-script.sh + + current-time: + needs: admin-ci-cd + runs-on: ubuntu-latest + steps: + - name: Get Current Time + uses: 1466587594/get-current-time@v2 + id: current-time + with: + format: YYYY-MM-DDTHH:mm:ss + utcOffset: "+09:00" # 기준이 UTC이기 때문에 한국시간인 KST를 맞추기 위해 +9시간 추가 + + - name: Print Current Time + run: echo "Current Time=${{steps.current-time.outputs.formattedTime}}" # current-time 에서 지정한 포맷대로 현재 시간 출력 + shell: bash + + ## discord + action-discord: + needs: admin-ci-cd + runs-on: ubuntu-latest + steps: + - name: Discord Alarm + uses: tsickert/discord-webhook@v5.3.0 + with: + webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} + content: "Dev Deploy ${{ job.status }}" \ No newline at end of file diff --git a/.github/workflows/mulit-ci-cd.yml b/.github/workflows/api-ci-cd.yml similarity index 75% rename from .github/workflows/mulit-ci-cd.yml rename to .github/workflows/api-ci-cd.yml index 75ddbe26..94767dc3 100644 --- a/.github/workflows/mulit-ci-cd.yml +++ b/.github/workflows/api-ci-cd.yml @@ -1,13 +1,16 @@ -name: dev CI/CD +name: Api-Module CI/CD on: push: - branches: [ to_multi-module ] + branches: [ main, develop ] paths: - - 'api-module/**' + - 'sluv-api/**' + - 'sluv-domain/**' + - 'sluv-common/**' + - 'sluv-infra/**' jobs: - dev-ci-cd: + api-ci-cd: runs-on: ubuntu-latest steps: - name: Checkout Latest Repo @@ -31,9 +34,9 @@ jobs: - name: Docker build run: | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} - docker build -t sluv-api-module ./sluv-api - docker tag sluv-api-module sluv2323/sluv-api-module:latest - docker push sluv2323/sluv-api-module:latest + docker build -t sluv-springboot-${{ github.ref_name }}-api-module sluv-api/. + docker tag sluv-springboot-${{ github.ref_name }}-api-module sluv2323/sluv-springboot-${{ github.ref_name }}-api-module:latest + docker push sluv2323/sluv-springboot-${{ github.ref_name }}-api-module:latest - name: Get timestamp uses: gerred/actions/current-time@master @@ -56,11 +59,11 @@ jobs: username: ${{ secrets.LOCAL_SERVER_USER }} password: ${{ secrets.LOCAL_SERVER_SSH_PASSWORD }} script: | - chmod +x /home/sluv/api_module_deploy_script.sh - echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S /home/sluv/api_module_deploy_script.sh + echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S chmod +x /home/sluv/dev-server/dev-deploy-script.sh + echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S /home/sluv/dev-server/dev-deploy-script.sh current-time: - needs: dev-ci-cd + needs: api-ci-cd runs-on: ubuntu-latest steps: - name: Get Current Time @@ -76,7 +79,7 @@ jobs: ## discord action-discord: - needs: dev-ci-cd + needs: api-ci-cd runs-on: ubuntu-latest steps: - name: Discord Alarm diff --git a/.github/workflows/batch-ci-cd.yml b/.github/workflows/batch-ci-cd.yml new file mode 100644 index 00000000..773695c4 --- /dev/null +++ b/.github/workflows/batch-ci-cd.yml @@ -0,0 +1,89 @@ +name: Batch-Module CI/CD + +on: + push: + branches: [ main, develop ] + paths: + - 'sluv-batch/**' + - 'sluv-domain/**' + - 'sluv-common/**' + - 'sluv-infra/**' + +jobs: + batch-ci-cd: + runs-on: ubuntu-latest + steps: + - name: Checkout Latest Repo + uses: actions/checkout@v3 + with: + token: ${{ secrets.TOKEN_OF_GITHUB }} + submodules: true + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew :sluv-batch:clean :sluv-batch:build + + - name: Docker build + run: | + docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} + docker build -t sluv-springboot-${{ github.ref_name }}-batch-module sluv-batch/. + docker tag sluv-springboot-${{ github.ref_name }}-batch-module sluv2323/sluv-springboot-${{ github.ref_name }}-batch-module:latest + docker push sluv2323/sluv-springboot-${{ github.ref_name }}-batch-module:latest + + - name: Get timestamp + uses: gerred/actions/current-time@master + id: current-time + + - name: Run string replace + uses: frabert/replace-string-action@master + id: format-time + with: + pattern: '[:\.]+' + string: "${{ steps.current-time.outputs.time }}" + replace-with: '-' + flags: 'g' + + + - name: Deploy to Local Server + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.LOCAL_SERVER_HOST }} + username: ${{ secrets.LOCAL_SERVER_USER }} + password: ${{ secrets.LOCAL_SERVER_SSH_PASSWORD }} + script: | + echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S chmod +x /home/sluv/dev-server/dev-deploy-script.sh + echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S /home/sluv/dev-server/dev-deploy-script.sh + + current-time: + needs: batch-ci-cd + runs-on: ubuntu-latest + steps: + - name: Get Current Time + uses: 1466587594/get-current-time@v2 + id: current-time + with: + format: YYYY-MM-DDTHH:mm:ss + utcOffset: "+09:00" # 기준이 UTC이기 때문에 한국시간인 KST를 맞추기 위해 +9시간 추가 + + - name: Print Current Time + run: echo "Current Time=${{steps.current-time.outputs.formattedTime}}" # current-time 에서 지정한 포맷대로 현재 시간 출력 + shell: bash + + ## discord + action-discord: + needs: batch-ci-cd + runs-on: ubuntu-latest + steps: + - name: Discord Alarm + uses: tsickert/discord-webhook@v5.3.0 + with: + webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} + content: "Dev Deploy ${{ job.status }}" \ No newline at end of file diff --git a/.github/workflows/dev-ci-cd.yml b/.github/workflows/dev-ci-cd.yml index 4d1eec75..e00972d3 100644 --- a/.github/workflows/dev-ci-cd.yml +++ b/.github/workflows/dev-ci-cd.yml @@ -1,83 +1,83 @@ -name: dev CI/CD - -on: - push: - branches: [ develop ] - -jobs: - dev-ci-cd: - runs-on: ubuntu-latest - steps: - - name: Checkout Latest Repo - uses: actions/checkout@v3 - with: - token: ${{ secrets.TOKEN_OF_GITHUB }} - submodules: true - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - - name: Build with Gradle - run: ./gradlew clean build - - - name: Docker build - run: | - docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} - docker build -t sluv-springboot-main-cicd . - docker tag sluv-springboot-main-cicd sluv2323/sluv-springboot-main-cicd:latest - docker push sluv2323/sluv-springboot-main-cicd:latest - - - name: Get timestamp - uses: gerred/actions/current-time@master - id: current-time - - - name: Run string replace - uses: frabert/replace-string-action@master - id: format-time - with: - pattern: '[:\.]+' - string: "${{ steps.current-time.outputs.time }}" - replace-with: '-' - flags: 'g' - - - - name: Deploy to Local Server - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.LOCAL_SERVER_HOST }} - username: ${{ secrets.LOCAL_SERVER_USER }} - password: ${{ secrets.LOCAL_SERVER_SSH_PASSWORD }} - script: | - chmod +x /home/sluv/dev_deploy_script.sh - echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S /home/sluv/dev_deploy_script.sh - - current-time: - needs: dev-ci-cd - runs-on: ubuntu-latest - steps: - - name: Get Current Time - uses: 1466587594/get-current-time@v2 - id: current-time - with: - format: YYYY-MM-DDTHH:mm:ss - utcOffset: "+09:00" # 기준이 UTC이기 때문에 한국시간인 KST를 맞추기 위해 +9시간 추가 - - - name: Print Current Time - run: echo "Current Time=${{steps.current-time.outputs.formattedTime}}" # current-time 에서 지정한 포맷대로 현재 시간 출력 - shell: bash - - ## discord - action-discord: - needs: dev-ci-cd - runs-on: ubuntu-latest - steps: - - name: Discord Alarm - uses: tsickert/discord-webhook@v5.3.0 - with: - webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} - content: "Dev Deploy ${{ job.status }}" \ No newline at end of file +#name: dev CI/CD +# +#on: +# push: +# branches: [ develop ] +# +#jobs: +# dev-ci-cd: +# runs-on: ubuntu-latest +# steps: +# - name: Checkout Latest Repo +# uses: actions/checkout@v3 +# with: +# token: ${{ secrets.TOKEN_OF_GITHUB }} +# submodules: true +# - name: Set up JDK 17 +# uses: actions/setup-java@v3 +# with: +# java-version: '17' +# distribution: 'temurin' +# +# - name: Grant execute permission for gradlew +# run: chmod +x gradlew +# +# - name: Build with Gradle +# run: ./gradlew clean build +# +# - name: Docker build +# run: | +# docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} +# docker build -t sluv-springboot-main-cicd . +# docker tag sluv-springboot-main-cicd sluv2323/sluv-springboot-main-cicd:latest +# docker push sluv2323/sluv-springboot-main-cicd:latest +# +# - name: Get timestamp +# uses: gerred/actions/current-time@master +# id: current-time +# +# - name: Run string replace +# uses: frabert/replace-string-action@master +# id: format-time +# with: +# pattern: '[:\.]+' +# string: "${{ steps.current-time.outputs.time }}" +# replace-with: '-' +# flags: 'g' +# +# +# - name: Deploy to Local Server +# uses: appleboy/ssh-action@master +# with: +# host: ${{ secrets.LOCAL_SERVER_HOST }} +# username: ${{ secrets.LOCAL_SERVER_USER }} +# password: ${{ secrets.LOCAL_SERVER_SSH_PASSWORD }} +# script: | +# chmod +x /home/sluv/dev_deploy_script.sh +# echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S /home/sluv/dev_deploy_script.sh +# +# current-time: +# needs: dev-ci-cd +# runs-on: ubuntu-latest +# steps: +# - name: Get Current Time +# uses: 1466587594/get-current-time@v2 +# id: current-time +# with: +# format: YYYY-MM-DDTHH:mm:ss +# utcOffset: "+09:00" # 기준이 UTC이기 때문에 한국시간인 KST를 맞추기 위해 +9시간 추가 +# +# - name: Print Current Time +# run: echo "Current Time=${{steps.current-time.outputs.formattedTime}}" # current-time 에서 지정한 포맷대로 현재 시간 출력 +# shell: bash +# +# ## discord +# action-discord: +# needs: dev-ci-cd +# runs-on: ubuntu-latest +# steps: +# - name: Discord Alarm +# uses: tsickert/discord-webhook@v5.3.0 +# with: +# webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} +# content: "Dev Deploy ${{ job.status }}" \ No newline at end of file diff --git a/.github/workflows/prod-ci-cd.yml b/.github/workflows/prod-ci-cd.yml index e04275c1..063ba8a4 100644 --- a/.github/workflows/prod-ci-cd.yml +++ b/.github/workflows/prod-ci-cd.yml @@ -1,83 +1,83 @@ -name: prod CI/CD - -on: - push: - branches: [ main ] - -jobs: - prod-ci-cd: - runs-on: ubuntu-latest - steps: - - name: Checkout Latest Repo - uses: actions/checkout@v3 - with: - token: ${{ secrets.TOKEN_OF_GITHUB }} - submodules: true - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - - name: Build with Gradle - run: ./gradlew clean build - - - name: Docker build - run: | - docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} - docker build -t sluv-springboot-prod-cicd . - docker tag sluv-springboot-prod-cicd sluv2323/sluv-springboot-prod-cicd:latest - docker push sluv2323/sluv-springboot-prod-cicd:latest - - - name: Get timestamp - uses: gerred/actions/current-time@master - id: current-time - - - name: Run string replace - uses: frabert/replace-string-action@master - id: format-time - with: - pattern: '[:\.]+' - string: "${{ steps.current-time.outputs.time }}" - replace-with: '-' - flags: 'g' - - - - name: Deploy to Local Server - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.LOCAL_SERVER_HOST }} - username: ${{ secrets.LOCAL_SERVER_USER }} - password: ${{ secrets.LOCAL_SERVER_SSH_PASSWORD }} - script: | - chmod +x /home/sluv/prod_deploy_script.sh - echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S /home/sluv/prod_deploy_script.sh - - current-time: - needs: prod-ci-cd - runs-on: ubuntu-latest - steps: - - name: Get Current Time - uses: 1466587594/get-current-time@v2 - id: current-time - with: - format: YYYY-MM-DDTHH:mm:ss - utcOffset: "+09:00" # 기준이 UTC이기 때문에 한국시간인 KST를 맞추기 위해 +9시간 추가 - - - name: Print Current Time - run: echo "Current Time=${{steps.current-time.outputs.formattedTime}}" # current-time 에서 지정한 포맷대로 현재 시간 출력 - shell: bash - - ## discord - action-discord: - needs: prod-ci-cd - runs-on: ubuntu-latest - steps: - - name: Discord Alarm - uses: tsickert/discord-webhook@v5.3.0 - with: - webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} - content: "Prod Deploy ${{ job.status }}" \ No newline at end of file +#name: prod CI/CD +# +#on: +# push: +# branches: [ main ] +# +#jobs: +# prod-ci-cd: +# runs-on: ubuntu-latest +# steps: +# - name: Checkout Latest Repo +# uses: actions/checkout@v3 +# with: +# token: ${{ secrets.TOKEN_OF_GITHUB }} +# submodules: true +# - name: Set up JDK 17 +# uses: actions/setup-java@v3 +# with: +# java-version: '17' +# distribution: 'temurin' +# +# - name: Grant execute permission for gradlew +# run: chmod +x gradlew +# +# - name: Build with Gradle +# run: ./gradlew clean build +# +# - name: Docker build +# run: | +# docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} +# docker build -t sluv-springboot-prod-cicd . +# docker tag sluv-springboot-prod-cicd sluv2323/sluv-springboot-prod-cicd:latest +# docker push sluv2323/sluv-springboot-prod-cicd:latest +# +# - name: Get timestamp +# uses: gerred/actions/current-time@master +# id: current-time +# +# - name: Run string replace +# uses: frabert/replace-string-action@master +# id: format-time +# with: +# pattern: '[:\.]+' +# string: "${{ steps.current-time.outputs.time }}" +# replace-with: '-' +# flags: 'g' +# +# +# - name: Deploy to Local Server +# uses: appleboy/ssh-action@master +# with: +# host: ${{ secrets.LOCAL_SERVER_HOST }} +# username: ${{ secrets.LOCAL_SERVER_USER }} +# password: ${{ secrets.LOCAL_SERVER_SSH_PASSWORD }} +# script: | +# chmod +x /home/sluv/prod_deploy_script.sh +# echo ${{ secrets.LOCAL_SERVER_SUDO_PASSWORD }} | sudo -S /home/sluv/prod_deploy_script.sh +# +# current-time: +# needs: prod-ci-cd +# runs-on: ubuntu-latest +# steps: +# - name: Get Current Time +# uses: 1466587594/get-current-time@v2 +# id: current-time +# with: +# format: YYYY-MM-DDTHH:mm:ss +# utcOffset: "+09:00" # 기준이 UTC이기 때문에 한국시간인 KST를 맞추기 위해 +9시간 추가 +# +# - name: Print Current Time +# run: echo "Current Time=${{steps.current-time.outputs.formattedTime}}" # current-time 에서 지정한 포맷대로 현재 시간 출력 +# shell: bash +# +# ## discord +# action-discord: +# needs: prod-ci-cd +# runs-on: ubuntu-latest +# steps: +# - name: Discord Alarm +# uses: tsickert/discord-webhook@v5.3.0 +# with: +# webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }} +# content: "Prod Deploy ${{ job.status }}" \ No newline at end of file