feat: 实现CutThenThink P0阶段核心功能
项目初始化 - 创建完整项目结构(src/, data/, docs/, examples/, tests/) - 配置requirements.txt依赖 - 创建.gitignore P0基础框架 - 数据库模型:Record模型,6种分类类型 - 配置管理:YAML配置,支持AI/OCR/云存储/UI配置 - OCR模块:PaddleOCR本地识别,支持云端扩展 - AI模块:支持OpenAI/Claude/通义/Ollama,6种分类 - 存储模块:完整CRUD,搜索,统计,导入导出 - 主窗口框架:侧边栏导航,米白配色方案 - 图片处理:截图/剪贴板/文件选择/图片预览 - 处理流程整合:OCR→AI→存储串联,Markdown展示,剪贴板复制 - 分类浏览:卡片网格展示,分类筛选,搜索,详情查看 技术栈 - PyQt6 + SQLAlchemy + PaddleOCR + OpenAI/Claude SDK - 共47个Python文件,4000+行代码 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
381
docs/P0-8_processor_integration.md
Normal file
381
docs/P0-8_processor_integration.md
Normal file
@@ -0,0 +1,381 @@
|
||||
# P0-8: 处理流程整合 - 使用文档
|
||||
|
||||
本文档说明如何使用 CutThenThink 的处理流程整合功能。
|
||||
|
||||
## 功能概述
|
||||
|
||||
处理流程整合模块提供了以下功能:
|
||||
|
||||
1. **完整流程串联**:OCR → AI 分类 → 数据库存储
|
||||
2. **Markdown 结果展示**:将处理结果格式化为 Markdown
|
||||
3. **一键复制到剪贴板**:方便复制处理结果
|
||||
4. **错误提示和日志**:完善的错误处理和日志记录
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 1. ImageProcessor
|
||||
|
||||
图片处理器是整合流程的核心类。
|
||||
|
||||
```python
|
||||
from src.core.processor import ImageProcessor, ProcessCallback
|
||||
from src.config.settings import get_settings
|
||||
|
||||
# 加载配置
|
||||
settings = get_settings()
|
||||
|
||||
# 创建回调(可选)
|
||||
callback = ProcessCallback()
|
||||
|
||||
# 创建处理器
|
||||
processor = ImageProcessor(
|
||||
ocr_config={
|
||||
'mode': 'local', # 'local' 或 'cloud'
|
||||
'lang': 'ch', # 语言
|
||||
'use_gpu': False # 是否使用 GPU
|
||||
},
|
||||
ai_config=settings.ai,
|
||||
db_path='data/cutnthink.db',
|
||||
callback=callback
|
||||
)
|
||||
|
||||
# 处理图片
|
||||
result = processor.process_image('/path/to/image.png')
|
||||
|
||||
# 检查结果
|
||||
if result.success:
|
||||
print(f"处理成功! 耗时: {result.process_time:.2f}秒")
|
||||
print(f"记录 ID: {result.record_id}")
|
||||
else:
|
||||
print(f"处理失败: {result.error_message}")
|
||||
```
|
||||
|
||||
### 2. ProcessResult
|
||||
|
||||
处理结果数据结构。
|
||||
|
||||
```python
|
||||
from src.core.processor import ProcessResult
|
||||
|
||||
result: ProcessResult = processor.process_image(...)
|
||||
|
||||
# 访问结果
|
||||
result.success # 是否成功
|
||||
result.image_path # 图片路径
|
||||
result.ocr_result # OCR 结果 (OCRBatchResult)
|
||||
result.ai_result # AI 结果 (ClassificationResult)
|
||||
result.record_id # 数据库记录 ID
|
||||
result.process_time # 处理耗时(秒)
|
||||
result.steps_completed # 已完成的步骤列表
|
||||
result.warnings # 警告信息列表
|
||||
|
||||
# 转换为字典
|
||||
data = result.to_dict()
|
||||
```
|
||||
|
||||
### 3. ProcessCallback
|
||||
|
||||
处理进度回调类。
|
||||
|
||||
```python
|
||||
from src.core.processor import ProcessCallback
|
||||
|
||||
class MyCallback(ProcessCallback):
|
||||
def on_start(self, message="开始处理"):
|
||||
print(f"开始: {message}")
|
||||
|
||||
def on_ocr_complete(self, result):
|
||||
print(f"OCR 完成: {len(result.results)} 行")
|
||||
|
||||
def on_ai_complete(self, result):
|
||||
print(f"AI 分类: {result.category.value}")
|
||||
|
||||
def on_complete(self, result):
|
||||
if result.success:
|
||||
print("处理成功!")
|
||||
else:
|
||||
print("处理失败")
|
||||
|
||||
callback = MyCallback()
|
||||
processor = ImageProcessor(..., callback=callback)
|
||||
```
|
||||
|
||||
### 4. Markdown 格式化
|
||||
|
||||
创建 Markdown 格式的处理结果。
|
||||
|
||||
```python
|
||||
from src.core.processor import create_markdown_result
|
||||
|
||||
# 创建 Markdown
|
||||
markdown = create_markdown_result(
|
||||
ai_result=result.ai_result,
|
||||
ocr_text=result.ocr_result.full_text
|
||||
)
|
||||
|
||||
print(markdown)
|
||||
```
|
||||
|
||||
### 5. 剪贴板功能
|
||||
|
||||
复制内容到剪贴板。
|
||||
|
||||
```python
|
||||
from src.utils.clipboard import copy_to_clipboard
|
||||
|
||||
# 复制文本
|
||||
success = copy_to_clipboard("要复制的文本")
|
||||
|
||||
if success:
|
||||
print("复制成功!")
|
||||
else:
|
||||
print("复制失败")
|
||||
```
|
||||
|
||||
### 6. 结果展示组件
|
||||
|
||||
在 GUI 中展示处理结果。
|
||||
|
||||
```python
|
||||
import tkinter as tk
|
||||
from src.gui.widgets import ResultWidget
|
||||
|
||||
# 创建主窗口
|
||||
root = tk.Tk()
|
||||
|
||||
# 创建结果组件
|
||||
result_widget = ResultWidget(root)
|
||||
result_widget.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
# 设置结果
|
||||
result_widget.set_result(process_result)
|
||||
|
||||
# 获取内容
|
||||
content = result_widget.get_content()
|
||||
|
||||
root.mainloop()
|
||||
```
|
||||
|
||||
### 7. 消息处理
|
||||
|
||||
显示各种对话框。
|
||||
|
||||
```python
|
||||
from src.gui.widgets import show_info, show_error, show_warning, ask_yes_no
|
||||
|
||||
# 显示信息
|
||||
show_info("标题", "消息内容")
|
||||
|
||||
# 显示警告
|
||||
show_warning("警告", "警告内容")
|
||||
|
||||
# 显示错误
|
||||
show_error("错误", "错误内容", exception=e)
|
||||
|
||||
# 询问是/否
|
||||
if ask_yes_no("确认", "确定要继续吗?"):
|
||||
print("用户选择是")
|
||||
```
|
||||
|
||||
## 完整示例
|
||||
|
||||
### 命令行示例
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
from src.core.processor import process_single_image
|
||||
from src.config.settings import get_settings
|
||||
|
||||
settings = get_settings()
|
||||
|
||||
# 处理单张图片
|
||||
result = process_single_image(
|
||||
image_path="/path/to/image.png",
|
||||
ocr_config={
|
||||
'mode': 'local',
|
||||
'lang': 'ch',
|
||||
'use_gpu': False
|
||||
},
|
||||
ai_config=settings.ai,
|
||||
db_path="data/cutnthink.db"
|
||||
)
|
||||
|
||||
if result.success:
|
||||
print("处理成功!")
|
||||
print(f"分类: {result.ai_result.category.value}")
|
||||
print(f"标题: {result.ai_result.title}")
|
||||
else:
|
||||
print(f"处理失败: {result.error_message}")
|
||||
```
|
||||
|
||||
### GUI 示例
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog, ttk
|
||||
from src.core.processor import ImageProcessor, ProcessCallback, ProcessResult
|
||||
from src.gui.widgets import ResultWidget, ProgressDialog, MessageHandler
|
||||
from src.config.settings import get_settings
|
||||
|
||||
class App:
|
||||
def __init__(self):
|
||||
self.root = tk.Tk()
|
||||
self.settings = get_settings()
|
||||
self.message_handler = MessageHandler(self.root)
|
||||
|
||||
# 创建 UI
|
||||
self._create_ui()
|
||||
|
||||
def _create_ui(self):
|
||||
# 工具栏
|
||||
toolbar = ttk.Frame(self.root)
|
||||
toolbar.pack(fill=tk.X, padx=5, pady=5)
|
||||
|
||||
ttk.Button(toolbar, text="选择图片", command=self._select_image).pack(side=tk.LEFT)
|
||||
ttk.Button(toolbar, text="处理", command=self._process).pack(side=tk.LEFT)
|
||||
|
||||
# 状态栏
|
||||
self.status_label = ttk.Label(self.root, text="就绪", relief=tk.SUNKEN)
|
||||
self.status_label.pack(side=tk.BOTTOM, fill=tk.X)
|
||||
|
||||
# 结果展示
|
||||
self.result_widget = ResultWidget(self.root)
|
||||
self.result_widget.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
def _select_image(self):
|
||||
filename = filedialog.askopenfilename(filetypes=[("图片", "*.png *.jpg")])
|
||||
if filename:
|
||||
self.image_path = filename
|
||||
self.status_label.config(text=f"已选择: {filename}")
|
||||
|
||||
def _process(self):
|
||||
# 创建进度对话框
|
||||
progress = ProgressDialog(self.root, title="处理中", message="正在处理...")
|
||||
|
||||
# 创建处理器
|
||||
callback = ProcessCallback()
|
||||
processor = ImageProcessor(
|
||||
ocr_config={'mode': 'local', 'lang': 'ch'},
|
||||
ai_config=self.settings.ai,
|
||||
db_path="data/cutnthink.db",
|
||||
callback=callback
|
||||
)
|
||||
|
||||
# 处理
|
||||
result = processor.process_image(self.image_path)
|
||||
|
||||
# 关闭进度
|
||||
progress.close()
|
||||
|
||||
# 显示结果
|
||||
if result.success:
|
||||
self.result_widget.set_result(result)
|
||||
self.message_handler.show_info("完成", "处理成功!")
|
||||
else:
|
||||
self.message_handler.show_error("失败", result.error_message)
|
||||
|
||||
def run(self):
|
||||
self.root.mainloop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = App()
|
||||
app.run()
|
||||
```
|
||||
|
||||
## 高级功能
|
||||
|
||||
### 批量处理
|
||||
|
||||
```python
|
||||
# 批量处理多张图片
|
||||
image_paths = [
|
||||
"/path/to/image1.png",
|
||||
"/path/to/image2.png",
|
||||
"/path/to/image3.png"
|
||||
]
|
||||
|
||||
results = processor.batch_process(image_paths)
|
||||
|
||||
for i, result in enumerate(results):
|
||||
print(f"图片 {i+1}: {'成功' if result.success else '失败'}")
|
||||
```
|
||||
|
||||
### 跳过步骤
|
||||
|
||||
```python
|
||||
# 跳过 OCR,使用提供的文本
|
||||
result = processor.process_image(
|
||||
image_path="/path/to/image.png",
|
||||
skip_ocr=True,
|
||||
ocr_text="直接提供的文本"
|
||||
)
|
||||
|
||||
# 跳过 AI 分类
|
||||
result = processor.process_image(
|
||||
image_path="/path/to/image.png",
|
||||
skip_ai=True
|
||||
)
|
||||
|
||||
# 不保存到数据库
|
||||
result = processor.process_image(
|
||||
image_path="/path/to/image.png",
|
||||
save_to_db=False
|
||||
)
|
||||
```
|
||||
|
||||
### 自定义日志
|
||||
|
||||
```python
|
||||
from src.utils.logger import init_logger, get_logger
|
||||
|
||||
# 初始化日志
|
||||
init_logger(
|
||||
log_dir="logs",
|
||||
level="DEBUG",
|
||||
console_output=True,
|
||||
file_output=True
|
||||
)
|
||||
|
||||
logger = get_logger(__name__)
|
||||
logger.info("处理开始")
|
||||
logger.error("处理失败")
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
|
||||
```python
|
||||
from src.core.processor import ProcessResult
|
||||
from src.gui.widgets import show_error
|
||||
|
||||
result = processor.process_image(...)
|
||||
|
||||
if not result.success:
|
||||
# 显示错误
|
||||
show_error("处理失败", result.error_message)
|
||||
|
||||
# 检查警告
|
||||
for warning in result.warnings:
|
||||
print(f"警告: {warning}")
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **数据库路径**:确保数据库路径正确,目录存在
|
||||
2. **AI 配置**:使用 AI 分类前需配置 API Key
|
||||
3. **OCR 模式**:本地模式需要安装 PaddleOCR
|
||||
4. **错误处理**:建议使用 try-except 捕获异常
|
||||
5. **日志记录**:生产环境建议启用文件日志
|
||||
|
||||
## 参考文档
|
||||
|
||||
- [OCR 模块文档](../src/core/ocr.py)
|
||||
- [AI 模块文档](../src/core/ai.py)
|
||||
- [数据库文档](../src/models/database.py)
|
||||
- [配置管理文档](../src/config/settings.py)
|
||||
|
||||
## 示例文件
|
||||
|
||||
- `/examples/processor_example.py` - 命令行示例
|
||||
- `/examples/gui_integration_example.py` - GUI 集成示例
|
||||
- `/tests/test_processor.py` - 单元测试
|
||||
Reference in New Issue
Block a user