diff --git a/HANDOFF.md b/HANDOFF.md index a3f822d..3027260 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -18,7 +18,7 @@ Stash 已从「只读本地导航站」升级为**可登录、可配置、可编辑内容的本地发布台**: - 登录(单用户,argon2id + Cookie 会话); -- `/admin` 设置页(页头滚动信息 / 首页卡片 / 归类 / 侧栏 / 资料 / 系统); +- `/admin` 设置页(页头 / 背景 / 内容卡片 / 侧栏 / 资料 / 系统); - 条目就地编辑(Drawer + 乐观锁); - 分区新增/删除、**条目新增/删除(可选分区与分组)**、分组(子分类)新建/改名/删除、侧栏子分类配置、浏览/点赞/分享/跳转; - 数据库自动迁移到 **v18**; @@ -79,7 +79,7 @@ src/ mod.rs Db 门面(所有方法)+ 迁移测试 schema.rs 建表、种子、版本迁移(0 / 15→…→23) auth.rs 管理员、密码哈希、会话(token 只存 sha256) - settings.rs settings JSON(header/sidebar/profile/site) + settings.rs settings JSON(header/sidebar/background/profile/site) entries.rs 条目读取/编辑、浏览数、点赞、审计 groups.rs 分组树新增/移动/排序/删除 cards.rs 首页卡片与勾选分组 diff --git a/src/db/settings.rs b/src/db/settings.rs index df60708..093e014 100644 --- a/src/db/settings.rs +++ b/src/db/settings.rs @@ -110,6 +110,15 @@ pub struct SidebarSettings { pub show_nav: bool, } +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] +#[serde(default)] +pub struct BackgroundSettings { + /// 亮色背景图地址;空表示用内置图 + pub light: String, + /// 暗色背景图地址;空表示用内置图 + pub dark: String, +} + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(default)] pub struct ProfileSettings { @@ -220,6 +229,7 @@ impl Default for SiteMetaSettings { pub struct Settings { pub header: HeaderSettings, pub sidebar: SidebarSettings, + pub background: BackgroundSettings, pub profile: ProfileSettings, pub site: SiteMetaSettings, } @@ -275,6 +285,16 @@ pub fn validate(settings: &Settings) -> Result<(), StashError> { if settings.profile.location.chars().count() > 40 { return Err(StashError::InvalidDirectory("位置最多 40 个字".into())); } + if settings.background.light.chars().count() > 500 { + return Err(StashError::InvalidDirectory( + "亮色背景地址最多 500 个字符".into(), + )); + } + if settings.background.dark.chars().count() > 500 { + return Err(StashError::InvalidDirectory( + "暗色背景地址最多 500 个字符".into(), + )); + } if settings.site.title.chars().count() > 120 { return Err(StashError::InvalidDirectory("页面标题最多 120 个字".into())); } diff --git a/stash-web/src/App.css b/stash-web/src/App.css index 5c737b6..55ab461 100644 --- a/stash-web/src/App.css +++ b/stash-web/src/App.css @@ -1379,3 +1379,46 @@ html.theme-transition .site-background { transition: none !important; } } + +/* 后台:背景管理预览 */ +.background-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--su-space-5); +} + +.background-section { + display: flex; + flex-direction: column; + gap: var(--su-space-3); + min-width: 0; +} + +.background-preview { + position: relative; + height: 180px; + border: 1px solid var(--su-border); + border-radius: var(--su-radius-md); + background-color: var(--su-bg-subtle); + background-position: center top; + background-repeat: no-repeat; + background-size: cover; + overflow: hidden; +} + +.background-preview span { + position: absolute; + bottom: var(--su-space-3); + left: var(--su-space-3); + padding: 2px var(--su-space-2); + border-radius: var(--su-radius-pill); + background-color: rgb(0 0 0 / 55%); + color: #fff; + font-size: var(--su-font-size-xs); +} + +@media (width <= 900px) { + .background-grid { + grid-template-columns: minmax(0, 1fr); + } +} diff --git a/stash-web/src/AppNext.tsx b/stash-web/src/AppNext.tsx index 15167f7..bb3fc4c 100644 --- a/stash-web/src/AppNext.tsx +++ b/stash-web/src/AppNext.tsx @@ -276,6 +276,7 @@ export default function AppNext() { show_service: true, show_nav: true, }, + background: { light: '', dark: '' }, profile: { name: '本地管理员', role: '管理员', @@ -644,8 +645,24 @@ export default function AppNext() { }} /> -
- + +