feat(forum): P1 topic coupons, P2 plate follow gateway, cash creator revenue

- Topic_Pay: soft/hard coupon validate, payable amount, free-after-discount, paid burn
- Creator_Revenue: settle content/topic/plate_follow cash (type=order), keep shop path
- Plate VIP1/VIP2 meta + resolve_plate_follow_pay_price via aksrt_get_user_vip_level
- New AKSRT_Plate_Follow_Pay REST multi-gateway; remove Credits×100 money bypass
- Frontend: cms-download plate_follow apiKind + forum-governance money cashier bridge
This commit is contained in:
kate522 committed 2026-07-15 13:04:04 +08:00
1 parent 1a15ae7cea
commit 78d3189f8f
14 files changed
+1189 -169

No files matched your search

@@ -168,9 +168,10 @@ class AKSRT_Plate_Meta_Box {
<p>
<label for="aksrt_plate_follow_pay_modo"><strong><?php esc_html_e('关注支付方式', 'aksrt'); ?></strong></label>
<select id="aksrt_plate_follow_pay_modo" name="aksrt_plate_follow_pay_modo" class="widefat">
<option value="money" <?php selected(($follow_pay['modo'] ?? 'money'), 'money'); ?>><?php esc_html_e('现金(余额)', 'aksrt'); ?></option>
<option value="money" <?php selected(($follow_pay['modo'] ?? 'money'), 'money'); ?>><?php esc_html_e('现金', 'aksrt'); ?></option>
<option value="points" <?php selected(($follow_pay['modo'] ?? ''), 'points'); ?>><?php esc_html_e('积分', 'aksrt'); ?></option>
</select>
<span class="description" style="display:block;"><?php esc_html_e('现金走多网关收银台;积分仍即时扣点。', 'aksrt'); ?></span>
</p>
<p>
<label for="aksrt_plate_follow_pay_price"><strong><?php esc_html_e('现金价格(元)', 'aksrt'); ?></strong></label>
@@ -181,9 +182,13 @@ class AKSRT_Plate_Meta_Box {
<input type="number" step="1" min="0" class="widefat" name="aksrt_plate_follow_pay_points" id="aksrt_plate_follow_pay_points" value="<?php echo esc_attr((string) (int) ($follow_pay['points'] ?? 0)); ?>">
</p>
<p>
<label for="aksrt_plate_follow_pay_vip_price"><strong><?php esc_html_e('VIP 价格(可选)', 'aksrt'); ?></strong></label>
<input type="number" step="0.01" min="0" class="widefat" name="aksrt_plate_follow_pay_vip_price" id="aksrt_plate_follow_pay_vip_price" value="<?php echo esc_attr((string) ($follow_pay['vip_price'] ?? '')); ?>" placeholder="<?php esc_attr_e('留空=不设 VIP 价;0=VIP 免费', 'aksrt'); ?>">
<span class="description"><?php esc_html_e('现金模式用元;积分模式填积分数。', 'aksrt'); ?></span>
<label for="aksrt_plate_follow_pay_vip1_price"><strong><?php esc_html_e('VIP1 价格(可选)', 'aksrt'); ?></strong></label>
<input type="number" step="0.01" min="0" class="widefat" name="aksrt_plate_follow_pay_vip1_price" id="aksrt_plate_follow_pay_vip1_price" value="<?php echo esc_attr((string) ($follow_pay['vip1_price'] ?? '')); ?>" placeholder="<?php esc_attr_e('留空=不设 VIP1 价;0=VIP1 免费', 'aksrt'); ?>">
</p>
<p>
<label for="aksrt_plate_follow_pay_vip2_price"><strong><?php esc_html_e('VIP2 价格(可选)', 'aksrt'); ?></strong></label>
<input type="number" step="0.01" min="0" class="widefat" name="aksrt_plate_follow_pay_vip2_price" id="aksrt_plate_follow_pay_vip2_price" value="<?php echo esc_attr((string) ($follow_pay['vip2_price'] ?? '')); ?>" placeholder="<?php esc_attr_e('留空=不设 VIP2 价;0=VIP2 免费', 'aksrt'); ?>">
<span class="description"><?php esc_html_e('现金模式用元;积分模式填积分数。未填 VIP1 时仍可读旧「VIP 价格」字段。', 'aksrt'); ?></span>
</p>
<hr>
<?php
@@ -391,6 +396,8 @@ class AKSRT_Plate_Meta_Box {
delete_post_meta($post_id, '_aksrt_follow_pay_price');
delete_post_meta($post_id, '_aksrt_follow_pay_points');
delete_post_meta($post_id, '_aksrt_follow_pay_vip_price');
delete_post_meta($post_id, '_aksrt_follow_pay_vip1_price');
delete_post_meta($post_id, '_aksrt_follow_pay_vip2_price');
return;
}
@@ -399,16 +406,25 @@ class AKSRT_Plate_Meta_Box {
update_post_meta($post_id, '_aksrt_follow_pay_price', $price);
update_post_meta($post_id, '_aksrt_follow_pay_points', $points);
if (isset($_POST['aksrt_plate_follow_pay_vip_price']) && (string) wp_unslash($_POST['aksrt_plate_follow_pay_vip_price']) !== '') {
$vip = max(0, (float) wp_unslash($_POST['aksrt_plate_follow_pay_vip_price']));
update_post_meta($post_id, '_aksrt_follow_pay_vip_price', $vip);
if (isset($_POST['aksrt_plate_follow_pay_vip1_price']) && (string) wp_unslash($_POST['aksrt_plate_follow_pay_vip1_price']) !== '') {
$vip1 = max(0, (float) wp_unslash($_POST['aksrt_plate_follow_pay_vip1_price']));
update_post_meta($post_id, '_aksrt_follow_pay_vip1_price', $vip1);
// Keep legacy single VIP key in sync with VIP1 for old readers.
update_post_meta($post_id, '_aksrt_follow_pay_vip_price', $vip1);
} else {
delete_post_meta($post_id, '_aksrt_follow_pay_vip1_price');
delete_post_meta($post_id, '_aksrt_follow_pay_vip_price');
}
if (isset($_POST['aksrt_plate_follow_pay_vip2_price']) && (string) wp_unslash($_POST['aksrt_plate_follow_pay_vip2_price']) !== '') {
update_post_meta($post_id, '_aksrt_follow_pay_vip2_price', max(0, (float) wp_unslash($_POST['aksrt_plate_follow_pay_vip2_price'])));
} else {
delete_post_meta($post_id, '_aksrt_follow_pay_vip2_price');
}
}
/**
* @return array{enabled:bool,modo:string,price:float,points:int,vip_price:string}
* @return array{enabled:bool,modo:string,price:float,points:int,vip1_price:string,vip2_price:string}
*/
private function get_follow_pay_meta(int $plate_id): array {
$enabled = (int) get_post_meta($plate_id, '_aksrt_follow_pay', true) === 1;
@@ -416,15 +432,25 @@ class AKSRT_Plate_Meta_Box {
if (!in_array($modo, ['money', 'points'], true)) {
$modo = 'money';
}
$vip_raw = get_post_meta($plate_id, '_aksrt_follow_pay_vip_price', true);
$vip_set = ($vip_raw !== '' && $vip_raw !== null && $vip_raw !== false);
$vip1_raw = get_post_meta($plate_id, '_aksrt_follow_pay_vip1_price', true);
$vip1_set = ($vip1_raw !== '' && $vip1_raw !== null && $vip1_raw !== false);
if (!$vip1_set) {
// Legacy single VIP key → vip1.
$vip1_raw = get_post_meta($plate_id, '_aksrt_follow_pay_vip_price', true);
$vip1_set = ($vip1_raw !== '' && $vip1_raw !== null && $vip1_raw !== false);
}
$vip2_raw = get_post_meta($plate_id, '_aksrt_follow_pay_vip2_price', true);
$vip2_set = ($vip2_raw !== '' && $vip2_raw !== null && $vip2_raw !== false);
return [
'enabled' => $enabled,
'modo' => $modo,
'price' => (float) get_post_meta($plate_id, '_aksrt_follow_pay_price', true),
'points' => (int) get_post_meta($plate_id, '_aksrt_follow_pay_points', true),
'vip_price' => $vip_set ? (string) (float) $vip_raw : '',
'enabled' => $enabled,
'modo' => $modo,
'price' => (float) get_post_meta($plate_id, '_aksrt_follow_pay_price', true),
'points' => (int) get_post_meta($plate_id, '_aksrt_follow_pay_points', true),
'vip1_price' => $vip1_set ? (string) (float) $vip1_raw : '',
'vip2_price' => $vip2_set ? (string) (float) $vip2_raw : '',
];
}