feat(frontend): replicate reference header user box 1:1

顶导航点击小人弹出的用户信息浮层,从 AKSRT 定制结构改为与参考主题 zib_header_user_box() 逐行同构:头像链接包裹、钱包双瓷砖、会员条、签到、消息图标、统计徽章行全部改用参考主题遗留类,渲染交回 main.css(.sub-user-box 242px、.avatar-img 38px、.msg-news-icon、badge.top、.payvip-icon 深色渐变加 gem 水印、.vip-expdate-tag、.muted-box)。

头像改走 aksrt_get_avatar_box(用户ID, avatar-img, true, false),得到参考的 a 链接包裹 avatar-img 结构。消息图标改参考标记 msg-news-icon abs-right 加 toggle-radius msg-icon,未读徽章用 badge.top,avatar_dropdown 位置门控契约保留。管理端行在「后台管理」前插入「支付中心」,跳 admin.php?page=aksrt_pay,即参考主题「商城中心」槽位,图标 fa-credit-card。

钱包重写为参考双瓷砖:余额在前(c-blue-2 加 fa-money-bill-wave)、积分在后(c-yellow 加 fa-coins),分别按充值开关与积分总开关门控,两块皆关则不渲染,并保留 data-aksrt-wallet-value 与 data-aksrt-points-value 两个 JS 刷新钩子。会员条去掉 AKSRT 自创的 vipbg-v2 level-N 金色背景,改参考的 payvip-icon 加 badg jb-yellow vip-expdate-tag,到期文案按参考语义分为已过期、永久会员、裸日期三种。签到入口由 button 改为 a.but block c-yellow,并去掉随之失效的 compact 形参,data-signin 挂载与 wp_footer 验证码不变。统计行删掉文章徽章(本站不做帖子),图标由 SVG sprite 换 FA5+ 的 fa-comment-dots、fa-thumbs-up、fa-fire。

会员等级图标契约不动:aksrt_get_vip_icon 与 User\Level::get_badge_html 的调用与参数保持原样。

顺带清死代码:aksrt_header_user_badges_row 原本取到函数后直接返回空串,现在真正输出统计行;删掉 header-userbox.css 里整套 bespoke 规则与 vip-modal.css 的 vipbg-v2 死规则。

显式偏差:统计行链接保持扁平用户主页 URL(AKSRT 用户主页是干净 URL 加 JS tab,没有 query tab 路由);签到入口沿用积分签到总开关门控,不新增管理端可配置项。

public.css 与 public.min.css 用 tools/build-public-assets.mjs 重建:该 bundle 打包了 header-userbox.css 且作为依赖先于单模块入队,旧的 width 260px 会压过新源码、把卡片钉在 260px 而不是参考的 242px。

