diff --git a/assets/admin/src/pages/users/UsersVerify.vue b/assets/admin/src/pages/users/UsersVerify.vue index 611f00be..f4e0cb45 100644 --- a/assets/admin/src/pages/users/UsersVerify.vue +++ b/assets/admin/src/pages/users/UsersVerify.vue @@ -31,7 +31,7 @@ - 人工审核台读取 `aksrt_user_verify_status`、`aksrt_user_verify_reason` 和审核日志。开启“邮箱验证通过视为已认证”后,公开页仍会优先展示邮件验证结果。 + 官方认证必须由用户提交申请并经审核通过;邮箱验证仅用于账户安全,不授予官方认证徽标。 @@ -48,9 +48,6 @@ - - - @@ -153,7 +150,6 @@ const form = reactive({ user_verify_enabled: true, user_verify_public_display: true, user_verify_badge_text: '已认证', - user_verify_accept_email_verified: true, user_verify_require_manual_review: false, user_verify_allow_apply: true, user_verify_disable_desc: '由于系统正在维护,暂时无法申请身份认证\n详情请联系管理员', @@ -316,7 +312,6 @@ async function load() { form.user_verify_enabled = schemaData.user_verify_enabled !== false form.user_verify_public_display = schemaData.user_verify_public_display !== false form.user_verify_badge_text = schemaData.user_verify_badge_text || '已认证' - form.user_verify_accept_email_verified = schemaData.user_verify_accept_email_verified !== false form.user_verify_require_manual_review = !!schemaData.user_verify_require_manual_review form.user_verify_allow_apply = schemaData.user_verify_allow_apply !== false form.user_verify_disable_desc = schemaData.user_verify_disable_desc @@ -359,7 +354,6 @@ async function handleSave() { user_verify_enabled: form.user_verify_enabled, user_verify_public_display: form.user_verify_public_display, user_verify_badge_text: form.user_verify_badge_text, - user_verify_accept_email_verified: form.user_verify_accept_email_verified, user_verify_require_manual_review: form.user_verify_require_manual_review, user_verify_allow_apply: form.user_verify_allow_apply, user_verify_disable_desc: form.user_verify_disable_desc, diff --git a/assets/admin/src/schema/sections/users/verify.js b/assets/admin/src/schema/sections/users/verify.js index e64e3300..d7f27add 100644 --- a/assets/admin/src/schema/sections/users/verify.js +++ b/assets/admin/src/schema/sections/users/verify.js @@ -7,7 +7,6 @@ export const verifySchema = { user_verify_enabled: true, user_verify_public_display: true, user_verify_badge_text: '已认证', - user_verify_accept_email_verified: true, user_verify_require_manual_review: false, user_verify_allow_apply: true, user_verify_disable_desc: @@ -45,13 +44,6 @@ export const verifySchema = { title: '审核流程', icon: 'fas fa-tasks', fields: [ - { - key: 'user_verify_accept_email_verified', - label: '邮箱验证通过视为已认证', - type: 'switch', - default: true, - dependsOn: { key: 'user_verify_enabled', value: true }, - }, { key: 'user_verify_require_manual_review', label: '保留人工审核位', diff --git a/inc/helpers/user-center-renderers/sidebar-nav.php b/inc/helpers/user-center-renderers/sidebar-nav.php index 546bcbf9..fb24a19e 100644 --- a/inc/helpers/user-center-renderers/sidebar-nav.php +++ b/inc/helpers/user-center-renderers/sidebar-nav.php @@ -11,8 +11,9 @@ $cart_url = function_exists('aksrt_get_cart_page_url') ? aksrt_get_cart_page_url $level_url = isset($dashboard_tabs['credits']) ? add_query_arg('asset_tab', 'points', aksrt_get_user_center_tab_url('credits')) : ''; -$auth_url = function_exists('aksrt_get_page_url_by_template') - ? aksrt_get_page_url_by_template('templates/pages/page-user-auth.php') +$auth_settings = class_exists('\AKSRT\User\AuthApply') ? \AKSRT\User\AuthApply::settings() : []; +$auth_url = !empty($auth_settings['enabled']) && function_exists('aksrt_get_user_auth_page_url') + ? aksrt_get_user_auth_page_url() : ''; $services = array_values(array_filter([ diff --git a/inc/modules/user-parts/routing.php b/inc/modules/user-parts/routing.php index cddbe01d..618c9e96 100644 --- a/inc/modules/user-parts/routing.php +++ b/inc/modules/user-parts/routing.php @@ -18,6 +18,7 @@ add_filter('query_vars', function ($vars) { $vars[] = 'aksrt_orders'; $vars[] = 'aksrt_cart'; $vars[] = 'aksrt_revenue'; + $vars[] = 'aksrt_user_auth'; return $vars; }); @@ -42,12 +43,14 @@ add_action('init', function () { add_rewrite_tag('%aksrt_orders%', '([0-1])'); add_rewrite_tag('%aksrt_cart%', '([0-1])'); add_rewrite_tag('%aksrt_revenue%', '([0-1])'); + add_rewrite_tag('%aksrt_user_auth%', '([0-1])'); add_rewrite_rule('^profile/?$', 'index.php?aksrt_user_center=1', 'top'); add_rewrite_rule('^user/([^/]+)/?$', 'index.php?user_nicename=$matches[1]', 'top'); // Commerce center aliases (work even before WP page is assigned). add_rewrite_rule('^orders/?$', 'index.php?aksrt_orders=1', 'top'); add_rewrite_rule('^cart/?$', 'index.php?aksrt_cart=1', 'top'); add_rewrite_rule('^revenue/?$', 'index.php?aksrt_revenue=1', 'top'); + add_rewrite_rule('^user-auth/?$', 'index.php?aksrt_user_auth=1', 'top'); }); // --- 3b. 统一模板拦截器(核心)--- @@ -166,7 +169,7 @@ add_action('init', function () { } // 统一 flush 检查 — bump when user-home rewrite / author override changes - $rewrite_version = AKSRT_VERSION . ':user-home-profile-routing-v3'; + $rewrite_version = AKSRT_VERSION . ':user-home-profile-routing-v4'; $flushed = get_option('aksrt_user_rules_flushed'); $rules = get_option('rewrite_rules'); $need_flush = ($flushed !== $rewrite_version) @@ -215,6 +218,9 @@ add_filter('request', function ($query_vars) { if (empty($query_vars['aksrt_user_center']) && isset($_GET['aksrt_user_center'])) { $query_vars['aksrt_user_center'] = '1'; } + if (empty($query_vars['aksrt_user_auth']) && isset($_GET['aksrt_user_auth'])) { + $query_vars['aksrt_user_auth'] = '1'; + } return $query_vars; }); diff --git a/inc/modules/user-parts/template-registry.php b/inc/modules/user-parts/template-registry.php index 263f6178..a7e7f35e 100644 --- a/inc/modules/user-parts/template-registry.php +++ b/inc/modules/user-parts/template-registry.php @@ -131,6 +131,12 @@ $_aksrt_special_templates = [ 'title' => '消息中心', 'fallback' => '/messages/', ], + 'user-auth' => [ + 'file' => 'templates/pages/page-user-auth.php', + 'slug' => 'user-auth', + 'title' => '官方认证', + 'fallback' => '/user-auth/', + ], 'submit' => [ 'file' => 'templates/pages/page-submit.php', 'slug' => 'submit', @@ -276,6 +282,7 @@ function aksrt_resolve_page_template_file(string $template_file = '', string $po 'categories' => 'templates/pages/page-categories.php', 'friends' => 'templates/pages/page-friends.php', 'profile' => 'templates/pages/page-profile.php', + 'user-auth' => 'templates/pages/page-user-auth.php', ]; if (!empty($slug_map[$post_slug]) && aksrt_locate_template_file($slug_map[$post_slug])) { @@ -437,6 +444,11 @@ function aksrt_get_current_special_template_path(): string { return $revenue_template ?: ''; } + if (get_query_var('aksrt_user_auth')) { + $auth_template = aksrt_locate_template_file('templates/pages/page-user-auth.php'); + return $auth_template ?: ''; + } + if (get_query_var('aksrt_sign')) { $auth_template = aksrt_get_auth_template_file((string) get_query_var('aksrt_auth_tab'), true); $auth_template_path = aksrt_locate_template_file($auth_template); diff --git a/inc/modules/user-parts/urls.php b/inc/modules/user-parts/urls.php index bbb546e3..034d5e1c 100644 --- a/inc/modules/user-parts/urls.php +++ b/inc/modules/user-parts/urls.php @@ -106,6 +106,21 @@ function aksrt_get_revenue_page_url(): string { } endif; +if (!function_exists('aksrt_get_user_auth_page_url')) : +/** + * 官方认证页面 URL。 + */ +function aksrt_get_user_auth_page_url(): string { + if (function_exists('aksrt_get_template_url')) { + return aksrt_get_template_url('user-auth'); + } + if (get_option('permalink_structure')) { + return home_url('/user-auth/'); + } + return add_query_arg('aksrt_user_auth', '1', home_url('/')); +} +endif; + if (!function_exists('aksrt_get_messages_page_url')) : /** * 消息中心页面 URL(模板 templates/pages/page-messages.php)。 diff --git a/src/AKSRT/Admin/Native/UsersMenus.php b/src/AKSRT/Admin/Native/UsersMenus.php index 8e1fbf5a..be36339a 100644 --- a/src/AKSRT/Admin/Native/UsersMenus.php +++ b/src/AKSRT/Admin/Native/UsersMenus.php @@ -525,7 +525,35 @@ class UsersMenus { echo '' . esc_html((string) ($row['display_name'] ?? '')) . ''; echo '' . esc_html((string) ($row['user_email'] ?? '')) . ''; echo '' . esc_html($st) . ''; - echo '' . esc_html((string) ($row['verify_reason'] ?? '')) . ''; + $apply = get_user_meta($uid, 'aksrt_user_verify_apply', true); + $apply = is_array($apply) ? $apply : []; + $type_labels = []; + if (class_exists('\AKSRT\User\AuthApply')) { + foreach ((array) \AKSRT\User\AuthApply::settings()['types'] as $type) { + $type_labels[(string) ($type['slug'] ?? '')] = (string) ($type['label'] ?? ''); + } + } + echo ''; + if ($apply) { + $type_key = sanitize_key((string) ($apply['type'] ?? '')); + echo '' . esc_html((string) ($apply['name'] ?? '')) . ''; + if ($type_key !== '') { + echo '
' . esc_html($type_labels[$type_key] ?? $type_key) . '
'; + } + if (!empty($apply['desc'])) { + echo '
' . esc_html((string) $apply['desc']) . '
'; + } + if (!empty($apply['msg'])) { + echo '
' . esc_html((string) $apply['msg']) . '
'; + } + foreach ((array) ($apply['img'] ?? []) as $image_url) { + echo ''; + } + } + if (!empty($row['verify_reason'])) { + echo '
' . esc_html((string) $row['verify_reason']) . '
'; + } + echo ''; echo ''; if ($st === 'pending') { foreach (['verified' => __('通过', 'aksrt'), 'rejected' => __('拒绝', 'aksrt')] as $action => $label) { diff --git a/src/AKSRT/Admin/Schema/SchemaUsers.php b/src/AKSRT/Admin/Schema/SchemaUsers.php index 14b67a8e..950916bf 100644 --- a/src/AKSRT/Admin/Schema/SchemaUsers.php +++ b/src/AKSRT/Admin/Schema/SchemaUsers.php @@ -600,7 +600,6 @@ class SchemaUsers { ['key' => 'user_verify_badge_text', 'label' => '认证徽标文案', 'type' => 'input', 'default' => '已认证'], ]], ['key' => 'workflow', 'title' => '审核流程', 'fields' => [ - ['key' => 'user_verify_accept_email_verified', 'label' => '邮箱验证通过视为已认证', 'type' => 'switch', 'default' => true], ['key' => 'user_verify_require_manual_review', 'label' => '保留人工审核位', 'type' => 'switch', 'default' => false], ['key' => 'user_verify_apply_option', 'label' => '申请类型选项', 'type' => 'textarea', 'default' => "real_name|实名认证\norganization|企业认证", 'desc' => '每行:slug|显示名称'], ]], diff --git a/src/AKSRT/Admin/UserControllerVerifyIntegrations.php b/src/AKSRT/Admin/UserControllerVerifyIntegrations.php index d278dae4..63cfd898 100644 --- a/src/AKSRT/Admin/UserControllerVerifyIntegrations.php +++ b/src/AKSRT/Admin/UserControllerVerifyIntegrations.php @@ -189,6 +189,17 @@ trait UserControllerVerifyIntegrations { } elseif ($status === 'verified') { delete_user_meta($user_id, 'aksrt_user_verify_reason'); } + if ($status === 'verified') { + $apply = get_user_meta($user_id, 'aksrt_user_verify_apply', true); + if (is_array($apply)) { + update_user_meta($user_id, 'aksrt_user_verify_info', [ + 'name' => (string) ($apply['name'] ?? ''), + 'desc' => (string) ($apply['desc'] ?? ''), + 'type' => (string) ($apply['type'] ?? ''), + 'time' => current_time('Y-m-d H:i'), + ]); + } + } $log = get_option('aksrt_verify_review_log', []); if (!is_array($log)) { @@ -219,6 +230,8 @@ trait UserControllerVerifyIntegrations { $reviewer = $reviewer_id > 0 ? get_userdata($reviewer_id) : null; $status = sanitize_key((string) ($row['verify_status'] ?? 'pending')); $email_verified = (bool) get_user_meta($user_id, 'aksrt_email_verified', true); + $application = get_user_meta($user_id, 'aksrt_user_verify_apply', true); + $application = is_array($application) ? $application : []; return [ 'user_id' => $user_id, @@ -229,6 +242,7 @@ trait UserControllerVerifyIntegrations { 'requested_at' => (string) ($row['user_registered'] ?? ''), 'reviewed_at' => (string) ($row['reviewed_at'] ?? ''), 'email_verified' => $email_verified, + 'application' => $application, 'reviewer' => $this->build_admin_user_summary($reviewer_id, $reviewer), 'history_count' => count($this->get_verify_history_for_user($user_id)), ]; diff --git a/src/AKSRT/Core/ScriptsPart1b.php b/src/AKSRT/Core/ScriptsPart1b.php index 75d1b053..fec29acb 100644 --- a/src/AKSRT/Core/ScriptsPart1b.php +++ b/src/AKSRT/Core/ScriptsPart1b.php @@ -624,7 +624,16 @@ $hmb_js = get_template_directory() . '/assets/js/header-newadd.js'; } // 用户身份认证页(zibll user-auth.php) - if (is_page_template('templates/pages/page-user-auth.php')) { + $is_user_auth_page = (bool) get_query_var('aksrt_user_auth') + || is_page_template('templates/pages/page-user-auth.php') + || ( + is_page() + && ( + (string) get_post_field('post_name', get_queried_object_id()) === 'user-auth' + || (string) get_post_meta(get_queried_object_id(), '_wp_page_template', true) === 'templates/pages/page-user-auth.php' + ) + ); + if ($is_user_auth_page) { $ua_css = get_template_directory() . '/assets/css/routes/user-auth.css'; if (file_exists($ua_css)) { wp_enqueue_style( diff --git a/src/AKSRT/Settings/UserRuntime.php b/src/AKSRT/Settings/UserRuntime.php index 59c28686..52796fe0 100644 --- a/src/AKSRT/Settings/UserRuntime.php +++ b/src/AKSRT/Settings/UserRuntime.php @@ -161,7 +161,7 @@ class UserRuntime { 'enabled' => !isset($settings['user_verify_enabled']) || !empty($settings['user_verify_enabled']), 'public_display' => !isset($settings['user_verify_public_display']) || !empty($settings['user_verify_public_display']), 'badge_text' => $verify_badge_text !== '' ? $verify_badge_text : __('已认证', 'aksrt'), - 'accept_email_verified' => !isset($settings['user_verify_accept_email_verified']) || !empty($settings['user_verify_accept_email_verified']), + 'accept_email_verified' => false, 'require_manual_review' => !empty($settings['user_verify_require_manual_review']), 'allow_apply' => !isset($settings['user_verify_allow_apply']) || !empty($settings['user_verify_allow_apply']), 'disable_desc' => (string) ($settings['user_verify_disable_desc'] ?? ''), diff --git a/src/AKSRT/User/AuthApply.php b/src/AKSRT/User/AuthApply.php index f6107796..c33b79a6 100644 --- a/src/AKSRT/User/AuthApply.php +++ b/src/AKSRT/User/AuthApply.php @@ -132,9 +132,13 @@ class AuthApply { $desc = isset($_POST['desc']) ? sanitize_textarea_field(wp_unslash((string) $_POST['desc'])) : ''; $msg = isset($_POST['msg']) ? sanitize_textarea_field(wp_unslash((string) $_POST['msg'])) : ''; $type = isset($_POST['type']) ? sanitize_key((string) wp_unslash($_POST['type'])) : ''; + $allowed_types = array_column((array) $s['types'], 'slug'); if ($name === '') { wp_send_json(['error' => 1, 'msg' => __('请填写认证身份名称', 'aksrt')]); } + if ($type === '' || !in_array($type, $allowed_types, true)) { + wp_send_json(['error' => 1, 'msg' => __('请选择有效的认证类型', 'aksrt')]); + } $images = []; if (!empty($_FILES['image']['name'])) { diff --git a/templates/pages/page-user-auth.php b/templates/pages/page-user-auth.php index 62a6ef8e..326a3167 100644 --- a/templates/pages/page-user-auth.php +++ b/templates/pages/page-user-auth.php @@ -17,7 +17,7 @@ $user_id = get_current_user_id(); $status = $user_id && class_exists(AuthApply::class) ? AuthApply::get_status($user_id) : ''; $info = $user_id && class_exists(AuthApply::class) ? AuthApply::get_auth_info($user_id) : []; $apply = $user_id && class_exists(AuthApply::class) ? AuthApply::get_apply_payload($user_id) : []; -$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url(get_permalink()) : wp_login_url(get_permalink()); +$login_url = function_exists('aksrt_get_login_url') ? aksrt_get_login_url(aksrt_get_user_auth_page_url()) : wp_login_url(aksrt_get_user_auth_page_url()); get_header(); ?>