Files
QRGen/CLAUDE.md
T
Serendipity 15b3119588 docs: 更新 CLAUDE.md — web 端 + Docker + 修复说明
- workspace: core+cli+gui → core+cli+gui+web
- 新增 Web 服务构建/API 文档
- 新增 Docker 构建说明
- 测试数更新: 69 → 82
- 新增已知坑位 (PNG margin, finder separator, Tauri 导出)
- beforeBuildCommand 改为 npm run build
- 架构树增加 capabilities/ utils/ Dockerfile/ .dockerignore

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-19 15:22:58 +08:00

188 lines
8.2 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.
# CLAUDE.md
## 项目概述
QRGen — 从零手搓的 QR 码生成器,Rust workspace (core + cli + gui + web),完整实现 ISO/IEC 18004 国际标准。GUI + CLI + Web + Library 四种使用方式。
## 构建命令
```bash
# 安装前端依赖(首次或 package.json 变更后)
cd gui/src-frontend && pnpm install && cd ../..
# 全 workspace 编译检查
cargo check
# 全部测试
cargo test # 82 tests
# 仅核心库
cargo test -p qr-core
cargo build -p qr-core
# CLI 构建
cargo build --release -p qrgen
cargo run -p qrgen -- "Hello World"
# Web 服务
cargo run -p qrgen-web # → http://localhost:3000
# GUI 开发模式
cd gui/src-frontend && pnpm dev # 终端1: Vite 热更新
cargo run -p qrgen-gui # 终端2: Tauri 窗口
# GUI 前端类型检查
cd gui/src-frontend && pnpm tsc --noEmit
# GUI 前端构建
cd gui/src-frontend && pnpm build
# GUI 完整打包(生成 NSIS 安装包)
# beforeBuildCommand 用 npmTauri CWD 在 src-frontend/pnpm 不在 PATH
cd gui/src-frontend && pnpm build && cd ..
src-frontend/node_modules/.bin/tauri.cmd build
# Docker 构建(Web 服务)
docker build -t qrgen-web -f web/Dockerfile .
# Rust lint
cargo clippy -- -D warnings
```
## 架构
Cargo workspace 四层。
```
QRGen/
├── core/ # Rust 库 crate(零 Tauri 依赖)
│ └── src/
│ ├── qr.rs # 顶层 API — QrCode::encode()9 步流水线
│ ├── version.rs # 40 版本容量表 + 自动选择
│ ├── ecc/
│ │ ├── galois.rs # GF(2⁸) 运算 + exp/log 预计算表
│ │ └── reed_solomon.rs # RS 纠错码 + 数据交错
│ ├── encoder/
│ │ ├── mode.rs # 4 种编码模式 (数字/字母/字节/汉字 Shift JIS)
│ │ ├── segment.rs # 字符串分析 + 自动分段
│ │ └── bitstream.rs # 比特流拼接 + 终止符/填充
│ ├── matrix/
│ │ ├── grid.rs # 模块矩阵 (含 reserved 保留区)
│ │ ├── patterns.rs # 定位/对齐/时序图案 + BCH(15,5) + BCH(18,6)
│ │ │ # 含 finder separator 四边预留
│ │ ├── placement.rs # 蛇形数据排列
│ │ └── mask.rs # 8 种掩码 + 四规则惩罚评分
│ └── render/
│ ├── png.rs # PNG 输出 (image crate, 直接边界检测 margin)
│ ├── svg.rs # SVG 输出 (预分配容量)
│ └── ascii.rs # 终端 ASCII (██/ )
├── cli/ # CLI 命令行 (依赖 core + clap + anyhow)
│ └── src/main.rs # Args { content, -o, -l, -v, -s, -m, --invert }
│ # 含路径遍历防护(拒绝 .. 组件)
├── gui/ # Tauri 桌面应用 (依赖 core + tauri-plugin-*)
│ ├── capabilities/default.json # ACL 权限 (store/dialog/clipboard/fs)
│ ├── src/
│ │ ├── main.rs # Windows 子系统入口
│ │ └── lib.rs # 5 个 Tauri commands + AppState
│ ├── src-frontend/ # React 18 + TypeScript + TailwindCSS
│ │ └── src/
│ │ ├── App.tsx # 三栏 + 底部输入布局
│ │ ├── components/ # ModePanel / QrPreview / ExportPanel / HistoryList / ErrorBoundary
│ │ ├── modes/ # Text/Url/Wifi/VCard/Email/Phone/Sms
│ │ ├── hooks/ # useQrEncode (200ms 防抖, Store 缓存, WiFi 脱敏)
│ │ ├── store/ # QrProvider + useReducer
│ │ ├── types/ # ModeType / QrState / QrAction / HistoryEntry
│ │ └── utils/ # qrText.ts — 共享文本构造函数
│ ├── tauri.conf.json # 窗口 900×650 + CSP + NSIS 打包
│ └── WebView2Loader.dll # WebView2 运行时(打包用)
├── web/ # Web 服务 (依赖 core + axum + tokio)
│ ├── Dockerfile # rust-alpine 多阶段构建 → 17.7MB
│ ├── src/
│ │ ├── main.rs # axum: GET / + GET /api/qr?text=&level=&margin=&size=&fmt=
│ │ └── templates/
│ │ └── index.html # 内嵌 GUI 风格界面(三栏+7模式+实时预览)
├── .dockerignore # 排除 target/ gui/ test/
└── Cargo.toml # Workspace: core + cli + gui + web
```
## IPC 接口(Rust → GUI Frontend
| Command | 参数 | 返回值 | 功能 |
|---------|------|--------|------|
| `encode_qr` | `text: String, level: String, margin: u8` | `Result<QrResponse, String>` | 编码文本为 QR,返回 SVG + 版本/尺寸/掩码 |
| `export_png` | `text: String, level: String, margin: u8, module_size: u8` | `Result<Vec<u8>, String>` | 编码并导出 PNG 字节 |
| `save_history` | `entry: HistoryEntry` | `Result<(), String>` | 添加历史记录(最多 50 条) |
| `load_history` | — | `Result<Vec<HistoryEntry>, String>` | 加载全部历史记录 |
| `clear_history` | — | `Result<(), String>` | 清空历史记录 |
## Web API
| Endpoint | 参数 | 返回 |
|----------|------|------|
| `GET /` | — | HTML 页面(内嵌 7 种编码模式) |
| `GET /api/qr` | `text`, `level`(L/M/Q/H), `margin`(1-20), `size`(2-20), `fmt`(svg) | PNG 或 SVG |
## 前端状态管理
```
QrState {
mode → 当前编码模式 (text/url/wifi/vcard/email/phone/sms)
formData → 各模式表单数据 (Record<string, string>)
config → { level: L|M|Q|H, margin: 1-10, moduleSize: 2-20 }
preview → { svg, version, size, mask } | null
history → HistoryEntry[] (最多 50 条, FIFO, 含 formData 字段用于恢复)
loading → boolean
}
Action: SET_MODE | SET_FORM_DATA | SET_CONFIG | SET_PREVIEW | SET_LOADING
| SET_HISTORY | ADD_HISTORY | REMOVE_HISTORY | RESET
```
## 编码模式文本格式
| 模式 | QR 内容格式 |
|------|-----------|
| text | 原始文本 |
| url | 原始 URL(失焦自动补全 `https://` |
| wifi | `WIFI:T:<auth>;S:<ssid>;P:<pwd>;<H:true;>;` |
| vcard | `BEGIN:VCARD\nVERSION:3.0\nFN:...\nTEL:...\nEMAIL:...\nORG:...\nADR:...\nEND:VCARD` |
| email | `mailto:<addr>?subject=<s>&body=<b>` |
| phone | `tel:<number>` |
| sms | `smsto:<number>:<message>` |
## 关键约束
- **Rust 工具链**`stable-x86_64-pc-windows-gnu`MinGW-Builds GCC 15.2.0
- **MinGW 兼容**`.cargo/config.toml` 已添加 `-lmcfgthread` 链接标志
- **qr-core 纯算法**:除 `image` (PNG) 外无外部依赖,不依赖任何 QR 编码库
- **WebView2**Windows 10+ 自带,打包需 `WebView2Loader.dll`
- **GUI beforeBuildCommand**Tauri CWD 在 `gui/src-frontend/`,用 `npm run build`(非 pnpm
- **GUI 导出**:需 `tauri-plugin-fs` + `fs:allow-write-file` + `$HOME/**` scope
- **Docker 构建**`web/Dockerfile` 用 sed 移除 gui 成员避免拉 Tauri 依赖
## 已知坑位
- **PNG margin**:不能用 `saturating_sub` 检测 margin——它在 0 处回绕,导致 quiet zone 全黑
- **Finder separator**:必须预留四边隔离带(不只是右侧和底部),否则数据模块会破坏 finder 检测
- **Tauri 导出**`tauri-plugin-fs` 需同时在 Cargo.toml、lib.rs `.plugin()` 和 capabilities 三处注册
## 测试覆盖
| 层级 | 数量 | 说明 |
|------|------|------|
| 单元测试 | 58 | Galois 运算、RS 编码、模式编码、掩码评分、格式信息等 |
| 集成测试 | 24 | 端到端编码、渲染输出验证、边距、特殊字符、自动版本选择、格式信息 roundtrip |
| 总计 | 82 | `cargo test` 全部通过 |
## 版本号升级清单
| 文件 | 字段 | 说明 |
|------|------|------|
| `Cargo.toml` | `[workspace.package] version` | Rust 全量自动继承 |
| `gui/tauri.conf.json` | `version` | 打包版本号 |
| `gui/tauri.conf.json` | 窗口 `title` | 窗口标题栏 |
Release 操作:
- `git tag vX.Y.Z && git push --tags`
- `tea release create --login cloud --repo Serendipity/QRGen --tag vX.Y.Z`