feat: CutThenThink v3.0 初始版本
完整实现 Tauri + Vanilla JS 轻量级截图工具 Phase 1 - 项目搭建 - Tauri 2.x 项目初始化 - Vite 前端项目搭建 - 基础 UI 框架(CSS 变量、组件库) - 构建配置优化 Phase 2 - 核心截图功能 - 全屏/区域/窗口截图 - 截图预览和管理 - 文件命名和缩略图 - 全局快捷键集成 Phase 3 - 上传与存储 - 多图床上传(GitHub/Imgur/自定义) - 配置管理系统 - SQLite 数据库 Phase 4 - OCR 集成 - 云端 OCR(百度/腾讯云) - 插件管理系统 - 本地 OCR 插件(Go) - OCR 结果处理 Phase 5 - AI 分类系统 - Claude/OpenAI API 集成 - Prompt 模板引擎 - 模板管理界面 - 自动分类流程 Phase 6 - 历史记录与管理 - 图库视图(网格/列表) - 搜索与筛选 - 批量操作 - 导出功能(JSON/CSV/ZIP) Phase 7 - 打包与发布 - 多平台构建配置 - CI/CD 工作流 - 图标和资源 - 安装包配置 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
523
lightweight-redesign.md
Normal file
523
lightweight-redesign.md
Normal file
@@ -0,0 +1,523 @@
|
||||
# CutThenThink v3.0 - 轻量级语言重构设计
|
||||
|
||||
## 项目背景
|
||||
|
||||
当前 Python + PyQt6 方案存在的问题:
|
||||
- 打包体积大(~214MB)
|
||||
- 启动速度慢
|
||||
- 依赖 PyQt6 大型框架
|
||||
- 用户需要安装 Python 环境
|
||||
|
||||
## 新技术栈选择
|
||||
|
||||
### 方案对比
|
||||
|
||||
| 方案 | 语言 | 框架 | 包体积 | 跨平台 | 开发效率 | 热更新 |
|
||||
|------|------|--------|--------|---------|---------|---------|
|
||||
| **Tauri** | Rust + Web 前端 | 系统WebView | ~5-10MB | ✅ | ⭐⭐⭐ | 快 |
|
||||
| **Electron** | Node.js + Web 前端 | Chromium 内嵌 | ~100-150MB | ✅ | ⭐⭐ | 快 |
|
||||
| **Flutter** | Dart + Skia 引擎 | 自绘引擎 | ~20MB | ✅ | ⭐ | 中等 |
|
||||
| **Go + Fyne** | Go + 自绘引擎 | 轻量 OpenGL | ~10-15MB | ✅ | ⭐ | 快 |
|
||||
|
||||
### 推荐方案:Tauri
|
||||
|
||||
**理由:**
|
||||
1. **极小体积**:5-10MB 完整应用
|
||||
2. **原生性能**:Rust 后端,前端任选(HTML/React/Vue/Svelte)
|
||||
3. **现代体验**:支持热更新
|
||||
4. **活跃生态**:Tauri 1.0 已非常成熟
|
||||
|
||||
---
|
||||
|
||||
## 架构设计
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ CutThenThink v3.0 │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ Rust Core (tauri backend) │ │
|
||||
│ ├─────────────────────────────────────────────────┤ │
|
||||
│ │ │ │
|
||||
│ │ ┌────────────────────────────────────────────┐ │ │
|
||||
│ │ │ Web Frontend (任选) │ │ │
|
||||
│ │ │ - HTML/CSS/JS │ │ │
|
||||
│ │ │ - React/Vue/Svelte │ │ │
|
||||
│ │ │ - TailwindCSS │ │ │
|
||||
│ │ └────────────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ ┌──────────────────────────────────────────┐ │ │
|
||||
│ │ │ System Integration (平台API) │ │
|
||||
│ │ │ - 截图 API │ │
|
||||
│ │ │ - 文件系统 │ │
|
||||
│ │ │ - 剪贴板 │ │
|
||||
│ │ │ - 全局快捷键 │ │
|
||||
│ │ │ - 通知 │ │
|
||||
│ │ └────────────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ ┌──────────────────────────────────────────┐ │ │
|
||||
│ │ │ External Services (可选) │ │
|
||||
│ │ │ - RapidOCR (本地) │ │
|
||||
│ │ │ - 云端 OCR API │ │
|
||||
│ │ │ - 云存储 (S3/OSS/WebDAV) │ │
|
||||
│ │ │ - AI 分类 API (可选) │ │
|
||||
│ │ └────────────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────────────────┘ │ │
|
||||
│ │ │
|
||||
└─────────────────────────────────────────────────────────┘ │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
cutthenthink-v3/
|
||||
├── src-tauri/ # Rust 后端 (Tauri CLI)
|
||||
│ ├── src/
|
||||
│ │ ├── main.rs # Rust 入口
|
||||
│ │ ├── lib.rs # 核心库
|
||||
│ │ ├── commands.rs # 命令处理
|
||||
│ │ ├── screenshot.rs # 截图模块
|
||||
│ │ ├── upload.rs # 上传模块
|
||||
│ │ ├── database.rs # 数据库 (SQLite)
|
||||
│ │ └── ocr.rs # OCR 接口
|
||||
│ ├── Cargo.toml # Rust 项目配置
|
||||
│ ├── tauri.conf.json # Tauri 配置
|
||||
│ └── build.rs # 构建脚本
|
||||
│
|
||||
├── src-ui/ # Web 前端
|
||||
│ ├── index.html # 入口 HTML
|
||||
│ ├── src/
|
||||
│ │ ├── main.js # 主 JS
|
||||
│ │ ├── styles.css # 样式
|
||||
│ │ ├── components/ # UI 组件
|
||||
│ │ │ ├── screenshot.html
|
||||
│ │ │ ├── upload.html
|
||||
│ │ │ ├── browse.html
|
||||
│ │ │ └── settings.html
|
||||
│ │ ├── api/
|
||||
│ │ │ ├── commands.js # Tauri API 调用
|
||||
│ │ │ ├── database.js # 数据库操作
|
||||
│ │ │ ├── screenshot.js # 截图功能
|
||||
│ │ │ └── upload.js # 上传功能
|
||||
│ └── assets/ # 静态资源
|
||||
│ ├── icons/
|
||||
│ └── screenshots/
|
||||
│
|
||||
├── src-ocr-plugin/ # 可选的本地 OCR 插件 (Go)
|
||||
│ ├── main.go
|
||||
│ ├── ocr.go
|
||||
│ └── models/ # OCR 模型文件
|
||||
│
|
||||
└── docs/
|
||||
├── architecture.md # 本文档
|
||||
├── api.md # API 文档
|
||||
└── development.md # 开发指南
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 核心功能模块
|
||||
|
||||
### 1. 截图模块 (screenshot.rs)
|
||||
|
||||
```rust
|
||||
use tauri::command::screenshot::ScreenshotConfig;
|
||||
|
||||
/// 截全屏
|
||||
#[tauri::command]
|
||||
pub fn capture_fullscreen() -> Result<String, String> {
|
||||
let screen = Window::current_monitor()?.ok_or("无法获取屏幕")?;
|
||||
|
||||
// 调用平台截图 API
|
||||
match screen {
|
||||
Screen::CaptureFullscreen(path) => Ok(path.to_string_lossy()),
|
||||
_ => Err("未实现".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
/// 区域截图
|
||||
#[tauri::command]
|
||||
pub fn capture_region() -> Result<String, String> {
|
||||
// 显示区域选择器
|
||||
// 使用 Tauri 对话框 API
|
||||
Ok("region_capture".to_string())
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 上传模块 (upload.rs)
|
||||
|
||||
```rust
|
||||
use reqwest::blocking::Client;
|
||||
use serde_json::json;
|
||||
|
||||
/// 上传文件
|
||||
pub struct UploadConfig {
|
||||
pub provider: String,
|
||||
pub endpoint: String,
|
||||
pub api_key: Option<String>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn upload_file(filepath: String) -> Result<String, String> {
|
||||
let config = get_upload_config()?;
|
||||
|
||||
let client = Client::new();
|
||||
let form = multipart::Form::new()
|
||||
.text("file", filepath_to_name(&filepath)?)
|
||||
.text("provider", &config.provider);
|
||||
|
||||
// 执行上传
|
||||
let response = client.post(&config.endpoint, &body)?;
|
||||
|
||||
// 返回 URL
|
||||
Ok(parse_upload_response(&response.text())?)
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 数据库模块 (database.rs)
|
||||
|
||||
```rust
|
||||
use rusqlite::{Connection, Result as SQLResult};
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Record {
|
||||
pub id: Option<i64>,
|
||||
pub filename: String,
|
||||
pub filepath: String,
|
||||
pub upload_url: Option<String>,
|
||||
pub category: String,
|
||||
pub ocr_text: Option<String>,
|
||||
pub created_at: String,
|
||||
pub uploaded_at: Option<String>,
|
||||
pub file_size: i64,
|
||||
}
|
||||
|
||||
impl Database {
|
||||
pub fn add_record(&self, record: &Record) -> SQLResult<i64> {
|
||||
self.conn.execute(
|
||||
"INSERT INTO records (filename, filepath, category, created_at, file_size)
|
||||
VALUES (?1, ?2, ?3, datetime('now'), ?4)",
|
||||
[&record.filename, &record.filepath, &record.category, &record.created_at, &record.file_size],
|
||||
)?;
|
||||
|
||||
Ok(conn.last_insert_rowid())
|
||||
}
|
||||
|
||||
pub fn get_all_records(&self, limit: i64) -> SQLResult<Vec<Record>> {
|
||||
// 查询实现
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 前端 API 绑定 (api/commands.js)
|
||||
|
||||
```javascript
|
||||
import { invoke } from '@tauri-apps/api/commands';
|
||||
|
||||
// 截图命令
|
||||
export const captureFullscreen = async () => {
|
||||
const filepath = await invoke('capture_fullscreen');
|
||||
return filepath;
|
||||
};
|
||||
|
||||
// 上传命令
|
||||
export const uploadFile = async (filepath, config) => {
|
||||
const url = await invoke('upload_file', {
|
||||
filepath,
|
||||
provider: config.provider,
|
||||
endpoint: config.endpoint,
|
||||
apiKey: config.apiKey
|
||||
});
|
||||
return url;
|
||||
};
|
||||
|
||||
// 数据库命令
|
||||
export const getRecords = async () => {
|
||||
const records = await invoke('get_all_records', { limit: 100 });
|
||||
return records;
|
||||
};
|
||||
```
|
||||
|
||||
### 5. 前端 UI (components/screenshot.html)
|
||||
|
||||
```html
|
||||
<div class="screenshot-view">
|
||||
<div class="toolbar">
|
||||
<button id="btn-fullscreen" class="primary-btn">
|
||||
<span class="icon">📷</span>
|
||||
<span class="text">截全屏</span>
|
||||
<span class="shortcut">Ctrl+Shift+A</span>
|
||||
</button>
|
||||
<button id="btn-region" class="secondary-btn">
|
||||
<span class="icon">⛶</span>
|
||||
<span class="text">区域截图</span>
|
||||
<span class="shortcut">Ctrl+Shift+R</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="preview-container">
|
||||
<img id="preview" src="assets/placeholder.png" alt="预览">
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button id="btn-upload" disabled>
|
||||
<span class="icon">☁️</span>
|
||||
<span class="text">上传</span>
|
||||
</button>
|
||||
<button id="btn-ocr" disabled>
|
||||
<span class="icon">🔍</span>
|
||||
<span class="text">OCR 识别</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.screenshot-view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.primary-btn, .secondary-btn {
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 10px 16px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.primary-btn {
|
||||
background: #8B6914;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.secondary-btn {
|
||||
background: #f1f3f4;
|
||||
color: #2C2C2C;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tauri 配置 (tauri.conf.json)
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/1.0.0",
|
||||
"build": {
|
||||
"beforeBuildCommand": "npm run build",
|
||||
"beforeDevCommand": "npm run dev",
|
||||
"devUrl": "http://localhost:3000",
|
||||
"frontendDist": "../src-ui/dist"
|
||||
},
|
||||
"package": {
|
||||
"productName": "CutThenThink",
|
||||
"version": "3.0.0"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
"all": false,
|
||||
"shell": {
|
||||
"all": false,
|
||||
"open": true
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"identifier": "com.cutthenthink.app",
|
||||
"icon": [
|
||||
"icons/128x128.png"
|
||||
],
|
||||
"targets": ["all"]
|
||||
},
|
||||
"windows": {
|
||||
"webviewInstallMode": "embed",
|
||||
"nsis": {
|
||||
"displayName": "CutThenThink",
|
||||
"installerIcon": "icons/icon.ico"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"shell": {
|
||||
"open": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 可选 OCR 插件 (Go)
|
||||
|
||||
使用 Go 编写独立的 OCR 插件,通过 IPC 或本地服务器通信:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/tetratelabs/tesseract-go/tesseract"
|
||||
"github.com/genmo/invoices/invoices"
|
||||
)
|
||||
|
||||
type OCRResult struct {
|
||||
Text string
|
||||
Confidence float64
|
||||
Error string
|
||||
}
|
||||
|
||||
func Recognize(imagePath string) OCRResult {
|
||||
// 使用 RapidOCR 或 Tesseract
|
||||
// 通过本地 socket 或 HTTP 与主程序通信
|
||||
return OCRResult{
|
||||
Text: "识别的文字",
|
||||
Confidence: 0.95,
|
||||
Error: "",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 依赖清单
|
||||
|
||||
### Rust 后端依赖
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
tauri = { version = "1.0", features = ["shell-open"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
rusqlite = "0.3"
|
||||
reqwest = { version = "0.11", features = ["blocking", "multipart"] }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
dirs = "2.0"
|
||||
```
|
||||
|
||||
### Web 前端依赖
|
||||
|
||||
```json
|
||||
{
|
||||
"devDependencies": {
|
||||
"vite": "^4.0.0",
|
||||
"@tauri-apps/api": "^1.0.0"
|
||||
"tailwindcss": "^3.0.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 构建与打包
|
||||
|
||||
### 开发命令
|
||||
|
||||
```bash
|
||||
# 前端开发
|
||||
cd src-ui && npm run dev
|
||||
|
||||
# Rust 后端开发
|
||||
cd src-tauri && cargo tauri dev
|
||||
|
||||
# 完整构建
|
||||
npm run tauri build
|
||||
```
|
||||
|
||||
### 打包输出
|
||||
|
||||
| 平台 | 输出位置 | 说明 |
|
||||
|--------|---------|------|
|
||||
| Linux | `src-tauri/target/release/bundle/appimage` | AppImage 单文件 |
|
||||
| Windows | `src-tauri/target/release/bundle/msi` | MSI 安装包 |
|
||||
| macOS | `src-tauri/target/release/bundle/dmg` | DMG 磁盘镜像 |
|
||||
|
||||
**预估体积**:
|
||||
- 基础应用:5-10MB
|
||||
- 包含 OCR 模型:+15-20MB
|
||||
|
||||
---
|
||||
|
||||
## 实施计划
|
||||
|
||||
### Phase 1: 项目初始化 (1周)
|
||||
- [ ] 创建 Rust Tauri 项目骨架
|
||||
- [ ] 设置前端项目 (Vite + React)
|
||||
- [ ] 配置构建工具链
|
||||
- [ ] 基础 UI 框架
|
||||
|
||||
### Phase 2: 核心功能 (2周)
|
||||
- [ ] Rust 后端:截图 API 集成
|
||||
- [ ] Rust 后端:文件系统访问
|
||||
- [ ] 前端:截图 UI 组件
|
||||
- [ ] Rust 后端:SQLite 数据库实现
|
||||
- [ ] 前端:记录列表和浏览
|
||||
|
||||
### Phase 3: 上传功能 (1周)
|
||||
- [ ] Rust 后端:HTTP 上传模块
|
||||
- [ ] 前端:上传配置界面
|
||||
- [ ] 支持多种上传服务
|
||||
|
||||
### Phase 4: OCR 集成 (1周)
|
||||
- [ ] Go OCR 插件基础框架
|
||||
- [ ] RapidOCR 模型集成
|
||||
- [ ] IPC 通信机制
|
||||
- [ ] 前端:OCR 结果展示
|
||||
|
||||
### Phase 5: 打包发布 (1周)
|
||||
- [ ] 各平台构建配置
|
||||
- [ ] 图标和资源
|
||||
- [ ] 代码签名 (Windows/macOS)
|
||||
- [ ] GitHub Actions 自动构建
|
||||
- [ ] 安装包测试
|
||||
|
||||
---
|
||||
|
||||
## 优势总结
|
||||
|
||||
| 特性 | Python 方案 | Tauri 方案 |
|
||||
|------|-----------|-----------|
|
||||
| 安装体积 | 需要 Python (~200MB+) | **单文件,无需运行时** |
|
||||
| 启动速度 | 较慢 | **极快(Rust 原生)** |
|
||||
| 内存占用 | 高 (~100MB+) | **低 (~20-30MB)** |
|
||||
| 更新机制 | 需要重新打包 | **支持热更新** |
|
||||
| 开发体验 | 框架限制 | **现代 Web 开发** |
|
||||
| 跨平台 | 依赖复杂 | **一次编译,多平台** |
|
||||
|
||||
---
|
||||
|
||||
## 参考
|
||||
|
||||
- **Tauri 文档**: https://tauri.app/
|
||||
- **Tauri Examples**: https://github.com/tauri-apps/tauri/tree/dev/examples
|
||||
- **Rusqlite**: https://github.com/rusqlite/rusqlite
|
||||
- **RapidOCR**: https://github.com/RapidAI/RapidOCR
|
||||
|
||||
---
|
||||
|
||||
*文档版本: v3.0*
|
||||
*创建日期: 2025-02-12*
|
||||
*技术栈: Tauri (Rust) + Web 前端*
|
||||
Reference in New Issue
Block a user