diff --git a/Match-Api/src/main/generated/com/example/matchapi/admin/notice/mapper/AdminNoticeMapperImpl.java b/Match-Api/src/main/generated/com/example/matchapi/admin/notice/mapper/AdminNoticeMapperImpl.java index a6f654b8..946d8471 100644 --- a/Match-Api/src/main/generated/com/example/matchapi/admin/notice/mapper/AdminNoticeMapperImpl.java +++ b/Match-Api/src/main/generated/com/example/matchapi/admin/notice/mapper/AdminNoticeMapperImpl.java @@ -10,7 +10,7 @@ @Generated( value = "org.mapstruct.ap.MappingProcessor", - date = "2023-12-05T09:50:48+0900", + date = "2023-12-07T09:51:10+0900", comments = "version: 1.5.3.Final, compiler: javac, environment: Java 11.0.19 (Oracle Corporation)" ) public class AdminNoticeMapperImpl implements AdminNoticeMapper { diff --git a/Match-Api/src/main/generated/com/example/matchapi/order/mapper/OrderMapperImpl.java b/Match-Api/src/main/generated/com/example/matchapi/order/mapper/OrderMapperImpl.java index 5bc23f92..0b244f53 100644 --- a/Match-Api/src/main/generated/com/example/matchapi/order/mapper/OrderMapperImpl.java +++ b/Match-Api/src/main/generated/com/example/matchapi/order/mapper/OrderMapperImpl.java @@ -9,7 +9,7 @@ @Generated( value = "org.mapstruct.ap.MappingProcessor", - date = "2023-12-05T09:50:48+0900", + date = "2023-12-07T13:17:18+0900", comments = "version: 1.5.3.Final, compiler: javac, environment: Java 11.0.19 (Oracle Corporation)" ) public class OrderMapperImpl implements OrderMapper { diff --git a/Match-Api/src/main/generated/com/example/matchapi/portone/mapper/PaymentMapperImpl.java b/Match-Api/src/main/generated/com/example/matchapi/portone/mapper/PaymentMapperImpl.java index 9330c095..651f8bd4 100644 --- a/Match-Api/src/main/generated/com/example/matchapi/portone/mapper/PaymentMapperImpl.java +++ b/Match-Api/src/main/generated/com/example/matchapi/portone/mapper/PaymentMapperImpl.java @@ -13,7 +13,7 @@ @Generated( value = "org.mapstruct.ap.MappingProcessor", - date = "2023-12-05T09:50:48+0900", + date = "2023-12-07T13:17:18+0900", comments = "version: 1.5.3.Final, compiler: javac, environment: Java 11.0.19 (Oracle Corporation)" ) public class PaymentMapperImpl implements PaymentMapper { diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/banner/controller/AdminBannerController.java b/Match-Api/src/main/java/com/example/matchapi/admin/banner/controller/AdminBannerController.java index 485874c6..b9fd4cd4 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/banner/controller/AdminBannerController.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/banner/controller/AdminBannerController.java @@ -4,6 +4,7 @@ import com.example.matchapi.banner.dto.BannerReq; import com.example.matchapi.banner.dto.BannerRes; import com.example.matchcommon.reponse.CommonResponse; +import com.example.matchcommon.reponse.PageResponse; import com.example.matchdomain.banner.enums.BannerType; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -29,11 +30,36 @@ public class AdminBannerController { @PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) @Operation(summary = "ADMIN-08-01 배너 업로드") public CommonResponse> uploadBanner( - //@RequestPart BannerType bannerType, @RequestPart MultipartFile bannerImage, - @RequestPart BannerReq.BannerUpload bannerUploadDto + @RequestPart("bannerUploadDto") BannerReq.BannerUpload bannerUploadDto ){ - System.out.println(bannerUploadDto.getContentsUrl()); return CommonResponse.onSuccess(adminBannerService.uploadBanner(BannerType.EVENT, bannerImage, bannerUploadDto)); } + + @GetMapping("") + @Operation(summary = "ADMIN-08-02 배너 조회") + public CommonResponse>> getBannerLists( + @Parameter(description = "페이지", example = "0") @RequestParam(required = false, defaultValue = "0") int page, + @Parameter(description = "페이지 사이즈", example = "10") @RequestParam(required = false, defaultValue = "10") int size + + ){ + return CommonResponse.onSuccess(adminBannerService.getBannerLists(page, size)); + } + + @DeleteMapping("/{bannerId}") + @Operation(summary = "ADMIN-08-03 배너 삭제") + public CommonResponse deleteBanner(@PathVariable Long bannerId){ + adminBannerService.deleteBanner(bannerId); + return CommonResponse.onSuccess("삭제 성공"); + } + + @PatchMapping("/{bannerId}") + @Operation(summary = "ADMIN-08-04 배너 수정") + public CommonResponse patchBanner( + @PathVariable Long bannerId, + @RequestPart(value = "bannerImage", required = false) MultipartFile bannerImage, + @RequestPart("bannerPatchDto") BannerReq.BannerPatchDto bannerPatchDto){ + adminBannerService.patchBanner(bannerId, bannerPatchDto, bannerImage); + return CommonResponse.onSuccess("수정 성공"); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/banner/service/AdminBannerService.java b/Match-Api/src/main/java/com/example/matchapi/admin/banner/service/AdminBannerService.java index 524f4af2..45d664ec 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/banner/service/AdminBannerService.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/banner/service/AdminBannerService.java @@ -3,14 +3,15 @@ import com.example.matchapi.banner.converter.BannerConverter; import com.example.matchapi.banner.dto.BannerReq; import com.example.matchapi.banner.dto.BannerRes; +import com.example.matchcommon.reponse.PageResponse; import com.example.matchdomain.banner.adaptor.BannerAdaptor; import com.example.matchdomain.banner.entity.Banner; import com.example.matchdomain.banner.enums.BannerType; -import com.example.matchdomain.banner.repository.BannerRepository; import com.example.matchinfrastructure.config.s3.S3UploadService; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; +import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -20,7 +21,6 @@ @Service @RequiredArgsConstructor public class AdminBannerService { - private final BannerRepository bannerRepository; private final BannerConverter bannerConverter; private final S3UploadService s3UploadService; private final BannerAdaptor bannerAdaptor; @@ -31,7 +31,7 @@ public List uploadBanner(BannerType bannerType, MultipartFile bannerImage, BannerReq.BannerUpload bannerUploadDto) { String bannerImg = s3UploadService.uploadBannerImage(bannerImage); - bannerRepository.save(bannerConverter.convertToBannerUpload(bannerType, bannerImg, bannerUploadDto)); + bannerAdaptor.save(bannerConverter.convertToBannerUpload(bannerType, bannerImg, bannerUploadDto)); return cachingBannerList(); } @@ -41,4 +41,29 @@ public List cachingBannerList() { return bannerConverter.convertToBannerList(banners); } + + @Transactional + public void deleteBanner(Long bannerId) { + Banner banner = bannerAdaptor.findById(bannerId); + s3UploadService.deleteFile(banner.getBannerImg()); + bannerAdaptor.deleteById(bannerId); + } + + @Transactional + public void patchBanner(Long bannerId, BannerReq.BannerPatchDto bannerPatchDto, MultipartFile bannerImage) { + Banner banner = bannerAdaptor.findById(bannerId); + if(bannerPatchDto.isEditImage()){ + s3UploadService.deleteFile(banner.getBannerImg()); + String imgUrl = s3UploadService.uploadBannerImage(bannerImage); + banner.updateBanner(bannerPatchDto.getName(), banner.getStartDate(), banner.getEndDate(), imgUrl); + }else{ + banner.updateBanner(bannerPatchDto.getName(), banner.getStartDate(), banner.getEndDate(), banner.getBannerImg()); + } + bannerAdaptor.save(banner); + } + + public PageResponse> getBannerLists(int page, int size) { + Page banners = bannerAdaptor.getBannerLists(page, size); + return new PageResponse<>(banners.isLast(), banners.getSize(), bannerConverter.convertToBannerLists(banners.getContent())); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/donation/controller/AdminDonationController.java b/Match-Api/src/main/java/com/example/matchapi/admin/donation/controller/AdminDonationController.java index 06691b62..d142eb85 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/donation/controller/AdminDonationController.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/donation/controller/AdminDonationController.java @@ -39,6 +39,15 @@ public CommonResponse getDonationInfo(){ return CommonResponse.onSuccess(info); } + @GetMapping("/regular") + @ApiErrorCodeExample(UserAuthErrorCode.class) + @Operation(summary = "ADMIN-05-01-01 정기 결제 현황 파악", description = "정기 결제 현황파악") + public CommonResponse getRegularInfo(){ + return CommonResponse.onSuccess(adminDonationService.getRegularInfo()); + } + + + @GetMapping("/{donationId}") @ApiErrorCodeExample(UserAuthErrorCode.class) @Operation(summary = "ADMIN-05-02 기부금 상세조회 API", description = "기부금 상세조회 API") @@ -91,4 +100,5 @@ public CommonResponse>> getPro Project project = projectService.findByProjectId(projectId); return CommonResponse.onSuccess(adminDonationService.getProjectDonationLists(project, page, size)); } + } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/donation/converter/AdminDonationConverter.java b/Match-Api/src/main/java/com/example/matchapi/admin/donation/converter/AdminDonationConverter.java index e527a3d8..872892b8 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/donation/converter/AdminDonationConverter.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/donation/converter/AdminDonationConverter.java @@ -124,7 +124,22 @@ private DonationRes.ProjectDonationDto convertToDonationInfo(DonationUser result .userName(result.getUser().getName()) .amount(result.getPrice()) .importedAmount((int) (result.getPrice()*0.1)) - .waitingSortingAmount(result.getDonationStatus().equals(DonationStatus.PARTIAL_EXECUTION) ? result.getExecutionPrice() : (long) (result.getPrice() * 0.9)) + .waitingSortingAmount(result.getDonationStatus().equals(DonationStatus.PARTIAL_EXECUTION) ? (long) (result.getPrice() * 0.9 - result.getExecutionPrice()) : (long) (result.getPrice() * 0.9)) + .partialAmount(result.getExecutionPrice()) .build(); } + + public DonationRes.RegularInfoDto convertToRegularInfoDto(Long beforeCnt, Long underCnt, Long successCnt, String successAmount, Long regularCnt, String totalAmount, Long beforeMonthRegularCnt, String beforeMonthRegularAmount) { + return DonationRes.RegularInfoDto + .builder() + .beforeCnt(beforeCnt) + .underCnt(underCnt) + .successCnt(successCnt) + .successAmount(successAmount) + .regularCnt(regularCnt) + .regularAmount(totalAmount) + .beforeMonthRegularCnt(beforeMonthRegularCnt) + .beforeMonthRegularAmount(beforeMonthRegularAmount) + .build(); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java b/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java index 444be6a8..8e516b88 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/donation/service/AdminDonationService.java @@ -8,15 +8,19 @@ import com.example.matchcommon.reponse.PageResponse; import com.example.matchdomain.donation.adaptor.DonationAdaptor; import com.example.matchdomain.donation.adaptor.DonationHistoryAdaptor; +import com.example.matchdomain.donation.adaptor.RegularPaymentAdaptor; import com.example.matchdomain.donation.entity.DonationHistory; import com.example.matchdomain.donation.entity.DonationUser; import com.example.matchdomain.donation.entity.HistoryImage; +import com.example.matchdomain.donation.entity.RegularPayment; +import com.example.matchdomain.donation.entity.enums.RegularPayStatus; import com.example.matchdomain.donation.repository.HistoryImageRepository; import com.example.matchdomain.project.adaptor.ProjectAdaptor; import com.example.matchdomain.project.entity.Project; import com.example.matchinfrastructure.config.s3.S3UploadService; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; + +import org.springframework.cache.annotation.Cacheable; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; @@ -25,6 +29,7 @@ import javax.transaction.Transactional; import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.YearMonth; import java.time.temporal.TemporalAdjusters; import java.util.ArrayList; import java.util.List; @@ -43,9 +48,9 @@ public class AdminDonationService { private final AdminDonationConverter adminDonationConverter; private final S3UploadService s3UploadService; private final ProjectAdaptor projectAdaptor; + private final RegularPaymentAdaptor paymentAdaptor; private final HistoryImageRepository historyImageRepository; - @Autowired - private ApplicationEventPublisher eventPublisher; + private final ApplicationEventPublisher eventPublisher; @Transactional @@ -57,6 +62,7 @@ public DonationRes.DonationInfo getDonationInfo() { int oneDayDonationAmount = 0; int weekendDonationAmount = 0; int monthlyDonationAmount = 0; + int totalDonationAmount = 0; for (DonationUser donationUser : donationUsers) { if(donationUser.getCreatedAt().isAfter(LocalDateTime.parse(localDate+FIRST_TIME))&&donationUser.getCreatedAt().isBefore(LocalDateTime.parse(localDate+LAST_TIME))){ oneDayDonationAmount += donationUser.getPrice(); @@ -67,9 +73,10 @@ public DonationRes.DonationInfo getDonationInfo() { if(donationUser.getCreatedAt().isAfter(LocalDateTime.parse(localDate.with(TemporalAdjusters.firstDayOfMonth())+FIRST_TIME))&&donationUser.getCreatedAt().isBefore( LocalDateTime.parse(localDate.with(TemporalAdjusters.lastDayOfMonth())+LAST_TIME))){ monthlyDonationAmount += donationUser.getPrice(); } + totalDonationAmount += donationUser.getPrice(); } - return new DonationRes.DonationInfo(donationHelper.parsePriceComma(oneDayDonationAmount),donationHelper.parsePriceComma(weekendDonationAmount),donationHelper.parsePriceComma(monthlyDonationAmount)); + return new DonationRes.DonationInfo(donationHelper.parsePriceComma(oneDayDonationAmount),donationHelper.parsePriceComma(weekendDonationAmount),donationHelper.parsePriceComma(monthlyDonationAmount), donationHelper.parsePriceComma(totalDonationAmount)); } public DonationRes.DonationDetail getDonationDetail(Long donationId) { @@ -181,4 +188,62 @@ public PageResponse> getProjectDonationList return new PageResponse<>(donationUsers.isLast(),donationUsers.getTotalElements(), adminDonationConverter.convertToDonationLists(donationUsers.getContent())); } + + @Transactional + @Cacheable(value = "regularInfo", cacheManager = "redisCacheManager") + public DonationRes.RegularInfoDto getRegularInfo() { + List donationUsers = donationAdaptor.getRegularDonationLists(); + List regularPayments = paymentAdaptor.getRegularInfo(); + + Long beforeCnt = 0L, underCnt = 0L, successCnt = 0L, successAmount = 0L; + Long regularCnt = 0L, totalAmount = 0L; + Long beforeMonthRegularCnt = 0L, beforeMonthRegularAmount = 0L; + YearMonth previousMonth = YearMonth.now().minusMonths(1); + + + for(DonationUser donationUser : donationUsers){ + switch (donationUser.getDonationStatus()){ + case EXECUTION_SUCCESS: + case PARTIAL_EXECUTION: + successAmount += donationUser.getExecutionPrice(); + successCnt++; + break; + case EXECUTION_BEFORE: + beforeCnt++; + break; + case EXECUTION_UNDER: + underCnt++; + break; + case EXECUTION_REFUND: + break; + } + + if(donationUser.getRegularPaymentId()!=null) { + YearMonth creationMonth = YearMonth.from(donationUser.getCreatedAt()); + if (creationMonth.equals(previousMonth)) { + beforeMonthRegularAmount += donationUser.getPrice(); + beforeMonthRegularCnt++; + } + } + } + + for (RegularPayment payment : regularPayments) { + if (payment.getRegularPayStatus().equals(RegularPayStatus.PROCEEDING)) { + regularCnt++; + totalAmount += payment.getAmount(); + } + } + + return adminDonationConverter.convertToRegularInfoDto(beforeCnt, underCnt, successCnt, donationHelper.parsePriceComma( + Math.toIntExact(successAmount)), regularCnt, donationHelper.parsePriceComma(Math.toIntExact(totalAmount)), beforeMonthRegularCnt, donationHelper.parsePriceComma( + Math.toIntExact(beforeMonthRegularAmount))); + } + + public Long countByUserId(Long userId) { + return paymentAdaptor.countByUserId(userId); + } + + public List findByUserId(Long userId) { + return donationAdaptor.findByUserId(userId); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/event/controller/AdminEventController.java b/Match-Api/src/main/java/com/example/matchapi/admin/event/controller/AdminEventController.java index e7eb9a14..b578d3d9 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/event/controller/AdminEventController.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/event/controller/AdminEventController.java @@ -28,4 +28,12 @@ public CommonResponse uploadEventList(@RequestBody EventUploadReq eventU return CommonResponse.onSuccess("업로드 성공"); } + @DeleteMapping("/{eventId}") + @Operation(summary = "ADMIN-09-02 이벤트 삭제") + public CommonResponse deleteEvent(@PathVariable Long eventId){ + adminEventService.deleteEvent(eventId); + return CommonResponse.onSuccess("삭제 성공"); + } + + } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/event/service/AdminEventService.java b/Match-Api/src/main/java/com/example/matchapi/admin/event/service/AdminEventService.java index 1265b47a..82be48e9 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/event/service/AdminEventService.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/event/service/AdminEventService.java @@ -4,17 +4,17 @@ import com.example.matchapi.common.model.ContentsList; import com.example.matchapi.common.util.MessageHelper; import com.example.matchapi.event.converter.EventConverter; -import com.example.matchapi.event.service.EventService; -import com.example.matchcommon.annotation.RedissonLock; import com.example.matchcommon.constants.enums.Topic; +import com.example.matchdomain.event.adaptor.EventAdaptor; +import com.example.matchdomain.event.adaptor.EventContentAdaptor; import com.example.matchdomain.event.entity.Event; import com.example.matchdomain.event.entity.EventContent; -import com.example.matchdomain.event.repository.EventContentRepository; -import com.example.matchdomain.event.repository.EventRepository; +import com.example.matchinfrastructure.config.s3.S3UploadService; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.CacheEvict; import org.springframework.stereotype.Service; +import javax.transaction.Transactional; import java.util.ArrayList; import java.util.List; @@ -25,16 +25,17 @@ @Service @RequiredArgsConstructor public class AdminEventService { - private final EventRepository eventRepository; - private final EventContentRepository eventContentRepository; private final EventConverter eventConverter; - private final EventService eventService; private final MessageHelper messageHelper; - @RedissonLock(LockName = "이벤트 업로드", key = "#eventUploadReq") + private final EventAdaptor eventAdaptor; + private final EventContentAdaptor eventContentAdaptor; + private final S3UploadService s3UploadService; + + @Transactional @CacheEvict(value = "eventCache", allEntries = true, cacheManager = "ehcacheManager") public void uploadEventList(EventUploadReq eventUploadReq) { - Event event = eventRepository.save(eventConverter.convertToEventUpload(eventUploadReq, eventUploadReq.getThumbnail())); + Event event = eventAdaptor.save(eventConverter.convertToEventUpload(eventUploadReq, eventUploadReq.getThumbnail())); Long eventId = event.getId(); @@ -48,10 +49,22 @@ public void uploadEventList(EventUploadReq eventUploadReq) { } } - eventContentRepository.saveAll(eventContents); + eventContentAdaptor.saveAll(eventContents); messageHelper.helpFcmMessage(EVENT_UPLOAD_BODY, Topic.EVENT_UPLOAD, event.getId()); } + @Transactional + @CacheEvict(value = "eventCache", allEntries = true, cacheManager = "ehcacheManager") + public void deleteEvent(Long eventId) { + Event event = eventAdaptor.findByEvent(eventId); + List eventContents = event.getEventContents(); + for(EventContent eventContent : eventContents){ + if(eventContent.getContentsType().equals(IMG)){ + s3UploadService.deleteFile(eventContent.getContents()); + } + } + eventAdaptor.deleteByEventId(eventId); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/keyword/controller/AdminKeywordController.java b/Match-Api/src/main/java/com/example/matchapi/admin/keyword/controller/AdminKeywordController.java index b233bf8e..ac6e2fbc 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/keyword/controller/AdminKeywordController.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/keyword/controller/AdminKeywordController.java @@ -34,4 +34,11 @@ public CommonResponse> postKeywordList( return CommonResponse.onSuccess(adminKeywordService.postKeyword(keyword)); } + + @DeleteMapping("/{keywordId}") + @Operation(summary = "07-03 ADMIN Keyword 삭제🔎") + public CommonResponse deleteKeyword(@PathVariable Long keywordId){ + adminKeywordService.deleteKeyword(keywordId); + return CommonResponse.onSuccess("삭제 성공"); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/keyword/service/AdminKeywordService.java b/Match-Api/src/main/java/com/example/matchapi/admin/keyword/service/AdminKeywordService.java index d44f66aa..ae622c41 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/keyword/service/AdminKeywordService.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/keyword/service/AdminKeywordService.java @@ -40,4 +40,9 @@ public List cachingKeywordList(){ ); return keywordLists; } + + @CacheEvict(cacheNames = "keywordList", cacheManager = "ehcacheManager") + public void deleteKeyword(Long keywordId) { + searchKeywordRepository.deleteById(keywordId); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/notice/controller/AdminNoticeController.java b/Match-Api/src/main/java/com/example/matchapi/admin/notice/controller/AdminNoticeController.java index 74f9f52d..075470b0 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/notice/controller/AdminNoticeController.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/notice/controller/AdminNoticeController.java @@ -11,10 +11,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; -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; +import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.List; @@ -32,4 +29,11 @@ public CommonResponse uploadNoticeList(@Valid @RequestBody NoticeUploadR adminNoticeService.uploadNoticeList(mapper.toEntityNoticeContents(noticeUploadReq.getContentsList()), mapper.toEntityNotice(noticeUploadReq)); return CommonResponse.onSuccess("업로드 성공"); } + + @DeleteMapping("/{noticeId}") + @Operation(summary = "ADMIN-10-02 공지사항 삭제") + public CommonResponse deleteNotice(@PathVariable Long noticeId){ + adminNoticeService.deleteNotice(noticeId); + return CommonResponse.onSuccess("삭제 성공"); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/notice/service/AdminNoticeService.java b/Match-Api/src/main/java/com/example/matchapi/admin/notice/service/AdminNoticeService.java index b24ac992..41b674ae 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/notice/service/AdminNoticeService.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/notice/service/AdminNoticeService.java @@ -1,29 +1,44 @@ package com.example.matchapi.admin.notice.service; +import com.example.matchdomain.notice.adaptor.NoticeAdapter; +import com.example.matchdomain.notice.adaptor.NoticeContentAdaptor; import com.example.matchdomain.notice.entity.Notice; import com.example.matchdomain.notice.entity.NoticeContent; import com.example.matchdomain.notice.repository.NoticeContentRepository; import com.example.matchdomain.notice.repository.NoticeRepository; +import com.example.matchinfrastructure.config.s3.S3UploadService; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.CacheEvict; import org.springframework.stereotype.Service; import java.util.List; +import static com.example.matchdomain.common.model.ContentsType.IMG; + @Service @RequiredArgsConstructor public class AdminNoticeService { - private final NoticeRepository noticeRepository; - private final NoticeContentRepository noticeContentRepository; + private final NoticeContentAdaptor noticeContentAdaptor; + private final NoticeAdapter noticeAdapter; + private final S3UploadService s3UploadService; @CacheEvict(value = "noticeCache", allEntries = true, cacheManager = "ehcacheManager") public void uploadNoticeList(List noticeContents, Notice notice) { - notice = noticeRepository.save(notice); + notice = noticeAdapter.save(notice); for(NoticeContent noticeContent : noticeContents){ noticeContent.setNoticeId(notice.getId()); } - noticeContentRepository.saveAll(noticeContents); + noticeContentAdaptor.saveAll(noticeContents); + } + + public void deleteNotice(Long noticeId) { + Notice notice = noticeAdapter.findNoticeDetail(noticeId); + List noticeContents = notice.getNoticeContents(); + for(NoticeContent noticeContent : noticeContents){ + if(noticeContent.getContentsType().equals(IMG))s3UploadService.deleteFile(noticeContent.getContents()); + } + noticeAdapter.delete(notice); } } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/user/controller/AdminUserController.java b/Match-Api/src/main/java/com/example/matchapi/admin/user/controller/AdminUserController.java index 1f93c6a4..e4e3251a 100644 --- a/Match-Api/src/main/java/com/example/matchapi/admin/user/controller/AdminUserController.java +++ b/Match-Api/src/main/java/com/example/matchapi/admin/user/controller/AdminUserController.java @@ -1,5 +1,7 @@ package com.example.matchapi.admin.user.controller; +import com.example.matchapi.admin.donation.service.AdminDonationService; +import com.example.matchapi.admin.user.service.AdminUserService; import com.example.matchapi.donation.service.DonationService; import com.example.matchapi.user.converter.UserConverter; import com.example.matchapi.user.dto.UserRes; @@ -9,16 +11,25 @@ import com.example.matchcommon.reponse.PageResponse; import com.example.matchdomain.common.model.Status; import com.example.matchdomain.donation.entity.DonationUser; +import com.example.matchdomain.donation.entity.RegularPayment; import com.example.matchdomain.user.entity.User; +import com.example.matchdomain.user.entity.enums.Gender; import com.example.matchdomain.user.exception.UserAuthErrorCode; +import com.fasterxml.jackson.annotation.JsonFormat; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.security.core.parameters.P; import org.springframework.web.bind.annotation.*; import javax.validation.constraints.Min; + +import java.time.LocalDate; import java.util.List; @RestController @@ -26,14 +37,16 @@ @RequiredArgsConstructor @Tag(name = "ADMIN-02 User👤 관리자 유저 관련 API 입니다.", description = "ADMIN 유저 관련 API 입니다.") public class AdminUserController { - private final UserService userService; + private final AdminUserService adminUserService; private final DonationService donationService; private final UserConverter userConverter; + private final AdminDonationService adminDonationService; + @GetMapping("/info") @ApiErrorCodeExample(UserAuthErrorCode.class) @Operation(summary = "ADMIN-02-01👤 유저저 가입 현황파악 API.",description = "프로젝트 리스트 조회 API 입니다.") public CommonResponse getUserSingUpInfo(){ - UserRes.SignUpInfo signUpInfo = userService.getUserSignUpInfo(); + UserRes.SignUpInfo signUpInfo = adminUserService.getUserSignUpInfo(); return CommonResponse.onSuccess(signUpInfo); } @@ -46,7 +59,7 @@ public CommonResponse>> getUserList( @RequestParam(required = false) Status status, @RequestParam(required = false) String content ){ - PageResponse> userList = userService.getUserList(page, size, status, content); + PageResponse> userList = adminUserService.getUserList(page, size, status, content); return CommonResponse.onSuccess(userList); } @@ -54,7 +67,7 @@ public CommonResponse>> getUserList( @ApiErrorCodeExample(UserAuthErrorCode.class) @Operation(summary = "ADMIN-02-03👤 유저 상세 조회 API.",description = "유저 상세 조회 API 입니다.") public CommonResponse getUserDetail(@PathVariable Long userId){ - UserRes.UserAdminDetail userAdminDetail = userService.getUserAdminDetail(userId); + UserRes.UserAdminDetail userAdminDetail = adminUserService.getUserAdminDetail(userId); return CommonResponse.onSuccess(userAdminDetail); } @@ -62,11 +75,65 @@ public CommonResponse getUserDetail(@PathVariable Long @ApiErrorCodeExample(UserAuthErrorCode.class) @Operation(summary = "ADMIN-02-04 유저 불꽃이 생성기록 조회" ,description = "유저 불꽃이 기록 조회") public CommonResponse>> getUserFlameList(@PathVariable Long userId, - @Parameter(description = "페이지", example = "0") @RequestParam(required = false, defaultValue = "0") @Min(value = 0) int page, + @Parameter(description = "페이지", example = "0") @RequestParam(required = false, defaultValue = "0") int page, @Parameter(description = "페이지 사이즈", example = "10") @RequestParam(required = false, defaultValue = "10") int size){ - User user = userService.findByUserId(userId); + User user = adminUserService.findByUserId(userId); Page donationUsers = donationService.findByUserId(user, page, size); return CommonResponse.onSuccess(new PageResponse<>(donationUsers.isLast(), donationUsers.getTotalElements(), userConverter.convertToFlameList(donationUsers.getContent()))); } + + @DeleteMapping("/{userId}") + @ApiErrorCodeExample({UserAuthErrorCode.class}) + @Operation(summary = "ADMIN-02-05👤 유저 삭제 API.",description = "유저 삭제 API 입니다.") + public CommonResponse deleteUser(@PathVariable Long userId){ + User user = adminUserService.findByUserId(userId); + adminUserService.unActivateUser(user); + return CommonResponse.onSuccess(new UserRes.UserDelete(userId)); + } + + @PatchMapping("/nickname/{userId}") + @Operation(summary = "ADMIN-02-06👤 유저 닉네임 수정 API.",description = "유저 닉네임 수정 API 입니다.") + public CommonResponse updateNickname(@PathVariable Long userId, @RequestParam String nickname){ + adminUserService.updateNickname(userId, nickname); + return CommonResponse.onSuccess("닉네임 수정 성공"); + } + + @PatchMapping("/birth/{userId}") + @Operation(summary = "ADMIN-02-07👤 유저 생일 수정 API.",description = "유저 생일 수정 API 입니다.") + public CommonResponse updateBirth(@PathVariable Long userId, @DateTimeFormat(pattern = "yyyy-MM-dd") @RequestParam LocalDate birth){ + adminUserService.updateBirth(userId, birth); + return CommonResponse.onSuccess("생일 수정 성공"); + } + + @PatchMapping("/phone/{userId}") + @Operation(summary = "ADMIN-02-08👤 유저 전화번호 수정 API.",description = "유저 전화번호 수정 API 입니다.") + public CommonResponse updatePhone(@PathVariable Long userId, @RequestParam String phone){ + adminUserService.updatePhone(userId, phone); + return CommonResponse.onSuccess("전화번호 수정 성공"); + } + + @PatchMapping("/email/{userId}") + @Operation(summary = "ADMIN-02-09 유저 이메일 수정 API" , description = "유저 이메일 수정 API") + public CommonResponse updateEmail(@PathVariable Long userId, @RequestParam String email){ + adminUserService.updateEmail(userId, email); + return CommonResponse.onSuccess("이메일 수정 성공"); + } + + @PatchMapping("/gender/{userId}") + @Operation(summary = "ADMIN-02-10 유저 성별 수정 API" , description = "유저 성별 수정 API") + public CommonResponse updateGender(@PathVariable Long userId, @RequestParam Gender gender){ + adminUserService.updateGender(userId, gender); + return CommonResponse.onSuccess("성별 수정 성공"); + } + + @GetMapping("/donations/{userId}") + @Operation(summary = "ADMIN-02-11 유저 기부 정보" , description = "유저 기부 정보") + public CommonResponse getDonationInfo(@PathVariable Long userId){ + Long regularCnt = adminDonationService.countByUserId(userId); + List donationUsers = adminDonationService.findByUserId(userId); + boolean isCard = adminUserService.findByUserId(userId).getUserCard().size() > 0; + return CommonResponse.onSuccess(userConverter.convertToDonationInfoDto(regularCnt, donationUsers, isCard)); + } + } diff --git a/Match-Api/src/main/java/com/example/matchapi/admin/user/service/AdminUserService.java b/Match-Api/src/main/java/com/example/matchapi/admin/user/service/AdminUserService.java new file mode 100644 index 00000000..dbd3ae70 --- /dev/null +++ b/Match-Api/src/main/java/com/example/matchapi/admin/user/service/AdminUserService.java @@ -0,0 +1,111 @@ +package com.example.matchapi.admin.user.service; + +import com.example.matchapi.donation.service.DonationService; +import com.example.matchapi.user.converter.UserConverter; +import com.example.matchapi.user.dto.UserRes; +import com.example.matchcommon.annotation.RedissonLock; +import com.example.matchcommon.exception.BadRequestException; +import com.example.matchcommon.exception.ForbiddenException; +import com.example.matchcommon.exception.NotFoundException; +import com.example.matchcommon.reponse.PageResponse; +import com.example.matchdomain.common.model.Status; +import com.example.matchdomain.user.adaptor.UserAdaptor; +import com.example.matchdomain.user.entity.User; +import com.example.matchdomain.user.entity.enums.Gender; +import com.example.matchdomain.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import static com.example.matchdomain.user.exception.UserAuthErrorCode.NOT_EXIST_USER; +import static com.example.matchdomain.user.exception.UserNormalSignUpErrorCode.*; + +@Service +@RequiredArgsConstructor +public class AdminUserService { + private final UserAdaptor userAdaptor; + private final UserConverter userConverter; + private final DonationService donationService; + + public UserRes.SignUpInfo getUserSignUpInfo() { + LocalDate localDate = LocalDate.now(); + Long totalUser = userAdaptor.getTotalUserCnt(); + Long oneDayUser = userAdaptor.getOneDayUserCnt(localDate); + Long weekUser = userAdaptor.getWeekUserCnt(localDate); + Long monthUser = userAdaptor.getMonthUserCnt(localDate); + Long deleteUser = userAdaptor.getDeleteUserCnt(); + System.out.println(deleteUser); + return userConverter.convertToUserSignUpInfo(oneDayUser,weekUser,monthUser,totalUser, deleteUser); + } + + @Transactional + public PageResponse> getUserList(int page, int size, Status status, String content) { + Page userList = userAdaptor.getUserList(page, size, status, content); + + List userLists = new ArrayList<>(); + + userList.getContent().forEach( + result -> userLists.add( + userConverter.convertToUserList(result) + ) + ); + + return new PageResponse<>(userList.isLast(),userList.getTotalElements(),userLists); + } + + public UserRes.UserAdminDetail getUserAdminDetail(Long userId) { + //UserRepository.UserList userDetail = userAdaptor.getUserDetail(userId); + User user = findByUserId(userId); + return userConverter.convertToUserAdminDetail(user); + } + + public User findByUserId(Long userId) { + return userAdaptor.findByUserId(userId).orElseThrow(() -> new NotFoundException(NOT_EXIST_USER)); + } + + @RedissonLock(LockName = "유저", key = "#user.id") + public void unActivateUser(User user) { + updateUserInfo(user.getId(), users -> users.setStatus(Status.INACTIVE)); + donationService.deleteRegularPayment(user); + } + + @Transactional + public void updateNickname(Long userId, String nickname) { + updateUserInfo(userId, user -> user.setNickname(nickname)); + } + + @Transactional + public void updatePhone(Long userId, String phone) { + if (userAdaptor.existsPhoneNumber(phone)) { + throw new ForbiddenException(USERS_EXISTS_PHONE); + } + updateUserInfo(userId, user -> user.setPhoneNumber(phone)); + } + @Transactional + public void updateEmail(Long userId, String email) { + if (userAdaptor.existsEmail(email)) { + throw new ForbiddenException(USERS_EXISTS_EMAIL); + } + updateUserInfo(userId, user -> user.setEmail(email)); + } + @Transactional + public void updateGender(Long userId, Gender gender) { + updateUserInfo(userId, user -> user.setGender(gender)); + } + @Transactional + public void updateBirth(Long userId, LocalDate birth) { + updateUserInfo(userId, user -> user.setBirth(birth)); + } + + public void updateUserInfo(Long userId, Consumer updateFunction) { + User user = findByUserId(userId); + updateFunction.accept(user); + userAdaptor.save(user); + } +} diff --git a/Match-Api/src/main/java/com/example/matchapi/banner/converter/BannerConverter.java b/Match-Api/src/main/java/com/example/matchapi/banner/converter/BannerConverter.java index b3735aa6..774888e6 100644 --- a/Match-Api/src/main/java/com/example/matchapi/banner/converter/BannerConverter.java +++ b/Match-Api/src/main/java/com/example/matchapi/banner/converter/BannerConverter.java @@ -18,14 +18,21 @@ public Banner convertToBannerUpload(BannerType bannerType, String bannerImg, Ban .builder() .bannerImg(bannerImg) .bannerType(bannerType) + .name(bannerUploadDto.getName()) .eventId(bannerUploadDto.getEventId()) + .startDate(bannerUploadDto.getStartDate()) + .endDate(bannerUploadDto.getEndDate()) + .contentsUrl(bannerUploadDto.getContentsUrl()) .build(); } else{ - return Banner - .builder() + return Banner.builder() .bannerImg(bannerImg) .bannerType(bannerType) + .name(bannerUploadDto.getName()) + .contentsUrl(bannerUploadDto.getContentsUrl()) + .startDate(bannerUploadDto.getStartDate()) + .endDate(bannerUploadDto.getEndDate()) .contentsUrl(bannerUploadDto.getContentsUrl()) .build(); } @@ -54,4 +61,31 @@ private BannerRes.BannerList convertToBannerInfo(Banner result) { .contentsUrl(result.getContentsUrl()) .build(); } + + public List convertToBannerLists(List content) { + List bannerLists = new ArrayList<>(); + + content.forEach( + result -> + bannerLists.add( + convertToBannerListDto(result) + ) + ); + + return bannerLists; + } + + private BannerRes.BannerAdminListDto convertToBannerListDto(Banner result) { + return BannerRes.BannerAdminListDto + .builder() + .bannerId(result.getId()) + .bannerType(result.getBannerType()) + .eventId(result.getEventId()) + .name(result.getName()) + .contentsUrl(result.getContentsUrl()) + .bannerImg(result.getBannerImg()) + .startDate(result.getStartDate()) + .endDate(result.getEndDate()) + .build(); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/banner/dto/BannerReq.java b/Match-Api/src/main/java/com/example/matchapi/banner/dto/BannerReq.java index e143305d..9851ca44 100644 --- a/Match-Api/src/main/java/com/example/matchapi/banner/dto/BannerReq.java +++ b/Match-Api/src/main/java/com/example/matchapi/banner/dto/BannerReq.java @@ -1,5 +1,7 @@ package com.example.matchapi.banner.dto; +import java.time.LocalDateTime; + import lombok.*; public class BannerReq { @@ -14,5 +16,28 @@ public static class BannerUpload { private Long eventId; private String contentsUrl; + + private String name; + + private LocalDateTime startDate; + + private LocalDateTime endDate; } + + + @Getter + @Setter + @Builder + @AllArgsConstructor + @ToString + @NoArgsConstructor + public static class BannerPatchDto { + private String name; + + private LocalDateTime startDate; + + private LocalDateTime endDate; + + private boolean isEditImage; + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/banner/dto/BannerRes.java b/Match-Api/src/main/java/com/example/matchapi/banner/dto/BannerRes.java index 1cc454da..03a57cdc 100644 --- a/Match-Api/src/main/java/com/example/matchapi/banner/dto/BannerRes.java +++ b/Match-Api/src/main/java/com/example/matchapi/banner/dto/BannerRes.java @@ -1,9 +1,12 @@ package com.example.matchapi.banner.dto; import com.example.matchdomain.banner.enums.BannerType; +import com.fasterxml.jackson.annotation.JsonFormat; + import lombok.*; import java.io.Serializable; +import java.time.LocalDateTime; public class BannerRes { @Getter @@ -24,4 +27,29 @@ public static class BannerList implements Serializable { } + + @Getter + @Setter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class BannerAdminListDto { + private Long bannerId; + + private BannerType bannerType; + + private String name; + + private String contentsUrl; + + private String bannerImg; + + private Long eventId; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime startDate; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime endDate; + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/common/TestController.java b/Match-Api/src/main/java/com/example/matchapi/common/TestController.java index 365fdefa..3f699895 100644 --- a/Match-Api/src/main/java/com/example/matchapi/common/TestController.java +++ b/Match-Api/src/main/java/com/example/matchapi/common/TestController.java @@ -1,19 +1,19 @@ package com.example.matchapi.common; +import com.example.matchapi.common.security.JwtService; import com.example.matchcommon.reponse.CommonResponse; import com.example.matchinfrastructure.aligo.service.AligoInfraService; import com.example.matchinfrastructure.match_aligo.dto.AlimTalkDto; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.context.annotation.Profile; +import org.springframework.web.bind.annotation.*; import static com.example.matchinfrastructure.aligo.dto.AlimType.EXECUTION; import static com.example.matchinfrastructure.aligo.dto.AlimType.PAYMENT; @RestController @RequiredArgsConstructor +@Profile("localDev") @RequestMapping("/test") public class TestController { private final AligoInfraService aligoInfraService; diff --git a/Match-Api/src/main/java/com/example/matchapi/config/SecurityConfig.java b/Match-Api/src/main/java/com/example/matchapi/config/SecurityConfig.java index c7545321..d2474f60 100644 --- a/Match-Api/src/main/java/com/example/matchapi/config/SecurityConfig.java +++ b/Match-Api/src/main/java/com/example/matchapi/config/SecurityConfig.java @@ -105,7 +105,7 @@ private void configureAuthorizationRequests(HttpSecurity httpSecurity) throws Ex .antMatchers("/payments/web-hook").permitAll() .antMatchers("/payments/validate").permitAll() .antMatchers("/payments/info").permitAll() - .antMatchers("/test").permitAll() + .antMatchers("/test/**").permitAll() .and() .apply(new JwtSecurityConfig(jwtService)); } diff --git a/Match-Api/src/main/java/com/example/matchapi/donation/controller/DonationController.java b/Match-Api/src/main/java/com/example/matchapi/donation/controller/DonationController.java index 8b8a1f2d..1a705666 100644 --- a/Match-Api/src/main/java/com/example/matchapi/donation/controller/DonationController.java +++ b/Match-Api/src/main/java/com/example/matchapi/donation/controller/DonationController.java @@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.Getter; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; @@ -44,6 +45,9 @@ public CommonResponse refundDonation( return CommonResponse.onSuccess("기부금 환불 성공"); } + @Value("${spring.config.activate.on-profile}") + private String profile; + /* @GetMapping("/flame/filter") @Deprecated @@ -187,7 +191,7 @@ public CommonResponse>> getBurnin @Parameter(description = "페이지", example = "0") @RequestParam(required = false, defaultValue = "0") int page, @Parameter(description = "페이지 사이즈", example = "10") @RequestParam(required = false, defaultValue = "10") int size ){ - return CommonResponse.onSuccess(donationService.getBurningFlameList(user, page, size)); + return CommonResponse.onSuccess(donationService.getBurningFlameList(profile,user, page, size)); } @@ -203,7 +207,7 @@ public CommonResponse> getTutorialDonation( @Operation(summary = "05-14 튜토리얼 기부 ", description = "튜토리얼 1원 기부 POST API 입니다.") @PostMapping("/tutorial") @ApiErrorCodeExample({UserAuthErrorCode.class, RequestErrorCode.class}) - @RedissonLock(LockName = "유저 튜토리얼 기부", key = "#user.id") + @RedissonLock(LockName = "프로젝트", key = "#tutorial.projectId") public CommonResponse postTutorialDonation( @AuthenticationPrincipal User user, @RequestBody DonationReq.Tutorial tutorial){ diff --git a/Match-Api/src/main/java/com/example/matchapi/donation/converter/DonationConverter.java b/Match-Api/src/main/java/com/example/matchapi/donation/converter/DonationConverter.java index 3200b480..00c3c90f 100644 --- a/Match-Api/src/main/java/com/example/matchapi/donation/converter/DonationConverter.java +++ b/Match-Api/src/main/java/com/example/matchapi/donation/converter/DonationConverter.java @@ -324,8 +324,8 @@ public DonationUser convertToTutorialDonation(User user, DonationReq.Tutorial tu .inherenceName(createInherenceDto.getInherenceName()) .inherenceNumber(createInherenceDto.getInherenceNumber()) .regularStatus(RegularStatus.ONE_TIME) - .flameImage(FlameImage.NORMAL_IMG.getImg()) - .flameType(FlameType.NORMAL_FLAME) + .flameImage(FlameImage.TUTORIAL_IMG.getImg()) + .flameType(FlameType.TUTORIAL_FLAME) .build(); } diff --git a/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationRes.java b/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationRes.java index c141caf1..d59e3e37 100644 --- a/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationRes.java +++ b/Match-Api/src/main/java/com/example/matchapi/donation/dto/DonationRes.java @@ -77,6 +77,8 @@ public static class DonationInfo { private String weekDonation; private String monthDonation; + + private String totalDonation; } @Getter @@ -397,7 +399,32 @@ public static class ProjectDonationDto { private Long waitingSortingAmount; + private Long partialAmount; + @Schema(description = "수입 금액") private int importedAmount; } + + @Getter + @Setter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class RegularInfoDto { + private Long beforeCnt; + + private Long underCnt; + + private Long successCnt; + + private String successAmount; + + private Long regularCnt; + + private String regularAmount; + + private Long beforeMonthRegularCnt; + + private String beforeMonthRegularAmount; + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/donation/service/DonationService.java b/Match-Api/src/main/java/com/example/matchapi/donation/service/DonationService.java index 1dc67775..351637d6 100644 --- a/Match-Api/src/main/java/com/example/matchapi/donation/service/DonationService.java +++ b/Match-Api/src/main/java/com/example/matchapi/donation/service/DonationService.java @@ -25,7 +25,6 @@ import org.springframework.stereotype.Service; import javax.transaction.Transactional; -import javax.validation.constraints.Min; import java.util.List; import static com.example.matchdomain.common.model.Status.ACTIVE; @@ -146,8 +145,8 @@ public PageResponse> getUserMatchList(User user, int return new PageResponse<>(regularPayments.isLast(), regularPayments.getTotalElements(), regularPaymentConverter.convertToMatchList(regularPayments.getContent())); } - @Cacheable(value = "flameCache", key = "{#user.id, #page, #size}", cacheManager = "ehcacheManager") - public PageResponse> getBurningFlameList(User user, int page, int size) { + @Cacheable(value = "flameCache", key = "{#profile, #user.id, #page, #size}", cacheManager = "redisCacheManager") + public PageResponse> getBurningFlameList(String profile, User user, int page, int size) { Page donationUsers = donationAdaptor.findByUser(user, page, size); return new PageResponse<>(donationUsers.isLast(), donationUsers.getTotalElements(), regularPaymentConverter.convertToBurningFlameList(donationUsers.getContent())); } @@ -172,4 +171,8 @@ public DonationRes.CompleteDonation postTutorialDonation(User user, DonationReq. public Page findByUserId(User user, int page, int size) { return donationAdaptor.findByUserForAdminPage(user, page, size); } + + public List findByUser(User user) { + return regularPaymentAdaptor.findByUserPage(user); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/notification/service/NotificationService.java b/Match-Api/src/main/java/com/example/matchapi/notification/service/NotificationService.java index 0f805bff..f5f3f8ee 100644 --- a/Match-Api/src/main/java/com/example/matchapi/notification/service/NotificationService.java +++ b/Match-Api/src/main/java/com/example/matchapi/notification/service/NotificationService.java @@ -25,12 +25,6 @@ public PageResponse getNotificationList(Us return new PageResponse<>(notifications.isLast(), notifications.getTotalElements(), new NotificationRes.NotificationListInfo(notificationCount, notificationConverter.convertToNotificationList(notifications.getContent()))); } - public void saveTestNotification(User user, FCMNotificationRequestDto fcmNotificationRequestDto) { - Notification notification = notificationConverter.convertToNotificationTest(user, fcmNotificationRequestDto); - - notificationAdaptor.saveNotification(notification); - } - public NotificationRes.NotificationDetail getNotificationDetail(Long notificationId) { Notification notification = notificationAdaptor.findNotification(notificationId); notificationAdaptor.readNotification(notification); diff --git a/Match-Api/src/main/java/com/example/matchapi/order/service/OrderService.java b/Match-Api/src/main/java/com/example/matchapi/order/service/OrderService.java index 56fb866a..e542dddc 100644 --- a/Match-Api/src/main/java/com/example/matchapi/order/service/OrderService.java +++ b/Match-Api/src/main/java/com/example/matchapi/order/service/OrderService.java @@ -1,6 +1,6 @@ package com.example.matchapi.order.service; -import com.example.matchapi.common.security.JwtService; +import com.example.matchcommon.listner.CacheService; import com.example.matchapi.donation.service.DonationHistoryService; import com.example.matchapi.order.converter.OrderConverter; import com.example.matchapi.order.dto.OrderCommand; @@ -8,7 +8,6 @@ import com.example.matchapi.order.dto.OrderRes; import com.example.matchapi.order.helper.OrderHelper; import com.example.matchapi.portone.service.PaymentService; -import com.example.matchapi.project.service.ProjectService; import com.example.matchapi.user.service.AligoService; import com.example.matchcommon.annotation.PaymentIntercept; import com.example.matchcommon.annotation.RedissonLock; @@ -39,6 +38,7 @@ import com.example.matchinfrastructure.pay.portone.service.PortOneService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.transaction.Transactional; @@ -70,7 +70,9 @@ public class OrderService { private final PortOneService portOneService; private final AligoService aligoService; private final AligoConverter aligoConverter; - private final JwtService jwtService; + private final CacheService cacheService; + @Value("${spring.config.activate.on-profile}") + private String profile; @Transactional public List getUserBillCard(Long userId) { @@ -79,7 +81,7 @@ public List getUserBillCard(Long userId) { return orderConverter.convertToUserCardLists(userCards); } - @RedissonLock(LockName = "카드-삭제", key = "#cardId") + @RedissonLock(LockName = "카드", key = "#cardId") public void deleteBillCard(Long cardId) { UserCard userCard = userCardAdaptor.findCardByCardId(cardId); @@ -87,7 +89,7 @@ public void deleteBillCard(Long cardId) { cancelRegularPayment(regularPayments); - String accessToken = portOneAuthService.getToken(); + String accessToken = portOneAuthService.getToken(profile); portOneFeignClient.deleteBillKey(accessToken, userCard.getBid()); @@ -103,7 +105,7 @@ private void validateCard(UserCard card, User user) { } @PaymentIntercept(key = "#orderCommand.orderId") - @RedissonLock(LockName = "빌키-단기-기부", key = "#orderCommand.userCard.id") + @RedissonLock(LockName = "프로젝트", key = "#orderCommand.project.id") public OrderRes.CompleteDonation paymentForOnetime(OrderCommand.OneTimeDonation orderCommand) { UserCard card = orderCommand.getUserCard(); Project project = orderCommand.getProject(); @@ -114,6 +116,8 @@ public OrderRes.CompleteDonation paymentForOnetime(OrderCommand.OneTimeDonation PortOneResponse portOneResponse = paymentService.payBillKey(card, oneTimeDonation.getAmount(), project.getProjectName(), orderCommand.getOrderId()); + if(portOneResponse.getResponse().getFail_reason()!=null) throw new BaseException(BAD_REQUEST, false, "PORT_ONE_BILL_AUTH_001", portOneResponse.getResponse().getFail_reason()); + OrderRes.CreateInherenceDto createInherenceDto = orderHelper.createInherence(user); DonationUser donationUser = donationUserRepository.save( @@ -123,13 +127,15 @@ public OrderRes.CompleteDonation paymentForOnetime(OrderCommand.OneTimeDonation donationHistoryService.oneTimeDonationHistory(donationUser.getId()); - aligoService.sendAlimTalk(AlimType.PAYMENT, aligoConverter.convertToAlimTalkPayment(donationUser.getId(), user.getName(), user.getPhoneNumber())); + //aligoService.sendAlimTalk(AlimType.PAYMENT, aligoConverter.convertToAlimTalkPayment(donationUser.getId(), user.getName(), user.getPhoneNumber())); + + cacheService.evictCache(user.getId()); return orderConverter.convertToCompleteDonation(user.getName(), project, oneTimeDonation.getAmount()); } @PaymentIntercept(key = "#orderCommand.orderId") - @RedissonLock(LockName = "정기-기부-신청", key = "#orderCommand.userCard.id") + @RedissonLock(LockName = "프로젝트", key = "#orderCommand.project.id") public OrderRes.CompleteDonation paymentForRegular(OrderCommand.RegularDonation orderCommand) { UserCard card = orderCommand.getUserCard(); Project project = orderCommand.getProject(); @@ -139,6 +145,8 @@ public OrderRes.CompleteDonation paymentForRegular(OrderCommand.RegularDonation PortOneResponse portOneResponse = paymentService.payBillKey(card, regularDonation.getAmount(), project.getProjectName(), orderCommand.getOrderId()); + if(portOneResponse.getResponse().getFail_reason()!=null) throw new BaseException(BAD_REQUEST, false, "PORT_ONE_BILL_AUTH_001", portOneResponse.getResponse().getFail_reason()); + OrderRes.CreateInherenceDto createInherenceDto = orderHelper.createInherence(user); RegularPayment regularPayment = regularPaymentRepository.save(orderConverter.convertToRegularPayment(user.getId(), regularDonation, card.getId(), project.getId())); @@ -151,6 +159,8 @@ public OrderRes.CompleteDonation paymentForRegular(OrderCommand.RegularDonation aligoService.sendAlimTalk(AlimType.PAYMENT, aligoConverter.convertToAlimTalkPayment(donationUser.getId(), user.getName(), user.getPhoneNumber())); + cacheService.evictCache(user.getId()); + return orderConverter.convertToCompleteDonation(user.getName(), project, regularDonation.getAmount()); } @@ -162,7 +172,7 @@ public String saveRequest(User user, Long projectId) { PortOnePrepareReq portOnePrepareReq = portOneConverter.convertToRequestPrepare(orderId, 1000); - portOneFeignClient.preparePayments(portOneAuthService.getToken(), portOnePrepareReq); + portOneFeignClient.preparePayments(portOneAuthService.getToken(profile), portOnePrepareReq); return orderId; } @@ -197,7 +207,7 @@ public void revokePay(User user, Long cardId) { @RedissonLock(LockName = "유저-카드-등록", key = "#user.id") public PortOneBillResponse postCard(User user, OrderReq.RegistrationCard registrationCard) { - String accessToken = portOneAuthService.getToken(); + String accessToken = portOneAuthService.getToken(profile); String cardNo = orderHelper.formatString(registrationCard.getCardNo(), 4); String expiry = "20" + registrationCard.getExpYear() + "-" + registrationCard.getExpMonth(); PortOneResponse portOneResponse = portOneFeignClient.getBillKey( @@ -232,7 +242,7 @@ public String saveRequestPrepare(User user, Long projectId, int amount) { PortOnePrepareReq portOnePrepareReq = portOneConverter.convertToRequestPrepare(orderId, amount); - portOneFeignClient.preparePayments(portOneAuthService.getToken(), portOnePrepareReq); + portOneFeignClient.preparePayments(portOneAuthService.getToken(profile), portOnePrepareReq); return orderId; } diff --git a/Match-Api/src/main/java/com/example/matchapi/portone/service/PaymentService.java b/Match-Api/src/main/java/com/example/matchapi/portone/service/PaymentService.java index c43c8cca..64fde166 100644 --- a/Match-Api/src/main/java/com/example/matchapi/portone/service/PaymentService.java +++ b/Match-Api/src/main/java/com/example/matchapi/portone/service/PaymentService.java @@ -1,6 +1,5 @@ package com.example.matchapi.portone.service; -import com.example.matchapi.common.security.JwtService; import com.example.matchapi.donation.service.DonationHistoryService; import com.example.matchapi.order.converter.OrderConverter; import com.example.matchapi.order.dto.OrderRes; @@ -36,6 +35,7 @@ import com.siot.IamportRestClient.response.Payment; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; @@ -62,7 +62,8 @@ public class PaymentService { private final UserAdaptor userAdaptor; private final AligoService aligoService; private final AligoConverter aligoConverter; - private final JwtService jwtService; + @Value("${spring.config.activate.on-profile}") + private String profile; private IamportClient iamportClient; @@ -126,7 +127,7 @@ public DonationUser saveDonationUser(User user, Project project, Payment payment } public PortOneResponse payBillKey(UserCard card, Long amount, String projectName, String orderId) { - String accessToken = portOneAuthService.getToken(); + String accessToken = portOneAuthService.getToken(profile); PortOneResponse portOneResponse = portOneFeignClient.payWithBillKey(accessToken, portOneConverter.convertPayWithBillKey(card.getBid(), orderId, amount, projectName, card.getCustomerId())); diff --git a/Match-Api/src/main/java/com/example/matchapi/project/controller/ProjectController.java b/Match-Api/src/main/java/com/example/matchapi/project/controller/ProjectController.java index c87bc70b..46efabb2 100644 --- a/Match-Api/src/main/java/com/example/matchapi/project/controller/ProjectController.java +++ b/Match-Api/src/main/java/com/example/matchapi/project/controller/ProjectController.java @@ -4,6 +4,7 @@ import com.example.matchapi.donation.service.DonationService; import com.example.matchapi.project.dto.ProjectReq; import com.example.matchapi.project.dto.ProjectRes; +import com.example.matchapi.project.service.CommentService; import com.example.matchcommon.constants.enums.FILTER; import com.example.matchapi.project.service.ProjectService; import com.example.matchcommon.annotation.ApiErrorCodeExample; @@ -38,6 +39,7 @@ public class ProjectController { private final ProjectService projectService; private final DonationService donationService; + private final CommentService commentService; @Operation(summary = "03-01💻 프로젝트 리스트 조회 API. #Web version",description = "프로젝트 리스트 조회 API 입니다.") @GetMapping("") public CommonResponse>> getProjectList( @@ -81,7 +83,7 @@ public CommonResponse>> getProjectComm @Parameter(description = "프로젝트 id") @PathVariable("projectId") Long projectId ){ log.info("03-04 프로젝트 댓글 조회 projectId : "+ projectId); - return CommonResponse.onSuccess(projectService.getProjectComment(user, projectId, page, size)); + return CommonResponse.onSuccess(commentService.getProjectComment(user, projectId, page, size)); } @Operation(summary = "03-05💻 프로젝트 리스트 조회 API #FRAME_프로젝트 리스트 조회.",description = "프로젝트 리스트 조회 API 입니다.") @@ -152,7 +154,7 @@ public CommonResponse>> getMatchHisto public CommonResponse postComment(@Parameter(hidden = true) @AuthenticationPrincipal User user, @Parameter(description = "프로젝트 id") @PathVariable("projectId") Long projectId, @Valid @RequestBody ProjectReq.Comment comment){ - return CommonResponse.onSuccess(projectService.postComment(user, projectId, comment)); + return CommonResponse.onSuccess(commentService.postComment(user, projectId, comment)); } @Operation(summary = "03-11💻 후원 응원 신고하기 #FRAME_후원 상세조회", description = "후원 응원 신고하기 기능입니다") @@ -160,7 +162,7 @@ public CommonResponse postComment(@Parameter(hidden = tr @ApiErrorCodeExample({UserAuthErrorCode.class, CommentGetErrorCode.class}) public CommonResponse reportComment(@PathVariable Long commentId, @RequestParam("reportReason")ReportReason reportReason){ - projectService.reportComment(commentId,reportReason); + commentService.reportComment(commentId,reportReason); return CommonResponse.onSuccess("신고 성공"); } @@ -170,7 +172,7 @@ public CommonResponse reportComment(@PathVariable Long commentId, public CommonResponse deleteComment( @Parameter(hidden = true) @AuthenticationPrincipal User user, @PathVariable Long commentId){ - projectService.deleteComment(user, commentId); + commentService.deleteComment(user, commentId); return CommonResponse.onSuccess("삭제 성공"); } diff --git a/Match-Api/src/main/java/com/example/matchapi/project/converter/CommentConverter.java b/Match-Api/src/main/java/com/example/matchapi/project/converter/CommentConverter.java new file mode 100644 index 00000000..521a6e11 --- /dev/null +++ b/Match-Api/src/main/java/com/example/matchapi/project/converter/CommentConverter.java @@ -0,0 +1,38 @@ +package com.example.matchapi.project.converter; + +import com.example.matchapi.project.dto.ProjectRes; +import com.example.matchcommon.annotation.Converter; +import com.example.matchdomain.project.entity.CommentReport; +import com.example.matchdomain.project.entity.ProjectComment; +import com.example.matchdomain.project.entity.enums.ReportReason; +import com.example.matchdomain.user.entity.User; + +@Converter +public class CommentConverter { + public ProjectComment convertToComment(Long id, Long projectId, String comment) { + return ProjectComment.builder() + .userId(id) + .projectId(projectId) + .comment(comment) + .build(); + } + + public ProjectRes.CommentList projectComment(User user, ProjectComment result) { + return ProjectRes.CommentList.builder() + .commentId(result.getId()) + .comment(result.getComment()) + .commentDate(result.getCreatedAt()) + .nickname(user.getNickname()) + .profileImgUrl(user.getProfileImgUrl()) + .userId(result.getUserId()) + .isMy(result.getUserId().equals(user.getId())) + .build(); + } + public CommentReport convertToReportComment(Long commentId, ReportReason reportReason) { + return CommentReport + .builder() + .commentId(commentId) + .reportReason(reportReason) + .build(); + } +} diff --git a/Match-Api/src/main/java/com/example/matchapi/project/converter/ProjectConverter.java b/Match-Api/src/main/java/com/example/matchapi/project/converter/ProjectConverter.java index fa97ea7e..cf9a16ea 100644 --- a/Match-Api/src/main/java/com/example/matchapi/project/converter/ProjectConverter.java +++ b/Match-Api/src/main/java/com/example/matchapi/project/converter/ProjectConverter.java @@ -2,7 +2,6 @@ import com.example.matchapi.donation.dto.DonationRes; import com.example.matchapi.donation.helper.DonationHelper; -import com.example.matchapi.order.helper.OrderHelper; import com.example.matchapi.project.dto.ProjectReq; import com.example.matchapi.project.dto.ProjectRes; import com.example.matchapi.project.helper.ProjectHelper; @@ -11,13 +10,9 @@ import com.example.matchdomain.donation.entity.*; import com.example.matchdomain.donation.entity.enums.HistoryStatus; import com.example.matchdomain.donation.entity.enums.RegularPayStatus; -import com.example.matchdomain.donation.repository.RegularPaymentRepository; -import com.example.matchdomain.project.dto.ProjectDto; import com.example.matchdomain.project.entity.*; import com.example.matchdomain.project.entity.enums.ImageRepresentStatus; -import com.example.matchdomain.project.entity.enums.ReportReason; import com.example.matchdomain.project.repository.ProjectRepository; -import com.example.matchdomain.user.entity.User; import lombok.RequiredArgsConstructor; import java.time.LocalDateTime; @@ -33,7 +28,6 @@ public class ProjectConverter { private final ProjectHelper projectHelper; private final DonationHelper donationHelper; - private final RegularPaymentRepository regularPaymentRepository; private static final String FIRST_TIME = "T00:00:00"; private static final String LAST_TIME = "T23:59:59"; public ProjectRes.ProjectDetail projectImgList(List projectImage) { @@ -257,36 +251,6 @@ private ProjectRes.ProjectImgList convertToProjectImages(ProjectImage projectIma .build(); } - public ProjectRes.ProjectLists convertToProjectToDto(ProjectDto result) { - List imgUrlList = new ArrayList<>(); - List regularPayments = regularPaymentRepository.findByProjectIdAndRegularPayStatus(result.getId(), RegularPayStatus.PROCEEDING); - - for(RegularPayment regularPayment : regularPayments){ - imgUrlList.add(regularPayment.getUser().getProfileImgUrl()); - } - - return ProjectRes.ProjectLists - .builder() - .projectId(result.getId()) - .imgUrl(result.getImgUrl()) - .title(result.getProjectName()) - .usages(result.getUsages()) - .kind(result.getProjectKind().getName()) - .like(result.getLike()) - .userProfileImages(imgUrlList) - .totalDonationCnt(imgUrlList.size()) - .build(); - } - - public ProjectComment convertToComment(Long id, Long projectId, String comment) { - return ProjectComment - .builder() - .userId(id) - .comment(comment) - .projectId(projectId) - .build(); - } - public DonationHistory convertToDonationHistory(Long projectId, HistoryStatus historyStatus) { return DonationHistory .builder() @@ -295,13 +259,6 @@ public DonationHistory convertToDonationHistory(Long projectId, HistoryStatus hi .build(); } - public CommentReport convertToReportComment(Long commentId, ReportReason reportReason) { - return CommentReport - .builder() - .commentId(commentId) - .reportReason(reportReason) - .build(); - } public List convertToProjectListWeb(List projects) { List projectLists = new ArrayList<>(); @@ -341,18 +298,6 @@ public List convertToProjectListWebForNotLogin(List convertToTutorialDonation(List projects) { List tutorials = new ArrayList<>(); diff --git a/Match-Api/src/main/java/com/example/matchapi/project/service/CommentService.java b/Match-Api/src/main/java/com/example/matchapi/project/service/CommentService.java new file mode 100644 index 00000000..ec77d374 --- /dev/null +++ b/Match-Api/src/main/java/com/example/matchapi/project/service/CommentService.java @@ -0,0 +1,65 @@ +package com.example.matchapi.project.service; + +import com.example.matchapi.project.converter.CommentConverter; +import com.example.matchapi.project.dto.ProjectReq; +import com.example.matchapi.project.dto.ProjectRes; +import com.example.matchcommon.exception.BadRequestException; +import com.example.matchcommon.reponse.PageResponse; +import com.example.matchdomain.project.adaptor.CommentReportAdaptor; +import com.example.matchdomain.project.adaptor.ProjectCommentAdaptor; +import com.example.matchdomain.project.entity.ProjectComment; +import com.example.matchdomain.project.entity.enums.ReportReason; +import com.example.matchdomain.user.entity.User; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +import static com.example.matchdomain.common.model.Status.INACTIVE; +import static com.example.matchdomain.project.exception.CommentDeleteErrorCode.COMMENT_DELETE_ERROR_CODE; + +@Service +@RequiredArgsConstructor +public class CommentService { + private final ProjectCommentAdaptor commentAdaptor; + private final CommentReportAdaptor commentReportAdaptor; + private final CommentConverter commentConverter; + + public ProjectRes.CommentList postComment(User user, Long projectId, ProjectReq.Comment comment) { + ProjectComment projectComment = commentAdaptor.save(commentConverter.convertToComment(user.getId(), projectId, comment.getComment())); + + return commentConverter.projectComment(user, projectComment); + } + + public void reportComment(Long commentId, ReportReason reportReason) { + ProjectComment projectComment = commentAdaptor.findById(commentId); + + commentReportAdaptor.save(commentConverter.convertToReportComment(commentId, reportReason)); + } + + public void deleteComment(User user, Long commentId) { + ProjectComment projectComment = commentAdaptor.findById(commentId); + if(!projectComment.getUserId().equals(user.getId())) throw new BadRequestException(COMMENT_DELETE_ERROR_CODE); + projectComment.setStatus(INACTIVE); + commentAdaptor.save(projectComment); + } + + + public PageResponse> getProjectComment(User user, Long projectId, int page, int size) { + Page projectComments = commentAdaptor.getProjectComment(user, projectId, page, size); + + List commentLists = new ArrayList<>(); + projectComments.getContent().forEach( + result-> { + commentLists.add( + commentConverter.projectComment(user, result) + ); + } + ); + + + return new PageResponse<>(projectComments.isLast(), projectComments.getTotalElements(), commentLists); + } +} diff --git a/Match-Api/src/main/java/com/example/matchapi/project/service/ProjectImgService.java b/Match-Api/src/main/java/com/example/matchapi/project/service/ProjectImgService.java new file mode 100644 index 00000000..a1987d1c --- /dev/null +++ b/Match-Api/src/main/java/com/example/matchapi/project/service/ProjectImgService.java @@ -0,0 +1,45 @@ +package com.example.matchapi.project.service; + +import com.example.matchapi.project.converter.ProjectConverter; +import com.example.matchdomain.project.adaptor.ProjectImgAdaptor; +import com.example.matchdomain.project.entity.ProjectImage; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import java.util.ArrayList; +import java.util.List; + +import static com.example.matchdomain.project.entity.enums.ImageRepresentStatus.NORMAL; +import static com.example.matchdomain.project.entity.enums.ImageRepresentStatus.REPRESENT; + +@Service +@RequiredArgsConstructor +public class ProjectImgService { + private final ProjectImgAdaptor projectImgAdaptor; + private final ProjectConverter projectConverter; + + @Transactional + public void saveImgList(Long id, String url, List imgUrlList) { + imgUrlList.add(url); + List projectImages = new ArrayList<>(); + + for (int i=1 ; i <= imgUrlList.size(); i++) { + if(i==imgUrlList.size()){ + projectImages.add(projectConverter.postProjectImage(id,imgUrlList.get(i-1),REPRESENT,i)); + }else { + projectImages.add(projectConverter.postProjectImage(id, imgUrlList.get(i-1),NORMAL, i)); + } + } + + projectImgAdaptor.saveAll(projectImages); + } + + public List findByProjectId(Long projectId) { + return projectImgAdaptor.findProjectImages(projectId); + } + + public ProjectImage save(ProjectImage projectImage) { + return projectImgAdaptor.save(projectImage); + } +} diff --git a/Match-Api/src/main/java/com/example/matchapi/project/service/ProjectService.java b/Match-Api/src/main/java/com/example/matchapi/project/service/ProjectService.java index 8ae0316d..6bd48165 100644 --- a/Match-Api/src/main/java/com/example/matchapi/project/service/ProjectService.java +++ b/Match-Api/src/main/java/com/example/matchapi/project/service/ProjectService.java @@ -5,6 +5,7 @@ import com.example.matchapi.project.converter.ProjectConverter; import com.example.matchapi.project.dto.ProjectReq; import com.example.matchapi.project.dto.ProjectRes; +import com.example.matchcommon.annotation.RedissonLock; import com.example.matchcommon.constants.enums.FILTER; import com.example.matchapi.user.helper.AuthHelper; import com.example.matchcommon.exception.BadRequestException; @@ -16,6 +17,7 @@ import com.example.matchdomain.donation.entity.DonationUser; import com.example.matchdomain.donation.entity.enums.HistoryStatus; import com.example.matchdomain.donation.entity.enums.RegularStatus; +import com.example.matchdomain.project.adaptor.AttentionAdaptor; import com.example.matchdomain.project.adaptor.ProjectAdaptor; import com.example.matchdomain.project.adaptor.ProjectImgAdaptor; import com.example.matchdomain.project.dto.ProjectDto; @@ -56,18 +58,17 @@ @RequiredArgsConstructor public class ProjectService { private final ProjectAdaptor projectAdaptor; - private final ProjectRepository projectRepository; private final ProjectConverter projectConverter; - private final ProjectImageRepository projectImageRepository; private final AuthHelper authHelper; - private final ProjectCommentRepository projectCommentRepository; private final S3UploadService s3UploadService; - private final ProjectUserAttentionRepository projectUserAttentionRepository; private final DonationHistoryAdaptor donationHistoryAdaptor; - private final CommentReportRepository commentReportRepository; private final ProjectImgAdaptor projectImgAdaptor; private final DonationAdaptor donationAdaptor; private final MessageHelper messageHelper; + private final AttentionAdaptor attentionAdaptor; + private final ProjectImgService projectImgService; + + public PageResponse> getProjectList(User user, int page, int size) { Long userId = 0L; @@ -109,13 +110,13 @@ public PageResponse> searchProjectList(User user, S @Transactional public void postProject(ProjectReq.Project projects, MultipartFile presentFile, List multipartFiles) { - Project project = projectRepository.save(projectConverter.postProject(projects)); + Project project = projectAdaptor.save(projectConverter.postProject(projects)); String url = s3UploadService.uploadProjectPresentFile(project.getId() ,presentFile); List imgUrlList = s3UploadService.listUploadProjectFiles(project.getId(), multipartFiles); - saveImgList(project.getId(), url, imgUrlList); + projectImgService.saveImgList(project.getId(), url, imgUrlList); donationHistoryAdaptor.saveDonationHistory(projectConverter.convertToDonationHistory(project.getId(), HistoryStatus.START)); @@ -126,7 +127,7 @@ public void postProject(ProjectReq.Project projects, MultipartFile presentFile, public PageResponse> getProjectList(int page, int size) { Pageable pageable = PageRequest.of(page,size); - Page projectAdminLists = projectRepository.getProjectAdminList(pageable); + Page projectAdminLists = projectAdaptor.getProjectAdminList(pageable); List projectLists = new ArrayList<>(); @@ -139,7 +140,7 @@ public PageResponse> getProjectList(int page, return new PageResponse<>(projectAdminLists.isLast(), projectAdminLists.getTotalElements(), projectLists); } - @Transactional + @RedissonLock(LockName = "프로젝트", key = "#projectId") public void patchProjectStatus(ProjectStatus projectStatus, Long projectId) { Project project = projectAdaptor.findById(projectId); @@ -147,7 +148,7 @@ public void patchProjectStatus(ProjectStatus projectStatus, Long projectId) { if(projectStatus.equals(ProjectStatus.DEADLINE)) donationHistoryAdaptor.saveDonationHistory(projectConverter.convertToDonationHistory(projectId, HistoryStatus.FINISH)); - projectRepository.save(project); + projectAdaptor.save(project); } public void deleteProject(Long projectId) { @@ -155,7 +156,7 @@ public void deleteProject(Long projectId) { project.setStatus(Status.INACTIVE); - projectRepository.save(project); + projectAdaptor.save(project); } @Transactional @@ -164,24 +165,9 @@ public void patchProject(Long projectId, ProjectReq.ModifyProject modifyProject) project.modifyProject(modifyProject.getProjectName(), modifyProject.getUsages(), modifyProject.getDetail(), modifyProject.getRegularStatus(), modifyProject.getStartDate(), modifyProject.getEndDate(), modifyProject.getProjectKind(), modifyProject.getSearchKeyword()); - projectRepository.save(project); + projectAdaptor.save(project); } - @Transactional - public void saveImgList(Long id, String url, List imgUrlList) { - imgUrlList.add(url); - List projectImages = new ArrayList<>(); - - for (int i=1 ; i <= imgUrlList.size(); i++) { - if(i==imgUrlList.size()){ - projectImages.add(projectConverter.postProjectImage(id,imgUrlList.get(i-1),REPRESENT,i)); - }else { - projectImages.add(projectConverter.postProjectImage(id, imgUrlList.get(i-1),NORMAL, i)); - } - } - - projectImageRepository.saveAll(projectImages); - } @Transactional public ProjectRes.ProjectAdminDetail getProjectAdminDetail(Long projectId) { @@ -212,7 +198,7 @@ public ProjectRes.PatchProjectImg modifyProjectImg(Long projectId, Long projectI projectImage.setUrl(imgUrl); - projectImageRepository.save(projectImage); + projectImgService.save(projectImage); return new ProjectRes.PatchProjectImg(projectImgId, projectImage.getUrl()); } @@ -222,7 +208,7 @@ public void patchProjectActive(Long projectId) { project.setStatus(ACTIVE); - projectRepository.save(project); + projectAdaptor.save(project); } public PageResponse> getProjectLists(User user, int page, int size, ProjectKind projectKind, String content, FILTER filter) { @@ -233,11 +219,11 @@ public PageResponse> getProjectLists(User user, in @Transactional public ProjectRes.ProjectLike patchProjectLike(User user, Long projectId) { - boolean checkProjectLike = projectUserAttentionRepository.existsById_userIdAndId_projectId(user.getId(), projectId); + boolean checkProjectLike = attentionAdaptor.existsAttention(user.getId(), projectId); if(checkProjectLike){ - projectUserAttentionRepository.deleteById_userIdAndId_projectId(user.getId(), projectId); + attentionAdaptor.deleteProjectLike(user.getId(), projectId); }else{ - projectUserAttentionRepository.save(ProjectUserAttention.builder().id(new ProjectUserAttentionPk(user.getId(), projectId)).build()); + attentionAdaptor.save(ProjectUserAttention.builder().id(new ProjectUserAttentionPk(user.getId(), projectId)).build()); } return new ProjectRes.ProjectLike(!checkProjectLike); @@ -250,71 +236,13 @@ public PageResponse> getTodayProjectLists(User use } public ProjectRes.ProjectAppDetail getProjectAppDetail(User user, Long projectId) { - ProjectRepository.ProjectDetail projects = projectRepository.getProjectAppDetail(user.getId(), projectId); - List projectImages = projectImageRepository.findByProjectIdOrderBySequenceAsc(projectId); + ProjectRepository.ProjectDetail projects = projectAdaptor.getProjectAppDetail(user.getId(), projectId); + List projectImages = projectImgService.findByProjectId(projectId); return projectConverter.convertToProjectAppDetail(projects, projectImages); } - public PageResponse> projectList(User user, int page, int size, ProjectKind projectKind, String content) { - Pageable pageable = PageRequest.of(page, size); - List project = new ArrayList<>(); - - Page projects = projectRepository.findProject(user, PROCEEDING, LocalDateTime.now(), - REPRESENT, ACTIVE, projectKind, content, pageable); - - - projects.getContent().forEach( - result -> { - project.add(projectConverter.convertToProjectToDto(result)); - } - ); - return new PageResponse<>(projects.isLast(), projects.getTotalElements(), project); - } - - - public ProjectRes.CommentList postComment(User user, Long projectId, ProjectReq.Comment comment) { - ProjectComment projectComment = projectCommentRepository.save(projectConverter.convertToComment(user.getId(), projectId, comment.getComment())); - - return projectConverter.projectComment(user, projectComment); - } - - public void reportComment(Long commentId, ReportReason reportReason) { - ProjectComment projectComment = projectCommentRepository.findByIdAndStatus(commentId, ACTIVE).orElseThrow(()-> new NotFoundException(COMMENT_NOT_EXIST)); - - commentReportRepository.save(projectConverter.convertToReportComment(commentId, reportReason)); - } - - public void deleteComment(User user, Long commentId) { - ProjectComment projectComment = projectCommentRepository.findByIdAndStatus(commentId, ACTIVE).orElseThrow(()-> new NotFoundException(COMMENT_NOT_EXIST)); - if(!projectComment.getUserId().equals(user.getId())) throw new BadRequestException(COMMENT_DELETE_ERROR_CODE); - projectComment.setStatus(INACTIVE); - projectCommentRepository.save(projectComment); - } - - public Project checkProjectExists(Long projectId, RegularStatus regularStatus) { - return projectAdaptor.checkRegularProjects(projectId, regularStatus); - } - - public PageResponse> getProjectComment(User user, Long projectId, int page, int size) { - Pageable pageable = PageRequest.of(page, size); - - - Page projectComments = projectCommentRepository.findByProjectIdAndStatusOrderByCreatedAtAsc(projectId, ACTIVE,pageable); - - List commentLists = new ArrayList<>(); - projectComments.getContent().forEach( - result-> { - commentLists.add( - projectConverter.projectComment(user, result) - ); - } - ); - - - return new PageResponse<>(projectComments.isLast(), projectComments.getTotalElements(), commentLists); - } public PageResponse> getLikeProjects(User user, int page, int size) { Page projects = projectAdaptor.findLikeProjects(user, page, size); @@ -333,4 +261,14 @@ public List getTutorialDonation() { List projects = projectAdaptor.getRandom3Project(); return projectConverter.convertToTutorialDonation(projects); } + + public Long getProjectAttentionCnt(Long userId) { + return attentionAdaptor.getAttentionCnt(userId); + } + + + public Project checkProjectExists(Long projectId, RegularStatus regularStatus) { + return projectAdaptor.checkRegularProjects(projectId, regularStatus); + } + } diff --git a/Match-Api/src/main/java/com/example/matchapi/user/controller/AuthController.java b/Match-Api/src/main/java/com/example/matchapi/user/controller/AuthController.java index 26149096..4f18ce02 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/controller/AuthController.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/controller/AuthController.java @@ -161,7 +161,7 @@ public CommonResponse checkPhone(@RequestParam String phone){ return CommonResponse.onSuccess("문자 전송 성공"); } - @Operation(summary="01-10🔑 유저 전화번호 인증번호 확인 API", description= "전화번호 인증번호 확인 API 입니다.") + @Operation(summary="01-10🔑 유저 전화번호전화번호 인증번호 확인 API", description= "전화번호 인증번호 확인 API 입니다.") @PostMapping("/check/phone") @ApiErrorCodeExample(CodeAuthErrorCode.class) @DisableSecurity diff --git a/Match-Api/src/main/java/com/example/matchapi/user/controller/UserController.java b/Match-Api/src/main/java/com/example/matchapi/user/controller/UserController.java index d06caf64..7a03aa50 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/controller/UserController.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/controller/UserController.java @@ -2,13 +2,20 @@ import com.example.matchapi.common.model.AlarmType; import com.example.matchapi.common.security.JwtService; +import com.example.matchapi.donation.service.DonationService; +import com.example.matchapi.project.converter.ProjectConverter; +import com.example.matchapi.project.service.ProjectService; import com.example.matchapi.user.dto.UserRes; import com.example.matchapi.user.dto.UserReq; +import com.example.matchapi.user.service.RefreshTokenService; +import com.example.matchapi.user.service.UserFcmService; import com.example.matchapi.user.service.UserService; import com.example.matchcommon.annotation.ApiErrorCodeExample; import com.example.matchcommon.annotation.DisableSecurity; import com.example.matchcommon.exception.BadRequestException; import com.example.matchcommon.exception.errorcode.RequestErrorCode; +import com.example.matchdomain.donation.entity.RegularPayment; +import com.example.matchdomain.project.entity.enums.ProjectStatus; import com.example.matchdomain.redis.entity.RefreshToken; import com.example.matchdomain.redis.repository.RefreshTokenRepository; import com.example.matchdomain.user.entity.enums.SocialType; @@ -31,6 +38,7 @@ import javax.transaction.Transactional; import javax.validation.Valid; import java.io.IOException; +import java.util.List; import static com.example.matchdomain.user.exception.DeleteUserErrorCode.APPLE_USER_NOT_API; import static com.example.matchdomain.user.exception.UserAuthErrorCode.INVALID_REFRESH_TOKEN; @@ -43,19 +51,11 @@ public class UserController { private final UserService userService; private final JwtService jwtService; - private final RefreshTokenRepository refreshTokenRepository; - - /* - @Deprecated - @Operation(summary= "02-01👤 마이페이지 전체 조회",description = "마이페이지 전체 조회입니다.") - @GetMapping("") - public CommonResponse getMyPage(@Parameter(hidden = true) - @AuthenticationPrincipal User user){ - log.info("02-01 마이페이지 전체조회 userId : " + user.getId()); - return CommonResponse.onSuccess(userService.getMyPage(user)); - } - - */ + private final RefreshTokenService refreshTokenService; + private final UserFcmService userFcmService; + private final ProjectService projectService; + private final DonationService donationService; + private final ProjectConverter projectConverter; @ApiErrorCodeExample(UserAuthErrorCode.class) @Deprecated @@ -82,12 +82,9 @@ public CommonResponse editMyPage(@Parameter(hidden = true) @Transactional public CommonResponse logOut(@Parameter(hidden = true) @AuthenticationPrincipal User user, @Parameter(description = "디바이스 아이디") @RequestParam(value = "DEVICE_ID", required = true) String deviceId){ - log.info("api = logout 02-03"); - Long userId = user.getId(); - jwtService.logOut(userId); - userService.deleteFcmToken(userId, deviceId); + userFcmService.deleteFcmToken(userId, deviceId); return CommonResponse.onSuccess("로그아웃 성공"); } @@ -97,10 +94,9 @@ public CommonResponse logOut(@Parameter(hidden = true) @AuthenticationPr public CommonResponse reIssueToken( @Parameter(description = "리프레쉬 토큰", required = true, in = ParameterIn.HEADER, name = "X-REFRESH-TOKEN", schema = @Schema(type = "string")) @RequestHeader("X-REFRESH-TOKEN") String refreshToken ){ - log.info("reIssue-token : "+refreshToken); - log.info("api = reIssue-token 02-04"); Long userId=jwtService.getUserIdByRefreshToken(refreshToken); - RefreshToken redisRefreshToken= refreshTokenRepository.findById(String.valueOf(userId)).orElseThrow(()-> new BadRequestException(INVALID_REFRESH_TOKEN)); + + RefreshToken redisRefreshToken= refreshTokenService.findRefreshToken(userId); if(!redisRefreshToken.getToken().equals(refreshToken)) throw new BadRequestException(INVALID_REFRESH_TOKEN); @@ -114,7 +110,9 @@ public CommonResponse reIssueToken( public CommonResponse getMyPage(@Parameter(hidden = true) @AuthenticationPrincipal User user){ log.info("02-01 마이페이지 전체조회 userId : " + user.getId()); - return CommonResponse.onSuccess(userService.getMyPage(user)); + Long projectAttentionCnt = projectService.getProjectAttentionCnt(user.getId()); + List regularPayments = donationService.findByUser(user); + return CommonResponse.onSuccess(projectConverter.getMyPage(regularPayments, projectAttentionCnt, user.getNickname())); } @ApiErrorCodeExample(UserAuthErrorCode.class) @@ -145,7 +143,7 @@ public CommonResponse saveFcmToken( @Parameter(hidden = true) @AuthenticationPrincipal User user, @RequestBody UserReq.FcmToken token ){ - userService.saveFcmToken(user, token); + userFcmService.saveFcmToken(user, token); return CommonResponse.onSuccess("저장 성공"); } diff --git a/Match-Api/src/main/java/com/example/matchapi/user/converter/UserConverter.java b/Match-Api/src/main/java/com/example/matchapi/user/converter/UserConverter.java index 8582cd73..2fab6c81 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/converter/UserConverter.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/converter/UserConverter.java @@ -1,5 +1,6 @@ package com.example.matchapi.user.converter; +import com.example.matchapi.donation.helper.DonationHelper; import com.example.matchapi.order.dto.OrderRes; import com.example.matchapi.user.dto.UserReq; import com.example.matchapi.user.dto.UserRes; @@ -7,13 +8,11 @@ import com.example.matchapi.user.helper.UserHelper; import com.example.matchcommon.annotation.Converter; import com.example.matchcommon.properties.AligoProperties; -import com.example.matchcommon.reponse.PageResponse; import com.example.matchdomain.donation.entity.DonationUser; import com.example.matchdomain.redis.entity.RefreshToken; import com.example.matchdomain.user.entity.*; import com.example.matchdomain.user.entity.enums.AddressType; import com.example.matchdomain.user.entity.enums.AuthorityEnum; -import com.example.matchdomain.user.entity.enums.Gender; import com.example.matchdomain.user.entity.enums.SocialType; import com.example.matchdomain.user.entity.pk.UserFcmPk; import com.example.matchdomain.user.repository.UserRepository; @@ -22,11 +21,11 @@ import com.example.matchinfrastructure.oauth.kakao.dto.KakaoUserInfoDto; import com.example.matchinfrastructure.oauth.naver.dto.NaverUserInfoDto; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; + import org.springframework.security.crypto.password.PasswordEncoder; import javax.validation.Valid; -import java.time.LocalDate; + import java.util.ArrayList; import java.util.List; @@ -40,6 +39,7 @@ public class UserConverter { private final UserHelper userHelper; private final PasswordEncoder passwordEncoder; private final AligoProperties aligoProperties; + private final DonationHelper donationHelper; public User convertToKakaoSignUpUser(KakaoUserInfoDto kakaoUserInfoDto, SocialType authType) { String profileImg = BASE_PROFILE; @@ -58,7 +58,7 @@ public User convertToKakaoSignUpUser(KakaoUserInfoDto kakaoUserInfoDto, SocialTy .birth(authHelper.birthConversion(kakaoUserInfoDto.getBirthYear(), kakaoUserInfoDto.getBirthDay())) .gender(authHelper.genderConversion(kakaoUserInfoDto.getGender())) .role(AuthorityEnum.ROLE_USER.getValue()) - .nickname(userHelper.createRandomNickName()) + .nickname(kakaoUserInfoDto.getName()) .serviceAlarm(ACTIVE) .eventAlarm(ACTIVE) .build(); @@ -87,7 +87,7 @@ public User convertToNaverSignUpUser(NaverUserInfoDto naverUserInfoDto, SocialTy .birth(authHelper.birthConversion(naverUserInfoDto.getBirthyear(), naverUserInfoDto.getBirthday())) .gender(authHelper.genderConversion(naverUserInfoDto.getGender())) .role(AuthorityEnum.ROLE_USER.getValue()) - .nickname(userHelper.createRandomNickName()) + .nickname(naverUserInfoDto.getName()) .serviceAlarm(ACTIVE) .eventAlarm(ACTIVE) .build(); @@ -105,7 +105,7 @@ public User convertToSignUpUser(UserReq.SignUpUser signUpUser) { .birth(authHelper.birthConversionToLocalDate(signUpUser.getBirthDate())) .gender(signUpUser.getGender()) .role(AuthorityEnum.ROLE_USER.getValue()) - .nickname(userHelper.createRandomNickName()) + .nickname(signUpUser.getName()) .serviceAlarm(ACTIVE) .eventAlarm(ACTIVE) .build(); @@ -152,12 +152,14 @@ public OrderRes.UserDetail convertToUserInfo(User user) { .phoneNumber(user.getPhoneNumber()).build(); } - public UserRes.SignUpInfo convertToUserSignUpInfo(Long oneDayUser, Long weekUser, Long monthUser, Long totalUser) { + public UserRes.SignUpInfo convertToUserSignUpInfo(Long oneDayUser, Long weekUser, Long monthUser, Long totalUser, + Long deleteUser) { return UserRes.SignUpInfo.builder() .totalUserCnt(totalUser) .oneDayUserCnt(oneDayUser) .weekUserCnt(weekUser) .monthUserCnt(monthUser) + .deleteUserCnt(deleteUser) .build(); } @@ -168,7 +170,7 @@ public UserRes.UserList convertToUserList(UserRepository.UserList result) { .name(result.getName()) .birth(String.valueOf(result.getBirth())) .socialType(result.getSocialType().getName()) - .gender(result.getGender().getValue()) + .gender(result.getGender() == null ? null : result.getGender().getValue()) .email(result.getEmail()) .phoneNumber(result.getPhoneNumber()) .donationCnt(result.getDonationCnt()) @@ -179,22 +181,19 @@ public UserRes.UserList convertToUserList(UserRepository.UserList result) { .build(); } - public UserRes.UserAdminDetail convertToUserAdminDetail(UserRepository.UserList userDetail, List userCards) { + public UserRes.UserAdminDetail convertToUserAdminDetail(User userDetail) { return UserRes.UserAdminDetail .builder() - .userId(userDetail.getUserId()) + .userId(userDetail.getId()) .name(userDetail.getName()) .birth(String.valueOf(userDetail.getBirth())) .socialType(userDetail.getSocialType().getName()) - .gender(userDetail.getGender().getValue()) + .gender(userDetail.getGender() == null ? null : userDetail.getGender().getValue()) .email(userDetail.getEmail()) .phoneNumber(userDetail.getPhoneNumber()) - .donationCnt(userDetail.getDonationCnt()) - .totalAmount(userDetail.getTotalAmount()) - .card(userDetail.getCard()) .status(userDetail.getStatus().getValue()) .createdAt(userDetail.getCreatedAt().toString()) - //.userCards(userCards) + .nickname(userDetail.getNickname()) .build(); } @@ -243,7 +242,7 @@ public User convertToAppleUserSignUp(UserReq.@Valid AppleSignUp appleSignUp) { .socialId(appleSignUp.getSocialId()) .socialType(SocialType.APPLE) .role(AuthorityEnum.ROLE_USER.getValue()) - .nickname(userHelper.createRandomNickName()) + .nickname(appleSignUp.getName()) .serviceAlarm(ACTIVE) .eventAlarm(ACTIVE) .gender(appleSignUp.getGender()) @@ -292,4 +291,15 @@ private UserRes.UserFlameListDto convertToFlameDto(DonationUser donationUser, in .donationStatusName(donationUser.getDonationStatus().getName()) .build(); } + + public UserRes.DonationInfoDto convertToDonationInfoDto(Long regularCnt, List donationUsers, boolean isCard) { + return UserRes.DonationInfoDto + .builder() + .regularCnt(regularCnt) + .isCard(isCard) + .totalCnt((long)donationUsers.size()) + .totalAmount(donationHelper.parsePriceComma( + (int)donationUsers.stream().mapToLong(DonationUser::getPrice).sum())) + .build(); + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/user/dto/UserRes.java b/Match-Api/src/main/java/com/example/matchapi/user/dto/UserRes.java index 9329ea21..0a04235b 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/dto/UserRes.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/dto/UserRes.java @@ -7,6 +7,8 @@ import lombok.*; import org.springframework.format.annotation.DateTimeFormat; +import java.util.List; + public class UserRes { @Getter @Setter @@ -117,6 +119,8 @@ public static class SignUpInfo { private Long weekUserCnt; private Long monthUserCnt; + + private Long deleteUserCnt; } @Getter @@ -170,17 +174,11 @@ public static class UserAdminDetail { private String email; - private boolean card; - - private int donationCnt; - - private int totalAmount; - private String status; private String createdAt; - //private List userCards; + private String nickname; } public static class EmailAuth { @@ -234,4 +232,43 @@ public static class UserFlameListDto { private String donationStatusName; } + + @Getter + @Setter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class UserDelete { + private Long userId; + } + + @Getter + @Setter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class UserDonationInfo { + private int nowDonationCnt; + + private int pastDonationCnt; + + private int totalCnt; + + private List flameLists; + } + + @Getter + @Setter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class DonationInfoDto { + private Long regularCnt; + + private Long totalCnt; + + private String totalAmount; + + private boolean isCard; + } } diff --git a/Match-Api/src/main/java/com/example/matchapi/user/service/RefreshTokenService.java b/Match-Api/src/main/java/com/example/matchapi/user/service/RefreshTokenService.java new file mode 100644 index 00000000..89632e94 --- /dev/null +++ b/Match-Api/src/main/java/com/example/matchapi/user/service/RefreshTokenService.java @@ -0,0 +1,19 @@ +package com.example.matchapi.user.service; + +import com.example.matchcommon.exception.BadRequestException; +import com.example.matchdomain.redis.entity.RefreshToken; +import com.example.matchdomain.redis.repository.RefreshTokenRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import static com.example.matchdomain.user.exception.UserAuthErrorCode.INVALID_REFRESH_TOKEN; + +@Service +@RequiredArgsConstructor +public class RefreshTokenService { + private final RefreshTokenRepository refreshTokenRepository; + + public RefreshToken findRefreshToken(Long userId) { + return refreshTokenRepository.findById(String.valueOf(userId)).orElseThrow(()-> new BadRequestException(INVALID_REFRESH_TOKEN)); + } +} diff --git a/Match-Api/src/main/java/com/example/matchapi/user/service/UserFcmService.java b/Match-Api/src/main/java/com/example/matchapi/user/service/UserFcmService.java new file mode 100644 index 00000000..fd033268 --- /dev/null +++ b/Match-Api/src/main/java/com/example/matchapi/user/service/UserFcmService.java @@ -0,0 +1,27 @@ +package com.example.matchapi.user.service; + +import com.example.matchapi.user.converter.UserConverter; +import com.example.matchapi.user.dto.UserReq; +import com.example.matchdomain.user.entity.User; +import com.example.matchdomain.user.entity.pk.UserFcmPk; +import com.example.matchdomain.user.repository.UserFcmTokenRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@RequiredArgsConstructor +@Service +public class UserFcmService { + private final UserFcmTokenRepository userFcmTokenRepository; + private final UserConverter userConverter; + + public void saveFcmToken(User user, UserReq.FcmToken token) { + userFcmTokenRepository.save(userConverter.convertToUserFcm(user, token)); + } + + public void deleteFcmToken(Long userId, String deviceId) { + UserFcmPk userFcmPk = UserFcmPk.builder().userId(userId).deviceId(deviceId).build(); + if(userFcmTokenRepository.existsById(userFcmPk)) { + userFcmTokenRepository.deleteById(userFcmPk); + } + } +} diff --git a/Match-Api/src/main/java/com/example/matchapi/user/service/UserService.java b/Match-Api/src/main/java/com/example/matchapi/user/service/UserService.java index d84c1cdc..0aff4105 100644 --- a/Match-Api/src/main/java/com/example/matchapi/user/service/UserService.java +++ b/Match-Api/src/main/java/com/example/matchapi/user/service/UserService.java @@ -3,48 +3,23 @@ import com.example.matchapi.common.model.AlarmType; import com.example.matchapi.donation.service.DonationService; import com.example.matchapi.order.dto.OrderRes; -import com.example.matchapi.order.service.OrderService; -import com.example.matchapi.project.converter.ProjectConverter; import com.example.matchapi.user.converter.UserConverter; import com.example.matchapi.user.dto.UserReq; import com.example.matchapi.user.dto.UserRes; import com.example.matchcommon.annotation.RedissonLock; import com.example.matchcommon.exception.BadRequestException; -import com.example.matchcommon.exception.NotFoundException; -import com.example.matchcommon.exception.UnauthorizedException; -import com.example.matchcommon.reponse.PageResponse; import com.example.matchdomain.common.model.Status; -import com.example.matchdomain.donation.entity.RegularPayment; -import com.example.matchdomain.donation.repository.RegularPaymentRepository; -import com.example.matchdomain.project.entity.Project; -import com.example.matchdomain.project.repository.ProjectUserAttentionRepository; import com.example.matchdomain.user.adaptor.UserAdaptor; import com.example.matchdomain.user.entity.User; -import com.example.matchdomain.user.entity.UserAddress; import com.example.matchdomain.user.entity.enums.Alarm; -import com.example.matchdomain.user.entity.pk.UserFcmPk; import com.example.matchdomain.user.exception.ModifyEmailCode; -import com.example.matchdomain.user.exception.UserAuthErrorCode; -import com.example.matchdomain.user.repository.UserAddressRepository; -import com.example.matchdomain.user.repository.UserFcmTokenRepository; -import com.example.matchdomain.user.repository.UserRepository; import com.example.matchinfrastructure.config.s3.S3UploadService; import com.example.matchinfrastructure.oauth.apple.service.AppleAuthService; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.CacheEvict; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import javax.transaction.Transactional; -import javax.validation.Valid; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.temporal.TemporalAdjusters; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; import static com.example.matchapi.common.model.AlarmType.EVENT; import static com.example.matchcommon.constants.MatchStatic.*; @@ -52,105 +27,33 @@ import static com.example.matchdomain.user.entity.enums.Alarm.INACTIVE; import static com.example.matchdomain.user.exception.ModifyEmailCode.NOT_CORRECT_EMAIL; import static com.example.matchdomain.user.exception.ModifyPhoneErrorCode.NOT_CORRECT_PHONE; -import static com.example.matchdomain.user.exception.UserAuthErrorCode.NOT_EXIST_USER; import static com.example.matchdomain.user.exception.UserNormalSignUpErrorCode.USERS_EXISTS_PHONE; @Service @RequiredArgsConstructor public class UserService { - - private final UserRepository userRepository; - private final UserAddressRepository userAddressRepository; private final UserConverter userConverter; - private final ProjectConverter projectConverter; - private final ProjectUserAttentionRepository projectUserAttentionRepository; - private final OrderService orderService; - private final RegularPaymentRepository regularPaymentRepository; private final S3UploadService s3UploadService; - private final UserFcmTokenRepository userFcmTokenRepository; private final DonationService donationService; private final AppleAuthService appleAuthService; private final AuthService authService; private final UserAdaptor userAdaptor; - public Optional findUser(long id) { - return userRepository.findById(id); - } - - public List findUserAddress(Long id) { - List userAddressEntity = userAddressRepository.findByUserId(id); - System.out.println(userAddressEntity); - return userAddressEntity; - } - public UserRes.EditMyPage getEditMyPage(User user) { return userConverter.convertToMyPage(user); } - public UserRes.MyPage getMyPage(User user) { - List regularPayments = regularPaymentRepository.findByUser(user); - Long projectAttentionCnt = projectUserAttentionRepository.countById_userId(user.getId()); - - return projectConverter.getMyPage(regularPayments,projectAttentionCnt, user.getNickname()); - } public OrderRes.UserDetail getUserInfo(User user) { return userConverter.convertToUserInfo(user); } - public UserRes.SignUpInfo getUserSignUpInfo() { - LocalDate localDate = LocalDate.now(); - Long totalUser = userRepository.countBy(); - Long oneDayUser = userRepository.countByCreatedAtGreaterThanAndCreatedAtLessThan(LocalDateTime.parse(localDate+FIRST_TIME), LocalDateTime.parse(localDate+LAST_TIME)); - Long weekUser = userRepository.countByCreatedAtGreaterThanAndCreatedAtLessThan(LocalDateTime.parse(localDate.minusWeeks(1)+FIRST_TIME) , LocalDateTime.parse(localDate+LAST_TIME)); - Long monthUser = userRepository.countByCreatedAtGreaterThanAndCreatedAtLessThan(LocalDateTime.parse(localDate.with(TemporalAdjusters.firstDayOfMonth())+FIRST_TIME), LocalDateTime.parse(localDate.with(TemporalAdjusters.lastDayOfMonth())+LAST_TIME)); - - return userConverter.convertToUserSignUpInfo(oneDayUser,weekUser,monthUser,totalUser); - } - - @Transactional - public PageResponse> getUserList(int page, int size, Status status, String content) { - Pageable pageable = PageRequest.of(page, size); - Page userList = null; - System.out.println(status); - if(status == null && content ==null) { - userList = userRepository.getUserList(pageable); - } - else if (status !=null && content ==null){ - userList = userRepository.getUserListByStatus(pageable, status.getValue()); - } - else if(status!=null){ - userList = userRepository.getUserListByStatusAndName(pageable, status.getValue(),content); - } - else{ - userList = userRepository.getUserListByName(pageable, content); - } - List userLists = new ArrayList<>(); - - userList.getContent().forEach( - result -> userLists.add( - userConverter.convertToUserList(result) - ) - ); - - return new PageResponse<>(userList.isLast(),userList.getTotalElements(),userLists); - } - - public UserRes.UserAdminDetail getUserAdminDetail(Long userId) { - UserRepository.UserList userDetail = userRepository.getUserDetail(userId); - - List userCards = orderService.getUserBillCard(userId); - - - return userConverter.convertToUserAdminDetail(userDetail,userCards); - } public UserRes.Profile getProfile(User user) { return userConverter.convertToUserProfile(user); } @Transactional - @CacheEvict(value = "userCache", key = "#user.id", cacheManager = "redisCacheManager") public void modifyUserProfile(User user, UserReq.ModifyProfile modifyProfile) { if(modifyProfile.getName() == null && modifyProfile.getMultipartFile()!=null){ String beforeProfileImg = user.getProfileImgUrl(); @@ -173,35 +76,23 @@ else if (modifyProfile.getMultipartFile() != null){ user.setModifyProfile(newProfileImg, modifyProfile.getName()); } - userRepository.save(user); - } - - public void saveFcmToken(User user, UserReq.FcmToken token) { - userFcmTokenRepository.save(userConverter.convertToUserFcm(user, token)); - } - - public void deleteFcmToken(Long userId, String deviceId) { - UserFcmPk userFcmPk = UserFcmPk.builder().userId(userId).deviceId(deviceId).build(); - if(userFcmTokenRepository.existsById(userFcmPk)) { - userFcmTokenRepository.deleteById(userFcmPk); - } + userAdaptor.save(user); } @Transactional public void modifyPhoneNumber(User user, UserReq.ModifyPhone phone) { if(!user.getPhoneNumber().equals(phone.getOldPhone())) throw new BadRequestException(NOT_CORRECT_PHONE); - if(userRepository.existsByPhoneNumber(phone.getNewPhone())) throw new BadRequestException(USERS_EXISTS_PHONE); + if(userAdaptor.existsPhoneNumber(phone.getNewPhone())) throw new BadRequestException(USERS_EXISTS_PHONE); user.setPhoneNumber(phone.getNewPhone()); - userRepository.save(user); - + userAdaptor.save(user); } @Transactional public void modifyEmail(User user, UserReq.ModifyEmail email) { if(!user.getEmail().equals(email.getOldEmail())) throw new BadRequestException(NOT_CORRECT_EMAIL); - if(userRepository.existsByEmailAndStatus(email.getNewEmail(), Status.ACTIVE)) throw new BadRequestException(ModifyEmailCode.USERS_EXISTS_EMAIL); + if(userAdaptor.existsEmail(email.getNewEmail())) throw new BadRequestException(ModifyEmailCode.USERS_EXISTS_EMAIL); user.setEmail(email.getNewEmail()); - userRepository.save(user); + userAdaptor.save(user); } public UserRes.AlarmAgreeList getAlarmAgreeList(User user) { @@ -229,7 +120,7 @@ public UserRes.AlarmAgreeList patchAlarm(User user, AlarmType alarmType) { } } - user = userRepository.save(user); + user = userAdaptor.save(user); return userConverter.convertToAlarmAgree(user); } @@ -239,14 +130,14 @@ public void postAppleUserInfo(User user, UserReq.AppleUserInfo appleUserInfo) { authService.checkUserPhone(new UserReq.UserPhone(appleUserInfo.getPhone())); user.updateUserInfo(appleUserInfo.getBirthDate(), appleUserInfo.getName(), appleUserInfo.getPhone()); - userRepository.save(user); + userAdaptor.save(user); } @RedissonLock(LockName = "유저 탈퇴", key = "#user.id") public void deleteUserInfo(User user) { user.setStatus(Status.INACTIVE); donationService.deleteRegularPayment(user); - userRepository.save(user); + userAdaptor.save(user); } public void deleteAppleUserInfo(User user, UserReq.AppleCode appleCode) { @@ -258,7 +149,4 @@ public User findByUser(String userId) { return userAdaptor.findByUser(userId); } - public User findByUserId(Long userId) { - return userAdaptor.findByUserId(userId).orElseThrow(() -> new NotFoundException(NOT_EXIST_USER)); - } } diff --git a/Match-Api/src/main/resources/ehcache.xml b/Match-Api/src/main/resources/ehcache.xml index 9f720e54..8044e301 100644 --- a/Match-Api/src/main/resources/ehcache.xml +++ b/Match-Api/src/main/resources/ehcache.xml @@ -17,18 +17,6 @@ - - - - - - - - diff --git a/Match-Batch/src/main/java/com/example/matchbatch/service/OrderService.java b/Match-Batch/src/main/java/com/example/matchbatch/service/OrderService.java index 51a096e9..bff083e0 100644 --- a/Match-Batch/src/main/java/com/example/matchbatch/service/OrderService.java +++ b/Match-Batch/src/main/java/com/example/matchbatch/service/OrderService.java @@ -6,6 +6,7 @@ import com.example.matchbatch.model.CalculateMonthLastDateDto; import com.example.matchbatch.model.PaymentCntDto; import com.example.matchcommon.annotation.RedissonLock; +import com.example.matchcommon.exception.BaseException; import com.example.matchdomain.donation.adaptor.RegularPaymentAdaptor; import com.example.matchdomain.donation.adaptor.RequestFailedHistoryAdapter; import com.example.matchdomain.donation.entity.*; @@ -26,6 +27,7 @@ import java.util.stream.Collectors; import static com.example.matchcommon.constants.MatchStatic.*; +import static org.springframework.http.HttpStatus.*; @Service @RequiredArgsConstructor @@ -111,7 +113,7 @@ public boolean processRegularPayment(RegularPayment payment, String accessToken, String orderId = orderHelper.createRandomOrderId(); PortOneResponse portOneResponse = attemptPayment(payment, accessToken, orderId); - if(portOneResponse.getCode()!=0){ + if(portOneResponse.getCode()!=0 || portOneResponse.getResponse().getFail_reason()!=null){ handlePaymentFailure(payment, portOneResponse.getMessage(), type); return true; } diff --git a/Match-Common/src/main/java/com/example/matchcommon/config/CacheConfig.java b/Match-Common/src/main/java/com/example/matchcommon/config/CacheConfig.java index 3001c20e..4a615c01 100644 --- a/Match-Common/src/main/java/com/example/matchcommon/config/CacheConfig.java +++ b/Match-Common/src/main/java/com/example/matchcommon/config/CacheConfig.java @@ -1,10 +1,6 @@ package com.example.matchcommon.config; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.extern.slf4j.Slf4j; -import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.ehcache.EhCacheCacheManager; import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; @@ -12,17 +8,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.core.io.ClassPathResource; -import org.springframework.data.redis.cache.RedisCacheConfiguration; -import org.springframework.data.redis.cache.RedisCacheManager; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; -import org.springframework.data.redis.serializer.RedisSerializationContext; -import org.springframework.data.redis.serializer.StringRedisSerializer; -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; @Configuration @EnableCaching @@ -44,28 +30,4 @@ public EhCacheCacheManager ehcacheManager() { return ehCacheCacheManager; } - @Bean(name = "redisCacheManager") - public CacheManager redisCacheManager(RedisConnectionFactory connectionFactory) { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JavaTimeModule()); - objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - - GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(objectMapper); - - - RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() - .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) - .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer)) - .disableCachingNullValues() - .entryTtl(Duration.ofHours(5L)); - - Map cacheConfigurations = new HashMap<>(); - - cacheConfigurations.put("userCache", redisCacheConfiguration.entryTtl(Duration.ofMinutes(5))); - - return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(connectionFactory) - .cacheDefaults(redisCacheConfiguration) - .withInitialCacheConfigurations(cacheConfigurations) - .build(); - } } \ No newline at end of file diff --git a/Match-Common/src/main/java/com/example/matchcommon/config/CacheUtils.java b/Match-Common/src/main/java/com/example/matchcommon/config/CacheUtils.java new file mode 100644 index 00000000..5ada38ef --- /dev/null +++ b/Match-Common/src/main/java/com/example/matchcommon/config/CacheUtils.java @@ -0,0 +1,31 @@ +package com.example.matchcommon.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +public class CacheUtils { + @SuppressWarnings("unchecked") + public static Page convertLinkedHashMapToPage(LinkedHashMap map, Class dtoClass) { + List content = (List) map.get("content"); + List dtos = (List) content.stream() + .map(item -> convertMapToDto((Map) item, dtoClass)) + .collect(Collectors.toList()); + + int number = (int) map.get("number"); + int size = (int) map.get("size"); + int totalElements = (int) map.get("totalElements"); + + return new PageImpl<>(dtos, PageRequest.of(number, size), totalElements); + } + + private static Object convertMapToDto(Map map, Class dtoClass) { + // ObjectMapper를 사용하여 Map을 DTO 클래스로 변환 + ObjectMapper mapper = new ObjectMapper(); + return mapper.convertValue(map, dtoClass); + } +} diff --git a/Match-Common/src/main/java/com/example/matchcommon/config/RedisConfig.java b/Match-Common/src/main/java/com/example/matchcommon/config/RedisConfig.java index 4b002180..b8494e8d 100644 --- a/Match-Common/src/main/java/com/example/matchcommon/config/RedisConfig.java +++ b/Match-Common/src/main/java/com/example/matchcommon/config/RedisConfig.java @@ -1,6 +1,11 @@ package com.example.matchcommon.config; import com.example.matchcommon.properties.RedisProperties; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.lettuce.core.ClientOptions; import io.lettuce.core.SocketOptions; import lombok.RequiredArgsConstructor; @@ -8,17 +13,22 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; -import org.springframework.data.redis.core.RedisKeyValueAdapter; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; +import java.util.HashMap; +import java.util.Map; @Configuration @EnableRedisRepositories( @@ -56,15 +66,12 @@ public RedisTemplate redisTemplate() { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); - // 일반적인 key:value의 경우 시리얼라이저 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); - // Hash를 사용할 경우 시리얼라이저 redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new StringRedisSerializer()); - // 모든 경우 redisTemplate.setDefaultSerializer(new StringRedisSerializer()); return redisTemplate; @@ -78,4 +85,31 @@ public StringRedisTemplate stringRedisTemplate(){ stringRedisTemplate.setConnectionFactory(redisConnectionFactory()); return stringRedisTemplate; } + + @Bean(name = "redisCacheManager") + public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, + ObjectMapper.DefaultTyping.NON_FINAL, + JsonTypeInfo.As.PROPERTY); + + // Jackson2JsonRedisSerializer를 사용하여 타입 정보를 포함 + Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class); + serializer.setObjectMapper(objectMapper); + + RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() + .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) + .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer)); + + Map cacheConfiguration = new HashMap<>(); + cacheConfiguration.put("flameCache", redisCacheConfiguration.entryTtl(Duration.ofMinutes(10L))); + cacheConfiguration.put("regularInfo", redisCacheConfiguration.entryTtl(Duration.ofMinutes(3L))); + + + return RedisCacheManager.RedisCacheManagerBuilder + .fromConnectionFactory(redisConnectionFactory) + .cacheDefaults(redisCacheConfiguration) + .withInitialCacheConfigurations(cacheConfiguration) + .build(); + } } diff --git a/Match-Common/src/main/java/com/example/matchcommon/listner/CacheEvictEvent.java b/Match-Common/src/main/java/com/example/matchcommon/listner/CacheEvictEvent.java new file mode 100644 index 00000000..426b90d4 --- /dev/null +++ b/Match-Common/src/main/java/com/example/matchcommon/listner/CacheEvictEvent.java @@ -0,0 +1,16 @@ +package com.example.matchcommon.listner; + +import org.springframework.context.ApplicationEvent; + +public class CacheEvictEvent extends ApplicationEvent { + private final Long userId; + + public CacheEvictEvent(Object source, Long userId) { + super(source); + this.userId = userId; + } + + public Long getUserId(){ + return userId; + } +} diff --git a/Match-Common/src/main/java/com/example/matchcommon/listner/CacheEvictListener.java b/Match-Common/src/main/java/com/example/matchcommon/listner/CacheEvictListener.java new file mode 100644 index 00000000..df48744e --- /dev/null +++ b/Match-Common/src/main/java/com/example/matchcommon/listner/CacheEvictListener.java @@ -0,0 +1,34 @@ +package com.example.matchcommon.listner; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.event.EventListener; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import java.util.Set; + + +@Component +@Slf4j +public class CacheEvictListener { + @Autowired + private StringRedisTemplate stringRedisTemplate; + @Value("${spring.config.activate.on-profile}") + private String profile; + + @EventListener + @Async("event-listener") + public void onCacheEvict(CacheEvictEvent event){ + log.info("CacheEvictEvent received, userId: {}", event.getUserId()); + String pattern = "flameCache::" + profile + "," + event.getUserId() + ",*"; + Set keys = stringRedisTemplate.keys(pattern); + if (keys != null && !keys.isEmpty()) { + log.info("CacheEvictEvent delete keys: {}", keys); + stringRedisTemplate.delete(keys); + } + log.info("CacheEvictEvent finished, userId: {}", event.getUserId()); + } +} diff --git a/Match-Common/src/main/java/com/example/matchcommon/listner/CacheService.java b/Match-Common/src/main/java/com/example/matchcommon/listner/CacheService.java new file mode 100644 index 00000000..baa0d6e8 --- /dev/null +++ b/Match-Common/src/main/java/com/example/matchcommon/listner/CacheService.java @@ -0,0 +1,22 @@ +package com.example.matchcommon.listner; + +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class CacheService { + @Autowired + private ApplicationEventPublisher eventPublisher; + + + public void evictCache(Long userId){ + CacheEvictEvent event = new CacheEvictEvent(this, userId); + + eventPublisher.publishEvent(event); + } + + +} diff --git a/Match-Common/src/main/java/com/example/matchcommon/reponse/CommonResponse.java b/Match-Common/src/main/java/com/example/matchcommon/reponse/CommonResponse.java index 3d84def6..6416f632 100644 --- a/Match-Common/src/main/java/com/example/matchcommon/reponse/CommonResponse.java +++ b/Match-Common/src/main/java/com/example/matchcommon/reponse/CommonResponse.java @@ -35,10 +35,6 @@ public CommonResponse() { this.code = null; } - // 요청에 성공한 경우11 - - - public static CommonResponse onSuccess(T data) { return new CommonResponse<>(true, "요청에 성공하였습니다.","1000", data); diff --git a/Match-Common/src/main/java/com/example/matchcommon/reponse/PageResponse.java b/Match-Common/src/main/java/com/example/matchcommon/reponse/PageResponse.java index 7d9f3dc0..0b613d79 100644 --- a/Match-Common/src/main/java/com/example/matchcommon/reponse/PageResponse.java +++ b/Match-Common/src/main/java/com/example/matchcommon/reponse/PageResponse.java @@ -1,15 +1,16 @@ package com.example.matchcommon.reponse; +import com.fasterxml.jackson.annotation.JsonCreator; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.ToString; +import lombok.*; +import org.springframework.stereotype.Service; import java.io.Serializable; @Getter @AllArgsConstructor +@Setter @ToString @Schema(description = "페이징 처리 응답") public class PageResponse implements Serializable { @@ -19,4 +20,11 @@ public class PageResponse implements Serializable { private final long totalCnt; @Schema(description = "요소", required = true) private final T contents; + + @JsonCreator + public PageResponse(){ + this.isLast = null; + this.totalCnt = 0; + this.contents = null; + } } diff --git a/Match-Domain/src/main/generated/com/example/matchdomain/banner/entity/QBanner.java b/Match-Domain/src/main/generated/com/example/matchdomain/banner/entity/QBanner.java index fd118ba3..bb427f07 100644 --- a/Match-Domain/src/main/generated/com/example/matchdomain/banner/entity/QBanner.java +++ b/Match-Domain/src/main/generated/com/example/matchdomain/banner/entity/QBanner.java @@ -33,12 +33,18 @@ public class QBanner extends EntityPathBase { //inherited public final DateTimePath createdAt = _super.createdAt; + public final DateTimePath endDate = createDateTime("endDate", java.time.LocalDateTime.class); + public final com.example.matchdomain.event.entity.QEvent event; public final NumberPath eventId = createNumber("eventId", Long.class); public final NumberPath id = createNumber("id", Long.class); + public final StringPath name = createString("name"); + + public final DateTimePath startDate = createDateTime("startDate", java.time.LocalDateTime.class); + //inherited public final EnumPath status = _super.status; diff --git a/Match-Domain/src/main/java/com/example/matchdomain/banner/adaptor/BannerAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/banner/adaptor/BannerAdaptor.java index 2fe52148..99699594 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/banner/adaptor/BannerAdaptor.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/banner/adaptor/BannerAdaptor.java @@ -1,12 +1,19 @@ package com.example.matchdomain.banner.adaptor; +import static com.example.matchdomain.banner.exception.BannerGerErrorCode.*; + import com.example.matchcommon.annotation.Adaptor; +import com.example.matchcommon.exception.NotFoundException; import com.example.matchdomain.banner.entity.Banner; import com.example.matchdomain.banner.repository.BannerRepository; import com.example.matchdomain.keyword.entity.SearchKeyword; import lombok.RequiredArgsConstructor; import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -16,6 +23,25 @@ public class BannerAdaptor { private final BannerRepository bannerRepository; public List getBannerList() { - return bannerRepository.findAllByOrderByCreatedAtDesc(); + LocalDateTime now = LocalDateTime.now(); + return bannerRepository.findByStartDateLessThanAndEndDateGreaterThanOrderByCreatedAtDesc(now, now); + } + + public Banner save(Banner banner) { + return bannerRepository.save(banner); + } + + public Banner findById(Long bannerId) { + return bannerRepository.findById(bannerId).orElseThrow(() -> new NotFoundException(NOT_EXISTS_BANNER)); } + + public void deleteById(Long bannerId) { + bannerRepository.deleteById(bannerId); + } + + public Page getBannerLists(int page, int size) { + Pageable pageable = PageRequest.of(page, size); + return bannerRepository.findByOrderByCreatedAtDesc(pageable); + + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/banner/entity/Banner.java b/Match-Domain/src/main/java/com/example/matchdomain/banner/entity/Banner.java index c48067e9..238d4af2 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/banner/entity/Banner.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/banner/entity/Banner.java @@ -1,5 +1,7 @@ package com.example.matchdomain.banner.entity; +import java.time.LocalDateTime; + import com.example.matchdomain.banner.enums.BannerType; import com.example.matchdomain.common.model.BaseEntity; import com.example.matchdomain.event.entity.Event; @@ -29,6 +31,8 @@ public class Banner extends BaseEntity { @Enumerated(EnumType.STRING) private BannerType bannerType; + private String name; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "eventId",nullable = false, insertable=false, updatable=false) private Event event; @@ -39,4 +43,15 @@ public class Banner extends BaseEntity { private String bannerImg; private String contentsUrl; + + private LocalDateTime startDate; + + private LocalDateTime endDate; + + public void updateBanner(String name, LocalDateTime startDate, LocalDateTime endDate, String bannerImg) { + this.name = name; + this.startDate = startDate; + this.endDate = endDate; + this.bannerImg = bannerImg; + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/banner/exception/BannerGerErrorCode.java b/Match-Domain/src/main/java/com/example/matchdomain/banner/exception/BannerGerErrorCode.java new file mode 100644 index 00000000..667de9a7 --- /dev/null +++ b/Match-Domain/src/main/java/com/example/matchdomain/banner/exception/BannerGerErrorCode.java @@ -0,0 +1,44 @@ +package com.example.matchdomain.banner.exception; + +import static org.springframework.http.HttpStatus.*; + +import java.lang.reflect.Field; +import java.util.Objects; + +import org.springframework.http.HttpStatus; + +import com.example.matchcommon.annotation.ExplainError; +import com.example.matchcommon.dto.ErrorReason; +import com.example.matchcommon.exception.errorcode.BaseErrorCode; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum BannerGerErrorCode implements BaseErrorCode { + @ExplainError("해당 도네이션이 존재하지 않습니다.") + NOT_EXISTS_BANNER(NOT_FOUND,"DONATION001", "해당 배너가 존재하지 않습니다."); + + + private final HttpStatus httpStatus; + private final String code; + private final String message; + + @Override + public ErrorReason getErrorReason() { + return ErrorReason.builder().message(message).code(code).isSuccess(false).build(); + } + + @Override + public String getExplainError() throws NoSuchFieldException { + Field field = this.getClass().getField(this.name()); + ExplainError annotation = field.getAnnotation(ExplainError.class); + return Objects.nonNull(annotation) ? annotation.value() : this.getMessage(); + } + + @Override + public ErrorReason getErrorReasonHttpStatus(){ + return ErrorReason.builder().message(message).code(code).isSuccess(false).httpStatus(httpStatus).build(); + } +} \ No newline at end of file diff --git a/Match-Domain/src/main/java/com/example/matchdomain/banner/repository/BannerRepository.java b/Match-Domain/src/main/java/com/example/matchdomain/banner/repository/BannerRepository.java index 35c2ce85..685f0ad5 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/banner/repository/BannerRepository.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/banner/repository/BannerRepository.java @@ -1,10 +1,18 @@ package com.example.matchdomain.banner.repository; import com.example.matchdomain.banner.entity.Banner; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import java.time.LocalDateTime; import java.util.List; public interface BannerRepository extends JpaRepository { List findAllByOrderByCreatedAtDesc(); + + List findByStartDateLessThanAndEndDateGreaterThanOrderByCreatedAtDesc(LocalDateTime now, LocalDateTime now1); + + Page findByOrderByCreatedAtDesc(Pageable pageable); } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/DonationAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/DonationAdaptor.java index 1b92e024..bd0a5d70 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/DonationAdaptor.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/DonationAdaptor.java @@ -11,6 +11,7 @@ import com.example.matchdomain.project.entity.Project; import com.example.matchdomain.user.entity.User; import lombok.RequiredArgsConstructor; +import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -131,4 +132,12 @@ public Page findDonationLists(Long projectId, int page, int size) return donationUserRepository.findByProjectIdAndDonationStatusInOrderByCreatedAtAsc(projectId, in, pageable); } + + public List getRegularDonationLists() { + return donationUserRepository.findAll(); + } + + public List findByUserId(Long userId) { + return donationUserRepository.findByUserIdAndDonationStatusNot(userId, EXECUTION_REFUND); + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/RegularPaymentAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/RegularPaymentAdaptor.java index 87cadee5..f0b96c44 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/RegularPaymentAdaptor.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/donation/adaptor/RegularPaymentAdaptor.java @@ -16,7 +16,7 @@ import java.util.List; import java.util.stream.Collectors; -import static com.example.matchdomain.donation.entity.enums.RegularPayStatus.PROCEEDING; +import static com.example.matchdomain.donation.entity.enums.RegularPayStatus.*; import static com.example.matchdomain.donation.exception.CancelRegularPayErrorCode.REGULAR_PAY_NOT_EXIST; import static com.example.matchdomain.donation.exception.GetRegularErrorCode.REGULAR_NOT_EXIST; @@ -68,4 +68,16 @@ public List findByDate(int currentDay) { public void saveAll(List regularPayments) { regularPaymentRepository.saveAll(regularPayments); } + + public List findByUserPage(User user) { + return regularPaymentRepository.findByUser(user); + } + + public List getRegularInfo() { + return regularPaymentRepository.findAllByOrderByCreatedAtAsc(); + } + + public Long countByUserId(Long userId) { + return regularPaymentRepository.countByUserIdAndRegularPayStatusNot(userId, USER_CANCEL); + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/flameEnum/FlameImage.java b/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/flameEnum/FlameImage.java index 9654a99e..7280d1fb 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/flameEnum/FlameImage.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/flameEnum/FlameImage.java @@ -6,6 +6,7 @@ @Getter @AllArgsConstructor public enum FlameImage { - NORMAL_IMG("https://match-image.s3.ap-northeast-2.amazonaws.com/flame.png"); + NORMAL_IMG("https://match-image.s3.ap-northeast-2.amazonaws.com/flame.png"), + TUTORIAL_IMG("https://match-image.s3.ap-northeast-2.amazonaws.com/tutorial_flame.png"); private final String img; } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/flameEnum/FlameType.java b/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/flameEnum/FlameType.java index 81f9c2ba..73951864 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/flameEnum/FlameType.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/donation/entity/flameEnum/FlameType.java @@ -6,6 +6,7 @@ @Getter @AllArgsConstructor public enum FlameType { + TUTORIAL_FLAME("TUTORIAL_FLAME", "튜토리얼 불꽃"), NORMAL_FLAME("NORMAL_FLAME", "일반 불꽃"); private final String value; diff --git a/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/DonationUserRepository.java b/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/DonationUserRepository.java index 0da83b60..f2ff8f3d 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/DonationUserRepository.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/DonationUserRepository.java @@ -88,6 +88,9 @@ public interface DonationUserRepository extends JpaRepository countQuery = "SELECT count(DU) FROM DonationUser DU WHERE DU.projectId = :projectId AND DU.donationStatus IN :statuses") Page findByProjectIdAndDonationStatusInOrderByCreatedAtAsc(@Param("projectId") Long projectId, @Param("statuses") List donationStatuses, Pageable pageable); + List findByRegularPaymentNotNull(); + + List findByUserIdAndDonationStatusNot(Long userId, DonationStatus donationStatus); interface flameList { Long getRegularPayId(); diff --git a/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/RegularPaymentRepository.java b/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/RegularPaymentRepository.java index 81fb3a16..6dec1297 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/RegularPaymentRepository.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/donation/repository/RegularPaymentRepository.java @@ -48,6 +48,10 @@ Page getBurningFlameListCustom(@Param("userId") Long userId List findByPayDateAndStatusAndRegularPayStatus(int currentDay, Status status, RegularPayStatus regularPayStatus); + List findAllByOrderByCreatedAtAsc(); + + Long countByUserIdAndRegularPayStatusNot(Long userId, RegularPayStatus regularPayStatus); + interface RegularPaymentFlame { Long getRegularPayId(); diff --git a/Match-Domain/src/main/java/com/example/matchdomain/event/adaptor/EventAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/event/adaptor/EventAdaptor.java index 42b54cff..c993e77d 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/event/adaptor/EventAdaptor.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/event/adaptor/EventAdaptor.java @@ -24,4 +24,12 @@ public Page findEvent(int page, int size) { public Event findByEvent(Long eventId) { return eventRepository.findById(eventId).orElseThrow(() -> new BadRequestException(NOT_EXIST_EVENT)); } + + public Event save(Event event) { + return eventRepository.save(event); + } + + public void deleteByEventId(Long eventId) { + eventRepository.deleteById(eventId); + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/event/adaptor/EventContentAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/event/adaptor/EventContentAdaptor.java new file mode 100644 index 00000000..f7352812 --- /dev/null +++ b/Match-Domain/src/main/java/com/example/matchdomain/event/adaptor/EventContentAdaptor.java @@ -0,0 +1,20 @@ +package com.example.matchdomain.event.adaptor; + +import com.example.matchcommon.annotation.Adaptor; +import com.example.matchdomain.event.entity.EventContent; +import com.example.matchdomain.event.repository.EventContentRepository; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@Adaptor +@RequiredArgsConstructor +public class EventContentAdaptor { + private final EventContentRepository contentRepository; + + + public void saveAll(List eventContents) { + contentRepository.saveAll(eventContents); + } + +} diff --git a/Match-Domain/src/main/java/com/example/matchdomain/event/entity/Event.java b/Match-Domain/src/main/java/com/example/matchdomain/event/entity/Event.java index b75cb555..96f8ffc7 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/event/entity/Event.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/event/entity/Event.java @@ -29,7 +29,7 @@ public class Event extends BaseEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) @JoinColumn(name = "eventId") @BatchSize(size = 20) private List eventContents = new ArrayList<>(); diff --git a/Match-Domain/src/main/java/com/example/matchdomain/notice/adaptor/NoticeAdapter.java b/Match-Domain/src/main/java/com/example/matchdomain/notice/adaptor/NoticeAdapter.java index c43b61c6..fdffb469 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/notice/adaptor/NoticeAdapter.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/notice/adaptor/NoticeAdapter.java @@ -24,4 +24,12 @@ public Page getNoticeList(int page, int size) { public Notice findNoticeDetail(Long noticeId) { return noticeRepository.findById(noticeId).orElseThrow(() -> new BadRequestException(NOT_EXIST_NOTICE)); } + + public Notice save(Notice notice) { + return noticeRepository.save(notice); + } + + public void delete(Notice notice) { + noticeRepository.deleteById(notice.getId()); + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/notice/adaptor/NoticeContentAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/notice/adaptor/NoticeContentAdaptor.java new file mode 100644 index 00000000..53580232 --- /dev/null +++ b/Match-Domain/src/main/java/com/example/matchdomain/notice/adaptor/NoticeContentAdaptor.java @@ -0,0 +1,18 @@ +package com.example.matchdomain.notice.adaptor; + +import com.example.matchcommon.annotation.Adaptor; +import com.example.matchdomain.notice.entity.NoticeContent; +import com.example.matchdomain.notice.repository.NoticeContentRepository; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@Adaptor +@RequiredArgsConstructor +public class NoticeContentAdaptor { + private final NoticeContentRepository contentRepository; + + public void saveAll(List noticeContents) { + contentRepository.saveAll(noticeContents); + } +} diff --git a/Match-Domain/src/main/java/com/example/matchdomain/notice/entity/Notice.java b/Match-Domain/src/main/java/com/example/matchdomain/notice/entity/Notice.java index 93e69d0e..3af2d3b8 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/notice/entity/Notice.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/notice/entity/Notice.java @@ -27,7 +27,7 @@ public class Notice extends BaseEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) @JoinColumn(name = "noticeId") @BatchSize(size = 20) private List noticeContents = new ArrayList<>(); diff --git a/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/AttentionAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/AttentionAdaptor.java index 1abb2459..64d6d8ed 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/AttentionAdaptor.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/AttentionAdaptor.java @@ -1,6 +1,7 @@ package com.example.matchdomain.project.adaptor; import com.example.matchcommon.annotation.Adaptor; +import com.example.matchdomain.project.entity.ProjectUserAttention; import com.example.matchdomain.project.repository.ProjectUserAttentionRepository; import com.example.matchdomain.user.entity.User; import lombok.RequiredArgsConstructor; @@ -13,4 +14,20 @@ public class AttentionAdaptor { public void deleteByUser(User user) { projectUserAttentionRepository.deleteById_userId(user.getId()); } + + public Long getAttentionCnt(Long userId) { + return projectUserAttentionRepository.countById_userId(userId); + } + + public boolean existsAttention(Long userId, Long projectId) { + return projectUserAttentionRepository.existsById_userIdAndId_projectId(userId, projectId); + } + + public void deleteProjectLike(Long userId, Long projectId) { + projectUserAttentionRepository.deleteById_userIdAndId_projectId(userId, projectId); + } + + public void save(ProjectUserAttention projectUserAttention) { + projectUserAttentionRepository.save(projectUserAttention); + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/CommentReportAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/CommentReportAdaptor.java new file mode 100644 index 00000000..e99111f0 --- /dev/null +++ b/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/CommentReportAdaptor.java @@ -0,0 +1,16 @@ +package com.example.matchdomain.project.adaptor; + +import com.example.matchcommon.annotation.Adaptor; +import com.example.matchdomain.project.entity.CommentReport; +import com.example.matchdomain.project.repository.CommentReportRepository; +import lombok.RequiredArgsConstructor; + +@Adaptor +@RequiredArgsConstructor +public class CommentReportAdaptor { + private final CommentReportRepository commentReportRepository; + + public CommentReport save(CommentReport commentReport) { + return commentReportRepository.save(commentReport); + } +} diff --git a/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectAdaptor.java index a763314e..28e17c63 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectAdaptor.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectAdaptor.java @@ -144,4 +144,16 @@ public Page findAll(int page, int size) { public List getRandom3Project() { return projectRepository.findRandomThreeProject(LocalDateTime.now()); } + + public Project save(Project project) { + return projectRepository.save(project); + } + + public ProjectRepository.ProjectDetail getProjectAppDetail(Long id, Long projectId) { + return projectRepository.getProjectAppDetail(id, projectId); + } + + public Page getProjectAdminList(Pageable pageable) { + return projectRepository.getProjectAdminList(pageable); + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectCommentAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectCommentAdaptor.java index c9646f90..9caf6f49 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectCommentAdaptor.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectCommentAdaptor.java @@ -1,9 +1,17 @@ package com.example.matchdomain.project.adaptor; import com.example.matchcommon.annotation.Adaptor; +import com.example.matchcommon.exception.NotFoundException; +import com.example.matchdomain.project.entity.ProjectComment; import com.example.matchdomain.project.repository.ProjectCommentRepository; import com.example.matchdomain.user.entity.User; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; + +import static com.example.matchdomain.common.model.Status.ACTIVE; +import static com.example.matchdomain.project.exception.CommentGetErrorCode.COMMENT_NOT_EXIST; @Adaptor @RequiredArgsConstructor @@ -13,4 +21,18 @@ public class ProjectCommentAdaptor { public void deleteByUser(User user) { projectCommentRepository.deleteByUserId(user.getId()); } + + public ProjectComment save(ProjectComment projectComment) { + return projectCommentRepository.save(projectComment); + } + + public ProjectComment findById(Long commentId) { + return projectCommentRepository.findByIdAndStatus(commentId, ACTIVE).orElseThrow(()-> new NotFoundException(COMMENT_NOT_EXIST)); + } + + public Page getProjectComment(User user, Long projectId, int page, int size) { + Pageable pageable = PageRequest.of(page, size); + + return projectCommentRepository.findByProjectIdAndStatusOrderByCreatedAtAsc(projectId, ACTIVE, pageable); + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectImgAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectImgAdaptor.java index 891aa1d1..68459fdb 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectImgAdaptor.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/project/adaptor/ProjectImgAdaptor.java @@ -29,4 +29,12 @@ public List findProjectImages(Long projectId) { public ProjectImage findById(Long projectImgId) { return projectImageRepository.findById(projectImgId).orElseThrow(()-> new BadRequestException(PROJECT_IMAGE_NOT_EXIST)); } + + public void saveAll(List projectImages) { + projectImageRepository.saveAll(projectImages); + } + + public ProjectImage save(ProjectImage projectImage) { + return projectImageRepository.save(projectImage); + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/user/adaptor/UserAdaptor.java b/Match-Domain/src/main/java/com/example/matchdomain/user/adaptor/UserAdaptor.java index 0bdc2f22..9fa53ebf 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/user/adaptor/UserAdaptor.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/user/adaptor/UserAdaptor.java @@ -9,15 +9,25 @@ import com.example.matchdomain.user.exception.UserAuthErrorCode; import com.example.matchdomain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.temporal.TemporalAdjusters; import java.util.List; import java.util.Optional; +import static com.example.matchcommon.constants.MatchStatic.FIRST_TIME; +import static com.example.matchcommon.constants.MatchStatic.LAST_TIME; import static com.example.matchdomain.user.entity.enums.Alarm.ACTIVE; import static com.example.matchdomain.user.entity.enums.SocialType.APPLE; import static com.example.matchdomain.user.entity.enums.SocialType.NORMAL; import static com.example.matchdomain.user.exception.UserLoginErrorCode.NOT_EXIST_USER; +import javax.transaction.Transactional; + @Adaptor @RequiredArgsConstructor public class UserAdaptor { @@ -69,4 +79,49 @@ public boolean existsEmailAndSocial(String email, SocialType socialType){ public User findByUsernameAndStatus(String username){ return userRepository.findByUsernameAndStatus(username, Status.ACTIVE).orElseThrow(() -> new UnauthorizedException(UserAuthErrorCode.NOT_EXIST_USER)); } + + public Long getTotalUserCnt(){ + return userRepository.countBy(); + } + + public Long getOneDayUserCnt(LocalDate localDate){ + return userRepository.countByCreatedAtGreaterThanAndCreatedAtLessThan(LocalDateTime.parse(localDate+FIRST_TIME), LocalDateTime.parse(localDate+LAST_TIME)); + } + + public Long getWeekUserCnt(LocalDate localDate) { + return userRepository.countByCreatedAtGreaterThanAndCreatedAtLessThan(LocalDateTime.parse(localDate.minusWeeks(1)+FIRST_TIME) , LocalDateTime.parse(localDate+LAST_TIME)); + } + + public Long getMonthUserCnt(LocalDate localDate) { + return userRepository.countByCreatedAtGreaterThanAndCreatedAtLessThan(LocalDateTime.parse(localDate.with(TemporalAdjusters.firstDayOfMonth())+FIRST_TIME), LocalDateTime.parse(localDate.with(TemporalAdjusters.lastDayOfMonth())+LAST_TIME)); + } + + public Page getUserList(int page, int size, Status status, String content) { + Pageable pageable = PageRequest.of(page, size); + + Page userList = null; + + if(status == null && content ==null) { + userList = userRepository.getUserList(pageable); + } + else if (status !=null && content ==null){ + userList = userRepository.getUserListByStatus(pageable, status.getValue()); + } + else if(status!=null){ + userList = userRepository.getUserListByStatusAndName(pageable, status.getValue(),content); + } + else{ + userList = userRepository.getUserListByName(pageable, content); + } + + return userList; + } + + public UserRepository.UserList getUserDetail(Long userId) { + return userRepository.getUserDetail(userId); + } + + public Long getDeleteUserCnt() { + return userRepository.countByStatus(Status.INACTIVE); + } } diff --git a/Match-Domain/src/main/java/com/example/matchdomain/user/repository/UserRepository.java b/Match-Domain/src/main/java/com/example/matchdomain/user/repository/UserRepository.java index 74e7456b..7b7b4d4e 100644 --- a/Match-Domain/src/main/java/com/example/matchdomain/user/repository/UserRepository.java +++ b/Match-Domain/src/main/java/com/example/matchdomain/user/repository/UserRepository.java @@ -73,7 +73,7 @@ public interface UserRepository extends JpaRepository { "FROM User U where name LIKE concat('%',:content,'%') order by createdAt desc" ,nativeQuery = true, countQuery = "select count(*) from User where name LIKE concat('%',:content,'%')") Page getUserListByName(Pageable pageable,@Param("content") String content); - @Query(value = "SELECT U.id 'userId', name, birth, socialType, gender, phoneNumber,email," + + @Query(value = "SELECT U.id 'userId', name, birth, socialType, gender, phoneNumber,email, nickname," + "If((select exists (select * from UserCard UC where UC.userId=U.id)),'true','false')'card'," + "(select count(*) from DonationUser DU where DU.userId = U.id)'donationCnt'," + "COALESCE((SELECT SUM(DU.price) FROM DonationUser DU WHERE DU.userId = U.id), 0) AS totalAmount,U.status, U.createdAt " + @@ -102,6 +102,8 @@ public interface UserRepository extends JpaRepository { boolean existsByEmailAndSocialTypeNotAndStatus(String email, SocialType socialType, Status status); + Long countByStatus(Status status); + public interface UserList { Long getUserId(); String getName(); @@ -120,6 +122,8 @@ public interface UserList { Status getStatus(); + String getNickname(); + LocalDateTime getCreatedAt(); } } diff --git a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/config/s3/S3UploadService.java b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/config/s3/S3UploadService.java index b8894263..3092ad71 100644 --- a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/config/s3/S3UploadService.java +++ b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/config/s3/S3UploadService.java @@ -142,7 +142,6 @@ public String uploadProjectPresentFile(Long projectId,MultipartFile presentFile) public void deleteFile(String fileName){ int index=fileName.indexOf(awsS3Properties.getS3().getBaseUrl()); String fileRoute=fileName.substring(index+awsS3Properties.getS3().getBaseUrl().length()+1); - System.out.println("deletefilename : "+fileRoute); try { boolean isObjectExist = amazonS3.doesObjectExist(awsS3Properties.getS3().getBucket(), fileRoute); if (isObjectExist) { diff --git a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/dto/PortOneBillPayResponse.java b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/dto/PortOneBillPayResponse.java index 59325039..6892146e 100644 --- a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/dto/PortOneBillPayResponse.java +++ b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/dto/PortOneBillPayResponse.java @@ -4,6 +4,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; +import lombok.ToString; import java.util.List; @@ -11,6 +12,7 @@ @Setter @AllArgsConstructor @RequiredArgsConstructor +@ToString public class PortOneBillPayResponse { private String imp_uid; private String merchant_uid; diff --git a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/dto/PortOneResponse.java b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/dto/PortOneResponse.java index 73a9a465..1ca65fb1 100644 --- a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/dto/PortOneResponse.java +++ b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/dto/PortOneResponse.java @@ -4,10 +4,12 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.ToString; @Getter @AllArgsConstructor @NoArgsConstructor +@ToString public class PortOneResponse { @SerializedName("code") int code; diff --git a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/service/PortOneAuthService.java b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/service/PortOneAuthService.java index 223229ac..53f6ed22 100644 --- a/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/service/PortOneAuthService.java +++ b/Match-Infrastructure/src/main/java/com/example/matchinfrastructure/pay/portone/service/PortOneAuthService.java @@ -7,45 +7,59 @@ import com.example.matchinfrastructure.pay.portone.client.PortOneFeignClient; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; +import java.time.Duration; + @Service @Slf4j @RequiredArgsConstructor public class PortOneAuthService { private final PortOneFeignClient portOneFeignClient; private final PortOneProperties portOneProperties; + private final StringRedisTemplate stringRedisTemplate; - @Cacheable(value = "portOneTokenCache", key = "'all'") - public String getToken() { - String token = fetchPortOneToken(); - log.info("request : " + token); - return token; - } - public String fetchPortOneToken() { + public String getToken(String profile) { log.info("request token"); - return getTokens(); + String cachedToken = stringRedisTemplate.opsForValue().get("portOneTokenCache::" + profile); + if (cachedToken != null) { + return cachedToken; + } + + return requestNewToken(profile); } - @CachePut(value = "portOneTokenCache", key = "'all'") - public String getTokens() { - PortOneResponse portOneResponse = portOneFeignClient.getAccessToken(PortOneAuthReq.builder().imp_key(portOneProperties.getKey()).imp_secret(portOneProperties.getSecret()).build()); + public String requestNewToken(String profile) { + PortOneResponse portOneResponse = getPortOneToken(); + + long ttl = portOneResponse.getResponse().getExpired_at()-portOneResponse.getResponse().getNow(); + + log.info("token ttl : " + ttl); + + String newToken = portOneResponse.getResponse().getAccess_token(); + + stringRedisTemplate.opsForValue().set("portOneTokenCache::" + profile, newToken, Duration.ofSeconds(ttl)); + return portOneResponse.getResponse().getAccess_token(); } + public String getAuthToken() { - PortOneResponse portOneResponse = portOneFeignClient.getAccessToken(PortOneAuthReq.builder().imp_key(portOneProperties.getKey()).imp_secret(portOneProperties.getSecret()).build()); - return portOneResponse.getResponse().getAccess_token(); + return getPortOneToken().getResponse().getAccess_token(); } - @Scheduled(fixedRate = 1200000) - public void refreshAuthToken() { - String refreshToken = getTokens(); - log.info("refresh token {} ", refreshToken); + + private PortOneResponse getPortOneToken() { + return portOneFeignClient.getAccessToken(PortOneAuthReq.builder().imp_key(portOneProperties.getKey()).imp_secret(portOneProperties.getSecret()).build()); } + }