feat: 实现多 OCR 提供商架构和完整设置页面

## 主要变更

### OCR 架构
- 新增多提供商 OCR 系统 (Tesseract.js, Baidu OCR, RapidOCR)
- 添加 Provider 基类接口和工厂模式
- 支持 provider 自动选择和降级处理
- 新增 RapidOCR Python HTTP 服务 (端口 8080)

### 路径修复
- 修复 Windows 平台路径解析问题
- 统一路径处理工具 (lib/path.ts)
- 修复 uploads 目录定位问题

### 设置页面重构
- 三个标签页:API 配置、OCR 配置、AI 配置
- API 服务器地址配置
- OCR 服务商配置(Tesseract.js, RapidOCR, 百度 OCR)
- AI 服务商配置(智谱 GLM, MiniMax, DeepSeek, Kimi, OpenAI, Anthropic)

### 端口配置
- 前端端口: 13056
- 后端端口: 13057

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
锦麟 王
2026-02-26 14:00:22 +08:00
parent 813df6c738
commit f8472987f0
23 changed files with 2321 additions and 275 deletions
+136 -8
View File
@@ -26,9 +26,14 @@ npm run test:watch # Jest 监视模式
npm run test:coverage # 测试覆盖率报告
npm run lint # ESLint 检查
npm run lint:fix # ESLint 自动修复
npm run format # Prettier 格式化
npm run prisma:generate # 生成 Prisma Client
npm run prisma:migrate # 运行数据库迁移
npm run prisma:studio # 打开 Prisma Studio
# 运行单个测试文件
npm test -- tests/unit/services/auth.service.test.ts
npm test -- --testNamePattern="should login"
```
### 前端 (端口 3000)
@@ -43,6 +48,12 @@ npm run test:coverage # Vitest 覆盖率报告
npm run test:e2e # 运行 Playwright E2E 测试
npm run test:e2e:ui # Playwright UI 模式
npm run lint # ESLint 检查
# 运行单个测试文件
npx vitest src/services/__tests__/auth.service.test.ts
# 运行单个 E2E 测试
npx playwright test auth.spec.ts
```
### 数据库操作
@@ -63,12 +74,18 @@ backend/src/
├── services/ # 业务逻辑层
│ ├── auth.service.ts # 认证逻辑 (注册/登录/验证)
│ ├── password.service.ts # 密码验证和强度检查
│ ├── ocr.service.ts # OCR 处理逻辑(置信度验证重试
│ ├── ocr.service.ts # OCR 置信度验证重试逻辑
│ ├── ocr-processor.service.ts # OCR 处理服务 (多 Provider 支持)
│ ├── ocr-providers/ # OCR Provider 实现
│ │ ├── base.provider.ts # 基础接口
│ │ ├── tesseract.provider.ts # Tesseract.js (本地)
│ │ ├── baidu.provider.ts # 百度 OCR (云端)
│ │ └── rapidocr.provider.ts # RapidOCR (本地)
│ ├── document.service.ts # 文档 CRUD
│ ├── todo.service.ts # 待办事项管理(三态工作流)
│ └── image.service.ts # 图片上传和处理
├── routes/ # API 路由定义
├── middleware/ # 中间件 (JWT 认证)
├── middleware/ # 中间件 (JWT 认证、上传)
└── lib/prisma.ts # Prisma 客户端单例
```
@@ -76,6 +93,8 @@ backend/src/
- **分层架构**: Controller → Service → Prisma (数据层)
- **服务类**: 使用静态方法实现无状态业务逻辑
- **中间件**: JWT 认证中间件保护需要登录的路由
- **OCR Provider**: 可插拔的 OCR 提供商架构,支持扩展
- **上传中间件**: `upload.middleware.ts` 使用 multer 处理文件上传
### 前端架构
```
@@ -130,17 +149,75 @@ SELECT * FROM images
WHERE user_id = ? AND (document_id IS NULL OR processing_status = 'failed')
```
## OCR 多 Provider 架构
系统支持多种 OCR 提供商,可根据需求选择:
| Provider | 类型 | 速度 | 准确率 | 成本 | 部署要求 |
|----------|------|------|--------|------|----------|
| **tesseract** | 本地 | 慢 | 中 | 免费 | `npm install tesseract.js` |
| **rapidocr** | 本地 | 快 | 高 | 免费 | Docker: `cshgg/rapidocr` |
| **baidu** | 云端 | 快 | 高 | 按次付费 (有免费额度) | 需要 API Key |
### 配置方式
`.env` 中设置 `OCR_PROVIDER`:
```bash
# 自动选择可用的 provider (推荐)
OCR_PROVIDER="auto"
# 或指定具体 provider
OCR_PROVIDER="tesseract" # 或 "rapidocr", "baidu"
```
### 各 Provider 配置
**Tesseract.js** (本地轻量,免费)
```bash
# 安装依赖
npm install tesseract.js
# 无需额外配置
```
**RapidOCR** (本地快速准确,推荐)
```bash
# Docker 启动
docker run -d -p 8080:8080 cshgg/rapidocr
# 配置环境变量
RAPIDOCR_API_URL="http://localhost:8080"
```
**Baidu OCR** (云端准确,有免费额度)
```bash
# 申请地址: https://cloud.baidu.com/product/ocr
BAIDU_OCR_API_KEY="your_api_key"
BAIDU_OCR_SECRET_KEY="your_secret_key"
```
### Provider 架构
OCR Provider 实现位于 `backend/src/services/ocr-providers/`:
- `base.provider.ts` - 基础接口定义
- `tesseract.provider.ts` - Tesseract.js 实现
- `rapidocr.provider.ts` - RapidOCR HTTP API 实现
- `baidu.provider.ts` - 百度 OCR API 实现
新增 Provider 只需继承 `BaseOCRProvider` 并实现 `recognize()` 方法。
## 测试策略
### 后端测试 (Jest)
- 单元测试覆盖所有 Service 类
- 集成测试验证 API 端点
- 目标覆盖率: 80%+
- 覆盖率阈值: 80% (branches, functions, lines, statements)
- 测试文件匹配: `**/__tests__/**/*.ts`, `**/?(*.)+(spec|test).ts`
### 前端测试
- **Vitest**: 组件和服务的单元测试
- **Playwright**: E2E 测试,跨浏览器测试 (Chrome, Firefox, Safari)
- 测试文件位于 `e2e/` 目录
- E2E 测试配置: 自动启动开发服务器,支持 CI 模式重试
## API 端点
@@ -161,16 +238,66 @@ WHERE user_id = ? AND (document_id IS NULL OR processing_status = 'failed')
- `DELETE /api/todos/:id` - 删除待办
### 图片
- `POST /api/images/upload` - 上传图片
- `GET /api/images` - 获取图片列表
- `POST /api/images` - 上传图片
- `GET /api/images` - 获取用户图片列表
- `GET /api/images/pending` - 获取待处理图片 (OCR 失败)
- `GET /api/images/ocr/providers` - 获取可用的 OCR 提供商列表
- `GET /api/images/:id` - 获取单张图片详情
- `POST /api/images/:id/reprocess` - 重新触发 OCR 处理 (支持指定 provider)
- `PUT /api/images/:id/ocr` - 更新 OCR 结果
- `PUT /api/images/:id/link` - 关联图片到文档
- `DELETE /api/images/:id` - 删除图片
## 环境变量
后端需要创建 `.env` 文件:
后端需要创建 `.env` 文件(参考 `backend/.env.example`
```
# Database
DATABASE_URL="file:./dev.db"
JWT_SECRET="your-secret-key"
# JWT
JWT_SECRET="your-secret-key-change-in-production"
JWT_EXPIRES_IN="24h"
# Server
PORT=4000
NODE_ENV="development"
# CORS
CORS_ORIGIN="http://localhost:3000"
# OCR Provider: tesseract | baidu | rapidocr | auto
OCR_PROVIDER="auto"
OCR_CONFIDENCE_THRESHOLD="0.3"
# Tesseract.js (本地 OCR)
# 安装: npm install tesseract.js
# Baidu OCR (云端 OCR)
BAIDU_OCR_API_KEY=""
BAIDU_OCR_SECRET_KEY=""
# RapidOCR (本地快速 OCR)
RAPIDOCR_API_URL="http://localhost:8080"
# AI (GLM)
GLM_API_KEY=""
GLM_API_URL="https://open.bigmodel.cn/api/paas/v4/chat/completions"
GLM_MODEL="glm-4-flash"
# AI (MiniMax)
MINIMAX_API_KEY=""
MINIMAX_API_URL="https://api.minimax.chat/v1/chat/completions"
MINIMAX_MODEL="abab6.5s-chat"
# AI (DeepSeek)
DEEPSEEK_API_KEY=""
DEEPSEEK_API_URL="https://api.deepseek.com/v1/chat/completions"
DEEPSEEK_MODEL="deepseek-chat"
# Upload
UPLOAD_MAX_SIZE="10485760"
UPLOAD_ALLOWED_TYPES="image/jpeg,image/png,image/webp"
```
## 测试账号
@@ -187,10 +314,11 @@ PORT=4000
- ✅ 文档 CRUD
- ✅ 待办三态工作流
- ✅ 图片上传和 OCR 状态追踪
- ✅ 多 Provider OCR 架构 (Tesseract.js / Baidu / RapidOCR)
- ✅ 前后端单元测试 (148 个测试全部通过)
- ✅ E2E 测试框架
待开发功能 (P1 优先级)
- ⏳ OCR 集成 (Tesseract/PaddleOCR)
- ⏳ AI 分析功能 (GLM/MiniMax/DeepSeek)
- ⏳ 图片-文档-待办关联增强
- ⏳ 前端 OCR 设置页面 (Provider 选择和测试)