feat: 搜索带并入 Layout toolbar,后台重组首页配置

前台
- 搜索框从内容列移到 Layout 的 toolbar 插槽,去掉 fixed + TOP_OFFSET + top-blur 三处补偿
- 左右栏滚动容器不变,左栏吸顶改用 CSS sticky(修回顶时侧栏抖动)
- 只让分组导航滚动,资料卡与本地服务固定
- 页头操作支持配置:搜索改为刷新(重扫项目 + 重拉内容库)
- 站点级设置:页面标题 / favicon / 品牌 logo / 品牌文字
- 停用的分组在侧边栏、首页卡片、分组页、条目页统一不再出现

后台
- 「侧边栏」「首页卡片」合并为「首页」Tab
- 首页卡片表格新增状态列与顺序列(上下箭头即时保存)
- 分组显隐只由「分组管理 → 状态」决定,去掉侧栏独立勾选
- 页头 Tab 增加站点信息、首页 Logo(带实时预览)、操作工具开关
- 后台页头与前台同构并吸顶

后端
- settings 新增 site(标题 / favicon / 品牌 / 操作工具)与 sidebar.show_nav
- 写接口成功后广播内容库变更,SSE 改为「广播 + data_version 兜底」
- catalog SSE 事件名与前端监听对齐(catalog)
This commit is contained in:
2026-11-01 15:15:20 +08:00
parent bb5a615ed2
commit 59fd61d832
9 changed files with 822 additions and 296 deletions
+157 -49
View File
@@ -6,7 +6,7 @@
z-index: 1;
/* 透明:让固定背景图从下面透出来(Layout 默认有底色) */
background-color: transparent;
/* 旧版阴影是 2% / 6%,比库默认更深,属于主题级覆盖 */
/* 旧版影子是 2% / 6%,比库默认更深,属于主题级覆盖 */
--su-shadow-card: 0 6px 16px rgba(27, 26, 49, 0.02);
--su-shadow-hover: 0 6px 16px rgba(27, 26, 49, 0.06);
}
@@ -63,6 +63,24 @@
font-weight: var(--su-font-weight-strong);
}
.site-brand-logo {
width: 32px;
height: 32px;
border-radius: var(--su-radius-sm);
object-fit: contain;
}
/* 后台「首页 Logo」的实时预览 */
.brand-preview {
display: flex;
align-items: center;
gap: var(--su-space-2);
padding: var(--su-space-3) var(--su-space-4);
border: 1px dashed var(--su-border);
border-radius: var(--su-radius-md);
background-color: var(--su-bg-card);
}
.site-brand-name {
font-size: var(--su-font-size-lg);
line-height: var(--su-line-height-lg);
@@ -114,8 +132,10 @@
transform: translateX(0);
}
/* 位移量由 SiteHeader 量出「一组」的真实宽度写进 --ticker-shift;
回退值仅在第一帧兜底,正常情况不会用到 */
to {
transform: translateX(calc(-100% / 3));
transform: translateX(var(--ticker-shift, -33.3333%));
}
}
@@ -129,16 +149,18 @@
margin-left: auto;
}
/* ---------- 搜索:悬浮在页头下方居中 ---------- */
/* ---------- 搜索:页头下的工具条(Layout 的 toolbar 插槽) ---------- */
.search-toolbar {
display: flex;
justify-content: center;
/* 整条带 120(32 + 44 + 44):搜索框比贴着页头时再往下挪 16 */
padding: var(--su-space-8) 0 calc(var(--su-space-10) + var(--su-space-1));
}
.search-row {
position: fixed;
top: 76px;
left: 50%;
z-index: var(--su-z-header);
width: min(480px, calc(100vw - 48px));
width: min(480px, 100%);
height: 44px;
transform: translateX(-50%);
}
/* 旧版搜索是「浅边框 + 卡片阴影」,聚焦时不额外加边框/焦点环 */
@@ -151,31 +173,6 @@
/* 搜索框保持实底清晰,透明度/虚化只作用于周围区域 */
/* 搜索区域软虚化:上下都用 mask 渐隐,不出现横向分割线 */
.top-blur {
position: fixed;
top: 60px;
right: 0;
left: 0;
z-index: 4;
height: 120px;
pointer-events: none;
background: linear-gradient(
to bottom,
color-mix(in srgb, var(--su-bg-page) 22%, transparent) 0%,
transparent 80%
);
backdrop-filter: blur(8px);
mask-image: linear-gradient(to bottom, transparent 0%, #000 28%, #000 62%, transparent 100%);
-webkit-mask-image: linear-gradient(
to bottom,
transparent 0%,
#000 28%,
#000 62%,
transparent 100%
);
}
/* ---------- 两栏骨架 ---------- */
.content {
@@ -214,7 +211,7 @@
display: flex;
flex-direction: column;
gap: var(--su-space-4);
padding-top: 88px;
padding-top: 0;
}
/* ---------- 侧栏卡片 ---------- */
@@ -855,13 +852,11 @@
background-color: var(--su-bg-page);
}
/* 与前台页头同一套:整条吸顶,内部 .site-header-inner 负责 60 高与限宽 */
.admin-topbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--su-space-4);
height: 64px;
padding: 0 var(--su-space-6);
position: sticky;
top: 0;
z-index: var(--su-z-header);
border-bottom: 1px solid var(--su-border);
background-color: var(--su-bg-card);
}
@@ -949,15 +944,12 @@
display: none;
}
.search-row {
position: static;
width: 100%;
height: 36px;
transform: none;
.search-toolbar {
padding: var(--su-space-5) 0 var(--su-space-6);
}
.content {
padding-top: var(--su-space-4);
padding-top: var(--su-space-2);
}
}
@@ -1326,7 +1318,7 @@ a.entry-href:hover {
min-width: 0;
}
/* 首页:左右栏共用一个滚动区,左侧到底后吸底 */
/* 首页:左右栏共用一个滚动区,左侧吸顶交给 CSS sticky */
#page-scroll {
scrollbar-width: none;
-ms-overflow-style: none;
@@ -1336,6 +1328,46 @@ a.entry-href:hover {
display: none;
}
/* 左栏吸顶:sticky 由滚动引擎处理,不会像 JS 改 transform 那样落后平滑滚动一帧。
高度锁在滚动区高度内,栏内只有「分组导航」可滚,资料卡与本地服务保持不动。 */
#page-scroll > aside {
position: sticky;
top: 0;
align-self: flex-start;
height: 100%;
max-height: 100%;
overflow: hidden;
}
#page-scroll > aside .sidebar-wrap,
#page-scroll > aside .sidebar-home {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
}
#page-scroll > aside .profile-card,
#page-scroll > aside .service-panel {
flex-shrink: 0;
}
/* 只有导航卡参与滚动,滚动条隐藏 */
#page-scroll > aside .nav-card {
flex: 0 1 auto;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
scrollbar-width: none;
-ms-overflow-style: none;
}
#page-scroll > aside .nav-card::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
}
.sidebar-home {
padding-top: 0;
padding-bottom: 24px;
@@ -1477,10 +1509,29 @@ a.entry-href:hover {
.cards-table-wrap {
margin-top: var(--su-space-2);
/* 列多了以后表格会比面板宽,横向滚动而不是把名字挤成两三行 */
overflow-x: auto;
}
.cards-table th,
.cards-table td {
padding: var(--su-space-2);
}
.cards-col-limit {
width: 140px;
width: 100px;
}
/* 分组名不换行,超长省略;列宽固定,保证五列都落在面板内 */
.cards-table {
table-layout: fixed;
}
.cards-table td:first-child .group-name {
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.cards-table th,
@@ -1488,6 +1539,63 @@ a.entry-href:hover {
padding: var(--su-space-2) var(--su-space-4);
}
/* 首页 Tab:侧边栏设置 + 首页卡片上下两段 */
.admin-home {
display: flex;
flex-direction: column;
gap: var(--su-space-4);
}
.admin-home-section {
display: flex;
flex-direction: column;
gap: var(--su-space-3);
}
/* 首页卡片:分组展示顺序(表格里的「顺序」列,上下箭头即时保存) */
.cards-col-state {
width: 72px;
}
.cards-col-order {
width: 92px;
}
.card-order-cell {
display: flex;
align-items: center;
gap: 2px;
}
/* 分组管理里状态为「关闭」的分组:卡片里只能看、不能勾选 */
.group-off-tag {
display: inline-block;
padding: 0 8px;
border-radius: var(--su-radius-pill);
background-color: var(--su-gray-2);
color: var(--su-text-muted);
font-size: var(--su-font-size-xs);
line-height: 20px;
white-space: nowrap;
}
.group-state-on {
font-size: var(--su-font-size-xs);
color: var(--su-text-muted);
}
.card-order-index {
display: grid;
place-items: center;
width: 20px;
height: 20px;
margin-right: var(--su-space-1);
border-radius: var(--su-radius-pill);
background-color: var(--su-color-primary-soft);
color: var(--su-color-primary);
font-size: var(--su-font-size-xs);
}
@media (max-width: 860px) {
.cards-manager {
grid-template-columns: 1fr;