主题
设计文档
本文档整合了架构设计、数据模型和UI流程,为技术实现提供统一的参考。
1. 架构设计
1.1 整体架构
reading_vocab_helper 采用 Clean Architecture(整洁架构)+ Riverpod 状态管理,确保代码的可测试性、可维护性和可扩展性。
┌─────────────────────────────────────────────────┐
│ Presentation Layer (表现层) │
│ - Widgets / Pages / Riverpod Providers │
│ - User Interactions │
├─────────────────────────────────────────────────┤
│ Domain Layer (领域层) │
│ - Entities (实体) │
│ - Use Cases (用例) │
│ - Repository Interfaces (仓储接口) │
│ - 无依赖,纯业务逻辑 │
├─────────────────────────────────────────────────┤
│ Data Layer (数据层) │
│ - Repository Implementations │
│ - Data Sources (SQLite/API/File) │
└─────────────────────────────────────────────────┘1.2 目录结构
项目规模:
- 代码规模:~10,000+ 行 Dart 代码
- 文件数量:~80+ 个 Dart 文件
- 功能模块:7 个主要模块
- 数据库版本:详见 schema.md
- 依赖包:40+ 个
核心目录:
lib/
├── main.dart # 应用入口
├── core/ # 核心层
│ ├── algorithms/ # SM-2 算法
│ ├── constants/ # 常量定义
│ ├── services/ # 核心服务
│ └── utils/ # 工具类
├── features/ # 功能模块(7个)
│ ├── photo_recognition/ # 拍照识别
│ ├── vocabulary_filtering/ # 词汇过滤
│ ├── vocabulary_notebook/ # 词汇笔记本
│ ├── reading_tracking/ # 阅读追踪
│ ├── translation/ # 翻译
│ ├── statistics/ # 统计
│ └── settings/ # 设置
└── shared/ # 共享层
├── data/database/ # 数据库
├── domain/ # 共享实体
└── presentation/ # 共享组件每个功能模块的标准结构:
features/[module_name]/
├── domain/
│ ├── entities/ # 业务实体
│ └── repositories/ # 仓储接口
├── data/
│ ├── datasources/ # 数据源实现
│ └── models/ # 数据模型
└── presentation/
├── pages/ # 页面
├── widgets/ # 组件
└── providers/ # Riverpod Providers1.3 技术栈
核心框架:
- Flutter >=3.0.0 - 跨平台 UI 框架
- Dart >=3.0.0 - 开发语言
状态管理:
- Riverpod ^2.4.0 - 状态管理
- riverpod_generator ^2.3.0 - 代码生成
数据库:
- sqflite ^2.3.0 - 本地数据库(3层回填架构)
- supabase_flutter ^2.5.0 - 云端词汇库
- path_provider ^2.1.1 - 文件路径
图像处理 & OCR:
- image_picker ^1.0.7 - 相机/相册
- opencv_dart ^1.4.5 - 图像算法(本地修改版)
- google_mlkit_text_recognition ^0.11.0 - OCR 文字识别
网络请求:
- Dio ^5.4.0 - HTTP 客户端
- connectivity_plus ^5.0.0 - 网络状态
UI 组件:
- fl_chart ^0.66.2 - 图表库
- cached_network_image ^3.3.1 - 网络图片缓存
- shimmer ^3.0.0 - 加载动画
序列化:
- freezed ^2.4.1 - 不可变数据类
- json_serializable ^6.7.1 - JSON 序列化
其他工具:
- logger ^2.0.1 - 日志
- shared_preferences ^2.2.2 - 键值存储
- uuid ^4.0.0 - UUID 生成
- flutter_tts ^4.2.3 - 文字转语音
- firebase_analytics ^10.7.0 - 数据分析
1.4 架构分层详解
Domain Layer(领域层)
职责:纯业务逻辑,不依赖任何框架
特点:
- ✅ 纯 Dart 代码,无 Flutter 依赖
- ✅ 可独立测试
- ✅ 可复用到其他平台
示例:
dart
// Entities - 业务实体
class VocabularyEntity {
final String word;
final String? cefrLevel;
final String? partOfSpeech;
}
// Repository Interfaces - 仓储接口
abstract class VocabularyFilteringRepository {
Future<List<VocabularyEntity>> filterVocabularies({
required List<String> words,
required String userLevel,
});
}Data Layer(数据层)
职责:数据获取和持久化
特点:
- ✅ 实现 Domain 层定义的接口
- ✅ 处理数据缓存
- ✅ 错误处理和重试
示例:
dart
class VocabularyFilteringRepositoryImpl implements VocabularyFilteringRepository {
final VocabularyFilteringLocalDataSource _localDataSource;
@override
Future<List<VocabularyEntity>> filterVocabularies(...) async {
final models = await _localDataSource.getVocabulariesByWords(words);
return models.map((m) => m.toEntity()).toList();
}
}Presentation Layer(表现层)
职责:UI 和用户交互
特点:
- ✅ 响应式 UI(Riverpod)
- ✅ 用户输入处理
- ✅ 导航和路由
示例:
dart
@riverpod
class VocabularyFiltering extends _$VocabularyFiltering {
@override
FutureOr<FilteringResultEntity> build() {
return FilteringResultEntity.initial();
}
Future<void> filterVocabularies(List<String> words) async {
state = const AsyncValue.loading();
state = await AsyncValue.guard(() async {
final repository = ref.read(vocabularyFilteringRepositoryProvider);
return await repository.filterVocabularies(
words: words,
userLevel: ref.read(userSettingsProvider).cefrLevel,
);
});
}
}1.5 关键设计决策
为什么使用 Clean Architecture?
优势:
- ✅ 依赖倒置:外层依赖内层,内层不依赖外层
- ✅ 可测试性:每层可独立测试
- ✅ 可维护性:层次清晰,职责分明
- ✅ 可扩展性:易于替换数据源、UI 框架
权衡:
- ⚠️ 初始代码量较多
- ⚠️ 学习曲线较陡
结论:对于长期维护的项目,Clean Architecture 是值得的投资
为什么使用 Riverpod?
对比 Provider:
- ✅ 编译时安全(不会忘记提供 Provider)
- ✅ 支持 Provider 容器测试
- ✅ 更好的性能优化
- ✅ 自动依赖管理
对比 Bloc:
- ✅ 代码更简洁
- ✅ 学习曲线更低
- ✅ 更适合个人项目
为什么使用 SQLite?
优势:
- ✅ 本地存储:隐私保护,无需网络
- ✅ 支持复杂查询:JOIN、GROUP BY、索引
- ✅ 成熟稳定:Flutter 官方推荐
- ✅ 离线优先:核心功能无需网络
性能指标:
- 查询响应:< 100ms(有索引)
- 数据库大小:~10MB(含词库)
为什么使用 Google ML Kit?
优势:
- ✅ 离线可用:无需网络即可识别
- ✅ 准确性高:清晰文字识别率 > 90%
- ✅ 免费:无 API 调用成本
- ✅ 跨平台:iOS 和 Android 都支持
2. 数据模型
2.1 数据库设计
权威文档:完整的数据库设计请参见 docs/database/ 目录。
📚 快速导航:
- schema.md - 完整表结构和 ER 图
- optimization.md - 索引策略和性能优化
- README.md - 数据库管理流程
核心架构概览:
- 版本:详见 schema.md
- 数据库文件:
english_learning.db(唯一功能数据库) - 表数量:9 张(v27 删除 learning_records)
- 词汇库架构:3 层回填
- 本地
vocabulary_items表(预装词 + 回填词) - Supabase 云端词汇库(3 万+ 词)
- Edge Function API(Cambridge/Merriam-Webster)
- 本地
设计原则:
- 单一数据库(移除了 vocabulary.db 和缓存表)
- 预装词支持全量更新(source='preinstalled')
- 回填词 LRU 淘汰机制(last_accessed_at 字段)
- SQL 脚本化管理(DDL/DML 分离)
注意:本文档只提供概览,所有表结构定义以
database/schema.md为准。
2.2 词汇数据模型
2.2.1 CEFR 等级体系
基于 CEFR(欧洲语言共同参考框架)的词汇分级:
3. UI 流程
3.1 应用导航结构
┌─────────────────────────────────────┐
│ 应用入口 │
├─────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌────┐│
│ │ 首页 │ │ 学习 │ │我的││
│ └──────────┘ └──────────┘ └────┘│
└─────────────────────────────────────┘3.2 核心页面
首页(HomePage)
路由:/home
功能:
- 今日学习概览
- 快速入口:拍照识词、学习复习
- 待复习词汇数量
- 最近书籍
交互:
- 点击"拍照识词" → 进入相机/相册选择
- 点击"学习复习" → 进入学习页面
- 点击书籍卡片 → 进入书籍详情页
拍照识词页面(PhotoRecognitionPage)
路由:/photo-recognition
完整流程:
1. 选择图片
[📷 相机] [🖼️ 相册]
↓
2. OCR 识别
识别中... ⏳
↓
2.5 词形还原(v11 新增)
识别:books, went, children, established
还原:book, go, child, establish
去重:减少20-30%重复单词
↓
3. 词汇过滤
识别到 50 个单词
过滤后: 12 个
CEFR 等级: B1
↓
4. 预览和确认
☑ establish (B2) 👁️ 原图高亮: established
☑ epiphany (C2)
☑ ephemeral (C1)
☐ the (A1)
[全选] [翻译] [添加到笔记本]
↓
5. 选择书籍
○ 《The Great Gatsby》
○ 新建书籍
↓
6. 完成确认
✅ 添加成功
已添加 12 个词汇词形还原机制(v11):
- 目的:统一单词变形,减少重复和PENDING/UNKNOWN
- 引擎:四层还原(例外词60+ → 不规则词430+ → 后缀规则13条 → 原词)
- 显示策略:用户看到词根(book),减少认知负担
- 高亮查询:点击 establish → 原图 established 正确高亮
- 数据库:learning_entries 存词根;ocr_word_positions 存原词+词根
学习会话页面(LearningSessionPage)
路由:/learning/session/:sessionId
卡片式复习(v9.1优化 - 3按钮设计):
┌─────────────────────────────┐
│ [✕] 5 / 20 │
├─────────────────────────────┤
│ │
│ epiphany │
│ /ɪˈpɪfəni/ │
│ │
│ 💡 点击查看释义 │
│ │
├─────────────────────────────┤
│[Forgot] [Recalled] [Perfect]│
│ 🟠橙 🔵蓝 🟢绿 │
└─────────────────────────────┘交互流程:
- 显示单词正面(隐藏释义)
- 点击卡片翻转(显示释义)
- 选择评分(v10 改为 2-Button):
- Hard(橙):不确定/困难 → Quality 由序列推导
- Easy(绿):确定掌握 → Quality 由序列推导
- 自动进入下一张卡片
- 完成后显示总结
SM-2学习算法(v10 — 2-Button + 序列推导):
质量推导:根据「上一次按钮 + 本次按钮」推导 4 级 SM-2 Quality:
| 上次 | 本次 | Quality | 含义 |
|---|---|---|---|
| Hard | Hard | 1 | 持续困难,重置 |
| Easy | Hard | 2 | 退步,降低间隔 |
| Hard | Easy | 4 | 进步中,适度加速 |
| Easy | Easy | 5 | 稳定掌握,最大加速 |
首次复习(无历史)默认按 Hard→X 处理(Hard=1, Easy=4)。
晋级机制(不变):
- Level 0 → Level 1: 1次成功 (Q≥2)
- Level 1 → Level 2: 2次成功 (Q≥3)
- Level 2 → Level 3: 4次成功 (Q≥4)
- Level 3 → Level 4: 7次成功 (Q≥4)
- Level 4 → Level 5: 10次成功 (Q≥4)
降级机制(v10 细化):
- Q=1(Hard→Hard):降 2 级(持续困难)
- Q=2(Easy→Hard):降 1 级(轻微退步)
- 同时 Ease Factor 按 SM-2 公式自然调整
设计理念(v10 演进):
- 从 v9.1 的 3-Button(Forgot/Recalled/Perfect)简化为 2-Button
- 解决用户难以区分 Recalled 和 Perfect 的问题
- 通过序列推导保留 4 级质量粒度,不损失算法精度
- 竞品验证:Anki Pass/Fail、FSRS 二元模式、Duolingo HLR 均支持二元输入
- 技术决策详情:
docs/decisions.md→ 决策14
词汇笔记本页面(VocabularyNotebookPage)
路由:/notebook
功能:
- 按书籍查看词汇
- 搜索和筛选
- 词汇详情
布局:
┌─────────────────────────────┐
│ [🔍搜索] [⚙️筛选] │
├─────────────────────────────┤
│ 📚 所有书籍 (150 个词汇) │
│ │
│ ┌─────────────────────────┐ │
│ │《The Great Gatsby》 │ │
│ │50个词汇 │ 8个待复习 │ │
│ └─────────────────────────┘ │
│ │
│ [+ 新建书籍] │
└─────────────────────────────┘书籍管理相关页面 🆕
书籍列表页面(BookListPage)
路由:/books
功能:
- 浏览所有书籍
- 创建新书籍
- 查看书籍统计
布局:
┌─────────────────────────────┐
│ Books │
│ [+ 新建] │
├─────────────────────────────┤
│ ┌─────────────────────────┐ │
│ │《The Great Gatsby》 │ │
│ │📖 50词汇 ✓ 30已掌握 │ │
│ └─────────────────────────┘ │
│ │
│ ┌─────────────────────────┐ │
│ │《1984》 │ │
│ │📖 35词汇 ✓ 20已掌握 │ │
│ └─────────────────────────┘ │
└─────────────────────────────┘书籍详情页面(BookDetailPage)
路由:/books/:bookId
功能:
- 查看书籍信息和封面
- 浏览该书所有词汇
- 查看学习进度统计
布局:
┌─────────────────────────────┐
│ [←] The Great Gatsby │
├─────────────────────────────┤
│ [封面图片] │
│ F. Scott Fitzgerald │
│ │
│ 📊 学习进度: 60% (30/50) │
│ 📅 创建时间: 2026-01-05 │
├─────────────────────────────┤
│ 词汇列表 │
│ • epiphany (C2) ✓ │
│ • ephemeral (C1) ✓ │
│ • quintessential (C1) │
└─────────────────────────────┘创建书籍页面(CreateBookPage)
路由:/books/create
功能:
- 输入书名和作者
- 上传封面(可选)
- 创建新书籍记录
表单:
- 书名(必填)
- 作者(必填)
- 封面图片(可选)
书籍选择对话框(BookSelectionDialog)
触发场景:OCR识别后添加词汇时
功能:
- 选择现有书籍
- 快速创建新书籍
- 关联词汇到书籍
布局:
┌─────────────────────────────┐
│ 选择书籍 │
├─────────────────────────────┤
│ ○ The Great Gatsby │
│ ○ 1984 │
│ ○ + 创建新书籍 │
└─────────────────────────────┘词汇详情页面(VocabularyDetailPage)
路由:/vocabulary/:vocabularyId
功能:
- 显示完整词汇信息
- 播放发音(未来)
- 编辑笔记
- 标记熟练度
信息展示:
- 单词 + 音标 + 发音按钮
- 释义(英文 + 中文)
- 例句
- 来源信息
- 学习统计(添加日期、复习次数、下次复习)
统计页面(StatisticsPage)
路由:/statistics
功能:
- 学习趋势图(日/周/月)
- 词汇掌握度分布
- 学习时长统计
- 书籍统计
可视化组件:
- 折线图:学习趋势
- 饼图:掌握度分布
- 柱状图:每日学习量
设置页面(SettingsPage)
路由:/settings
功能分类:
- 学习设置:CEFR 等级、每日目标、复习提醒
- OCR 设置:OCR 引擎选择、自动裁剪、图像增强
- 界面设置:主题模式、语言
- 数据管理:导入/导出、清除缓存
3.3 页面导航流程
主流程:
首页
├─ 拍照识词 → OCR识别 → 词汇过滤 → 添加到笔记本 → 选择书籍
├─ 学习复习 → 选择书籍 → 学习会话 → 完成总结
├─ 词汇笔记本 → 词汇列表 → 词汇详情
├─ 书籍管理 → 书籍列表 → 书籍详情
└─ 统计 / 设置快速操作:
- 从任意页面快速进入拍照识词(浮动按钮)
- 底部导航栏快速切换主要功能
最后更新:2026-01-06 更新频率:架构变更时更新 文档状态:v1.1 - 添加Books书籍管理功能