feat(payment): VIP 作者分成档位 + get_user_vip_level
实现 aksrt_get_user_vip_level(0/1/2) 与 aksrt_is_vip2,统一 aksrt_is_vip; Creator_Revenue 现有 resolve_share_ratio 按 VIP1/VIP2 比例生效。 赠送 vip_days 时补写 aksrt_vip_level≥1,不降级 VIP2。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
347968b6b1
commit
4862142fb6
2 files changed
+134
-39
No files matched your search
@@ -334,6 +334,11 @@ trait AKSRT_Shop_Part_3 {
|
|||||||
$current = (int) get_user_meta($user_id, 'aksrt_vip_expires', true);
|
$current = (int) get_user_meta($user_id, 'aksrt_vip_expires', true);
|
||||||
$base = max($current, time());
|
$base = max($current, time());
|
||||||
update_user_meta($user_id, 'aksrt_vip_expires', $base + ((int) $gift_value * DAY_IN_SECONDS));
|
update_user_meta($user_id, 'aksrt_vip_expires', $base + ((int) $gift_value * DAY_IN_SECONDS));
|
||||||
|
// 赠送 VIP 天数时确保至少 VIP1;不降级已有 VIP2。
|
||||||
|
$level = (int) get_user_meta($user_id, 'aksrt_vip_level', true);
|
||||||
|
if ($level < 1) {
|
||||||
|
update_user_meta($user_id, 'aksrt_vip_level', 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+129
-39
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* AKSRT VIP Helper — VIP 会员展示辅助函数
|
* AKSRT VIP Helper — VIP 会员等级与展示辅助函数
|
||||||
*
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
*/
|
*/
|
||||||
@@ -8,47 +8,131 @@
|
|||||||
defined('ABSPATH') || exit;
|
defined('ABSPATH') || exit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查用户是否为 VIP
|
* 解析用户 VIP 等级:0=非 VIP,1=VIP1,2=VIP2。
|
||||||
*
|
*
|
||||||
* 判定逻辑:
|
* 判定顺序:
|
||||||
* 1. VIP 功能未启用 → false
|
* 1. VIP 功能未启用 → 0
|
||||||
* 2. 用户角色在 exempt_roles 白名单中 → true(管理员/编辑等特权角色)
|
* 2. 角色在 vip_exempt_roles 白名单 → 当前启用的最高档
|
||||||
* 3. 用户有有效的 VIP 订单(status=completed 且未过期) → true
|
* 3. user meta aksrt_vip_level + aksrt_vip_expires(过期 lazy 清 0;expires=0 且 level>0 视为永久)
|
||||||
|
* 4. 有效 VIP 订单兜底 → 1(套餐无 level 列,订单无法区分 VIP2)
|
||||||
|
* 5. 按 pay_user_vip_1/2 开关钳制
|
||||||
|
*
|
||||||
|
* @param int $user_id 用户 ID,0 时取当前用户。
|
||||||
|
* @return int 0|1|2
|
||||||
|
*/
|
||||||
|
function aksrt_get_user_vip_level(int $user_id = 0): int {
|
||||||
|
if ($user_id <= 0) {
|
||||||
|
$user_id = get_current_user_id();
|
||||||
|
}
|
||||||
|
if ($user_id <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!class_exists('AKSRT_Settings')) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$vip_settings = AKSRT_Settings::get_payment_vip_settings();
|
||||||
|
if (empty($vip_settings['enabled'])) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$levels = is_array($vip_settings['levels'] ?? null) ? $vip_settings['levels'] : [];
|
||||||
|
$vip1_enabled = !empty($levels[1]['enabled']);
|
||||||
|
$vip2_enabled = !empty($levels[2]['enabled']);
|
||||||
|
|
||||||
|
// 1. 角色豁免:特权角色取当前启用最高档。
|
||||||
|
$paid_settings = AKSRT_Settings::get_paid_content_settings();
|
||||||
|
$exempt_roles = $paid_settings['vip_exempt_roles'] ?? [];
|
||||||
|
if (!empty($exempt_roles)) {
|
||||||
|
$user = get_userdata($user_id);
|
||||||
|
if ($user && !empty(array_intersect((array) $user->roles, $exempt_roles))) {
|
||||||
|
if ($vip2_enabled) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if ($vip1_enabled) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$candidate = 0;
|
||||||
|
|
||||||
|
// 2. meta 主路径。
|
||||||
|
$meta_level = (int) get_user_meta($user_id, 'aksrt_vip_level', true);
|
||||||
|
$expires = (int) get_user_meta($user_id, 'aksrt_vip_expires', true);
|
||||||
|
|
||||||
|
if ($meta_level > 0) {
|
||||||
|
if ($expires > 0 && $expires < time()) {
|
||||||
|
// 过期:lazy 清 level,与 capabilities 读 meta 对齐。
|
||||||
|
update_user_meta($user_id, 'aksrt_vip_level', 0);
|
||||||
|
$candidate = 0;
|
||||||
|
} else {
|
||||||
|
// expires === 0 视为永久;expires >= now 视为有效。
|
||||||
|
$candidate = min(2, max(0, $meta_level));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 订单兜底(meta 无有效等级时)。
|
||||||
|
if ($candidate <= 0 && class_exists('AKSRT_Order')) {
|
||||||
|
$order_mgr = AKSRT_Order::get_instance();
|
||||||
|
$valid_order = method_exists($order_mgr, 'get_valid_vip_order')
|
||||||
|
? $order_mgr->get_valid_vip_order($user_id)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
if (is_array($valid_order) && !empty($valid_order)) {
|
||||||
|
$order_expires = trim((string) ($valid_order['expires_at'] ?? ''));
|
||||||
|
$order_expired = false;
|
||||||
|
if ($order_expires !== '') {
|
||||||
|
$ts = strtotime($order_expires);
|
||||||
|
if ($ts !== false && $ts < time()) {
|
||||||
|
$order_expired = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$order_expired) {
|
||||||
|
// 套餐无 level 列:有效 VIP 订单至少视为 VIP1。
|
||||||
|
$candidate = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 按档位开关钳制。
|
||||||
|
if ($candidate >= 2) {
|
||||||
|
if ($vip2_enabled) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if ($vip1_enabled) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($candidate === 1) {
|
||||||
|
return $vip1_enabled ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查用户是否为 VIP(level >= 1)。
|
||||||
*
|
*
|
||||||
* @param int $user_id
|
* @param int $user_id
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function aksrt_is_vip(int $user_id = 0): bool {
|
function aksrt_is_vip(int $user_id = 0): bool {
|
||||||
if ($user_id <= 0) $user_id = get_current_user_id();
|
return aksrt_get_user_vip_level($user_id) >= 1;
|
||||||
if ($user_id <= 0) return false;
|
}
|
||||||
|
|
||||||
if (!class_exists('AKSRT_Settings')) return false;
|
/**
|
||||||
|
* 检查用户是否为 VIP2(level >= 2)。
|
||||||
$vip_settings = AKSRT_Settings::get_payment_vip_settings();
|
*
|
||||||
if (empty($vip_settings['enabled'])) return false;
|
* @param int $user_id
|
||||||
|
* @return bool
|
||||||
// 1. 角色豁免:VIP exempt_roles 中的角色直接视为 VIP
|
*/
|
||||||
$paid_settings = AKSRT_Settings::get_paid_content_settings();
|
function aksrt_is_vip2(int $user_id = 0): bool {
|
||||||
$exempt_roles = $paid_settings['vip_exempt_roles'] ?? [];
|
return aksrt_get_user_vip_level($user_id) >= 2;
|
||||||
if (!empty($exempt_roles)) {
|
|
||||||
$user = get_userdata($user_id);
|
|
||||||
if ($user && !empty(array_intersect($user->roles, $exempt_roles))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 订单判定:检查是否有有效的 VIP 订单
|
|
||||||
if (class_exists('AKSRT_Order')) {
|
|
||||||
$order_mgr = AKSRT_Order::get_instance();
|
|
||||||
$valid_order = method_exists($order_mgr, 'get_valid_vip_order')
|
|
||||||
? $order_mgr->get_valid_vip_order($user_id)
|
|
||||||
: null;
|
|
||||||
if ($valid_order) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,7 +141,9 @@ function aksrt_is_vip(int $user_id = 0): bool {
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function aksrt_get_vip_badge_text(): string {
|
function aksrt_get_vip_badge_text(): string {
|
||||||
if (!class_exists('AKSRT_Settings')) return 'VIP';
|
if (!class_exists('AKSRT_Settings')) {
|
||||||
|
return 'VIP';
|
||||||
|
}
|
||||||
|
|
||||||
$vip_settings = AKSRT_Settings::get_payment_vip_settings();
|
$vip_settings = AKSRT_Settings::get_payment_vip_settings();
|
||||||
return sanitize_text_field($vip_settings['badge_text'] ?? 'VIP');
|
return sanitize_text_field($vip_settings['badge_text'] ?? 'VIP');
|
||||||
@@ -71,7 +157,9 @@ function aksrt_get_vip_badge_text(): string {
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function aksrt_render_vip_badge(int $user_id = 0, string $size = 'sm'): string {
|
function aksrt_render_vip_badge(int $user_id = 0, string $size = 'sm'): string {
|
||||||
if (!aksrt_is_vip($user_id)) return '';
|
if (!aksrt_is_vip($user_id)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
$badge_text = aksrt_get_vip_badge_text();
|
$badge_text = aksrt_get_vip_badge_text();
|
||||||
$size_class = 'aksrt-vip-badge--' . $size;
|
$size_class = 'aksrt-vip-badge--' . $size;
|
||||||
@@ -83,14 +171,16 @@ function aksrt_render_vip_badge(int $user_id = 0, string $size = 'sm'): string {
|
|||||||
* 获取用户 VIP 等级信息(用于展示)
|
* 获取用户 VIP 等级信息(用于展示)
|
||||||
*
|
*
|
||||||
* @param int $user_id
|
* @param int $user_id
|
||||||
* @return array{is_vip: bool, badge_text: string, badge_html: string, name: string}
|
* @return array{is_vip: bool, level: int, badge_text: string, badge_html: string, name: string}
|
||||||
*/
|
*/
|
||||||
function aksrt_get_vip_info(int $user_id = 0): array {
|
function aksrt_get_vip_info(int $user_id = 0): array {
|
||||||
$is_vip = aksrt_is_vip($user_id);
|
$level = aksrt_get_user_vip_level($user_id);
|
||||||
|
$is_vip = $level >= 1;
|
||||||
$badge_text = aksrt_get_vip_badge_text();
|
$badge_text = aksrt_get_vip_badge_text();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'is_vip' => $is_vip,
|
'is_vip' => $is_vip,
|
||||||
|
'level' => $level,
|
||||||
'badge_text' => $badge_text,
|
'badge_text' => $badge_text,
|
||||||
'badge_html' => $is_vip ? aksrt_render_vip_badge($user_id) : '',
|
'badge_html' => $is_vip ? aksrt_render_vip_badge($user_id) : '',
|
||||||
'name' => $is_vip ? ($badge_text . '会员') : '普通用户',
|
'name' => $is_vip ? ($badge_text . '会员') : '普通用户',
|
||||||
|
|||||||
Reference in new issue
Block a user