feat(user-center): add cash wallet balance separate from credits
Introduce AKSRT_Balance (user_meta aksrt_balance + balance_log) for Zibll-like pay_balance wallet. User center assets panel shows wallet and points; balance gateway/card-pass/refunds credit cash when enabled.
This commit is contained in:
1 parent
f043d2c1ab
commit
8e0f9d989d
16 files changed
+637
-74
No files matched your search
@@ -432,6 +432,8 @@ if (!function_exists('aksrt_get_user_center_render_context')) {
|
||||
$affiliate_settings = class_exists('AKSRT_Settings') ? AKSRT_Settings::get_payment_affiliate_settings() : [];
|
||||
$show_credit_tabs = (bool) ($dashboard['credits_enabled'] ?? false);
|
||||
$currency_name = (string) ($dashboard['currency_name'] ?? __('积分', 'aksrt'));
|
||||
$balance_enabled = (bool) ($dashboard['balance_enabled'] ?? false);
|
||||
$wallet_balance = (float) ($dashboard['wallet_balance'] ?? 0.0);
|
||||
|
||||
$render_context = [
|
||||
'user_center_settings' => $user_center_settings,
|
||||
@@ -470,6 +472,8 @@ if (!function_exists('aksrt_get_user_center_render_context')) {
|
||||
'currency_name' => $currency_name,
|
||||
'credit_balance' => (float) ($dashboard['credit_balance'] ?? 0.0),
|
||||
'credits_enabled' => $show_credit_tabs,
|
||||
'balance_enabled' => $balance_enabled,
|
||||
'wallet_balance' => $wallet_balance,
|
||||
'vip_settings' => $vip_settings,
|
||||
'show_invite_section' => $show_credit_tabs
|
||||
&& class_exists('AKSRT_Settings')
|
||||
|
||||
@@ -81,6 +81,10 @@ function aksrt_get_user_dashboard_view(int $user_id, array $args = []): array {
|
||||
? AKSRT_Settings::get_currency_name()
|
||||
: __('积分', 'aksrt');
|
||||
|
||||
// Cash wallet (Zibll pay_balance) — separate from points.
|
||||
$balance_enabled = $is_own_profile && class_exists('AKSRT_Balance') && AKSRT_Balance::enabled();
|
||||
$wallet_balance = $balance_enabled ? AKSRT_Balance::balance($user_id) : 0.0;
|
||||
|
||||
$user_home_manager = $include_governance && class_exists('AKSRT_User_Home')
|
||||
? AKSRT_User_Home::get_instance()
|
||||
: null;
|
||||
@@ -103,6 +107,8 @@ function aksrt_get_user_dashboard_view(int $user_id, array $args = []): array {
|
||||
'credit_balance' => $credit_balance,
|
||||
'currency_name' => $currency_name,
|
||||
'credits_enabled' => $credits_enabled,
|
||||
'balance_enabled' => $balance_enabled,
|
||||
'wallet_balance' => $wallet_balance,
|
||||
'is_own_profile' => $is_own_profile,
|
||||
];
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* User center credits: balance card + sign-in controls + card-pass redeem.
|
||||
* User center credits: points card + sign-in controls + credits card-pass redeem.
|
||||
*
|
||||
* Expects extracted $context vars.
|
||||
* Cash wallet UI lives in credits-wallet.php.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -11,34 +11,26 @@ defined('ABSPATH') || exit;
|
||||
|
||||
$balance = (float) ($credit_balance ?? 0.0);
|
||||
$credits_enabled = !empty($credits_enabled);
|
||||
if (!$credits_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$card_pass_balance = ['enabled' => false, 'desc' => '', 'only_password' => true];
|
||||
$card_pass_credits = ['enabled' => false, 'desc' => '', 'only_password' => true];
|
||||
if (class_exists('AKSRT_Charge_Card')) {
|
||||
$opts = AKSRT_Charge_Card::get_instance()->get_public_options();
|
||||
$card_pass_balance = is_array($opts['balance'] ?? null) ? $opts['balance'] : $card_pass_balance;
|
||||
$card_pass_credits = is_array($opts['credits'] ?? null) ? $opts['credits'] : $card_pass_credits;
|
||||
} elseif (class_exists('AKSRT_Settings') && method_exists('AKSRT_Settings', 'get_payment_recharge_settings')) {
|
||||
$recharge = AKSRT_Settings::get_payment_recharge_settings();
|
||||
$pc = is_array($recharge['pass_charge'] ?? null) ? $recharge['pass_charge'] : [];
|
||||
$card_pass_balance = [
|
||||
'enabled' => !empty($pc['enabled']),
|
||||
'desc' => (string) ($pc['desc'] ?? ''),
|
||||
'only_password' => !isset($pc['only_password']) || !empty($pc['only_password']),
|
||||
];
|
||||
}
|
||||
?>
|
||||
<div class="uc-balance-card">
|
||||
<div class="uc-balance-card__bg"></div>
|
||||
<div class="uc-balance-card__content">
|
||||
<div class="uc-balance-card__header">
|
||||
<span class="uc-balance-card__label"><?php esc_html_e('账户余额', 'aksrt'); ?></span>
|
||||
<span class="uc-balance-card__label"><?php echo esc_html(sprintf(__('%s余额', 'aksrt'), $currency_name)); ?></span>
|
||||
<span class="uc-balance-card__currency"><?php echo esc_html($currency_name); ?></span>
|
||||
</div>
|
||||
<div class="uc-balance-card__amount">
|
||||
<span class="uc-balance-card__value"><?php echo esc_html(aksrt_format_credits($balance)); ?></span>
|
||||
<span class="uc-balance-card__value"><?php echo esc_html(aksrt_format_credits((int) $balance)); ?></span>
|
||||
</div>
|
||||
<?php if ($credits_enabled) : ?>
|
||||
<div class="uc-balance-card__actions" data-aksrt-signin>
|
||||
<span class="uc-balance-card__sign-status" data-signin-status></span>
|
||||
<button type="button" class="uc-balance-card__sign-btn" data-signin-btn disabled>
|
||||
@@ -47,30 +39,9 @@ if (class_exists('AKSRT_Charge_Card')) {
|
||||
</button>
|
||||
</div>
|
||||
<p class="uc-balance-card__tip" data-signin-tip></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($card_pass_balance['enabled'])) : ?>
|
||||
<div class="uc-card-pass" data-aksrt-card-pass="balance">
|
||||
<div class="uc-card-pass__title">
|
||||
<i class="fas fa-ticket-alt" aria-hidden="true"></i>
|
||||
<span><?php esc_html_e('卡密兑换余额', 'aksrt'); ?></span>
|
||||
</div>
|
||||
<?php if (!empty($card_pass_balance['desc'])) : ?>
|
||||
<p class="uc-card-pass__desc"><?php echo esc_html((string) $card_pass_balance['desc']); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if (empty($card_pass_balance['only_password'])) : ?>
|
||||
<input type="text" class="uc-card-pass__input" name="aksrt_card_no" data-aksrt-card-no autocomplete="off" placeholder="<?php esc_attr_e('请输入卡号', 'aksrt'); ?>">
|
||||
<?php endif; ?>
|
||||
<input type="text" class="uc-card-pass__input" name="aksrt_card_password" data-aksrt-card-password autocomplete="off" placeholder="<?php esc_attr_e('请输入卡密', 'aksrt'); ?>">
|
||||
<button type="button" class="uc-card-pass__btn" data-aksrt-card-redeem data-type="balance">
|
||||
<?php esc_html_e('兑换余额', 'aksrt'); ?>
|
||||
</button>
|
||||
<p class="uc-card-pass__tip" data-aksrt-card-tip></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($card_pass_credits['enabled'])) : ?>
|
||||
<div class="uc-card-pass" data-aksrt-card-pass="credits">
|
||||
<div class="uc-card-pass__title">
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
/**
|
||||
* User center: cash wallet (站内余额) card + ledger.
|
||||
*
|
||||
* Expects extracted $context vars: $user_id, $wallet_balance, $balance_enabled, $card pass opts.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (empty($balance_enabled)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wallet = (float) ($wallet_balance ?? 0.0);
|
||||
|
||||
$card_pass_balance = ['enabled' => false, 'desc' => '', 'only_password' => true];
|
||||
if (class_exists('AKSRT_Charge_Card')) {
|
||||
$opts = AKSRT_Charge_Card::get_instance()->get_public_options();
|
||||
$card_pass_balance = is_array($opts['balance'] ?? null) ? $opts['balance'] : $card_pass_balance;
|
||||
} elseif (class_exists('AKSRT_Settings') && method_exists('AKSRT_Settings', 'get_payment_recharge_settings')) {
|
||||
$recharge = AKSRT_Settings::get_payment_recharge_settings();
|
||||
$pc = is_array($recharge['pass_charge'] ?? null) ? $recharge['pass_charge'] : [];
|
||||
$card_pass_balance = [
|
||||
'enabled' => !empty($pc['enabled']),
|
||||
'desc' => (string) ($pc['desc'] ?? ''),
|
||||
'only_password' => !isset($pc['only_password']) || !empty($pc['only_password']),
|
||||
];
|
||||
}
|
||||
?>
|
||||
<div class="uc-wallet-grid">
|
||||
<div class="uc-balance-card uc-balance-card--wallet">
|
||||
<div class="uc-balance-card__bg uc-balance-card__bg--wallet"></div>
|
||||
<div class="uc-balance-card__content">
|
||||
<div class="uc-balance-card__header">
|
||||
<span class="uc-balance-card__label"><?php esc_html_e('钱包余额', 'aksrt'); ?></span>
|
||||
<span class="uc-balance-card__currency"><?php esc_html_e('元', 'aksrt'); ?></span>
|
||||
</div>
|
||||
<div class="uc-balance-card__amount">
|
||||
<span class="uc-balance-card__value">
|
||||
<?php
|
||||
echo esc_html(
|
||||
class_exists('AKSRT_Balance')
|
||||
? AKSRT_Balance::format($wallet)
|
||||
: number_format_i18n($wallet, 2)
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
</div>
|
||||
<p class="uc-balance-card__tip"><?php esc_html_e('可用于站内余额支付、卡密充值入账', 'aksrt'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($card_pass_balance['enabled'])) : ?>
|
||||
<div class="uc-card-pass" data-aksrt-card-pass="balance">
|
||||
<div class="uc-card-pass__title">
|
||||
<i class="fas fa-ticket-alt" aria-hidden="true"></i>
|
||||
<span><?php esc_html_e('卡密兑换余额', 'aksrt'); ?></span>
|
||||
</div>
|
||||
<?php if (!empty($card_pass_balance['desc'])) : ?>
|
||||
<p class="uc-card-pass__desc"><?php echo esc_html((string) $card_pass_balance['desc']); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if (empty($card_pass_balance['only_password'])) : ?>
|
||||
<input type="text" class="uc-card-pass__input" name="aksrt_card_no" data-aksrt-card-no autocomplete="off" placeholder="<?php esc_attr_e('请输入卡号', 'aksrt'); ?>">
|
||||
<?php endif; ?>
|
||||
<input type="text" class="uc-card-pass__input" name="aksrt_card_password" data-aksrt-card-password autocomplete="off" placeholder="<?php esc_attr_e('请输入卡密', 'aksrt'); ?>">
|
||||
<button type="button" class="uc-card-pass__btn" data-aksrt-card-redeem data-type="balance">
|
||||
<?php esc_html_e('兑换余额', 'aksrt'); ?>
|
||||
</button>
|
||||
<p class="uc-card-pass__tip" data-aksrt-card-tip></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="uc-transactions uc-transactions--wallet">
|
||||
<div class="uc-transactions__header">
|
||||
<h3 class="uc-transactions__title">
|
||||
<i class="fas fa-list-ul" aria-hidden="true"></i>
|
||||
<?php esc_html_e('余额明细', 'aksrt'); ?>
|
||||
</h3>
|
||||
</div>
|
||||
<?php
|
||||
$wallet_page = max(1, isset($_GET['wallet_page']) ? (int) $_GET['wallet_page'] : 1);
|
||||
if (class_exists('AKSRT_Balance')) {
|
||||
$wlog = AKSRT_Balance::get_log(['user_id' => (int) $user_id, 'page' => $wallet_page, 'per_page' => 10]);
|
||||
} else {
|
||||
$wlog = ['items' => [], 'total' => 0];
|
||||
}
|
||||
if (!empty($wlog['items'])) :
|
||||
?>
|
||||
<div class="uc-transactions__list">
|
||||
<?php foreach ($wlog['items'] as $row) :
|
||||
$delta = (float) $row['delta'];
|
||||
$delta_class = $delta >= 0 ? 'is-positive' : 'is-negative';
|
||||
$delta_txt = ($delta > 0 ? '+' : '') . (class_exists('AKSRT_Balance') ? AKSRT_Balance::format($delta) : number_format_i18n($delta, 2));
|
||||
?>
|
||||
<div class="uc-transactions__item">
|
||||
<div class="uc-transactions__icon <?php echo esc_attr($delta_class); ?>">
|
||||
<i class="fas fa-<?php echo $delta >= 0 ? 'arrow-up' : 'arrow-down'; ?>" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="uc-transactions__info">
|
||||
<div class="uc-transactions__reason">
|
||||
<?php
|
||||
echo esc_html(
|
||||
class_exists('AKSRT_Balance')
|
||||
? AKSRT_Balance::reason_label((string) $row['reason'])
|
||||
: (string) $row['reason']
|
||||
);
|
||||
?>
|
||||
<?php if (!empty($row['remark'])) : ?>
|
||||
<span class="uc-transactions__remark">(<?php echo esc_html((string) $row['remark']); ?>)</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="uc-transactions__time">
|
||||
<?php echo esc_html(get_date_from_gmt((string) $row['created_at'], 'Y-m-d H:i')); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uc-transactions__amount">
|
||||
<span class="uc-transactions__delta <?php echo esc_attr($delta_class); ?>">
|
||||
<?php echo esc_html($delta_txt); ?>
|
||||
</span>
|
||||
<span class="uc-transactions__balance">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: wallet balance */
|
||||
esc_html__('余额 %s', 'aksrt'),
|
||||
esc_html(
|
||||
class_exists('AKSRT_Balance')
|
||||
? AKSRT_Balance::format((float) $row['balance_after'])
|
||||
: number_format_i18n((float) $row['balance_after'], 2)
|
||||
)
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php
|
||||
$total_pages = (int) ceil((int) ($wlog['total'] ?? 0) / 10);
|
||||
if ($total_pages > 1 && function_exists('aksrt_render_profile_pagination')) {
|
||||
aksrt_render_profile_pagination($total_pages, $wallet_page, 'wallet_page');
|
||||
}
|
||||
?>
|
||||
<?php else : ?>
|
||||
<div class="uc-transactions__empty">
|
||||
<div class="uc-transactions__empty-icon">
|
||||
<i class="fas fa-wallet" aria-hidden="true"></i>
|
||||
</div>
|
||||
<p><?php esc_html_e('还没有任何余额流水', 'aksrt'); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* User center profile credits part (orchestrator).
|
||||
* User center credits panel orchestrator.
|
||||
*
|
||||
* Zibll-like dual assets: cash wallet + points, when each is enabled.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -11,7 +13,24 @@ $context = is_array($args['context'] ?? null) ? $args['context'] : [];
|
||||
extract($context, EXTR_SKIP); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
|
||||
|
||||
$dir = __DIR__;
|
||||
require $dir . '/credits-balance.php';
|
||||
require $dir . '/credits-vip.php';
|
||||
require $dir . '/credits-signin.php';
|
||||
require $dir . '/credits-transactions.php';
|
||||
|
||||
$show_wallet = !empty($balance_enabled);
|
||||
$show_credits = !empty($credits_enabled);
|
||||
|
||||
if ($show_wallet) {
|
||||
require $dir . '/credits-wallet.php';
|
||||
}
|
||||
|
||||
// Points block (existing UI) — only when credits system on.
|
||||
if ($show_credits) {
|
||||
// Rename label in balance card is handled inside credits-balance (账户余额 → 积分).
|
||||
require $dir . '/credits-balance.php';
|
||||
require $dir . '/credits-vip.php';
|
||||
require $dir . '/credits-signin.php';
|
||||
require $dir . '/credits-transactions.php';
|
||||
} elseif ($show_wallet) {
|
||||
// Wallet-only: still show VIP block if enabled.
|
||||
if (!empty($show_vip)) {
|
||||
require $dir . '/credits-vip.php';
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (empty($orders_url) && empty($show_vip) && empty($show_credit_tabs)) {
|
||||
if (empty($orders_url) && empty($show_vip) && empty($show_credit_tabs) && empty($balance_enabled)) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
|
||||
Reference in new issue
Block a user