feat(user-center): redesign sidebar and wallet tips
This commit is contained in:
1 parent
82e71d1bf9
commit
a7f3caec59
24 files changed
+895
-528
No files matched your search
@@ -1,8 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Per-user tip (打赏) helpers — Zibll post_rewards_s + user QR parity.
|
||||
*
|
||||
* Meta: aksrt_rewards_weixin, aksrt_rewards_alipay (attachment id or URL).
|
||||
* On-site wallet tipping helpers.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -11,103 +9,125 @@ defined('ABSPATH') || exit;
|
||||
|
||||
if (!function_exists('aksrt_rewards_enabled')) {
|
||||
function aksrt_rewards_enabled(): bool {
|
||||
if (!class_exists('\AKSRT\Settings\Settings') || !method_exists('\AKSRT\Settings\Settings', 'get_post_page_settings')) {
|
||||
if (!class_exists('\AKSRT\Settings\Settings')) {
|
||||
return false;
|
||||
}
|
||||
$s = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
return !empty($s['rewards_enabled']) || !empty($s['post_rewards_s']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_get_user_rewards_img_urls')) {
|
||||
/**
|
||||
* @return array{weixin:string,alipay:string}
|
||||
*/
|
||||
function aksrt_get_user_rewards_img_urls(int $user_id): array {
|
||||
$out = ['weixin' => '', 'alipay' => ''];
|
||||
if ($user_id <= 0) {
|
||||
return $out;
|
||||
}
|
||||
foreach (['weixin' => 'aksrt_rewards_weixin', 'alipay' => 'aksrt_rewards_alipay'] as $key => $meta) {
|
||||
$raw = get_user_meta($user_id, $meta, true);
|
||||
if (is_numeric($raw) && (int) $raw > 0) {
|
||||
$url = wp_get_attachment_image_url((int) $raw, 'full');
|
||||
$out[$key] = is_string($url) ? $url : '';
|
||||
} else {
|
||||
$out[$key] = esc_url_raw((string) $raw);
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_user_has_rewards_qr')) {
|
||||
function aksrt_user_has_rewards_qr(int $user_id): bool {
|
||||
$urls = aksrt_get_user_rewards_img_urls($user_id);
|
||||
return $urls['weixin'] !== '' || $urls['alipay'] !== '';
|
||||
$settings = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
return !empty($settings['rewards_enabled']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_get_rewards_button')) {
|
||||
function aksrt_get_rewards_button(int $user_id, string $class = 'but jb-blue ml10 pw-1em'): string {
|
||||
if ($user_id <= 0 || !aksrt_rewards_enabled() || !aksrt_user_has_rewards_qr($user_id)) {
|
||||
function aksrt_get_rewards_button(int $user_id, string $class = 'but jb-blue ml10 pw-1em', int $post_id = 0): string {
|
||||
if ($user_id <= 0 || !aksrt_rewards_enabled()) {
|
||||
return '';
|
||||
}
|
||||
$label = '赞赏';
|
||||
if (class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'get_post_page_settings')) {
|
||||
$s = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
$label = (string) ($s['rewards_btn_text'] ?? $s['rewards_text'] ?? $label);
|
||||
if ($label === '') {
|
||||
$label = '赞赏';
|
||||
}
|
||||
}
|
||||
return '<button type="button" class="' . esc_attr($class) . ' aksrt-reward-open" data-aksrt-reward-open data-user-id="' . (int) $user_id . '"><i class="fa fa-gift em09" aria-hidden="true"></i> ' . esc_html($label) . '</button>';
|
||||
$settings = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
$label = (string) ($settings['rewards_btn_text'] ?? __('赞赏', 'aksrt'));
|
||||
return sprintf(
|
||||
'<button type="button" class="%1$s aksrt-reward-open" data-aksrt-reward-open data-user-id="%2$d" data-post-id="%3$d"><i class="fa fa-gift em09" aria-hidden="true"></i> <span class="action-btn__label">%4$s</span></button>',
|
||||
esc_attr($class),
|
||||
$user_id,
|
||||
$post_id,
|
||||
esc_html($label)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('aksrt_render_rewards_modal_for_user')) {
|
||||
function aksrt_render_rewards_modal_for_user(int $user_id): void {
|
||||
function aksrt_render_rewards_modal_for_user(int $user_id, int $post_id = 0): void {
|
||||
static $done = [];
|
||||
if ($user_id <= 0 || isset($done[$user_id])) {
|
||||
$key = $user_id . ':' . $post_id;
|
||||
if ($user_id <= 0 || isset($done[$key]) || !aksrt_rewards_enabled()) {
|
||||
return;
|
||||
}
|
||||
if (!aksrt_rewards_enabled() || !aksrt_user_has_rewards_qr($user_id)) {
|
||||
return;
|
||||
}
|
||||
$done[$user_id] = true;
|
||||
$urls = aksrt_get_user_rewards_img_urls($user_id);
|
||||
$label = '赞赏';
|
||||
if (class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'get_post_page_settings')) {
|
||||
$s = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
$label = (string) ($s['rewards_text'] ?? $label);
|
||||
if ($label === '') {
|
||||
$label = __('赞赏', 'aksrt');
|
||||
}
|
||||
}
|
||||
$done[$key] = true;
|
||||
$settings = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
$amounts = (array) ($settings['rewards_amounts'] ?? [5, 10, 20, 50, 100]);
|
||||
$recipient = get_userdata($user_id);
|
||||
?>
|
||||
<div class="reward-modal" id="reward-modal-<?php echo (int) $user_id; ?>" data-user-id="<?php echo (int) $user_id; ?>" aria-hidden="true">
|
||||
<div class="reward-modal" id="reward-modal-<?php echo (int) $user_id; ?>" data-user-id="<?php echo (int) $user_id; ?>" data-post-id="<?php echo (int) $post_id; ?>" aria-hidden="true">
|
||||
<div class="reward-modal__overlay" data-aksrt-reward-close></div>
|
||||
<div class="reward-modal__dialog" role="dialog" aria-modal="true">
|
||||
<div class="reward-modal__dialog" role="dialog" aria-modal="true" aria-labelledby="reward-title-<?php echo (int) $user_id; ?>">
|
||||
<button type="button" class="reward-modal__close" data-aksrt-reward-close aria-label="<?php esc_attr_e('关闭', 'aksrt'); ?>"><i class="fas fa-times" aria-hidden="true"></i></button>
|
||||
<div class="reward-modal__content">
|
||||
<h3><?php echo esc_html($label); ?></h3>
|
||||
<div class="reward-modal__qrcodes flex jc ac hh">
|
||||
<?php if ($urls['weixin'] !== '') : ?>
|
||||
<div class="reward-modal__qrcode text-center mr10">
|
||||
<img src="<?php echo esc_url($urls['weixin']); ?>" alt="<?php esc_attr_e('微信收款码', 'aksrt'); ?>" loading="lazy" decoding="async" />
|
||||
<div class="em09 muted-2-color mt6"><?php esc_html_e('微信', 'aksrt'); ?></div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($urls['alipay'] !== '') : ?>
|
||||
<div class="reward-modal__qrcode text-center">
|
||||
<img src="<?php echo esc_url($urls['alipay']); ?>" alt="<?php esc_attr_e('支付宝收款码', 'aksrt'); ?>" loading="lazy" decoding="async" />
|
||||
<div class="em09 muted-2-color mt6"><?php esc_html_e('支付宝', 'aksrt'); ?></div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<h3 id="reward-title-<?php echo (int) $user_id; ?>"><?php echo esc_html((string) ($settings['rewards_text'] ?? __('赞赏', 'aksrt'))); ?></h3>
|
||||
<p class="muted-2-color em09"><?php printf(esc_html__('赞赏将直接进入 %s 的站内余额', 'aksrt'), esc_html($recipient ? $recipient->display_name : __('作者', 'aksrt'))); ?></p>
|
||||
<div class="reward-amounts" data-aksrt-reward-amounts>
|
||||
<?php foreach ($amounts as $index => $amount) : ?>
|
||||
<button type="button" class="reward-amount<?php echo $index === 0 ? ' is-active' : ''; ?>" data-reward-amount="<?php echo esc_attr(number_format((float) $amount, 2, '.', '')); ?>">¥<?php echo esc_html(number_format_i18n((float) $amount, 2)); ?></button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php if (!empty($settings['rewards_custom'])) : ?>
|
||||
<label class="reward-custom"><span><?php esc_html_e('自定义金额', 'aksrt'); ?></span><input type="number" min="<?php echo esc_attr((string) ($settings['rewards_min'] ?? 1)); ?>" max="<?php echo esc_attr((string) ($settings['rewards_max'] ?? 1000)); ?>" step="0.01" data-aksrt-reward-custom placeholder="<?php esc_attr_e('输入金额', 'aksrt'); ?>"></label>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="btn-primary reward-modal__submit" data-aksrt-reward-submit><?php esc_html_e('余额赞赏', 'aksrt'); ?></button>
|
||||
<div class="reward-modal__message" data-aksrt-reward-message role="status"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
add_action('wp_ajax_aksrt_submit_tip', function (): void {
|
||||
check_ajax_referer('aksrt_public_nonce', 'nonce');
|
||||
if (!is_user_logged_in()) {
|
||||
wp_send_json_error(['message' => __('请先登录后赞赏', 'aksrt')], 401);
|
||||
}
|
||||
if (!aksrt_rewards_enabled() || !class_exists('\AKSRT\Credits\Balance') || !\AKSRT\Credits\Balance::enabled()) {
|
||||
wp_send_json_error(['message' => __('赞赏功能当前不可用', 'aksrt')], 400);
|
||||
}
|
||||
|
||||
$sender_id = get_current_user_id();
|
||||
$post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0;
|
||||
$recipient_id = isset($_POST['recipient_id']) ? absint($_POST['recipient_id']) : 0;
|
||||
if ($post_id > 0) {
|
||||
$post = get_post($post_id);
|
||||
if (!$post instanceof WP_Post || $post->post_status !== 'publish') {
|
||||
wp_send_json_error(['message' => __('赞赏内容不存在', 'aksrt')], 404);
|
||||
}
|
||||
$recipient_id = (int) $post->post_author;
|
||||
}
|
||||
if ($recipient_id <= 0 || !get_userdata($recipient_id) || $recipient_id === $sender_id) {
|
||||
wp_send_json_error(['message' => __('不能赞赏该用户', 'aksrt')], 400);
|
||||
}
|
||||
|
||||
$settings = \AKSRT\Settings\Settings::get_post_page_settings();
|
||||
$amount = isset($_POST['amount']) ? round((float) wp_unslash($_POST['amount']), 2) : 0.0;
|
||||
$minimum = (float) ($settings['rewards_min'] ?? 1);
|
||||
$maximum = (float) ($settings['rewards_max'] ?? 1000);
|
||||
if (!is_finite($amount) || $amount < $minimum || $amount > $maximum) {
|
||||
wp_send_json_error(['message' => sprintf(__('赞赏金额需在 ¥%1$s 至 ¥%2$s 之间', 'aksrt'), number_format_i18n($minimum, 2), number_format_i18n($maximum, 2))], 400);
|
||||
}
|
||||
if (empty($settings['rewards_custom'])) {
|
||||
$allowed_amounts = array_map(static fn($value): float => round((float) $value, 2), (array) ($settings['rewards_amounts'] ?? []));
|
||||
if (!in_array($amount, $allowed_amounts, true)) {
|
||||
wp_send_json_error(['message' => __('请选择预设的赞赏金额', 'aksrt')], 400);
|
||||
}
|
||||
}
|
||||
|
||||
$rate_key = 'aksrt_tip_rate_' . $sender_id;
|
||||
if (get_transient($rate_key)) {
|
||||
wp_send_json_error(['message' => __('操作太频繁,请稍后再试', 'aksrt')], 429);
|
||||
}
|
||||
set_transient($rate_key, 1, 3);
|
||||
|
||||
$result = \AKSRT\Credits\Balance::transfer(
|
||||
$sender_id,
|
||||
$recipient_id,
|
||||
$amount,
|
||||
'tip_sent',
|
||||
'tip_received',
|
||||
['type' => 'tip', 'id' => $post_id],
|
||||
$post_id > 0 ? sprintf(__('赞赏文章 #%d', 'aksrt'), $post_id) : __('用户赞赏', 'aksrt')
|
||||
);
|
||||
if (is_wp_error($result)) {
|
||||
wp_send_json_error(['message' => $result->get_error_message()], 400);
|
||||
}
|
||||
|
||||
wp_send_json_success([
|
||||
'message' => __('赞赏成功,金额已进入对方余额', 'aksrt'),
|
||||
'balance' => \AKSRT\Credits\Balance::format((float) $result['sender_balance']),
|
||||
]);
|
||||
});
|
||||
Reference in new issue
Block a user