feat(profile): rebuild account settings page

This commit is contained in:
2026-10-05 18:58:49 +08:00
parent f00c3faeaa
commit 346146b4fa
14 changed files with 609 additions and 750 deletions
@@ -452,24 +452,25 @@ test('article visual matrix pins every breakpoint, state and strict threshold',
assert.equal(matrix.acceptance.pixelDifferencePercentMax, 1.5);
});
test('profile routes load versioned leaf styles and keep dialogs hidden initially', () => {
test('profile routes load versioned leaf styles and settings dialogs use the shared runtime', () => {
const scripts = read('src/Core/ScriptsPart1b.php');
const accountModals = read('inc/helpers/user-center-renderers/profile-account-modals.php');
const settingsSecurity = read('inc/helpers/user-center-renderers/settings-security.php');
const settingsAccount = read('inc/helpers/user-center-renderers/settings-account.php');
const settingsBindings = read('inc/helpers/user-center-renderers/settings-bindings.php');
const userCenterJs = read('assets/js/routes/user-center.js');
const settingsCss = read('assets/css/routes/user-center/settings.css');
const profileListsCss = read('assets/css/routes/profile/lists.css');
const userHomeCss = read('assets/css/routes/user-home.css');
const profileLayoutCss = read('assets/css/routes/profile/layout.css');
const frontendLayoutCss = read('assets/css/frontend/layout.css');
const publicBundleCss = read('assets/css/build/public.css');
const userCenterShellCss = read('assets/css/routes/user-center/shell.css');
const profileModalsCss = read('assets/css/routes/profile/modals.css');
const userCenterCreditsCss = read('assets/css/routes/user-center/credits.css');
const profileCredits = read('inc/helpers/user-center-renderers/profile-credits.php');
const profileOrders = read('inc/helpers/user-center-renderers/profile-orders.php');
const ordersCss = read('assets/css/routes/orders.css');
const orderCenterJs = read('assets/js/order-center.js');
assert.ok(scripts.includes("$profile_parts = ['layout', 'lists', 'modals'];"));
assert.ok(scripts.includes("$profile_parts = ['layout', 'lists'];"));
for (const part of ['user-center/shell', 'user-center/credits', 'user-center/vip', 'user-center/level', 'user-center/settings', 'user-center/revenue', 'user-center/revenue-earnings', 'user-center/responsive']) {
assert.ok(scripts.includes(`'${part}'`), `missing direct route leaf ${part}`);
}
@@ -482,9 +483,39 @@ test('profile routes load versioned leaf styles and keep dialogs hidden initiall
assert.doesNotMatch(scripts, /assets\/css\/routes\/profile\.css/);
assert.doesNotMatch(scripts, /assets\/css\/routes\/user-center\.css/);
assert.match(accountModals, /id="pwd-modal" class="aksrt-modal" hidden/);
assert.match(accountModals, /id="email-modal" class="aksrt-modal" hidden/);
assert.match(userCenterJs, /function closeModal\(m\)[\s\S]*?m\.hidden = true;/);
assert.match(settingsAccount, /data-aksrt-settings-modal="<\?php echo esc_attr\(\$modal\); \?>"/);
assert.match(settingsAccount, /\$render_row\([^;]*'email'/);
assert.match(settingsAccount, /\$render_row\([^;]*'phone'/);
assert.match(settingsAccount, /\$render_row\([^;]*'password'/);
assert.match(settingsAccount, /template data-aksrt-settings-modal-template="password"/);
assert.match(settingsAccount, /template data-aksrt-settings-modal-template="email"/);
assert.match(settingsAccount, /template data-aksrt-settings-modal-template="phone"/);
assert.ok(settingsAccount.indexOf('绑定邮箱') < settingsAccount.indexOf('绑定手机'));
assert.ok(settingsAccount.indexOf('绑定手机') < settingsAccount.indexOf("require __DIR__ . '/settings-bindings.php'"));
assert.ok(settingsAccount.indexOf("require __DIR__ . '/settings-bindings.php'") < settingsAccount.indexOf('账户密码'));
assert.ok(settingsBindings.indexOf('绑定社交账号') < settingsBindings.indexOf('aksrt-account-list--social'));
assert.match(settingsAccount, /!empty\(\$user_settings\['bind_phone'\]\)/);
assert.match(settingsBindings, /aksrt-account-list--social/);
assert.match(settingsBindings, /binding-unbind-btn/);
assert.match(userCenterJs, /runtime\.open\(\{/);
assert.match(userCenterJs, /className: 'aksrt-user-settings-modal modal-mini'/);
assert.match(userCenterJs, /mobileBottom: true/);
assert.match(userCenterJs, /onContent: function \(_, session\)/);
assert.match(userCenterJs, /aksrt:modal:close[\s\S]*?resetSettingsModal\(shell\)/);
assert.match(userCenterJs, /resetCaptcha\(scene, form\)/);
assert.match(userCenterJs, /aksrt_change_password/);
assert.match(userCenterJs, /aksrt_change_email/);
assert.match(userCenterJs, /AksrtModalRuntime\.close\('settings-submit'\)/);
assert.match(settingsCss, /\.aksrt-modal-runtime\.aksrt-user-settings-modal:not\(\.aksrt-modal-runtime--bottom\)[\s\S]*?width: 400px/);
assert.match(settingsCss, /\.aksrt-settings-modal \.modal-colorful-header[\s\S]*?height: 120px/);
assert.match(settingsAccount, /class="colorful-make"/);
assert.doesNotMatch(userCenterJs, /function closeModal\(|\.aksrt-modal\.is-open|security-trigger|data-close-modal/);
for (const deletedPath of [
'inc/helpers/user-center-renderers/profile-account-modals.php',
'inc/helpers/user-center-renderers/settings-security.php',
'assets/css/routes/profile/modals.css',
]) assert.equal(fs.existsSync(path.join(root, deletedPath)), false, `stale settings modal file: ${deletedPath}`);
assert.doesNotMatch(profileListsCss, /aksrt-modal__icon|aksrt-modal__close|security-action/);
assert.match(userHomeCss, /\.aksrt-profile-details-modal\[hidden\]\s*\{\s*display:\s*none\s*!important;\s*\}/);
assert.match(userHomeCss, /\.aksrt-user-home \.aksrt-user-home__post-list\[data-view="list"\] \.posts-item\s*\{[^}]*background:\s*transparent;[^}]*box-shadow:\s*none;/);
assert.match(userHomeCss, /@media \(min-width: 992px\)\s*\{[\s\S]*?\.aksrt-user-home \.aksrt-user-home__post-list\[data-view="list"\]\s*\{[^}]*display:\s*grid;[^}]*grid-template-columns:\s*repeat\(2,\s*minmax\(0,\s*1fr\)\);/);
@@ -515,11 +546,10 @@ test('profile routes load versioned leaf styles and keep dialogs hidden initiall
assert.match(userCenterShellCss, /\.aksrt-profile\.content-shell > \.content-wrap,[\s\S]*?\.aksrt-profile\.content-shell \.uc-header\s*\{[\s\S]*?width:\s*100%;[\s\S]*?max-width:\s*none/);
assert.match(profileLayoutCss, /\.aksrt-cover-menu__panel\[hidden\]\s*\{\s*display:\s*none\s*!important;\s*\}/);
assert.match(profileLayoutCss, /#aksrt-bg-file-input\[hidden\],[\s\S]*?#aksrt-avatar-file-input\[hidden\][\s\S]*?display:\s*none\s*!important;/);
assert.match(settingsSecurity, /data-modal="email-modal"[\s\S]*?<\/button>\s*<\/div>\s*<div class="security-action-item">[\s\S]*?data-modal="phone-modal"/);
assert.match(accountModals, /id="phone-modal" class="aksrt-modal" hidden role="dialog"[\s\S]*?aksrt-modal__overlay" data-close-modal[\s\S]*?aksrt-modal__box/);
assert.match(accountModals, /id="phone-modal"[\s\S]*?class="modal-field modal-field--code"[\s\S]*?class="code-input-group"[\s\S]*?class="aksrt-modal__footer"/);
assert.doesNotMatch(accountModals, /id="phone-modal"[\s\S]*?aksrt-modal__(?:dialog|body|actions)/);
assert.match(profileModalsCss, /\.modal-field input\[type="tel"\]/);
assert.match(settingsAccount, /id="aksrt-bind-phone-form"[\s\S]*?data-aksrt-sms-trigger/);
assert.match(settingsAccount, /class="modal-colorful-header colorful-bg jb-blue"/);
assert.match(settingsAccount, /class="modal-colorful-header colorful-bg jb-yellow"/);
assert.doesNotMatch(settingsAccount, /class="aksrt-modal"|aksrt-modal__overlay|aksrt-modal__box/);
assert.match(userCenterCreditsCss, /#panel-credits\.dashboard-panel\s*\{[^}]*background:\s*transparent;[^}]*box-shadow:\s*none;/);
assert.match(userCenterCreditsCss, /\.uc-asset-tabs\s*\{[^}]*background:\s*var\(--surface-1,\s*#fff\);[^}]*border:[^;}]+;[^}]*box-shadow:[^;}]+;/);
assert.doesNotMatch(profileCredits, /credits-signin\.php|data-aksrt-signin-calendar/);
+4 -1
View File
@@ -335,6 +335,7 @@ test('profile save uses AJAX rehydrate and a fixed-id notyf flow without query f
test('settings actions use rehydrated fixed-id notyf flows', () => {
const userCenter = read('assets/js/routes/user-center.js');
const auth = read('assets/js/auth.js');
const settings = read('inc/helpers/user-center-renderers/profile-settings.php');
const context = read('inc/helpers/aksrt-user-center.php');
const page = read('templates/pages/page-profile.php');
@@ -355,6 +356,8 @@ test('settings actions use rehydrated fixed-id notyf flows', () => {
assert.match(userCenter, /aksrtSettingsInitialized/);
assert.match(userCenter, /oauth_action[\s\S]*?notyf\(message, type\)[\s\S]*?history\.replaceState/);
assert.doesNotMatch(userCenter, /oauth_unbound/);
assert.match(auth, /\[data-identity-root\], \[data-aksrt-settings-root\]/);
assert.doesNotMatch(auth, /\.settings-section/);
assert.match(userCenter, /'aksrt-settings-phone-code-toast'/);
assert.match(userCenter, /notyf\('正在发送验证码…', 'load', '', toastId\)/);
@@ -362,7 +365,7 @@ test('settings actions use rehydrated fixed-id notyf flows', () => {
assert.match(userCenter, /notyf\([^;]+?'danger', 5, toastId\)/);
assert.match(userCenter, /\/user\/phone-code/);
assert.match(settings, /require \$dir \. '\/profile-account-modals\.php';/);
assert.match(settings, /require \$dir \. '\/settings-account\.php';/);
assert.doesNotMatch(context, /account_modals_html|'account-modals'/);
assert.doesNotMatch(page, /user-center\/account-modals/);
assert.equal(fs.existsSync(path.join(root, 'templates/parts/user-center/account-modals.php')), false);