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

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
+78 -33
View File
@@ -67,16 +67,16 @@ trait FrontSubmitPay {
$meta['pay_type'] = $pay_type;
$meta['pay_modo'] = $pay_modo;
$min = (float) ($settings['pay_price_min'] ?? 0);
$max = (float) ($settings['pay_price_max'] ?? 0);
$allow_free = !empty($settings['pay_free_s']);
$vip_manual = !empty($settings['pay_vip_price_s']);
$vip1_disc = (int) ($settings['pay_vip_1_discount'] ?? 100);
$vip2_disc = (int) ($settings['pay_vip_2_discount'] ?? 100);
if ($pay_modo === 'points') {
$points = isset($raw['points_price']) ? (int) $raw['points_price'] : (int) ($data['points_price'] ?? 0);
if ($points < 0) {
$points = $this->parse_front_points($raw['points_price'] ?? $data['points_price'] ?? null);
$min = $this->parse_front_points_limit($settings['pay_price_min'] ?? '0.00');
$max = $this->parse_front_points_limit($settings['pay_price_max'] ?? '0.00');
if ($points === null) {
return ['success' => false, 'message' => __('请设置正确的积分价格', 'aksrt')];
}
if (!$allow_free && $points <= 0) {
@@ -90,59 +90,64 @@ trait FrontSubmitPay {
}
if ($vip_manual) {
$vip1 = isset($raw['vip1_points']) ? (int) $raw['vip1_points'] : (int) ($raw['vip_1_points'] ?? 0);
$vip2 = isset($raw['vip2_points']) ? (int) $raw['vip2_points'] : (int) ($raw['vip_2_points'] ?? 0);
$vip1 = $this->parse_front_points($raw['vip1_points'] ?? $raw['vip_1_points'] ?? null);
$vip2 = $this->parse_front_points($raw['vip2_points'] ?? $raw['vip_2_points'] ?? null);
if ($vip1 === null || $vip2 === null) {
return ['success' => false, 'message' => __('请设置正确的会员积分价格', 'aksrt')];
}
} else {
$vip1 = (int) floor($points * $vip1_disc / 100);
$vip2 = (int) floor($points * $vip2_disc / 100);
$vip1 = (intdiv($points, 100) * $vip1_disc) + intdiv(($points % 100) * $vip1_disc, 100);
$vip2 = (intdiv($points, 100) * $vip2_disc) + intdiv(($points % 100) * $vip2_disc, 100);
}
$vip1 = max(0, min($points, $vip1));
$vip2 = max(0, min($vip1, $vip2));
$meta['points_price'] = $points;
$meta['price'] = 0.0;
$meta['price'] = '0.00';
$meta['vip1_points'] = $vip1;
$meta['vip2_points'] = $vip2;
$meta['vip1_price'] = 0.0;
$meta['vip2_price'] = 0.0;
$meta['vip1_price'] = '0.00';
$meta['vip2_price'] = '0.00';
} else {
$price = isset($raw['price']) ? (float) $raw['price'] : (float) ($raw['pay_price'] ?? $data['pay_price'] ?? 0);
$price = round($price, 2);
if ($price < 0) {
$price_minor = $this->parse_front_cash_minor($raw['price'] ?? $raw['pay_price'] ?? $data['pay_price'] ?? null);
$min_minor = $this->parse_front_cash_minor($settings['pay_price_min'] ?? '0') ?? 0;
$max_minor = $this->parse_front_cash_minor($settings['pay_price_max'] ?? '0') ?? 0;
if ($price_minor === null) {
return ['success' => false, 'message' => __('请设置正确的价格', 'aksrt')];
}
if (!$allow_free && $price <= 0) {
if (!$allow_free && $price_minor <= 0) {
return ['success' => false, 'message' => __('请设置付费内容的价格', 'aksrt')];
}
if ($min > 0 && $price < $min) {
return ['success' => false, 'message' => sprintf(__('价格不能低于:%s', 'aksrt'), (string) $min)];
if ($min_minor > 0 && $price_minor < $min_minor) {
return ['success' => false, 'message' => sprintf(__('价格不能低于:%s', 'aksrt'), \AKSRT\Ledger\AssetAmount::decimal_from_minor($min_minor))];
}
if ($max > 0 && $price > $max) {
return ['success' => false, 'message' => sprintf(__('价格不能高于:%s', 'aksrt'), (string) $max)];
if ($max_minor > 0 && $price_minor > $max_minor) {
return ['success' => false, 'message' => sprintf(__('价格不能高于:%s', 'aksrt'), \AKSRT\Ledger\AssetAmount::decimal_from_minor($max_minor))];
}
if ($vip_manual) {
$vip1 = isset($raw['vip1_price']) ? (float) $raw['vip1_price'] : (float) ($raw['vip_1_price'] ?? 0);
$vip2 = isset($raw['vip2_price']) ? (float) $raw['vip2_price'] : (float) ($raw['vip_2_price'] ?? 0);
$vip1 = round($vip1, 2);
$vip2 = round($vip2, 2);
if ($vip1 > $price) {
$vip1_minor = $this->parse_front_cash_minor($raw['vip1_price'] ?? $raw['vip_1_price'] ?? null);
$vip2_minor = $this->parse_front_cash_minor($raw['vip2_price'] ?? $raw['vip_2_price'] ?? null);
if ($vip1_minor === null || $vip2_minor === null) {
return ['success' => false, 'message' => __('请设置正确的会员价格', 'aksrt')];
}
if ($vip1_minor > $price_minor) {
return ['success' => false, 'message' => __('会员价不能高于普通价', 'aksrt')];
}
if ($vip2 > $vip1) {
if ($vip2_minor > $vip1_minor) {
return ['success' => false, 'message' => __('更高等级会员价不能高于较低等级会员价', 'aksrt')];
}
} else {
$vip1 = round($price * $vip1_disc / 100, 2);
$vip2 = round($price * $vip2_disc / 100, 2);
$vip1_minor = \AKSRT\Ledger\AssetAmount::percentage($price_minor, max(0, min(100, $vip1_disc)));
$vip2_minor = \AKSRT\Ledger\AssetAmount::percentage($price_minor, max(0, min(100, $vip2_disc)));
}
$vip1 = max(0, min($price, $vip1));
$vip2 = max(0, min($vip1, $vip2));
$vip1_minor = max(0, min($price_minor, $vip1_minor));
$vip2_minor = max(0, min($vip1_minor, $vip2_minor));
$meta['price'] = $price;
$meta['price'] = \AKSRT\Ledger\AssetAmount::decimal_from_minor($price_minor);
$meta['points_price'] = 0;
$meta['vip1_price'] = $vip1;
$meta['vip2_price'] = $vip2;
$meta['vip1_price'] = \AKSRT\Ledger\AssetAmount::decimal_from_minor($vip1_minor);
$meta['vip2_price'] = \AKSRT\Ledger\AssetAmount::decimal_from_minor($vip2_minor);
$meta['vip1_points'] = 0;
$meta['vip2_points'] = 0;
}
@@ -159,6 +164,40 @@ trait FrontSubmitPay {
return ['success' => true];
}
private function parse_front_points($value): ?int {
if (is_int($value)) {
return $value >= 0 ? $value : null;
}
if (!is_string($value) || !preg_match('/^(0|[1-9]\d*)$/', trim($value))) {
return null;
}
$value = trim($value);
if (strlen($value) > strlen((string) PHP_INT_MAX)
|| (strlen($value) === strlen((string) PHP_INT_MAX) && strcmp($value, (string) PHP_INT_MAX) > 0)
) {
return null;
}
return (int) $value;
}
private function parse_front_cash_minor($value): ?int {
if (!is_string($value)) {
return null;
}
try {
return \AKSRT\Ledger\AssetAmount::balance_minor($value);
} catch (\InvalidArgumentException $e) {
return null;
}
}
private function parse_front_points_limit($value): int {
if (!is_string($value) || !preg_match('/^(0|[1-9]\d*)(?:\.00)?$/', trim($value), $matches)) {
return 0;
}
return $this->parse_front_points((string) $matches[1]) ?? 0;
}
/**
* @param mixed $raw
* @return array<int, array<string, string>>
@@ -210,7 +249,13 @@ trait FrontSubmitPay {
$meta = DomainModel::sanitize_pay_meta($meta);
update_post_meta($post_id, DomainModel::PAY_META_KEY, $meta);
update_post_meta($post_id, DomainModel::PAY_TYPE_KEY, (string) ($meta['pay_type'] ?? DomainModel::PAY_TYPE_NO));
update_post_meta($post_id, DomainModel::PAY_PRICE_KEY, (float) ($meta['price'] ?? 0));
update_post_meta(
$post_id,
DomainModel::PAY_PRICE_KEY,
($meta['pay_modo'] ?? '0') === 'points'
? (int) ($meta['points_price'] ?? 0)
: (string) ($meta['price'] ?? '0.00')
);
update_post_meta(
$post_id,
DomainModel::RESOURCE_MARKER_KEY,