From adcebc10c95237e9b51d0b12330ad7a7aa87892a Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 18:00:20 +0900 Subject: [PATCH 01/15] epic: latest comment get add and hot board list fix --- .../repository/BoardQueryRepository.java | 29 ++++ .../comment/controller/CommentController.java | 19 +++ .../comment/dto/response/CommentResponse.java | 11 ++ .../repository/CommentQueryRepository.java | 16 +++ .../comment/service/CommentReadService.java | 7 + .../util/redis/service/RedisService.java | 35 ++++- .../recommend/BoardRecommendHandler.java | 4 + .../server/redis/GetHotBoardZsetTest.java | 129 ++++++++++++++++++ .../server/support/TestDriverSupport.java | 39 ++++++ 9 files changed, 287 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java diff --git a/src/main/java/org/myteam/server/board/repository/BoardQueryRepository.java b/src/main/java/org/myteam/server/board/repository/BoardQueryRepository.java index 7a010bf3..5d2e7b60 100644 --- a/src/main/java/org/myteam/server/board/repository/BoardQueryRepository.java +++ b/src/main/java/org/myteam/server/board/repository/BoardQueryRepository.java @@ -40,6 +40,7 @@ import org.myteam.server.global.util.redis.CommonCountDto; import org.myteam.server.global.util.redis.ServiceType; import org.myteam.server.global.util.redis.service.RedisCountService; +import org.myteam.server.global.util.redis.service.RedisService; import org.myteam.server.home.dto.HotBoardDto; import org.myteam.server.home.dto.NewBoardDto; import org.myteam.server.report.domain.DomainType; @@ -57,6 +58,7 @@ public class BoardQueryRepository { private final JPAQueryFactory queryFactory; private final RedisBoardRankingReader rankingReader; private final RedisCountService redisCountService; + private final RedisService redisService; /** * 게시글 목록 조회 @@ -488,6 +490,33 @@ public List getHotBoardList() { return hotBoardList; } + public List zSetGetHotBoardList(){ + List boardId=redisService.getBoardRecommendRankPerDay(); + List hotBoardList = queryFactory + .select(Projections.fields(HotBoardDto.class, + board.boardType, + board.categoryType, + board.id, + board.title, + board.id.in(boardId).as("isHot"), + board.id.in(getNewBoardIdList()).as("isNew"), + new CaseBuilder() + .when(board.thumbnail.isNotEmpty()).then(true) + .otherwise(false) + .as("isImage") + )) + .from(board) + .where(board.id.in(boardId)) + .fetch(); + Map orderMap = IntStream.range(0, boardId.size()) + .boxed() + .collect(Collectors.toMap(boardId::get, i -> i)); + hotBoardList.sort(Comparator.comparingInt(dto -> orderMap.getOrDefault(dto.getId(), Integer.MAX_VALUE))); + // 순위 부여 + AtomicInteger rankCounter = new AtomicInteger(1); + hotBoardList.forEach(dto -> dto.setRank(rankCounter.getAndIncrement())); + return hotBoardList; + } public Long findPreviousBoardId(Long boardId, Category boardType, CategoryType categoryType) { return queryFactory diff --git a/src/main/java/org/myteam/server/comment/controller/CommentController.java b/src/main/java/org/myteam/server/comment/controller/CommentController.java index b63c9ae8..edca3477 100644 --- a/src/main/java/org/myteam/server/comment/controller/CommentController.java +++ b/src/main/java/org/myteam/server/comment/controller/CommentController.java @@ -1,5 +1,6 @@ package org.myteam.server.comment.controller; +import static org.myteam.server.comment.dto.response.CommentResponse.*; import static org.myteam.server.global.web.response.ResponseStatus.SUCCESS; import io.swagger.v3.oas.annotations.Operation; @@ -14,6 +15,7 @@ import org.myteam.server.comment.dto.request.CommentRequest.CommentDeleteRequest; import org.myteam.server.comment.dto.request.CommentRequest.CommentListRequest; import org.myteam.server.comment.dto.request.CommentRequest.CommentSaveRequest; +import org.myteam.server.comment.dto.response.CommentResponse; import org.myteam.server.comment.dto.response.CommentResponse.BestCommentSaveListResponse; import org.myteam.server.comment.dto.response.CommentResponse.CommentSaveListResponse; import org.myteam.server.comment.dto.response.CommentResponse.CommentSaveResponse; @@ -33,6 +35,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + @RestController @RequestMapping("/api/comments") @RequiredArgsConstructor @@ -169,4 +173,19 @@ public ResponseEntity> getBestComments( bestComments )); } + @Operation(summary = "최신 댓글 조회", description = "최신 댓글들을 조회합니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "최신 댓글 목록 조회 성공"), + @ApiResponse(responseCode = "404", description = "게시글이 존재하지 않음", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + @GetMapping("/latest") + public ResponseEntity>> getLatestComments() { + List + latestCommentListResponse=commentReadService.getLatestComments(); + return ResponseEntity.ok(new ResponseDto<>( + SUCCESS.name(), + "베스트 댓글 목록 조회 성공", + latestCommentListResponse + )); + } } diff --git a/src/main/java/org/myteam/server/comment/dto/response/CommentResponse.java b/src/main/java/org/myteam/server/comment/dto/response/CommentResponse.java index d2cad2b4..1e11bff2 100644 --- a/src/main/java/org/myteam/server/comment/dto/response/CommentResponse.java +++ b/src/main/java/org/myteam/server/comment/dto/response/CommentResponse.java @@ -3,6 +3,8 @@ import java.time.LocalDateTime; import java.util.List; import java.util.UUID; + +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -10,6 +12,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import org.myteam.server.comment.domain.Comment; +import org.myteam.server.comment.domain.CommentType; import org.myteam.server.global.page.response.PageCustomResponse; import org.myteam.server.util.ClientUtils; @@ -122,4 +125,12 @@ public static BestCommentSaveListResponse createResponse( .build(); } } + + @AllArgsConstructor + public static class LatestCommentListResponse{ + private Long commentId; + @Schema(description = "최신댓글이 어떤 게시글에 대한 댓글인지를 보여줍니다.") + private CommentType commentType; + private String content; + } } diff --git a/src/main/java/org/myteam/server/comment/repository/CommentQueryRepository.java b/src/main/java/org/myteam/server/comment/repository/CommentQueryRepository.java index 7338139f..11acb314 100644 --- a/src/main/java/org/myteam/server/comment/repository/CommentQueryRepository.java +++ b/src/main/java/org/myteam/server/comment/repository/CommentQueryRepository.java @@ -9,6 +9,7 @@ import static org.myteam.server.comment.domain.QInquiryComment.inquiryComment; import static org.myteam.server.comment.domain.QNewsComment.newsComment; import static org.myteam.server.comment.domain.QNoticeComment.noticeComment; +import static org.myteam.server.comment.dto.response.CommentResponse.*; import static org.myteam.server.improvement.domain.QImprovement.improvement; import static org.myteam.server.inquiry.domain.QInquiry.inquiry; import static org.myteam.server.member.entity.QMember.member; @@ -45,6 +46,7 @@ import org.myteam.server.comment.domain.QMatchComment; import org.myteam.server.comment.domain.QNewsComment; import org.myteam.server.comment.domain.QNoticeComment; +import org.myteam.server.comment.dto.response.CommentResponse; import org.myteam.server.comment.dto.response.CommentResponse.BestCommentResponse; import org.myteam.server.comment.dto.response.CommentResponse.CommentSaveResponse; import org.myteam.server.comment.service.CommentRecommendReadService; @@ -69,6 +71,20 @@ public class CommentQueryRepository { private final CommentRepository commentRepository; private final CommentRecommendReadService commentRecommendReadService; + public List getNewestComment(){ + List comments=queryFactory + .select(Projections.constructor(LatestCommentListResponse.class, + comment1.id, + comment1.commentType, + comment1.comment.substring(0,20))) + .from(comment1) + .orderBy(comment1.createDate.desc()) + .limit(10) + .fetch(); + + return comments; + } + /** * 대댓글 목록 조회 */ diff --git a/src/main/java/org/myteam/server/comment/service/CommentReadService.java b/src/main/java/org/myteam/server/comment/service/CommentReadService.java index 04a6b3d0..b279e042 100644 --- a/src/main/java/org/myteam/server/comment/service/CommentReadService.java +++ b/src/main/java/org/myteam/server/comment/service/CommentReadService.java @@ -1,11 +1,13 @@ package org.myteam.server.comment.service; +import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.myteam.server.comment.domain.Comment; import org.myteam.server.comment.domain.CommentType; import org.myteam.server.comment.dto.request.CommentRequest.CommentListRequest; +import org.myteam.server.comment.dto.response.CommentResponse; import org.myteam.server.comment.dto.response.CommentResponse.BestCommentResponse; import org.myteam.server.comment.dto.response.CommentResponse.BestCommentSaveListResponse; import org.myteam.server.comment.dto.response.CommentResponse.CommentSaveListResponse; @@ -25,6 +27,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import static org.myteam.server.comment.dto.response.CommentResponse.*; + @Slf4j @Service @RequiredArgsConstructor @@ -36,6 +40,9 @@ public class CommentReadService { private final SecurityReadService securityReadService; private final CommentRecommendReadService commentRecommendReadService; + public List getLatestComments(){ + return commentQueryRepository.getNewestComment(); + } public Comment findById(Long commentId) { return commentRepository.findById(commentId) .orElseThrow(() -> new PlayHiveException(ErrorCode.COMMENT_NOT_FOUND)); diff --git a/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java b/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java index 3c63487c..b67a15b4 100644 --- a/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java +++ b/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java @@ -1,10 +1,18 @@ package org.myteam.server.global.util.redis.service; +import java.sql.Date; import java.time.Duration; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.util.Collections; +import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; import org.myteam.server.admin.utill.StaticDataType; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; @@ -16,7 +24,7 @@ public class RedisService { // TODO: RedisReportService 로 변경. private final RedisTemplate redisTemplate; - + private static final String BOARD_RANK_KEY=":BoardRank"; private static final int ADMIN_LOGIN_MAX_REQUESTS=10; private static final int MAX_REQUESTS = 3; // 제한 횟수 (기본값: 5분 동안 3회) private static final long EXPIRED_TIME = 5L; // 만료 시간 (5분) @@ -96,7 +104,30 @@ public void adminReadCheckUpdate(String category, String adminIdentifier, Static redisTemplate.expire(redisKey, Duration.ofMinutes(ADMIN_ALARM_READ_EXPIRE_TIME)); } } - + public void boardRecommendRankPerDay(Long contentId,Long delta){ + LocalDateTime now = LocalDateTime.now().with(LocalTime.MIDNIGHT); + String key = now.toLocalDate().toString() +BOARD_RANK_KEY; + LocalDateTime nextMidnight = now.plusDays(1).with(LocalTime.MIDNIGHT); + redisTemplate.opsForZSet().incrementScore(key,contentId.toString(),delta); + redisTemplate.expireAt(key,Date.valueOf(nextMidnight.toLocalDate())); + } + public List getBoardRecommendRankPerDay(){ + LocalDateTime now=LocalDateTime.now().with(LocalTime.MIDNIGHT); + String key=now+BOARD_RANK_KEY; + List ids=redisTemplate.opsForZSet().reverseRange(key,0,9) + .stream() + .filter(x->{ + if(Long.parseLong(x)>0){ + return true; + } + return false; + }) + .map(x->{ + return Long.parseLong(x); + }) + .collect(Collectors.toList()); + return ids; + } /** * 요청 제한을 적용할 Redis Key 생성 diff --git a/src/main/java/org/myteam/server/recommend/BoardRecommendHandler.java b/src/main/java/org/myteam/server/recommend/BoardRecommendHandler.java index ea4d7537..93073693 100644 --- a/src/main/java/org/myteam/server/recommend/BoardRecommendHandler.java +++ b/src/main/java/org/myteam/server/recommend/BoardRecommendHandler.java @@ -9,6 +9,7 @@ import org.myteam.server.board.service.BoardRecommendReadService; import org.myteam.server.global.exception.ErrorCode; import org.myteam.server.global.exception.PlayHiveException; +import org.myteam.server.global.util.redis.service.RedisService; import org.myteam.server.member.entity.Member; import org.myteam.server.report.domain.DomainType; import org.springframework.stereotype.Component; @@ -20,6 +21,7 @@ public class BoardRecommendHandler implements RecommendHandler { private final BoardRecommendReadService boardRecommendReadService; private final BoardRecommendRepository boardRecommendRepository; private final BoardRepository boardRepository; + private final RedisService redisService; @Override public boolean supports(DomainType type) { @@ -39,10 +41,12 @@ public void saveRecommendation(Long contentId, Member member) { .orElseThrow(() -> new PlayHiveException(ErrorCode.BOARD_NOT_FOUND)); BoardRecommend recommend = BoardRecommend.builder().board(board).member(member).build(); boardRecommendRepository.save(recommend); + redisService.boardRecommendRankPerDay(contentId,1L); } @Override public void deleteRecommendation(Long contentId, UUID userId) { boardRecommendRepository.deleteByBoardIdAndMemberPublicId(contentId, userId); + redisService.boardRecommendRankPerDay(contentId,-1L); } } diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java new file mode 100644 index 00000000..fc484916 --- /dev/null +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -0,0 +1,129 @@ +package org.myteam.server.redis; + + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.myteam.server.board.domain.Board; +import org.myteam.server.board.domain.CategoryType; +import org.myteam.server.global.domain.Category; +import org.myteam.server.global.security.dto.CustomUserDetails; +import org.myteam.server.global.util.redis.RedisCountBulkUpdater; +import org.myteam.server.global.util.redis.ServiceType; +import org.myteam.server.global.util.redis.service.RedisCountService; +import org.myteam.server.global.util.redis.service.RedisService; +import org.myteam.server.member.domain.MemberRole; +import org.myteam.server.member.domain.MemberStatus; +import org.myteam.server.member.domain.MemberType; +import org.myteam.server.member.entity.Member; +import org.myteam.server.member.entity.MemberActivity; +import org.myteam.server.member.repository.MemberJpaRepository; +import org.myteam.server.recommend.RecommendActionType; +import org.myteam.server.recommend.RecommendService; +import org.myteam.server.report.domain.DomainType; +import org.myteam.server.support.TestContainerSupport; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.test.context.ActiveProfiles; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.assertj.core.api.Assertions.*; + +@SpringBootTest +@ActiveProfiles("test") +public class GetHotBoardZsetTest extends TestContainerSupport { + + + @Autowired + RedisService redisService; + + @Autowired + RedisCountService redisCountService; + + private List memberList; + private List boardList; + + + @BeforeEach + void setting(){ + for(int i=0;10>i;i++){ + Member m=createMember(i); + memberList.add(m); + + } + for(int i=0;10>i;i++){ + Board board=createBoard(memberList.get(i), Category.BASEBALL, CategoryType.FREE,"제목", + "내용"); + boardList.add(board); + } + } + @Test + @DisplayName("여러 사용자가 순위를 매기고 정합성이 잘지켜지는지 그리고 순위가 양수인 데이터만 잘가져오는지.") + void recommendZsetTest() throws ExecutionException, InterruptedException { + int threadCount = 10; + ExecutorService executorService = Executors.newFixedThreadPool(5); + CountDownLatch countDownLatch = new CountDownLatch(threadCount); + + List members = new ArrayList<>(); + for (int i = 0; i < threadCount; i++) { + Member newMember = Member.builder() + .email("user" + i + "@test.com") + .password("1234") + .tel("010123456" + i) + .nickname("user" + i) + .role(MemberRole.USER) + .type(MemberType.LOCAL) + .publicId(UUID.randomUUID()) + .status(MemberStatus.ACTIVE) + .build(); + memberJpaRepository.save(newMember); + memberActivityRepository.save(new MemberActivity(newMember)); + members.add(newMember); + } + + for (Member m: members) { + executorService.execute(() -> { + SecurityContext context = SecurityContextHolder.createEmptyContext(); + context.setAuthentication(new UsernamePasswordAuthenticationToken( + new CustomUserDetails(m), + null, + List.of(new SimpleGrantedAuthority("ROLE_USER")) + )); + SecurityContextHolder.setContext(context); + try { + boardList.stream().forEach(x->{ + if(x.getId()%2==0) { + redisCountService.getCommonCount(ServiceType.RECOMMEND, + DomainType.BOARD, x.getId(), null); + } + else{ + redisCountService.getCommonCount(ServiceType.RECOMMEND_CANCEL, + DomainType.BOARD, x.getId(), null); + } + }); + } finally { + countDownLatch.countDown(); + } + }); + } + countDownLatch.await(); + List ids=redisService.getBoardRecommendRankPerDay(); + assertThat(ids.size()).isEqualTo(5); + ids.stream().forEach(x->{ + assertThat(x%2).isEqualTo(0); + }); + } + +} diff --git a/src/test/java/org/myteam/server/support/TestDriverSupport.java b/src/test/java/org/myteam/server/support/TestDriverSupport.java index fdd23074..1e2102f3 100644 --- a/src/test/java/org/myteam/server/support/TestDriverSupport.java +++ b/src/test/java/org/myteam/server/support/TestDriverSupport.java @@ -38,9 +38,14 @@ import org.myteam.server.match.team.domain.Team; import org.myteam.server.match.team.domain.TeamCategory; import org.myteam.server.match.team.repository.TeamRepository; +import org.myteam.server.member.domain.MemberRole; +import org.myteam.server.member.domain.MemberStatus; +import org.myteam.server.member.domain.MemberType; import org.myteam.server.member.entity.Member; +import org.myteam.server.member.entity.MemberActivity; import org.myteam.server.member.repository.MemberActivityRepository; import org.myteam.server.member.repository.MemberJpaRepository; +import org.myteam.server.member.service.SecurityReadService; import org.myteam.server.news.news.domain.News; import org.myteam.server.news.news.repository.NewsRepository; import org.myteam.server.news.newsCount.domain.NewsCount; @@ -61,9 +66,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.transaction.annotation.Transactional; import software.amazon.awssdk.services.s3.presigner.S3Presigner; import java.time.LocalDateTime; +import java.util.UUID; + +import static org.mockito.BDDMockito.given; @SpringBootTest public abstract class TestDriverSupport { @@ -152,6 +161,9 @@ public abstract class TestDriverSupport { @Autowired protected CommonCountAspect commonCountAspect; + @MockBean + SecurityReadService securityReadService; + @AfterEach void tearDown() { commentRecommendRepository.deleteAllInBatch(); @@ -178,6 +190,33 @@ void tearDown() { memberJpaRepository.deleteAllInBatch(); } + + @Transactional + protected Member createMember(int index) { + Member member = Member.builder() + .email("test" + index + "@test.com") + .password("1234") + .tel("01012345678") + .nickname("test" + index) + .role(MemberRole.USER) + .type(MemberType.LOCAL) + .publicId(UUID.randomUUID()) + .status(MemberStatus.ACTIVE) + .build(); + + MemberActivity memberActivity = new MemberActivity(member); + Member savedMember = memberJpaRepository.save(member); + + given(securityReadService.getMember()) + .willReturn(savedMember); + + given(securityReadService.getAuthenticatedPublicId()) + .willReturn(member.getPublicId()); + + return savedMember; + } + + protected News createNews(int index, Category category, int count) { News savedNews = newsRepository.save(News.builder() .title("기사타이틀" + index) From 2eca796b1c359be3eb8a4866f5d75ceac9036f21 Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 19:47:09 +0900 Subject: [PATCH 02/15] fix: testcode --- .../server/redis/GetHotBoardZsetTest.java | 6 +--- .../server/support/TestDriverSupport.java | 28 +------------------ 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java index fc484916..c67602c4 100644 --- a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -40,6 +40,7 @@ import java.util.concurrent.Executors; import static org.assertj.core.api.Assertions.*; +import static org.mockito.BDDMockito.given; @SpringBootTest @ActiveProfiles("test") @@ -58,11 +59,6 @@ public class GetHotBoardZsetTest extends TestContainerSupport { @BeforeEach void setting(){ - for(int i=0;10>i;i++){ - Member m=createMember(i); - memberList.add(m); - - } for(int i=0;10>i;i++){ Board board=createBoard(memberList.get(i), Category.BASEBALL, CategoryType.FREE,"제목", "내용"); diff --git a/src/test/java/org/myteam/server/support/TestDriverSupport.java b/src/test/java/org/myteam/server/support/TestDriverSupport.java index 1e2102f3..1418fc9e 100644 --- a/src/test/java/org/myteam/server/support/TestDriverSupport.java +++ b/src/test/java/org/myteam/server/support/TestDriverSupport.java @@ -162,7 +162,7 @@ public abstract class TestDriverSupport { protected CommonCountAspect commonCountAspect; @MockBean - SecurityReadService securityReadService; + protected SecurityReadService securityReadService; @AfterEach void tearDown() { @@ -191,32 +191,6 @@ void tearDown() { } - @Transactional - protected Member createMember(int index) { - Member member = Member.builder() - .email("test" + index + "@test.com") - .password("1234") - .tel("01012345678") - .nickname("test" + index) - .role(MemberRole.USER) - .type(MemberType.LOCAL) - .publicId(UUID.randomUUID()) - .status(MemberStatus.ACTIVE) - .build(); - - MemberActivity memberActivity = new MemberActivity(member); - Member savedMember = memberJpaRepository.save(member); - - given(securityReadService.getMember()) - .willReturn(savedMember); - - given(securityReadService.getAuthenticatedPublicId()) - .willReturn(member.getPublicId()); - - return savedMember; - } - - protected News createNews(int index, Category category, int count) { News savedNews = newsRepository.save(News.builder() .title("기사타이틀" + index) From 83eb86713ed95093fa37573e43aee05734a1534c Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 19:56:27 +0900 Subject: [PATCH 03/15] fix: testcode --- .../controller/AdminDashBoardController.java | 33 +- .../dto/request/AdminDashBoardRequestDto.java | 63 --- .../admin/dto/request/ContentRequestDto.java | 8 +- .../admin/dto/request/ImproveRequestDto.java | 7 +- .../admin/dto/request/InquiryRequestDto.java | 6 +- .../response/AdminDashBoardResponseDto.java | 21 +- .../dto/response/InquiryResponseDto.java | 5 +- .../dto/response/MemberSearchResponseDto.java | 3 + .../admin/entity/AdminContentChangeLog.java | 1 + .../server/admin/entity/AdminContentMemo.java | 1 + .../admin/entity/AdminImproveChangeLog.java | 1 + .../admin/entity/AdminInquiryChangeLog.java | 1 + .../admin/entity/AdminMemberChangeLog.java | 1 + .../server/admin/entity/AdminMemberMemo.java | 1 + .../repository/AdminDashBoardRepository.java | 340 ++++++-------- .../repository/AdminMemberRepository.java | 3 +- .../admin/repository/InquirySearchRepo.java | 5 +- .../admin/service/AdminDashBoardService.java | 14 +- .../service/AdminImprovementService.java | 16 +- .../admin/service/AdminInquiryService.java | 16 +- .../admin/service/ContentSearchService.java | 15 +- .../admin/utill/CreateStaticQueryFactory.java | 296 +++++++++++- .../server/admin/utill/StaticDataType.java | 2 + .../myteam/server/admin/utill/StaticUtil.java | 7 +- .../auth/controller/AdminLoginController.java | 29 ++ .../service/InquiryAnsSendService.java | 20 +- .../filter/JwtAuthenticationFilter.java | 11 +- .../global/util/date/DateFormatUtil.java | 3 +- .../util/redis/service/RedisService.java | 23 +- .../member/controller/AdminController.java | 4 +- .../templates/mail/admin-to-user-reply.html | 180 ++++++++ .../server/admin/AdminReadCheckTest.java | 199 ++++++++ .../server/admin/inquriyimprovementtest.java | 40 ++ .../admin/repository/DashBoardRepoTest.java | 423 +++++++----------- 34 files changed, 1162 insertions(+), 636 deletions(-) delete mode 100644 src/main/java/org/myteam/server/admin/dto/request/AdminDashBoardRequestDto.java create mode 100644 src/main/java/org/myteam/server/auth/controller/AdminLoginController.java create mode 100644 src/main/resources/templates/mail/admin-to-user-reply.html create mode 100644 src/test/java/org/myteam/server/admin/AdminReadCheckTest.java diff --git a/src/main/java/org/myteam/server/admin/controller/AdminDashBoardController.java b/src/main/java/org/myteam/server/admin/controller/AdminDashBoardController.java index 76258476..18452c17 100644 --- a/src/main/java/org/myteam/server/admin/controller/AdminDashBoardController.java +++ b/src/main/java/org/myteam/server/admin/controller/AdminDashBoardController.java @@ -1,28 +1,23 @@ package org.myteam.server.admin.controller; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.myteam.server.admin.service.AdminDashBoardService; +import org.myteam.server.admin.utill.DateType; +import org.myteam.server.admin.utill.StaticDataType; import org.myteam.server.global.exception.ErrorResponse; import org.myteam.server.global.web.response.ResponseDto; import org.myteam.server.global.web.response.ResponseStatus; import org.springframework.http.ResponseEntity; -import org.springframework.validation.BindingResult; -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 java.util.List; - -import static org.myteam.server.admin.dto.request.AdminDashBoardRequestDto.RequestLatestData; -import static org.myteam.server.admin.dto.request.AdminDashBoardRequestDto.RequestStatic; +import java.util.Map; import static org.myteam.server.admin.dto.response.AdminDashBoardResponseDto.ResponseLatestData; import static org.myteam.server.admin.dto.response.AdminDashBoardResponseDto.ResponseStatic; @@ -41,12 +36,14 @@ public class AdminDashBoardController { @ApiResponse(responseCode = "200", description = "조회 성공", useReturnTypeSchema = true), @ApiResponse(responseCode = "400", description = "잘못된 요청 형식", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) - @PostMapping("/static") - public ResponseEntity> - getStaticData(@RequestBody @Valid RequestStatic requestStatic, BindingResult bindingResult) { + @GetMapping("/static") + public ResponseEntity>> + getStaticData(@Parameter(description = "통계를 불러올 탭과 일치해서 사용하는 쿼리 스트링입니다.",example = "DashBoard,MemberBoard,ContentBoard,Inquiry,Improvement 중택1") + @RequestParam(name ="staticType",required = true) StaticDataType staticDataType, + @Parameter(description = "쿼리 스트링값입니다.",example ="Day,WeekEnd,OneMonth,ThreeMonth,SixMonth,Year 중택1" )@RequestParam(name="dateType",required = true) DateType dateType) { return ResponseEntity.ok( new ResponseDto<>(ResponseStatus.SUCCESS.name(), "조회 성공", - adminDashBoardService.getStaticData(requestStatic)) + adminDashBoardService.getStaticData(staticDataType,dateType)) ); } @@ -58,13 +55,13 @@ public class AdminDashBoardController { @ApiResponse(responseCode = "400", description = "잘못된 요청 형식", content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) - @PostMapping("/latest") - public ResponseEntity>> - getLatestData(@RequestBody @Valid RequestLatestData requestLatestData, BindingResult bindingResult) { + @GetMapping("/latest") + public ResponseEntity>>> + getLatestData() { return ResponseEntity.ok( new ResponseDto<>(ResponseStatus.SUCCESS.name(), "조회 성공", - adminDashBoardService.getLatestData(requestLatestData))); + adminDashBoardService.getLatestData())); } } diff --git a/src/main/java/org/myteam/server/admin/dto/request/AdminDashBoardRequestDto.java b/src/main/java/org/myteam/server/admin/dto/request/AdminDashBoardRequestDto.java deleted file mode 100644 index ecd1ba23..00000000 --- a/src/main/java/org/myteam/server/admin/dto/request/AdminDashBoardRequestDto.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.myteam.server.admin.dto.request; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.myteam.server.admin.utill.DateType; -import org.myteam.server.admin.utill.StaticDataType; - -public record AdminDashBoardRequestDto() { - - @Getter - @NoArgsConstructor - @Schema(name = "RequestStatic", description = "대시보드 통계 요청") - public static class RequestStatic { - @NotNull(message ="데이터 타입값이 비어있습니다.") - @Schema(description ="데이터 타입입니다.필수입니다.",examples = - "Report, ReportedChat, ReportedComment, ReportedBoard,\n"+ - "BOARD, COMMENT, BoardComment,\n"+ - "Improvement, Inquiry, ImprovementInquiry,\n"+ - "ImprovementPending,ImprovementComplete,ImprovementReceived,\n"+ - "InquiryPending,InquiryComplete,InquiryMember,InquiryNoMember,\n" + - "UserAccess, UserSignIn, UserDeleted, UserWarned, UserBanned,\n"+ - "HideComment, HideBoard") - private StaticDataType staticDataType; - - @NotNull(message = "기간 값이 비어있습니다.") - @Schema(description = "기간 종류, 필수입니다.", examples = "Day,WeekEnd,OneMonth,ThreeMonth,SixMonth,Year" + - "중 택1") - private DateType dateType; - - @Builder - public RequestStatic(StaticDataType staticDataType, DateType dateType) { - this.staticDataType = staticDataType; - this.dateType = dateType; - } - - } - - @Getter - @NoArgsConstructor - @Schema(name = "RequestLatestData", description = "최신 데이터 요청") - public static class RequestLatestData { - @NotNull(message ="데이터 타입값이 비어있습니다.") - @Schema(description ="데이터 타입입니다. 필수입니다.",examples = "Report, ReportedChat, ReportedComment, ReportedBoard,\n"+ - "BOARD, COMMENT, BoardComment,\n"+ - "Improvement, Inquiry, ImprovementInquiry,\n"+ - "ImprovementPending,ImprovementComplete,ImprovementReceived,\n"+ - "InquiryPending,InquiryComplete,InquiryMember,InquiryNoMember,\n" + - "UserAccess, UserSignIn, UserDeleted, UserWarned, UserBanned,\n"+ - "HideComment, HideBoard") - private StaticDataType staticDataType; - - @Builder - public RequestLatestData(StaticDataType staticDataType) { - this.staticDataType = staticDataType; - - } - - } - -} diff --git a/src/main/java/org/myteam/server/admin/dto/request/ContentRequestDto.java b/src/main/java/org/myteam/server/admin/dto/request/ContentRequestDto.java index 3b5078a7..f342d22c 100644 --- a/src/main/java/org/myteam/server/admin/dto/request/ContentRequestDto.java +++ b/src/main/java/org/myteam/server/admin/dto/request/ContentRequestDto.java @@ -78,10 +78,16 @@ public static class RequestDetail { @NotNull(message ="contentid는 비면안됩니다.") @Schema(description = "필수값입니다.") private Long contentId; + @Schema(description = "관리자단 대시보드의 최신데이터 알람에서 신고목록을 클릭해서 넘어올떄만 넣어주세요") + private Long reportId; + @Schema(description = "관리자단 대시보드의 최신데이터 알람에서 넘어올경우에만 넣어주세요") + private String alarmCheck; @Builder - public RequestDetail(StaticDataType staticDataType, Long contentId) { + public RequestDetail(StaticDataType staticDataType, Long contentId,Long reportId,String alarmCheck) { this.staticDataType = staticDataType; this.contentId = contentId; + this.reportId=reportId; + this.alarmCheck=alarmCheck; } } diff --git a/src/main/java/org/myteam/server/admin/dto/request/ImproveRequestDto.java b/src/main/java/org/myteam/server/admin/dto/request/ImproveRequestDto.java index bcf98d48..d3a60416 100644 --- a/src/main/java/org/myteam/server/admin/dto/request/ImproveRequestDto.java +++ b/src/main/java/org/myteam/server/admin/dto/request/ImproveRequestDto.java @@ -80,10 +80,13 @@ public final static class RequestImprovementDetail { @NotNull(message = "contentid는 비면안됩니다.") @Schema(description = "필수값 입니다.") private Long contentId; - + @Schema(description = "관리자단 대시보드의 최신데이터 알림에서 넘어올경우에만 넘겨주시면됩니다." + + "그외엔 null로 주시면됩니다.") + private String alarmCheck; @Builder - public RequestImprovementDetail(Long contentId) { + public RequestImprovementDetail(Long contentId,String alarmCheck) { this.contentId = contentId; + this.alarmCheck=alarmCheck; } } diff --git a/src/main/java/org/myteam/server/admin/dto/request/InquiryRequestDto.java b/src/main/java/org/myteam/server/admin/dto/request/InquiryRequestDto.java index 56767561..c735162b 100644 --- a/src/main/java/org/myteam/server/admin/dto/request/InquiryRequestDto.java +++ b/src/main/java/org/myteam/server/admin/dto/request/InquiryRequestDto.java @@ -98,10 +98,14 @@ public final static class RequestInquiryDetail { @NotNull(message = "contentid 는 비면안됩니다.") @Schema(description = "inquiry id값입니다. 필수입니다.") private Long contentId; + @Schema(description = "관리자단 대시보드의 최신데이터 알림에서 넘어올경우에만 넘겨주시면됩니다." + + "그외엔 null로 주시면됩니다.") + private String alarmCheck; @Builder - public RequestInquiryDetail(Long id) { + public RequestInquiryDetail(Long id,String alarmCheck) { this.contentId = id; + this.alarmCheck=alarmCheck; } } diff --git a/src/main/java/org/myteam/server/admin/dto/response/AdminDashBoardResponseDto.java b/src/main/java/org/myteam/server/admin/dto/response/AdminDashBoardResponseDto.java index ebab76e5..ff1c14ac 100644 --- a/src/main/java/org/myteam/server/admin/dto/response/AdminDashBoardResponseDto.java +++ b/src/main/java/org/myteam/server/admin/dto/response/AdminDashBoardResponseDto.java @@ -15,19 +15,22 @@ public static class ResponseStatic { @Schema(description = "기간에 따른 데이터의 양을 보여줍니다.", example = "{2025.02.06 : 1}") private Map currentStaticData; + @Schema(description = "기간에 따른 데이터의 양을 보여줍니다.", + example = "{2025.02.06 : 1}") + private Map pastStaticData; private Long currentCount; private Long pastCount; private Long totCount; @Schema(examples = "-100,100") private int percent; + private String staticDataName; } @Getter public static class ResponseLatestData { - @Schema(description = "불러온 데이터 타입이 신고일때 어떤 콘텐츠에대한 신고인지를 나타냅니다.") + @Schema(description = "불러온 최신 데이터 타입이 신고일때 어떤 콘텐츠에대한 신고인지를 나타냅니다.") private String reportType; - private StaticDataType staticDataType; @Schema(description = "최신 데이터를 관리자단의 우측 하단에서 표시할때 가장 왼쪽에오는 상태값입니다.") private String mainStatus; @Schema(description = "최신 데이터를 관리자단의 우측 하단에서 표시할때 왼쪽에서 두번째에 해당하는 상태값입니다.") @@ -37,20 +40,26 @@ public static class ResponseLatestData { private String content; @Schema(example = "2025.06.06") private String createAt; + @Schema(description = "어떤 종류의 최신데이터인지 보여줍니다") + private StaticDataType staticDataType; @Schema(description = "이값이 true이면 이미 읽은것,아니면은 읽지않은것입니다.") - private boolean checkRead; + private Boolean checkRead; + @Schema(description = "신고 관련 최신 리스트일떄 참조하는 값으로 다른 관련 최신 리스트라면 무시해주세요") + private Long reportId; - public ResponseLatestData(String reportType, StaticDataType staticDataType, + public ResponseLatestData(String reportType, String mainStatus, String subStatus, Long contentId, - String name, String content, String createAt) { + String name, String content, String createAt,Long reportId + ,StaticDataType staticDataType) { this.reportType = reportType; - this.staticDataType = staticDataType; this.mainStatus = mainStatus; this.subStatus = subStatus; this.contentId = contentId; this.name = name; this.content = content; this.createAt = createAt; + this.reportId=reportId; + this.staticDataType=staticDataType; } public void updateCreateAt(String createAt) { diff --git a/src/main/java/org/myteam/server/admin/dto/response/InquiryResponseDto.java b/src/main/java/org/myteam/server/admin/dto/response/InquiryResponseDto.java index 8646ed1a..30e56d53 100644 --- a/src/main/java/org/myteam/server/admin/dto/response/InquiryResponseDto.java +++ b/src/main/java/org/myteam/server/admin/dto/response/InquiryResponseDto.java @@ -35,10 +35,11 @@ public final static class ResponseInquiryListCond { private String isAnswered; @Schema(example = "회원,비회원") private String isMember; - @Schema(example = "닉네임 혹은 이메일 값") + @Schema(description ="문의 작성자의 닉네임입니다. 닉네임이없다면 메일로 들어갑니다.") private String nicknameEmail; private String content; - private String publicId; + @Schema(description = "문의 작성자의 메일입니다.") + private String userMail; private String createDate; public void updateCreateDate(String date) { diff --git a/src/main/java/org/myteam/server/admin/dto/response/MemberSearchResponseDto.java b/src/main/java/org/myteam/server/admin/dto/response/MemberSearchResponseDto.java index 76a24ff6..3d864c21 100644 --- a/src/main/java/org/myteam/server/admin/dto/response/MemberSearchResponseDto.java +++ b/src/main/java/org/myteam/server/admin/dto/response/MemberSearchResponseDto.java @@ -6,6 +6,7 @@ import lombok.NoArgsConstructor; import java.util.List; +import java.util.UUID; import static org.myteam.server.admin.dto.response.CommonResponseDto.*; @@ -25,6 +26,8 @@ public static class ResponseMemberSearch { private String email; private String tel; private String createDate; + @Schema(description = "회원 식별값입니다. 상세검색시에 이용해주세요") + private UUID memberId; public void updateCreateDate(String date) { this.createDate = date; diff --git a/src/main/java/org/myteam/server/admin/entity/AdminContentChangeLog.java b/src/main/java/org/myteam/server/admin/entity/AdminContentChangeLog.java index 0836a414..f252b261 100644 --- a/src/main/java/org/myteam/server/admin/entity/AdminContentChangeLog.java +++ b/src/main/java/org/myteam/server/admin/entity/AdminContentChangeLog.java @@ -18,6 +18,7 @@ public class AdminContentChangeLog extends BaseTime { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "public_id") private Member admin; private Long contentId; @Enumerated(EnumType.STRING) diff --git a/src/main/java/org/myteam/server/admin/entity/AdminContentMemo.java b/src/main/java/org/myteam/server/admin/entity/AdminContentMemo.java index 83c78145..458adff3 100644 --- a/src/main/java/org/myteam/server/admin/entity/AdminContentMemo.java +++ b/src/main/java/org/myteam/server/admin/entity/AdminContentMemo.java @@ -17,6 +17,7 @@ public class AdminContentMemo extends BaseTime { private Long id; private String content; @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "public_id") private Member writer; @Enumerated(EnumType.STRING) private StaticDataType staticDataType; diff --git a/src/main/java/org/myteam/server/admin/entity/AdminImproveChangeLog.java b/src/main/java/org/myteam/server/admin/entity/AdminImproveChangeLog.java index 25571a61..7e7d9441 100644 --- a/src/main/java/org/myteam/server/admin/entity/AdminImproveChangeLog.java +++ b/src/main/java/org/myteam/server/admin/entity/AdminImproveChangeLog.java @@ -17,6 +17,7 @@ public class AdminImproveChangeLog extends BaseTime { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "public_id") private Member admin; private Long contentId; @Enumerated(EnumType.STRING) diff --git a/src/main/java/org/myteam/server/admin/entity/AdminInquiryChangeLog.java b/src/main/java/org/myteam/server/admin/entity/AdminInquiryChangeLog.java index 690caf19..9c1a9987 100644 --- a/src/main/java/org/myteam/server/admin/entity/AdminInquiryChangeLog.java +++ b/src/main/java/org/myteam/server/admin/entity/AdminInquiryChangeLog.java @@ -16,6 +16,7 @@ public class AdminInquiryChangeLog extends BaseTime { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "public_id") private Member admin; private Long contentId; private boolean isAnswered; diff --git a/src/main/java/org/myteam/server/admin/entity/AdminMemberChangeLog.java b/src/main/java/org/myteam/server/admin/entity/AdminMemberChangeLog.java index 248eba72..f0c2d184 100644 --- a/src/main/java/org/myteam/server/admin/entity/AdminMemberChangeLog.java +++ b/src/main/java/org/myteam/server/admin/entity/AdminMemberChangeLog.java @@ -17,6 +17,7 @@ public class AdminMemberChangeLog extends BaseTime { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "public_id") private Member admin; private UUID memberId; @Enumerated(EnumType.STRING) diff --git a/src/main/java/org/myteam/server/admin/entity/AdminMemberMemo.java b/src/main/java/org/myteam/server/admin/entity/AdminMemberMemo.java index bd82ace7..2292188e 100644 --- a/src/main/java/org/myteam/server/admin/entity/AdminMemberMemo.java +++ b/src/main/java/org/myteam/server/admin/entity/AdminMemberMemo.java @@ -19,6 +19,7 @@ public class AdminMemberMemo extends BaseTime { private Long id; private String content; @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "public_id") private Member writer; private UUID memberId; @Builder diff --git a/src/main/java/org/myteam/server/admin/repository/AdminDashBoardRepository.java b/src/main/java/org/myteam/server/admin/repository/AdminDashBoardRepository.java index 60417975..a05a60a9 100644 --- a/src/main/java/org/myteam/server/admin/repository/AdminDashBoardRepository.java +++ b/src/main/java/org/myteam/server/admin/repository/AdminDashBoardRepository.java @@ -22,13 +22,9 @@ import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.myteam.server.admin.dto.request.AdminDashBoardRequestDto.RequestLatestData; -import static org.myteam.server.admin.dto.request.AdminDashBoardRequestDto.RequestStatic; import static org.myteam.server.admin.dto.response.AdminDashBoardResponseDto.ResponseLatestData; import static org.myteam.server.admin.dto.response.AdminDashBoardResponseDto.ResponseStatic; import static org.myteam.server.board.domain.QBoard.board; @@ -49,181 +45,87 @@ public class AdminDashBoardRepository { private final SecurityReadService securityReadService; - public ResponseStatic getStaticData(RequestStatic requestStatic) { - - DateType dateType = requestStatic.getDateType(); - StaticDataType staticDataType = requestStatic.getStaticDataType(); + public List getStaticData(StaticDataType staticDataType, DateType dateType) { return getStaticDataByRequest(dateType, staticDataType); } - private ResponseStatic getStaticDataByRequest(DateType dateType, StaticDataType staticDataType) { + private List getStaticDataByRequest(DateType dateType, StaticDataType staticDataType) { LocalDateTime now = LocalDateTime.now(); List dateList = DateTypeFactory.SupplyDateTime(dateType, now); - LocalDateTime static_start_time = dateList.get(0); - LocalDateTime static_end_time = dateList.get(1); - LocalDateTime static_start_time2 = dateList.get(2); - LocalDateTime static_end_time2 = dateList.get(3); - - if (staticDataType.name().equals(StaticDataType.BOARD.name())) { - return CreateStaticQueryFactory.createStaticQuery(board, dateType, dateList, queryFactory); + if(staticDataType.name().equals(StaticDataType.DashBoard.name())){ + List responseStatics=new ArrayList<>(); + responseStatics.add(CreateStaticQueryFactory.createStaticQuery(board, dateType, dateList, queryFactory)); + responseStatics.add(CreateStaticQueryFactory.createStaticQuery(comment1, dateType, dateList, queryFactory)); + responseStatics.add(CreateStaticQueryFactory.createReportStaticQuery(dateType, dateList, queryFactory,ReportType.BOARD)); + responseStatics.add(CreateStaticQueryFactory.createReportStaticQuery(dateType, dateList, queryFactory, ReportType.COMMENT)); + responseStatics.add(makeInquiryImprovementStatic(dateType,dateList)); + responseStatics.add(CreateStaticQueryFactory.createStaticQuery(memberAccess, dateType, dateList, queryFactory)); + responseStatics.add(CreateStaticQueryFactory.createUserDelStatic(dateType,dateList,queryFactory)); + responseStatics.add(CreateStaticQueryFactory.createStaticQuery(member, dateType, dateList, queryFactory)); + return responseStatics; } - if (staticDataType.name().equals(StaticDataType.COMMENT.name())) { - return CreateStaticQueryFactory.createStaticQuery(comment1, dateType, dateList, queryFactory); + if(staticDataType.name().equals(StaticDataType.MemberBoard.name())){ + List responseStatics=new ArrayList<>(); + responseStatics.add(CreateStaticQueryFactory.createSimpleStaticQuery(member, dateType, dateList, queryFactory)); + responseStatics.add(CreateStaticQueryFactory.createSimpleStaticQuery(memberAccess, dateType, dateList, queryFactory)); + responseStatics.add(CreateStaticQueryFactory.createSimpleUserDelStatic(dateType,dateList,queryFactory)); + responseStatics.add(CreateStaticQueryFactory.createStaticMemberStatusQuery( + MemberStatus.WARNED,dateList,queryFactory)); + responseStatics.add(CreateStaticQueryFactory.createStaticMemberStatusQuery( + MemberStatus.INACTIVE,dateList,queryFactory)); + return responseStatics; } - if (staticDataType.name().equals(StaticDataType.UserSignIn.name())) { - return CreateStaticQueryFactory.createStaticQuery(member, dateType, dateList, queryFactory); + if(staticDataType.name().equals(StaticDataType.ContentBoard.name())){ + List responseStatics=new ArrayList<>(); + responseStatics.add(CreateStaticQueryFactory.createSimpleStaticQuery(board, dateType, dateList, queryFactory)); + responseStatics.add(CreateStaticQueryFactory.createSimpleStaticQuery(comment1, dateType, dateList, queryFactory)); + responseStatics.add(CreateStaticQueryFactory.createSimpleReportStaticQuery(dateType, dateList, queryFactory,ReportType.BOARD)); + responseStatics.add(CreateStaticQueryFactory.createSimpleReportStaticQuery(dateType, dateList, queryFactory, ReportType.COMMENT)); + responseStatics.add(CreateStaticQueryFactory.createStaticContentQuery(StaticDataType.BOARD,AdminControlType.HIDDEN + ,dateList,queryFactory)); + responseStatics.add(CreateStaticQueryFactory.createStaticContentQuery(StaticDataType.COMMENT,AdminControlType.HIDDEN + ,dateList,queryFactory)); + return responseStatics; } - if (staticDataType.name().equals(StaticDataType.UserAccess.name())) { - return CreateStaticQueryFactory.createStaticQuery(memberAccess, dateType, dateList, queryFactory); + if(staticDataType.name().equals(StaticDataType.Inquiry.name())){ + List responseStatics=new ArrayList<>(); + responseStatics.add(CreateStaticQueryFactory.createSimpleStaticQuery( + inquiry, dateType, dateList, queryFactory)); + responseStatics.add(CreateStaticQueryFactory + .createInquiryStaticQuery(dateList,false,queryFactory)); + responseStatics.add(CreateStaticQueryFactory + .createInquiryStaticQuery(dateList,true,queryFactory)); + responseStatics.add(CreateStaticQueryFactory + .createMemberInquiryStaticQuery(dateList,true,queryFactory)); + responseStatics.add(CreateStaticQueryFactory + .createMemberInquiryStaticQuery(dateList,false,queryFactory)); + return responseStatics; } - if (staticDataType.name().equals(StaticDataType.ImprovementInquiry.name())) { - - ResponseStatic improvementResponse = CreateStaticQueryFactory.createStaticQuery( - improvement, dateType, dateList, queryFactory); - ResponseStatic inquiryResponse = CreateStaticQueryFactory.createStaticQuery( - inquiry, dateType, dateList, queryFactory); - - Map improvementMap = improvementResponse.getCurrentStaticData(); - Map inquiryMap = improvementResponse.getCurrentStaticData(); - - Map finalMap = Stream.concat(inquiryMap.entrySet().stream(), - improvementMap.entrySet().stream()) - .collect(Collectors.toMap( - entry -> entry.getKey(), - entry -> entry.getValue(), - (oldValue, newValue) -> oldValue + newValue - )); - Long currentCount = improvementResponse.getCurrentCount() + inquiryResponse.getCurrentCount(); - Long pastCount = improvementResponse.getPastCount() + inquiryResponse.getPastCount(); - Long totCount = improvementResponse.getTotCount() + inquiryResponse.getTotCount(); - int totPercent = StaticUtil.makeStaticPercent(currentCount, pastCount); + if(staticDataType.name().equals(StaticDataType.Improvement.name())){ + List responseStatics=new ArrayList<>(); + responseStatics.add(CreateStaticQueryFactory.createSimpleStaticQuery( + improvement, dateType, dateList, queryFactory)); + responseStatics.add(CreateStaticQueryFactory + .createImprovementStaticQuery(dateList,StaticDataType.ImprovementPending,queryFactory)); + responseStatics.add(CreateStaticQueryFactory + .createImprovementStaticQuery(dateList,StaticDataType.ImprovementReceived,queryFactory)); + responseStatics.add(CreateStaticQueryFactory + .createImprovementStaticQuery(dateList,StaticDataType.ImprovementComplete,queryFactory)); + return responseStatics; - return ResponseStatic - .builder() - .currentStaticData(finalMap) - .percent(totPercent) - .totCount(totCount) - .currentCount(currentCount) - .pastCount(pastCount) - .build(); - - } - if (staticDataType.name().equals(StaticDataType.ReportedBoard.name()) - || staticDataType.name().equals(StaticDataType.ReportedComment.name())) { - - ReportType reportType = ReportType.BOARD; - if (staticDataType.name().equals(StaticDataType.ReportedComment.name())) { - reportType = ReportType.COMMENT; - } - return CreateStaticQueryFactory.createStaticQuery(dateType, dateList, queryFactory, reportType); } - - if (staticDataType.name().equals(StaticDataType.UserDeleted.name())) { - - StringTemplate groupByDate = StaticUtil.delTemplate(dateType); - - List current_count = queryFactory.select(groupByDate, member.count()). - from(member) - .where(StaticUtil.betweenStaticTimeDel(static_end_time, static_start_time)) - .groupBy(groupByDate) - .orderBy(groupByDate.desc()) - .fetch(); - Long past_count = queryFactory.select(member.count()). - from(member) - .where(StaticUtil.betweenStaticTimeDel(static_end_time2, static_start_time2)) - .fetch().get(0); - - Long tot_count = queryFactory.select(member.count()) - .from(member) - .where(member.deleteAt.isNotNull()) - .fetch().get(0); - - - Map currentStataicData = new HashMap<>(); - - current_count.stream() - .forEach(x -> { - currentStataicData.put(x.get(0, String.class), x.get(1, Long.class)); - }); - - Long sums = current_count - .stream() - .mapToLong(x -> { - return x.get(1, Long.class); - }) - .sum(); - - int percent = StaticUtil.makeStaticPercent(sums, past_count); - - return ResponseStatic - .builder() - .currentStaticData(currentStataicData) - .currentCount(sums) - .pastCount(past_count) - .totCount(tot_count) - .percent(percent) - .build(); - } - - if (staticDataType.name().equals(StaticDataType.UserWarned.name())){ - return CreateStaticQueryFactory.createStaticMemberStatusQuery( - MemberStatus.WARNED,dateList,queryFactory); - } - if (staticDataType.name().equals(StaticDataType.UserBanned.name())) { - return CreateStaticQueryFactory.createStaticMemberStatusQuery( - MemberStatus.INACTIVE,dateList,queryFactory); - } - if (staticDataType.name().equals(StaticDataType.HideComment.name()) - ||staticDataType.name().equals(StaticDataType.HideBoard.name())) { - - StaticDataType staticDataType1=StaticDataType.HideComment.equals(StaticDataType.HideComment) - ? StaticDataType.COMMENT:StaticDataType.BOARD; - - return CreateStaticQueryFactory.createStaticContentQuery(staticDataType1,AdminControlType.HIDDEN - ,dateList,queryFactory); - } - if(staticDataType.equals(StaticDataType.InquiryComplete)||staticDataType - .equals(StaticDataType.InquiryPending)){ - if(staticDataType.equals(StaticDataType.InquiryComplete)){ - return CreateStaticQueryFactory - .createInquiryStaticQuery(dateList,true,queryFactory);} - - return CreateStaticQueryFactory - .createInquiryStaticQuery(dateList,false,queryFactory); - } - if(staticDataType.equals(StaticDataType.InquiryMember)||staticDataType - .equals(StaticDataType.InquiryNoMember)){ - if(staticDataType.equals(StaticDataType.InquiryMember)){ - return CreateStaticQueryFactory - .createMemberInquiryStaticQuery(dateList,true,queryFactory);} - - return CreateStaticQueryFactory - .createMemberInquiryStaticQuery(dateList,false,queryFactory); - } - - if(staticDataType.equals(StaticDataType.ImprovementComplete)||staticDataType - .equals(StaticDataType.ImprovementPending)||staticDataType - .equals(StaticDataType.ImprovementReceived)){ - return CreateStaticQueryFactory - .createImprovementStaticQuery(dateList,staticDataType,queryFactory); - } - - - throw new PlayHiveException(ErrorCode.INVALID_PARAMETER, "없는 형식의 파라미터 입니다"); } - public List getLatestData(RequestLatestData requestLatestData) { + public Map> getLatestData() { Member admin = securityReadService.getMember(); - - if (requestLatestData.getStaticDataType().name().equals(StaticDataType.Report.name())) { - - List responseLatestDataList = queryFactory.select( + Map> latestDataResult=new HashMap<>(); + List reportLatest=queryFactory.select( Projections.constructor(ResponseLatestData.class, new CaseBuilder() .when(report.reportType.eq(ReportType.COMMENT)) @@ -235,7 +137,6 @@ public List getLatestData(RequestLatestData requestLatestDat .when(report.reportType.eq(ReportType.CHAT)) .then("채팅") .otherwise("기타"), - Expressions.constant(StaticDataType.Report), new CaseBuilder() .when(report.reportType.eq(ReportType.COMMENT)) .then(JPAExpressions.select(comment1.adminControlType.stringValue()) @@ -264,7 +165,9 @@ public List getLatestData(RequestLatestData requestLatestDat .otherwise(JPAExpressions.select(board.title) .from(board) .where(board.id.eq(report.reportedContentId))), - report.createDate.stringValue() + report.createDate.stringValue(), + report.id, + Expressions.constant(StaticDataType.Report) )) .from(report) .join(member) @@ -273,11 +176,10 @@ public List getLatestData(RequestLatestData requestLatestDat .limit(10) .offset(0) .fetch(); - - responseLatestDataList.stream() + reportLatest.stream() .forEach(x -> { - boolean readCheck = redisService.AdminReadCheck("ADMIN_ALARM", admin.getPublicId().toString() - , x.getStaticDataType(), x.getContentId()); + boolean readCheck = redisService.AdminReadCheck(admin.getPublicId().toString() + ,StaticDataType.Report, x.getContentId()); x.mappingCheckRead(readCheck); x.updateCreateAt( DateFormatUtil.formatByDot.format( @@ -294,16 +196,9 @@ public List getLatestData(RequestLatestData requestLatestDat } }); - - return responseLatestDataList; - } - - if (requestLatestData.getStaticDataType().name().equals(StaticDataType.Inquiry.name())) { - - List responseLatestDataList = queryFactory.select( + List inquiryLatest=queryFactory.select( Projections.constructor(ResponseLatestData.class, Expressions.constant(""), - Expressions.constant(StaticDataType.Inquiry), new CaseBuilder() .when(inquiry.isAdminAnswered.isTrue()) .then("답변완료") @@ -314,40 +209,35 @@ public List getLatestData(RequestLatestData requestLatestDat .otherwise("회원"), inquiry.id, new CaseBuilder() - .when(member.nickname.isNull()) - .then(member.email) + .when(member.isNull()) + .then(inquiry.email) .otherwise(member.nickname), inquiry.content.substring(0, 20), - inquiry.createdAt.stringValue() + inquiry.createdAt.stringValue(), + Expressions.constant(0L), + Expressions.constant(StaticDataType.Inquiry) )) .from(inquiry) - .join(member) + .leftJoin(member) .on(member.eq(inquiry.member)) .orderBy(inquiry.createdAt.desc()) .limit(10) .offset(0) .fetch(); - responseLatestDataList.stream() + inquiryLatest.stream() .forEach(x -> { x.updateCreateAt( DateFormatUtil.formatByDot.format( LocalDateTime.parse(x.getCreateAt(), DateFormatUtil.FLEXIBLE_NANO_FORMATTER))); - boolean readCheck = redisService.AdminReadCheck("ADMIN_ALARM", admin.getPublicId().toString() + boolean readCheck = redisService.AdminReadCheck(admin.getPublicId().toString() , x.getStaticDataType(), x.getContentId()); x.mappingCheckRead(readCheck); }); - - return responseLatestDataList; - } - if (requestLatestData.getStaticDataType().name().equals(StaticDataType.Improvement.name())) { - - - List responseLatestDataList = queryFactory.select( + List improveLatest=queryFactory.select( Projections.constructor(ResponseLatestData.class, Expressions.constant(""), - Expressions.constant(StaticDataType.Improvement), new CaseBuilder() .when(improvement.improvementStatus.eq(ImprovementStatus.COMPLETED)) .then("완료") @@ -359,7 +249,9 @@ public List getLatestData(RequestLatestData requestLatestDat improvement.id, member.nickname, improvement.content, - improvement.createDate.stringValue() + improvement.createDate.stringValue(), + Expressions.constant(0L), + Expressions.constant(StaticDataType.Improvement) )) .from(improvement) @@ -369,22 +261,60 @@ public List getLatestData(RequestLatestData requestLatestDat .limit(10) .offset(0) .fetch(); - - - responseLatestDataList.stream() - .forEach(x -> { - x.updateCreateAt( - DateFormatUtil.formatByDot.format( - LocalDateTime.parse(x.getCreateAt(), DateFormatUtil.FLEXIBLE_NANO_FORMATTER))); - boolean readCheck = redisService.AdminReadCheck("ADMIN_ALARM", admin.getPublicId().toString() - , x.getStaticDataType(), x.getContentId()); - x.mappingCheckRead(readCheck); - }); - - return responseLatestDataList; - } - - throw new PlayHiveException(ErrorCode.INVALID_PARAMETER, "없는 형식의 파라미터 입니다"); + improveLatest.stream() + .forEach(x -> { + x.updateCreateAt( + DateFormatUtil.formatByDot.format( + LocalDateTime.parse(x.getCreateAt(), DateFormatUtil.FLEXIBLE_NANO_FORMATTER))); + boolean readCheck = redisService.AdminReadCheck(admin.getPublicId().toString() + , StaticDataType.Improvement, x.getContentId()); + x.mappingCheckRead(readCheck); + }); + latestDataResult.put(StaticDataType.Report.name(),reportLatest); + latestDataResult.put(StaticDataType.Inquiry.name(),inquiryLatest); + latestDataResult.put(StaticDataType.Improvement.name(),improveLatest); + return latestDataResult; } + private ResponseStatic makeInquiryImprovementStatic(DateType dateType,List dateList){ + ResponseStatic improvementResponse = CreateStaticQueryFactory.createStaticQuery( + improvement, dateType, dateList, queryFactory); + ResponseStatic inquiryResponse = CreateStaticQueryFactory.createStaticQuery( + inquiry, dateType, dateList, queryFactory); + + Map improvementMap = improvementResponse.getCurrentStaticData(); + Map inquiryMap = improvementResponse.getCurrentStaticData(); + Map finalMap = Stream.concat(inquiryMap.entrySet().stream(), + improvementMap.entrySet().stream()) + .collect(Collectors.toMap( + entry -> entry.getKey(), + entry -> entry.getValue(), + (oldValue, newValue) -> oldValue + newValue + )); + Map improvementPastMap = improvementResponse.getCurrentStaticData(); + Map inquiryPastMap = improvementResponse.getCurrentStaticData(); + Map finalPastMap = Stream.concat(inquiryPastMap.entrySet().stream(), + improvementPastMap.entrySet().stream()) + .collect(Collectors.toMap( + entry -> entry.getKey(), + entry -> entry.getValue(), + (oldValue, newValue) -> oldValue + newValue + )); + + Long currentCount = improvementResponse.getCurrentCount() + inquiryResponse.getCurrentCount(); + Long pastCount = improvementResponse.getPastCount() + inquiryResponse.getPastCount(); + Long totCount = improvementResponse.getTotCount() + inquiryResponse.getTotCount(); + int totPercent = StaticUtil.makeStaticPercent(currentCount, pastCount); + + return ResponseStatic + .builder() + .currentStaticData(finalMap) + .pastStaticData(finalPastMap) + .percent(totPercent) + .totCount(totCount) + .currentCount(currentCount) + .pastCount(pastCount) + .staticDataName("InquiryImprovement") + .build(); + } } diff --git a/src/main/java/org/myteam/server/admin/repository/AdminMemberRepository.java b/src/main/java/org/myteam/server/admin/repository/AdminMemberRepository.java index e1d5a6dd..c6b4cfb0 100644 --- a/src/main/java/org/myteam/server/admin/repository/AdminMemberRepository.java +++ b/src/main/java/org/myteam/server/admin/repository/AdminMemberRepository.java @@ -148,7 +148,8 @@ public Page getMemberDataList(RequestMemberSearch requestM .otherwise("일반"), member.email, member.tel, - member.createDate.stringValue() + member.createDate.stringValue(), + member.publicId ) ) .from(member) diff --git a/src/main/java/org/myteam/server/admin/repository/InquirySearchRepo.java b/src/main/java/org/myteam/server/admin/repository/InquirySearchRepo.java index 4be41c4b..cec2be92 100644 --- a/src/main/java/org/myteam/server/admin/repository/InquirySearchRepo.java +++ b/src/main/java/org/myteam/server/admin/repository/InquirySearchRepo.java @@ -148,10 +148,7 @@ public Page getInquiryListByCond(RequestInquiryListCond .then(inquiry.email) .otherwise(member.nickname), inquiry.content, - new CaseBuilder() - .when(member.isNotNull()) - .then(member.publicId.toString()) - .otherwise(""), + inquiry.email, inquiry.createdAt.stringValue() ) ) diff --git a/src/main/java/org/myteam/server/admin/service/AdminDashBoardService.java b/src/main/java/org/myteam/server/admin/service/AdminDashBoardService.java index 0fd2e5ed..5a711976 100644 --- a/src/main/java/org/myteam/server/admin/service/AdminDashBoardService.java +++ b/src/main/java/org/myteam/server/admin/service/AdminDashBoardService.java @@ -2,12 +2,12 @@ import lombok.RequiredArgsConstructor; import org.myteam.server.admin.repository.AdminDashBoardRepository; +import org.myteam.server.admin.utill.DateType; +import org.myteam.server.admin.utill.StaticDataType; import org.springframework.stereotype.Service; import java.util.List; - -import static org.myteam.server.admin.dto.request.AdminDashBoardRequestDto.RequestLatestData; -import static org.myteam.server.admin.dto.request.AdminDashBoardRequestDto.RequestStatic; +import java.util.Map; import static org.myteam.server.admin.dto.response.AdminDashBoardResponseDto.ResponseLatestData; import static org.myteam.server.admin.dto.response.AdminDashBoardResponseDto.ResponseStatic; @@ -19,14 +19,14 @@ public class AdminDashBoardService { private final AdminDashBoardRepository adminDashBoardRepository; - public ResponseStatic getStaticData(RequestStatic requestStatic) { + public List getStaticData(StaticDataType staticDataType,DateType dateType) { - return adminDashBoardRepository.getStaticData(requestStatic); + return adminDashBoardRepository.getStaticData(staticDataType,dateType); } - public List getLatestData(RequestLatestData requestLatestData) { + public Map> getLatestData() { - return adminDashBoardRepository.getLatestData(requestLatestData); + return adminDashBoardRepository.getLatestData(); } } diff --git a/src/main/java/org/myteam/server/admin/service/AdminImprovementService.java b/src/main/java/org/myteam/server/admin/service/AdminImprovementService.java index 857dcbbf..7d473ca4 100644 --- a/src/main/java/org/myteam/server/admin/service/AdminImprovementService.java +++ b/src/main/java/org/myteam/server/admin/service/AdminImprovementService.java @@ -3,6 +3,10 @@ import lombok.RequiredArgsConstructor; import org.myteam.server.admin.repository.AdminImprovementSearchRepo; +import org.myteam.server.admin.utill.StaticDataType; +import org.myteam.server.global.util.redis.service.RedisService; +import org.myteam.server.member.entity.Member; +import org.myteam.server.member.service.SecurityReadService; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; @@ -15,6 +19,8 @@ public class AdminImprovementService { private final AdminImprovementSearchRepo adminImprovementSearchRepo; + private final SecurityReadService securityReadService; + private final RedisService redisService; public Page getImproveListCond(RequestImprovementList requestImprovementList) { @@ -28,8 +34,14 @@ public Page getImproveListMember(RequestMemberImprove } public ResponseImprovementDetail getImproveDetail(RequestImprovementDetail requestImprovementList) { - - return adminImprovementSearchRepo.getImprovementDetail(requestImprovementList); + ResponseImprovementDetail responseImprovementDetail + =adminImprovementSearchRepo.getImprovementDetail(requestImprovementList);; + if(requestImprovementList.getAlarmCheck()!=null) { + Member admin = securityReadService.getMember(); + redisService.adminReadCheckUpdate(admin.getPublicId().toString() + , StaticDataType.Improvement, requestImprovementList.getContentId()); + } + return responseImprovementDetail; } public void addAdminMemo(AdminMemoImprovementRequest adminMemoRequest) { diff --git a/src/main/java/org/myteam/server/admin/service/AdminInquiryService.java b/src/main/java/org/myteam/server/admin/service/AdminInquiryService.java index e649eed5..850505e2 100644 --- a/src/main/java/org/myteam/server/admin/service/AdminInquiryService.java +++ b/src/main/java/org/myteam/server/admin/service/AdminInquiryService.java @@ -3,8 +3,12 @@ import lombok.RequiredArgsConstructor; import org.myteam.server.admin.entity.AdminContentMemo; import org.myteam.server.admin.repository.InquirySearchRepo; +import org.myteam.server.admin.utill.StaticDataType; import org.myteam.server.common.certification.service.InquiryAnsSendService; +import org.myteam.server.global.util.redis.service.RedisService; +import org.myteam.server.member.entity.Member; import org.myteam.server.member.service.MemberReadService; +import org.myteam.server.member.service.SecurityReadService; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import static org.myteam.server.admin.dto.request.AdminMemoRequestDto.AdminMemoInquiryRequest; @@ -21,6 +25,8 @@ public class AdminInquiryService { private final InquirySearchRepo inquirySearchRepo; private final InquiryAnsSendService inquiryAnsSendStrategy; private final MemberReadService memberReadService; + private final SecurityReadService securityReadService; + private final RedisService redisService; public Page getInquiryListCond(RequestInquiryListCond requestInquiryListCond) { @@ -28,8 +34,14 @@ public Page getInquiryListCond(RequestInquiryListCond r } public ResponseInquiryDetail getInquiryDetail(RequestInquiryDetail requestInquiryDetail) { - - return inquirySearchRepo.getInquiryDetail(requestInquiryDetail); + ResponseInquiryDetail responseInquiryDetail= + inquirySearchRepo.getInquiryDetail(requestInquiryDetail); + if(requestInquiryDetail.getAlarmCheck()!=null) { + Member admin = securityReadService.getMember(); + redisService.adminReadCheckUpdate(admin.getPublicId().toString() + , StaticDataType.Inquiry, requestInquiryDetail.getContentId()); + } + return responseInquiryDetail; } public Page getInquiryListMember(RequestInquiryList requestInquiryDetail) { diff --git a/src/main/java/org/myteam/server/admin/service/ContentSearchService.java b/src/main/java/org/myteam/server/admin/service/ContentSearchService.java index 182e8232..fddf047f 100644 --- a/src/main/java/org/myteam/server/admin/service/ContentSearchService.java +++ b/src/main/java/org/myteam/server/admin/service/ContentSearchService.java @@ -3,6 +3,10 @@ import lombok.RequiredArgsConstructor; import org.myteam.server.admin.repository.ContentSearchRepository; +import org.myteam.server.admin.utill.StaticDataType; +import org.myteam.server.global.util.redis.service.RedisService; +import org.myteam.server.member.entity.Member; +import org.myteam.server.member.service.SecurityReadService; import org.springframework.data.domain.Page; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; @@ -17,6 +21,8 @@ public class ContentSearchService { private final ContentSearchRepository contentSearchRepository; + private final SecurityReadService securityReadService; + private final RedisService redisService; public Page getReportList(RequestReportList requestReportList){ @@ -27,8 +33,13 @@ public Page getContentList(RequestContentData requestRepo return contentSearchRepository.getDataList(requestReportList); } public ResponseDetail getContentDetail(RequestDetail requestDetail){ - - return contentSearchRepository.getDetail(requestDetail); + ResponseDetail responseDetail=contentSearchRepository.getDetail(requestDetail); + if(requestDetail.getAlarmCheck()!=null&&requestDetail.getReportId()!=null) { + Member admin = securityReadService.getMember(); + redisService.adminReadCheckUpdate(admin.getPublicId().toString() + , StaticDataType.Report, requestDetail.getReportId()); + } + return responseDetail; } public void addAdminMemo(AdminMemoContentRequest adminMemoContentRequest){ contentSearchRepository.addAdminMemo(adminMemoContentRequest); diff --git a/src/main/java/org/myteam/server/admin/utill/CreateStaticQueryFactory.java b/src/main/java/org/myteam/server/admin/utill/CreateStaticQueryFactory.java index e7c1ce6c..65b1b88b 100644 --- a/src/main/java/org/myteam/server/admin/utill/CreateStaticQueryFactory.java +++ b/src/main/java/org/myteam/server/admin/utill/CreateStaticQueryFactory.java @@ -6,14 +6,16 @@ import com.querydsl.core.types.dsl.EntityPathBase; import com.querydsl.core.types.dsl.StringTemplate; import com.querydsl.jpa.impl.JPAQueryFactory; +import org.hibernate.type.descriptor.DateTimeUtils; import org.myteam.server.admin.entity.AdminInquiryChangeLog; +import org.myteam.server.global.util.date.DateFormatUtil; import org.myteam.server.improvement.domain.ImprovementStatus; import org.myteam.server.member.domain.MemberStatus; import org.myteam.server.report.domain.ReportType; import java.time.LocalDateTime; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.time.YearMonth; +import java.util.*; + import static org.myteam.server.admin.dto.response.AdminDashBoardResponseDto.ResponseStatic; import static org.myteam.server.admin.entity.QAdminContentChangeLog.adminContentChangeLog; import static org.myteam.server.admin.entity.QAdminImproveChangeLog.adminImproveChangeLog; @@ -42,11 +44,12 @@ public static ResponseStatic createStaticQuery(EntityPath target, .groupBy(groupByDate) .orderBy(groupByDate.desc()) .fetch(); - Long pastCount = queryFactory.select(((EntityPathBase) target).count()) + List pastCount = queryFactory.select(groupByDate, ((EntityPathBase) target).count()) .from(target) .where(StaticUtil.betweenStaticTime(staticEndTimePast, staticStartTimePast, target)) - .fetch() - .get(0); + .groupBy(groupByDate) + .orderBy(groupByDate.desc()) + .fetch(); Long totCount = queryFactory.select(((EntityPathBase) target).count()) .from(target) @@ -54,26 +57,84 @@ public static ResponseStatic createStaticQuery(EntityPath target, .get(0); Map currentCountByDate = new HashMap<>(); - + Map pastCountByDate=new HashMap<>(); currentCount.stream() .forEach(x -> { currentCountByDate.put(x.get(0, String.class), x.get(1, Long.class)); }); - Long sums = currentCount.stream() + pastCount.stream() + .forEach(x -> { + pastCountByDate.put(x.get(0, String.class), x.get(1, Long.class)); + }); + + Map currentCountByDateFinal; + Map pastCountByDateFinal; + + currentCountByDateFinal=fillEmptyDate(staticEndTime,staticStartTime,currentCountByDate,dateType); + pastCountByDateFinal=fillEmptyDate(staticEndTimePast,staticStartTimePast,pastCountByDate,dateType); + + Long currentSums = currentCount.stream() .mapToLong(x -> x.get(1, Long.class)) .sum(); - int percent = StaticUtil.makeStaticPercent(sums, pastCount); + + Long pastSums = pastCount.stream() + .mapToLong(x -> x.get(1, Long.class)) + .sum(); + + int percent = StaticUtil.makeStaticPercent(currentSums,pastSums); + + + Class entityClass = ((EntityPath) target).getType(); + String name = entityClass.getSimpleName(); return ResponseStatic.builder() - .currentStaticData(currentCountByDate) - .currentCount(sums) - .pastCount(pastCount) + .currentStaticData(currentCountByDateFinal) + .pastStaticData(pastCountByDateFinal) + .currentCount(currentSums) + .pastCount(pastSums) .totCount(totCount) .percent(percent) + .staticDataName(name.equals("Member") ? StaticDataType.UserSignIn.name() :name) .build(); + } + + public static ResponseStatic createSimpleStaticQuery(EntityPath target, + DateType dateType, List dateList + , JPAQueryFactory queryFactory) { + + LocalDateTime staticStartTime = dateList.get(0); + LocalDateTime staticEndTime = dateList.get(1); + LocalDateTime staticStartTimePast = dateList.get(2); + LocalDateTime staticEndTimePast = dateList.get(3); + Long currentCount = Optional.ofNullable(queryFactory.select(((EntityPathBase) target).count()) + .from(target) + .where(StaticUtil.betweenStaticTime(staticEndTime, staticStartTime, target)) + .fetchOne()).orElse(0L); + Long pastCount = Optional.ofNullable(queryFactory.select(((EntityPathBase) target).count()) + .from(target) + .where(StaticUtil.betweenStaticTime(staticEndTimePast, staticStartTimePast, target)) + .fetchOne()).orElse(0L); + + Long totCount =Optional.ofNullable( queryFactory.select(((EntityPathBase) target).count()) + .from(target) + .fetchOne()).orElse(0L); + + int percent = StaticUtil.makeStaticPercent(currentCount,pastCount); + Class entityClass = ((EntityPath) target).getType(); + String name = entityClass.getSimpleName(); + return ResponseStatic.builder() + .currentCount(currentCount) + .pastCount(pastCount) + .totCount(totCount) + .percent(percent) + .staticDataName(name.equals("member") ? StaticDataType.UserSignIn.name() :name) + .build(); } + + + public static ResponseStatic createImprovementStaticQuery(List dateList ,StaticDataType staticDataType, JPAQueryFactory queryFactory){ @@ -106,6 +167,7 @@ public static ResponseStatic createImprovementStaticQuery(List da .pastCount(pastCount) .totCount(totCount) .percent(percent) + .staticDataName(staticDataType.name()) .build(); } @@ -141,6 +203,8 @@ public static ResponseStatic createInquiryStaticQuery(List dateLi .pastCount(pastCount) .totCount(totCount) .percent(percent) + .staticDataName( isAnswered ? StaticDataType.InquiryComplete.name() + : StaticDataType.InquiryPending.name()) .build(); } @@ -181,6 +245,8 @@ public static ResponseStatic createMemberInquiryStaticQuery(List .pastCount(pastCount) .totCount(totCount) .percent(percent) + .staticDataName(isMember ? StaticDataType.InquiryMember.name() + : StaticDataType.InquiryNoMember.name()) .build(); } @@ -223,6 +289,7 @@ public static ResponseStatic createStaticContentQuery(StaticDataType staticDataT .pastCount(past_count) .totCount(tot_count) .percent(percent) + .staticDataName(staticDataType.name().equals("BOARD")?"HideBoard":"HideComment") .build(); } @@ -260,10 +327,12 @@ public static ResponseStatic createStaticMemberStatusQuery(MemberStatus memberSt .pastCount(past_count) .totCount(tot_count) .percent(percent) + .staticDataName(memberStatus.equals(MemberStatus.WARNED) ?StaticDataType.UserWarned.name() + :StaticDataType.UserBanned.name()) .build(); } - public static ResponseStatic createStaticQuery(DateType dateType, List dateList + public static ResponseStatic createReportStaticQuery(DateType dateType, List dateList , JPAQueryFactory queryFactory, ReportType reportType) { LocalDateTime staticStartTime = dateList.get(0); @@ -279,12 +348,13 @@ public static ResponseStatic createStaticQuery(DateType dateType, List pastCount = queryFactory.select(groupByDate, report.count()) .from(report) .where(StaticUtil.betweenStaticTime(staticEndTimePast, staticStartTimePast, report), report.reportType.eq(reportType)) - .fetch() - .get(0); + .groupBy(groupByDate) + .orderBy(groupByDate.desc()) + .fetch(); Long totCount = queryFactory.select(report.count()) .from(report) @@ -293,25 +363,183 @@ public static ResponseStatic createStaticQuery(DateType dateType, List currentCountByDate = new HashMap<>(); - + Map pastCountByDate=new HashMap<>(); currentCount.stream() .forEach(x -> { currentCountByDate.put(x.get(0, String.class), x.get(1, Long.class)); }); - Long sums = currentCount.stream() + pastCount.stream() + .forEach(x -> { + pastCountByDate.put(x.get(0, String.class), x.get(1, Long.class)); + }); + + Map currentCountByDateFinal; + Map pastCountByDateFinal; + + currentCountByDateFinal=fillEmptyDate(staticEndTime,staticStartTime,currentCountByDate,dateType); + pastCountByDateFinal=fillEmptyDate(staticEndTimePast,staticStartTimePast,pastCountByDate,dateType); + + Long currentSums = currentCount.stream() .mapToLong(x -> x.get(1, Long.class)) .sum(); - int percent = StaticUtil.makeStaticPercent(sums, pastCount); + + Long pastSums = pastCount.stream() + .mapToLong(x -> x.get(1, Long.class)) + .sum(); + + int percent = StaticUtil.makeStaticPercent(currentSums,pastSums); + + return ResponseStatic.builder() + .currentStaticData(currentCountByDateFinal) + .pastStaticData(pastCountByDateFinal) + .currentCount(currentSums) + .pastCount(pastSums) + .totCount(totCount) + .percent(percent) + .staticDataName(reportType.equals(ReportType.BOARD) ? "ReportedBoard":"ReportedComment") + .build(); + } + + public static ResponseStatic createSimpleReportStaticQuery(DateType dateType, List dateList + , JPAQueryFactory queryFactory, ReportType reportType) { + + LocalDateTime staticStartTime = dateList.get(0); + LocalDateTime staticEndTime = dateList.get(1); + LocalDateTime staticStartTimePast = dateList.get(2); + LocalDateTime staticEndTimePast = dateList.get(3); + + Long currentCount = Optional.ofNullable( + queryFactory.select(report.count()) + .from(report) + .where(StaticUtil.betweenStaticTime(staticEndTime, staticStartTime, report), + report.reportType.eq(reportType)) + .fetchOne()) + .orElse(0L); + Long pastCount = Optional.ofNullable(queryFactory.select(report.count()) + .from(report) + .where(StaticUtil.betweenStaticTime(staticEndTimePast, staticStartTimePast, report), + report.reportType.eq(reportType)) + .fetchOne()) + .orElse(0L); + + Long totCount = queryFactory.select(report.count()) + .from(report) + .where(report.reportType.eq(reportType)) + .fetch() + .get(0); + + + int percent = StaticUtil.makeStaticPercent(currentCount,pastCount); return ResponseStatic.builder() - .currentStaticData(currentCountByDate) - .currentCount(sums) + .currentCount(currentCount) + .pastCount(pastCount) + .totCount(totCount) + .percent(percent) + .staticDataName(reportType.equals(ReportType.BOARD) ? "ReportedBoard":"ReportedComment") + .build(); + } + + + public static ResponseStatic createSimpleUserDelStatic(DateType dateType,List dateList,JPAQueryFactory queryFactory){ + LocalDateTime staticStartTime = dateList.get(0); + LocalDateTime staticEndTime = dateList.get(1); + LocalDateTime staticStartTimePast = dateList.get(2); + LocalDateTime staticEndTimePast = dateList.get(3); + Long currentCount =Optional.ofNullable(queryFactory.select(member.count()). + from(member) + .where(StaticUtil.betweenStaticTimeDel(staticEndTime,staticStartTime)) + .fetchOne()).orElse(0L); + Long pastCount =Optional.ofNullable( queryFactory.select( member.count()). + from(member) + .where(StaticUtil.betweenStaticTimeDel(staticEndTimePast,staticStartTimePast)) + .fetchOne()).orElse(0L); + Long totCount = Optional.ofNullable(queryFactory.select(member.count()) + .from(member) + .where(member.deleteAt.isNotNull()) + .fetchOne()) + .orElse(0L); + int percent = StaticUtil.makeStaticPercent(currentCount,pastCount); + return ResponseStatic + .builder() + .currentCount(currentCount) .pastCount(pastCount) .totCount(totCount) .percent(percent) + .staticDataName(StaticDataType.UserDeleted.name()) .build(); } + public static ResponseStatic createUserDelStatic(DateType dateType,List dateList,JPAQueryFactory queryFactory){ + StringTemplate groupByDate = StaticUtil.delTemplate(dateType); + LocalDateTime staticStartTime = dateList.get(0); + LocalDateTime staticEndTime = dateList.get(1); + LocalDateTime staticStartTimePast = dateList.get(2); + LocalDateTime staticEndTimePast = dateList.get(3); + + List currentCount = queryFactory.select(groupByDate, member.count()). + from(member) + .where(StaticUtil.betweenStaticTimeDel(staticEndTime,staticStartTime)) + .groupBy(groupByDate) + .orderBy(groupByDate.desc()) + .fetch(); + List pastCount = queryFactory.select(groupByDate, member.count()). + from(member) + .where(StaticUtil.betweenStaticTimeDel(staticEndTimePast,staticStartTimePast)) + .groupBy(groupByDate) + .orderBy(groupByDate.desc()) + .fetch(); + Long totCount = queryFactory.select(member.count()) + .from(member) + .where(member.deleteAt.isNotNull()) + .fetch().get(0); + + Map currentCountByDate = new HashMap<>(); + Map pastCountByDate=new HashMap<>(); + currentCount.stream() + .forEach(x -> { + currentCountByDate.put(x.get(0, String.class), x.get(1, Long.class)); + }); + pastCount.stream() + .forEach(x -> { + pastCountByDate.put(x.get(0, String.class), x.get(1, Long.class)); + }); + + Map currentCountByDateFinal; + Map pastCountByDateFinal; + + currentCountByDateFinal=fillEmptyDate(staticEndTime,staticStartTime,currentCountByDate,dateType); + pastCountByDateFinal=fillEmptyDate(staticEndTimePast,staticStartTimePast,pastCountByDate,dateType); + + Long currentSum = currentCount + .stream() + .mapToLong(x -> { + return x.get(1, Long.class); + }) + .sum(); + Long pastSum = pastCount + .stream() + .mapToLong(x -> { + return x.get(1, Long.class); + }) + .sum(); + + int percent = StaticUtil.makeStaticPercent(currentSum,pastSum); + + return ResponseStatic + .builder() + .currentStaticData(currentCountByDateFinal) + .pastStaticData(pastCountByDateFinal) + .currentCount(currentSum) + .pastCount(pastSum) + .totCount(totCount) + .percent(percent) + .staticDataName(StaticDataType.UserDeleted.name()) + .build(); + } + + + private static Predicate inquiryIsMember(boolean isMember){ if(isMember){ return adminInquiryChangeLog.isMember.isTrue(); @@ -329,5 +557,29 @@ private static Predicate improvementProcessCond(StaticDataType staticDataType){ return adminImproveChangeLog.improvementStatus.eq(ImprovementStatus.COMPLETED); } - + public static Map fillEmptyDate(LocalDateTime startTime, + LocalDateTime endTime,Map maps,DateType dateType){ + Map filledResult = new TreeMap<>(); + if(dateType.equals(DateType.OneMonth)||dateType.equals(DateType.SixMonth)|| + dateType.equals(DateType.ThreeMonth)||dateType.equals(DateType.Year)) + { + YearMonth startMonth = YearMonth.from(startTime); + YearMonth endMonth = YearMonth.from(endTime); + YearMonth current = startMonth; + while (current.isBefore(endMonth)) { + String monthKey = DateFormatUtil.formatByDotMonth.format(current); + filledResult.put(monthKey, maps.getOrDefault(monthKey, 0L)); + current = current.plusMonths(1); + } + } + else{ + LocalDateTime current=startTime; + while (current.isBefore(endTime)) { + String dayKey =DateFormatUtil.formatByDot.format(current); + filledResult.put(dayKey,maps.getOrDefault(dayKey, 0L)); + current = current.plusDays(1L); + } + } + return filledResult; + } } diff --git a/src/main/java/org/myteam/server/admin/utill/StaticDataType.java b/src/main/java/org/myteam/server/admin/utill/StaticDataType.java index e771a916..bc713dca 100644 --- a/src/main/java/org/myteam/server/admin/utill/StaticDataType.java +++ b/src/main/java/org/myteam/server/admin/utill/StaticDataType.java @@ -2,6 +2,8 @@ public enum StaticDataType { + DashBoard,MemberBoard,ContentBoard, + Report, ReportedChat, ReportedComment, ReportedBoard, //BOARD,COMMENT의 경우 ReportType이라는 enum과 값을 맞춰야 하는 로직이 다른 기능에서 존재해서 대문자로 했습니다. BOARD, COMMENT, BoardComment, diff --git a/src/main/java/org/myteam/server/admin/utill/StaticUtil.java b/src/main/java/org/myteam/server/admin/utill/StaticUtil.java index e8d4f70e..639b6f0c 100644 --- a/src/main/java/org/myteam/server/admin/utill/StaticUtil.java +++ b/src/main/java/org/myteam/server/admin/utill/StaticUtil.java @@ -127,9 +127,9 @@ public static StringTemplate dateTemplate(DateType dateType, Object target) { public static StringTemplate delTemplate(DateType dateType) { if (dateType.name().equals(DateType.Day.name()) || dateType.name().equals(DateType.WeekEnd.name())) { return stringTemplate( - "DATE_FORMAT({0}, '%Y-%m-%d')", member.deleteAt); + "DATE_FORMAT({0}, '%Y.%m.%d')", member.deleteAt); } - return stringTemplate("DATE_FORMAT({0}, '%Y-%m')", member.deleteAt); + return stringTemplate("DATE_FORMAT({0}, '%Y.%m')", member.deleteAt); } public static Predicate betweenStaticTimeDel(LocalDateTime static_end_time, LocalDateTime static_start_time) { @@ -137,6 +137,9 @@ public static Predicate betweenStaticTimeDel(LocalDateTime static_end_time, Loca } public static int makeStaticPercent(Long val1, Long val2) { + if(val1-val2==0L){ + return 0; + } if (val2 == 0) { return 100; } diff --git a/src/main/java/org/myteam/server/auth/controller/AdminLoginController.java b/src/main/java/org/myteam/server/auth/controller/AdminLoginController.java new file mode 100644 index 00000000..6961ee21 --- /dev/null +++ b/src/main/java/org/myteam/server/auth/controller/AdminLoginController.java @@ -0,0 +1,29 @@ +package org.myteam.server.auth.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.myteam.server.auth.dto.AuthResponse; +import org.myteam.server.global.exception.ErrorResponse; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Tag(name = "관리자 인증 api", description = "관리자 로그인 관련 api") +public class AdminLoginController { + @Operation(summary = "관리자 로그인", description = "관리자가 로그인을 하여 토큰을 받습니다." + + "계정은 username으로 비밀번호는 password를 프로퍼티로 보내주시면됩니다. 사실상 기존의 일반 회원 로그인과" + + "같되 경로만 다르다고 보시면됩니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "로그인 성공", content = @Content(schema = @Schema(implementation = AuthResponse.class))), + @ApiResponse(responseCode = "404", description = "사용자를 찾을 수 없음", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + @ApiResponse(responseCode = "500", description = "JSON 파싱 오류", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), + }) + @PostMapping("api/admin/login") + public void adminLoginController(){ + } +} diff --git a/src/main/java/org/myteam/server/common/certification/service/InquiryAnsSendService.java b/src/main/java/org/myteam/server/common/certification/service/InquiryAnsSendService.java index 79f395e0..d934519a 100644 --- a/src/main/java/org/myteam/server/common/certification/service/InquiryAnsSendService.java +++ b/src/main/java/org/myteam/server/common/certification/service/InquiryAnsSendService.java @@ -8,6 +8,8 @@ import org.myteam.server.global.exception.ErrorCode; import org.myteam.server.global.exception.PlayHiveException; import org.myteam.server.global.util.date.DateFormatUtil; +import org.myteam.server.inquiry.domain.Inquiry; +import org.myteam.server.inquiry.repository.InquiryRepository; import org.myteam.server.member.controller.response.MemberResponse; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.MailException; @@ -28,19 +30,23 @@ public class InquiryAnsSendService { private final JavaMailSender javaMailSender; private final SpringTemplateEngine templateEngine; + private final InquiryRepository inquiryRepository; @Value("${SENDER_EMAIL}") private String senderEmail; private String getSubject() { return "문의 답변 메일입니다."; } - private String getBody(String content,String email) { - LocalDateTime now=LocalDateTime.now(); + private String getBody(AdminContentMemo adminContentMemo,MemberResponse memberResponse) { + Long inquiryId=adminContentMemo.getContentId(); + Inquiry inquiry=inquiryRepository.findById(inquiryId).get(); Context context = new Context(); - context.setVariable("email",email); - context.setVariable("content",content); - context.setVariable("setTime", DateFormatUtil.formatByDot.format(now)); - return templateEngine.process("mail/signup-complete-template", context); + context.setVariable("content",inquiry.getContent()); + context.setVariable("answer",adminContentMemo.getContent()); + context.setVariable("inquiryMeta.meta.ip",inquiry.getClientIp()); + context.setVariable(" inquiryMeta.meta.created_at", + DateFormatUtil.formatByDot.format(inquiry.getCreatedAt())); + return templateEngine.process("mail/admin-to-user-reply", context); } @Async public CompletableFuture send(AdminContentMemo adminMemo, MemberResponse memberResponse) { @@ -49,7 +55,7 @@ public CompletableFuture send(AdminContentMemo adminMemo, MemberResponse m try { String subject = getSubject(); - String body = getBody(adminMemo.getContent(),memberResponse.getEmail()); + String body = getBody(adminMemo,memberResponse); MimeMessage message = createMail(memberResponse.getEmail(), subject, body); javaMailSender.send(message); diff --git a/src/main/java/org/myteam/server/global/security/filter/JwtAuthenticationFilter.java b/src/main/java/org/myteam/server/global/security/filter/JwtAuthenticationFilter.java index d6bc81af..b8ad76c8 100644 --- a/src/main/java/org/myteam/server/global/security/filter/JwtAuthenticationFilter.java +++ b/src/main/java/org/myteam/server/global/security/filter/JwtAuthenticationFilter.java @@ -127,7 +127,7 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR return; } else if (status.equals(INACTIVE.name())) { log.warn("INACTIVE 상태인 경우 로그인이 불가능합니다"); - sendErrorResponse(response, HttpStatus.FORBIDDEN, "INACTIVE 상태인 경우 로그인이 불가능합니다"); + sendErrorResponse(response, HttpStatus.FORBIDDEN, "해당 아이디 로그인 시도가 10번 불일치하여 계정이 잠금되었습니다."); return; } else if (!status.equals(ACTIVE.name())&&!status.equals(WARNED.name())) { log.warn("알 수 없는 유저 상태 코드 : " + status); @@ -148,12 +148,9 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR log.debug("print refreshToken: {}", refreshToken); log.debug("print role: {}", role); - - if(status.equals(MemberRole.ADMIN.name())){ + if(role.equals(MemberRole.ADMIN.name())){ redisService.resetRequestCount("LOGIN_ADMIN",username); } - - redisService.putRefreshToken(publicId, refreshToken); redisUserInfoService.saveUserInfo(accessToken, new UserInfo(publicId, customUserDetails.getNickname(), customUserDetails.getImg())); @@ -179,14 +176,14 @@ protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServle if (redisService.isAdminLoginAllowed("LOGIN_ADMIN", username)) { int count = redisService.getRequestCount("LOGIN_ADMIN", username); sendErrorResponse(response, HttpStatus.UNAUTHORIZED, - "%s".formatted(String.valueOf(10 - count))); + "아이디 또는 비밀번호를 확인해주세요. (%s/10)".formatted(String.valueOf(count))); return; } int count = redisService.getRequestCount("LOGIN_ADMIN", username); if (count >= 10) { eventPublisher.publishEvent(new AdminBanEvent(username, ClientUtils.getRemoteIP(request))); } - sendErrorResponse(response, HttpStatus.UNAUTHORIZED, "잠긴 계정입니다."); + sendErrorResponse(response, HttpStatus.UNAUTHORIZED, "해당 아이디 로그인 시도가 10번 불일치하여 계정이 잠금되었습니다."); return; } diff --git a/src/main/java/org/myteam/server/global/util/date/DateFormatUtil.java b/src/main/java/org/myteam/server/global/util/date/DateFormatUtil.java index 3ce7f12a..e346b94e 100644 --- a/src/main/java/org/myteam/server/global/util/date/DateFormatUtil.java +++ b/src/main/java/org/myteam/server/global/util/date/DateFormatUtil.java @@ -14,12 +14,13 @@ public class DateFormatUtil { DateTimeFormatter.ofPattern("yyyy.MM.dd/hh:mm:ss"); public final static DateTimeFormatter formatByDot = DateTimeFormatter.ofPattern("yyyy.MM.dd"); + public final static DateTimeFormatter formatByDotMonth = + DateTimeFormatter.ofPattern("yyyy.MM"); public static final DateTimeFormatter FLEXIBLE_NANO_FORMATTER = new DateTimeFormatterBuilder() .appendPattern("yyyy-MM-dd HH:mm:ss") // 기본 날짜-시간 패턴 .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true) // 소수점 초 (나노초)를 0~9자리까지 선택적으로 추가 .toFormatter(); - public static LocalDate convertToLocalDateToDate(LocalDate localDate) { return Date.valueOf(localDate).toLocalDate(); } diff --git a/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java b/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java index b67a15b4..b23e183c 100644 --- a/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java +++ b/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java @@ -25,6 +25,7 @@ public class RedisService { // TODO: RedisReportService 로 변경. private final RedisTemplate redisTemplate; private static final String BOARD_RANK_KEY=":BoardRank"; + private static final String ADMIN_ALARM_KEY="ADMIN_ALARM"; private static final int ADMIN_LOGIN_MAX_REQUESTS=10; private static final int MAX_REQUESTS = 3; // 제한 횟수 (기본값: 5분 동안 3회) private static final long EXPIRED_TIME = 5L; // 만료 시간 (5분) @@ -71,22 +72,18 @@ public boolean isAdminLoginAllowed(String category,String identifier){ String redisKey = getRateLimitKey(category, identifier); String requestCountStr = redisTemplate.opsForValue().get(redisKey); int requestCount = requestCountStr == null ? 0 : Integer.parseInt(requestCountStr); - - if (requestCount >= ADMIN_LOGIN_MAX_REQUESTS) { + long newCount = redisTemplate.opsForValue().increment(redisKey); + requestCount+=1; + if (0>=(ADMIN_LOGIN_MAX_REQUESTS-requestCount)) { log.warn("🚫 [RateLimit] 관리자 요청 차단 - Key: {}, 요청 횟수: {}", redisKey, requestCount); return false; } - - long newCount = redisTemplate.opsForValue().increment(redisKey); - log.info("✅ [RateLimit] 관리자 요청 허용 - Key: {}, 요청 횟수: {}", redisKey, newCount); return true; } - - public boolean AdminReadCheck(String category, String adminIdentifier, StaticDataType staticDataType, Long contentId){ - - String redisKey=getRateLimitKey(category,adminIdentifier+staticDataType.name()+String.valueOf(contentId)); + public boolean AdminReadCheck(String adminIdentifier, StaticDataType staticDataType, Long contentId){ + String redisKey=ADMIN_ALARM_KEY+adminIdentifier+staticDataType.name()+contentId; String requestCountStr=redisTemplate.opsForValue().get(redisKey); int requestCount = requestCountStr == null ? 0 : Integer.parseInt(requestCountStr); if(requestCount==0){ @@ -94,16 +91,16 @@ public boolean AdminReadCheck(String category, String adminIdentifier, StaticDat } return true; } - - public void adminReadCheckUpdate(String category, String adminIdentifier, StaticDataType staticDataType, Long contentId){ - String redisKey=getRateLimitKey(category,adminIdentifier+staticDataType.name()+String.valueOf(contentId)); + public void adminReadCheckUpdate(String adminIdentifier, StaticDataType staticDataType, Long contentId){ + String redisKey=ADMIN_ALARM_KEY+adminIdentifier+staticDataType.name()+contentId; String requestCountStr=redisTemplate.opsForValue().get(redisKey); int requestCount = requestCountStr == null ? 0 : Integer.parseInt(requestCountStr); if(requestCount==0) { redisTemplate.opsForValue().increment(redisKey); - redisTemplate.expire(redisKey, Duration.ofMinutes(ADMIN_ALARM_READ_EXPIRE_TIME)); + redisTemplate.expire(redisKey, Duration.ofDays(30L)); } } + public void boardRecommendRankPerDay(Long contentId,Long delta){ LocalDateTime now = LocalDateTime.now().with(LocalTime.MIDNIGHT); String key = now.toLocalDate().toString() +BOARD_RANK_KEY; diff --git a/src/main/java/org/myteam/server/member/controller/AdminController.java b/src/main/java/org/myteam/server/member/controller/AdminController.java index c6c4522c..20fa0c6e 100644 --- a/src/main/java/org/myteam/server/member/controller/AdminController.java +++ b/src/main/java/org/myteam/server/member/controller/AdminController.java @@ -49,7 +49,7 @@ public class AdminController { private final MemberService memberService; private final AdminMemberSearchService adminMemberSearchService; - @Operation(summary = "이메일로 회원 조회", description = "관리자가 특정 이메일을 가진 회원을 조회합니다.") + /*@Operation(summary = "이메일로 회원 조회", description = "관리자가 특정 이메일을 가진 회원을 조회합니다.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "회원 정보 조회 성공"), @ApiResponse(responseCode = "400", description = "잘못된 요청 형식", content = @Content(schema = @Schema(implementation = ErrorResponse.class))), @@ -99,7 +99,7 @@ public ResponseEntity> delete(@RequestBody MemberDeleteReque "회원 삭제 성공", null )); - } + }*/ @Operation(summary = "회원 정보들을 조회", description = "각종 조건을 바탕으로 회원 정보들을 조회합니다.") @ApiResponses(value = { diff --git a/src/main/resources/templates/mail/admin-to-user-reply.html b/src/main/resources/templates/mail/admin-to-user-reply.html new file mode 100644 index 00000000..0594f149 --- /dev/null +++ b/src/main/resources/templates/mail/admin-to-user-reply.html @@ -0,0 +1,180 @@ + + + + + + + + + PlayHive 문의하기 답변 + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ PlayHive 로고 이미지 + +

+ 모두 함께 즐기는 클린 스포츠 커뮤니티, 플레이 하이브! +

+
+
+
+ 문의하기 고객센터 발송메일 +
+
+ + + + + + + + + +
+ 작성날짜 + 2025.05.05 / 18:24:32 (IP + 106.101.44.321)
+ 내용 + 문의하려고하는데요 로그인이 안돼요
+
+
+ 문의하기 답변
+

+ 안녕하세요. 플레이 하이브 입니다. +
+ 문의에 대해 답변드립니다. 해당부분은 빠른시일 내에 조치하겠습니다. +

+
+ + 플레이하이브 보러가기 + + + 플레이하이브 고객센터 문의하기 + +
+ 본 메일은 발신전용으로 회신하실 경우 답변이 되지 않습니다. 자세한 사항은 + + 플레이하이브 고객센터 + + 를 이용하세요. +
+
+ + +
+ + + + +
+ + + + + + + + + + + + +
+
+ PlayHive +
+
+

+ 열정적으로 응원하고 서로를 존중하며
+ + 모두 함께 즐기는 클린 스포츠 커뮤니티, 플레이 하이브! + +

+
+

+ 서비스명: PlayHive · 대표: 홍길표 · 개인정보 보호책임자: 홍길표
+ 콘텐츠 내용에 대한 저작권 및 법적 책임은 자료제공자 또는 글쓴이에 있으며 PlayHive의 입장과 다를 수 있습니다. +

+
+ + + + +
+

+ Copyright © PlayHive Co., Ltd All rights reserved. +

+
+
+
+ + + \ No newline at end of file diff --git a/src/test/java/org/myteam/server/admin/AdminReadCheckTest.java b/src/test/java/org/myteam/server/admin/AdminReadCheckTest.java new file mode 100644 index 00000000..c69d4cc2 --- /dev/null +++ b/src/test/java/org/myteam/server/admin/AdminReadCheckTest.java @@ -0,0 +1,199 @@ +package org.myteam.server.admin; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.myteam.server.admin.dto.request.ImproveRequestDto.RequestImprovementDetail; +import org.myteam.server.admin.repository.AdminDashBoardRepository; +import org.myteam.server.admin.service.AdminImprovementService; +import org.myteam.server.admin.service.AdminInquiryService; +import org.myteam.server.admin.service.ContentSearchService; +import org.myteam.server.admin.utill.StaticDataType; +import org.myteam.server.board.domain.Board; +import org.myteam.server.board.domain.CategoryType; +import org.myteam.server.chat.block.domain.BanReason; +import org.myteam.server.global.domain.Category; +import org.myteam.server.improvement.domain.Improvement; +import org.myteam.server.inquiry.domain.Inquiry; +import org.myteam.server.member.entity.Member; +import org.myteam.server.report.domain.Report; +import org.myteam.server.report.domain.ReportType; +import org.myteam.server.support.IntegrationTestSupport; +import org.springframework.beans.factory.annotation.Autowired; +import java.util.List; +import java.util.Map; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; +import static org.myteam.server.admin.dto.request.ContentRequestDto.*; +import static org.myteam.server.admin.dto.request.InquiryRequestDto.*; +import static org.myteam.server.admin.dto.response.AdminDashBoardResponseDto.*; + +public class AdminReadCheckTest extends IntegrationTestSupport { + + + @Autowired + AdminDashBoardRepository adminDashBoardRepository; + @Autowired + AdminInquiryService adminInquiryService; + @Autowired + AdminImprovementService adminImprovementService; + + + @Autowired + ContentSearchService contentSearchService; + Member admin; + Improvement improvement; + Inquiry inquiry; + + Board board; + Report report; + + @BeforeEach + public void setting(){ + + admin=createAdmin(0); + Member member=createMember(0); + board=createBoard(admin, Category.BASEBALL, CategoryType.FREE,"title", + "zzzz"); + report=createReport(admin,member, BanReason.SEXUAL_CONTENT, ReportType.BOARD,board.getId()); + improvement=createImprovement(admin,false); + inquiry=createInquiry(admin); + } + + @DisplayName("읽지않음이 정상 처리되는지") + void testNotRead(){ + when(redisService.AdminReadCheck(admin.getPublicId().toString() + , StaticDataType.Inquiry,inquiry.getId())) + .thenReturn(false); + when(redisService.AdminReadCheck(admin.getPublicId().toString() + , StaticDataType.Improvement,improvement.getId())) + .thenReturn(false); + Map> responseLatestData=adminDashBoardRepository.getLatestData(); + responseLatestData.keySet().stream().forEach( + x->{ + List responseLatestDataList= + responseLatestData.get((String) x); + + responseLatestDataList.stream() + .forEach(y->{ + assertThat(y.getCheckRead()).isFalse(); + }); + } + ); + + } + @DisplayName("읽음으로 정상 처리되는지") + void testRead(){ + when(redisService.AdminReadCheck(admin.getPublicId().toString() + , StaticDataType.Inquiry,inquiry.getId())) + .thenReturn(true); + when(redisService.AdminReadCheck(admin.getPublicId().toString() + , StaticDataType.Improvement,improvement.getId())) + .thenReturn(true); + Map> responseLatestData=adminDashBoardRepository.getLatestData(); + responseLatestData.keySet().stream().forEach( + x->{ + List responseLatestDataList= + responseLatestData.get((String) x); + + responseLatestDataList.stream() + .forEach(y->{ + assertThat(y.getCheckRead()).isFalse(); + }); + } + ); + + } + + @DisplayName("content detail 서비스로 접근시 호출이잘되는가") + @Test + void testContentReadDetail(){ + + RequestDetail requestDetail=RequestDetail + .builder() + .alarmCheck("zczx") + .contentId(board.getId()) + .staticDataType(StaticDataType.BOARD) + .reportId(report.getId()) + .build(); + contentSearchService.getContentDetail(requestDetail); + verify(redisService).adminReadCheckUpdate(any(String.class),any(StaticDataType.class), + any(Long.class)); + } + + + @DisplayName("content detail 서비스로 접근시 호출이안되는가") + @Test + void testContentReadDetail2(){ + + RequestDetail requestDetail=RequestDetail + .builder() + .alarmCheck("zczx") + .contentId(board.getId()) + .staticDataType(StaticDataType.BOARD) + .build(); + contentSearchService.getContentDetail(requestDetail); + RequestDetail requestDetail2=RequestDetail + .builder() + .contentId(board.getId()) + .reportId(report.getId()) + .staticDataType(StaticDataType.BOARD) + .build(); + contentSearchService.getContentDetail(requestDetail2); + RequestDetail requestDetail3=RequestDetail + .builder() + .contentId(board.getId()) + .staticDataType(StaticDataType.BOARD) + .build(); + contentSearchService.getContentDetail(requestDetail3); + + + verify(redisService,never()).adminReadCheckUpdate(any(String.class),any(StaticDataType.class), + any(Long.class)); + } + + @DisplayName("detail 서비스로 접근시에 adminreadcheckupdate가 호출이되는가") + @Test + void testInquiryReadDetail(){ + RequestInquiryDetail requestInquiryDetail=RequestInquiryDetail + .builder() + .alarmCheck("dsfdsf") + .id(inquiry.getId()) + .build(); + adminInquiryService.getInquiryDetail(requestInquiryDetail); + verify(redisService).adminReadCheckUpdate(any(String.class),any(StaticDataType.class), + any(Long.class)); + + } + @DisplayName("detail 서비스로 접근시에 adminreadcheckupdate가 호출이되는가") + @Test + void testImprovementReadDetail(){ + RequestImprovementDetail requestImprovementDetail= + RequestImprovementDetail + .builder() + .alarmCheck("check") + .contentId(improvement.getId()) + .build(); + adminImprovementService.getImproveDetail(requestImprovementDetail); + verify(redisService).adminReadCheckUpdate(any(String.class),any(StaticDataType.class), + any(Long.class)); + + } + @DisplayName("detail 서비스로 접근시에 adminreadcheckupdate가 호출이 안되는가") + @Test + void testNotReadDetail(){ + RequestImprovementDetail requestImprovementDetail= RequestImprovementDetail + .builder() + .contentId(improvement.getId()) + .build(); + adminImprovementService.getImproveDetail(requestImprovementDetail); + RequestInquiryDetail requestInquiryDetail=RequestInquiryDetail + .builder() + .id(inquiry.getId()) + .build(); + adminInquiryService.getInquiryDetail(requestInquiryDetail); + verify(redisService,never()).adminReadCheckUpdate(any(String.class),any(StaticDataType.class), + any(Long.class)); + } +} diff --git a/src/test/java/org/myteam/server/admin/inquriyimprovementtest.java b/src/test/java/org/myteam/server/admin/inquriyimprovementtest.java index b78db05f..e2a978f0 100644 --- a/src/test/java/org/myteam/server/admin/inquriyimprovementtest.java +++ b/src/test/java/org/myteam/server/admin/inquriyimprovementtest.java @@ -3,21 +3,35 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.myteam.server.admin.entity.AdminContentMemo; import org.myteam.server.admin.entity.AdminImproveChangeLog; import org.myteam.server.admin.entity.AdminInquiryChangeLog; +import org.myteam.server.admin.entity.AdminMemberMemo; import org.myteam.server.admin.repository.AdminImprovementSearchRepo; import org.myteam.server.admin.repository.InquirySearchRepo; +import org.myteam.server.admin.service.AdminInquiryService; +import org.myteam.server.common.certification.service.InquiryAnsSendService; import org.myteam.server.improvement.domain.ImportantStatus; import org.myteam.server.improvement.domain.Improvement; import org.myteam.server.improvement.domain.ImprovementStatus; import org.myteam.server.inquiry.domain.Inquiry; +import org.myteam.server.member.controller.response.MemberResponse; import org.myteam.server.member.entity.Member; +import org.myteam.server.member.service.MemberReadService; import org.myteam.server.support.IntegrationTestSupport; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.MockBeans; + import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import static org.myteam.server.admin.dto.request.AdminMemoRequestDto.AdminMemoImprovementRequest; import static org.myteam.server.admin.dto.request.AdminMemoRequestDto.AdminMemoInquiryRequest; import static org.myteam.server.admin.dto.response.ImprovementResponseDto.*; @@ -37,12 +51,21 @@ public class inquriyimprovementtest extends IntegrationTestSupport { AdminImprovementSearchRepo adminImprovementSearchRepo; @Autowired InquirySearchRepo inquirySearchRepo; + @MockBean + InquiryAnsSendService inquiryAnsSendService; + + + @MockBean + MemberReadService memberReadService; Member admin; Improvement improvement1; Inquiry inquiry1; + @Autowired + AdminInquiryService adminInquiryService; + @Autowired JPAQueryFactory queryFactory; @@ -157,6 +180,23 @@ void getdetailandmemo() { assertThat(adminInquiryChangeLogs.size()).isEqualTo(1); } + @Test + @DisplayName("문의 메일 전송 호출 테스트") + void inquriyMailSendVerify(){ + AdminMemoInquiryRequest adminMemoInquiryRequest=AdminMemoInquiryRequest + .builder() + .contentId(inquiry1.getId()) + .content("Zcxzcxzcxzc") + .email("wsdas") + .build(); + + when(memberReadService.getByEmail(any(String.class))) + .thenReturn(MemberResponse.createMemberResponse(admin)); + + adminInquiryService.sendInquiryAnswer(adminMemoInquiryRequest); + + verify(inquiryAnsSendService).send(any(AdminContentMemo.class), any(MemberResponse.class)); + } @Test void addMemberImproveInquriy() { diff --git a/src/test/java/org/myteam/server/admin/repository/DashBoardRepoTest.java b/src/test/java/org/myteam/server/admin/repository/DashBoardRepoTest.java index c0426ff1..6fea04ff 100644 --- a/src/test/java/org/myteam/server/admin/repository/DashBoardRepoTest.java +++ b/src/test/java/org/myteam/server/admin/repository/DashBoardRepoTest.java @@ -46,13 +46,11 @@ import java.util.List; import java.util.Map; import java.util.stream.IntStream; -import static org.assertj.core.api.Assertions.assertThat; -import static org.myteam.server.admin.dto.request.AdminDashBoardRequestDto.RequestLatestData; -import static org.myteam.server.admin.dto.request.AdminDashBoardRequestDto.RequestStatic; +import static org.assertj.core.api.Assertions.*; import static org.myteam.server.admin.dto.response.AdminDashBoardResponseDto.ResponseLatestData; import static org.myteam.server.admin.dto.response.AdminDashBoardResponseDto.ResponseStatic; import static org.myteam.server.global.security.jwt.JwtProvider.TOKEN_CATEGORY_ACCESS; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -147,7 +145,7 @@ void createDate() { .build(); - AdminInquiryChangeLog adminInquiryChangeLog= + AdminInquiryChangeLog adminInquiryChangeLog= AdminInquiryChangeLog .builder() .isMember(true) @@ -215,77 +213,61 @@ void createDate() { @Test @DisplayName("문의 개선 건의사항 세부 통계테스트") void testGetInquiryImprovementTest(){ - RequestStatic InquiryFin= RequestStatic - .builder() - .staticDataType(StaticDataType.InquiryComplete) - .dateType(DateType.Day) - .build(); - - RequestStatic InquiryNotFin = RequestStatic - .builder() - .staticDataType(StaticDataType.InquiryPending) - .dateType(DateType.Day) - .build(); - ResponseStatic responseStatic=adminDashBoardService.getStaticData(InquiryFin); - ResponseStatic responseStatic1=adminDashBoardService.getStaticData(InquiryNotFin); + List responseStatics=adminDashBoardService.getStaticData(StaticDataType.Inquiry,DateType.Day); - assertThat(responseStatic.getCurrentCount()).isEqualTo(5); - assertThat(responseStatic.getPastCount()).isEqualTo(0); - assertThat(responseStatic.getPercent()).isEqualTo(100); - assertThat(responseStatic1.getCurrentCount()).isEqualTo(5); - assertThat(responseStatic1.getPastCount()).isEqualTo(0); - assertThat(responseStatic1.getPercent()).isEqualTo(100); + assertThat(responseStatics.size()).isEqualTo(5); - RequestStatic InquiryIsMember= RequestStatic - .builder() - .staticDataType(StaticDataType.InquiryMember) - .dateType(DateType.Day) - .build(); + assertThat(responseStatics.get(0).getStaticDataName()).isEqualTo("Inquiry"); + assertThat(responseStatics.get(0).getCurrentCount()).isEqualTo(10); + assertThat(responseStatics.get(0).getPastCount()).isEqualTo(0); + assertThat(responseStatics.get(0).getPercent()).isEqualTo(100); - RequestStatic InquiryNotMember = RequestStatic - .builder() - .staticDataType(StaticDataType.InquiryNoMember) - .dateType(DateType.Day) - .build(); + assertThat(responseStatics.get(1).getStaticDataName()).isEqualTo("InquiryPending"); + assertThat(responseStatics.get(1).getCurrentCount()).isEqualTo(5); + assertThat(responseStatics.get(1).getPastCount()).isEqualTo(0); + assertThat(responseStatics.get(1).getPercent()).isEqualTo(100); - ResponseStatic responseStaticIsMember=adminDashBoardService.getStaticData(InquiryIsMember); - ResponseStatic responseStaticNotMember=adminDashBoardService.getStaticData(InquiryNotMember); + assertThat(responseStatics.get(2).getStaticDataName()).isEqualTo("InquiryComplete"); + assertThat(responseStatics.get(2).getCurrentCount()).isEqualTo(5); + assertThat(responseStatics.get(2).getPastCount()).isEqualTo(0); + assertThat(responseStatics.get(2).getPercent()).isEqualTo(100); - assertThat(responseStaticIsMember.getCurrentCount()).isEqualTo(5); - assertThat(responseStaticIsMember.getPastCount()).isEqualTo(0); - assertThat(responseStaticIsMember.getPercent()).isEqualTo(100); + assertThat(responseStatics.get(3).getStaticDataName()).isEqualTo("InquiryMember"); + assertThat(responseStatics.get(3).getCurrentCount()).isEqualTo(5); + assertThat(responseStatics.get(3).getPastCount()).isEqualTo(0); + assertThat(responseStatics.get(3).getPercent()).isEqualTo(100); - assertThat(responseStaticNotMember.getCurrentCount()).isEqualTo(5); - assertThat(responseStaticNotMember.getPastCount()).isEqualTo(0); - assertThat(responseStaticNotMember.getPercent()).isEqualTo(100); + assertThat(responseStatics.get(4).getStaticDataName()).isEqualTo("InquiryNoMember"); + assertThat(responseStatics.get(4).getCurrentCount()).isEqualTo(5); + assertThat(responseStatics.get(4).getPastCount()).isEqualTo(0); + assertThat(responseStatics.get(4).getPercent()).isEqualTo(100); + List responseImproves=adminDashBoardService.getStaticData(StaticDataType.Improvement,DateType.Day); + assertThat(responseImproves.size()).isEqualTo(4); - RequestStatic ImprovementFin= RequestStatic - .builder() - .staticDataType(StaticDataType.ImprovementComplete) - .dateType(DateType.Day) - .build(); + assertThat(responseImproves.get(0).getStaticDataName()).isEqualTo("Improvement"); + assertThat(responseImproves.get(0).getCurrentCount()).isEqualTo(10); + assertThat(responseImproves.get(0).getPastCount()).isEqualTo(0); + assertThat(responseImproves.get(0).getPercent()).isEqualTo(100); - RequestStatic ImprovementPending = RequestStatic - .builder() - .staticDataType(StaticDataType.ImprovementPending) - .dateType(DateType.Day) - .build(); - ResponseStatic responseStaticComplete=adminDashBoardService.getStaticData(ImprovementFin); - ResponseStatic responseStaticPending=adminDashBoardService.getStaticData(ImprovementPending); + assertThat(responseImproves.get(1).getStaticDataName()).isEqualTo("ImprovementPending"); + assertThat(responseImproves.get(1).getCurrentCount()).isEqualTo(5); + assertThat(responseImproves.get(1).getPastCount()).isEqualTo(0); + assertThat(responseImproves.get(1).getPercent()).isEqualTo(100); - assertThat(responseStaticComplete.getCurrentCount()).isEqualTo(5); - assertThat(responseStaticComplete.getPastCount()).isEqualTo(0); - assertThat(responseStaticComplete.getPercent()).isEqualTo(100); - - assertThat(responseStaticPending.getCurrentCount()).isEqualTo(5); - assertThat(responseStaticPending.getPastCount()).isEqualTo(0); - assertThat(responseStaticPending.getPercent()).isEqualTo(100); + assertThat(responseImproves.get(2).getStaticDataName()).isEqualTo("ImprovementReceived"); + assertThat(responseImproves.get(2).getCurrentCount()).isEqualTo(0); + assertThat(responseImproves.get(2).getPastCount()).isEqualTo(0); + assertThat(responseImproves.get(2).getPercent()).isEqualTo(0); + assertThat(responseImproves.get(3).getStaticDataName()).isEqualTo("ImprovementComplete"); + assertThat(responseImproves.get(3).getCurrentCount()).isEqualTo(5); + assertThat(responseImproves.get(3).getPastCount()).isEqualTo(0); + assertThat(responseImproves.get(3).getPercent()).isEqualTo(100); } @@ -295,141 +277,106 @@ void testGetInquiryImprovementTest(){ void testGetDataByDay() { LocalDateTime now = LocalDateTime.now(); - RequestStatic requestStaticComment = RequestStatic - .builder() - .staticDataType(StaticDataType.ReportedComment) - .dateType(DateType.Day) - .build(); - RequestStatic requestStaticImprovement = RequestStatic - .builder() - .staticDataType(StaticDataType.ImprovementInquiry) - .dateType(DateType.Day) - .build(); - - RequestStatic requestStaticBoard = RequestStatic - .builder() - .staticDataType(StaticDataType.ReportedBoard) - .dateType(DateType.Day) - .build(); - RequestStatic requestStaticSignIn = RequestStatic - .builder() - .staticDataType(StaticDataType.UserSignIn) - .dateType(DateType.Day) - .build(); - RequestStatic requestStaticDelete = RequestStatic - .builder() - .staticDataType(StaticDataType.UserDeleted) - .dateType(DateType.Day) - .build(); - RequestStatic requestStaticAccess = RequestStatic - .builder() - .staticDataType(StaticDataType.UserAccess) - .dateType(DateType.Day) - .build(); - - RequestStatic requestStaticWarned = RequestStatic - .builder() - .staticDataType(StaticDataType.UserWarned) - .dateType(DateType.Day) - .build(); - - RequestStatic requestStaticBanned = RequestStatic - .builder() - .staticDataType(StaticDataType.UserBanned) - .dateType(DateType.Day) - .build(); - - RequestStatic requestStaticHiddenComment = RequestStatic - .builder() - .staticDataType(StaticDataType.HideComment) - .dateType(DateType.Day) - .build(); - - RequestStatic requestStaticHiddenBoard = RequestStatic - .builder() - .staticDataType(StaticDataType.HideBoard) - .dateType(DateType.Day) - .build(); - - - ResponseStatic responseStaticBoard = adminDashBoardService.getStaticData(requestStaticBoard); - ResponseStatic responseStaticComment = adminDashBoardService.getStaticData(requestStaticComment); - ResponseStatic responseStaticDelete = adminDashBoardService.getStaticData(requestStaticDelete); - ResponseStatic responseStaticSignIn = adminDashBoardService.getStaticData(requestStaticSignIn); - ResponseStatic responseStaticImprovement = adminDashBoardService.getStaticData(requestStaticImprovement); - ResponseStatic responseStaticUserAccess = adminDashBoardService.getStaticData(requestStaticAccess); - ResponseStatic responseStaticWarned = adminDashBoardService.getStaticData(requestStaticWarned); - ResponseStatic responseStaticBanned = adminDashBoardService.getStaticData(requestStaticBanned); - ResponseStatic responseStaticHiddenComment = adminDashBoardService.getStaticData(requestStaticHiddenComment); - ResponseStatic responseStaticHiddenBoard = adminDashBoardService.getStaticData(requestStaticHiddenBoard); - - - assertThat(responseStaticBoard.getCurrentStaticData().keySet().size()).isEqualTo(1); - assertThat(responseStaticBoard.getCurrentCount()).isEqualTo(5); - assertThat(responseStaticBoard.getPastCount()).isEqualTo(0); - assertThat(responseStaticBoard.getTotCount()).isEqualTo(5); - assertThat(responseStaticBoard.getPercent()).isEqualTo(100); - - assertThat(responseStaticComment.getCurrentStaticData().keySet().size()).isEqualTo(1); - assertThat(responseStaticComment.getCurrentCount()).isEqualTo(5); - assertThat(responseStaticComment.getPastCount()).isEqualTo(0); - assertThat(responseStaticComment.getTotCount()).isEqualTo(5); - assertThat(responseStaticComment.getPercent()).isEqualTo(100); - - assertThat(responseStaticImprovement.getCurrentStaticData().keySet().size()).isEqualTo(1); - assertThat(responseStaticImprovement.getCurrentCount()).isEqualTo(20); - assertThat(responseStaticImprovement.getPastCount()).isEqualTo(0); - assertThat(responseStaticImprovement.getTotCount()).isEqualTo(20); - assertThat(responseStaticImprovement.getPercent()).isEqualTo(100); - - assertThat(responseStaticSignIn.getCurrentStaticData().keySet().size()).isEqualTo(1); - assertThat(responseStaticSignIn.getCurrentCount()).isEqualTo(11); - assertThat(responseStaticSignIn.getPastCount()).isEqualTo(0); - assertThat(responseStaticSignIn.getTotCount()).isEqualTo(11); - assertThat(responseStaticSignIn.getPercent()).isEqualTo(100); - - assertThat(responseStaticDelete.getCurrentStaticData().keySet().size()).isEqualTo(0); - assertThat(responseStaticDelete.getCurrentCount()).isEqualTo(0); - assertThat(responseStaticDelete.getPastCount()).isEqualTo(5); - assertThat(responseStaticDelete.getTotCount()).isEqualTo(10); - assertThat(responseStaticDelete.getPercent()).isEqualTo(-100); - - assertThat(responseStaticUserAccess.getCurrentStaticData().keySet().size()).isEqualTo(1); - assertThat(responseStaticUserAccess.getCurrentCount()).isEqualTo(5); - assertThat(responseStaticUserAccess.getPastCount()).isEqualTo(5); - assertThat(responseStaticUserAccess.getTotCount()).isEqualTo(10); - assertThat(responseStaticUserAccess.getPercent()).isEqualTo(0); - - assertThat(responseStaticWarned.getCurrentCount()).isEqualTo(5); - assertThat(responseStaticWarned.getPercent()).isEqualTo(100); - assertThat(responseStaticWarned.getPastCount()).isEqualTo(0); - - assertThat(responseStaticBanned.getCurrentCount()).isEqualTo(5); - assertThat(responseStaticBanned.getPercent()).isEqualTo(100); - assertThat(responseStaticBanned.getPastCount()).isEqualTo(0); - - assertThat(responseStaticHiddenBoard.getCurrentCount()).isEqualTo(5); - assertThat(responseStaticHiddenBoard.getPercent()).isEqualTo(100); - assertThat(responseStaticHiddenBoard.getPastCount()).isEqualTo(0); - - assertThat(responseStaticHiddenComment.getCurrentCount()).isEqualTo(5); - assertThat(responseStaticHiddenComment.getPercent()).isEqualTo(100); - assertThat(responseStaticHiddenComment.getPastCount()).isEqualTo(0); - - Map hashmap = responseStaticImprovement.getCurrentStaticData(); - - hashmap.keySet().stream() - .forEach(x -> { - assertThat(hashmap.get(x)).isEqualTo(20); - }); - - Map hashmap2 = responseStaticUserAccess.getCurrentStaticData(); - - hashmap2.keySet().stream() - .forEach(x -> { - assertThat(hashmap2.get(x)).isEqualTo(5); - }); + List responseStaticsDashBoard=adminDashBoardService.getStaticData(StaticDataType.DashBoard,DateType.Day); + List responseStaticsMemberBoard=adminDashBoardService.getStaticData(StaticDataType.MemberBoard,DateType.Day); + List responseStaticsContentBoard=adminDashBoardService.getStaticData(StaticDataType.ContentBoard,DateType.Day); + + + assertThat(responseStaticsDashBoard.size()).isEqualTo(8); + + assertThat(responseStaticsDashBoard.get(0).getCurrentStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(0).getPastStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(0).getCurrentCount()).isEqualTo(10); + assertThat(responseStaticsDashBoard.get(0).getPastCount()).isEqualTo(0); + assertThat(responseStaticsDashBoard.get(0).getTotCount()).isEqualTo(10); + assertThat(responseStaticsDashBoard.get(0).getPercent()).isEqualTo(100); + + assertThat(responseStaticsDashBoard.get(1).getStaticDataName()).isEqualTo("Comment"); + assertThat(responseStaticsDashBoard.get(1).getCurrentStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(1).getPastStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(1).getCurrentCount()).isEqualTo(10); + assertThat(responseStaticsDashBoard.get(1).getPastCount()).isEqualTo(0); + assertThat(responseStaticsDashBoard.get(1).getTotCount()).isEqualTo(10); + assertThat(responseStaticsDashBoard.get(1).getPercent()).isEqualTo(100); + + assertThat(responseStaticsDashBoard.get(2).getStaticDataName()).isEqualTo("ReportedBoard"); + assertThat(responseStaticsDashBoard.get(2).getCurrentStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(2).getPastStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(2).getCurrentCount()).isEqualTo(5); + assertThat(responseStaticsDashBoard.get(2).getPastCount()).isEqualTo(0); + assertThat(responseStaticsDashBoard.get(2).getTotCount()).isEqualTo(5); + assertThat(responseStaticsDashBoard.get(2).getPercent()).isEqualTo(100); + + assertThat(responseStaticsDashBoard.get(3).getStaticDataName()).isEqualTo("ReportedComment"); + assertThat(responseStaticsDashBoard.get(3).getCurrentStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(3).getPastStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(3).getCurrentCount()).isEqualTo(5); + assertThat(responseStaticsDashBoard.get(3).getPastCount()).isEqualTo(0); + assertThat(responseStaticsDashBoard.get(3).getTotCount()).isEqualTo(5); + assertThat(responseStaticsDashBoard.get(3).getPercent()).isEqualTo(100); + + assertThat(responseStaticsDashBoard.get(4).getStaticDataName()).isEqualTo("InquiryImprovement"); + assertThat(responseStaticsDashBoard.get(4).getCurrentStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(4).getPastStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(4).getCurrentCount()).isEqualTo(20); + assertThat(responseStaticsDashBoard.get(4).getPastCount()).isEqualTo(0); + assertThat(responseStaticsDashBoard.get(4).getTotCount()).isEqualTo(20); + assertThat(responseStaticsDashBoard.get(4).getPercent()).isEqualTo(100); + + assertThat(responseStaticsDashBoard.get(5).getStaticDataName()).isEqualTo("MemberAccess"); + assertThat(responseStaticsDashBoard.get(5).getCurrentStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(5).getPastStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(5).getCurrentCount()).isEqualTo(5); + assertThat(responseStaticsDashBoard.get(5).getPastCount()).isEqualTo(5); + assertThat(responseStaticsDashBoard.get(5).getTotCount()).isEqualTo(10); + assertThat(responseStaticsDashBoard.get(5).getPercent()).isEqualTo(0); + + assertThat(responseStaticsDashBoard.get(6).getStaticDataName()).isEqualTo("UserDeleted"); + assertThat(responseStaticsDashBoard.get(6).getCurrentStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(6).getPastStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(6).getCurrentCount()).isEqualTo(0); + assertThat(responseStaticsDashBoard.get(6).getPastCount()).isEqualTo(5); + assertThat(responseStaticsDashBoard.get(6).getTotCount()).isEqualTo(10); + assertThat(responseStaticsDashBoard.get(6).getPercent()).isEqualTo(-100); + + assertThat(responseStaticsDashBoard.get(7).getStaticDataName()).isEqualTo("UserSignIn"); + assertThat(responseStaticsDashBoard.get(7).getCurrentStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(7).getPastStaticData().keySet().size()).isEqualTo(1); + assertThat(responseStaticsDashBoard.get(7).getCurrentCount()).isEqualTo(11); + assertThat(responseStaticsDashBoard.get(7).getPastCount()).isEqualTo(0); + assertThat(responseStaticsDashBoard.get(7).getTotCount()).isEqualTo(11); + assertThat(responseStaticsDashBoard.get(7).getPercent()).isEqualTo(100); + + + + assertThat(responseStaticsMemberBoard.size()).isEqualTo(5); + + assertThat(responseStaticsMemberBoard.get(3).getStaticDataName()).isEqualTo("UserWarned"); + assertThat(responseStaticsMemberBoard.get(3).getCurrentCount()).isEqualTo(5); + assertThat(responseStaticsMemberBoard.get(3).getPastCount()).isEqualTo(0); + assertThat(responseStaticsMemberBoard.get(3).getTotCount()).isEqualTo(5); + assertThat(responseStaticsMemberBoard.get(3).getPercent()).isEqualTo(100); + + assertThat(responseStaticsMemberBoard.get(4).getStaticDataName()).isEqualTo("UserBanned"); + assertThat(responseStaticsMemberBoard.get(4).getCurrentCount()).isEqualTo(5); + assertThat(responseStaticsMemberBoard.get(4).getPastCount()).isEqualTo(0); + assertThat(responseStaticsMemberBoard.get(4).getTotCount()).isEqualTo(5); + assertThat(responseStaticsMemberBoard.get(4).getPercent()).isEqualTo(100); + + assertThat(responseStaticsContentBoard.size()).isEqualTo(6); + + assertThat(responseStaticsContentBoard.get(4).getStaticDataName()).isEqualTo("HideBoard"); + assertThat(responseStaticsContentBoard.get(4).getCurrentCount()).isEqualTo(5); + assertThat(responseStaticsContentBoard.get(4).getPastCount()).isEqualTo(0); + assertThat(responseStaticsContentBoard.get(4).getTotCount()).isEqualTo(5); + assertThat(responseStaticsContentBoard.get(4).getPercent()).isEqualTo(100); + + assertThat(responseStaticsContentBoard.get(5).getStaticDataName()).isEqualTo("HideComment"); + assertThat(responseStaticsContentBoard.get(5).getTotCount()).isEqualTo(5); + assertThat(responseStaticsContentBoard.get(5).getCurrentCount()).isEqualTo(5); + assertThat(responseStaticsContentBoard.get(5).getPastCount()).isEqualTo(0); + assertThat(responseStaticsContentBoard.get(5).getPercent()).isEqualTo(100); } @@ -438,30 +385,16 @@ void testGetDataByDay() { void testGetLatestDate() { - RequestLatestData requestLatestDataInquiry = RequestLatestData. - builder() - .staticDataType(StaticDataType.Inquiry) - .build(); - - RequestLatestData requestLatestDataImproveMent = RequestLatestData. - builder() - .staticDataType(StaticDataType.Improvement) - .build(); - - - RequestLatestData requestLatestDataReport = RequestLatestData. - builder() - .staticDataType(StaticDataType.Report) - .build(); + Map> responseMap = adminDashBoardService.getLatestData(); + assertThat(responseMap.keySet().size()).isEqualTo(3); + List reports=responseMap.get("Report"); + List inquiry=responseMap.get("Inquiry"); + List improve=responseMap.get("Improvement"); + assertThat(reports.size()).isEqualTo(10); + assertThat(inquiry.size()).isEqualTo(10); + assertThat(improve.size()).isEqualTo(10); - List responseLatestDataInquiry = adminDashBoardService.getLatestData(requestLatestDataInquiry); - List responseLatestDataImprovement = adminDashBoardService.getLatestData(requestLatestDataImproveMent); - List responseLatestDataReport = adminDashBoardService.getLatestData(requestLatestDataReport); - - assertThat(responseLatestDataInquiry.size()).isEqualTo(10); - assertThat(responseLatestDataImprovement.size()).isEqualTo(10); - assertThat(responseLatestDataReport.size()).isEqualTo(10); } @@ -469,76 +402,34 @@ void testGetLatestDate() { @DisplayName("요구되는 변수가 빠졋을떄 및 범위 밖의 다른값을 입력시 일어나는 에러체크") void testValueNullError() throws Exception { - String requestBodyWithAbsent = """ - { - "dateType": "Day" - } - """; - - String requestBodyWithWrongValue = """ - { - - "staticDataType":"Inqy" - "dateType": "Day" - } - """; - String requestBodyWithAbsent2 = """ - { - - } - """; - - String requestBodyWithWrongValue2 = """ - { - "staticDataType":"Inqy" - } - """; - String requestBodyWithWrongDate = """ - { - "staticDataType":"Inquiry" - "dateType":"zzzz" - } - """; - - mockMvc.perform(post("/api/admin/data/static") + mockMvc.perform(get("/api/admin/data/static") .contentType(MediaType.APPLICATION_JSON) - .content(requestBodyWithAbsent) .header("Authorization", "Bearer " + accessToken)) .andDo(print()) .andExpect(status().isBadRequest()); - mockMvc.perform(post("/api/admin/data/static") + mockMvc.perform(get("/api/admin/data/static?dateType=Day") .contentType(MediaType.APPLICATION_JSON) - .content(requestBodyWithWrongValue) + .header("Authorization", "Bearer " + accessToken)) .andDo(print()) .andExpect(status().isBadRequest()); - - - mockMvc.perform(post("/api/admin/data/latest") + mockMvc.perform(get("/api/admin/data/static?staticType=Dash&dateType=Day") .contentType(MediaType.APPLICATION_JSON) - .content(requestBodyWithWrongValue2) + .header("Authorization", "Bearer " + accessToken)) .andDo(print()) .andExpect(status().isBadRequest()); - - mockMvc.perform(post("/api/admin/data/latest") + mockMvc.perform(get("/api/admin/data/static?staticType=DashBoard&dateType=Day") .contentType(MediaType.APPLICATION_JSON) - .content(requestBodyWithAbsent2) .header("Authorization", "Bearer " + accessToken)) .andDo(print()) - .andExpect(status().isBadRequest()); + .andExpect(status().isOk()); - mockMvc.perform(post("/api/admin/data/static") - .contentType(MediaType.APPLICATION_JSON) - .content(requestBodyWithWrongDate) - .header("Authorization", "Bearer " + accessToken)) - .andDo(print()) - .andExpect(status().isBadRequest()); } } From 9f45c60b3a425f0a9e4644b9cb1355911c005c07 Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 20:06:46 +0900 Subject: [PATCH 04/15] fix:testdirver --- src/test/java/org/myteam/server/support/TestDriverSupport.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/org/myteam/server/support/TestDriverSupport.java b/src/test/java/org/myteam/server/support/TestDriverSupport.java index 1418fc9e..c9d9cacc 100644 --- a/src/test/java/org/myteam/server/support/TestDriverSupport.java +++ b/src/test/java/org/myteam/server/support/TestDriverSupport.java @@ -161,9 +161,6 @@ public abstract class TestDriverSupport { @Autowired protected CommonCountAspect commonCountAspect; - @MockBean - protected SecurityReadService securityReadService; - @AfterEach void tearDown() { commentRecommendRepository.deleteAllInBatch(); From adcde233f820b9ed7923149bb428375fa353fe79 Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 20:13:26 +0900 Subject: [PATCH 05/15] fix: testcode --- .../server/redis/GetHotBoardZsetTest.java | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java index c67602c4..e024a4be 100644 --- a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -53,27 +53,14 @@ public class GetHotBoardZsetTest extends TestContainerSupport { @Autowired RedisCountService redisCountService; - private List memberList; + private List members; private List boardList; @BeforeEach void setting(){ - for(int i=0;10>i;i++){ - Board board=createBoard(memberList.get(i), Category.BASEBALL, CategoryType.FREE,"제목", - "내용"); - boardList.add(board); - } - } - @Test - @DisplayName("여러 사용자가 순위를 매기고 정합성이 잘지켜지는지 그리고 순위가 양수인 데이터만 잘가져오는지.") - void recommendZsetTest() throws ExecutionException, InterruptedException { - int threadCount = 10; - ExecutorService executorService = Executors.newFixedThreadPool(5); - CountDownLatch countDownLatch = new CountDownLatch(threadCount); - List members = new ArrayList<>(); - for (int i = 0; i < threadCount; i++) { + for (int i = 0; i < 10; i++) { Member newMember = Member.builder() .email("user" + i + "@test.com") .password("1234") @@ -87,7 +74,21 @@ void recommendZsetTest() throws ExecutionException, InterruptedException { memberJpaRepository.save(newMember); memberActivityRepository.save(new MemberActivity(newMember)); members.add(newMember); + } + for(int i=0;10>i;i++){ + Board board=createBoard(members.get(i), Category.BASEBALL, CategoryType.FREE,"제목", + "내용"); + boardList.add(board); + } + } + @Test + @DisplayName("여러 사용자가 순위를 매기고 정합성이 잘지켜지는지 그리고 순위가 양수인 데이터만 잘가져오는지.") + void recommendZsetTest() throws ExecutionException, InterruptedException { + int threadCount = 10; + ExecutorService executorService = Executors.newFixedThreadPool(5); + CountDownLatch countDownLatch = new CountDownLatch(threadCount); + for (Member m: members) { executorService.execute(() -> { From 18b217e767ecc1d75dc3a6e1d0483efea9b7c089 Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 20:19:54 +0900 Subject: [PATCH 06/15] fix:testcode --- src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java index e024a4be..b87549c1 100644 --- a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -53,7 +53,7 @@ public class GetHotBoardZsetTest extends TestContainerSupport { @Autowired RedisCountService redisCountService; - private List members; + private List members=new ArrayList<>(); private List boardList; From 643e2a2a4f39574165d2024310e53f6ef9a743d0 Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 20:25:25 +0900 Subject: [PATCH 07/15] fix:testcode --- src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java index b87549c1..71c4d9a6 100644 --- a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -54,7 +54,7 @@ public class GetHotBoardZsetTest extends TestContainerSupport { RedisCountService redisCountService; private List members=new ArrayList<>(); - private List boardList; + private List boardList=new ArrayList<>(); @BeforeEach From 065c925e9e7405924fa2051bc802f22234cf84c6 Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 20:50:37 +0900 Subject: [PATCH 08/15] fix:Testcode --- .../myteam/server/global/util/redis/service/RedisService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java b/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java index b23e183c..5261a9c4 100644 --- a/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java +++ b/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java @@ -103,7 +103,7 @@ public void adminReadCheckUpdate(String adminIdentifier, StaticDataType staticDa public void boardRecommendRankPerDay(Long contentId,Long delta){ LocalDateTime now = LocalDateTime.now().with(LocalTime.MIDNIGHT); - String key = now.toLocalDate().toString() +BOARD_RANK_KEY; + String key = now+BOARD_RANK_KEY; LocalDateTime nextMidnight = now.plusDays(1).with(LocalTime.MIDNIGHT); redisTemplate.opsForZSet().incrementScore(key,contentId.toString(),delta); redisTemplate.expireAt(key,Date.valueOf(nextMidnight.toLocalDate())); From 0dc1334664d414bb37bc56c96093c3252827cb71 Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 21:00:27 +0900 Subject: [PATCH 09/15] fix:test --- src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java index 71c4d9a6..fa472f8b 100644 --- a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -101,7 +101,9 @@ void recommendZsetTest() throws ExecutionException, InterruptedException { SecurityContextHolder.setContext(context); try { boardList.stream().forEach(x->{ + System.out.printf("boardid:%d",x.getId()); if(x.getId()%2==0) { + redisCountService.getCommonCount(ServiceType.RECOMMEND, DomainType.BOARD, x.getId(), null); } From 7c5873348b4d283594de97613841b75cb7226435 Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 21:27:26 +0900 Subject: [PATCH 10/15] fix:test --- .../server/global/util/redis/service/RedisService.java | 6 +++--- .../java/org/myteam/server/redis/GetHotBoardZsetTest.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java b/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java index 5261a9c4..91427b99 100644 --- a/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java +++ b/src/main/java/org/myteam/server/global/util/redis/service/RedisService.java @@ -111,16 +111,16 @@ public void boardRecommendRankPerDay(Long contentId,Long delta){ public List getBoardRecommendRankPerDay(){ LocalDateTime now=LocalDateTime.now().with(LocalTime.MIDNIGHT); String key=now+BOARD_RANK_KEY; - List ids=redisTemplate.opsForZSet().reverseRange(key,0,9) + List ids=redisTemplate.opsForZSet().reverseRangeWithScores(key,0,9) .stream() .filter(x->{ - if(Long.parseLong(x)>0){ + if(x.getScore()>0){ return true; } return false; }) .map(x->{ - return Long.parseLong(x); + return Long.parseLong(x.getValue()); }) .collect(Collectors.toList()); return ids; diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java index fa472f8b..958b861f 100644 --- a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -79,7 +79,7 @@ void setting(){ for(int i=0;10>i;i++){ Board board=createBoard(members.get(i), Category.BASEBALL, CategoryType.FREE,"제목", "내용"); - boardList.add(board); + System.out.printf("boardid:%d",board.getId()); } } @Test @@ -101,7 +101,7 @@ void recommendZsetTest() throws ExecutionException, InterruptedException { SecurityContextHolder.setContext(context); try { boardList.stream().forEach(x->{ - System.out.printf("boardid:%d",x.getId()); + if(x.getId()%2==0) { redisCountService.getCommonCount(ServiceType.RECOMMEND, From f73a6ca3c579a6ac9ae4d66d4c5fbc01ee2a443d Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 21:41:10 +0900 Subject: [PATCH 11/15] fix:last fix;; --- .../java/org/myteam/server/redis/GetHotBoardZsetTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java index 958b861f..a92efdec 100644 --- a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -48,10 +48,10 @@ public class GetHotBoardZsetTest extends TestContainerSupport { @Autowired - RedisService redisService; + private RedisService redisService; @Autowired - RedisCountService redisCountService; + private RedisCountService redisCountService; private List members=new ArrayList<>(); private List boardList=new ArrayList<>(); @@ -79,6 +79,7 @@ void setting(){ for(int i=0;10>i;i++){ Board board=createBoard(members.get(i), Category.BASEBALL, CategoryType.FREE,"제목", "내용"); + boardList.add(board); System.out.printf("boardid:%d",board.getId()); } } From 92a8de7b1f7ff4d84436af4d0ac0049ed93639f3 Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 21:51:57 +0900 Subject: [PATCH 12/15] fix:last fix;; --- .../java/org/myteam/server/redis/GetHotBoardZsetTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java index a92efdec..1b4ea6e4 100644 --- a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -89,7 +89,8 @@ void recommendZsetTest() throws ExecutionException, InterruptedException { int threadCount = 10; ExecutorService executorService = Executors.newFixedThreadPool(5); CountDownLatch countDownLatch = new CountDownLatch(threadCount); - + assertThat(members.size()).isEqualTo(10); + assertThat(boardList.size()).isEqualTo(10); for (Member m: members) { executorService.execute(() -> { @@ -104,7 +105,6 @@ void recommendZsetTest() throws ExecutionException, InterruptedException { boardList.stream().forEach(x->{ if(x.getId()%2==0) { - redisCountService.getCommonCount(ServiceType.RECOMMEND, DomainType.BOARD, x.getId(), null); } From 2c8209f36bb32b4ca3a0a01a9046fadc851236f6 Mon Sep 17 00:00:00 2001 From: dong3058 Date: Mon, 4 Aug 2025 22:00:29 +0900 Subject: [PATCH 13/15] fix:last fix;; --- src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java index 1b4ea6e4..efa09d69 100644 --- a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -50,6 +50,9 @@ public class GetHotBoardZsetTest extends TestContainerSupport { @Autowired private RedisService redisService; + @Autowired + private RecommendService recommendService; + @Autowired private RedisCountService redisCountService; From 0fec646384c123b2f08e2e4f85cc9c3f94537b7d Mon Sep 17 00:00:00 2001 From: dong3058 Date: Tue, 5 Aug 2025 16:31:46 +0900 Subject: [PATCH 14/15] fix: test --- .../server/redis/GetHotBoardZsetTest.java | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java index efa09d69..2bd732ef 100644 --- a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -2,11 +2,15 @@ import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.myteam.server.board.domain.Board; +import org.myteam.server.board.domain.BoardCount; import org.myteam.server.board.domain.CategoryType; +import org.myteam.server.board.repository.BoardCountRepository; +import org.myteam.server.board.repository.BoardRepository; import org.myteam.server.global.domain.Category; import org.myteam.server.global.security.dto.CustomUserDetails; import org.myteam.server.global.util.redis.RedisCountBulkUpdater; @@ -18,19 +22,25 @@ import org.myteam.server.member.domain.MemberType; import org.myteam.server.member.entity.Member; import org.myteam.server.member.entity.MemberActivity; +import org.myteam.server.member.repository.MemberActivityRepository; import org.myteam.server.member.repository.MemberJpaRepository; import org.myteam.server.recommend.RecommendActionType; import org.myteam.server.recommend.RecommendService; import org.myteam.server.report.domain.DomainType; +import org.myteam.server.support.IntegrationTestSupport; import org.myteam.server.support.TestContainerSupport; +import org.myteam.server.support.TestDriverSupport; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.test.context.ActiveProfiles; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -49,10 +59,6 @@ public class GetHotBoardZsetTest extends TestContainerSupport { @Autowired private RedisService redisService; - - @Autowired - private RecommendService recommendService; - @Autowired private RedisCountService redisCountService; @@ -60,6 +66,14 @@ public class GetHotBoardZsetTest extends TestContainerSupport { private List boardList=new ArrayList<>(); + @AfterEach + void end(){ + memberActivityRepository.deleteAllInBatch(); + boardCountRepository.deleteAllInBatch(); + boardRepository.deleteAllInBatch(); + memberJpaRepository.deleteAllInBatch(); + } + @BeforeEach void setting(){ @@ -106,27 +120,21 @@ void recommendZsetTest() throws ExecutionException, InterruptedException { SecurityContextHolder.setContext(context); try { boardList.stream().forEach(x->{ + redisCountService.getCommonCount(ServiceType.RECOMMEND, + DomainType.BOARD, x.getId(), null); - if(x.getId()%2==0) { - redisCountService.getCommonCount(ServiceType.RECOMMEND, - DomainType.BOARD, x.getId(), null); - } - else{ - redisCountService.getCommonCount(ServiceType.RECOMMEND_CANCEL, - DomainType.BOARD, x.getId(), null); - } }); } finally { + SecurityContextHolder.clearContext(); countDownLatch.countDown(); } }); } countDownLatch.await(); List ids=redisService.getBoardRecommendRankPerDay(); - assertThat(ids.size()).isEqualTo(5); - ids.stream().forEach(x->{ - assertThat(x%2).isEqualTo(0); - }); + assertThat(ids.size()).isEqualTo(10); } + + } From 046cccefe8af86497b7df68450c266b699b473e7 Mon Sep 17 00:00:00 2001 From: dong3058 Date: Tue, 5 Aug 2025 16:38:02 +0900 Subject: [PATCH 15/15] fix: test --- .../java/org/myteam/server/redis/GetHotBoardZsetTest.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java index 2bd732ef..7fc1338a 100644 --- a/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java +++ b/src/test/java/org/myteam/server/redis/GetHotBoardZsetTest.java @@ -66,14 +66,6 @@ public class GetHotBoardZsetTest extends TestContainerSupport { private List boardList=new ArrayList<>(); - @AfterEach - void end(){ - memberActivityRepository.deleteAllInBatch(); - boardCountRepository.deleteAllInBatch(); - boardRepository.deleteAllInBatch(); - memberJpaRepository.deleteAllInBatch(); - } - @BeforeEach void setting(){