Skip to content

Commit

Permalink
[BE] FIX: 아이템 구매 통계 및 특정 기간동안 재화 사용량 반환 컨트롤러 AdminStatisticsControlle…
Browse files Browse the repository at this point in the history
…rV5로 이동 & 재화 사용량 반환 시 날짜 기준 정렬 추가
  • Loading branch information
chyo1 committed Jun 3, 2024
2 parents 588e839 + 3cb4a48 commit 290bda6
Show file tree
Hide file tree
Showing 13 changed files with 335 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
package org.ftclub.cabinet.admin.item.controller;

import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import org.ftclub.cabinet.admin.dto.AdminItemHistoryPaginationDto;
import org.ftclub.cabinet.admin.item.service.AdminItemFacadeService;
import org.ftclub.cabinet.admin.statistics.service.AdminStatisticsFacadeService;
import org.ftclub.cabinet.auth.domain.AuthGuard;
import org.ftclub.cabinet.auth.domain.AuthLevel;
import org.ftclub.cabinet.dto.CoinStaticsDto;
import org.ftclub.cabinet.dto.ItemAssignRequestDto;
import org.ftclub.cabinet.dto.ItemCreateDto;
import org.ftclub.cabinet.dto.ItemStatisticsDto;
import org.ftclub.cabinet.log.Logging;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/v5/admin/items")
Expand Down Expand Up @@ -60,25 +54,4 @@ public AdminItemHistoryPaginationDto getUserItemHistoryPagination(
@PathVariable(value = "userId") Long userId, Pageable pageable) {
return adminItemFacadeService.getUserItemHistories(userId, pageable);
}

/**
* 아이템별 구매 인원 조회
*
* @return
*/
@GetMapping("/statistics/items")
@AuthGuard(level = AuthLevel.ADMIN_ONLY)
public ItemStatisticsDto getItemPurchaseStatistics() {
return adminItemFacadeService.getItemPurchaseStatistics();
}

