Files
WebTools/README.zh-CN.md
T

344 lines
15 KiB
Markdown
Raw 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.
# Web Tools
一个匿名访问、自托管的浏览器本地工具箱。支持多人同时使用;除全局导航顺序外,文本、密钥、文件、图片和计算结果均只存在于各自浏览器中,不会发送到服务端。
当前应用版本:`0.0.5`。
## 内置工具
- ASCII/UTF-8 与 Hex 互转
- Base64 与 Base64 URL 编码、解码,解码结果支持 UTF-8、连续 Hex 和代码字节数组
- AES-128-CMAC(RFC 4493)
- CRC-8/16/32/64 预设与自定义参数,支持 BIN 和多 block Intel HEX
- RSA 2048/3072/4096 位密钥对,导出 PEM,以及可分别复制的 N/E Hex 或代码字节数组
- 密码学安全随机数,支持连续 Hex、空格 Hex 和代码字节数组
- JSON 格式化、压缩、校验和语法着色
- XML 格式化、压缩、校验和语法着色
- PNG 转多尺寸 ICO
## 交付物与源码
容器交付 ZIP 同时包含源码、测试、生产构建结果和部署文件,不是只有压缩后的网页。主要目录如下:
```text
src/ Vue 3 前端源码
components/ 所有工具共用的 UI 组件
lib/ 可测试的纯计算与浏览器辅助逻辑
tools/ 每个工具一个独立 Vue 组件
workers/ 大文件计算使用的浏览器后台线程
views/SettingView.vue /setting 工具管理页
server/ 零依赖 Node.js 静态服务和导航配置 API
shared/tool-catalog.json 工具与分类的权威元数据目录
shared/default-navigation.json 新部署的默认分类和工具顺序
tests/ Vitest 单元测试
dist/ npm run build 生成的生产前端
Dockerfile 多阶段容器构建
docker-compose.yml 默认部署配置
THIRD_PARTY_NOTICES.md 第三方依赖许可说明
CHANGELOG.md 版本变更、修复和验证记录
```
交付包不包含 `node_modules`。Docker 首次构建需要访问 Node 镜像仓库和 npm 软件源;若环境完全离线,应另外交付 Docker 镜像 tar。
## 架构约束
- Vue 3、TypeScript、Vite 前端;Node.js 标准库服务端;不引入数据库。
- 工具组件彼此独立并懒加载,公共交互使用 `ToolPage`、`ModeTabs`、`TextEditor` 和 `src/styles.css` 中的现有样式。
- 工具的计算、解析和文件生成逻辑放在 `src/lib/`,Vue 组件只负责状态与交互。
- 大文件或长时间计算必须放入 `src/workers/` 的 Web Worker,避免阻塞页面交互;Worker 仍只在浏览器本地处理数据。
- 路由和左侧导航由工具目录自动生成,增加普通工具时不得手工新增路由。
- 工具输入只在浏览器内存中处理,不得发送给服务端、遥测服务或第三方接口。
- 服务端只持久化导航顺序,文件为 `/data/navigation.json`,写入采用临时文件和原子替换。
- `/setting` 是固定但不公开显示的管理入口;项目没有登录、收藏、赞助或用户系统。
- 页面必须保持统一 UI,并兼容桌面端和移动端竖屏。
## 多人使用与状态边界
- 每个浏览器标签页拥有独立的 Vue 组件状态、文件对象、图像对象和 Web Worker。不同用户、浏览器或标签页不会共享工具输入与结果。
- CRC、RSA、AES-CMAC、随机数、PNG/ICO、编码转换和格式化都在浏览器中执行;服务端没有工具计算接口。
- `/setting` 保存的是所有访问者共享的导航配置。并发保存没有版本冲突合并,最后完成原子替换的请求生效。
- 原子替换保证读取者看到完整的旧配置或新配置,不会看到写到一半的 JSON;它不保证保留多个用户各自的排序修改。
- 已打开的页面不会实时接收其他用户保存的新顺序,刷新或重新打开后才会读取。
- 深浅主题保存在当前浏览器同源 `localStorage` 中;系统剪贴板由操作系统管理。这两项不会改变工具计算结果。
## 资源限制
限制用于避免异常文件、解压后超大图像或高密度语法 token 长时间占用浏览器。修改这些数值时必须同步源码常量、测试和本文档。
| 功能 | 当前限制 | 超限行为 |
| --- | --- | --- |
| CRC 固件文件 | 最大 64 MiB | 选择时拒绝,不保留旧文件结果 |
| Intel HEX 数据记录 | 最多 500,000 条 | Worker 停止解析并显示错误 |
| Intel HEX 数据块 | 最多 1,024 个 block | Worker 停止解析并显示错误 |
| PNG 压缩文件 | 最大 32 MiB | 创建预览前拒绝 |
| PNG 尺寸 | 单边最大 16,384 像素,总计最大 32,000,000 像素 | 浏览器解码前拒绝 |
| 安全随机数 | 每次 1 至 65,536 字节 | 拒绝无效长度 |
| JSON/XML 语法着色 | 最大 100,000 字符且不超过 10,000 个 token | 结果仍完整显示,但降级为纯文本以减少 DOM 节点 |
| 导航配置请求体 | 最大 64 KiB | 服务端返回 400 |
## Docker Compose 部署
要求 Linux AMD64/ARM64、Docker Engine 24+、Docker Compose v2。
```bash
docker compose up -d --build
```
默认访问地址:`http://服务器地址:8080`
自定义端口:
```bash
WEB_TOOLS_PORT=9000 docker compose up -d --build
```
检查状态:
```bash
docker compose ps
docker compose logs --tail=100 web-tools
```
停止服务:
```bash
docker compose down
```
导航配置保存在 Docker 卷 `web-tools-data` 中的 `/data/navigation.json`。全新部署且从未保存过排序时,应用直接使用内置默认配置,该文件可能尚不存在;首次保存后会创建。删除或重建容器不会丢失已有配置,执行 `docker compose down -v` 才会删除该卷。
健康检查地址:`http://服务器地址:8080/healthz`
## Windows Server 部署(不使用 Docker)
要求安装 Git、Node.js 22.12.0 或更高版本,并使用 PowerShell 5.1 或更高版本。以下示例假设项目位于 `C:\Services\WebTools`。
首次克隆后安装依赖并构建:
```powershell
Set-Location C:\Services\WebTools
npm.cmd ci --include=dev
npm.cmd run build
```
生产构建成功后,使用项目根目录的统一脚本启动:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\web-tools.ps1 start
```
默认监听 `0.0.0.0:9000`,导航配置保存在 `C:\ProgramData\WebTools\data\navigation.json`。可以通过参数覆盖:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\web-tools.ps1 start `
-ListenAddress 127.0.0.1 `
-Port 8080 `
-DataDir C:\ProgramData\WebTools\data
```
从 Git `main` 分支更新时,先在运行窗口按 `Ctrl+C` 停止服务,再执行:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\web-tools.ps1 update
```
更新脚本只接受干净的 Git 工作区和当前 `main` 分支,使用 `git pull --ff-only origin main` 避免隐式合并。随后执行 `npm ci --include=dev`、生产构建并自动重新启动服务。`npm ci` 会先删除现有 `node_modules` 再按 `package-lock.json` 完整重建,不需要手工删除旧依赖。只更新和构建、不立即启动时增加 `-NoStart`。
脚本不会读取、覆盖或删除 `C:\ProgramData\WebTools\data`。PowerShell 窗口关闭后前台服务会停止;如使用 Windows 计划任务,应让任务执行 `web-tools.ps1 start`,更新时停止任务、运行 `web-tools.ps1 update -NoStart`,然后重新启动任务。
## 工具管理
管理入口不显示在页面中,直接访问:
```text
http://服务器地址:8080/setting
```
可以调整分类顺序、分类内工具顺序及工具所属分类。保存时采用同目录临时文件和原子替换。
导出配置(至少保存过一次排序后执行):
```bash
docker compose cp web-tools:/data/navigation.json ./navigation.json
```
导入配置:
```bash
docker compose cp ./navigation.json web-tools:/data/navigation.json
docker compose restart web-tools
```
升级应用前建议导出该文件。新版本增加工具时,服务端会保留已有顺序,并把缺少的新工具追加到其默认分类。
## 离线镜像
若交付目录包含 `personal-web-tools-0.0.5-amd64.tar`,可直接导入:
```bash
docker load -i personal-web-tools-0.0.5-amd64.tar
docker compose up -d --no-build
```
当前源码 ZIP 本身不是 Docker 镜像 tar。
## 本地开发
要求 Node.js 22.12.0 或更高版本。首次安装使用锁定依赖:
```bash
npm ci
```
终端一运行配置服务:
```bash
PORT=8081 DATA_DIR=./data node server/index.mjs
```
终端二运行 Vite;`/api` 和 `/healthz` 会代理到 `127.0.0.1:8081`:
```bash
npm run dev
```
生产模式本地运行:
```bash
npm run build
npm start
```
生产服务默认监听 `0.0.0.0:8080`。
完整工程检查:
```bash
npm run check
npm audit --audit-level=low
```
`npm run check` 会依次运行全部 Vitest 测试、TypeScript/Vue 类型检查和生产构建。服务端测试使用随机本地端口验证 SPA 直达路由、静态资源 404、导航 API、请求大小限制及跨站写入拦截。
自动化测试还覆盖标准算法向量、Base64 规范性、Intel HEX 记录与 block 边界、PNG 头部与像素限制、导航排序纯函数、目录/图标/懒加载组件一致性,以及原子写入失败后的临时文件清理。
## 增加工具
### 1. 先定义稳定标识
为工具选择永久的 kebab-case `id`,例如 `url-encode`。已发布工具的 `id` 不应修改,因为路由、懒加载映射和用户保存的导航配置都依赖它。
确定工具所属分类。新增分类时,需要同时更新:
- `shared/tool-catalog.json` 中的 `categories`
- `shared/default-navigation.json` 中的 `categories`
仅新增工具时,分类配置版本仍保持 `version: 1`,不要因为工具数量变化而升级配置格式版本。
### 2. 编写独立计算逻辑
将编码、解析、加密、校验或文件生成逻辑放入 `src/lib/`。优先使用浏览器标准 API或经过验证的现有依赖,不在 Vue 组件中堆积算法实现。
在 `tests/` 添加正常输入、边界输入、无效输入和已知测试向量。涉及字节的工具必须明确 UTF-8、Hex、Base64、换行及分隔符语义,避免隐式改变数据。
文件或高开销工具还必须定义文件大小、记录数量、图像尺寸或输出 DOM 数量等资源上限。异步工具在清空、更换输入或卸载后必须忽略旧任务结果;计算量较大的文件解析与 CRC 计算放入 Web Worker。
### 3. 编写统一的工具页面
在 `src/tools/` 新增一个 Vue 组件,并参考现有 `Base64Tool.vue` 或与需求最接近的工具。
- 页面外层使用 `ToolPage`。
- 文本输入输出优先使用 `TextEditor`。
- 模式切换使用 `ModeTabs`。
- 操作按钮使用 Lucide 图标和现有 `action-button` 类。
- 必须提供清空、错误提示和必要的复制/粘贴操作。
- 不增加登录、收藏、赞助、遥测、外部网络请求或独立视觉风格。
- 在窄屏下确认控件不溢出、不重叠,文字不会遮挡。
### 4. 登记工具元数据
在 `shared/tool-catalog.json` 的 `tools` 中增加:
```json
{
"id": "url-encode",
"title": "URL 编解码",
"category": "encoding",
"description": "编码和解码 URL 组件。",
"icon": "Link"
}
```
`id` 必须唯一,`category` 必须存在。`icon` 使用 Lucide Vue 图标名称。
在 `shared/default-navigation.json` 的目标分类工具数组中加入相同 `id`,位置即新部署的默认显示顺序。
### 5. 注册图标与懒加载组件
在 `src/tools/registry.ts` 中完成三件事:
1. 从 `@lucide/vue` 导入目录中填写的图标。
2. 把图标加入 `iconComponents`。
3. 把工具 `id` 和 `defineAsyncComponent(() => import(...))` 加入 `toolComponents`。
工具目录、默认导航和注册表中的 `id` 必须完全一致。路由会从注册表自动生成,不需要修改 `src/router.ts`。
现有自动化测试会校验目录分类、工具 ID、图标注册和懒加载组件映射。新增工具后若漏改任一处,`npm test` 或应用启动会直接报错。
### 6. 验证兼容性
```bash
npm run check
npm audit --audit-level=low
```
还应在真实浏览器中检查:
- 新工具的默认路径 `/tools/<id>` 可以直接打开和刷新。
- 左侧导航、搜索和 `/setting` 正常显示新工具。
- 已保存的旧 `navigation.json` 启动后会自动补入新工具。
- 桌面端和约 `390 x 844` 的移动端竖屏布局正常。
- 浏览器控制台无错误,工具内容没有发往服务端。
## AI 接手清单
后续由 AI 增加或修改工具时,应先阅读本文件,然后依次检查:
1. `shared/tool-catalog.json` 和 `shared/default-navigation.json`
2. `src/tools/registry.ts`
3. 与目标功能最接近的 `src/tools/*.vue`
4. `src/components/ToolPage.vue`、`TextEditor.vue`、`ModeTabs.vue`
5. 相关 `src/lib/` 和 `tests/`
6. `server/navigation.mjs` 中的导航兼容逻辑
AI 不应仅修改 `dist/`;必须修改源码并重新构建。不得覆盖或删除用户的 `data/navigation.json`。发现工作区已有未说明的改动时应保留并兼容,不得擅自回退。
处理多人访问、文件工具或异步计算时,还必须检查本文档中的“多人使用与状态边界”和“资源限制”,避免重新引入共享状态、旧任务覆盖新输入或无上限解析。
完成任务后至少报告:修改的工具、数据格式选择、测试和构建结果、容器包路径及 SHA-256。涉及 UI 的改动还要进行桌面和移动端浏览器验收。
## 版本与发布
应用版本的权威来源是 `package.json`。发布新版本时:
1. 使用 `npm version patch --no-git-tag-version` 或按兼容性选择 minor/major,使 `package.json` 与 `package-lock.json` 同步。
2. 更新 `docker-compose.yml` 中的镜像标签。
3. 更新本文档中的当前版本和离线镜像文件名。
4. 在 `CHANGELOG.md` 记录用户可见变更、重要修复和验证结果。
5. 运行测试、生产构建和依赖审计。
6. 重新制作源码/容器部署 ZIP,并生成 SHA-256。
版本号固定显示在左侧导航底部;版权信息 `Copyright © mid All Rights Reserved.` 固定显示在所有页面底部。第三方许可保留在 `THIRD_PARTY_NOTICES.md`。
## 安全边界
- 无登录、无统计、无遥测、无 CDN 和第三方网络请求。
- `/setting` 是固定但不显示的入口,不构成身份认证;直接公开到互联网时任何访问者都可能修改排序。
- 工具内容仅在浏览器内存中处理,默认不会持久化。
- 容器以非 root 用户运行,根文件系统只读,全部 Linux capabilities 已移除。
- 服务端只接受不超过 64 KiB 的导航 JSON 配置。
- 服务端只提供静态文件、`GET/PUT /api/navigation` 和 `GET /healthz`。
- 只有无扩展名且明确请求 HTML 的前端路由会回退到 `index.html`;缺失的 JS、CSS 和其他资源返回 404。
- JSON API 响应使用 `Cache-Control: no-store`,避免浏览器缓存导航和健康状态。
- 安全响应头禁止第三方脚本、跨站嵌入、摄像头、麦克风和定位权限。