From a9a913942a55de0b639cdad2933483267692b2d2 Mon Sep 17 00:00:00 2001 From: CNWei Date: Wed, 4 Nov 2026 19:30:28 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E4=BA=A4=E6=8E=A5?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E5=88=B0=E5=BD=93=E5=89=8D=E6=90=9C=E7=B4=A2?= =?UTF-8?q?/=E8=83=8C=E6=99=AF/=E4=B8=BB=E9=A2=98=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 记录 develop 领先远端 19 个提交、stash-ui 三个未推送提交 - 更新 v23 库结构、settings(search/background)、后台 IA 与 API 清单 - 补充构建顺序、双份 git_helper、exe 占用等坑 --- HANDOFF.md | 387 ++++++++++++++++++++++++++++------------------------- 1 file changed, 202 insertions(+), 185 deletions(-) diff --git a/HANDOFF.md b/HANDOFF.md index a7800b1..17e0a53 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -1,236 +1,253 @@ # Stash 交接文档 -> 写于 2026-10-29。新会话第一件事:读这份 + `docs/ADMIN-PLAN.md` + `stash-ui/README.md`。 +> 更新于 2026-11-04 19:30(Asia/Shanghai)。本文件是当前状态,取代旧版历史快照。 +> 新会话先读这份,再按需看 `README.md`、`docs/ADMIN-PLAN.md`、`stash-ui/README.md`。 -> **⚠️ 这是一份历史快照,只保留当时的决策背景。** 2026-11-01 之后又做了这些改动, -> 下面正文里提到的文件名与页面结构可能已经不同,以 `README.md` 为准: -> -> - 前端 `App.tsx` → `AppNext.tsx`,后台 `admin/AdminPage.tsx` → `admin/AdminNext.tsx`(旧文件已删除); -> - 后台从横向 Tabs 改成**左侧导航 + 右侧内容**,页头归到「首页管理」下, -> Tab 名改为 分组管理 / 数据管理 / 首页管理(页头·侧边栏·内容卡片)/ 资料管理 / 系统管理; -> - 新增 `/interface` 接口一览页;侧栏「查看接口」走站内路由,不再直接开 `/api/projects`; -> - 接入 `@stash/ui` 组件库:前后台所有卡片、表格、开关、文字按钮都来自库里, -> 明暗主题(浅色 / 深色 / 跟随系统)由令牌接管; -> - 内容库表结构升到 v23 并**有了自动迁移**,卡片模型是 `card` + `card_group`;`section_block` 与旧 `node` 兼容字段已删除。 +## 1. 一句话现状 -## 0. 一句话现状 +Stash 是「本地项目托管 + 可配置导航首页」:Rust 单 crate 内嵌 React 前端,单管理员登录,内容库为 SQLite,分组 / 条目 / 首页卡片 / 站点设置都在 `/admin` 管理。 -Stash 已从「只读本地导航站」升级为**可登录、可配置、可编辑内容的本地发布台**: +当前开发分支 `develop`,本地服务: -- 登录(单用户,argon2id + Cookie 会话); -- `/admin` 设置页(页头 / 背景 / 内容卡片 / 侧栏 / 资料 / 系统); -- 条目就地编辑(Drawer + 乐观锁); -- 分区新增/删除、**条目新增/删除(可选分区与分组)**、分组(子分类)新建/改名/删除、侧栏子分类配置、浏览/点赞/分享/跳转; -- 数据库自动迁移到 **v18**; -- 前端 100% 使用组件库 `@stash/ui`(v0.3.1,42 个组件)。 +- 前台 + 后台: +- 管理后台: +- 接口一览: +- Vite 开发服务器 `5173` 当前**未运行**;需要时 `cd stash-web && npm run dev` -当前数据库**已设置管理员密码**(2026-10-30 由使用者设置);忘记密码按 §6 删除 `admin` 行即可回到首次设置。 +## 2. 仓库与分支 -## 1. 仓库与运行环境 +| 仓库 | 路径 | 分支 | 状态 | +| --- | --- | --- | --- | +| 主项目 | `D:\CNWei\CNW\Rust\stash` | `develop` | 工作区干净;功能最新 `1d1ece6`,本文件随后单独提交 | +| 组件库 | `D:\CNWei\CNW\Rust\stash-ui` | `master` | 工作区只有忽略的 `.idea/`;`994436a` 最新 | -| 项目 | 路径 | 分支 | 端口 | 说明 | -| --- | --- | --- | --- | --- | -| 新版(组件重构) | `D:\CNWei\CNW\Rust\stash` | `feat/use-stash-ui` | **8080** | 所有新功能都在这里 | -| 旧版(1:1 基线) | `D:\CNWei\CNW\Rust\stash-old`(worktree) | `develop` | **8081** | 只用于视觉对照,不要改 | -| 组件库 | `D:\CNWei\CNW\Rust\stash-ui` | `master` | — | tag `v0.1.0` / `v0.2.0` / `v0.3.0` / `v0.3.1` | +- 主项目 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`。 -后端:Rust 2024 + Axum 0.8 + rusqlite(bundled)。前端:React 19 + Vite + TS + CSS Modules,`@stash/ui` 通过 `file:` 依赖引入。 +## 3. 启动 / 构建 / 测试 -### 启动 / 构建(顺序重要) +前端产物会被 `build.rs` 内嵌,顺序不能反: ```powershell -# 1) 前端(产物会被 build.rs 内嵌,必须先构建) cd D:\CNWei\CNW\Rust\stash\stash-web -npm run build +npm run build # tsc -b + vite,产物 dist/ -# 2) 先杀掉正在运行的 stash.exe,否则 cargo 会报「拒绝访问」 -Get-Process stash -ErrorAction SilentlyContinue | Where-Object { $_.Path -like '*stash\target*' } | Stop-Process -Force - -# 3) 后端 -cd .. +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 +Start-Process .\target\debug\stash.exe ` + -RedirectStandardOutput "$env:TEMP\stash.log" ` + -RedirectStandardError "$env:TEMP\stash-err.log" -WindowStyle Hidden ``` -旧版(8081,仅在需要对照时): - -```powershell -D:\CNWei\CNW\Rust\stash-old\target\debug\stash.exe --port 8081 -``` - -### 测试 - -Windows 下 `TEMP` 权限有问题,跑测试要覆盖临时目录: +测试(Windows 下覆盖 TEMP 权限): ```powershell $env:TEMP = "D:\CNWei\CNW\Rust\stash\target\tmp"; $env:TMP = $env:TEMP -cargo test # 当前 48 passed +cargo test # 交接时 52 passed ``` -## 2. 目录 / 文件地图 +组件库: + +```powershell +cd D:\CNWei\CNW\Rust\stash-ui +npm run build # dist/stash-ui.js + .css + types +``` + +## 4. 代码地图 ``` src/ - main.rs / lib.rs 启动、日志 - config.rs 端口 / 数据目录(默认 target/debug/data) - server.rs 全部路由(API + 内嵌前端 + SPA 回落) - error.rs StashError(含 Conflict → 409) + main.rs / lib.rs 启动、参数、日志 + config.rs 端口 / 数据目录 / 托管目录 + server.rs 全部 API + 内嵌前端 + SPA 回落 + listing.rs 托管目录扫描 + watcher.rs 文件监听 + SSE 防抖 db/ - mod.rs Db 门面(所有方法)+ 迁移测试 - schema.rs 建表、种子、版本迁移(0 / 15→…→23) - auth.rs 管理员、密码哈希、会话(token 只存 sha256) - settings.rs settings JSON(header/sidebar/background/search/profile/site) - entries.rs 条目读取/编辑、浏览数、点赞、审计 - groups.rs 分组树新增/移动/排序/删除 - cards.rs 首页卡片与勾选分组 + 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 与 /login) - api.ts / auth.ts / settings.ts / items.ts / manage.ts 前端 API 客户端 + AppNext.tsx 前台壳:路由、卡片、侧栏、搜索框、主题 + main.tsx /admin 与普通前台分流 + settings.ts SiteSettings 类型 / 默认值 / API 客户端 + manage.ts 分组、卡片、catalog2 客户端 + items.ts 条目编辑客户端 + api.ts 项目扫描 / SSE 客户端 components/ - header/SiteHeader.tsx 品牌 + 滚动信息 + 操作图标 - admin/AdminNext.tsx /admin 全部 Tab - auth/LoginDialog.tsx Modal 登录 - content/ 首页、条目、文章、编辑器 - sidebar/ 资料卡、服务面板、导航 -docs/ADMIN-PLAN.md 后台方案 + P0–P4 实施记录 + 未做项 -README.md 运行、路由、库结构、登录说明 + admin/AdminNext.tsx 后台全部面板 + header/SiteHeader.tsx 品牌 / 滚动信息 / 操作图标 + content/ 卡片、网格、详情、编辑器 + sidebar/ 资料卡、本地服务、导航 +stash-ui/src/components/ SearchField / Input / EngineIcon 等 ``` -## 3. 功能清单(已完成) +## 5. 数据库(v23) -### 登录 -- 单用户 `admin`,密码 argon2id; -- 会话:随机 32 字节 token,HttpOnly + SameSite=Strict + Path=/,7 天,库里存 sha256; -- 登录失败 5 次锁 60 秒;写接口校验 Origin;写接口需要会话。 +路径:`target/debug/data/stash.db`(`--data` 可覆盖)。 -### `/admin`(新原子模型) -| Tab | 能力 | -| --- | --- | -| 分组管理 | 树形表格:新建根分组(左侧)、加子分组、编辑(名称/上级/图标/排序/状态)、删除;格式已下沉到条目,不再在分组上设置 | -| 内容 | 选分组以列表展示条目(选主分组时包含所有子分组);列:标题 / 格式 / 跳转链接 / 所属分组 / 操作;每条内容单独选格式(应用/海报/图文),同一分组可混合 | -| 侧边栏 | 顶部「侧栏卡片」控制本地管理员 / 本地服务显隐;下方「分组导航」逐项勾选;开关即保存 | -| 首页卡片 | 左侧列表含「本地服务」只读表(不可删除,但可拖动排序)+ 自建卡片;右侧分组表格;表格内开关/条数即时保存,标题用「保存」按钮 | -| 页头 | 启用开关、速度、条目、标签与色调 | -| 资料 | 头像 URL、名称、角色、简介、位置 | -| 系统 | 修改密码、下载备份 | +- `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/`。 -保存:分组/内容/卡片逐项保存;侧边栏、页头、资料走 `PATCH /api/settings`(`version` 乐观锁)。 +## 6. settings JSON -### 内容编辑 -- 详情页 `[编辑]` 只在登录后显示; -- 打开右侧 Drawer:标题、简介、标签、一句话评价、正文 Markdown、封面、跳转地址; -- `PATCH /api/items/{key}`,`updatedAt` 乐观锁; -- 保存后 `catalog.reload()` 局部刷新,不整页刷新。 - -### 详情操作条 -- 浏览:进入页面 `POST /api/items/{key}/view`,数字 +1; -- 点赞:可切换,`POST /like`,localStorage 记住状态; -- 分享:复制当前链接,Toast 反馈; -- 跳转:保存时规范化 `href`(`www.` 自动补 `https://`,拒绝 `javascript:` 等协议);为空或 `#` 时按钮置灰。 - -## 4. HTTP API +`setting` 表 `key='site'`,API `GET/PATCH /api/settings`,`version` 乐观锁。当前字段: +```jsonc +{ + "header": { "enabled": true, "speed": 24, "gap": 26, "items": [...] }, + "sidebar": { "show_profile": true, "show_service": false, "show_nav": true }, + "background": { "light": "", "dark": "" }, // 空 = 内置背景 + "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 / 启停、恢复默认; + - 侧边栏:资料卡 / 本地服务 / 分组导航显隐; + - 内容卡片:卡片 + 勾选分组 + 预览条数 + 排序; +- **资料管理**:头像、名称、角色、简介、位置; +- **系统管理**:改密码、下载备份。 + +搜索框行为: + +- 顶部悬浮标签显示当前引擎图标 + 名称,点击展开下拉; +- 第一项固定「站内搜索」,分隔线后是启用的外部引擎; +- 站内模式:输入过滤本地内容;回车打开第一个匹配条目/分组; +- 外部模式:输入**不再过滤**本地内容;回车用该引擎 URL 新标签页搜索; +- 当前选择只存在当前页面会话,刷新后回到后台默认项。 + +主题: + +- 深色背景来自 Alright 演示站,资源 `site-bg-dark.jpg`; +- 明暗切换优先用 View Transition 整页快照交叉淡入(160ms),不支持时回退到 CSS 颜色过渡; +- 首帧由 `index.html` 内联脚本按 localStorage / 系统偏好先上色; +- 背景图两层(light/dark)交叉淡入。 + +## 8. HTTP API(当前保留) + +```text GET /api/health -GET /api/projects GET /api/projects/events (SSE) -GET /api/catalog2 分组树 + 卡片(新前台/后台) -GET /api/cards 卡片列表 -POST /api/nodes {key,title,parentKey?,icon?,sort?,enabled?} 需登录 -PATCH /api/nodes/{key} {title,parentKey?,sort?,icon?,enabled?} 需登录 -DELETE /api/nodes/{key} 需登录,级联 -POST /api/cards {title} 需登录 -PATCH /api/cards/{id} {title?,sort?} 需登录 -DELETE /api/cards/{id} 需登录 -PUT /api/cards/{id}/groups [{groupKey,previewLimit}] 需登录 - -GET /api/auth/session -> {authenticated, has_admin, username} -POST /api/auth/setup {password} 仅当无管理员 -POST /api/auth/login {password} -POST /api/auth/logout -PATCH /api/auth/password {current, next} - -GET /api/settings -> {version, settings} -PATCH /api/settings {version, settings} 需登录 - -GET /api/items/{key} -> 原始字段(编辑表单) -POST /api/items {key,nodeKey,item} 需登录 -PATCH /api/items/{key} {updatedAt, item, nodeKey?} 需登录,nodeKey 可移动条目 -DELETE /api/items/{key} 需登录 +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} +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 {liked} - -GET /api/backup SQLite 快照附件 需登录 +POST /api/items/{key}/like +GET /api/backup 需登录 +GET /api/auth/session +POST /api/auth/setup / login / logout +PATCH /api/auth/password ``` -## 5. 数据库与迁移 +已删除:`/api/catalog`、`/api/categories/*`、旧 `/api/groups/{id}`。 -- 文件:开发态在 `target/debug/data/stash.db`;可用 `--root` / 数据目录覆盖(见 `config.rs`)。 -- 当前 `PRAGMA user_version = 23`;`schema::migrate` 逐级升级:0 建全量、15→16→17→18→19→20→21→22→23、更高版本拒绝启动。 -- 格式在 `entry.format`(apps / posters / articles),同组可混合;`node` 不再保存格式。 -- v23 迁移删除 `section_block` 表与 `node` 的 `view_mode / empty_text / show_in_sidebar / allow_groups` 字段。 -- `settings.sidebar.show_profile / show_service` 控制侧栏两张卡片显隐(默认 true)。 -- 首页滚动:`#page-scroll`(Layout 的 body)是唯一滚动容器,搜索框固定在其上方;左右两栏顶部对齐,左侧到底后通过 `translateY` 吸底,右侧继续滚动;滚动条隐藏;页头实底,搜索框 50% 透明,顶部另有一层上下渐隐的软虚化(`blur(8px)`)。 -- 本地服务是运行时卡片,但 `card` 表里有一行 `local-service` 只用于排序;内容来自 `/api/projects`,后端禁止删除/改名/配置分组。 -- `node` 是统一分组树(根节点 `kind='section'`,子节点 `kind='group'` 可多层);`enabled` 控制启停;`icon` 可为空。 -- 主要表:`node`、`entry`、`entry_tag`、`card`、`card_group`、`admin`、`session`、`setting`、`audit`。 -- `entry.updated_at` 用于编辑乐观锁;`setting` 表 `key='site'` 存站点 JSON。 -- **设置/内容都是 SQLite**:备份用 `/api/backup`,恢复需停机替换文件。 +## 9. 组件库改动(stash-ui) -## 6. 认证运维 +- `SearchField` 新增可选 `suffix` 与 `leading` 插槽; +- `Input` 新增 `leading` ReactNode,优先于 `icon`; +- 新增 `EngineIcon`(`internal/google/bing/baidu/sogou/360`),图标路径来自参考稿;`18px` 默认、`14px` 用于顶部小标签; +- 构建产物已更新,`stash-web` 通过 file 依赖读取;改库后必须重建 dist,否则主项目构建仍用旧类型/资源。 -- 忘记密码:删除 `admin` 行(或整库)后重启 → 回到首次设置。 - ```powershell - node -e "const {DatabaseSync}=require('node:sqlite');const d=new DatabaseSync('target/debug/data/stash.db');d.exec('DELETE FROM admin; DELETE FROM session;')" - ``` -- 改密码:`/admin → 系统`,成功后该账号所有会话失效,需要重新登录。 -- 首个管理员由 `/api/auth/setup` 创建,密码至少 8 位。 +## 10. 已知限制 / 坑 -## 7. 组件库 `@stash/ui` - -- 42 个组件,文档站:`cd stash-ui && npm run dev`(也可 `npm run build:site` 后看 `dist-site`)。 -- 关键命令:`npm run typecheck && npm run lint && npm run build && npm run build:site`。 -- 组件契约:`docs/COMPONENTS.md`;设计规范:`DESIGN.md`;外部风格接入流程:`docs/STYLE-INTAKE.md`(闸门:截图 → 映射 → 决策 → 评审 → 再写代码)。 -- 主题:`themes/example.css` 只改变量;页面禁止写组件内部选择器。 -- **判断归属**:全局配置放 `/admin`;页面版式(间距、布局容器)写在页面 CSS;只有「第二个页面也复用」的才抽组件。 - -## 8. 验证与截图 - -- 后端逻辑:`cargo test`(48 passed,覆盖迁移/登录/设置/条目编辑/分区)。 -- 前端构建:`stash-web npm run build`(tsc -b + vite)。 -- 视觉/交互:Playwright 脚本在 `stash-ui/.ref/*.mjs`(不提交 git),截图在 `stash-ui/shots/`。 - - `measure-final.mjs` **已过时**(旧 1:1 对照用),选择器 `.app header` 仍可用; - - `c3-check.mjs`、`d-check.mjs`、`p2-check.mjs` 是后期功能检查脚本。 -- 常用冒烟:首页卡片、`/admin` 各 Tab、详情编辑、登录弹窗。 - -## 9. 已知限制 / 未做 - -| 项 | 状态 | +| 项 | 说明 | | --- | --- | -| 备份恢复/导入 | 只提供下载快照;恢复需停机替换 `stash.db` | -| 回收站/软删除 | 未做,删除分组会级联删子分组与条目(有二次确认) | -| 图片上传 | 只支持 URL;上传需存储目录、大小/类型校验 | -| 拖拽排序 | 分组/卡片顺序暂用创建顺序;上移下移/拖拽未做 | -| 多用户/角色 | 未做,当前单管理员 | -| 分组移动 | 编辑弹窗里可改「上级分组」(防环);根分组不能移到子级 | -| 条目移动 | 内容弹窗里可直接换分组(`PATCH /api/items/{key}` 的 `nodeKey`) | -| 分组排序 | 可编辑「排序权重」数值;拖拽排序未做 | -| 旧接口 | 已删除 `/api/catalog`、`/api/categories/*`、旧 `/api/groups/{id}`;当前只保留 `/api/catalog2` 与 `/api/nodes` | -| 登录限流 | 进程内计数,重启清空 | +| 推送 | 本地 `develop` 领先远端 20 个提交,尚未推送;Gitea HTTPS 凭据需准备 | +| 搜索引擎 | id 固定五个;新增需同时补 EngineIcon、后端校验、前端默认值、后台面板 | +| 搜索选择记忆 | 不持久化;刷新按后台 `search.default` | +| 图片上传 | 背景 / 头像 / 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 改中文源码 | -## 10. 约定与坑 +## 11. 最近提交(主项目,倒序) -- 回复用中文,表格化优先;视觉工作要截图验证。 -- **任何共享组件改动**都要在 `docs/COMPONENTS.md` 补契约 + changelog,并说明兼容性。 -- PowerShell 写文件注意 UTF-8;优先用编辑工具,别用 `Set-Content` 写带中文的源码。 -- 改前端后必须 `npm run build` 再 `cargo build`,否则内嵌资源是旧的。 -- 重启前先杀 `stash.exe`,否则 cargo 报「拒绝访问」。 -- `/login` 是旧地址,`main.tsx` 会重定向到 `/`;登录已改为弹窗。 -- 前端路由:`/`、`/g/<分组 key>`、`/g/<分组 key>/i/<条目>`;旧 `/c/...` 地址按第一个路径段当分组 key 兼容,`/admin` 独立壳。 +```text +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 同款深色背景 +``` -## 11. 新会话建议的下一步 +组件库最近: -1. 先跑 `cargo test` + 打开 8080 冒烟,确认基线; -2. 若要继续产品化:条目移动 UI、回收站、图片上传、拖拽排序; -3. 若要发布:确认 `stash-ui` 以 `file:` 引入的方式在发布构建里如何锁定版本(建议改为 git tag 依赖或构建前 `npm pack`)。 +```text +994436a feat(icons): 增加搜索引擎图标 +46829cd feat(input): 增加左侧 leading 插槽 +b97c77e feat(search): SearchField 增加 suffix 插槽 +``` + +## 12. 新会话建议顺序 + +1. 打开 与 `/admin` 冒烟;确认 8080 在跑(当前 PID 会变,不必依赖 PID)。 +2. 改前端:`cd stash-web && npm run build` → 杀 stash → `cargo build` → 启动。 +3. 改组件库:先 `cd stash-ui && npm run build`,再构建 `stash-web`,最后 Rust。 +4. 改设置结构:同时改 `src/db/settings.rs`、`stash-web/src/settings.ts`、后台面板和默认值;旧 JSON 由 serde 默认值兜底。 +5. 改数据库结构:升 `SCHEMA_VERSION` 并补迁移与迁移测试;先备份 `target/debug/data/stash.db`。 +6. 视觉改动用 Playwright 截图到 `stash-ui/shots/` 验证;脚本在 `stash-ui/.ref/`(不提交)。 +7. 收尾跑 `cargo test`(52 条)和 `npm run build`,确认工作区干净。