@GetMapping("/statistics/coins/use")
@AuthGuard(level = AuthLevel.ADMIN_ONLY)
public CoinStaticsDto getCoinStaticsDto(
@RequestParam("startDate") @DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime startDate,
@RequestParam("endDate") @DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime endDate) {
return adminStatisticsFacadeService.getCoinStaticsDto(startDate.toLocalDate(),
endDate.toLocalDate());

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.ftclub.cabinet.admin.statistics.controller;

import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import org.ftclub.cabinet.admin.item.service.AdminItemFacadeService;
import org.ftclub.cabinet.admin.statistics.service.AdminStatisticsFacadeService;
import org.ftclub.cabinet.auth.domain.AuthGuard;
import org.ftclub.cabinet.auth.domain.AuthLevel;
import org.ftclub.cabinet.dto.CoinCollectStatisticsDto;
import org.ftclub.cabinet.dto.CoinStaticsDto;
import org.ftclub.cabinet.dto.ItemStatisticsDto;
import org.ftclub.cabinet.dto.TotalCoinAmountDto;
import org.ftclub.cabinet.log.Logging;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/v5/admin/statistics")
@RequiredArgsConstructor
@Logging
public class AdminStatisticsControllerV5 {

private final AdminStatisticsFacadeService adminStatisticsFacadeService;
private final AdminItemFacadeService adminItemFacadeService;

/**
* 특정 연도, 월의 동전 줍기 횟수를 횟수 별로 통계를 내서 반환
*
* @param year
* @param month 조회를 원하는 기간
* @return
*/
@GetMapping("/coins/collect")
@AuthGuard(level = AuthLevel.ADMIN_ONLY)
public CoinCollectStatisticsDto getCoinCollectCountByMonth(
@RequestParam("year") Integer year,
@RequestParam("month") Integer month) {
return adminStatisticsFacadeService.getCoinCollectCountByMonth(year, month);
}

/**
* 전체 기간동안 동전의 발행량 및 사용량 반환
*
* @return
*/
@GetMapping("/coins")
@AuthGuard(level = AuthLevel.ADMIN_ONLY)
public TotalCoinAmountDto getTotalCoinAmount() {
return adminStatisticsFacadeService.getTotalCoinAmount();
}

/**
* 아이템별 구매 인원 조회
*
* @return
*/
@GetMapping("/items")
@AuthGuard(level = AuthLevel.ADMIN_ONLY)
public ItemStatisticsDto getItemPurchaseStatistics() {
return adminItemFacadeService.getItemPurchaseStatistics();
}

/**
* 특정 기간동안 재화 사용량 및 발행량 조회
*
* @param startDate
* @param endDate 조회를 원하는 기간
* @return
*/
@GetMapping("/coins/use")
@AuthGuard(level = AuthLevel.ADMIN_ONLY)
public CoinStaticsDto getCoinStaticsDto(
@RequestParam("startDate") @DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime startDate,
@RequestParam("endDate") @DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime endDate) {
return adminStatisticsFacadeService.getCoinStaticsDto(startDate.toLocalDate(),
endDate.toLocalDate());

}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package org.ftclub.cabinet.admin.statistics.service;

import static java.util.stream.Collectors.groupingBy;
import static org.ftclub.cabinet.cabinet.domain.CabinetStatus.AVAILABLE;
import static org.ftclub.cabinet.cabinet.domain.CabinetStatus.BROKEN;
import static org.ftclub.cabinet.cabinet.domain.CabinetStatus.FULL;
import static org.ftclub.cabinet.cabinet.domain.CabinetStatus.OVERDUE;
import static org.ftclub.cabinet.item.domain.Sku.COIN_COLLECT;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -18,15 +21,20 @@
import org.ftclub.cabinet.dto.BlockedUserPaginationDto;
import org.ftclub.cabinet.dto.CabinetFloorStatisticsResponseDto;
import org.ftclub.cabinet.dto.CoinAmountDto;
import org.ftclub.cabinet.dto.CoinCollectStatisticsDto;
import org.ftclub.cabinet.dto.CoinCollectedCountDto;
import org.ftclub.cabinet.dto.CoinStaticsDto;
import org.ftclub.cabinet.dto.LentsStatisticsResponseDto;
import org.ftclub.cabinet.dto.OverdueUserCabinetDto;
import org.ftclub.cabinet.dto.OverdueUserCabinetPaginationDto;
import org.ftclub.cabinet.dto.TotalCoinAmountDto;
import org.ftclub.cabinet.dto.UserBlockedInfoDto;
import org.ftclub.cabinet.exception.ExceptionStatus;
import org.ftclub.cabinet.exception.ServiceException;
import org.ftclub.cabinet.item.domain.ItemHistory;
import org.ftclub.cabinet.item.service.ItemHistoryQueryService;
import org.ftclub.cabinet.item.service.ItemQueryService;
import org.ftclub.cabinet.item.service.ItemRedisService;
import org.ftclub.cabinet.lent.domain.LentHistory;
import org.ftclub.cabinet.lent.service.LentQueryService;
import org.ftclub.cabinet.log.LogLevel;
Expand Down Expand Up @@ -59,7 +67,9 @@ public class AdminStatisticsFacadeService {
private final CabinetMapper cabinetMapper;
private final UserMapper userMapper;
private final ItemHistoryQueryService itemHistoryQueryService;
private final ItemQueryService itemQueryService;
private final ItemMapper itemMapper;
private final ItemRedisService itemRedisService;

/**
* 현재 가용중인 모든 사물함의 현황을 반환합니다.
Expand Down Expand Up @@ -127,6 +137,52 @@ public OverdueUserCabinetPaginationDto getOverdueUsers(Pageable pageable) {
return cabinetMapper.toOverdueUserCabinetPaginationDto(result, (long) lentHistories.size());
}

/**
* 특정 연도, 월의 동전 줍기 횟수를 횟수 별로 통계를 내서 반환
*
* @param year
* @param month 조회를 원하는 기간
* @return
*/
public CoinCollectStatisticsDto getCoinCollectCountByMonth(Integer year, Integer month) {
Long itemId = itemQueryService.getBySku(COIN_COLLECT).getId();
List<ItemHistory> coinCollectedInfoByMonth =
itemHistoryQueryService.getCoinCollectedInfoByMonth(itemId, year, month);
Map<Long, Long> coinCollectCountByUser = coinCollectedInfoByMonth.stream()
.collect(groupingBy(ItemHistory::getUserId, Collectors.counting()));

int[] coinCollectArray = new int[31];
coinCollectCountByUser.forEach((userId, coinCount) ->
coinCollectArray[coinCount.intValue() - 1]++);

List<CoinCollectedCountDto> coinCollectedCountDto = IntStream.rangeClosed(0,
30) // 1부터 30까지의 범위로 스트림 생성
.mapToObj(i -> new CoinCollectedCountDto(i + 1,
coinCollectArray[i])) // 각 인덱스와 해당하는 배열 값으로 CoinCollectedCountDto 생성
.collect(Collectors.toList()); // 리스트로 변환하여 반환

return new CoinCollectStatisticsDto(coinCollectedCountDto);
}

/**
* 전체 기간동안 동전의 발행량 및 사용량 반환
*
* @return
*/
public TotalCoinAmountDto getTotalCoinAmount() {
long totalCoinSupply = itemRedisService.getTotalCoinSupply();
long totalCoinUsage = itemRedisService.getTotalCoinUsage();

return new TotalCoinAmountDto(-1 * totalCoinUsage, totalCoinSupply);
}

/**
* 특정 기간동안 재화 사용량 및 발행량 조회
*
* @param startDate
* @param endDate 조회를 원하는 기간
* @return
*/
public CoinStaticsDto getCoinStaticsDto(LocalDate startDate, LocalDate endDate) {
Map<LocalDate, Long> issuedAmount = new LinkedHashMap<>();
Map<LocalDate, Long> usedAmount = new LinkedHashMap<>();
Expand Down Expand Up @@ -162,6 +218,7 @@ public CoinStaticsDto getCoinStaticsDto(LocalDate startDate, LocalDate endDate)
List<CoinAmountDto> convertMapToList(Map<LocalDate, Long> map) {
return map.entrySet().stream()
.map(entry -> itemMapper.toCoinAmountDto(entry.getKey(), entry.getValue()))
.sorted(Comparator.comparing(CoinAmountDto::getDate))
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ public LentHistoryPaginationDto getLentHistoryPagination(Long cabinetId, Pageabl
Page<LentHistory> lentHistories = lentQueryService.findCabinetLentHistoriesWithUserAndCabinet(
cabinetId, pageable);
List<LentHistoryDto> result = lentHistories.stream()
.sorted(Comparator.comparing(LentHistory::getStartedAt).reversed())
.map(lh -> lentMapper.toLentHistoryDto(lh, lh.getUser(), lh.getCabinet()))
.collect(Collectors.toList());
return lentMapper.toLentHistoryPaginationDto(result, lentHistories.getTotalElements());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.ftclub.cabinet.dto;

import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

@Getter
@ToString
@AllArgsConstructor
public class CoinCollectStatisticsDto {

private List<CoinCollectedCountDto> coinCollectStatistics;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.ftclub.cabinet.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

@Getter
@ToString
@AllArgsConstructor
public class CoinCollectedCountDto {

private Integer coinCount;
private Integer userCount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.ftclub.cabinet.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class TotalCoinAmountDto {

private Long used;
private Long unused;
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,32 +34,64 @@ public class ItemController {

private final ItemFacadeService itemFacadeService;

/**
* 전체 아이템 목록 조회
*
* @return
*/
@GetMapping("")
@AuthGuard(level = AuthLevel.USER_OR_ADMIN)
public ItemStoreResponseDto getAllItems() {
return itemFacadeService.getAllItems();
}

/**
* 특정 아이템 구매 요청
*
* @param user
* @param sku
*/
@PostMapping("/{sku}/purchase")
@AuthGuard(level = AuthLevel.USER_ONLY)
public void purchaseItem(@UserSession UserSessionDto user,
@PathVariable Sku sku) {
itemFacadeService.purchaseItem(user.getUserId(), sku);
}

/**
* 유저의 아이템 구매, 사용 내역 목록 조회
*
* @param user
* @param pageable
* @return
*/
@GetMapping("/history")
@AuthGuard(level = AuthLevel.USER_ONLY)
public ItemHistoryPaginationDto getItemHistory(@UserSession UserSessionDto user,
Pageable pageable) {
return itemFacadeService.getItemHistory(user.getUserId(), pageable);
}

/**
* 유저가 보유하고 있는 아이템 목록 조회
*
* @param user
* @return
*/
@GetMapping("/me")
@AuthGuard(level = AuthLevel.USER_ONLY)
public MyItemResponseDto getMyItems(@UserSession UserSessionDto user) {
return itemFacadeService.getMyItems(user);
}

/**
* 유저의 동전 줍기 내역 반환
*
* @param user
* @param type ALL, EARN, USE
* @param pageable
* @return
*/
@GetMapping("/coin/history")
@AuthGuard(level = AuthLevel.USER_ONLY)
public CoinHistoryPaginationDto getCoinHistory(@UserSession UserSessionDto user,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ Page<ItemHistory> findAllByUserIdOnMinusPriceItemsWithSubQuery(

List<ItemHistory> findAllByUserIdAndItemIdAndUsedAtIsNull(Long userId, Long itemId);


@Query("SELECT ih "
+ "FROM ItemHistory ih "
+ "WHERE ih.itemId = :itemId "
+ "AND YEAR(ih.purchaseAt) = :year "
+ "AND MONTH(ih.purchaseAt) = :month "
)
List<ItemHistory> findCoinCollectInfoByMonth(@Param("itemId") Long itemId,
@Param("year") Integer year, @Param("month") Integer month);

@Query("SELECT COUNT(ih) "
+ "FROM ItemHistory ih "
+ "WHERE ih.itemId = :itemId")
Expand Down
Loading

0 comments on commit 290bda6

Please sign in to comment.