feat(admin,forum): download logs, hidecontent, VIP tiers, users commerce

Add aksrt_download_logs workbench, zibll hidecontent alias + topic
partial-hide path, VIP1/VIP2 price matrix for topics, and users list
commerce snapshot column with deep links.
This commit is contained in:
kate522 committed 2026-07-15 11:13:48 +08:00
1 parent cf6ad0e972
commit 8d31e65ccd
14 files changed
+611 -32

No files matched your search

@@ -83,6 +83,19 @@ class AKSRT_Topic_Meta_Box {
$pay_vip_price = get_post_meta($post->ID, '_aksrt_pay_vip_price', true);
$vip_set = ($pay_vip_price !== '' && $pay_vip_price !== null && $pay_vip_price !== false);
$vip_price_val = $vip_set ? (float) $pay_vip_price : '';
$pay_vip1_price = get_post_meta($post->ID, '_aksrt_pay_vip1_price', true);
$pay_vip2_price = get_post_meta($post->ID, '_aksrt_pay_vip2_price', true);
$vip1_set = ($pay_vip1_price !== '' && $pay_vip1_price !== null && $pay_vip1_price !== false);
$vip2_set = ($pay_vip2_price !== '' && $pay_vip2_price !== null && $pay_vip2_price !== false);
// Migrate single VIP price into vip1 display if vip1 empty.
if (!$vip1_set && $vip_set) {
$vip1_set = true;
$pay_vip1_price = $pay_vip_price;
}
$credits_vip1 = get_post_meta($post->ID, '_aksrt_credits_vip1', true);
$credits_vip2 = get_post_meta($post->ID, '_aksrt_credits_vip2', true);
$credits_vip1_set = ($credits_vip1 !== '' && $credits_vip1 !== null && $credits_vip1 !== false);
$credits_vip2_set = ($credits_vip2 !== '' && $credits_vip2 !== null && $credits_vip2 !== false);
$pay_hide_part = (int) get_post_meta($post->ID, '_aksrt_pay_hide_part', true) === 1;
$view_roles = get_post_meta($post->ID, '_aksrt_visibility_roles', true);
if (!is_array($view_roles)) {
@@ -172,21 +185,33 @@ class AKSRT_Topic_Meta_Box {
<input type="number" step="1" min="0" class="widefat" name="aksrt_credits_cost" id="aksrt_credits_cost" value="<?php echo esc_attr((string) $credits_cost); ?>">
<span class="description"><?php esc_html_e('可见性为「支付积分后可见」时使用。', 'aksrt'); ?></span>
</p>
<p class="aksrt-topic-meta-credits-fields">
<label for="aksrt_credits_vip1"><strong><?php esc_html_e('VIP1 积分价', 'aksrt'); ?></strong></label>
<input type="number" step="1" min="0" class="widefat" name="aksrt_credits_vip1" id="aksrt_credits_vip1" value="<?php echo esc_attr($credits_vip1_set ? (string) (int) $credits_vip1 : ''); ?>" placeholder="<?php esc_attr_e('留空=不设', 'aksrt'); ?>">
</p>
<p class="aksrt-topic-meta-credits-fields">
<label for="aksrt_credits_vip2"><strong><?php esc_html_e('VIP2 积分价', 'aksrt'); ?></strong></label>
<input type="number" step="1" min="0" class="widefat" name="aksrt_credits_vip2" id="aksrt_credits_vip2" value="<?php echo esc_attr($credits_vip2_set ? (string) (int) $credits_vip2 : ''); ?>" placeholder="<?php esc_attr_e('留空=不设;0=免费', 'aksrt'); ?>">
</p>
<p class="aksrt-topic-meta-pay-fields">
<label for="aksrt_pay_price"><strong><?php esc_html_e('付费价格(元)', 'aksrt'); ?></strong></label>
<input type="number" step="0.01" min="0" class="widefat" name="aksrt_pay_price" id="aksrt_pay_price" value="<?php echo esc_attr((string) $pay_price); ?>">
</p>
<p class="aksrt-topic-meta-pay-fields">
<label for="aksrt_pay_vip_price"><strong><?php esc_html_e('VIP 价格(元)', 'aksrt'); ?></strong></label>
<input type="number" step="0.01" min="0" class="widefat" name="aksrt_pay_vip_price" id="aksrt_pay_vip_price" value="<?php echo esc_attr($vip_set ? (string) $vip_price_val : ''); ?>" placeholder="<?php esc_attr_e('留空=不设 VIP 价', 'aksrt'); ?>">
<span class="description"><?php esc_html_e('填 0 表示 VIP 免费;留空则 VIP 与普通同价。', 'aksrt'); ?></span>
<label for="aksrt_pay_vip1_price"><strong><?php esc_html_e('VIP1 价格(元)', 'aksrt'); ?></strong></label>
<input type="number" step="0.01" min="0" class="widefat" name="aksrt_pay_vip1_price" id="aksrt_pay_vip1_price" value="<?php echo esc_attr($vip1_set ? (string) (float) $pay_vip1_price : ''); ?>" placeholder="<?php esc_attr_e('留空=不设 VIP1 价', 'aksrt'); ?>">
</p>
<p class="aksrt-topic-meta-pay-fields">
<label for="aksrt_pay_vip2_price"><strong><?php esc_html_e('VIP2 价格(元)', 'aksrt'); ?></strong></label>
<input type="number" step="0.01" min="0" class="widefat" name="aksrt_pay_vip2_price" id="aksrt_pay_vip2_price" value="<?php echo esc_attr($vip2_set ? (string) (float) $pay_vip2_price : ''); ?>" placeholder="<?php esc_attr_e('留空=不设;0=VIP2 免费', 'aksrt'); ?>">
<span class="description"><?php esc_html_e('兼容旧「VIP 价格」字段:未填 VIP1 时仍可读 _aksrt_pay_vip_price。', 'aksrt'); ?></span>
</p>
<p class="aksrt-topic-meta-pay-hide-fields">
<label>
<input type="checkbox" name="aksrt_pay_hide_part" value="1" <?php checked($pay_hide_part); ?>>
<?php esc_html_e('仅隐藏部分内容', 'aksrt'); ?>
</label>
<span class="description" style="display:block;"><?php esc_html_e('开启后仍以全文门控为默认;部分隐藏依赖正文隐藏块。未解锁用户正文不会下发。', 'aksrt'); ?></span>
<span class="description" style="display:block;"><?php esc_html_e('开启后正文仍输出,付费块用 [payshow] 或 [hidecontent type="payshow"] 包裹。未开启则全文门控。', 'aksrt'); ?></span>
</p>
<?php
}
@@ -281,9 +306,22 @@ class AKSRT_Topic_Meta_Box {
}
update_post_meta($post_id, '_aksrt_credits_cost', $cost);
update_post_meta($post_id, '_aksrt_pay_credits', $cost);
if (isset($_POST['aksrt_credits_vip1']) && (string) wp_unslash($_POST['aksrt_credits_vip1']) !== '') {
update_post_meta($post_id, '_aksrt_credits_vip1', max(0, (int) wp_unslash($_POST['aksrt_credits_vip1'])));
} else {
delete_post_meta($post_id, '_aksrt_credits_vip1');
}
if (isset($_POST['aksrt_credits_vip2']) && (string) wp_unslash($_POST['aksrt_credits_vip2']) !== '') {
update_post_meta($post_id, '_aksrt_credits_vip2', max(0, (int) wp_unslash($_POST['aksrt_credits_vip2'])));
} else {
delete_post_meta($post_id, '_aksrt_credits_vip2');
}
} else {
delete_post_meta($post_id, '_aksrt_credits_cost');
delete_post_meta($post_id, '_aksrt_pay_credits');
delete_post_meta($post_id, '_aksrt_credits_vip1');
delete_post_meta($post_id, '_aksrt_credits_vip2');
}
// Cash pay.
@@ -291,15 +329,34 @@ class AKSRT_Topic_Meta_Box {
$price = isset($_POST['aksrt_pay_price']) ? max(0, (float) wp_unslash($_POST['aksrt_pay_price'])) : 0;
update_post_meta($post_id, '_aksrt_pay_price', $price);
if (isset($_POST['aksrt_pay_vip_price']) && (string) wp_unslash($_POST['aksrt_pay_vip_price']) !== '') {
$vip1_written = false;
if (isset($_POST['aksrt_pay_vip1_price']) && (string) wp_unslash($_POST['aksrt_pay_vip1_price']) !== '') {
$vip1 = max(0, (float) wp_unslash($_POST['aksrt_pay_vip1_price']));
update_post_meta($post_id, '_aksrt_pay_vip1_price', $vip1);
// Keep legacy single VIP key in sync with VIP1 for older readers.
update_post_meta($post_id, '_aksrt_pay_vip_price', $vip1);
$vip1_written = true;
} else {
delete_post_meta($post_id, '_aksrt_pay_vip1_price');
}
if (isset($_POST['aksrt_pay_vip2_price']) && (string) wp_unslash($_POST['aksrt_pay_vip2_price']) !== '') {
update_post_meta($post_id, '_aksrt_pay_vip2_price', max(0, (float) wp_unslash($_POST['aksrt_pay_vip2_price'])));
} else {
delete_post_meta($post_id, '_aksrt_pay_vip2_price');
}
// Legacy field if posted without vip1.
if (!$vip1_written && isset($_POST['aksrt_pay_vip_price']) && (string) wp_unslash($_POST['aksrt_pay_vip_price']) !== '') {
$vip = max(0, (float) wp_unslash($_POST['aksrt_pay_vip_price']));
update_post_meta($post_id, '_aksrt_pay_vip_price', $vip);
} else {
update_post_meta($post_id, '_aksrt_pay_vip1_price', $vip);
} elseif (!$vip1_written) {
delete_post_meta($post_id, '_aksrt_pay_vip_price');
}
} else {
delete_post_meta($post_id, '_aksrt_pay_price');
delete_post_meta($post_id, '_aksrt_pay_vip_price');
delete_post_meta($post_id, '_aksrt_pay_vip1_price');
delete_post_meta($post_id, '_aksrt_pay_vip2_price');
}
// Partial hide only meaningful for pay/credits; otherwise clear.