更新增加统计【活动期间输赢总数据】

This commit is contained in:
2026-07-27 15:41:31 +08:00
parent f2543b9aa4
commit f91eb186ca
19 changed files with 375 additions and 122 deletions

View File

@@ -260,13 +260,24 @@ class MallDailyPushLogReplay
$newLocked = MallPointsConversion::dailyConvertedPoints(
$record['date'],
floatval($record['yesterday_win_loss_net']),
$pointsConfig
$pointsConfig,
MallPointsConversion::nextCalendarDate($record['date'])
);
$oldLocked = $daily
? MallPointsConversion::dailyConvertedPoints($record['date'], $oldWinLossNet, $pointsConfig)
? MallPointsConversion::dailyConvertedPoints(
$record['date'],
$oldWinLossNet,
$pointsConfig,
MallPointsConversion::nextCalendarDate($record['date'])
)
: 0;
$lockedDelta = $newLocked - $oldLocked;
$todayLimit = intval(round($record['yesterday_total_deposit'] * $unlockRatio));
$todayLimit = MallPointsConversion::dailyPushTodayLimit(
$record['date'],
floatval($record['yesterday_total_deposit']),
$pointsConfig,
MallPointsConversion::nextCalendarDate($record['date'])
);
$dailyData = [
'user_id' => $record['user_id'],
'date' => $record['date'],
@@ -352,6 +363,15 @@ class MallDailyPushLogReplay
MallPointsConversion::applyDailyConversionDelta($asset, $lockedDelta);
}
$this->applyDailyLimit($asset, $record['date'], $todayLimit);
$settlementDay = MallPointsConversion::nextCalendarDate($record['date']);
MallPointsConversion::applyEventPeriodWinLossForDailyPush(
$asset,
$record['date'],
floatval($record['yesterday_win_loss_net']),
$pointsConfig,
$settlementDay,
$daily ? $oldWinLossNet : null
);
$asset->save();
}
Db::commit();

View File

