bigint conversion fixes
All checks were successful
Deploy to VPS / deploy (push) Successful in 1m18s

This commit is contained in:
Tihon
2026-03-12 14:21:37 +02:00
parent fb92993e39
commit bd260497f9
7 changed files with 51 additions and 27 deletions

View File

@@ -43,8 +43,8 @@ public class OpenApiExamplesCustomizer implements GlobalOpenApiCustomizer {
value.put("screenName", "The Boy");
value.put("dateReg", 1772897273);
value.put("ip", "165.165.165.165");
value.put("balanceA", 100000);
value.put("balanceB", 100000);
value.put("balanceA", 10000);
value.put("balanceB", 10000);
value.put("avatarUrl", "/avatars/0/0/1/06c98267.png?v=1772897273");
value.put("languageCode", "EN");
value.put("paymentEnabled", true);

View File

@@ -24,6 +24,9 @@ import org.springframework.web.bind.annotation.*;
@RequiredArgsConstructor
public class UserController {
/** Divisor for converting balance bigint to display value (backend sends display value only). */
private static final double BALANCE_DISPLAY_DIVISOR = 1_000_000.0;
private final UserService userService;
private final UserBRepository userBRepository;
private final AvatarService avatarService;
@@ -37,10 +40,12 @@ public class UserController {
// Convert IP from byte[] to string for display
String ipAddress = IpUtils.bytesToIp(user.getIp());
// Get balances from UserB
// Get balances from UserB; convert to display value (divide by 1_000_000)
var userBOpt = userBRepository.findById(user.getId());
Long balanceA = userBOpt.map(UserB::getBalanceA).orElse(0L);
Long balanceB = userBOpt.map(UserB::getBalanceB).orElse(0L);
long rawBalanceA = userBOpt.map(UserB::getBalanceA).orElse(0L);
long rawBalanceB = userBOpt.map(UserB::getBalanceB).orElse(0L);
Double balanceA = rawBalanceA / BALANCE_DISPLAY_DIVISOR;
Double balanceB = rawBalanceB / BALANCE_DISPLAY_DIVISOR;
Integer depositCount = userBOpt.map(UserB::getDepositCount).orElse(0);
// Generate avatar URL on-the-fly (deterministic from userId)
@@ -126,7 +131,6 @@ public class UserController {
UserA user = UserContext.get();
Page<ReferralDto> referralsPage = userService.getReferrals(user.getId(), level, page);
return new ReferralsResponse(
referralsPage.getContent(),
referralsPage.getNumber(),

View File

@@ -5,13 +5,14 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/** API response DTO for referral list. Built from {@link ReferralProjection} in service. */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ReferralDto {
private String name; // screen_name from db_users_a
private Long commission; // to_referer_1/2/3 from db_users_d (bigint, needs to be divided by 1,000,000 on frontend)
private String name;
private Double commission; // display value (raw from DB / 1_000_000)
}

View File

@@ -0,0 +1,10 @@
package com.honey.honey.dto;
/**
* Persistence/read model: raw referral row from DB (used only between repository and service).
* Not sent to frontend. Map to {@link ReferralDto} for API response.
*/
public interface ReferralProjection {
String getName();
Long getCommission();
}

View File

@@ -16,8 +16,8 @@ public class UserDto {
private String screenName; // User's screen name
private Integer dateReg; // Registration date (Unix timestamp in seconds)
private String ip;
private Long balanceA; // Balance (stored as bigint, represents number with 6 decimal places)
private Long balanceB; // Second balance (stored as bigint)
private Double balanceA; // Balance for display (raw bigint / 1_000_000)
private Double balanceB; // Second balance for display (raw bigint / 1_000_000)
private String avatarUrl; // Public URL of user's avatar
private String languageCode; // User's language preference (EN, RU, DE, IT, NL, PL, FR, ES, ID, TR)
private Boolean paymentEnabled; // Runtime toggle: deposits (Store, Payment Options, etc.) allowed

View File

@@ -1,6 +1,6 @@
package com.honey.honey.repository;
import com.honey.honey.dto.ReferralDto;
import com.honey.honey.dto.ReferralProjection;
import com.honey.honey.model.UserD;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@@ -52,36 +52,33 @@ public interface UserDRepository extends JpaRepository<UserD, Integer> {
/**
* Finds referrals for level 1 (where referer_id_1 = userId).
* Returns referrals with their screen_name and to_referer_1 commission.
* Ordered by commission DESC, then id DESC.
* Returns raw rows (name, commission bigint). Map to ReferralDto in service.
*/
@Query("SELECT new com.honey.honey.dto.ReferralDto(ud.screenName, ud.toReferer1) " +
@Query("SELECT ud.screenName as name, ud.toReferer1 as commission " +
"FROM UserD ud " +
"WHERE ud.refererId1 = :userId AND ud.refererId1 > 0 " +
"ORDER BY ud.toReferer1 DESC, ud.id DESC")
Page<ReferralDto> findReferralsLevel1(@Param("userId") Integer userId, Pageable pageable);
Page<ReferralProjection> findReferralsLevel1(@Param("userId") Integer userId, Pageable pageable);
/**
* Finds referrals for level 2 (where referer_id_2 = userId).
* Returns referrals with their screen_name and to_referer_2 commission.
* Ordered by commission DESC, then id DESC.
* Returns raw rows (name, commission bigint). Map to ReferralDto in service.
*/
@Query("SELECT new com.honey.honey.dto.ReferralDto(ud.screenName, ud.toReferer2) " +
@Query("SELECT ud.screenName as name, ud.toReferer2 as commission " +
"FROM UserD ud " +
"WHERE ud.refererId2 = :userId AND ud.refererId2 > 0 " +
"ORDER BY ud.toReferer2 DESC, ud.id DESC")
Page<ReferralDto> findReferralsLevel2(@Param("userId") Integer userId, Pageable pageable);
Page<ReferralProjection> findReferralsLevel2(@Param("userId") Integer userId, Pageable pageable);
/**
* Finds referrals for level 3 (where referer_id_3 = userId).
* Returns referrals with their screen_name and to_referer_3 commission.
* Ordered by commission DESC, then id DESC.
* Returns raw rows (name, commission bigint). Map to ReferralDto in service.
*/
@Query("SELECT new com.honey.honey.dto.ReferralDto(ud.screenName, ud.toReferer3) " +
@Query("SELECT ud.screenName as name, ud.toReferer3 as commission " +
"FROM UserD ud " +
"WHERE ud.refererId3 = :userId AND ud.refererId3 > 0 " +
"ORDER BY ud.toReferer3 DESC, ud.id DESC")
Page<ReferralDto> findReferralsLevel3(@Param("userId") Integer userId, Pageable pageable);
Page<ReferralProjection> findReferralsLevel3(@Param("userId") Integer userId, Pageable pageable);
/**
* Masters: users whose id equals their master_id (and master_id > 0).

View File

@@ -1,6 +1,7 @@
package com.honey.honey.service;
import com.honey.honey.dto.ReferralDto;
import com.honey.honey.dto.ReferralProjection;
import com.honey.honey.model.UserA;
import com.honey.honey.model.UserB;
import com.honey.honey.model.UserD;
@@ -13,13 +14,16 @@ import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* Service for user management with sharded tables.
@@ -453,25 +457,33 @@ public class UserService {
return userARepository.findByTelegramId(telegramId);
}
private static final double COMMISSION_DISPLAY_DIVISOR = 1_000_000.0;
/**
* Gets referrals for a specific level with pagination.
* Returns 10 results per page, ordered by commission DESC, then id DESC.
* Fetches raw rows (ReferralProjection), maps to API DTO (ReferralDto) with display commission.
*
* @param userId The user ID to get referrals for
* @param level The referral level (1, 2, or 3)
* @param page Page number (0-indexed)
* @return Page of referrals with name and commission
* @return Page of ReferralDto (name, commission as display value)
*/
public Page<ReferralDto> getReferrals(Integer userId, Integer level, Integer page) {
Pageable pageable = PageRequest.of(page, 10);
return switch (level) {
Page<ReferralProjection> projectionPage = switch (level) {
case 1 -> userDRepository.findReferralsLevel1(userId, pageable);
case 2 -> userDRepository.findReferralsLevel2(userId, pageable);
case 3 -> userDRepository.findReferralsLevel3(userId, pageable);
default -> throw new IllegalArgumentException(
localizationService.getMessage("user.error.referralLevelInvalid", String.valueOf(level)));
};
List<ReferralDto> content = projectionPage.getContent().stream()
.map(p -> ReferralDto.builder()
.name(p.getName())
.commission(p.getCommission() != null ? p.getCommission() / COMMISSION_DISPLAY_DIVISOR : 0.0)
.build())
.collect(Collectors.toList());
return new PageImpl<>(content, projectionPage.getPageable(), projectionPage.getTotalElements());
}
}