dev add statistic files protected
Test Workflow / test (push) Successful in 2s

This commit is contained in:
vladp
2026-04-16 01:08:40 +07:00
parent bbf8e3ee3d
commit 74f9be8bf7
6 changed files with 152 additions and 1 deletions
@@ -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());
}
}