249 lines
10 KiB
TypeScript
249 lines
10 KiB
TypeScript
import { apiRequest } from "@/shared/api/request";
|
|
import { API_ENDPOINTS, API_OPERATIONS, apiEndpointPath } from "@/shared/api/generated/endpoints";
|
|
|
|
export interface LuckyGiftTierDto {
|
|
pool: string;
|
|
tierId: string;
|
|
rewardCoins: number;
|
|
multiplierPPM: number;
|
|
weight: number;
|
|
highWaterOnly: boolean;
|
|
enabled: boolean;
|
|
}
|
|
|
|
export interface LuckyGiftConfigDto {
|
|
appCode?: string;
|
|
poolId: string;
|
|
enabled: boolean;
|
|
ruleVersion: number;
|
|
giftPrice: number;
|
|
targetRTPPPM: number;
|
|
poolRatePPM: number;
|
|
globalWindowDraws: number;
|
|
giftWindowDraws: number;
|
|
noviceDrawLimit: number;
|
|
intermediateDrawLimit: number;
|
|
highMultiplier: number;
|
|
highWaterPoolMultiple: number;
|
|
platformPoolWeightPPM: number;
|
|
roomPoolWeightPPM: number;
|
|
giftPoolWeightPPM: number;
|
|
initialPlatformPool: number;
|
|
initialGiftPool: number;
|
|
initialRoomPool: number;
|
|
platformReserve: number;
|
|
giftReserve: number;
|
|
roomReserve: number;
|
|
maxSinglePayout: number;
|
|
userHourlyPayoutCap: number;
|
|
userDailyPayoutCap: number;
|
|
deviceDailyPayoutCap: number;
|
|
roomHourlyPayoutCap: number;
|
|
anchorDailyPayoutCap: number;
|
|
roomAtmosphereRatePPM: number;
|
|
roomAtmosphereInitial: number;
|
|
roomAtmosphereReserve: number;
|
|
activityBudget: number;
|
|
activityDailyLimit: number;
|
|
largeTierEnabled: boolean;
|
|
multiplierPPMs: number[];
|
|
tiers: LuckyGiftTierDto[];
|
|
updatedByAdminId?: number;
|
|
createdAtMs?: number;
|
|
updatedAtMs?: number;
|
|
}
|
|
|
|
export interface LuckyGiftConfigPayload {
|
|
pool_id: string;
|
|
enabled: boolean;
|
|
gift_price: number;
|
|
target_rtp_ppm: number;
|
|
pool_rate_ppm: number;
|
|
global_window_draws: number;
|
|
gift_window_draws: number;
|
|
novice_draw_limit: number;
|
|
intermediate_draw_limit: number;
|
|
high_multiplier: number;
|
|
high_water_pool_multiple: number;
|
|
platform_pool_weight_ppm: number;
|
|
room_pool_weight_ppm: number;
|
|
gift_pool_weight_ppm: number;
|
|
initial_platform_pool: number;
|
|
initial_gift_pool: number;
|
|
initial_room_pool: number;
|
|
platform_reserve: number;
|
|
gift_reserve: number;
|
|
room_reserve: number;
|
|
max_single_payout: number;
|
|
user_hourly_payout_cap: number;
|
|
user_daily_payout_cap: number;
|
|
device_daily_payout_cap: number;
|
|
room_hourly_payout_cap: number;
|
|
anchor_daily_payout_cap: number;
|
|
room_atmosphere_rate_ppm: number;
|
|
room_atmosphere_initial: number;
|
|
room_atmosphere_reserve: number;
|
|
activity_budget: number;
|
|
activity_daily_limit: number;
|
|
large_tier_enabled: boolean;
|
|
multiplier_ppms: number[];
|
|
tiers: Array<{
|
|
pool: string;
|
|
tier_id: string;
|
|
reward_coins: number;
|
|
multiplier_ppm: number;
|
|
weight: number;
|
|
high_water_only: boolean;
|
|
enabled: boolean;
|
|
}>;
|
|
}
|
|
|
|
export interface LuckyGiftDrawSummaryDto {
|
|
poolId: string;
|
|
totalDraws: number;
|
|
uniqueUsers: number;
|
|
uniqueRooms: number;
|
|
totalSpentCoins: number;
|
|
totalRewardCoins: number;
|
|
baseRewardCoins: number;
|
|
roomAtmosphereRewardCoins: number;
|
|
activitySubsidyCoins: number;
|
|
actualRTPPPM: number;
|
|
pendingDraws: number;
|
|
grantedDraws: number;
|
|
failedDraws: number;
|
|
}
|
|
|
|
type RawConfig = LuckyGiftConfigDto & Record<string, unknown>;
|
|
type RawTier = LuckyGiftTierDto & Record<string, unknown>;
|
|
type RawSummary = LuckyGiftDrawSummaryDto & Record<string, unknown>;
|
|
type LuckyGiftDrawSummaryQuery = Record<string, number | string | undefined>;
|
|
|
|
export function getLuckyGiftConfig(poolId: string): Promise<LuckyGiftConfigDto> {
|
|
const endpoint = API_ENDPOINTS.getLuckyGiftConfig;
|
|
return apiRequest<RawConfig>(apiEndpointPath(API_OPERATIONS.getLuckyGiftConfig), {
|
|
method: endpoint.method,
|
|
query: { pool_id: poolId },
|
|
}).then(normalizeConfig);
|
|
}
|
|
|
|
export function listLuckyGiftConfigs(): Promise<LuckyGiftConfigDto[]> {
|
|
const endpoint = API_ENDPOINTS.listLuckyGiftConfigs;
|
|
return apiRequest<RawConfig[]>(apiEndpointPath(API_OPERATIONS.listLuckyGiftConfigs), {
|
|
method: endpoint.method,
|
|
}).then((items) => (items || []).map(normalizeConfig));
|
|
}
|
|
|
|
export function updateLuckyGiftConfig(payload: LuckyGiftConfigPayload): Promise<LuckyGiftConfigDto> {
|
|
const endpoint = API_ENDPOINTS.upsertLuckyGiftConfig;
|
|
return apiRequest<RawConfig, LuckyGiftConfigPayload>(apiEndpointPath(API_OPERATIONS.upsertLuckyGiftConfig), {
|
|
body: payload,
|
|
method: endpoint.method,
|
|
query: { pool_id: payload.pool_id },
|
|
}).then(normalizeConfig);
|
|
}
|
|
|
|
export function getLuckyGiftDrawSummary(query: LuckyGiftDrawSummaryQuery = {}): Promise<LuckyGiftDrawSummaryDto> {
|
|
const endpoint = API_ENDPOINTS.getLuckyGiftDrawSummary;
|
|
return apiRequest<RawSummary>(apiEndpointPath(API_OPERATIONS.getLuckyGiftDrawSummary), {
|
|
method: endpoint.method,
|
|
query,
|
|
}).then(normalizeSummary);
|
|
}
|
|
|
|
function normalizeConfig(item: RawConfig): LuckyGiftConfigDto {
|
|
return {
|
|
appCode: stringValue(item.appCode ?? item.app_code),
|
|
poolId: stringValue(item.poolId ?? item.pool_id ?? item.gift_id),
|
|
enabled: booleanValue(item.enabled),
|
|
ruleVersion: numberValue(item.ruleVersion ?? item.rule_version),
|
|
giftPrice: numberValue(item.giftPrice ?? item.gift_price),
|
|
targetRTPPPM: numberValue(item.targetRTPPPM ?? item.target_rtp_ppm),
|
|
poolRatePPM: numberValue(item.poolRatePPM ?? item.pool_rate_ppm),
|
|
globalWindowDraws: numberValue(item.globalWindowDraws ?? item.global_window_draws),
|
|
giftWindowDraws: numberValue(item.giftWindowDraws ?? item.gift_window_draws),
|
|
noviceDrawLimit: numberValue(item.noviceDrawLimit ?? item.novice_draw_limit),
|
|
intermediateDrawLimit: numberValue(item.intermediateDrawLimit ?? item.intermediate_draw_limit),
|
|
highMultiplier: numberValue(item.highMultiplier ?? item.high_multiplier),
|
|
highWaterPoolMultiple: numberValue(item.highWaterPoolMultiple ?? item.high_water_pool_multiple),
|
|
platformPoolWeightPPM: numberValue(item.platformPoolWeightPPM ?? item.platform_pool_weight_ppm),
|
|
roomPoolWeightPPM: numberValue(item.roomPoolWeightPPM ?? item.room_pool_weight_ppm),
|
|
giftPoolWeightPPM: numberValue(item.giftPoolWeightPPM ?? item.gift_pool_weight_ppm),
|
|
initialPlatformPool: numberValue(item.initialPlatformPool ?? item.initial_platform_pool),
|
|
initialGiftPool: numberValue(item.initialGiftPool ?? item.initial_gift_pool),
|
|
initialRoomPool: numberValue(item.initialRoomPool ?? item.initial_room_pool),
|
|
platformReserve: numberValue(item.platformReserve ?? item.platform_reserve),
|
|
giftReserve: numberValue(item.giftReserve ?? item.gift_reserve),
|
|
roomReserve: numberValue(item.roomReserve ?? item.room_reserve),
|
|
maxSinglePayout: numberValue(item.maxSinglePayout ?? item.max_single_payout),
|
|
userHourlyPayoutCap: numberValue(item.userHourlyPayoutCap ?? item.user_hourly_payout_cap),
|
|
userDailyPayoutCap: numberValue(item.userDailyPayoutCap ?? item.user_daily_payout_cap),
|
|
deviceDailyPayoutCap: numberValue(item.deviceDailyPayoutCap ?? item.device_daily_payout_cap),
|
|
roomHourlyPayoutCap: numberValue(item.roomHourlyPayoutCap ?? item.room_hourly_payout_cap),
|
|
anchorDailyPayoutCap: numberValue(item.anchorDailyPayoutCap ?? item.anchor_daily_payout_cap),
|
|
roomAtmosphereRatePPM: numberValue(item.roomAtmosphereRatePPM ?? item.room_atmosphere_rate_ppm),
|
|
roomAtmosphereInitial: numberValue(item.roomAtmosphereInitial ?? item.room_atmosphere_initial),
|
|
roomAtmosphereReserve: numberValue(item.roomAtmosphereReserve ?? item.room_atmosphere_reserve),
|
|
activityBudget: numberValue(item.activityBudget ?? item.activity_budget),
|
|
activityDailyLimit: numberValue(item.activityDailyLimit ?? item.activity_daily_limit),
|
|
largeTierEnabled: booleanValue(item.largeTierEnabled ?? item.large_tier_enabled),
|
|
multiplierPPMs: arrayValue(item.multiplierPPMs ?? item.multiplier_ppms).map(numberValue),
|
|
tiers: arrayValue(item.tiers).map(normalizeTier),
|
|
updatedByAdminId: numberValue(item.updatedByAdminId ?? item.updated_by_admin_id),
|
|
createdAtMs: numberValue(item.createdAtMs ?? item.created_at_ms),
|
|
updatedAtMs: numberValue(item.updatedAtMs ?? item.updated_at_ms),
|
|
};
|
|
}
|
|
|
|
function normalizeTier(raw: unknown): LuckyGiftTierDto {
|
|
const item = asRecord(raw) as RawTier;
|
|
return {
|
|
pool: stringValue(item.pool),
|
|
tierId: stringValue(item.tierId ?? item.tier_id),
|
|
rewardCoins: numberValue(item.rewardCoins ?? item.reward_coins),
|
|
multiplierPPM: numberValue(item.multiplierPPM ?? item.multiplier_ppm),
|
|
weight: numberValue(item.weight),
|
|
highWaterOnly: booleanValue(item.highWaterOnly ?? item.high_water_only),
|
|
enabled: booleanValue(item.enabled),
|
|
};
|
|
}
|
|
|
|
function normalizeSummary(item: RawSummary): LuckyGiftDrawSummaryDto {
|
|
return {
|
|
poolId: stringValue(item.poolId ?? item.pool_id),
|
|
totalDraws: numberValue(item.totalDraws ?? item.total_draws),
|
|
uniqueUsers: numberValue(item.uniqueUsers ?? item.unique_users),
|
|
uniqueRooms: numberValue(item.uniqueRooms ?? item.unique_rooms),
|
|
totalSpentCoins: numberValue(item.totalSpentCoins ?? item.total_spent_coins),
|
|
totalRewardCoins: numberValue(item.totalRewardCoins ?? item.total_reward_coins),
|
|
baseRewardCoins: numberValue(item.baseRewardCoins ?? item.base_reward_coins),
|
|
roomAtmosphereRewardCoins: numberValue(item.roomAtmosphereRewardCoins ?? item.room_atmosphere_reward_coins),
|
|
activitySubsidyCoins: numberValue(item.activitySubsidyCoins ?? item.activity_subsidy_coins),
|
|
actualRTPPPM: numberValue(item.actualRTPPPM ?? item.actual_rtp_ppm),
|
|
pendingDraws: numberValue(item.pendingDraws ?? item.pending_draws),
|
|
grantedDraws: numberValue(item.grantedDraws ?? item.granted_draws),
|
|
failedDraws: numberValue(item.failedDraws ?? item.failed_draws),
|
|
};
|
|
}
|
|
|
|
function asRecord(value: unknown): Record<string, unknown> {
|
|
return value && typeof value === "object" && !Array.isArray(value) ? (value as Record<string, unknown>) : {};
|
|
}
|
|
|
|
function arrayValue(value: unknown): unknown[] {
|
|
return Array.isArray(value) ? value : [];
|
|
}
|
|
|
|
function booleanValue(value: unknown) {
|
|
return value === true || value === "true" || value === 1 || value === "1";
|
|
}
|
|
|
|
function stringValue(value: unknown) {
|
|
return typeof value === "string" ? value : value === undefined || value === null ? "" : String(value);
|
|
}
|
|
|
|
function numberValue(value: unknown) {
|
|
const number = Number(value || 0);
|
|
return Number.isFinite(number) ? number : 0;
|
|
}
|