diff --git a/assets/css/routes/user-center/credits.css b/assets/css/routes/user-center/credits.css index 9f4b1dbe..e328f3e8 100644 --- a/assets/css/routes/user-center/credits.css +++ b/assets/css/routes/user-center/credits.css @@ -1075,3 +1075,13 @@ body.uc-modal-open { height: 100%; background: linear-gradient(90deg, #22c55e, #16a34a); } + +/* VIP tab */ +.uc-vip-tab .user-content-myvip{position:relative;padding:16px;margin-bottom:16px} +.uc-vip-level-cards{display:flex;flex-wrap:wrap;gap:12px} +.uc-vip-level-card{position:relative;flex:1 1 240px;padding:18px 14px;overflow:hidden} +.uc-vip-level-card .v-equity{text-align:left;margin:10px 0 14px;padding-left:1.1em;font-size:13px;line-height:1.55} +.uc-vip-level-card .pay-vip{display:inline-block;margin-top:4px} +.uc-vip-assets-entry{gap:12px} +.jb-vip1{background:linear-gradient(90deg,#f6c453,#f39c12);color:#3b2a00;border:0} +.jb-vip2{background:linear-gradient(90deg,#8e44ad,#3f51b5);color:#fff;border:0} diff --git a/inc/helpers/aksrt-user-center.php b/inc/helpers/aksrt-user-center.php index 3a1ab39e..973cc8e7 100644 --- a/inc/helpers/aksrt-user-center.php +++ b/inc/helpers/aksrt-user-center.php @@ -169,6 +169,7 @@ if (!function_exists('aksrt_capture_user_center_view')) { 'comments' => 'comments', 'favorites' => 'favorites', 'credits' => 'credits', + 'vip' => 'vip', 'settings' => 'settings', 'header' => 'header', 'sidebar' => 'sidebar', @@ -193,7 +194,7 @@ if (!function_exists('aksrt_capture_user_center_panel')) { * Capture a built-in or registered user-center panel body. */ function aksrt_capture_user_center_panel(string $tab_key, array $tab, array $context): string { - $built_in_tabs = ['profile', 'posts', 'comments', 'favorites', 'credits', 'settings']; + $built_in_tabs = ['profile', 'posts', 'comments', 'favorites', 'credits', 'vip', 'settings']; if (in_array($tab_key, $built_in_tabs, true)) { return aksrt_capture_user_center_view($tab_key, $context); } diff --git a/inc/helpers/aksrt-vip.php b/inc/helpers/aksrt-vip.php index ffa105d2..e1987214 100644 --- a/inc/helpers/aksrt-vip.php +++ b/inc/helpers/aksrt-vip.php @@ -407,10 +407,10 @@ function aksrt_get_vip_info(int $user_id = 0): array { if (!function_exists('aksrt_get_vip_purchase_url')) { function aksrt_get_vip_purchase_url(): string { if (function_exists('aksrt_get_user_center_tab_url')) { - return aksrt_get_user_center_tab_url('credits'); + return aksrt_get_user_center_tab_url('vip'); } if (function_exists('aksrt_get_user_center_url')) { - return aksrt_get_user_center_url(); + return aksrt_get_user_center_url('vip'); } return home_url('/'); } diff --git a/inc/helpers/user-center-renderers/profile-credits.php b/inc/helpers/user-center-renderers/profile-credits.php index 8bd30da1..7bbd7b98 100644 --- a/inc/helpers/user-center-renderers/profile-credits.php +++ b/inc/helpers/user-center-renderers/profile-credits.php @@ -39,7 +39,15 @@ if ($show_wallet || $show_credits) : endif; if (!empty($show_vip)) { - require $dir . '/credits-vip.php'; + // Slim entry to dedicated VIP tab (full shop lives under tab=vip). + $vip_url = function_exists('aksrt_get_user_center_tab_url') + ? aksrt_get_user_center_tab_url('vip') + : '#'; + echo '
'; + echo '
' . esc_html__('我的会员', 'aksrt') . '
'; + echo '
' . esc_html__('查看权益、续费与升级', 'aksrt') . '
'; + echo '' . esc_html__('进入会员中心', 'aksrt') . ''; + echo '
'; } if ($show_credits) { require $dir . '/credits-signin.php'; diff --git a/inc/helpers/user-center-renderers/profile-vip.php b/inc/helpers/user-center-renderers/profile-vip.php new file mode 100644 index 00000000..f8ea303e --- /dev/null +++ b/inc/helpers/user-center-renderers/profile-vip.php @@ -0,0 +1,13 @@ + - + diff --git a/inc/helpers/user-center-renderers/vip-tab.php b/inc/helpers/user-center-renderers/vip-tab.php new file mode 100644 index 00000000..22b2e232 --- /dev/null +++ b/inc/helpers/user-center-renderers/vip-tab.php @@ -0,0 +1,152 @@ +' . esc_html__('会员功能未启用。', 'aksrt') . ''; + return; +} + +$user_id = (int) ($user_id ?? get_current_user_id()); +$level = function_exists('aksrt_get_user_vip_level') ? aksrt_get_user_vip_level($user_id) : 0; +$expires = (int) get_user_meta($user_id, 'aksrt_vip_expires', true); +$expired_level = (int) get_user_meta($user_id, 'aksrt_vip_level_expired', true); +$levels = is_array($vip_settings['levels'] ?? null) ? $vip_settings['levels'] : []; +$desc_top = (string) ($vip_settings['desc'] ?? ''); + +$user = get_userdata($user_id); +$display = $user ? $user->display_name : ''; +$avatar = get_avatar($user_id, 56); + +// Status header box. +$status_html = ''; +$btn_type = 'pay'; +if ($level > 0) { + $lv_name = (string) ($levels[$level]['name'] ?? ('VIP' . $level)); + $lv_desc = (string) ($levels[$level]['desc'] ?? ''); + if ($expires <= 0) { + $badge = '' . esc_html__('永久会员', 'aksrt') . ''; + if ($level < 2) { + $btn_type = 'upgrade'; + } + } else { + $badge = '' + . esc_html(sprintf(__('到期时间:%s', 'aksrt'), wp_date('Y年m月d日', $expires))) . ''; + $btn_type = 'renew_' . $level; + } + $status_html = '
' + . '
' . esc_html($lv_name) . '
' + . $badge + . ($lv_desc !== '' ? '
' . esc_html($lv_desc) . '
' : '') + . '
'; +} elseif ($expired_level > 0) { + $exp_label = $expires > 0 + ? sprintf(__('过期时间:%s', 'aksrt'), wp_date('Y年m月d日', $expires)) + : __('已过期', 'aksrt'); + $status_html = '
' + . '
' . esc_html__('会员已过期', 'aksrt') . '
' + . '
' . esc_html($exp_label) . '
' + . ($desc_top !== '' ? '
' . esc_html($desc_top) . '
' : '') + . '
'; + $btn_type = 'pay'; +} else { + $status_html = '
' + . '
' . esc_html__('开通会员', 'aksrt') . '
' + . ($desc_top !== '' ? '
' . esc_html($desc_top) . '
' : '
' . esc_html__('开通会员,尊享专属特权', 'aksrt') . '
') + . '
'; + $btn_type = 'pay'; +} + +// Level cards. +$cards = ''; +foreach ([1, 2] as $lv) { + if (empty($levels[$lv]['enabled'])) { + continue; + } + $lv_name = (string) ($levels[$lv]['name'] ?? ('VIP' . $lv)); + $lv_desc = (string) ($levels[$lv]['desc'] ?? ''); + $equity = (string) ($levels[$lv]['equity'] ?? ''); + $cta = sprintf(__('开通%s', 'aksrt'), $lv_name); + $vip_attr = $lv; + if (str_starts_with($btn_type, 'renew_')) { + $renew_lv = (int) substr($btn_type, 6); + if ($lv === $renew_lv) { + $cta = sprintf(__('续费%s', 'aksrt'), $lv_name); + } elseif ($lv > $renew_lv) { + $cta = sprintf(__('升级%s', 'aksrt'), $lv_name); + } else { + continue; + } + } elseif ($btn_type === 'upgrade') { + if ($lv <= $level) { + continue; + } + $cta = sprintf(__('升级%s', 'aksrt'), $lv_name); + $vip_attr = 2; + } elseif ($level > 0 && $lv < $level) { + continue; + } elseif ($level > 0 && $lv === $level) { + $cta = sprintf(__('续费%s', 'aksrt'), $lv_name); + } + + $cards .= '
'; + $cards .= '
'; + $cards .= '
'; + $cards .= '
'; + $cards .= '
' . esc_html($lv_name) . '
'; + if ($lv_desc !== '') { + $cards .= '
' . esc_html($lv_desc) . '
'; + } + $cards .= '
'; + if ($equity !== '') { + $cards .= ''; + } + $cards .= '' + . esc_html($cta) . ''; + $cards .= '
'; +} + +// Points exchange (non-VIP only) — slim link; full shop stays optional under credits. +$points_html = ''; +if ($level <= 0 && !empty($vip_settings['points_exchange']['enabled'])) { + $points_html = ''; +} +?> +
+
+
+
+
+
+
+ +
+
+
+ +
+ +
+ + + + +
+ +
+ +
diff --git a/src/AKSRT/User/Center.php b/src/AKSRT/User/Center.php index 4b16105d..7b6e651f 100644 --- a/src/AKSRT/User/Center.php +++ b/src/AKSRT/User/Center.php @@ -73,6 +73,12 @@ class Center { 'priority' => 50, 'type' => 'panel', ], + 'vip' => [ + 'label' => __('我的会员', 'aksrt'), + 'icon' => 'crown', + 'priority' => 45, + 'type' => 'panel', + ], 'notif' => [ 'label' => __('消息通知', 'aksrt'), 'icon' => 'bell', @@ -119,12 +125,26 @@ class Center { $this->panels['credits'] = $panel; } + // Dedicated VIP tab when membership is enabled. + $vip_on = class_exists('\AKSRT\Settings\Settings') + && !empty(\AKSRT\Settings\Settings::get_payment_vip_settings()['enabled']); + if ($vip_on && !isset($this->panels['vip'])) { + $this->panels['vip'] = $definitions['vip']; + } elseif (!$vip_on && isset($this->panels['vip'])) { + unset($this->panels['vip']); + } + if (!isset($this->panels['settings'])) { $this->panels['settings'] = $definitions['settings']; } $this->panels['notif'] = $definitions['notif']; + // Keep stable order by priority. + uasort($this->panels, static function (array $a, array $b): int { + return ((int) ($a['priority'] ?? 100)) <=> ((int) ($b['priority'] ?? 100)); + }); + /** * 允许插件/子主题注册额外面板 *