From 8d1b0dacf6fe61baa869f5bad9616cc978ecbc67 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 12 Jul 2026 11:14:10 +0800 Subject: [PATCH] =?UTF-8?q?feat(auth):=20=E7=99=BB=E5=BD=95=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E6=89=BE=E5=9B=9E=E7=BB=91=E5=AE=9A=E5=89=8D=E5=8F=B0?= =?UTF-8?q?=201:1=20=E5=A3=B3=E5=B1=82/=E6=96=87=E6=A1=88/=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 抽出 sign.css,统一全页登录/注册与找回/绑定视觉;中文文案与用户协议契约对齐 Auth_Service;弹层字段与 logo 同步。 Co-Authored-By: Claude Fable 5 --- assets/css/routes/sign.css | 295 ++++++++++++++++++ assets/js/modal-auth.js | 2 +- inc/bootstrap.php | 1 + .../trait-aksrt-scripts-part-1b.php | 10 + .../trait-aksrt-settings-auth-reader.php | 9 + inc/helpers/aksrt-auth-ui.php | 81 +++++ templates/pages/page-bind-account.php | 12 +- templates/pages/page-reset-password.php | 8 +- templates/pages/page-sign.php | 121 +++---- templates/parts/modal-auth.php | 86 ++--- 10 files changed, 511 insertions(+), 114 deletions(-) create mode 100644 assets/css/routes/sign.css create mode 100644 inc/helpers/aksrt-auth-ui.php diff --git a/assets/css/routes/sign.css b/assets/css/routes/sign.css new file mode 100644 index 00000000..5dee9111 --- /dev/null +++ b/assets/css/routes/sign.css @@ -0,0 +1,295 @@ +/** + * AKSRT full-page sign shell (login / register / reset / bind). + * + * @package AKSRT + */ + +.page-template-user-sign { + min-height: 500px; +} + +.sign-page { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + position: relative; + padding: 70px 16px 40px; +} + +.sign-bg { + position: fixed; + inset: 0; + background-repeat: no-repeat; + background-size: cover; + background-position: center; + z-index: 0; +} + +.sign-topbar { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 2; + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 20px; + background: color-mix(in srgb, var(--main-bg-color, #fff) 86%, transparent); + backdrop-filter: blur(8px); +} + +.sign-topbar a { + color: var(--main-color, #4e5358); + text-decoration: none; + font-size: 14px; +} + +.sign-card { + position: relative; + z-index: 1; + width: 100%; + max-width: 420px; + background: var(--main-bg-color, #fff); + border-radius: var(--main-radius, 8px); + box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, 0.08)); + padding: 30px 35px; +} + +.sign-card--left { margin-right: auto; } +.sign-card--right { margin-left: auto; } +.sign-card--center { margin: 0 auto; } + +.sign-logo { + text-align: center; + margin-bottom: 20px; +} + +.sign-logo img { + height: 36px; +} + +.sign-logo__text { + display: inline-flex; + align-items: center; + justify-content: center; + width: 48px; + height: 48px; + border-radius: 12px; + background: var(--focus-color, #f04494); + color: #fff; + font-size: 18px; + font-weight: 700; + text-decoration: none; +} + +.sign-tabs { + display: flex; + border-bottom: 2px solid var(--main-border-color, rgba(50, 50, 50, 0.06)); + margin-bottom: 20px; +} + +.sign-tab { + flex: 1; + padding: 10px 0; + border: none; + background: none; + font-size: 15px; + cursor: pointer; + color: var(--muted-color, #777); + border-bottom: 2px solid transparent; + margin-bottom: -2px; + transition: all .2s; + text-align: center; + font-weight: 500; +} + +.sign-tab.is-active { + color: var(--focus-color, #f04494); + border-bottom-color: var(--focus-color, #f04494); + font-weight: 600; +} + +.sign-tab:hover { color: var(--focus-color, #f04494); } + +.sign-panel { display: none; } +.sign-panel.is-active { display: block; } + +.sign-error { + background: rgba(239, 68, 68, 0.08); + border: 1px solid rgba(239, 68, 68, 0.2); + border-radius: var(--main-radius, 8px); + padding: 10px 14px; + font-size: 13px; + color: #ef4444; + margin-bottom: 16px; +} + +.sign-success { + background: rgba(16, 185, 129, 0.08); + border: 1px solid rgba(16, 185, 129, 0.2); + border-radius: var(--main-radius, 8px); + padding: 10px 14px; + font-size: 13px; + color: #10b981; + margin-bottom: 16px; +} + +.sign-notice { + padding: 16px; + text-align: center; + color: var(--muted-2-color, #666); + font-size: 14px; +} + +.sign-form { + display: flex; + flex-direction: column; + gap: 16px; +} + +.sign-form .form-field { + display: flex; + flex-direction: column; + gap: 6px; +} + +.sign-form label { + font-size: 14px; + font-weight: 500; + color: var(--main-color, #4e5358); +} + +.sign-form .input-wrap { position: relative; } + +.sign-form .input-wrap input { + width: 100%; + height: 44px; + padding: 0 14px; + border: 1px solid transparent; + background: var(--body-bg-color, #f5f6f7); + border-radius: var(--main-radius, 8px); + font-size: 14px; + color: var(--key-color, #333); + transition: border-color .15s; +} + +.sign-form .input-wrap input:focus { + outline: none; + border-color: var(--focus-color, #f04494); + box-shadow: 0 0 2px 3px var(--focus-shadow-color, rgba(253, 83, 161, 0.4)); +} + +.sign-form .toggle-pwd { + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + cursor: pointer; + color: var(--muted-2-color, #999); + padding: 4px; +} + +.sign-form .form-row-between { + display: flex; + align-items: center; + justify-content: space-between; + font-size: 13px; +} + +.sign-form .form-row-between a { color: var(--focus-color, #f04494); } + +.sign-form .form-row-between label { + display: flex; + align-items: center; + gap: 6px; + cursor: pointer; + font-size: 13px; + color: var(--muted-color, #777); +} + +.sign-form .btn-submit { + width: 100%; + height: 44px; + border: none; + border-radius: var(--main-radius, 8px); + background: var(--focus-color, #f04494); + color: #fff; + font-size: 15px; + font-weight: 600; + cursor: pointer; + transition: opacity .15s; +} + +.sign-form .btn-submit:hover { opacity: .85; } +.sign-form .btn-submit:disabled { opacity: .5; cursor: not-allowed; } + +.sign-hint { + margin: 0; + font-size: 13px; + color: var(--muted-color, #777); +} + +.sign-terms { + display: flex; + align-items: flex-start; + gap: 8px; + font-size: 13px; + cursor: pointer; + color: var(--muted-color, #777); +} + +.sign-terms a { + color: var(--focus-color, #f04494); +} + +.sign-footer { + text-align: center; + margin-top: 20px; + font-size: 14px; + color: var(--muted-color, #777); +} + +.sign-footer a { color: var(--focus-color, #f04494); } + +.sign-footer-bar { + position: fixed; + bottom: 0; + left: 0; + right: 0; + text-align: center; + padding: 10px; + font-size: 12px; + color: var(--muted-2-color, #999); + z-index: 1; + background: color-mix(in srgb, var(--main-bg-color, #fff) 80%, transparent); +} + +.sign-oauth { + margin-top: 20px; +} + +.sign-oauth__divider { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 14px; + font-size: 12px; + color: var(--muted-2-color, #999); +} + +.sign-oauth__divider::before, +.sign-oauth__divider::after { + content: ""; + flex: 1; + height: 1px; + background: var(--main-border-color, rgba(50, 50, 50, 0.08)); +} + +@media (max-width: 480px) { + .sign-card { padding: 24px 20px; } + .sign-page { padding-top: 56px; } +} diff --git a/assets/js/modal-auth.js b/assets/js/modal-auth.js index 6b7a51f6..38d050fa 100644 --- a/assets/js/modal-auth.js +++ b/assets/js/modal-auth.js @@ -454,7 +454,7 @@ btn.addEventListener('click', function (e) { var form = btn.closest('form'); if (!form) return; - var agree = form.querySelector('[name="user_agreement"]'); + var agree = form.querySelector('[name="agree_terms"], [name="user_agreement"]'); if (agree && !agree.checked) { e.preventDefault(); e.stopImmediatePropagation(); diff --git a/inc/bootstrap.php b/inc/bootstrap.php index 23a0dc96..fa66e6a3 100644 --- a/inc/bootstrap.php +++ b/inc/bootstrap.php @@ -34,6 +34,7 @@ require_once AKSRT_DIR . '/inc/helpers/aksrt-comments.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-forum.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-slider.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-vip.php'; +require_once AKSRT_DIR . '/inc/helpers/aksrt-auth-ui.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-i18n-switch.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-posts-renderer.php'; require_once AKSRT_DIR . '/inc/helpers/aksrt-resource.php'; diff --git a/inc/classes/scripts-traits/trait-aksrt-scripts-part-1b.php b/inc/classes/scripts-traits/trait-aksrt-scripts-part-1b.php index 95273606..6de49d00 100644 --- a/inc/classes/scripts-traits/trait-aksrt-scripts-part-1b.php +++ b/inc/classes/scripts-traits/trait-aksrt-scripts-part-1b.php @@ -532,6 +532,16 @@ trait AKSRT_Scripts_Part_1b { ? (string) filemtime(get_template_directory() . '/assets/css/routes/auth.css') : $version ); + + $sign_css = get_template_directory() . '/assets/css/routes/sign.css'; + if (file_exists($sign_css)) { + wp_enqueue_style( + 'aksrt-route-sign', + $base_uri . '/assets/css/routes/sign.css', + ['aksrt-tokens'], + (string) filemtime($sign_css) + ); + } // 手机号注册/登录 + SMS 倒计时 + 人机验证联动 $sign_js_path = get_template_directory() . '/assets/js/sign-register.js'; if (file_exists($sign_js_path)) { diff --git a/inc/classes/settings/trait-aksrt-settings-auth-reader.php b/inc/classes/settings/trait-aksrt-settings-auth-reader.php index 772f2f16..50a26bd8 100644 --- a/inc/classes/settings/trait-aksrt-settings-auth-reader.php +++ b/inc/classes/settings/trait-aksrt-settings-auth-reader.php @@ -208,4 +208,13 @@ trait AKSRT_Settings_Auth_Reader { return ['type' => $type, 'domains' => $domains]; } + + /** 用户协议前台配置(enabled / required / page) */ + public static function user_agreement_settings(): array { + return [ + 'enabled' => !isset(self::get_all()['user_agreement_s']) || !empty(self::get_value('user_agreement_s', true)), + 'required' => !isset(self::get_all()['user_agreement_check']) || !empty(self::get_value('user_agreement_check', true)), + 'page' => trim((string) self::get_value('user_agreement_page', '')), + ]; + } } diff --git a/inc/helpers/aksrt-auth-ui.php b/inc/helpers/aksrt-auth-ui.php new file mode 100644 index 00000000..75b7344e --- /dev/null +++ b/inc/helpers/aksrt-auth-ui.php @@ -0,0 +1,81 @@ +用户协议', 'aksrt'), + esc_url($url) + ); + } else { + $label_html = esc_html__('我已阅读并同意用户协议', 'aksrt'); + } + + return [ + 'enabled' => $enabled, + 'required' => $required, + 'label_html' => $label_html, + 'field_name' => 'agree_terms', + ]; + } +} + +if (!function_exists('aksrt_get_auth_sign_logo_html')) { + /** + * Shared logo block for full-page sign shell. + */ + function aksrt_get_auth_sign_logo_html(): string { + $logo_url = class_exists('AKSRT_Settings') ? AKSRT_Settings::user_logo_url() : ''; + $home = home_url('/'); + $name = get_bloginfo('name'); + if ($logo_url) { + return sprintf( + '%s', + esc_url($home), + esc_url($logo_url), + esc_attr($name) + ); + } + return sprintf( + '%s', + esc_url($home), + esc_html(mb_substr((string) $name, 0, 2)) + ); + } +} diff --git a/templates/pages/page-bind-account.php b/templates/pages/page-bind-account.php index f671e162..33909f9f 100644 --- a/templates/pages/page-bind-account.php +++ b/templates/pages/page-bind-account.php @@ -55,6 +55,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['log'], $_POST['pwd']) } } +remove_action('wp_footer', 'aksrt_render_footer_tabbar', 20); +remove_action('wp_footer', 'aksrt_render_float_buttons', 30); +add_filter('body_class', static function ($classes) { + $classes[] = 'page-template-user-sign'; + return $classes; +}); get_header(); ?> @@ -65,7 +71,7 @@ get_header();
- +

@@ -76,7 +82,7 @@ get_header(); - +

' . esc_html($provider_name) . ''); ?> @@ -120,7 +126,7 @@ get_header(); - diff --git a/templates/pages/page-reset-password.php b/templates/pages/page-reset-password.php index 77d0d8f8..4e485c09 100644 --- a/templates/pages/page-reset-password.php +++ b/templates/pages/page-reset-password.php @@ -54,13 +54,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['aksrt_action']) && $_ } } +remove_action('wp_footer', 'aksrt_render_footer_tabbar', 20); +remove_action('wp_footer', 'aksrt_render_float_buttons', 30); +add_filter('body_class', static function ($classes) { + $classes[] = 'page-template-user-sign'; + return $classes; +}); get_header(); ?>

- +

diff --git a/templates/pages/page-sign.php b/templates/pages/page-sign.php index c1cae16d..75893deb 100644 --- a/templates/pages/page-sign.php +++ b/templates/pages/page-sign.php @@ -1,4 +1,4 @@ - __('用户登录', 'aksrt'), - 'signup' => __('用户注册', 'aksrt'), + 'signup' => __('新用户注册', 'aksrt'), ]; $page_title = ($titles[$tab] ?? __('登录 / 注册', 'aksrt')) . ' - ' . get_bloginfo('name'); $interim = isset($_REQUEST['interim-login']); -// 搂4.1 Defense-in-depth: redirect out when close_sign is active (backup of auth router gate) if (class_exists('AKSRT_Settings') && AKSRT_Settings::close_sign() && !is_user_logged_in() && !$interim) { wp_safe_redirect(home_url('/'), 302); exit; } -// §4.1 close_signin: password login disabled — force signin tab to show social-only message $close_signin = class_exists('AKSRT_Settings') ? AKSRT_Settings::close_signin() : false; if ($close_signin && $tab === 'signin') { - // Don't allow password form submission $_SERVER['REQUEST_METHOD'] = 'GET'; } @@ -63,7 +63,7 @@ $background_html = ''; $sign_ui = class_exists('AKSRT_Settings') ? AKSRT_Settings::sign_page_ui() : []; $card_position = $sign_ui['card_position'] ?? 'center'; $sign_show_logo = $sign_ui['show_logo'] ?? true; -$sign_show_header = $sign_ui['show_header'] ?? true; +$sign_show_header = !empty($sign_ui['show_header']); $sign_theme_mode = $sign_ui['theme_mode'] ?? 'default'; if (class_exists('AKSRT_Settings')) { $bg_ids = $sign_ui['background'] ?? []; @@ -73,7 +73,6 @@ if (class_exists('AKSRT_Settings')) { $background_html = '
'; } } elseif (is_string($bg_ids) && $bg_ids !== '') { - // BC: comma-separated string from old storage $ids = array_filter(array_map('absint', explode(',', $bg_ids))); if (!empty($ids)) { $bg_url = wp_get_attachment_url($ids[array_rand($ids)]); @@ -106,13 +105,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['user_login'], $_POST[ if (!empty($result['verification_required'])) { $register_success = sprintf( '%s
%s', - esc_html($result['message'] ?? __('Registration successful. Please complete email verification.', 'aksrt')), + esc_html($result['message'] ?? __('注册成功,请完成邮箱验证。', 'aksrt')), esc_url($result['verify_url'] ?? ''), esc_html__('前往验证', 'aksrt') ); } else { $register_success = sprintf( - __('Registration successful. Please continue on the login page.', 'aksrt'), + __('注册成功,请前往登录页继续。', 'aksrt'), esc_url(aksrt_get_login_url()) ); } @@ -128,6 +127,15 @@ if (!empty($_GET['invite'])) { } elseif (!empty($_COOKIE['aksrt_invite'])) { $invite_prefill = sanitize_key(wp_unslash($_COOKIE['aksrt_invite'])); } + +$agreement = function_exists('aksrt_get_auth_agreement_view') + ? aksrt_get_auth_agreement_view() + : ['enabled' => true, 'required' => true, 'label_html' => esc_html__('我已阅读并同意用户协议', 'aksrt'), 'field_name' => 'agree_terms']; + +$sign_css_uri = get_template_directory_uri() . '/assets/css/routes/sign.css'; +$sign_css_ver = file_exists(get_template_directory() . '/assets/css/routes/sign.css') + ? (string) filemtime(get_template_directory() . '/assets/css/routes/sign.css') + : AKSRT_VERSION; ?> @@ -137,81 +145,45 @@ if (!empty($_GET['invite'])) { <?php echo esc_html($page_title); ?> - + > + + +
+ + +
+ +
-
-
-
- +
+
- -
+ +
@@ -221,20 +193,25 @@ if (!empty($_GET['invite'])) {
- - + +
- + render_social_buttons(); ?> - ' . $social . '
'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> + +
+
+ +
+ - +
@@ -245,12 +222,12 @@ if (!empty($_GET['invite'])) {
- +
- -
+ +
@@ -282,17 +259,19 @@ if (!empty($_GET['invite'])) {
+ + -

+

- +
diff --git a/templates/parts/modal-auth.php b/templates/parts/modal-auth.php index ef9c9560..4317752b 100644 --- a/templates/parts/modal-auth.php +++ b/templates/parts/modal-auth.php @@ -51,32 +51,40 @@ foreach ($oauth_providers as $provider) { $site_name = get_bloginfo('name'); $reset_url = function_exists('aksrt_get_reset_password_url') ? aksrt_get_reset_password_url() : wp_lostpassword_url(); +$agreement = function_exists('aksrt_get_auth_agreement_view') + ? aksrt_get_auth_agreement_view() + : ['enabled' => true, 'required' => true, 'label_html' => esc_html__('我已阅读并同意用户协议', 'aksrt'), 'field_name' => 'agree_terms']; +$logo_url = class_exists('AKSRT_Settings') ? AKSRT_Settings::user_logo_url() : ''; ?> -