This commit is contained in:
@@ -45,7 +45,8 @@ public class HandlerConfig {
|
||||
StatisticProtectedFilesHandler statisticProtectedFilesHandler,
|
||||
StatisticViolationHandler statisticViolationHandler,
|
||||
StatisticSubscriberHandler statisticSubscriberHandler,
|
||||
StatisticTokenHandler statisticTokenHandler
|
||||
StatisticTokenHandler statisticTokenHandler,
|
||||
StatisticIncomeHandler statisticIncomeHandler
|
||||
|
||||
) {
|
||||
Map<Integer, RequestHandler> map = new HashMap<>();
|
||||
@@ -83,6 +84,7 @@ public class HandlerConfig {
|
||||
map.put(30023, statisticViolationHandler);
|
||||
map.put(30024, statisticSubscriberHandler);
|
||||
map.put(30025, statisticTokenHandler);
|
||||
map.put(30026, statisticIncomeHandler);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package ru.soune.nocopy.dto.statistic;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class IncomeStatisticRequest {
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package ru.soune.nocopy.dto.statistic;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class IncomeStatisticResponse {
|
||||
|
||||
@JsonProperty("total_income")
|
||||
private Long totalIncome;
|
||||
|
||||
@JsonProperty("total_available")
|
||||
private Long totalAvailable;
|
||||
|
||||
@JsonProperty("total_hold")
|
||||
private Long totalHold;
|
||||
|
||||
@JsonProperty("income_per_user")
|
||||
private Percentiles incomePerUser;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class Percentiles {
|
||||
@JsonProperty("p5")
|
||||
private Long p5;
|
||||
|
||||
@JsonProperty("p50")
|
||||
private Long p50;
|
||||
|
||||
@JsonProperty("p95")
|
||||
private Long p95;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package ru.soune.nocopy.handler;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.soune.nocopy.dto.BaseRequest;
|
||||
import ru.soune.nocopy.dto.BaseResponse;
|
||||
import ru.soune.nocopy.dto.MessageCode;
|
||||
import ru.soune.nocopy.dto.statistic.IncomeStatisticResponse;
|
||||
import ru.soune.nocopy.service.statistic.IncomeStatisticService;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class StatisticIncomeHandler implements RequestHandler {
|
||||
|
||||
private final IncomeStatisticService statisticService;
|
||||
|
||||
@Override
|
||||
public BaseResponse handle(BaseRequest request) throws Exception {
|
||||
IncomeStatisticResponse statistics = statisticService.getIncomeStatistics();
|
||||
|
||||
return new BaseResponse(
|
||||
request.getMsgId(),
|
||||
MessageCode.SUCCESS.getCode(),
|
||||
MessageCode.SUCCESS.getDescription(),
|
||||
statistics
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -43,4 +43,22 @@ public interface ReferralJpaRepository extends JpaRepository<Referral, Long> {
|
||||
|
||||
@Query("SELECT COUNT(r) FROM Referral r WHERE r.inviterId = :userId")
|
||||
int countTotalInvitees(@Param("userId") Long userId);
|
||||
|
||||
@Query("SELECT COALESCE(SUM(r.totalIncome), 0) FROM Referral r")
|
||||
Long getTotalIncome();
|
||||
|
||||
@Query("SELECT COALESCE(SUM(r.availableIncome), 0) FROM Referral r")
|
||||
Long getTotalAvailableIncome();
|
||||
|
||||
@Query("SELECT COALESCE(SUM(r.holdBalance), 0) FROM Referral r")
|
||||
Long getTotalHoldBalance();
|
||||
|
||||
@Query("""
|
||||
SELECT
|
||||
r.userId,
|
||||
r.totalIncome
|
||||
FROM Referral r
|
||||
WHERE r.totalIncome > 0
|
||||
""")
|
||||
List<Object[]> getIncomePerUser();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package ru.soune.nocopy.service.statistic;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.soune.nocopy.dto.statistic.IncomeStatisticResponse;
|
||||
import ru.soune.nocopy.repository.ReferralJpaRepository;
|
||||
import ru.soune.nocopy.util.PercentileCalculator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class IncomeStatisticService {
|
||||
private final ReferralJpaRepository referralRepository;
|
||||
|
||||
private static final int PERCENTILE_5 = 5;
|
||||
|
||||
private static final int PERCENTILE_50 = 50;
|
||||
|
||||
private static final int PERCENTILE_95 = 95;
|
||||
|
||||
public IncomeStatisticResponse getIncomeStatistics() {
|
||||
Long totalIncome = referralRepository.getTotalIncome();
|
||||
Long totalAvailable = referralRepository.getTotalAvailableIncome();
|
||||
Long totalHold = referralRepository.getTotalHoldBalance();
|
||||
|
||||
List<Object[]> incomeData = referralRepository.getIncomePerUser();
|
||||
List<Long> incomeValues = extractIncomeValues(incomeData);
|
||||
|
||||
PercentileCalculator.PercentilesResult incomePercentiles =
|
||||
PercentileCalculator.calculatePercentiles(incomeValues, PERCENTILE_5, PERCENTILE_50,
|
||||
PERCENTILE_95);
|
||||
|
||||
return IncomeStatisticResponse.builder()
|
||||
.totalIncome(totalIncome != null ? totalIncome : 0L)
|
||||
.totalAvailable(totalAvailable != null ? totalAvailable : 0L)
|
||||
.totalHold(totalHold != null ? totalHold : 0L)
|
||||
.incomePerUser(new IncomeStatisticResponse.Percentiles(
|
||||
incomePercentiles.getP5() != null ? incomePercentiles.getP5() : 0L,
|
||||
incomePercentiles.getP50() != null ? incomePercentiles.getP50() : 0L,
|
||||
incomePercentiles.getP95() != null ? incomePercentiles.getP95() : 0L
|
||||
))
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<Long> extractIncomeValues(List<Object[]> data) {
|
||||
return data.stream()
|
||||
.map(row -> row[1] != null ? ((Number) row[1]).longValue() : 0L)
|
||||
.filter(value -> value > 0)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user