Files

147 lines
8.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 本地归档接入(LOCAL ARCHIVE)
把 `E:\归档` 接进本界面:主阵列展示从归档中精选的四十条档案,**LOCAL ARCHIVE** 面板负责检索归档的全部条目并直接执行归档写操作。
## 两块数据的关系
| | 三维阵列 | 主检索的本地归档栏 + LOCAL ARCHIVE 面板 |
| --- | --- | --- |
| 数据 | `public/archive-index.json`(全量,运行时载入) | 同一份索引 |
| 内容 | 列 = 归档顶层内容分类,列内 = 该分类的**全部真实归档条目** | 全量条目(约 5 万条路径) |
| 用途 | 三维阵列、详情、解密动效、抽盘与拖拽 | 列表检索、打开、定位、归档操作 |
| 条数约束 | 无(随归档变化) | 无 |
| 降级 | 索引不可用时退回 `content/archives.json` 的四十条精选档案 | 退回静态快照,只读 |
**2026-09-12 起阵列已改为全量归档驱动**,因此归档里新增的文件会直接出现在阵列中(换到它所在的列即可)。三维阵列与检索列表共用同一份内存索引(`loadArchiveIndex`),不会重复下载。
四十条精选档案现在只作为降级数据集与 TXT 摘要来源,见 [`../content/README.md`](../content/README.md)。全量阵列的设计、性能与证据见 [`../verification/ARCHIVE-ARRAY.md`](../verification/ARCHIVE-ARRAY.md)。
## 启动
推荐一条命令同时拉起归档服务与开发服务器:
```bash
npm run dev:archive
```
也可以分开启动(两个终端):
```bash
npm run archive:serve # 归档服务,默认 127.0.0.1:43117
npm run dev # Vite 开发服务器
```
只跑 `npm run dev` 也能用:面板会退回**只读检索模式**,此时打开文件、定位与归档操作会被禁用并给出提示。
启动后点击顶部导航的 **LOCAL ARCHIVE**。
## 数据更新
服务启动时会扫描一次归档并在 `E:\归档` 上挂一个递归监视器。归档里新增或改动文件后,约 2.5 秒防抖,服务自动重新生成快照,并通过事件流通知已打开的页面重新载入索引——不需要手动刷新。
也可以点面板状态栏的**重新扫描 ↻**,或调用 `POST /archive-api/refresh`。
`npm run dev` / `npm run build` 的钩子也会各生成一次快照。
## 详情页的「文件位置」按钮
详情页右下角的 **SHOW IN FOLDER / 文件位置** 按钮(原先是 EXPORT 下载 TXT)会直接在资源管理器中定位当前档案在 `E:\归档` 中的位置,用的是该条精选档案在 `content/archives.json` 里的真实 `path`,通过本地归档服务的 `POST /reveal` 完成。
- 服务未运行时按钮会提示"需要本地归档服务:请运行 `npm run dev:archive`",不会静默失败。
- 详情页脚注显示的是归档内的相对路径文本。浏览器不允许网页跳转 `file:` 链接,所以它不再是可点击链接。
- `public/archives/*.txt` 仍会为每条档案生成,但详情页不再提供下载入口。
## 面板能做什么
**检索**:输入任意片段,匹配相对路径(含文件名与扩展名)。命中数实时显示,单次最多渲染 200 行,匹配片段高亮。索引在第一次打开面板时载入一次,之后在内存中过滤,不再走网络。
**每行的三个动作**:
| 按钮 | 行为 | 是否需要服务 |
| --- | --- | --- |
| 打开 | 用系统默认程序打开文件;目录则用资源管理器打开 | 是 |
| 定位 | 在资源管理器中选中该条目 | 是 |
| 归档… | 选中该条目作为源,在右侧进入归档操作 | 是 |
**归档操作(四种,均为安全写)**:
| 操作 | 说明 |
| --- | --- |
| 移动到 | 归档内移动,同盘重命名。**跨盘拒绝**,请改用复制 |
| 复制到 | 递归复制 |
| 解压到 | 调用 `C:\Program Files\7-Zip\7z.exe` 解压到目标目录 |
| 新建分类目录 | 在归档内新建目录 |
一律**先点「预览影响」**:显示源、目标、体积、文件数、是否跨盘,并给出能不能执行的结论。`预览`不通过时执行按钮保持禁用。执行结果用界面右下角的提示条反馈,并追加到操作日志。
**不提供删除与重命名**:这两项不可逆,需要时请在资源管理器中手动完成。
## 安全设计
- **只监听回环**:服务绑定 `127.0.0.1`,不对外网开放。
- **每次启动的访问令牌**:服务启动时生成随机令牌写入项目根目录的 `.archive-token`(已加入 `.gitignore`)。浏览器**不持有**令牌——Vite 在 `/archive-api` 代理层注入它。因此即使别的网页知道端口号,也无法调用本服务。
- **路径围栏**:客户端只传相对路径,服务解析为绝对路径后必须仍落在归档根目录内;越界、绝对路径与 `..` 一律 `403`。符号链接不算越界,但不会被跟随。
- **操作日志**:每次写操作追加一行 JSON 到 `E:\归档\00_索引\操作日志.jsonl`,含时间、操作、源、目标。
- **写操作需要显式确认**:`/apply` 必须带 `confirm: true`,否则 `400`。服务端会**重新计算**一次影响预览,不信任客户端传来的结论。
## 配置
[`archive.config.json`](../archive.config.json):
```json
{
"root": "E:\\归档",
"port": 43117,
"exclude": [],
"indexFile": "public/archive-index.json",
"logFile": "00_索引\\操作日志.jsonl"
}
```
`exclude` 里的目录会被索引跳过(其本身仍作为目录条目保留)。改 `port` 时不需要同步改前端:Vite 代理会在配置加载时读取同一个文件。
## 接口
所有接口都需要 `x-archive-token` 头,经 Vite 代理访问时自动注入。在浏览器或 curl 里直接调用时前缀为 `/archive-api`,直连服务时无前缀。
| 方法与路径 | 用途 |
| --- | --- |
| `GET /status` | 根目录、端口、监视状态、最近一次快照时间、总量 |
| `GET /index` | 全量索引(支持 gzip,约 0.7 MB) |
| `GET /search?q=&limit=` | 服务端检索 |
| `POST /plan` | 影响预览,不修改任何文件 |
| `POST /apply` | 执行写操作,需要 `confirm: true` |
| `POST /open` / `POST /reveal` | 打开文件 / 在资源管理器中定位 |
| `POST /refresh` | 立即重新扫描归档 |
| `GET /events` | 快照更新事件流(SSE) |
## 快照文件
| 文件 | 体积 | 说明 |
| --- | ---: | --- |
| `content/archives.json` | 约 45 KB | 四十条精选档案,页面与 TXT 下载共用 |
| `public/archive-index.json` | 约 7.4 MB | 全量索引,紧凑数组 `[路径, 类型, 字节, mtime]` |
| `public/archives/*.txt` | 40 个 | 每条档案的可下载摘要 |
`archive-index.json` **不进入 PWA 离线预缓存**(`scripts/build-pwa.mjs` 的白名单不含根目录文件),因此离线包体积不受影响;代价是离线状态下打开检索面板只有空态。服务在线时索引走 gzip(约 0.7 MB),比静态快照快得多。
## 构建与部署
生产构建不包含归档服务,也不带 `/archive-api` 代理,线上站点打开面板会显示"只读检索模式",检索走静态 `archive-index.json`,写操作不可用——这是刻意的:本地归档服务不应暴露在公网。
`npm run preview` 同样配置了代理,因此本地预览可以完整体验。
## 故障排查
| 现象 | 处理 |
| --- | --- |
| 面板显示"服务未运行" | 先 `npm run archive:serve`;确认端口 43117 未被占用 |
| 打开/定位提示需要服务 | 同上;这是刻意的降级,检索仍可用 |
| 令牌无效(401) | 服务重启会换新令牌;重启 Vite 让代理读到新值,或直接用 `npm run dev:archive` |
| 「7-Zip 解压失败」 | 确认 `C:\Program Files\7-Zip\7z.exe` 存在;面板 `/status` 的 `sevenZip` 字段会说明 |
| 新增文件没有出现在检索里 | ① 等约 3 秒(防抖),或点「重新扫描 ↻」② 查 `/status` 的 `lastError` 与 `lastScan` ③ 手动 `npm run archive:snapshot`。索引与检索本身极少出错,**先查服务和快照时间,再怀疑代码**。 |
| 面板开了很久、刚加的文件搜不到 | 面板**每次打开都会重新取索引**(服务在线时),关闭面板不再退掉事件订阅;若仍不对,`Ctrl+F5` 整页刷新一次。 |
| 摘要里的数字和归档对不上 | 重新生成快照;`{size}`/`{files}`/`{date}` 只在生成时采样 |