diff --git a/src/main/java/com/honey/honey/controller/AdminUserController.java b/src/main/java/com/honey/honey/controller/AdminUserController.java index 3f0a676..0dee8b5 100644 --- a/src/main/java/com/honey/honey/controller/AdminUserController.java +++ b/src/main/java/com/honey/honey/controller/AdminUserController.java @@ -37,7 +37,7 @@ public class AdminUserController { "id", "screenName", "telegramId", "telegramName", "isPremium", "languageCode", "countryCode", "deviceCode", "dateReg", "dateLogin", "banned", "balanceA", "balanceB", "depositTotal", "withdrawTotal", "referralCount", "profit", - "referrerTelegramName" + "referrerTelegramName", "profitPercent" ); private static final Set DEPOSIT_SORT_FIELDS = Set.of("id", "usdAmount", "status", "orderId", "createdAt", "completedAt"); private static final Set WITHDRAWAL_SORT_FIELDS = Set.of("id", "usdAmount", "cryptoName", "amountToSend", "txhash", "status", "paymentId", "createdAt", "resolvedAt"); @@ -74,7 +74,8 @@ public class AdminUserController { // Build sort. Fields on UserB/UserD (balanceA, balanceB, depositTotal, etc.) are handled in service via custom query. Set sortRequiresJoin = Set.of( - "balanceA", "balanceB", "depositTotal", "withdrawTotal", "referralCount", "profit", "referrerTelegramName"); + "balanceA", "balanceB", "depositTotal", "withdrawTotal", "referralCount", "profit", + "referrerTelegramName", "profitPercent"); 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 diff --git a/src/main/java/com/honey/honey/service/AdminUserService.java b/src/main/java/com/honey/honey/service/AdminUserService.java index fcdcb19..3e87411 100644 --- a/src/main/java/com/honey/honey/service/AdminUserService.java +++ b/src/main/java/com/honey/honey/service/AdminUserService.java @@ -216,7 +216,8 @@ public class AdminUserService { }; Set sortRequiresJoin = Set.of( - "balanceA", "balanceB", "depositTotal", "withdrawTotal", "referralCount", "profit", "referrerTelegramName"); + "balanceA", "balanceB", "depositTotal", "withdrawTotal", "referralCount", "profit", + "referrerTelegramName", "profitPercent"); boolean useJoinSort = sortBy != null && sortRequiresJoin.contains(sortBy); List userList; long totalElements; @@ -519,6 +520,8 @@ public class AdminUserService { 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"; + // Same as (1 - withdraw/deposit)*100 when deposit > 0 (Honey linear USD scale) + case "profitPercent" -> "(CASE WHEN b.deposit_total > 0 THEN 100.0 * (b.deposit_total - b.withdraw_total) / b.deposit_total ELSE NULL END)"; default -> "a.id"; }; String direction = "asc".equalsIgnoreCase(sortDir) ? " ASC" : " DESC"; diff --git a/src/main/resources/db/migration/V82__users_b_admin_profit_percent_index.sql b/src/main/resources/db/migration/V82__users_b_admin_profit_percent_index.sql new file mode 100644 index 0000000..27144e5 --- /dev/null +++ b/src/main/resources/db/migration/V82__users_b_admin_profit_percent_index.sql @@ -0,0 +1,10 @@ +-- Admin users list: sort by profitPercent matches AdminUserService native ORDER BY on db_users_b: +-- CASE WHEN deposit_total > 0 THEN 100.0 * (deposit_total - withdraw_total) / deposit_total ELSE NULL END +-- MySQL 8.0.13+ functional index so ORDER BY can use an index (when planner chooses it). +CREATE INDEX idx_users_b_admin_profit_pct ON db_users_b ( + (CASE + WHEN deposit_total > 0 + THEN (100.0 * (deposit_total - withdraw_total) / deposit_total) + ELSE NULL + END) +);