- 新增 GET /api/fonts 列出二进制同级 font/ 目录里的字体文件,/fonts/<文件名> 对外提供(只认一级文件名,拒绝穿越) - 站点设置新增 font.url / font.family,校验只接受 http(s):// 或 /fonts/ 开头的链接 - 前台按设置注入 @font-face 或 CSS 链接并覆盖 --su-font-sans;留空回到内置文楷 - 后台「系统管理」新增字体选择 + 链接 + 族名;撤销/保存按钮覆盖该页 - 撤掉上一轮的霞鹜新晰黑改动
13 KiB
13 KiB
Stash 交接文档
更新于 2026-11-04 19:30(Asia/Shanghai)。本文件是当前状态,取代旧版历史快照。 新会话先读这份,再按需看
README.md、docs/ADMIN-PLAN.md、stash-ui/README.md。
1. 一句话现状
Stash 是「本地项目托管 + 可配置导航首页」:Rust 单 crate 内嵌 React 前端,单管理员登录,内容库为 SQLite,分组 / 条目 / 首页卡片 / 站点设置都在 /admin 管理。
当前开发分支 develop,本地服务:
- 前台 + 后台:http://127.0.0.1:8080
- 管理后台:http://127.0.0.1:8080/admin
- 接口一览:http://127.0.0.1:8080/interface
- Vite 开发服务器
5173当前未运行;需要时cd stash-web && npm run dev
2. 仓库与分支
| 仓库 | 路径 | 分支 | 状态 |
|---|---|---|---|
| 主项目 | D:\CNWei\CNW\Rust\stash |
develop |
工作区干净;功能最新 1d1ece6,本文件随后单独提交 |
| 组件库 | D:\CNWei\CNW\Rust\stash-ui |
master |
工作区只有忽略的 .idea/;994436a 最新 |
- 主项目 remote 名为
master(不是origin),地址https://gitea.ngmao.com/CNWei/stash.git。 develop比master/develop领先 20 个提交,尚未推送;此前 HTTPS 凭据不可用,需要时先准备 Gitea 凭据。stash-ui也有 3 个未推送提交:b97c77e(SearchField suffix)、46829cd(Input leading)、994436a(EngineIcon)。@stash/ui以file:../../stash-ui引入,stash-web使用其dist/;改组件库后必须重新npm run build。
3. 启动 / 构建 / 测试
前端产物会被 build.rs 内嵌,顺序不能反:
cd D:\CNWei\CNW\Rust\stash\stash-web
npm run build # tsc -b + vite,产物 dist/
cd D:\CNWei\CNW\Rust\stash
Get-Process stash -ErrorAction SilentlyContinue |
Where-Object { $_.Path -like '*stash\target*' } | Stop-Process -Force # 否则 exe 被占用
cargo build
Start-Process .\target\debug\stash.exe `
-RedirectStandardOutput "$env:TEMP\stash.log" `
-RedirectStandardError "$env:TEMP\stash-err.log" -WindowStyle Hidden
测试(Windows 下覆盖 TEMP 权限):
$env:TEMP = "D:\CNWei\CNW\Rust\stash\target\tmp"; $env:TMP = $env:TEMP
cargo test # 交接时 52 passed
组件库:
cd D:\CNWei\CNW\Rust\stash-ui
npm run build # dist/stash-ui.js + .css + types
4. 代码地图
src/
main.rs / lib.rs 启动、参数、日志
config.rs 端口 / 数据目录 / 托管目录
server.rs 全部 API + 内嵌前端 + SPA 回落
listing.rs 托管目录扫描
watcher.rs 文件监听 + SSE 防抖
db/
mod.rs Db 门面 + 迁移/种子测试
schema.rs 建表、种子、v15→…→v23 迁移
auth.rs admin / session / argon2id
settings.rs settings JSON + 校验
entries.rs 条目 CRUD、浏览、点赞、审计
groups.rs 分组树 CRUD / 移动 / 排序
cards.rs 卡片与勾选分组
catalog.rs 分组树 + 条目查询组装
stash-web/src/
AppNext.tsx 前台壳:路由、卡片、侧栏、搜索框、主题
main.tsx /admin 与普通前台分流
settings.ts SiteSettings 类型 / 默认值 / API 客户端
manage.ts 分组、卡片、catalog2 客户端
items.ts 条目编辑客户端
api.ts 项目扫描 / SSE 客户端
components/
admin/AdminNext.tsx 后台全部面板
header/SiteHeader.tsx 品牌 / 滚动信息 / 操作图标
content/ 卡片、网格、详情、编辑器
sidebar/ 资料卡、本地服务、导航
stash-ui/src/components/ SearchField / Input / EngineIcon 等
5. 数据库(v23)
路径:target/debug/data/stash.db(--data 可覆盖)。
PRAGMA user_version = 23;支持 0 建全量、15→16→…→23 迁移,高于程序版本拒绝启动。- 当前表:
admin、audit、card、card_group、entry、entry_tag、node、session、setting。 - 当前数据(交接时):15 个 node、44 条 entry、5 张 card;
PRAGMA foreign_key_check无异常。 section_block与node.view_mode / empty_text / show_in_sidebar / allow_groups已在 v23 删除。entry.format是每条内容自己的apps / posters / articles,同一分组可混合。node.kind = 'section'是根分组,group是子分组;enabled控制整棵子树显示。- 条目只存
node_key;格式、分组、卡片都通过业务 key 关联。 - 备份:
target/debug/data/stash.db.bak-pre-cleanup-v22是 v23 改造前快照;/api/backup可下载当前快照。 - 不要直接
cargo clean/删除整个target:运行库和备份在target/debug/data/。
6. settings JSON
setting 表 key='site',API GET/PATCH /api/settings,version 乐观锁。当前字段:
{
"header": { "enabled": true, "speed": 24, "gap": 26, "items": [...] },
"sidebar": { "show_profile": true, "show_service": false, "show_nav": true },
"background": { "light": "", "dark": "" }, // 空 = 内置背景
"font": { "url": "", "family": "" }, // 空 = 内置文楷;url 为 /fonts/xxx 或外部链接
"search": {
"default": "internal",
"engines": [
{ "id": "google", "name": "Google", "url": "https://www.google.com/search?q={query}", "enabled": true },
{ "id": "bing", "name": "Bing", "url": "https://www.bing.com/search?q={query}", "enabled": true },
{ "id": "baidu", "name": "百度", "url": "https://www.baidu.com/s?wd={query}", "enabled": true },
{ "id": "sogou", "name": "搜狗", "url": "https://www.sogou.com/web?query={query}", "enabled": true },
{ "id": "360", "name": "360", "url": "https://www.so.com/s?q={query}", "enabled": true }
]
},
"profile": { "name": "...", "role": "...", "description": "...", "location": "...", "avatar": "" },
"site": { "title": "...", "favicon": "", "theme": "light", "brand": {...}, "actions": {...} }
}
search.default可以是internal或某个引擎 id;默认默认值是internal。- 上面是字段结构示例;实际值以
GET /api/settings为准(交接时search.default=internal、site.theme=light,background 两项使用自定义 picsum 图)。 - 外部引擎 URL 必须以
http(s)://开头并包含{query},否则后端 400。 - 引擎 id 固定为
google / bing / baidu / sogou / 360,因为图标与 id 对应;暂不支持新增自定义引擎。 background.light/dark为空时用内置stash-web/src/assets/site-bg.jpg/site-bg-dark.jpg;否则填托管目录public/路径或完整 URL。- 旧 settings JSON 缺失字段会自动回落默认值;多余旧字段在下次保存时被丢弃。
7. 当前功能 / 后台 IA
后台左侧导航:
- 分组管理:根分组 / 子分组树、编辑、移动、排序、启停、删除;
- 数据管理:按主分组列出条目(含子分组),每条可选格式;
- 首页管理
- 页头:开关、速度、滚动条目、品牌 / 图标 / 配色;
- 背景管理:亮色 / 暗色背景 URL + 预览 + 恢复内置;
- 搜索框:默认搜索项、五个外部引擎的名称 / URL / 启停、恢复默认;
- 侧边栏:资料卡 / 本地服务 / 分组导航显隐;
- 内容卡片:卡片 + 勾选分组 + 预览条数 + 排序;
- 资料管理:头像、名称、角色、简介、位置;
- 系统管理:改密码、下载备份、正文字体(
font/目录里的文件或外部字体 / CSS 链接)。
搜索框行为:
- 顶部悬浮标签显示当前引擎图标 + 名称,点击展开下拉;
- 第一项固定「站内搜索」,分隔线后是启用的外部引擎;
- 站内模式:输入过滤本地内容;回车打开第一个匹配条目/分组;
- 外部模式:输入不再过滤本地内容;回车用该引擎 URL 新标签页搜索;
- 当前选择存在本机 localStorage(
stash-search-engine),刷新后仍用它;引擎被停用 / 删除时回落到后台默认项。
主题:
- 深色背景来自 Alright 演示站,资源
site-bg-dark.jpg; - 明暗切换优先用 View Transition 整页快照交叉淡入(160ms),不支持时回退到 CSS 颜色过渡;
- 首帧由
index.html内联脚本按 localStorage / 系统偏好先上色; - 背景地址也缓存在 localStorage(
stash-background),刷新首帧直接用它,设置回来再校准,不会先闪内置背景; - 页头图标显示当前实际明暗(深色月亮 / 浅色太阳),点它是切到另一侧;
- 背景图两层(light/dark)交叉淡入。
8. HTTP API(当前保留)
GET /api/health
GET /api/projects GET /api/projects/events (SSE)
GET /api/catalog2 分组树 + 卡片
GET /api/catalog/events SSE:catalog 变化
GET /api/settings
PATCH /api/settings 需登录,{version,settings}
GET /api/fonts font/ 目录里的字体清单(公开读)
POST /api/nodes 需登录
PATCH /api/nodes/{key} 需登录
DELETE /api/nodes/{key} 需登录
POST /api/cards 需登录
PATCH /api/cards/{id} 需登录
DELETE /api/cards/{id} 需登录
PUT /api/cards/{id}/groups 需登录
GET /api/items/{key}
POST /api/items 需登录
PATCH /api/items/{key} 需登录
DELETE /api/items/{key} 需登录
POST /api/items/{key}/view
POST /api/items/{key}/like
GET /api/backup 需登录
GET /api/auth/session
POST /api/auth/setup / login / logout
PATCH /api/auth/password
已删除:/api/catalog、/api/categories/*、旧 /api/groups/{id}。
9. 组件库改动(stash-ui)
SearchField新增可选suffix与leading插槽;Input新增leadingReactNode,优先于icon;- 新增
EngineIcon(internal/google/bing/baidu/sogou/360),图标路径来自参考稿;18px默认、14px用于顶部小标签; - 构建产物已更新,
stash-web通过 file 依赖读取;改库后必须重建 dist,否则主项目构建仍用旧类型/资源。
10. 已知限制 / 坑
| 项 | 说明 |
|---|---|
| 推送 | 本地 develop 领先远端 20 个提交,尚未推送;Gitea HTTPS 凭据需准备 |
| 搜索引擎 | id 固定五个;新增需同时补 EngineIcon、后端校验、前端默认值、后台面板 |
| 搜索选择记忆 | 存本机 localStorage(stash-search-engine);换设备 / 清站点数据后回到后台默认 |
| 图片上传 | 背景 / 头像 / Logo 只支持 URL,不支持上传 |
| 卡片/分组拖拽 | 排序用数值 / 现有 SortableList;分组拖拽排序未做 |
| 备份恢复 | 只有 /api/backup 下载;恢复需停机替换库文件 |
| 旧接口 | 已删;不要再按旧文档调用 /api/catalog 或 categories |
| 双份示例 | public/git_helper/ 是 Rust 托管示例;stash-web/public/git_helper/ 是 Vite dev 示例,两份都保留 |
| exe 占用 | 重启/构建前先杀 stash.exe,否则 cargo build 拒绝访问 |
| 编码 | 源码 UTF-8;PowerShell 控制台可能显示乱码,以 read 工具为准,别用 Set-Content 改中文源码 |
11. 最近提交(主项目,倒序)
1d1ece6 fix(group): 分组面包屑保留详情页外框
9d1e5dc fix(group): 分组页面包屑与详情页统一
4862f8f fix(search): 外部引擎模式不再过滤本地内容
aa6f341 feat(search): 按参考稿重做搜索框并支持后台配置
5ae2088 style(search): 引擎图标恢复 18px
200908c style(search): 引擎图标统一使用组件库图标
56f362f feat(search): 点击放大镜切换搜索引擎
8c1c658 feat(search): 效果五快捷栏加入本地搜索
038b7ec feat(search): 搜索框支持切换搜索引擎
a5d7859 fix(theme): 用整页快照过渡消除明暗割裂
5439ebf feat(admin): 增加背景管理
b9005dd style(theme): 暗色使用 Alright 同款深色背景
组件库最近:
994436a feat(icons): 增加搜索引擎图标
46829cd feat(input): 增加左侧 leading 插槽
b97c77e feat(search): SearchField 增加 suffix 插槽
12. 新会话建议顺序
- 打开 http://127.0.0.1:8080 与
/admin冒烟;确认 8080 在跑(当前 PID 会变,不必依赖 PID)。 - 改前端:
cd stash-web && npm run build→ 杀 stash →cargo build→ 启动。 - 改组件库:先
cd stash-ui && npm run build,再构建stash-web,最后 Rust。 - 改设置结构:同时改
src/db/settings.rs、stash-web/src/settings.ts、后台面板和默认值;旧 JSON 由 serde 默认值兜底。 - 改数据库结构:升
SCHEMA_VERSION并补迁移与迁移测试;先备份target/debug/data/stash.db。 - 视觉改动用 Playwright 截图到
stash-ui/shots/验证;脚本在stash-ui/.ref/(不提交)。 - 收尾跑
cargo test(52 条)和npm run build,确认工作区干净。