@@ -25,7 +25,11 @@ final class MallPointsConversion
* mall_open_date: ?string,
* mall_open_date_previous: ?string,
* mall_open_date_effective_on: ?string,
* active_mall_open_date: ?string
* active_mall_open_date: ?string,
* mall_event_end_date: ?string,
* mall_event_end_date_previous: ?string,
* mall_event_end_date_effective_on: ?string,
* active_event_end_date: ?string
* }
*/
public static function configFromRow(MallBusinessConfig $row): array
@@ -41,6 +45,10 @@ final class MallPointsConversion
'mall_open_date_previous' => self::normalizeDate($row->mall_open_date_previous ?? null),
'mall_open_date_effective_on' => self::normalizeDate($row->mall_open_date_effective_on ?? null),
'active_mall_open_date' => self::resolveActiveMallOpenDate($row),
'mall_event_end_date' => self::normalizeDate($row->mall_event_end_date ?? null),
'mall_event_end_date_previous' => self::normalizeDate($row->mall_event_end_date_previous ?? null),
'mall_event_end_date_effective_on' => self::normalizeDate($row->mall_event_end_date_effective_on ?? null),
'active_event_end_date' => self::resolveActiveEventEndDate($row),
];
}
@@ -74,13 +82,16 @@ final class MallPointsConversion
*
* @param array<string, mixed> $config
*/
public static function dailyConvertedPoints(string $businessDate, float $yesterdayWinLossNet, array $config): int
{
public static function dailyConvertedPoints(
string $businessDate,
float $yesterdayWinLossNet,
array $config,
?string $settlementCalendarDate = null
): int {
if (empty($config['daily_points_enabled'])) {
return 0;
}
$openDate = $config['active_mall_open_date'] ?? null;
if ($openDate !== null && $openDate !== '' && $businessDate < $openDate) {
if (!self::isDailyPushSettlementAllowed($businessDate, $config, $settlementCalendarDate)) {
return 0;
}
$ratio = floatval($config['return_ratio'] ?? 0);
@@ -88,6 +99,85 @@ final class MallPointsConversion
return self::lossIntegerToPoints($yesterdayWinLossNet, $ratio);
}
/**
* 每日推送是否允许折算昨日净输赢、昨日充值解锁上限(活动开始/结束日规则)
*/
public static function isDailyPushSettlementAllowed(
string $businessDate,
array $config,
?string $settlementCalendarDate = null
): bool {
$settlementDay = self::normalizeDate($settlementCalendarDate ?? date('Y-m-d')) ?? date('Y-m-d');
$start = self::normalizeDate($config['active_mall_open_date'] ?? null);
if ($start !== null && $businessDate < $start) {
return false;
}
$end = self::normalizeDate($config['active_event_end_date'] ?? null);
if ($end === null) {
return true;
}
if ($businessDate > $end) {
return false;
}
$endPlusOne = self::nextCalendarDate($end);
if ($settlementDay === $endPlusOne && $businessDate >= $end) {
return false;
}
if ($settlementDay > $endPlusOne) {
return false;
}
return true;
}
/**
* 活动开放期内按推送累加净输赢;关闭期间不累加,再开启后接着累加(不重置)。
*
* @param float|null $previousWinLossNet 更新已有每日推送时传旧「昨日净输赢」;新建推送传 null
*/
public static function applyEventPeriodWinLossForDailyPush(
MallUserAsset $asset,
string $businessDate,
float $yesterdayWinLossNet,
array $config,
?string $settlementCalendarDate = null,
?float $previousWinLossNet = null
): void {
if (!self::isDailyPushSettlementAllowed($businessDate, $config, $settlementCalendarDate)) {
return;
}
$current = floatval($asset->event_period_win_loss_net ?? 0);
if ($previousWinLossNet === null) {
$asset->event_period_win_loss_net = round($current + $yesterdayWinLossNet, 2);
return;
}
$delta = $yesterdayWinLossNet - $previousWinLossNet;
if ($delta === 0.0) {
return;
}
$asset->event_period_win_loss_net = round($current + $delta, 2);
}
public static function dailyPushTodayLimit(
string $businessDate,
float $yesterdayTotalDeposit,
array $config,
?string $settlementCalendarDate = null
): int {
if (!self::isDailyPushSettlementAllowed($businessDate, $config, $settlementCalendarDate)) {
return 0;
}
$unlockRatio = floatval($config['unlock_ratio'] ?? 0);
return intval(round($yesterdayTotalDeposit * $unlockRatio));
}
/**
* @param array<string, mixed> $config
* @deprecated 使用 dailyConvertedPoints
@@ -219,6 +309,27 @@ final class MallPointsConversion
return $previous;
}
public static function resolveActiveEventEndDate(MallBusinessConfig $row): ?string
{
$pending = self::normalizeDate($row->mall_event_end_date ?? null);
$previous = self::normalizeDate($row->mall_event_end_date_previous ?? null);
$effectiveOn = self::normalizeDate($row->mall_event_end_date_effective_on ?? null);
$today = date('Y-m-d');
if ($pending === null) {
if ($effectiveOn !== null && $today >= $effectiveOn) {
return null;
}
return $previous;
}
if ($effectiveOn === null || $today >= $effectiveOn) {
return $pending;
}
return $previous;
}
public static function normalizeDate(mixed $value): ?string
{
if ($value === null || $value === '') {

View File

@@ -32,6 +32,9 @@ class MallBusinessConfig extends Model
'mall_open_date' => 'string',
'mall_open_date_previous' => 'string',
'mall_open_date_effective_on' => 'string',
'mall_event_end_date' => 'string',
'mall_event_end_date_previous' => 'string',
'mall_event_end_date_effective_on' => 'string',
];
/**

View File

@@ -28,6 +28,7 @@ class MallUserAsset extends Model
'total_points_claimed' => 'integer',
'lifetime_converted_points' => 'integer',
'daily_converted_points' => 'integer',
'event_period_win_loss_net' => 'float',
];
/**