Files
cutThink_lite/lightweight-redesign.md
Claude e2ea309ee6 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>
2026-02-12 18:59:26 +08:00

15 KiB
Raw Permalink Blame History

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)

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)

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)

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)

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)

<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)

{
  "$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 或本地服务器通信:

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 后端依赖

[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 前端依赖

{
  "devDependencies": {
    "vite": "^4.0.0",
    "@tauri-apps/api": "^1.0.0"
    "tailwindcss": "^3.0.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}

构建与打包

开发命令

# 前端开发
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 开发
跨平台 依赖复杂 一次编译,多平台

参考


文档版本: v3.0 创建日期: 2025-02-12 技术栈: Tauri (Rust) + Web 前端