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

This commit is contained in:
kate522 committed 2026-08-24 15:59:11 +08:00
1 parent ca12226b39
commit 5cae5b5c93
159 files changed
+7275 -4718

No files matched your search

+41 -24
View File
@@ -43,6 +43,11 @@ class PayWithdrawals {
$per_page = 20;
$svc = \AKSRT\Payment\Withdrawal::get_instance();
$stats = $svc->get_stats();
$retry_id = isset($_GET['retry_id']) ? max(0, (int) $_GET['retry_id']) : 0;
$retry_key = isset($_GET['retry_key']) ? sanitize_text_field((string) wp_unslash($_GET['retry_key'])) : '';
if (!wp_is_uuid($retry_key)) {
$retry_key = '';
}
echo '<p>' . esc_html(sprintf(
/* translators: 1: total 2: pending 3: completed 4: paid */
@@ -52,7 +57,7 @@ class PayWithdrawals {
(int) ($stats['processing'] ?? 0),
(int) ($stats['completed'] ?? 0),
(int) ($stats['rejected'] ?? 0),
number_format((float) ($stats['total_paid'] ?? 0), 2)
(string) ($stats['total_paid'] ?? '0.00')
)) . '</p>';
echo '<form method="get" style="margin:12px 0;">';
@@ -106,17 +111,17 @@ class PayWithdrawals {
$user_id = (int) ($row['user_id'] ?? 0);
$user = $user_id > 0 ? get_userdata($user_id) : null;
$st = (string) ($row['status'] ?? '');
$gross = (float) ($row['gross_amount'] ?? $row['amount'] ?? 0);
$net = (float) ($row['amount'] ?? 0);
$fee = (int) ($row['fee_rate'] ?? 0);
$acct = (string) ($row['display_account'] ?? $row['account_info'] ?? '');
$amount_txt = number_format($net, 2);
if ($gross > 0 && abs($gross - $net) > 0.001) {
$amount_txt = sprintf(
$gross = (string) ($row['gross_amount'] ?? '0.00');
$net = (string) ($row['amount'] ?? '0.00');
$fee = (int) ($row['fee_rate'] ?? 0);
$acct = (string) ($row['display_account'] ?? $row['account_info'] ?? '');
$amount_txt = $net;
if ($gross !== $net) {
$amount_txt = sprintf(
/* translators: 1: gross 2: net 3: fee percent */
__('申请 %1$s / 到账 %2$s(手续费 %3$d%%)', 'aksrt'),
number_format($gross, 2),
number_format($net, 2),
$gross,
$net,
$fee
);
}
@@ -130,15 +135,22 @@ class PayWithdrawals {
echo '<td>' . esc_html($status_options[$st] ?? $st) . '</td>';
echo '<td>' . esc_html((string) ($row['created_at'] ?? '')) . '</td>';
echo '<td>';
echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '" style="display:flex;gap:4px;flex-wrap:wrap;align-items:center;">';
echo '<input type="hidden" name="action" value="aksrt_pay_update_withdrawal" />';
echo '<input type="hidden" name="withdrawal_id" value="' . esc_attr((string) $id) . '" />';
$next_statuses = $st === 'pending' ? ['processing', 'rejected'] : ($st === 'processing' ? ['completed', 'rejected'] : []);
if ($next_statuses === []) {
echo '&mdash;';
echo '</td>';
echo '</tr>';
continue;
}
$request_key = $retry_id === $id && $retry_key !== '' ? $retry_key : wp_generate_uuid4();
echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '" style="display:flex;gap:4px;flex-wrap:wrap;align-items:center;">';
echo '<input type="hidden" name="action" value="aksrt_pay_update_withdrawal" />';
echo '<input type="hidden" name="withdrawal_id" value="' . esc_attr((string) $id) . '" />';
echo '<input type="hidden" name="idempotency_key" value="' . esc_attr($request_key) . '" />';
wp_nonce_field('aksrt_pay_update_withdrawal_' . $id);
echo '<select name="new_status">';
foreach ($status_options as $key => $label) {
if ($key === '') {
continue;
}
foreach ($next_statuses as $key) {
$label = $status_options[$key];
printf(
'<option value="%s"%s>%s</option>',
esc_attr($key),
@@ -180,26 +192,31 @@ class PayWithdrawals {
$id = isset($_POST['withdrawal_id']) ? (int) $_POST['withdrawal_id'] : 0;
$new_status = isset($_POST['new_status']) ? sanitize_key((string) wp_unslash($_POST['new_status'])) : '';
$note = isset($_POST['note']) ? sanitize_textarea_field((string) wp_unslash($_POST['note'])) : '';
$request_key = isset($_POST['idempotency_key']) ? sanitize_text_field((string) wp_unslash($_POST['idempotency_key'])) : '';
check_admin_referer('aksrt_pay_update_withdrawal_' . $id);
$msg = 'withdraw_failed';
if ($id > 0 && $new_status !== '' && class_exists('\AKSRT\Payment\Withdrawal')) {
$result = \AKSRT\Payment\Withdrawal::get_instance()->process_status_change($id, $new_status, $note);
if ($id > 0 && $new_status !== '' && wp_is_uuid($request_key) && class_exists('\AKSRT\Payment\Withdrawal')) {
$operation_key = \AKSRT\Ledger\OperationKey::deterministic('admin-withdraw-transition', [get_current_user_id(), strtolower($request_key)]);
$result = \AKSRT\Payment\Withdrawal::get_instance()->process_status_change($id, $new_status, $note, $operation_key);
if (!is_wp_error($result) && $result) {
$msg = 'withdraw_updated';
} elseif (is_wp_error($result) && $result->get_error_code() === 'aksrt_balance') {
} elseif (is_wp_error($result) && $result->get_error_code() === 'aksrt_balance_insufficient') {
$msg = 'withdraw_refund_failed';
}
}
wp_safe_redirect($this->page_url('aksrt_withdraw', [
'aksrt_pay_msg' => $msg,
]));
$redirect_args = ['aksrt_pay_msg' => $msg];
if ($msg !== 'withdraw_updated' && wp_is_uuid($request_key)) {
$redirect_args['retry_id'] = $id;
$redirect_args['retry_key'] = $request_key;
}
wp_safe_redirect($this->page_url('aksrt_withdraw', $redirect_args));
exit;
}
/* ------------------------------------------------------------------
* Income / rebate
* Income
* ----------------------------------------------------------------*/