Some checks failed
lotterLaravel CI / test (push) Has been cancelled
- 扩大玩家ID随机数位宽降低碰撞概率 - 授信额度变更加 lockForUpdate 防并发下调 - 结算冲正与入账利用唯一索引实现幂等闸门 - 失败登录计数加锁防丢失 - 代理子树查询改用子查询替代全表 pluck - 修复返点默认值百分比单位转换 - 测试中全量 fake 广播事件防 CI 500
66 lines
2.1 KiB
PHP
66 lines
2.1 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace App\Support;
|
||
|
||
use App\Models\Currency;
|
||
use App\Services\LotterySettings;
|
||
|
||
/**
|
||
* 信用占成盘额度(代理/玩家授信、已用)在库内按「主货币整数」存储;
|
||
* 彩票下注、钱包 API 使用最小货币单位(minor)。本类负责二者换算。
|
||
*/
|
||
final class CreditAmountScale
|
||
{
|
||
public static function minorUnitFactor(string $currencyCode): int
|
||
{
|
||
$code = strtoupper(trim($currencyCode));
|
||
if ($code === '') {
|
||
return (int) max(1, 10 ** LotterySettings::currencyDisplayDecimals());
|
||
}
|
||
|
||
$currency = Currency::query()->where('code', $code)->first();
|
||
$decimals = $currency !== null
|
||
? (int) $currency->decimal_places
|
||
: LotterySettings::currencyDisplayDecimals();
|
||
|
||
return (int) max(1, 10 ** max(0, min(12, $decimals)));
|
||
}
|
||
|
||
public static function majorToMinor(int $major, string $currencyCode): int
|
||
{
|
||
// 负值防御:所有调用方都应在传入前 max(0, ...) 兜底(available credit / balance / 等),
|
||
// 此处 double-check 是兜底而非业务逻辑。若发生负数通常意味着上游计算 bug,
|
||
// 记录 warning 让 production 暴露问题而不被静默吞掉。
|
||
if ($major < 0) {
|
||
\Illuminate\Support\Facades\Log::warning('CreditAmountScale::majorToMinor received negative value', [
|
||
'major' => $major,
|
||
'currency_code' => $currencyCode,
|
||
'trace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4),
|
||
]);
|
||
|
||
return 0;
|
||
}
|
||
|
||
return $major * self::minorUnitFactor($currencyCode);
|
||
}
|
||
|
||
/**
|
||
* 最小单位 → 主货币整数(占用授信时向上取整,与 preflight 按 major 校验一致)。
|
||
*/
|
||
public static function minorToMajor(int $minor, string $currencyCode): int
|
||
{
|
||
$factor = self::minorUnitFactor($currencyCode);
|
||
if ($factor <= 1) {
|
||
return $minor;
|
||
}
|
||
|
||
if ($minor <= 0) {
|
||
return 0;
|
||
}
|
||
|
||
return intdiv($minor + $factor - 1, $factor);
|
||
}
|
||
}
|