验证:node --test tests/**/*.test.cjs 573 项全通过;六个改动 PHP 文件 php -l 无语法错误;卡片用到的 FA5 token 逐个核对 5.15.4 全部命中。未做真实视觉效果验收。
This commit is contained in:
2026-10-10 16:17:01 +08:00
parent 8ff74f56ee
commit 6f815678ec
13 changed files with 190 additions and 577 deletions
+5 -240
View File
@@ -2705,8 +2705,10 @@ main.container,
/**
* Header account popover.
*
* The shared legacy navigation styles provide the popover shell. This module
* owns AKSRT-specific account content such as check-in, wallet and VIP rows.
* The shared legacy navigation styles provide the popover shell, and every
* account row (avatar, VIP bar, check-in, wallet tiles, stats badges) renders
* through the reference legacy classes. This module only owns the navigation
* shell anchoring plus the account action-row geometry.
*/
/* The desktop action cluster owns one horizontal alignment context. */
@@ -2869,85 +2871,10 @@ main.container,
}
.aksrt-header-userbox {
width: 260px;
color: var(--color-ink-2);
}
.aksrt-header-userbox .user-info {
min-height: 44px;
padding: 2px;
}
.aksrt-header-userbox .user-info > .avatar {
flex: 0 0 44px;
width: 44px;
height: 44px;
object-fit: cover;
}
.aksrt-header-userbox .user-right,
.aksrt-header-userbox .user-right > .flex1 {
min-width: 0;
}
.aksrt-header-userbox .user-right b {
display: flex;
align-items: center;
gap: 4px;
max-width: 100%;
overflow: hidden;
white-space: nowrap;
}
.aksrt-header-userbox .display-name {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.aksrt-header-userbox .user-right .img-icon,
.aksrt-header-userbox .user-right .aksrt-user-level-icon,
.aksrt-header-userbox .user-right .aksrt-identity-medal,
.aksrt-header-userbox .user-right .aksrt-header-user-medal,
.aksrt-header-userbox .user-right .aksrt-identity-certification-icon {
flex: 0 0 auto;
height: 1.1em;
}
.aksrt-header-userbox .user-info > .abs-right {
top: 50%;
right: 2px;
transform: translateY(-50%);
display: inline-flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
border-radius: 50%;
background: var(--surface-2);
color: var(--color-ink-3);
}
.aksrt-header-userbox .aksrt-notification-badge {
position: absolute;
top: -4px;
right: -4px;
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 17px;
height: 17px;
padding: 0 4px;
border: 2px solid var(--surface-1);
border-radius: 999px;
background: #e74c3c;
color: #fff;
font-size: 10px;
font-weight: 700;
line-height: 1;
}
/* Top-nav bell badge (the card itself uses the legacy badge.top element). */
.aksrt-nav-notification .aksrt-notification-badge {
position: absolute;
top: 2px;
@@ -2967,150 +2894,6 @@ main.container,
line-height: 1;
}
.aksrt-header-wallet {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
width: 100%;
padding: 9px 10px;
border-radius: 8px;
background: var(--surface-2);
color: var(--color-ink-2);
font-size: 12px;
line-height: 1.35;
}
.aksrt-header-wallet:hover {
color: var(--color-ink);
}
.aksrt-header-wallet__item {
min-width: 0;
white-space: nowrap;
}
.aksrt-header-wallet__item i {
margin-right: 2px;
color: var(--color-ink-3);
}
.aksrt-header-wallet__item b {
margin-left: 2px;
color: var(--color-ink);
font-weight: 700;
}
.aksrt-header-checkin {
display: inline-flex !important;
align-items: center;
justify-content: center;
gap: 6px;
width: 100% !important;
min-height: 36px;
margin: 0;
padding: 8px 10px !important;
border: 0 !important;
border-radius: 6px !important;
background: #fff6db !important;
color: #8a5a00 !important;
font-size: 13px !important;
font-weight: 600;
line-height: 1.3;
white-space: nowrap;
}
.aksrt-header-checkin > i {
margin: 0 !important;
color: #b78103 !important;
}
.aksrt-header-checkin:hover {
background: #fff0c2 !important;
color: #8a5a00 !important;
}
/* 已签到态对齐参考主题:保留原配色(参考主题签到后仍为同一彩色按钮),
* 且按钮可点击(打开签到详情弹窗);仅请求进行中的禁用态降不透明度。 */
.aksrt-header-checkin:disabled,
.aksrt-header-checkin:disabled:hover {
cursor: default;
opacity: .85;
}
.aksrt-header-payvip__cta,
.aksrt-header-payvip:not(.is-vip) .payvip-icon,
.aksrt-header-payvip:not(.is-vip) .but {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
gap: 6px !important;
width: 100% !important;
min-width: 0 !important;
min-height: 36px;
margin: 0 !important;
padding: 8px 10px !important;
border: 0 !important;
border-radius: 6px !important;
background: linear-gradient(90deg, #ff6b6b, #f04494) !important;
color: #fff !important;
font-size: 13px !important;
font-weight: 600;
line-height: 1.3;
text-align: center;
white-space: nowrap;
}
.aksrt-header-payvip__cta > i,
.aksrt-header-payvip:not(.is-vip) .payvip-icon > i,
.aksrt-header-payvip:not(.is-vip) .but > i {
margin: 0 !important;
color: inherit !important;
}
.aksrt-header-payvip__cta:hover {
color: #fff !important;
opacity: .92;
}
.aksrt-header-payvip__active {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 8px !important;
width: 100%;
min-height: 42px;
padding: 7px 10px !important;
white-space: nowrap;
}
.aksrt-header-payvip__level {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
}
.aksrt-header-payvip__level > i {
margin: 0 !important;
}
.aksrt-header-payvip__exp {
display: inline;
margin: 0;
padding: 0;
border: 0;
background: none !important;
box-shadow: none;
color: inherit;
font-size: .85em;
font-weight: 400;
line-height: 1.3;
opacity: .9;
white-space: nowrap;
}
/* Navigation links are globally capped at 50px. Account actions are taller
* icon tiles and must opt out or their labels overlap the following row. */
.navbar-top .aksrt-header-userbox .header-user-href {
@@ -3155,24 +2938,6 @@ main.container,
margin-left: auto;
}
body.dark-theme .aksrt-header-checkin {
background: rgba(255, 193, 7, .18) !important;
color: #f0c14b !important;
}
body.dark-theme .aksrt-header-checkin > i {
color: #f0c14b !important;
}
body.dark-theme .aksrt-header-wallet {
background: rgba(255, 255, 255, .06);
}
body.dark-theme .aksrt-header-wallet__item,
body.dark-theme .aksrt-header-wallet__item b {
color: inherit;
}
@media (max-width: 360px) {
.aksrt-header-userbox .header-user-href {
gap: 2px;
+1 -1
View File
File diff suppressed because one or more lines are too long
+5 -240
View File
@@ -1,8 +1,10 @@
/**
* Header account popover.
*
* The shared legacy navigation styles provide the popover shell. This module
* owns AKSRT-specific account content such as check-in, wallet and VIP rows.
* The shared legacy navigation styles provide the popover shell, and every
* account row (avatar, VIP bar, check-in, wallet tiles, stats badges) renders
* through the reference legacy classes. This module only owns the navigation
* shell anchoring plus the account action-row geometry.
*/
/* The desktop action cluster owns one horizontal alignment context. */
@@ -165,85 +167,10 @@
}
.aksrt-header-userbox {
width: 260px;
color: var(--color-ink-2);
}
.aksrt-header-userbox .user-info {
min-height: 44px;
padding: 2px;
}
.aksrt-header-userbox .user-info > .avatar {
flex: 0 0 44px;
width: 44px;
height: 44px;
object-fit: cover;
}
.aksrt-header-userbox .user-right,
.aksrt-header-userbox .user-right > .flex1 {
min-width: 0;
}
.aksrt-header-userbox .user-right b {
display: flex;
align-items: center;
gap: 4px;
max-width: 100%;
overflow: hidden;
white-space: nowrap;
}
.aksrt-header-userbox .display-name {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.aksrt-header-userbox .user-right .img-icon,
.aksrt-header-userbox .user-right .aksrt-user-level-icon,
.aksrt-header-userbox .user-right .aksrt-identity-medal,
.aksrt-header-userbox .user-right .aksrt-header-user-medal,
.aksrt-header-userbox .user-right .aksrt-identity-certification-icon {
flex: 0 0 auto;
height: 1.1em;
}
.aksrt-header-userbox .user-info > .abs-right {
top: 50%;
right: 2px;
transform: translateY(-50%);
display: inline-flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
border-radius: 50%;
background: var(--surface-2);
color: var(--color-ink-3);
}
.aksrt-header-userbox .aksrt-notification-badge {
position: absolute;
top: -4px;
right: -4px;
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 17px;
height: 17px;
padding: 0 4px;
border: 2px solid var(--surface-1);
border-radius: 999px;
background: #e74c3c;
color: #fff;
font-size: 10px;
font-weight: 700;
line-height: 1;
}
/* Top-nav bell badge (the card itself uses the legacy badge.top element). */
.aksrt-nav-notification .aksrt-notification-badge {
position: absolute;
top: 2px;
@@ -263,150 +190,6 @@
line-height: 1;
}
.aksrt-header-wallet {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
width: 100%;
padding: 9px 10px;
border-radius: 8px;
background: var(--surface-2);
color: var(--color-ink-2);
font-size: 12px;
line-height: 1.35;
}
.aksrt-header-wallet:hover {
color: var(--color-ink);
}
.aksrt-header-wallet__item {
min-width: 0;
white-space: nowrap;
}
.aksrt-header-wallet__item i {
margin-right: 2px;
color: var(--color-ink-3);
}
.aksrt-header-wallet__item b {
margin-left: 2px;
color: var(--color-ink);
font-weight: 700;
}
.aksrt-header-checkin {
display: inline-flex !important;
align-items: center;
justify-content: center;
gap: 6px;
width: 100% !important;
min-height: 36px;
margin: 0;
padding: 8px 10px !important;
border: 0 !important;
border-radius: 6px !important;
background: #fff6db !important;
color: #8a5a00 !important;
font-size: 13px !important;
font-weight: 600;
line-height: 1.3;
white-space: nowrap;
}
.aksrt-header-checkin > i {
margin: 0 !important;
color: #b78103 !important;
}
.aksrt-header-checkin:hover {
background: #fff0c2 !important;
color: #8a5a00 !important;
}
/* 已签到态对齐参考主题:保留原配色(参考主题签到后仍为同一彩色按钮),
* 且按钮可点击(打开签到详情弹窗);仅请求进行中的禁用态降不透明度。 */
.aksrt-header-checkin:disabled,
.aksrt-header-checkin:disabled:hover {
cursor: default;
opacity: .85;
}
.aksrt-header-payvip__cta,
.aksrt-header-payvip:not(.is-vip) .payvip-icon,
.aksrt-header-payvip:not(.is-vip) .but {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
gap: 6px !important;
width: 100% !important;
min-width: 0 !important;
min-height: 36px;
margin: 0 !important;
padding: 8px 10px !important;
border: 0 !important;
border-radius: 6px !important;
background: linear-gradient(90deg, #ff6b6b, #f04494) !important;
color: #fff !important;
font-size: 13px !important;
font-weight: 600;
line-height: 1.3;
text-align: center;
white-space: nowrap;
}
.aksrt-header-payvip__cta > i,
.aksrt-header-payvip:not(.is-vip) .payvip-icon > i,
.aksrt-header-payvip:not(.is-vip) .but > i {
margin: 0 !important;
color: inherit !important;
}
.aksrt-header-payvip__cta:hover {
color: #fff !important;
opacity: .92;
}
.aksrt-header-payvip__active {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 8px !important;
width: 100%;
min-height: 42px;
padding: 7px 10px !important;
white-space: nowrap;
}
.aksrt-header-payvip__level {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
}
.aksrt-header-payvip__level > i {
margin: 0 !important;
}
.aksrt-header-payvip__exp {
display: inline;
margin: 0;
padding: 0;
border: 0;
background: none !important;
box-shadow: none;
color: inherit;
font-size: .85em;
font-weight: 400;
line-height: 1.3;
opacity: .9;
white-space: nowrap;
}
/* Navigation links are globally capped at 50px. Account actions are taller
* icon tiles and must opt out or their labels overlap the following row. */
.navbar-top .aksrt-header-userbox .header-user-href {
@@ -451,24 +234,6 @@
margin-left: auto;
}
body.dark-theme .aksrt-header-checkin {
background: rgba(255, 193, 7, .18) !important;
color: #f0c14b !important;
}
body.dark-theme .aksrt-header-checkin > i {
color: #f0c14b !important;
}
body.dark-theme .aksrt-header-wallet {
background: rgba(255, 255, 255, .06);
}
body.dark-theme .aksrt-header-wallet__item,
body.dark-theme .aksrt-header-wallet__item b {
color: inherit;
}
@media (max-width: 360px) {
.aksrt-header-userbox .header-user-href {
gap: 2px;
-15
View File
@@ -102,21 +102,6 @@
cursor: wait;
}
.vipbg-v2 {
display: flex;
align-items: center;
justify-content: center;
gap: 4px;
padding: 8px 10px;
border-radius: 8px;
color: #fff;
background: linear-gradient(90deg, #ffb347, #ff6b6b);
}
.vipbg-v2.level-2 {
background: linear-gradient(90deg, #9b59b6, #3f51b5);
}
.vip-expdate-tag {
font-size: 12px;
}