From fbda2930727fdd3f2d6b89abbaf6a06ba8984c14 Mon Sep 17 00:00:00 2001 From: Sakurasan <26715255+Sakurasan@users.noreply.github.com> Date: Wed, 23 Sep 2026 15:37:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=99=E7=99=BD=20UI=EF=BC=9A=E6=8C=89?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E7=A8=BF=E6=A8=A1=E5=9D=97=E5=8C=96=E8=BF=98?= =?UTF-8?q?=E5=8E=9F=20+=20=E7=AB=99=E4=B8=BB=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=20CSS=20+=20=E8=AF=A6=E6=83=85=20neighbors=20+=20=E9=9D=99?= =?UTF-8?q?=E6=80=81=E7=BC=93=E5=AD=98=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 前端(新增 ui/yohaku/,各视图按 ui_id=vivid 分支渲染;classic 与后台不受影响) - 令牌层:设计稿数值原样落地,28 个 --v-* 为站主接口(自定义 CSS 可覆盖, 放 @layer 让出优先级);另加防线,中和 styles.css 裸选择器 (h1 衬线 / body 行高 / 后台 .stat/.toolbar/.chip 卡片)漏进余白元素 - 顶栏(滚动收缩态)/ 阅读进度(顶部 2px + READ n%)/ 页脚 - 首页:hero(统计条)/ 筛选(类型分段 + 标签 chips + 搜索)/ 长文卡片与短文纸条 / 分页 / 作品展示区(3 件 + 查看所有,参照 diygod.cc); 面板栅格改 1.6fr 1fr 1fr 且高度自适应内容(标签云明显大一圈) - 文章页:三栏「纸」—— 左时间线(前后各两篇)/ 中纸张 / 右目录与阅读进度; 短文详情不显示标题(h1 视觉隐藏保留无障碍) - 全部规则收敛在 html[data-ui='vivid'] 前缀下;无 !important 后端 - GET /api/posts/:slug 增 neighbors(前后各两篇,详情页侧栏时间线用) - SPA 缓存头:index.html no-cache,assets/ 带 hash 长期 immutable (此前无缓存头,浏览器会一直拿旧构建) 其他 - 站主自定义 CSS 管线(customCss.js + ui/sections.js,按分区注入,仅 vivid) - 删除旧 vivid 覆盖层实现(VividNav/Hero/Footer/Timeline/Toc、ui/vivid.css) - 设计稿原型附于仓库根 index.html;作品表清掉外链 diygod.cc 的示例封面, 改用本地占位图(public/covers/) --- README.md | 71 +- backend/internal/admin/api_test.go | 64 + backend/internal/api/api.go | 10 +- backend/internal/model/model.go | 10 + backend/internal/store/store.go | 157 ++- backend/internal/store/store_test.go | 116 ++ backend/main.go | 12 +- frontend/index.html | 21 + frontend/public/covers/folo.jpg | Bin 0 -> 3744 bytes frontend/public/covers/inkplate.jpg | Bin 0 -> 3836 bytes frontend/public/covers/one.jpg | Bin 0 -> 3995 bytes frontend/public/covers/rsshub.jpg | Bin 0 -> 4096 bytes frontend/public/covers/xlog.jpg | Bin 0 -> 3743 bytes frontend/src/App.vue | 19 +- frontend/src/admin/SettingsView.vue | 280 ++++- frontend/src/components/LeftNav.vue | 9 +- frontend/src/components/RightRail.vue | 8 +- frontend/src/customCss.js | 80 ++ frontend/src/main.ts | 11 + frontend/src/site.js | 77 +- frontend/src/ui/sections.js | 15 + frontend/src/ui/yohaku/YohakuAbout.vue | 37 + frontend/src/ui/yohaku/YohakuArchive.vue | 48 + frontend/src/ui/yohaku/YohakuArticle.vue | 193 +++ frontend/src/ui/yohaku/YohakuFeed.vue | 65 + frontend/src/ui/yohaku/YohakuFoot.vue | 34 + frontend/src/ui/yohaku/YohakuHero.vue | 38 + frontend/src/ui/yohaku/YohakuHome.vue | 89 ++ frontend/src/ui/yohaku/YohakuPager.vue | 22 + frontend/src/ui/yohaku/YohakuProjects.vue | 37 + frontend/src/ui/yohaku/YohakuTags.vue | 40 + frontend/src/ui/yohaku/YohakuToolbar.vue | 69 + frontend/src/ui/yohaku/YohakuTop.vue | 61 + frontend/src/ui/yohaku/article.css | 182 +++ frontend/src/ui/yohaku/chrome.css | 138 ++ frontend/src/ui/yohaku/home.css | 243 ++++ frontend/src/ui/yohaku/pages.css | 160 +++ frontend/src/ui/yohaku/panels.css | 79 ++ frontend/src/ui/yohaku/tokens.css | 249 ++++ frontend/src/views/AboutView.vue | 26 +- frontend/src/views/ArchiveView.vue | 10 +- frontend/src/views/HomeView.vue | 57 +- frontend/src/views/PostView.vue | 44 +- frontend/src/views/ProjectsView.vue | 12 +- frontend/src/views/TagsView.vue | 12 +- index.html | 1396 +++++++++++++++++++++ 46 files changed, 4266 insertions(+), 35 deletions(-) create mode 100644 frontend/public/covers/folo.jpg create mode 100644 frontend/public/covers/inkplate.jpg create mode 100644 frontend/public/covers/one.jpg create mode 100644 frontend/public/covers/rsshub.jpg create mode 100644 frontend/public/covers/xlog.jpg create mode 100644 frontend/src/customCss.js create mode 100644 frontend/src/ui/sections.js create mode 100644 frontend/src/ui/yohaku/YohakuAbout.vue create mode 100644 frontend/src/ui/yohaku/YohakuArchive.vue create mode 100644 frontend/src/ui/yohaku/YohakuArticle.vue create mode 100644 frontend/src/ui/yohaku/YohakuFeed.vue create mode 100644 frontend/src/ui/yohaku/YohakuFoot.vue create mode 100644 frontend/src/ui/yohaku/YohakuHero.vue create mode 100644 frontend/src/ui/yohaku/YohakuHome.vue create mode 100644 frontend/src/ui/yohaku/YohakuPager.vue create mode 100644 frontend/src/ui/yohaku/YohakuProjects.vue create mode 100644 frontend/src/ui/yohaku/YohakuTags.vue create mode 100644 frontend/src/ui/yohaku/YohakuToolbar.vue create mode 100644 frontend/src/ui/yohaku/YohakuTop.vue create mode 100644 frontend/src/ui/yohaku/article.css create mode 100644 frontend/src/ui/yohaku/chrome.css create mode 100644 frontend/src/ui/yohaku/home.css create mode 100644 frontend/src/ui/yohaku/pages.css create mode 100644 frontend/src/ui/yohaku/panels.css create mode 100644 frontend/src/ui/yohaku/tokens.css create mode 100644 index.html diff --git a/README.md b/README.md index 829ab32..ebd350e 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,65 @@ ONE_ADMIN_USER=admin ONE_ADMIN_PASSWORD=换一个 make start | `ONE_WEB_DIST` | `./frontend/dist` | 前端构建产物目录 | | `ONE_DATA_DIR` | `./data` | SQLite 数据目录 | +## 界面:classic / vivid + +前台有两套完整界面,都保留,在后台 **设置 → 界面与自定义** 里整站切换(站点级设置,所有访客同款)。 +后台自身的外观不受影响。 + +| `ui_id` | 说明 | +| --- | --- | +| `classic`(默认) | 原来的极简版:三栏骨架(左导航 / 正文 / 右栏)、纸感分区线、衬线标题、首字下沉 | +| `vivid` | 顶部粘性导航 + 单栏卡片流、渐变配色与背景网格、悬浮卡片、首页 hero;支持站主自定义 CSS | + +实现要点,改这套东西前先读: + +- `ui_id` 写在 `` 上,由 `frontend/src/site.js` 的 `applyTheme()` 设置。 + `index.html` 里有一小段 inline script 先读 `localStorage['one.ui']` 设好,避免首帧闪一下 classic。 +- vivid 的皮肤**不复用** paper/sage/rose,而是让 `data-theme` 取 `vivid` / `vivid-dark` + (明暗仍由访客的 themeMode 决定)。这样两套调色板不会互相打架。 +- `frontend/src/ui/vivid.css` 是**纯覆盖层**,在 `main.ts` 里排在 `styles.css` 之后。 + **每个选择器都必须以 `html[data-ui="vivid"]` 开头**:scoped 样式编译后是 `.foo[data-v-HASH]` + (特指度 0,2,0),而 `html[data-ui="vivid"] .foo` 是 0,2,1 才能稳定取胜;scoped 样式是懒加载 chunk, + 在入口 CSS 之后才到位,漏了前缀会变成「有时生效有时不生效」。复合选择器要**整条链**镜像 + (如 `.card:hover .layer-front` 要写全,不能只前缀第一段)。该文件里不允许出现 `!important`。 +- vivid 把 classic 那 12 个 token 重新赋值(`--paper/--card/--ink/--accent/...`), + 所以读 token 的共享组件零改动就换了皮。vivid 自己的变量以 `--v-` 开头。 +- 顶部导航与首页 hero 是新增组件(`VividNav.vue` / `VividHero.vue`),由 `App.vue` 在 + `ui_id === 'vivid' && !isAdmin` 时渲染;`LeftNav.vue` / `RightRail.vue` 在 vivid 下自身不渲染, + 7 个公开视图没有任何改动。 + +### 站主自定义 CSS + +按分区分段写,存在 settings 的 `custom_css`(一行 JSON,`{分区: CSS}`)。 + +``` +global 全局 —— 每个前台页面都会加载,放变量和通用微调 +home 首页(含标签筛选) +post 文章详情(含短文) +archive 归档 +tags 标签云 + 单个标签下的列表 +projects 作品 +about 关于 +``` + +分区 id 必须与 `backend/internal/store/store.go` 的 `ValidCSSSections` +和 `frontend/src/ui/sections.js` 的 `SECTIONS` 三处保持一致,否则会出现「保存了但不生效」。 + +- **只在 `ui_id = vivid` 时注入**,并且 `/admin` 下一律清空 —— 写坏样式影响不到后台,classic 也完全不受影响。 +- 注入方式是两个 `` 也逃不出去,不需要 CSS 清洗库。 +- 上限:单个分区 16 KiB,全部合计 64 KiB。超限的分区会被**静默丢弃**(写的时候就不落库)。 +- 后台保存是**整对象 PUT**:请求里没带的字段会变成零值。用 curl 写的时候记得把其他字段一起带上。 + +可覆盖的变量(写进「全局」段即可整站生效):`--v-accent`、`--v-accent-2`、`--v-accent-3`、 +`--v-bg`、`--v-surface`、`--v-surface-2`、`--v-text`、`--v-text-soft`、`--v-muted`、`--v-line`、 +`--v-radius`、`--v-radius-pill`、`--v-content-width`、`--v-measure`、`--v-motion`(0 = 关掉全部动效)。 + +后台「界面与自定义」里内置了几个一键插入的片段(换主色 / 方正圆角 / 关渐变背景 / 首页单列), +它们只是往文本框里塞文本,不落库,插进去还能接着改。 + +> 注意:目前若将来给站点加 CSP,运行时的 ` \ No newline at end of file diff --git a/frontend/src/components/LeftNav.vue b/frontend/src/components/LeftNav.vue index e37d91a..0480320 100644 --- a/frontend/src/components/LeftNav.vue +++ b/frontend/src/components/LeftNav.vue @@ -1,12 +1,17 @@