Skip to content

设计文档

本文档整合了架构设计、数据模型和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 Providers

1.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
  • 数据库文件english_learning.db(唯一功能数据库)
  • 表数量:9 张(v27 删除 learning_records)
  • 词汇库架构:3 层回填
    1. 本地 vocabulary_items 表(预装词 + 回填词)
    2. Supabase 云端词汇库(3 万+ 词)
    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]│
│  🟠橙     🔵蓝      🟢绿    │
└─────────────────────────────┘

交互流程

  1. 显示单词正面(隐藏释义)
  2. 点击卡片翻转(显示释义)
  3. 选择评分(v10 改为 2-Button):
    • Hard(橙):不确定/困难 → Quality 由序列推导
    • Easy(绿):确定掌握 → Quality 由序列推导
  4. 自动进入下一张卡片
  5. 完成后显示总结

SM-2学习算法(v10 — 2-Button + 序列推导)

质量推导:根据「上一次按钮 + 本次按钮」推导 4 级 SM-2 Quality:

上次本次Quality含义
HardHard1持续困难,重置
EasyHard2退步,降低间隔
HardEasy4进步中,适度加速
EasyEasy5稳定掌握,最大加速

首次复习(无历史)默认按 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书籍管理功能