fix(payment): refresh rebate metrics and unify withdrawal statuses
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -71,7 +71,7 @@
|
||||
</n-card>
|
||||
|
||||
<n-card class="aksrt-section-card" title="提现统计">
|
||||
<n-grid :cols="4" :x-gap="12" :y-gap="12">
|
||||
<n-grid :cols="6" :x-gap="12" :y-gap="12">
|
||||
<n-grid-item>
|
||||
<div class="aksrt-revenue__stat">
|
||||
<strong>{{ withdrawalStats.total }}</strong>
|
||||
@@ -81,7 +81,13 @@
|
||||
<n-grid-item>
|
||||
<div class="aksrt-revenue__stat">
|
||||
<strong>{{ withdrawalStats.pending }}</strong>
|
||||
<p>待审核</p>
|
||||
<p>待处理</p>
|
||||
</div>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<div class="aksrt-revenue__stat">
|
||||
<strong>{{ withdrawalStats.processing }}</strong>
|
||||
<p>处理中</p>
|
||||
</div>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
@@ -90,6 +96,12 @@
|
||||
<p>已完成</p>
|
||||
</div>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<div class="aksrt-revenue__stat">
|
||||
<strong>{{ withdrawalStats.rejected }}</strong>
|
||||
<p>已拒绝</p>
|
||||
</div>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<div class="aksrt-revenue__stat">
|
||||
<strong>{{ withdrawalStats.total_paid.toFixed(2) }}</strong>
|
||||
@@ -108,7 +120,7 @@ import PaymentSectionPage from '@/pages/payment/PaymentSectionPage.vue'
|
||||
import api from '@/api'
|
||||
|
||||
const revenueStats = ref({ total: 0, pending: 0, settled: 0, count: 0 })
|
||||
const withdrawalStats = ref({ total: 0, pending: 0, completed: 0, total_paid: 0 })
|
||||
const withdrawalStats = ref({ total: 0, pending: 0, processing: 0, completed: 0, rejected: 0, total_paid: 0 })
|
||||
const timeSeries = ref([])
|
||||
const granularity = ref('day')
|
||||
|
||||
@@ -151,7 +163,9 @@ async function loadRevenue() {
|
||||
withdrawalStats.value = {
|
||||
total: Number(res.data.withdrawal.total || 0),
|
||||
pending: Number(res.data.withdrawal.pending || 0),
|
||||
processing: Number(res.data.withdrawal.processing || 0),
|
||||
completed: Number(res.data.withdrawal.completed || 0),
|
||||
rejected: Number(res.data.withdrawal.rejected || 0),
|
||||
total_paid: Number(res.data.withdrawal.total_paid || 0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,14 +168,16 @@ class PayMenus {
|
||||
|
||||
if ($page !== 'aksrt_withdraw' && class_exists('\AKSRT\Payment\Withdrawal')) {
|
||||
$pending = (int) \AKSRT\Payment\Withdrawal::get_instance()->get_count(['status' => \AKSRT\Payment\Withdrawal::STATUS_PENDING]);
|
||||
if ($pending > 0) {
|
||||
$processing = (int) \AKSRT\Payment\Withdrawal::get_instance()->get_count(['status' => \AKSRT\Payment\Withdrawal::STATUS_PROCESSING]);
|
||||
$active = $pending + $processing;
|
||||
if ($active > 0) {
|
||||
$url = admin_url('admin.php?page=aksrt_withdraw&status=pending');
|
||||
echo '<div class="notice notice-info is-dismissible">';
|
||||
echo '<h3>' . esc_html__('提现申请待处理', 'aksrt') . '</h3>';
|
||||
echo '<p>' . esc_html(sprintf(
|
||||
/* translators: %d: pending withdrawal count */
|
||||
/* translators: %d: open withdrawal count */
|
||||
__('您有 %d 个提现申请待处理', 'aksrt'),
|
||||
$pending
|
||||
$active
|
||||
)) . '</p>';
|
||||
echo '<p><a class="button button-primary" href="' . esc_url($url) . '">' . esc_html__('立即处理', 'aksrt') . '</a></p>';
|
||||
echo '</div>';
|
||||
|
||||
@@ -46,10 +46,12 @@ class PayWithdrawals {
|
||||
|
||||
echo '<p>' . esc_html(sprintf(
|
||||
/* translators: 1: total 2: pending 3: completed 4: paid */
|
||||
__('共 %1$d 条 · 待处理 %2$d · 已完成 %3$d · 已打款 %4$s', 'aksrt'),
|
||||
__('共 %1$d 条 · 待处理 %2$d · 处理中 %3$d · 已完成 %4$d · 已拒绝 %5$d · 已打款 %6$s', 'aksrt'),
|
||||
(int) ($stats['total'] ?? 0),
|
||||
(int) ($stats['pending'] ?? 0),
|
||||
(int) ($stats['processing'] ?? 0),
|
||||
(int) ($stats['completed'] ?? 0),
|
||||
(int) ($stats['rejected'] ?? 0),
|
||||
number_format((float) ($stats['total_paid'] ?? 0), 2)
|
||||
)) . '</p>';
|
||||
|
||||
@@ -59,7 +61,6 @@ class PayWithdrawals {
|
||||
$status_options = [
|
||||
'' => __('全部状态', 'aksrt'),
|
||||
'pending' => __('待处理', 'aksrt'),
|
||||
'approved' => __('已通过', 'aksrt'),
|
||||
'processing' => __('处理中', 'aksrt'),
|
||||
'completed' => __('已完成', 'aksrt'),
|
||||
'rejected' => __('已拒绝', 'aksrt'),
|
||||
|
||||
@@ -150,7 +150,7 @@ class PaymentController extends ControllerBase {
|
||||
$revenue_stats = \AKSRT\Payment\Revenue::get_instance()->get_stats();
|
||||
}
|
||||
|
||||
$withdrawal_stats = ['total' => 0, 'pending' => 0, 'completed' => 0, 'total_paid' => 0];
|
||||
$withdrawal_stats = ['total' => 0, 'pending' => 0, 'processing' => 0, 'completed' => 0, 'rejected' => 0, 'total_paid' => 0];
|
||||
if (class_exists('\AKSRT\Payment\Withdrawal')) {
|
||||
$withdrawal_stats = \AKSRT\Payment\Withdrawal::get_instance()->get_stats();
|
||||
}
|
||||
@@ -268,7 +268,7 @@ class PaymentController extends ControllerBase {
|
||||
$new_status = sanitize_key((string) ($params['status'] ?? ''));
|
||||
$note = sanitize_textarea_field((string) ($params['note'] ?? ''));
|
||||
|
||||
$valid_statuses = ['pending', 'approved', 'processing', 'completed', 'rejected'];
|
||||
$valid_statuses = ['pending', 'processing', 'completed', 'rejected'];
|
||||
if (!in_array($new_status, $valid_statuses, true)) {
|
||||
return $this->error('无效的提现状态');
|
||||
}
|
||||
|
||||
+20
-2
@@ -18,6 +18,18 @@ class Rebate {
|
||||
const STATUS_SETTLED = 'settled';
|
||||
const STATUS_CANCELLED = 'cancelled';
|
||||
|
||||
private function refresh_user_metric(int $user_id): void {
|
||||
if ($user_id <= 0) {
|
||||
return;
|
||||
}
|
||||
global $wpdb;
|
||||
$total = (float) $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT COALESCE(SUM(amount), 0) FROM {$this->table()} WHERE user_id = %d AND status IN ('pending', 'settled')",
|
||||
$user_id
|
||||
));
|
||||
update_user_meta($user_id, 'aksrt_pay_rebate_sum', round($total, 2));
|
||||
}
|
||||
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
@@ -62,7 +74,7 @@ class Rebate {
|
||||
'note' => $note,
|
||||
]);
|
||||
|
||||
$id = $result ? (int) $wpdb->insert_id : 0;
|
||||
$id = $result ? (int) $wpdb->insert_id : 0;
|
||||
if ($id > 0) {
|
||||
do_action('aksrt_pay_rebate_added', $user_id, $amount, [
|
||||
'rebate_id' => $id,
|
||||
@@ -123,6 +135,7 @@ class Rebate {
|
||||
}
|
||||
|
||||
$wpdb->query('COMMIT');
|
||||
$this->refresh_user_metric((int) $row['user_id']);
|
||||
return true;
|
||||
} catch (\Throwable $e) {
|
||||
$wpdb->query('ROLLBACK');
|
||||
@@ -134,9 +147,14 @@ class Rebate {
|
||||
*/
|
||||
public function cancel(int $id): bool {
|
||||
global $wpdb;
|
||||
return (bool) $wpdb->update($this->table(), [
|
||||
$updated = $wpdb->update($this->table(), [
|
||||
'status' => self::STATUS_CANCELLED,
|
||||
], ['id' => $id, 'status' => self::STATUS_PENDING]);
|
||||
if ($updated === 1) {
|
||||
$row = $wpdb->get_row($wpdb->prepare("SELECT user_id FROM {$this->table()} WHERE id = %d", $id), ARRAY_A);
|
||||
$this->refresh_user_metric((int) ($row['user_id'] ?? 0));
|
||||
}
|
||||
return $updated === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+12
-10
@@ -9,11 +9,10 @@ defined('ABSPATH') || exit;
|
||||
|
||||
class Withdrawal {
|
||||
|
||||
public const STATUS_PENDING = 'pending';
|
||||
public const STATUS_APPROVED = 'approved';
|
||||
public const STATUS_PROCESSING = 'processing';
|
||||
public const STATUS_COMPLETED = 'completed';
|
||||
public const STATUS_REJECTED = 'rejected';
|
||||
public const STATUS_PENDING = 'pending';
|
||||
public const STATUS_PROCESSING = 'processing';
|
||||
public const STATUS_COMPLETED = 'completed';
|
||||
public const STATUS_REJECTED = 'rejected';
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
@@ -99,7 +98,6 @@ class Withdrawal {
|
||||
$new_status = sanitize_key($new_status);
|
||||
$allowed = [
|
||||
self::STATUS_PENDING,
|
||||
self::STATUS_APPROVED,
|
||||
self::STATUS_PROCESSING,
|
||||
self::STATUS_COMPLETED,
|
||||
self::STATUS_REJECTED,
|
||||
@@ -195,7 +193,7 @@ class Withdrawal {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether user has open (pending/processing/approved) withdrawals.
|
||||
* Whether user has open (pending/processing) withdrawals.
|
||||
*/
|
||||
public function has_open_withdrawal(int $user_id): bool {
|
||||
return $this->count_open($user_id) > 0;
|
||||
@@ -211,7 +209,7 @@ class Withdrawal {
|
||||
}
|
||||
return (int) $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM {$this->table()}
|
||||
WHERE user_id = %d AND status IN ('pending','approved','processing')",
|
||||
WHERE user_id = %d AND status IN ('pending','processing')",
|
||||
$user_id
|
||||
));
|
||||
}
|
||||
@@ -226,7 +224,7 @@ class Withdrawal {
|
||||
}
|
||||
$rows = $wpdb->get_results($wpdb->prepare(
|
||||
"SELECT amount, account_info FROM {$this->table()}
|
||||
WHERE user_id = %d AND status IN ('pending','approved','processing')",
|
||||
WHERE user_id = %d AND status IN ('pending','processing')",
|
||||
$user_id
|
||||
), ARRAY_A);
|
||||
$total = 0.0;
|
||||
@@ -253,7 +251,7 @@ class Withdrawal {
|
||||
$params = [$user_id];
|
||||
|
||||
if (!empty($args['open_only'])) {
|
||||
$where[] = "status IN ('pending','approved','processing')";
|
||||
$where[] = "status IN ('pending','processing')";
|
||||
} else {
|
||||
$status = sanitize_key((string) ($args['status'] ?? ''));
|
||||
if ($status !== '') {
|
||||
@@ -326,6 +324,8 @@ class Withdrawal {
|
||||
"SELECT
|
||||
COUNT(*) as total,
|
||||
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending,
|
||||
SUM(CASE WHEN status = 'processing' THEN 1 ELSE 0 END) as processing,
|
||||
SUM(CASE WHEN status = 'rejected' THEN 1 ELSE 0 END) as rejected,
|
||||
SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed,
|
||||
COALESCE(SUM(CASE WHEN status = 'completed' THEN amount ELSE 0 END), 0) as total_paid
|
||||
FROM {$this->table()}",
|
||||
@@ -335,6 +335,8 @@ class Withdrawal {
|
||||
return [
|
||||
'total' => (int) ($row['total'] ?? 0),
|
||||
'pending' => (int) ($row['pending'] ?? 0),
|
||||
'processing' => (int) ($row['processing'] ?? 0),
|
||||
'rejected' => (int) ($row['rejected'] ?? 0),
|
||||
'completed' => (int) ($row['completed'] ?? 0),
|
||||
'total_paid' => (float) ($row['total_paid'] ?? 0),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user