feat: 添加货币格式化配置,支持自定义小数位和分隔符,增强 API 响应的可读性
This commit is contained in:
45
app/Support/CurrencyFormatter.php
Normal file
45
app/Support/CurrencyFormatter.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Support;
|
||||
|
||||
/**
|
||||
* 将「最小货币单位」整数格式化为展示用字符串(不改变业务数字,仅格式化)。
|
||||
*
|
||||
* 拆分位数由 {@see config('lottery.ui.format.currency.decimals')} 决定,默认 2(即 ÷100)。
|
||||
*/
|
||||
final class CurrencyFormatter
|
||||
{
|
||||
public static function fromMinor(int|string|null $minor): string
|
||||
{
|
||||
if ($minor === null || $minor === '') {
|
||||
return self::formatMinorInt(0);
|
||||
}
|
||||
|
||||
return self::formatMinorInt((int) $minor);
|
||||
}
|
||||
|
||||
private static function formatMinorInt(int $minorUnits): string
|
||||
{
|
||||
$decimals = max(0, min(12, (int) config('lottery.ui.format.currency.decimals', 2)));
|
||||
$decSep = (string) config('lottery.ui.format.currency.decimal_separator', '.');
|
||||
$thousandsSep = (string) config('lottery.ui.format.currency.thousands_separator', ',');
|
||||
|
||||
$divisor = (int) max(1, 10 ** $decimals);
|
||||
$negative = $minorUnits < 0;
|
||||
$abs = abs($minorUnits);
|
||||
|
||||
$integerPart = intdiv($abs, $divisor);
|
||||
$fractionRaw = $abs % $divisor;
|
||||
$fractionPadded = str_pad((string) $fractionRaw, $decimals, '0', STR_PAD_LEFT);
|
||||
|
||||
$integerPartFormatted = number_format((float) $integerPart, 0, $decSep, $thousandsSep);
|
||||
|
||||
if ($decimals === 0) {
|
||||
return ($negative ? '-' : '').$integerPartFormatted;
|
||||
}
|
||||
|
||||
return ($negative ? '-' : '').$integerPartFormatted.$decSep.$fractionPadded;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user