积分与余额账务系统硬切重构

This commit is contained in:
2026-08-24 15:59:11 +08:00
parent ca12226b39
commit 5cae5b5c93
159 changed files with 7275 additions and 4718 deletions
+23 -12
View File
@@ -88,13 +88,12 @@ class PaymentRuntime {
return [
'enabled' => !empty($settings['pay_balance_s']),
'desc' => $desc,
'auto_to_balance' => !isset($settings['pay_auto_to_balance']) || !empty($settings['pay_auto_to_balance']),
'packages_raw' => $packages,
'package_count' => self::count_structured_lines($packages),
'help_text' => $desc !== '' ? $desc : __('当前支持人工确认与测试联调;接入真实网关时复用同一组字段。', 'aksrt'),
'product' => [
'name' => sanitize_text_field((string) ($settings['pay_balance_product_name'] ?? '')),
'price' => max(0, (float) ($settings['pay_balance_price'] ?? 0)),
'price' => self::money_decimal($settings['pay_balance_price'] ?? '0.00', '0.00'),
'tag' => sanitize_text_field((string) ($settings['pay_balance_tag'] ?? '元')),
'tag_class' => sanitize_text_field((string) ($settings['pay_balance_tag_class'] ?? '')),
'custom_s' => !isset($settings['pay_balance_product_custom_s']) || !empty($settings['pay_balance_product_custom_s']),
@@ -234,7 +233,7 @@ class PaymentRuntime {
'desc' => sanitize_textarea_field((string) ($settings['vip_renew_desc'] ?? '')),
'price_type' => $renew_price_type,
'discount' => max(1, min(100, (int) ($settings['vip_renew_discount'] ?? 8))),
'reduce' => max(0, min(9999, (int) ($settings['vip_renew_reduce'] ?? 20))),
'reduce' => self::money_decimal($settings['vip_renew_reduce'] ?? '20.00', '20.00', 999900),
],
'upgrade' => [
'enabled' => !isset($settings['vip_upgrade']) || !empty($settings['vip_upgrade']),
@@ -284,7 +283,7 @@ class PaymentRuntime {
*/
public static function get_payment_affiliate_settings(): array {
$settings = Settings::get_all();
$clamp_ratio = static fn ($value): float => max(0, min(100, (float) $value));
$clamp_ratio = static fn($value): int => max(0, min(100, (int) $value));
$types = (array) ($settings['affiliate_order_types'] ?? ['membership', 'content']);
$types = array_values(array_intersect(['membership', 'content', 'credits'], array_map('sanitize_key', $types)));
if (!$types) { $types = ['membership', 'content']; }
@@ -303,14 +302,14 @@ class PaymentRuntime {
}
public static function affiliate_enabled(): bool { return !empty(self::get_payment_affiliate_settings()['enabled']); }
public static function affiliate_ratio_for_user(int $user_id): float {
public static function affiliate_ratio_for_user(int $user_id): int {
$level = function_exists('aksrt_get_user_vip_level') ? (int) aksrt_get_user_vip_level($user_id) : 0;
return self::affiliate_ratio_for_level($level);
}
public static function affiliate_ratio_for_level(int $level): float {
public static function affiliate_ratio_for_level(int $level): int {
$settings = self::get_payment_affiliate_settings();
$key = $level >= 2 ? 'vip_2' : ($level >= 1 ? 'vip_1' : 'user');
return (float) ($settings['ratios'][$key] ?? 0);
return (int) ($settings['ratios'][$key] ?? 0);
}
public static function get_affiliate_settings(): array { return self::get_payment_affiliate_settings(); }
public static function get_settlement_settings(): array {
@@ -433,7 +432,7 @@ class PaymentRuntime {
'batch_size' => max(1, min(500, (int) ($s['card_pass_batch_size'] ?? 50))),
'max_redeem' => max(1, min(100, (int) ($s['card_pass_max_redeem'] ?? 1))),
'expiry_days' => max(0, (int) ($s['card_pass_expiry'] ?? 0)),
'amount' => max(1, min(9999, (int) ($s['card_pass_amount'] ?? 10))),
'amount' => self::money_decimal($s['card_pass_amount'] ?? '10.00', '10.00', 999900),
'vip_days' => max(1, min(3650, (int) ($s['card_pass_vip_days'] ?? 30))),
'credits' => max(0, min(99999, (int) ($s['card_pass_credits'] ?? 0))),
'redeem_page' => esc_url_raw((string) ($s['card_pass_redeem_page'] ?? '')),
@@ -442,16 +441,16 @@ class PaymentRuntime {
];
}
/** @return array{min_amount:float,service_charge_rate:int,daily_count:int,daily_limit:float,reset_time:string,payout_channels:string[]} */
/** @return array{min_amount:string,service_charge_rate:int,daily_count:int,daily_limit:string,reset_time:string,payout_channels:string[]} */
public static function get_withdrawal_settings(): array {
$s = Settings::get_all();
$channels = array_values(array_intersect(['alipay', 'wechat'], array_map('sanitize_key', (array) ($s['affiliate_payout_channels'] ?? ['alipay', 'wechat']))));
if (!$channels) { $channels = ['alipay', 'wechat']; }
return [
'min_amount' => max(0, min(999999, (float) ($s['affiliate_min_withdrawal'] ?? 50))),
'service_charge_rate' => (int) round(max(0, min(100, (float) ($s['affiliate_withdrawal_fee'] ?? 5)))),
'min_amount' => self::money_decimal($s['affiliate_min_withdrawal'] ?? '50.00', '50.00', 99999900),
'service_charge_rate' => max(0, min(100, (int) ($s['affiliate_withdrawal_fee'] ?? 5))),
'daily_count' => max(0, min(99999, (int) ($s['affiliate_daily_withdrawal_count'] ?? 3))),
'daily_limit' => max(0, min(999999, (float) ($s['affiliate_daily_withdrawal_limit'] ?? 500))),
'daily_limit' => self::money_decimal($s['affiliate_daily_withdrawal_limit'] ?? '500.00', '500.00', 99999900),
'reset_time' => preg_match('/^(?:[01]\\d|2[0-3]):[0-5]\\d$/', (string) ($s['affiliate_withdrawal_reset_time'] ?? '00:00'))
? (string) $s['affiliate_withdrawal_reset_time']
: '00:00',
@@ -516,6 +515,18 @@ class PaymentRuntime {
return $count;
}
private static function money_decimal(mixed $value, string $default, int $max_minor = PHP_INT_MAX): string {
try {
if (!is_string($value)) {
throw new \InvalidArgumentException('money_decimal_must_be_string');
}
$amount = \AKSRT\Ledger\AssetAmount::balance(trim($value));
return $amount->minor() <= $max_minor ? $amount->decimal() : $default;
} catch (\InvalidArgumentException $e) {
return $default;
}
}
/**
* @param array<int,mixed> $products
*/