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:
381
docs/phase3_examples.md
Normal file
381
docs/phase3_examples.md
Normal file
@@ -0,0 +1,381 @@
|
||||
# Phase 3 API 使用示例
|
||||
|
||||
本文档展示如何使用 Phase 3 实现的上传、配置和数据库功能。
|
||||
|
||||
## 前端使用示例
|
||||
|
||||
### 1. 配置管理
|
||||
|
||||
```typescript
|
||||
import { useConfigStore } from '@/store';
|
||||
|
||||
const configStore = useConfigStore();
|
||||
|
||||
// 加载配置
|
||||
await configStore.loadConfig();
|
||||
|
||||
// 添加 GitHub 图床
|
||||
await configStore.addImageHost({
|
||||
type: 'github',
|
||||
token: 'your_github_token',
|
||||
owner: 'your_username',
|
||||
repo: 'your_repo',
|
||||
path: 'screenshots',
|
||||
branch: 'main'
|
||||
});
|
||||
|
||||
// 设置为默认图床
|
||||
const githubHost = {
|
||||
type: 'github',
|
||||
token: 'your_github_token',
|
||||
owner: 'your_username',
|
||||
repo: 'your_repo',
|
||||
path: 'screenshots',
|
||||
branch: 'main'
|
||||
};
|
||||
await configStore.setDefaultImageHost(githubHost);
|
||||
|
||||
// 更新上传设置
|
||||
await configStore.updateRetryCount(5);
|
||||
await configStore.updateUploadTimeout(60);
|
||||
```
|
||||
|
||||
### 2. 上传图片
|
||||
|
||||
```typescript
|
||||
import { useUploadStore } from '@/store';
|
||||
|
||||
const uploadStore = useUploadStore();
|
||||
|
||||
// 单个上传
|
||||
const result = await uploadStore.startUpload(
|
||||
'/path/to/image.png',
|
||||
'screenshot.png'
|
||||
);
|
||||
console.log('上传成功:', result.url);
|
||||
|
||||
// 批量上传
|
||||
const images = [
|
||||
{ path: '/path/to/image1.png', filename: 'image1.png' },
|
||||
{ path: '/path/to/image2.png', filename: 'image2.png' }
|
||||
];
|
||||
const results = await uploadStore.startBatchUpload(images);
|
||||
```
|
||||
|
||||
### 3. 记录管理
|
||||
|
||||
```typescript
|
||||
import { useRecordsStore } from '@/store';
|
||||
|
||||
const recordsStore = useRecordsStore();
|
||||
|
||||
// 加载所有记录
|
||||
await recordsStore.loadRecords();
|
||||
|
||||
// 添加记录
|
||||
const record = await recordsStore.addRecord({
|
||||
record_type: 'image',
|
||||
content: 'https://example.com/image.png',
|
||||
file_path: '/path/to/image.png',
|
||||
thumbnail: 'data:image/png;base64,...',
|
||||
metadata: JSON.stringify({ size: 1024, width: 1920, height: 1080 })
|
||||
});
|
||||
|
||||
// 删除记录
|
||||
await recordsStore.removeRecord(record.id);
|
||||
|
||||
// 清空所有记录
|
||||
await recordsStore.clearAllRecords();
|
||||
```
|
||||
|
||||
### 4. 设置管理
|
||||
|
||||
```typescript
|
||||
import { useSettingsStore } from '@/store';
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
// 设置值
|
||||
await settingsStore.updateSetting('theme', 'dark');
|
||||
await settingsStore.updateSetting('language', 'zh-CN');
|
||||
|
||||
// 获取值
|
||||
const theme = await settingsStore.fetchSetting('theme');
|
||||
// 或从缓存获取
|
||||
const theme = settingsStore.getSettingValue('theme');
|
||||
|
||||
// 便捷方法
|
||||
await settingsStore.setLastImageHostType('github');
|
||||
const lastType = await settingsStore.getLastImageHostType();
|
||||
```
|
||||
|
||||
### 5. 完整的上传流程示例
|
||||
|
||||
```typescript
|
||||
import { useUploadStore, useRecordsStore, useConfigStore } from '@/store';
|
||||
|
||||
async function uploadAndRecord(imagePath: string) {
|
||||
const configStore = useConfigStore();
|
||||
const uploadStore = useUploadStore();
|
||||
const recordsStore = useRecordsStore();
|
||||
|
||||
try {
|
||||
// 1. 确保有配置的图床
|
||||
if (!configStore.defaultImageHost) {
|
||||
throw new Error('请先配置图床');
|
||||
}
|
||||
|
||||
// 2. 上传图片
|
||||
const uploadResult = await uploadStore.startUpload(
|
||||
imagePath,
|
||||
'screenshot.png'
|
||||
);
|
||||
|
||||
// 3. 保存到数据库
|
||||
const record = await recordsStore.addRecord({
|
||||
record_type: 'image',
|
||||
content: uploadResult.url,
|
||||
file_path: imagePath,
|
||||
metadata: JSON.stringify({
|
||||
image_host: uploadResult.image_host,
|
||||
file_size: uploadResult.file_size,
|
||||
uploaded_at: uploadResult.uploaded_at
|
||||
})
|
||||
});
|
||||
|
||||
console.log('上传成功,记录已保存:', record);
|
||||
return record;
|
||||
|
||||
} catch (error) {
|
||||
console.error('上传失败:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 后端测试示例
|
||||
|
||||
### Rust 单元测试
|
||||
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::fs;
|
||||
use tempfile::tempdir;
|
||||
|
||||
#[test]
|
||||
fn test_config_manager() {
|
||||
let temp_dir = tempdir().unwrap();
|
||||
let config_file = temp_dir.path().join("config.json");
|
||||
|
||||
let config_manager = ConfigManager::new_with_path(&config_file).unwrap();
|
||||
|
||||
// 测试保存和加载
|
||||
let config = AppConfig::default();
|
||||
config_manager.save(&config).unwrap();
|
||||
|
||||
let loaded_config = config_manager.load().unwrap();
|
||||
assert_eq!(loaded_config.upload_retry_count, 3);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_database_operations() {
|
||||
let db = Database::open(":memory:").unwrap();
|
||||
|
||||
// 插入记录
|
||||
let record = db.insert_record(
|
||||
RecordType::Image,
|
||||
"https://example.com/image.png",
|
||||
Some("/path/to/image.png"),
|
||||
None,
|
||||
None,
|
||||
).unwrap();
|
||||
|
||||
// 查询记录
|
||||
let found = db.get_record(&record.id).unwrap();
|
||||
assert!(found.is_some());
|
||||
|
||||
// 删除记录
|
||||
let deleted = db.delete_record(&record.id).unwrap();
|
||||
assert!(deleted);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 常见使用场景
|
||||
|
||||
### 场景 1: 截图后自动上传
|
||||
|
||||
```typescript
|
||||
import { screenshotFullscreen } from '@/api';
|
||||
import { uploadAndRecord } from './upload-flow';
|
||||
|
||||
async function captureAndUpload() {
|
||||
// 1. 截图
|
||||
const screenshot = await screenshotFullscreen();
|
||||
|
||||
// 2. 上传并记录
|
||||
const record = await uploadAndRecord(screenshot.filepath);
|
||||
|
||||
// 3. 如果配置了自动复制,复制链接
|
||||
if (configStore.autoCopyLink) {
|
||||
await navigator.clipboard.writeText(record.content);
|
||||
}
|
||||
|
||||
return record;
|
||||
}
|
||||
```
|
||||
|
||||
### 场景 2: 批量处理历史截图
|
||||
|
||||
```typescript
|
||||
import { screenshotList } from '@/api';
|
||||
import { useUploadStore } from '@/store';
|
||||
|
||||
async function batchUploadHistory() {
|
||||
const uploadStore = useUploadStore();
|
||||
|
||||
// 1. 获取所有截图
|
||||
const screenshots = await screenshotList();
|
||||
|
||||
// 2. 批量上传
|
||||
const images = screenshots.map(ss => ({
|
||||
path: ss.filepath,
|
||||
filename: ss.filename
|
||||
}));
|
||||
|
||||
const results = await uploadStore.startBatchUpload(images);
|
||||
|
||||
console.log(`成功上传 ${results.length}/${images.length} 张图片`);
|
||||
return results;
|
||||
}
|
||||
```
|
||||
|
||||
### 场景 3: 查看和清理历史记录
|
||||
|
||||
```typescript
|
||||
import { useRecordsStore } from '@/store';
|
||||
import { getRecordsCount } from '@/api';
|
||||
|
||||
async function cleanupOldRecords() {
|
||||
const recordsStore = useRecordsStore();
|
||||
|
||||
// 1. 获取当前记录数
|
||||
const count = await getRecordsCount();
|
||||
|
||||
// 2. 如果超过限制,删除最旧的
|
||||
const limit = 100;
|
||||
if (count > limit) {
|
||||
const records = await recordsStore.loadRecords(limit + 1);
|
||||
const toDelete = records.slice(limit);
|
||||
|
||||
for (const record of toDelete) {
|
||||
await recordsStore.removeRecord(record.id);
|
||||
}
|
||||
|
||||
console.log(`清理了 ${toDelete.length} 条旧记录`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 网络错误处理
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const result = await uploadStore.startUpload(imagePath, filename);
|
||||
} catch (error) {
|
||||
if (error.message.includes('timeout')) {
|
||||
console.error('上传超时,请检查网络连接');
|
||||
} else if (error.message.includes('401')) {
|
||||
console.error('认证失败,请检查图床凭据');
|
||||
} else {
|
||||
console.error('上传失败:', error.message);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 配置验证
|
||||
|
||||
```typescript
|
||||
function validateImageHostConfig(config: ImageHostConfig): string[] {
|
||||
const errors: string[] = [];
|
||||
|
||||
if (config.type === 'github') {
|
||||
if (!config.token) errors.push('GitHub Token 不能为空');
|
||||
if (!config.owner) errors.push('GitHub Owner 不能为空');
|
||||
if (!config.repo) errors.push('GitHub Repository 不能为空');
|
||||
} else if (config.type === 'imgur') {
|
||||
if (!config.client_id) errors.push('Imgur Client ID 不能为空');
|
||||
} else if (config.type === 'custom') {
|
||||
if (!config.url) errors.push('自定义 URL 不能为空');
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
```
|
||||
|
||||
## 性能优化建议
|
||||
|
||||
### 1. 批量操作
|
||||
|
||||
对于大量记录操作,使用批量方法而非循环调用单个方法:
|
||||
|
||||
```typescript
|
||||
// 不推荐
|
||||
for (const id of ids) {
|
||||
await recordsStore.removeRecord(id);
|
||||
}
|
||||
|
||||
// 推荐
|
||||
await recordsStore.removeMultipleRecords(ids);
|
||||
```
|
||||
|
||||
### 2. 分页加载
|
||||
|
||||
对于大量记录,使用分页加载:
|
||||
|
||||
```typescript
|
||||
const PAGE_SIZE = 50;
|
||||
|
||||
async function loadAllRecords() {
|
||||
let allRecords: Record[] = [];
|
||||
let page = 0;
|
||||
|
||||
while (true) {
|
||||
const records = await recordsStore.loadRecords(PAGE_SIZE, page * PAGE_SIZE);
|
||||
if (records.length === 0) break;
|
||||
|
||||
allRecords = allRecords.concat(records);
|
||||
page++;
|
||||
}
|
||||
|
||||
return allRecords;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 缓存策略
|
||||
|
||||
合理使用设置缓存:
|
||||
|
||||
```typescript
|
||||
// 首次从数据库加载
|
||||
let theme = await settingsStore.fetchSetting('theme');
|
||||
|
||||
// 后续从缓存读取
|
||||
theme = settingsStore.getSettingValue('theme');
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
Phase 3 提供了完整的上传和存储功能,包括:
|
||||
|
||||
1. **多种图床支持**: GitHub、Imgur、自定义
|
||||
2. **配置管理**: 完善的配置读写和验证
|
||||
3. **数据持久化**: SQLite 数据库存储
|
||||
4. **前端封装**: TypeScript 类型和 Pinia Store
|
||||
5. **UI 组件**: 配置管理和历史查看界面
|
||||
|
||||
通过合理组合这些功能,可以实现完整的截图-上传-管理流程。
|
||||
Reference in New Issue
Block a user