# 网盘 (共享目录浏览 + 选择下载) 局域网里两台 LocalNetMsg 互传文件, 以前只能"发消息带附件" (点对点传单个文件)。 网盘功能让对方能**浏览我机器上指定的共享目录**, 挑需要的文件下载。 ## 1. 组成 ``` 被控端 (文件持有方) 控制端 (浏览/下载方) ┌────────────────────────────┐ ┌──────────────────────────────┐ │ FileServer (0.0.0.0:47901) │ │ 聊天框 → "网盘" tab │ │ GET /drive/meta │◀── HTTP ──│ DrivePanel.vue │ │ GET /drive/list │ │ 目录浏览 / 多选 / 下载 │ │ GET /drive/download │ │ ↓ ipc │ │ ↑ 只能访问 driveDir 内的 │ │ drive.ts (客户端) │ │ 文件, 且要带对 token │ │ listDrive / downloadDrive… │ └────────────────────────────┘ └──────────────────────────────┘ ``` - **文件服务器启动即开启**: `FileServer` 本来就在应用启动时跑起来了 (端口 47901), 网盘只是给它加了 3 个 `/drive/*` 路由, 不需要额外进程。 - **共享目录**: 设置 → 网盘 → 共享目录, 默认 `~/Documents/LocalNetMsg/网盘`。 对端**只能看到这个目录里的内容**, 子目录也跳不出去。 - **访问令牌**: 每台机器一个长期 token (`userData/data/drive.token`), 随局域网发现包广播, 对端拿它调 `/drive/*`。关掉"启用网盘"开关或 token 不符都会 403。 ## 2. 协议 | 接口 | 说明 | |---|---| | `GET /drive/meta?token=` | 取网盘根目录 (仅提示用) | | `GET /drive/list?token=&path=` | 列目录, `path` 是相对网盘根的路径 (`''` = 根) | | `GET /drive/download?token=&path=` | 下载文件 (流式, `Content-Disposition: attachment`) | 返回的条目: ```ts interface DriveEntry { name: string // 文件名 path: string // 相对网盘根的路径 (下载时用它) size: number mtime: number isDir: boolean } ``` ## 3. 安全 | 风险 | 处理 | |---|---| | 越权读任意文件 | 路径必须落在 `driveDir` 内 (resolve 后前缀校验), `..` 一律拒绝 | | 局域网陌生人访问 | 每次请求校验 token; 开关关掉直接 404 | | 对方版本太老 | 老版本没有 token 字段 → 控制端显示"对方版本暂不支持网盘" | 自测覆盖: `npm run selftest -- drive` (D1–D7), 包含目录穿越和错误 token 的用例。 ## 4. 用法 1. 把要共享的文件丢进网盘目录 (设置里可以改位置, 面板里有"打开文件夹") 2. 在聊天框切到 **网盘** tab → 看到对方网盘的文件列表 3. 点目录进去, 勾选文件 → **下载选中** 4. 文件落到本机接收目录 (设置 → 接收目录), 面板里能看到逐个进度 **目录也支持**: - 点目录名可以进去, "上一级"回退, 面包屑显示当前位置 - 目录行也能打勾 → **整个目录递归下载**, 本地保持原有层级 (下载 `产品文档/` → 本机得到 `产品文档/需求说明.md`、`产品文档/原型图/xx.png`) - 递归深度上限 12 层, 防止异常目录结构把进程拖死 对方从我的网盘下载文件时, 本机会弹一条提示, 并记进审计日志 (`drive.download`)。