This commit is contained in:
@@ -36,7 +36,8 @@ public class AdminUserController {
|
||||
private static final Set<String> SORTABLE_FIELDS = Set.of(
|
||||
"id", "screenName", "telegramId", "telegramName", "isPremium",
|
||||
"languageCode", "countryCode", "deviceCode", "dateReg", "dateLogin", "banned",
|
||||
"balanceA", "depositTotal", "withdrawTotal", "referralCount", "profit"
|
||||
"balanceA", "balanceB", "depositTotal", "withdrawTotal", "referralCount", "profit",
|
||||
"referrerTelegramName"
|
||||
);
|
||||
private static final Set<String> DEPOSIT_SORT_FIELDS = Set.of("id", "usdAmount", "status", "orderId", "createdAt", "completedAt");
|
||||
private static final Set<String> WITHDRAWAL_SORT_FIELDS = Set.of("id", "usdAmount", "cryptoName", "amountToSend", "txhash", "status", "paymentId", "createdAt", "resolvedAt");
|
||||
@@ -68,10 +69,12 @@ public class AdminUserController {
|
||||
@RequestParam(required = false) Integer referralLevel,
|
||||
@RequestParam(required = false) String ip,
|
||||
@RequestParam(required = false) Boolean botActive,
|
||||
@RequestParam(required = false) Integer depositCountMin) {
|
||||
@RequestParam(required = false) Integer depositCountMin,
|
||||
@RequestParam(required = false) Boolean hideSubAndBanned) {
|
||||
|
||||
// Build sort. Fields on UserB/UserD (balanceA, depositTotal, withdrawTotal, referralCount) are handled in service via custom query.
|
||||
Set<String> sortRequiresJoin = Set.of("balanceA", "depositTotal", "withdrawTotal", "referralCount", "profit");
|
||||
// Build sort. Fields on UserB/UserD (balanceA, balanceB, depositTotal, etc.) are handled in service via custom query.
|
||||
Set<String> sortRequiresJoin = Set.of(
|
||||
"balanceA", "balanceB", "depositTotal", "withdrawTotal", "referralCount", "profit", "referrerTelegramName");
|
||||
String effectiveSortBy = sortBy != null && sortBy.trim().isEmpty() ? null : (sortBy != null ? sortBy.trim() : null);
|
||||
if (effectiveSortBy != null && sortRequiresJoin.contains(effectiveSortBy)) {
|
||||
// Pass through; service will use custom ordered query
|
||||
@@ -113,7 +116,8 @@ public class AdminUserController {
|
||||
depositCountMin,
|
||||
effectiveSortBy,
|
||||
sortDir,
|
||||
excludeMasters
|
||||
excludeMasters,
|
||||
Boolean.TRUE.equals(hideSubAndBanned)
|
||||
);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
|
||||
@@ -27,6 +27,8 @@ public class AdminUserDetailDto {
|
||||
private Integer banned;
|
||||
/** IP address as string (e.g. xxx.xxx.xxx.xxx), converted from varbinary in DB. */
|
||||
private String ipAddress;
|
||||
/** Number of users sharing the same IP (including this user). */
|
||||
private Long ipAddressUserCount;
|
||||
|
||||
// Balance Info
|
||||
private Long balanceA;
|
||||
@@ -45,8 +47,10 @@ public class AdminUserDetailDto {
|
||||
// Referral Info
|
||||
private Integer referralCount;
|
||||
private Long totalCommissionsEarned;
|
||||
/** Total commissions earned in USD (converted from tickets). */
|
||||
/** Total commissions earned in USD (Honey: bigint / 10_000_000_000). */
|
||||
private java.math.BigDecimal totalCommissionsEarnedUsd;
|
||||
/** Sum of COMPLETED payment USD across referral levels 1–3 for this user. */
|
||||
private java.math.BigDecimal totalReferralDepositsUsd;
|
||||
private Integer masterId;
|
||||
private List<ReferralLevelDto> referralLevels;
|
||||
}
|
||||
|
||||
@@ -31,11 +31,21 @@ public class AdminUserDto {
|
||||
private Long totalCommissionsEarned; // Total commissions earned from referrals
|
||||
/** Profit in tickets (bigint): depositTotal - withdrawTotal */
|
||||
private Long profit;
|
||||
/** USD from db_users_b: depositTotal (tickets/1000) */
|
||||
/** USD from db_users_b deposit_total (Honey scale). */
|
||||
private BigDecimal depositTotalUsd;
|
||||
/** USD from db_users_b: withdrawTotal (tickets/1000) */
|
||||
/** USD from db_users_b withdraw_total (Honey scale). */
|
||||
private BigDecimal withdrawTotalUsd;
|
||||
/** USD from db_users_b: profit (tickets/1000) */
|
||||
/** USD from db_users_b: profit (Honey: bigint / 10_000_000_000). */
|
||||
private BigDecimal profitUsd;
|
||||
/** True when user has not blocked the bot. */
|
||||
private Boolean botActive;
|
||||
/** True when user has a session with created_at <= now and expires_at >= now. */
|
||||
private Boolean online;
|
||||
/** Direct referrer (db_users_d.referer_id_1), if any. */
|
||||
private Integer referrerId;
|
||||
/** Telegram name of direct referrer; "-" when absent. */
|
||||
private String referrerTelegramName;
|
||||
/** (1 - withdrawUsd/depositUsd) * 100 when depositUsd > 0; otherwise null. */
|
||||
private BigDecimal profitPercent;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,14 +12,16 @@ import java.math.BigDecimal;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ReferralLevelDto {
|
||||
private Integer level; // 1-5
|
||||
private Integer level; // 1–3 in admin UI; legacy rows may exist in DB
|
||||
private Integer refererId;
|
||||
private Integer referralCount;
|
||||
private Long commissionsEarned;
|
||||
private Long commissionsPaid;
|
||||
/** Commissions earned in USD (converted from tickets: 1000 tickets = 1 USD). */
|
||||
/** Commissions earned in USD (Honey: bigint / 10_000_000_000). */
|
||||
private BigDecimal commissionsEarnedUsd;
|
||||
/** Commissions paid in USD (converted from tickets). */
|
||||
/** Commissions paid in USD (Honey: bigint / 10_000_000_000). */
|
||||
private BigDecimal commissionsPaidUsd;
|
||||
/** Sum of COMPLETED payment USD from referrals at this level. */
|
||||
private BigDecimal depositsUsd;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,5 +99,15 @@ public interface PaymentRepository extends JpaRepository<Payment, Long>, JpaSpec
|
||||
@Param("start") Instant start,
|
||||
@Param("end") Instant end
|
||||
);
|
||||
|
||||
/** Sum COMPLETED payment USD for users whose level-1 referrer is {@code userId}. */
|
||||
@Query("SELECT COALESCE(SUM(p.usdAmount), 0) FROM Payment p, UserD d WHERE p.userId = d.id AND p.status = 'COMPLETED' AND p.usdAmount IS NOT NULL AND d.refererId1 = :userId")
|
||||
java.math.BigDecimal sumCompletedUsdForReferralsLevel1(@Param("userId") Integer userId);
|
||||
|
||||
@Query("SELECT COALESCE(SUM(p.usdAmount), 0) FROM Payment p, UserD d WHERE p.userId = d.id AND p.status = 'COMPLETED' AND p.usdAmount IS NOT NULL AND d.refererId2 = :userId")
|
||||
java.math.BigDecimal sumCompletedUsdForReferralsLevel2(@Param("userId") Integer userId);
|
||||
|
||||
@Query("SELECT COALESCE(SUM(p.usdAmount), 0) FROM Payment p, UserD d WHERE p.userId = d.id AND p.status = 'COMPLETED' AND p.usdAmount IS NOT NULL AND d.refererId3 = :userId")
|
||||
java.math.BigDecimal sumCompletedUsdForReferralsLevel3(@Param("userId") Integer userId);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,10 @@ import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@Repository
|
||||
public interface SessionRepository extends JpaRepository<Session, Long> {
|
||||
@@ -46,6 +48,13 @@ public interface SessionRepository extends JpaRepository<Session, Long> {
|
||||
* Returns the number of deleted rows.
|
||||
* Note: MySQL requires LIMIT to be a literal or bound parameter, so we use a native query.
|
||||
*/
|
||||
/**
|
||||
* User IDs in {@code userIds} that have at least one session valid at {@code now}
|
||||
* ({@code created_at <= now} and {@code expires_at >= now}).
|
||||
*/
|
||||
@Query("SELECT DISTINCT s.userId FROM Session s WHERE s.userId IN :userIds AND s.createdAt <= :now AND s.expiresAt >= :now")
|
||||
Set<Integer> findOnlineUserIdsAmong(@Param("userIds") Collection<Integer> userIds, @Param("now") LocalDateTime now);
|
||||
|
||||
@Modifying(clearAutomatically = true, flushAutomatically = true)
|
||||
@Query(value = "DELETE FROM sessions WHERE expires_at < :now LIMIT :batchSize", nativeQuery = true)
|
||||
int deleteExpiredSessionsBatch(@Param("now") LocalDateTime now, @Param("batchSize") int batchSize);
|
||||
|
||||
@@ -60,6 +60,10 @@ public interface UserARepository extends JpaRepository<UserA, Integer>, JpaSpeci
|
||||
*/
|
||||
@Query("SELECT u FROM UserA u WHERE u.id >= :fromId AND u.id <= :toId AND u.botActive = true ORDER BY u.id")
|
||||
Page<UserA> findByIdBetweenAndBotActiveTrue(@Param("fromId") int fromId, @Param("toId") int toId, Pageable pageable);
|
||||
|
||||
/** Count users sharing the same IP (varbinary); returns 0 if {@code ip} is null. */
|
||||
@Query("SELECT COUNT(u) FROM UserA u WHERE u.ip IS NOT NULL AND u.ip = :ip")
|
||||
long countByIpEqual(@Param("ip") byte[] ip);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class AdminMasterService {
|
||||
|
||||
private static final BigDecimal USD_DIVISOR = new BigDecimal("1000000000");
|
||||
/** Honey admin: balance bigint → USD (same scale as AdminUserService). */
|
||||
private static final BigDecimal USD_DIVISOR = new BigDecimal("10000000000");
|
||||
|
||||
private final UserDRepository userDRepository;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import jakarta.persistence.criteria.Subquery;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -36,7 +37,10 @@ public class AdminUserService {
|
||||
|
||||
private static final long TICKETS_MULTIPLIER = 1_000_000L;
|
||||
|
||||
private static final BigDecimal TICKETS_TO_USD = new BigDecimal("0.001"); // 1000 tickets = 1 USD
|
||||
/**
|
||||
* Honey: display balance = DB bigint / 1_000_000; 1 USD = 10_000 display units → USD = DB / 10_000_000_000.
|
||||
*/
|
||||
private static final BigDecimal HONEY_DB_UNITS_PER_USD = new BigDecimal("10000000000");
|
||||
|
||||
private final UserARepository userARepository;
|
||||
private final UserBRepository userBRepository;
|
||||
@@ -46,6 +50,7 @@ public class AdminUserService {
|
||||
private final PayoutRepository payoutRepository;
|
||||
private final UserTaskClaimRepository userTaskClaimRepository;
|
||||
private final TaskRepository taskRepository;
|
||||
private final SessionRepository sessionRepository;
|
||||
private final EntityManager entityManager;
|
||||
|
||||
public Page<AdminUserDto> getUsers(
|
||||
@@ -69,7 +74,8 @@ public class AdminUserService {
|
||||
Integer depositCountMin,
|
||||
String sortBy,
|
||||
String sortDir,
|
||||
boolean excludeMasters) {
|
||||
boolean excludeMasters,
|
||||
Boolean hideSubAndBanned) {
|
||||
|
||||
List<Integer> masterIds = excludeMasters ? userDRepository.findMasterUserIds() : List.of();
|
||||
|
||||
@@ -195,10 +201,22 @@ public class AdminUserService {
|
||||
predicates.add(cb.in(root.get("id")).value(subDep));
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(hideSubAndBanned)) {
|
||||
predicates.add(cb.equal(root.get("banned"), 0));
|
||||
Subquery<Integer> subMasterSelf = query.subquery(Integer.class);
|
||||
Root<UserD> dm = subMasterSelf.from(UserD.class);
|
||||
subMasterSelf.select(dm.get("id"));
|
||||
subMasterSelf.where(cb.and(
|
||||
cb.equal(dm.get("id"), dm.get("masterId")),
|
||||
cb.gt(dm.get("masterId"), 0)));
|
||||
predicates.add(cb.not(root.get("id").in(subMasterSelf)));
|
||||
}
|
||||
|
||||
return cb.and(predicates.toArray(new Predicate[0]));
|
||||
};
|
||||
|
||||
Set<String> sortRequiresJoin = Set.of("balanceA", "balanceB", "depositTotal", "withdrawTotal", "referralCount", "profit");
|
||||
Set<String> sortRequiresJoin = Set.of(
|
||||
"balanceA", "balanceB", "depositTotal", "withdrawTotal", "referralCount", "profit", "referrerTelegramName");
|
||||
boolean useJoinSort = sortBy != null && sortRequiresJoin.contains(sortBy);
|
||||
List<UserA> userList;
|
||||
long totalElements;
|
||||
@@ -210,6 +228,7 @@ public class AdminUserService {
|
||||
referralCountMin, referralCountMax,
|
||||
referrerId, referralLevel, ipFilter,
|
||||
botActive, depositCountMin,
|
||||
hideSubAndBanned,
|
||||
sortBy, sortDir != null ? sortDir : "desc",
|
||||
pageable.getPageSize(), (int) pageable.getOffset(),
|
||||
masterIds);
|
||||
@@ -236,6 +255,20 @@ public class AdminUserService {
|
||||
Map<Integer, UserD> userDMap = userDRepository.findAllById(userIds).stream()
|
||||
.collect(Collectors.toMap(UserD::getId, ud -> ud));
|
||||
|
||||
LocalDateTime sessionNow = LocalDateTime.now();
|
||||
Set<Integer> onlineIds = userIds.isEmpty()
|
||||
? Set.of()
|
||||
: sessionRepository.findOnlineUserIdsAmong(userIds, sessionNow);
|
||||
|
||||
Set<Integer> refererIds = userDMap.values().stream()
|
||||
.map(UserD::getRefererId1)
|
||||
.filter(id -> id != null && id > 0)
|
||||
.collect(Collectors.toSet());
|
||||
Map<Integer, UserA> referrersById = refererIds.isEmpty()
|
||||
? Map.of()
|
||||
: userARepository.findAllById(refererIds).stream()
|
||||
.collect(Collectors.toMap(UserA::getId, u -> u));
|
||||
|
||||
// Map to DTOs (filtering is done in DB via specification subqueries)
|
||||
List<AdminUserDto> pageContent = userList.stream()
|
||||
.map(userA -> {
|
||||
@@ -273,6 +306,21 @@ public class AdminUserService {
|
||||
BigDecimal depositTotalUsd = ticketsToUsd(userB.getDepositTotal());
|
||||
BigDecimal withdrawTotalUsd = ticketsToUsd(userB.getWithdrawTotal());
|
||||
BigDecimal profitUsd = ticketsToUsd(profit);
|
||||
BigDecimal profitPercent = computeProfitPercent(depositTotalUsd, withdrawTotalUsd);
|
||||
|
||||
Integer referrerIdVal = null;
|
||||
String referrerTelegramNameVal = null;
|
||||
int rid = userD.getRefererId1();
|
||||
if (rid > 0) {
|
||||
referrerIdVal = rid;
|
||||
UserA refA = referrersById.get(rid);
|
||||
String tn = refA != null ? refA.getTelegramName() : null;
|
||||
if (tn == null || tn.isBlank() || "-".equals(tn)) {
|
||||
referrerTelegramNameVal = "-";
|
||||
} else {
|
||||
referrerTelegramNameVal = tn;
|
||||
}
|
||||
}
|
||||
|
||||
return AdminUserDto.builder()
|
||||
.id(userA.getId())
|
||||
@@ -296,6 +344,11 @@ public class AdminUserService {
|
||||
.depositTotalUsd(depositTotalUsd)
|
||||
.withdrawTotalUsd(withdrawTotalUsd)
|
||||
.profitUsd(profitUsd)
|
||||
.profitPercent(profitPercent)
|
||||
.botActive(userA.isBotActive())
|
||||
.online(onlineIds.contains(userA.getId()))
|
||||
.referrerId(referrerIdVal)
|
||||
.referrerTelegramName(referrerTelegramNameVal)
|
||||
.build();
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
@@ -325,6 +378,7 @@ public class AdminUserService {
|
||||
String ipFilter,
|
||||
Boolean botActive,
|
||||
Integer depositCountMin,
|
||||
Boolean hideSubAndBanned,
|
||||
String sortBy,
|
||||
String sortDir,
|
||||
int limit,
|
||||
@@ -333,7 +387,8 @@ public class AdminUserService {
|
||||
StringBuilder sql = new StringBuilder(
|
||||
"SELECT a.id FROM db_users_a a " +
|
||||
"INNER JOIN db_users_b b ON a.id = b.id " +
|
||||
"INNER JOIN db_users_d d ON a.id = d.id WHERE 1=1");
|
||||
"INNER JOIN db_users_d d ON a.id = d.id " +
|
||||
"LEFT JOIN db_users_a ref ON d.referer_id_1 = ref.id WHERE 1=1");
|
||||
List<Object> params = new ArrayList<>();
|
||||
int paramIndex = 1;
|
||||
|
||||
@@ -451,6 +506,10 @@ public class AdminUserService {
|
||||
params.add(depositCountMin);
|
||||
paramIndex++;
|
||||
}
|
||||
if (Boolean.TRUE.equals(hideSubAndBanned)) {
|
||||
sql.append(" AND a.banned = 0");
|
||||
sql.append(" AND NOT (d.id = d.master_id AND d.master_id > 0)");
|
||||
}
|
||||
|
||||
String orderColumn = switch (sortBy != null ? sortBy : "") {
|
||||
case "balanceA" -> "b.balance_a";
|
||||
@@ -459,6 +518,7 @@ public class AdminUserService {
|
||||
case "withdrawTotal" -> "b.withdraw_total";
|
||||
case "referralCount" -> "(d.referals_1 + d.referals_2 + d.referals_3 + d.referals_4 + d.referals_5)";
|
||||
case "profit" -> "(b.deposit_total - b.withdraw_total)";
|
||||
case "referrerTelegramName" -> "ref.telegram_name";
|
||||
default -> "a.id";
|
||||
};
|
||||
String direction = "asc".equalsIgnoreCase(sortDir) ? " ASC" : " DESC";
|
||||
@@ -551,41 +611,47 @@ public class AdminUserService {
|
||||
long totalCommissions = userD.getFromReferals1() + userD.getFromReferals2() +
|
||||
userD.getFromReferals3() + userD.getFromReferals4() + userD.getFromReferals5();
|
||||
|
||||
// Build referral levels
|
||||
BigDecimal refDep1 = paymentRepository.sumCompletedUsdForReferralsLevel1(userId);
|
||||
BigDecimal refDep2 = paymentRepository.sumCompletedUsdForReferralsLevel2(userId);
|
||||
BigDecimal refDep3 = paymentRepository.sumCompletedUsdForReferralsLevel3(userId);
|
||||
if (refDep1 == null) refDep1 = BigDecimal.ZERO;
|
||||
if (refDep2 == null) refDep2 = BigDecimal.ZERO;
|
||||
if (refDep3 == null) refDep3 = BigDecimal.ZERO;
|
||||
BigDecimal totalReferralDepositsUsd = refDep1.add(refDep2).add(refDep3);
|
||||
|
||||
// Build referral levels (admin shows 1–3 only)
|
||||
List<ReferralLevelDto> referralLevels = new ArrayList<>();
|
||||
for (int level = 1; level <= 5; level++) {
|
||||
for (int level = 1; level <= 3; level++) {
|
||||
int refererId = switch (level) {
|
||||
case 1 -> userD.getRefererId1();
|
||||
case 2 -> userD.getRefererId2();
|
||||
case 3 -> userD.getRefererId3();
|
||||
case 4 -> userD.getRefererId4();
|
||||
case 5 -> userD.getRefererId5();
|
||||
default -> 0;
|
||||
};
|
||||
int referralCount = switch (level) {
|
||||
case 1 -> userD.getReferals1();
|
||||
case 2 -> userD.getReferals2();
|
||||
case 3 -> userD.getReferals3();
|
||||
case 4 -> userD.getReferals4();
|
||||
case 5 -> userD.getReferals5();
|
||||
default -> 0;
|
||||
};
|
||||
long commissionsEarned = switch (level) {
|
||||
case 1 -> userD.getFromReferals1();
|
||||
case 2 -> userD.getFromReferals2();
|
||||
case 3 -> userD.getFromReferals3();
|
||||
case 4 -> userD.getFromReferals4();
|
||||
case 5 -> userD.getFromReferals5();
|
||||
default -> 0L;
|
||||
};
|
||||
long commissionsPaid = switch (level) {
|
||||
case 1 -> userD.getToReferer1();
|
||||
case 2 -> userD.getToReferer2();
|
||||
case 3 -> userD.getToReferer3();
|
||||
case 4 -> userD.getToReferer4();
|
||||
case 5 -> userD.getToReferer5();
|
||||
default -> 0L;
|
||||
};
|
||||
BigDecimal depositsUsd = switch (level) {
|
||||
case 1 -> refDep1;
|
||||
case 2 -> refDep2;
|
||||
case 3 -> refDep3;
|
||||
default -> BigDecimal.ZERO;
|
||||
};
|
||||
|
||||
referralLevels.add(ReferralLevelDto.builder()
|
||||
.level(level)
|
||||
@@ -595,6 +661,7 @@ public class AdminUserService {
|
||||
.commissionsPaid(commissionsPaid)
|
||||
.commissionsEarnedUsd(ticketsToUsd(commissionsEarned))
|
||||
.commissionsPaidUsd(ticketsToUsd(commissionsPaid))
|
||||
.depositsUsd(depositsUsd)
|
||||
.build());
|
||||
}
|
||||
|
||||
@@ -602,6 +669,11 @@ public class AdminUserService {
|
||||
BigDecimal withdrawTotalUsd = ticketsToUsd(userB.getWithdrawTotal());
|
||||
BigDecimal totalCommissionsEarnedUsd = ticketsToUsd(totalCommissions);
|
||||
|
||||
long ipAddressUserCount = 0L;
|
||||
if (userA.getIp() != null) {
|
||||
ipAddressUserCount = userARepository.countByIpEqual(userA.getIp());
|
||||
}
|
||||
|
||||
return AdminUserDetailDto.builder()
|
||||
.id(userA.getId())
|
||||
.screenName(userA.getScreenName())
|
||||
@@ -616,6 +688,7 @@ public class AdminUserService {
|
||||
.dateLogin(userA.getDateLogin())
|
||||
.banned(userA.getBanned())
|
||||
.ipAddress(IpUtils.bytesToIp(userA.getIp()))
|
||||
.ipAddressUserCount(ipAddressUserCount)
|
||||
.balanceA(userB.getBalanceA())
|
||||
.balanceB(userB.getBalanceB())
|
||||
.depositTotal(userB.getDepositTotal())
|
||||
@@ -628,6 +701,7 @@ public class AdminUserService {
|
||||
.referralCount(totalReferrals)
|
||||
.totalCommissionsEarned(totalCommissions)
|
||||
.totalCommissionsEarnedUsd(totalCommissionsEarnedUsd)
|
||||
.totalReferralDepositsUsd(totalReferralDepositsUsd)
|
||||
.masterId(userD.getMasterId() > 0 ? userD.getMasterId() : null)
|
||||
.referralLevels(referralLevels)
|
||||
.build();
|
||||
@@ -635,7 +709,20 @@ public class AdminUserService {
|
||||
|
||||
private static BigDecimal ticketsToUsd(long ticketsBigint) {
|
||||
if (ticketsBigint == 0) return BigDecimal.ZERO;
|
||||
return BigDecimal.valueOf(ticketsBigint).divide(BigDecimal.valueOf(1_000_000L), 6, RoundingMode.HALF_UP).multiply(TICKETS_TO_USD).setScale(2, RoundingMode.HALF_UP);
|
||||
return BigDecimal.valueOf(ticketsBigint)
|
||||
.divide(HONEY_DB_UNITS_PER_USD, 8, RoundingMode.HALF_UP)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private static BigDecimal computeProfitPercent(BigDecimal depositUsd, BigDecimal withdrawUsd) {
|
||||
if (depositUsd == null || depositUsd.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return null;
|
||||
}
|
||||
BigDecimal w = withdrawUsd != null ? withdrawUsd : BigDecimal.ZERO;
|
||||
return BigDecimal.ONE
|
||||
.subtract(w.divide(depositUsd, 8, RoundingMode.HALF_UP))
|
||||
.multiply(BigDecimal.valueOf(100))
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
public Page<AdminTransactionDto> getUserTransactions(Integer userId, Pageable pageable) {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Speed up admin "online" batch lookup: sessions active at a point in time by user_id
|
||||
CREATE INDEX idx_sessions_user_expires ON sessions (user_id, expires_at);
|
||||
Reference in New Issue
Block a user