feat: Debug 模式连接本地 API + ATS 豁免 localhost
This commit is contained in:
parent
3e8c4dfa63
commit
f2f2d8b8ac
Binary file not shown.
@ -5,7 +5,11 @@
|
||||
import Foundation
|
||||
|
||||
enum APIConfig {
|
||||
#if DEBUG
|
||||
static let baseURL = "http://127.0.0.1:3000/api"
|
||||
#else
|
||||
static let baseURL = "https://api.longde.cloud/api"
|
||||
#endif
|
||||
|
||||
static let timeout: TimeInterval = 30
|
||||
|
||||
|
||||
@ -20,6 +20,11 @@
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsLocalNetworking</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
|
||||
421
docs/system-map/capabilities/01-文档阅读.md
Normal file
421
docs/system-map/capabilities/01-文档阅读.md
Normal file
@ -0,0 +1,421 @@
|
||||
# 01 文档阅读 — 跨项目完整能力分析
|
||||
|
||||
> 试点能力一:从 C 端业务能力"文档阅读"出发,跨项目完整整理。
|
||||
> 项目角色分类:主链路(iOS、Rust Document Runtime、主 API、数据库/COS)、上游支撑(Python RAG)、下游消费(Heavy Runtime)、运维可观测(Admin)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 能力目标
|
||||
|
||||
用户能够在知习 App 中流畅地阅读上传到知识库的学习资料,支持多种文件格式,自动记录阅读位置,标记已读状态,并在下次打开时从上次中断处继续阅读。
|
||||
|
||||
---
|
||||
|
||||
## 2. C 端入口
|
||||
|
||||
用户可以从以下 iOS 页面进入文档阅读:
|
||||
|
||||
| 入口页面 | 触发方式 | 进入场景 |
|
||||
|---------|---------|---------|
|
||||
| 学习主页 | 点击主操作卡片("继续上次学习") | 继续上次未读完的资料 |
|
||||
| 知识库详情页·来源 Tab | 点击来源文件条目 | 阅读知识库中的资料 |
|
||||
| 知识点详情页 | 点击"阅读原文件"或自动渲染 | 阅读知识点关联的原始资料 |
|
||||
| 学习分析页 | 点击"继续阅读"卡片 | 从分析页继续阅读 |
|
||||
| AI 反馈页 | "加入待巩固" → 学习主页 → 资料阅读 | 间接进入 |
|
||||
|
||||
在资料阅读页中,用户可以执行以下操作:
|
||||
|
||||
- 阅读内容(滚动浏览,支持 Markdown/纯文本/图片/EPUB 的原生渲染)
|
||||
- 系统预览 PDF、Word、Excel(通过 QuickLook)
|
||||
- 外部打开 PowerPoint(通过 ShareLink)
|
||||
- 标记已读(本地即时生效,marked_as_read 事件异步上报)
|
||||
- 取消标记已读(本地即时生效,服务端同步方式暂未确认)
|
||||
- 打开 AI 对话(资料范围,需 RAG 已完成向量化才能获得语义检索结果)
|
||||
- 查看资料详情(元数据、AI 处理状态、阅读进度)
|
||||
- 开始专注学习会话(主动计时)
|
||||
- 添加笔记(自动记录锚点位置)
|
||||
|
||||
---
|
||||
|
||||
## 3. 用户主流程
|
||||
|
||||
以下使用纯业务语言描述用户从进入资料到退出阅读的完整流程:
|
||||
|
||||
1. **进入资料:** 用户从知识库来源文件列表、继续学习推荐或知识点详情中点击资料,进入资料阅读页。
|
||||
|
||||
2. **资料加载:** App 检查设备上是否已有该文件。
|
||||
- 如果有本地文件:直接打开。
|
||||
- 如果没有:从云端 COS 下载文件到本地缓存目录。
|
||||
- 只要资料记录存在、用户有访问权限且 COS/本地文件可用,用户即可阅读原文件,不需要等待 Python RAG 的文本解析、分块、向量化和索引完成。
|
||||
|
||||
3. **类型检测与渲染:** 系统检测文件类型,根据类型选择渲染方式。
|
||||
- Markdown/文本/图片/EPUB:由 Rust Document Runtime 解析并渲染为可读内容。
|
||||
- PDF/Word/Excel:提供"系统预览"按钮,用户点击后使用 iOS QuickLook 预览。
|
||||
- PowerPoint:提供"外部打开"按钮,用户点击后使用系统分享功能在外部应用打开。
|
||||
- 不支持的格式:显示"暂不支持此格式"提示。
|
||||
|
||||
4. **自动阅读会话启动:** 用户进入资料阅读页时,系统自动创建阅读会话(无需用户手动操作)。iOS 调用 Rust Document Runtime 开启 V2 ReadingSession,生成唯一的 client_session_id。该会话自动推送 material_opened 事件。
|
||||
|
||||
5. **阅读位置恢复:** 系统按优先级恢复上次阅读位置。
|
||||
- 优先:从服务端 API 查询该资料的阅读进度(上次位置)。
|
||||
- 其次:从本地缓存读取上次位置。
|
||||
- 最后:从当前 Rust 阅读会话的 lastPosition 恢复。
|
||||
|
||||
6. **阅读中:** 用户滚动浏览内容。
|
||||
- 系统自动记录阅读位置(2 秒防抖,iOS 调用 Rust push_position_changed)。
|
||||
- iOS 创建并管理 15 秒心跳定时器,仅在阅读会话为 active 且 App 位于前台时触发。每次 Tick 调用 Rust heartbeat 接口,Rust 根据 ActiveTimeTracker 计算 activeSecondsDelta 后创建 heartbeat 事件并写入缓冲区。
|
||||
- Rust 不创建也不管理 iOS 的系统定时器。
|
||||
|
||||
7. **前后台切换:** 用户将 App 切到后台时,iOS 暂停心跳定时器,阅读会话自动暂停,时间跟踪停止。切回前台时自动恢复。
|
||||
|
||||
8. **标记已读:** 用户点击工具栏"标记已读"按钮。该操作在本地 UserDefaults 立即更新,同时推送 marked_as_read 事件到 Rust 缓冲区,后续通过上传链路同步至服务端。取消标记已读可在本地即时生效,但服务端同步方式暂未确认(当前事件模型只有 marked_as_read,没有 unmarked_as_read)。
|
||||
|
||||
9. **添加笔记:** 用户点击工具栏笔记按钮,弹出快速笔记 Sheet。系统自动捕获当前阅读位置作为笔记锚点。用户输入笔记文字并保存(本地 UserDefaults 存储)。
|
||||
|
||||
10. **AI 对话(资料范围):** 用户点击工具栏 AI 按钮,跳转到 AI 对话页。对话自动限定在当前资料范围内。如果 Python RAG 已完成该资料的向量化索引,AI 可通过语义检索引用资料内容回答用户问题;如果 RAG 未完成,AI 范围对话、语义检索和知识点候选提取可能暂不可用。
|
||||
|
||||
11. **开始专注学习会话:** 用户点击工具栏"开始学习"按钮,启动专注学习计时器。计时器以 1 秒精度运行,默认目标 30 分钟。该学习会话是用户主动发起的专注时段,与进入资料时自动创建的阅读会话是不同的业务对象。
|
||||
|
||||
12. **退出阅读:** 用户返回上一页或切换到其他 Tab。
|
||||
- iOS 调用 Rust close_reading_session,Rust 计算最终活跃时长增量,推送 material_closed 事件。
|
||||
- 阅读位置保存到本地缓存。
|
||||
- iOS 周期性地从 Rust 导出已缓冲事件,写入本地持久化上传队列,后续由队列负责 API 上传。
|
||||
|
||||
---
|
||||
|
||||
## 4. 项目参与关系
|
||||
|
||||
### iOS(AIStudyApp)— 主链路参与者
|
||||
|
||||
**职责:**
|
||||
- 提供资料阅读页的用户界面
|
||||
- 调用 Rust Document Runtime(通过 UniFFI FFI)进行文件解析
|
||||
- 管理 COS 文件下载和本地文件缓存
|
||||
- 驱动自动阅读会话生命周期(调用 Rust V2 Session API)
|
||||
- 创建并管理 15 秒心跳定时器(仅在 session active 且前台时触发)
|
||||
- 驱动阅读事件采集(调用 Rust push 函数 + heartbeat 接口)
|
||||
- 管理本地上传队列:将 Rust 导出事件映射为 UploadItem、写入持久化队列、确认 Rust 交接完成
|
||||
- 管理阅读位置本地缓存
|
||||
- 提供系统预览和外部打开能力
|
||||
- 提供笔记创建界面和本地存储
|
||||
- 提供标记已读本地缓存
|
||||
- 前台/后台切换时管理会话暂停/恢复和心跳定时器启停
|
||||
- App 被杀死后重启时执行崩溃恢复
|
||||
|
||||
### Rust Document Runtime(zhixi-document-runtime)— 主链路参与者
|
||||
|
||||
**职责:**
|
||||
- 检测文件类型(根据扩展名和文件内容推断 MaterialType)
|
||||
- 解析 Markdown 为结构化文档块树
|
||||
- 解析纯文本为段落块
|
||||
- 提取 EPUB 章节结构和元数据
|
||||
- 提取 PDF 页数和基本文本(用于搜索)
|
||||
- 提取图片元数据
|
||||
- 管理自动阅读会话(V2 ReadingSession:start、pause、resume、close、interrupt)
|
||||
- 管理阅读事件缓冲区(push、export、ack、reload)
|
||||
- 根据 ActiveTimeTracker 计算 activeSecondsDelta(由 iOS heartbeat tick 触发)
|
||||
- 提供阅读位置模型
|
||||
- 提供文件搜索能力
|
||||
- 提供笔记锚点模型
|
||||
- 提供活跃时间跟踪器
|
||||
- 提供崩溃恢复机制(stale event reload、stale session cleanup)
|
||||
|
||||
**不负责:** 网络请求、COS 下载、API 调用、用户认证、UI 渲染、Office 文件高清预览、PDF 完整渲染、iOS 系统定时器创建和管理。
|
||||
|
||||
### 主 API(api-server)— 主链路参与者
|
||||
|
||||
**职责:**
|
||||
- 提供资料信息查询
|
||||
- 提供文件下载 URL(COS 预签名 URL)
|
||||
- 提供资料阅读进度查询
|
||||
- 接收并处理阅读事件批量上传
|
||||
- 将原始阅读事件聚合为:自动阅读会话(LearningSession)、资料阅读进度、每日学习活动、学习记录
|
||||
- 提供文件上传 URL
|
||||
- 管理知识源的三个处理状态(parseStatus、indexStatus、learningStatus)
|
||||
- 提供继续学习推荐
|
||||
- 提供学习摘要
|
||||
- 提供阅读趋势
|
||||
|
||||
### Python RAG Worker — 上游支撑
|
||||
|
||||
**不直接参与文档阅读。** 只要资料记录、文件访问权限和 COS/本地文件可用,用户即可阅读原文件。Python RAG 负责文档导入后的异步处理(下载上传的文件 → 解析文本内容 → 分块 → 向量化嵌入 → 存入 Qdrant → AI 提取候选知识点)。RAG 未完成时,阅读原文件不受影响,但资料范围 AI 问答的语义检索和知识点候选提取可能暂不可用。
|
||||
|
||||
### Heavy Runtime — 下游数据消费者
|
||||
|
||||
**不直接参与文档阅读。** 消费已聚合的阅读数据,生成 AI 分析结果(掌握度评估、薄弱点识别、学习建议、测验题目、闪卡)。位于阅读数据采集链的下游,不属于用户阅读时的同步调用链。
|
||||
|
||||
### Admin(admin-projects)— 运维与可观测
|
||||
|
||||
**不属于用户阅读时的同步调用链。** 职责包括:
|
||||
- 知识库来源文件列表查看
|
||||
- 来源文件详情查看(含解析状态、索引状态)
|
||||
- 文件管理(查看、删除上传文件)
|
||||
- 资料阅读进度查看
|
||||
- 资料诊断
|
||||
- 文档导入监控与重试
|
||||
|
||||
---
|
||||
|
||||
## 5. 项目间调用关系
|
||||
|
||||
### 5.1 iOS → Rust Document Runtime
|
||||
|
||||
| 调用目的 | 调用方向 | 业务结果 |
|
||||
|---------|---------|---------|
|
||||
| 检测文件类型 | iOS → Rust | 返回 MaterialType 和 PreviewMode 建议 |
|
||||
| 解析 Markdown/文本文件 | iOS → Rust | 返回 DocumentBlock 数组 |
|
||||
| 提取 EPUB/PDF/图片信息 | iOS → Rust | 返回对应元数据 |
|
||||
| 搜索文档内容 | iOS → Rust | 返回 SearchResult 列表 |
|
||||
| 开启自动阅读会话 | iOS → Rust | 创建 V2 ReadingSession,返回 client_session_id |
|
||||
| 推送阅读事件 | iOS → Rust | 事件进入内存缓冲区(Pending 状态) |
|
||||
| 心跳 Tick | iOS → Rust | Rust 计算 activeSecondsDelta,创建 heartbeat 事件写入缓冲区 |
|
||||
| 导出待交接事件 | iOS → Rust | 返回 Exported 状态的事件列表,交接给 iOS |
|
||||
| 确认事件交接完成 | iOS → Rust | 已 Ack 的事件从 Rust 缓冲区移除(交接给 iOS 本地队列后立即调用) |
|
||||
| 崩溃恢复 | iOS → Rust | Exported 未 Ack 事件重置为 Pending |
|
||||
| 清理过期会话 | iOS → Rust | 超时会话标记为 Interrupted 并从内存移除 |
|
||||
|
||||
### 5.2 iOS → 主 API
|
||||
|
||||
| 调用目的 | 调用方向 | 业务结果 |
|
||||
|---------|---------|---------|
|
||||
| 获取文件下载 URL | iOS → API | 返回 COS 预签名下载链接 |
|
||||
| 查询阅读进度 | iOS → API | 返回上次阅读位置、累计阅读时长、是否已读 |
|
||||
| 上传阅读事件批次 | iOS → API | 从 iOS 本地持久化队列发起,返回 processed/duplicate/failed 计数 |
|
||||
| 查询继续学习 | iOS → API | 返回最近阅读的资料信息 |
|
||||
| 查询学习摘要/趋势 | iOS → API | 返回聚合数据 |
|
||||
| 查询资料信息 | iOS → API | 返回知识源详情 |
|
||||
|
||||
### 5.3 主 API 内部调用
|
||||
|
||||
| 调用目的 | 调用方向 | 业务结果 |
|
||||
|---------|---------|---------|
|
||||
| 阅读事件处理 | API 内部(同步事务) | 事件入库 → 聚合自动阅读会话 → 聚合阅读进度 → 聚合每日活动 → 创建学习记录 |
|
||||
| 资料解析触发 | API → Redis 队列 | 将资料加入 document-import 队列,由 Python RAG Worker 异步处理(不阻塞阅读) |
|
||||
|
||||
### 5.4 Admin → 主 API(运维可观测,非同步调用链)
|
||||
|
||||
| 调用目的 | 调用方向 | 业务结果 |
|
||||
|---------|---------|---------|
|
||||
| 查看知识库来源文件 | Admin → API | 返回来源文件列表(含解析和索引状态) |
|
||||
| 查看/删除文件 | Admin → API | 文件管理 |
|
||||
| 查看资料阅读进度 | Admin → API | 阅读进度详情 |
|
||||
| 资料诊断 | Admin → API | 全部阅读数据和关联会话 |
|
||||
| 文档导入监控/重试 | Admin → API | 导入任务列表、重试失败任务 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 核心业务数据
|
||||
|
||||
### 6.1 资料(Material / KnowledgeSource)
|
||||
|
||||
- **谁创建:** iOS 用户在导入资料页或添加知识点页上传文件后,API 创建 KnowledgeSource 记录。
|
||||
- **谁更新:** Python RAG Worker 更新解析状态和索引状态(异步,不阻塞阅读);API 在处理阅读事件时更新关联的阅读状态。
|
||||
- **谁查询:** iOS 在知识库详情页来源 Tab 查询列表、在资料详情页查询详情;Admin 在来源文件页查询列表。
|
||||
- **用于什么功能:** 知识库内容组织、文档阅读入口、资料处理状态展示。
|
||||
|
||||
### 6.2 阅读位置(ReadingPosition)
|
||||
|
||||
- **谁创建:** Rust Document Runtime 在 iOS 推送 position_changed 事件时创建。
|
||||
- **谁更新:** 每次用户滚动时更新(2 秒防抖),由 Rust Document Runtime 维护 last_position。
|
||||
- **谁查询:** iOS 在进入阅读页时恢复上次位置(优先 API、其次本地缓存、最后会话位置);API 在阅读进度查询时返回。
|
||||
- **用于什么功能:** 跨会话的阅读位置恢复、"继续学习"推荐。
|
||||
|
||||
### 6.3 自动阅读会话(ReadingSession,Rust V2)
|
||||
|
||||
- **谁创建:** Rust Document Runtime 在 iOS 调用 start_reading_session 时创建(用户进入资料阅读页时自动触发,无需用户手动操作)。
|
||||
- **谁更新:** Rust 在每次事件推送时更新内存中的会话状态(lastEventAt、totalActiveSeconds、lastPosition)。
|
||||
- **谁查询:** iOS 在恢复会话时查询 lastPosition 用于位置恢复。
|
||||
- **用于什么功能:** 自动追踪单次阅读行为的持续时长和事件序号,管理阅读会话生命周期(active→paused→closed)。产生 opened、closed、position_changed、heartbeat、marked_as_read 事件。
|
||||
|
||||
### 6.4 专注学习会话(LearningSessionView 计时)
|
||||
|
||||
- **谁创建:** 用户主动点击资料阅读页工具栏"开始学习"按钮后,iOS 创建本地计时器。
|
||||
- **谁更新:** 用户操作暂停/继续/结束(含确认弹窗),计时器以 1 秒精度运行,默认目标 30 分钟。
|
||||
- **谁查询:** iOS 学习会话页展示当前进度。
|
||||
- **用于什么功能:** 用户主动发起的专注学习时段计时。**与自动阅读会话(ReadingSession)是不同的业务对象。** 当前 iOS 是否调用专注学习会话 API(LearningSessionService)持久化仍标记为"暂未确认"。
|
||||
|
||||
### 6.5 阅读事件(ReadingEvent)
|
||||
|
||||
- **谁创建:** Rust Document Runtime 创建(5 种事件类型:material_opened、material_closed、position_changed、heartbeat、marked_as_read)。
|
||||
- **谁更新:** 事件创建后不可修改。API 更新其处理状态(processing → processed/failed/duplicate)。
|
||||
- **谁查询:** API 在批处理时查重;Admin 在阅读事件列表和异常检测页查询。
|
||||
- **用于什么功能:** 所有学习分析的原始数据源。API 根据事件聚合自动阅读会话、阅读进度、每日活动、学习记录。
|
||||
|
||||
### 6.6 资料阅读进度(MaterialReadingProgress)
|
||||
|
||||
- **谁创建:** API 在收到该资料的第一个阅读事件时自动创建。
|
||||
- **谁更新:** API 在每次事件处理事务中 upsert(递增总时长、更新最后位置、更新会话数、标记已读状态)。
|
||||
- **谁查询:** iOS 在进入阅读页时查询(恢复位置);Admin 在阅读进度页查询。
|
||||
- **用于什么功能:** 资料级别的阅读进度追踪、"继续学习"推荐的数据源、阅读统计。
|
||||
|
||||
### 6.7 笔记(QuickNote)
|
||||
|
||||
- **谁创建:** iOS 用户在快速笔记 Sheet 中输入并保存时创建。
|
||||
- **谁更新:** 当前不支持修改(仅创建和删除)。
|
||||
- **谁查询:** iOS 在资料阅读页和知识点详情页查询(本地 UserDefaults)。
|
||||
- **用于什么功能:** 阅读过程中的快速记录。当前仅本地存储,未同步到服务端。
|
||||
|
||||
---
|
||||
|
||||
## 7. 查询入口
|
||||
|
||||
### 用户在哪里查看
|
||||
|
||||
- **阅读内容:** iOS 资料阅读页直接渲染文档内容。
|
||||
- **阅读进度:** iOS 资料详情页的阅读进度卡片(累计时长、阅读状态、上次阅读时间)。
|
||||
- **资料信息:** iOS 资料详情页(文件名、格式、大小、上传日期、AI 处理状态)。
|
||||
- **来源文件列表:** iOS 知识库详情页的来源 Tab。
|
||||
- **继续阅读:** iOS 学习主页的主操作卡片(继续上次学习)。
|
||||
|
||||
### Admin 在哪里查看(运维可观测)
|
||||
|
||||
- **来源文件列表:** Admin 知识库→来源文件页(含解析状态、索引状态)。
|
||||
- **文件管理:** Admin 文件与 COS 管理页(按类型筛选、查看详情、删除)。
|
||||
- **阅读进度:** Admin 学习数据→阅读进度页(按用户/资料查看进度)。
|
||||
- **资料诊断:** Admin 学习数据→资料诊断页。
|
||||
- **导入监控:** Admin 知识库→文档导入监控页(任务状态、步骤日志、重试)。
|
||||
|
||||
### 系统内部在哪里使用
|
||||
|
||||
- **继续学习推荐:** API GET /learning/continue → iOS 学习主页优先级算法。
|
||||
- **学习摘要:** API GET /learning/summary → iOS 分析页 + 学习主页每周摘要。
|
||||
- **阅读趋势:** API GET /learning/trend → iOS 分析页阅读时长趋势图。
|
||||
- **学习记录:** API GET /learning/records → iOS 分析页最近学习记录。
|
||||
- **资料范围 AI 问答:** API 在 RAG 对话中根据资料范围检索相关 Chunk(依赖 Python RAG 的向量化结果;RAG 未完成时不可用)。
|
||||
|
||||
---
|
||||
|
||||
## 8. 修改入口
|
||||
|
||||
### 用户主动修改
|
||||
|
||||
- **标记已读:** iOS 资料阅读页工具栏按钮。本地 MarkedReadStore 即时生效,marked_as_read 事件通过事件采集链路上报。服务端同步已完成。
|
||||
- **取消标记已读:** 本地 MarkedReadStore 即时生效。服务端同步方式暂未确认(当前事件模型无 unmarked_as_read 事件类型)。
|
||||
- **添加笔记:** iOS 快速笔记 Sheet(本地 UserDefaults 存储)。
|
||||
- **删除来源文件:** iOS 知识库详情页来源 Tab 滑动删除(API 软删除)。
|
||||
- **开始/结束专注学习会话:** iOS 资料阅读页工具栏学习按钮 / 学习会话页结束按钮。
|
||||
- **上传新资料:** iOS 导入资料页(文件/相册/链接)。
|
||||
|
||||
### Admin 人工修改(运维可观测)
|
||||
|
||||
- **删除文件:** Admin 文件管理页删除上传文件。
|
||||
- **重试导入:** Admin 文档导入监控页重试失败任务。
|
||||
- **重新解析:** Admin 可触发知识源的重新解析。
|
||||
|
||||
### 系统自动修改
|
||||
|
||||
- **阅读位置更新:** iOS 2 秒防抖自动调用 Rust push_position_changed。
|
||||
- **心跳:** iOS 15 秒定时器 Tick → 调用 Rust heartbeat 接口 → Rust 计算 activeSecondsDelta 并创建事件。
|
||||
- **阅读会话状态切换:** iOS 前后台切换时自动暂停/恢复 Rust ReadingSession,同步控制心跳定时器。
|
||||
- **阅读进度聚合:** API 在每次事件处理事务中自动更新 MaterialReadingProgress。
|
||||
- **会话中断检测:** API 在事件处理前自动清理 30 分钟无新事件的活跃会话(标记为 interrupted)。
|
||||
- **解析状态更新:** Python RAG Worker 异步更新 KnowledgeSource 的 parseStatus(不阻塞阅读)。
|
||||
- **文件过期处理:** API 自动检测临时资料是否过期。
|
||||
|
||||
### 系统配置修改
|
||||
|
||||
- **文件大小限制:** API 配置(待确认具体配置入口)。
|
||||
- **COS 预签名 URL 有效期:** API 文件上传服务配置。
|
||||
- **解析触发轮询间隔:** iOS 端硬编码(60×2s),非配置化。
|
||||
|
||||
---
|
||||
|
||||
## 9. 异常与恢复
|
||||
|
||||
### 9.1 文件加载失败
|
||||
|
||||
- **场景:** 本地文件不存在或 COS 下载失败。
|
||||
- **iOS 处理:** 资料阅读页进入错误状态,显示错误提示和重试按钮。自动尝试从 COS 重新下载。
|
||||
- **API 处理:** 文件下载 URL 返回 COS 预签名链接,含过期时间。过期后 iOS 需重新请求。
|
||||
|
||||
### 9.2 解析失败
|
||||
|
||||
- **场景:** 文件内容损坏、格式不支持、或解析器报错。
|
||||
- **iOS 处理:** 资料阅读页显示"暂不支持此格式"或错误提示。
|
||||
- **API 处理:** Python RAG Worker 解析失败时更新 DocumentImport 状态为 FAILED,记录错误步骤。Admin 可查看步骤日志并重试。解析失败不影响用户阅读原文件。
|
||||
|
||||
### 9.3 网络中断
|
||||
|
||||
- **场景:** 阅读过程中网络断开。
|
||||
- **iOS 处理:** Rust Document Runtime 继续在本地采集事件,事件缓冲区正常运行。iOS 本地持久化队列中的事件暂停上传,NetworkMonitor 检测到网络恢复后自动触发队列 flush。阅读会话继续,心跳和位置事件照常写入 Rust 缓冲区。
|
||||
|
||||
### 9.4 App 被关闭(强制杀死或系统回收)
|
||||
|
||||
- **场景:** 用户在阅读过程中 App 被系统杀死或用户强制关闭。
|
||||
- **iOS 处理(App 重新启动时):**
|
||||
1. RuntimeRecoveryService.run() 执行崩溃恢复
|
||||
2. Rust reload_stale_events_v2:所有 Exported 但未 Ack 的事件重置为 Pending(处理 export 后、本地写入前崩溃的场景)
|
||||
3. Rust cleanup_stale_sessions_v2:清理超过 24 小时的非活跃会话
|
||||
4. iOS 本地队列 reloadOnLaunch:重新从 Rust 导出事件、映射为 UploadItem、写入持久化队列、立即 Ack。已持久化但未上传的队列条目继续上传。
|
||||
5. 服务器端:API 在下次处理事件前,清理超过 30 分钟的活跃会话(标记为 interrupted)
|
||||
|
||||
### 9.5 Export/Ack 链路中的三种崩溃场景
|
||||
|
||||
- **export 后、本地写入前崩溃:** Rust reload_stale_events_v2 将 Exported 事件重置为 Pending,下次启动重新导出。
|
||||
- **本地写入成功、Ack 前崩溃:** 重新启动后重新导出,API 端通过 eventId 去重(已在队列中的重复事件不会产生重复数据),iOS 再调用 Ack 完成交接。
|
||||
- **Ack 后、API 上传前崩溃:** 事件已从 Rust 缓冲区安全交接至 iOS 本地持久化队列。重启后本地队列继续上传,Rust 不需要再参与。
|
||||
|
||||
### 9.6 阅读位置恢复失败
|
||||
|
||||
- **场景:** API 未返回阅读进度(首次打开)或本地缓存丢失。
|
||||
- **iOS 处理:** 三级回退——API 位置 → 本地缓存位置 → Rust 会话位置 → 从头开始。
|
||||
|
||||
### 9.7 事件上传失败
|
||||
|
||||
- **场景:** 上传请求返回错误或超时。上传完全由 iOS 本地持久化队列负责,失败时不再调用 Rust markFailed。
|
||||
- **iOS 本地队列处理:**
|
||||
- 401 错误:暂停队列(保留 pending 状态),等待 Token 刷新
|
||||
- 403/404 错误:标记条目为永久失败(dead)
|
||||
- 其他错误:标记条目为 failed,进入指数退避重试(5s × 2^n,最多 3 次,最长 5 分钟)
|
||||
- 重试次数耗尽:条目进入 dead 状态,不再重试
|
||||
- **API 处理:**
|
||||
- 重复事件(相同 userId + eventId):标记为 duplicate,返回已处理
|
||||
- 验证失败(无效类型/超限/无权限):标记为 failed,返回错误码
|
||||
- 材料不存在:标记为 failed
|
||||
|
||||
### 9.8 资料被删除或失去权限
|
||||
|
||||
- **场景:** 用户正在阅读的资料被管理员删除或用户失去访问权限。
|
||||
- **API 处理:** 事件处理时校验材料存在性、归属性和状态。不存在的材料标记事件为 failed;无权限的标记为 failed;已过期的临时材料标记为 failed。
|
||||
- **iOS 处理:** 当前的阅读会话仍可继续(本地文件未被删除),但后续事件上传将被拒绝。
|
||||
|
||||
---
|
||||
|
||||
## 10. 当前完成情况
|
||||
|
||||
统一使用以下口径:
|
||||
- **已完成:** 跨项目链路已接通,用户可以获得最终结果。
|
||||
- **部分完成:** 只有部分项目、部分页面或部分场景完成。
|
||||
- **占位实现:** 存在结构,但使用 Mock、硬编码或静态数据。
|
||||
- **暂未确认:** 无法确认完整调用链。
|
||||
|
||||
| 组件 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| iOS 多格式渲染(Markdown/文本/图片/EPUB) | 已完成 | Rust FFI 解析 + SwiftUI 渲染 |
|
||||
| iOS 系统预览(PDF/Word/Excel/PPT) | 已完成 | QuickLook + ShareLink |
|
||||
| iOS 阅读位置记录与恢复 | 已完成 | 三级优先级(API→本地→会话) |
|
||||
| iOS 标记已读(服务端同步) | 已完成 | 本地 UserDefaults + marked_as_read 事件上报链路已接通 |
|
||||
| iOS 取消标记已读(服务端同步) | 暂未确认 | 本地即时生效,但当前事件模型无 unmarked_as_read,API 是否支持待确认 |
|
||||
| iOS 自动阅读会话管理 | 已完成 | Rust V2 ReadingSession(含前后台自动切换) |
|
||||
| iOS 专注学习会话计时 | 暂未确认 | 本地计时已完成,API 持久化调用待确认 |
|
||||
| iOS 快速笔记 | 已完成 | 锚点记录,本地 UserDefaults 存储 |
|
||||
| iOS 15 秒心跳定时器 | 已完成 | iOS 创建 Timer,仅在 session active 且前台时触发 |
|
||||
| Rust Document Runtime 文件解析 | 已完成 | 9 种 MaterialType 检测 + Markdown/文本/EPUB/图片/PDF 基础解析 |
|
||||
| Rust Document Runtime V2 自动阅读会话 | 已完成 | 完整生命周期 + 5 种事件类型 + 缓冲区管理 |
|
||||
| Rust 活跃时间跟踪器 | 已完成 | ActiveTimeTracker,由 iOS heartbeat tick 驱动 |
|
||||
| Rust 崩溃恢复 | 已完成 | stale event reload + stale session cleanup |
|
||||
| Rust → iOS 事件交接链路 | 已完成 | export → 本地队列写入 → Ack(交接在本地完成,不依赖网络) |
|
||||
| iOS 本地上传队列 | 已完成 | JSON 持久化,独立于 Rust 缓冲区的网络上传队列 |
|
||||
| iOS 上传重试与网络恢复 | 已完成 | 指数退避重试 + NetworkMonitor 自动恢复 |
|
||||
| API 文件上传与下载 | 已完成 | COS 预签名 URL 流程 |
|
||||
| API 阅读事件处理管线 | 已完成 | 去重→验证→事件入库→自动阅读会话聚合→进度聚合→每日活动→学习记录 |
|
||||
| API 阅读进度查询 | 已完成 | GET /materials/:id/reading-progress |
|
||||
| API 继续学习推荐 | 已完成 | 最近的未读完资料 |
|
||||
| Admin 来源文件查看 | 已完成 | 列表+筛选+解析状态(运维可观测) |
|
||||
| Admin 资料诊断 | 已完成 | material-diagnose 端点(运维可观测) |
|
||||
| Admin 阅读进度查看 | 已完成 | 列表+详情(运维可观测) |
|
||||
| 原文件阅读(不依赖 RAG) | 已完成 | 只要资料记录+权限+COS/本地文件可用即可阅读 |
|
||||
| 资料范围 AI 问答(依赖 RAG) | 部分完成 | 需 RAG 完成向量化后才可用;RAG 未完成时语义检索不可用 |
|
||||
| iOS 解析触发轮询 | 部分完成 | 使用硬编码 60×2s 轮询,非事件驱动 |
|
||||
| 笔记服务端同步 | 未完成 | 当前仅本地 UserDefaults 存储 |
|
||||
| Office 文件高清预览 | 暂未确认 | Word/Excel/PPT 依赖系统预览或外部打开,无内置高清渲染 |
|
||||
444
docs/system-map/capabilities/02-学习信息收集.md
Normal file
444
docs/system-map/capabilities/02-学习信息收集.md
Normal file
@ -0,0 +1,444 @@
|
||||
# 02 学习信息收集 — 跨项目完整能力分析
|
||||
|
||||
> 试点能力二:从 C 端业务能力"学习信息收集"出发,跨项目完整整理。
|
||||
> 项目角色分类:主链路(iOS、Rust Document Runtime、主 API、数据库)、上游支撑(无直接上游)、下游消费(Heavy Runtime)、运维可观测(Admin)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 能力目标
|
||||
|
||||
自动采集用户在学习过程中的所有行为数据(阅读行为、学习时长、阅读位置、标记已读等),经过 Rust 内存缓冲、iOS 本地持久化队列、批量上传、服务端去重验证、聚合计算后,为学习分析、继续学习推荐提供数据基础。
|
||||
|
||||
---
|
||||
|
||||
## 2. C 端入口
|
||||
|
||||
学习信息收集是一个**用户不可见的自动能力**。用户不需要主动触发,系统在以下场景自动采集:
|
||||
|
||||
| 触发场景 | 收集的数据 | iOS 页面 | 驱动方式 |
|
||||
|---------|-----------|---------|---------|
|
||||
| 用户打开一份资料 | material_opened 事件 | 资料阅读页 | iOS 调用 Rust push |
|
||||
| 用户滚动阅读内容 | position_changed 事件(2 秒防抖) | 资料阅读页 | iOS 调用 Rust push |
|
||||
| iOS 15 秒定时器触发 | heartbeat 事件 | 资料阅读页(自动) | iOS Timer → Rust heartbeat 接口 |
|
||||
| 用户关闭/离开资料 | material_closed 事件 | 资料阅读页(自动) | iOS 调用 Rust close → push |
|
||||
| 用户点击"标记已读" | marked_as_read 事件 | 资料阅读页 | iOS 调用 Rust push |
|
||||
| 用户开始专注学习 | 学习会话计时开始 | 学习会话页 | iOS 本地计时器(用户主动触发) |
|
||||
|
||||
用户在分析页和学习主页**消费**这些数据的结果,但数据采集本身是透明的。
|
||||
|
||||
---
|
||||
|
||||
## 3. 用户主流程
|
||||
|
||||
### 3.1 数据采集阶段(iOS + Rust Document Runtime)
|
||||
|
||||
1. 用户打开资料进入阅读页。iOS 调用 Rust start_reading_session,Rust 创建 V2 自动阅读会话,生成唯一的 client_session_id。iOS 调用 Rust push_material_opened,事件进入 Rust 内存缓冲区(Pending)。
|
||||
|
||||
2. 阅读过程中:
|
||||
- 用户滚动时,iOS 以 2 秒防抖调用 Rust push_position_changed。
|
||||
- iOS 创建并管理 15 秒心跳定时器。仅在阅读会话为 active 且 App 位于前台时触发。每次 Tick,iOS 调用 Rust heartbeat 接口,Rust 根据 ActiveTimeTracker 计算 activeSecondsDelta,创建 heartbeat 事件并写入缓冲区。
|
||||
- Rust 不创建也不管理 iOS 的系统定时器。
|
||||
|
||||
3. 用户点击"标记已读",iOS 本地更新 MarkedReadStore,同时调用 Rust push_marked_as_read。
|
||||
|
||||
4. 用户离开资料,iOS 调用 Rust close_reading_session,Rust 计算最终活跃时长增量,推送 material_closed 事件。
|
||||
|
||||
### 3.2 Rust 内存缓冲与交接阶段(Rust → iOS 本地队列)
|
||||
|
||||
5. 所有事件暂存在 Rust 内存缓冲区中,状态为 Pending。
|
||||
|
||||
6. iOS 周期性地调用 Rust export_pending_events_v2 导出事件(事件状态变为 Exported)。**Rust 缓冲区不是网络上传队列**——导出仅完成从 Rust 到 iOS 的内存交接。
|
||||
|
||||
7. iOS 将导出的原始事件映射为 UploadItem(补充 knowledgeBaseId、platform、appVersion、timezone 等元数据)。
|
||||
|
||||
8. iOS 将 UploadItem 成功写入持久化 ReadingEventUploadQueue(JSON 文件)后,**立即**调用 Rust ack_events_v2。Rust 从内存缓冲区删除已完成交接的事件。
|
||||
|
||||
9. 后续 API 上传完全由 iOS 本地持久化队列负责。API 上传失败时,只更新本地队列条目的 failed/dead/retry 状态,不再调用 Rust markFailed。
|
||||
|
||||
### 3.3 上传阶段(iOS 本地持久化队列 → API)
|
||||
|
||||
10. iOS 上传队列定期调用 flush,从本地持久化队列中取出事件,批量 POST /learning/reading-events/batch(每批最多 100 条)。
|
||||
11. 上传中的条目状态为 uploading。API 上传成功后,从 iOS 本地队列删除该条目记录。
|
||||
12. 上传失败时:
|
||||
- 401(未授权):暂停队列(保留 pending),等待 Token 刷新
|
||||
- 403/404(禁止/不存在):标记条目为永久失败(dead)
|
||||
- 其他错误:标记条目为 failed,进入指数退避重试(5s × 2^n,最多 3 次,最长 5 分钟)
|
||||
- 重试耗尽:条目进入 dead 状态
|
||||
|
||||
### 3.4 崩溃恢复的三种场景
|
||||
|
||||
13. **export 后、本地写入前崩溃:** Rust reload_stale_events_v2 将所有 Exported 未 Ack 事件重置为 Pending。下次启动重新导出。
|
||||
14. **本地写入成功、Ack 前崩溃:** 重新启动后从 Rust 重新导出(含已持久化但未 Ack 的事件)。API 端通过 eventId 去重。iOS 再次 Ack 完成交接。
|
||||
15. **Ack 后、API 上传前崩溃:** 事件已安全在 iOS 本地持久化队列中,Rust 不再参与。重启后本地队列继续上传。
|
||||
|
||||
### 3.5 服务端处理阶段(API)
|
||||
|
||||
16. API 收到事件批次后,逐条处理每个事件。单条事件处理在一个数据库事务中完成:
|
||||
- **验证:** 校检事件类型、目标类型、活跃时长(上限 300 秒)、时间戳。
|
||||
- **去重:** 检查 userId + eventId 是否已处理,已处理的标记为 duplicate。
|
||||
- **权限校验:** 验证材料存在、属于当前用户、未删除、未过期。
|
||||
- **事件入库:** 插入 ReadingEvent 行。
|
||||
- **自动阅读会话聚合:** Upsert LearningSession(按 clientSessionId,增量累加 totalActiveSeconds)。
|
||||
- **进度聚合:** Upsert MaterialReadingProgress(按 userId+materialId)。
|
||||
- **每日活动聚合:** Upsert DailyLearningActivity(按 userId+localDate,时区感知)。
|
||||
- **学习记录:** 为里程碑事件(opened/closed/marked_as_read)插入 LearningRecord。
|
||||
- **标记完成:** 事件 status 更新为 processed。
|
||||
|
||||
### 3.6 数据消费阶段(iOS 查询)
|
||||
|
||||
17. 用户在分析页和学习主页看到的结果:
|
||||
- **继续学习:** GET /learning/continue → 最近未读完的资料。
|
||||
- **学习摘要:** GET /learning/summary → 今日/本周/总计分钟、活跃天数。
|
||||
- **阅读趋势:** GET /learning/trend?days=7 → 每日阅读时长序列。
|
||||
- **连续天数:** GET /activity/streak → 当前连续、最长连续。
|
||||
- **活动摘要:** GET /activity/summary → 总分钟、复习卡片、活跃天、日均。
|
||||
- **学习记录:** GET /learning/records → 分页学习记录列表。
|
||||
|
||||
---
|
||||
|
||||
## 4. 项目参与关系
|
||||
|
||||
### iOS(AIStudyApp)— 主链路参与者
|
||||
|
||||
**职责:**
|
||||
- 驱动 Rust Document Runtime 的自动阅读会话和事件采集
|
||||
- 创建并管理 15 秒心跳定时器(仅在 session active 且前台时触发,每次 Tick 调用 Rust heartbeat 接口)
|
||||
- 管理阅读位置本地缓存和标记已读本地缓存
|
||||
- 管理本地上传队列(独立于 Rust 缓冲区的网络上传队列):事件映射、JSON 持久化、重试策略、从队列删除已上传条目
|
||||
- Rust → iOS 事件交接:export → UploadItem 映射 → 持久化写入 → **立即 Ack**(不等待 API 上传)
|
||||
- 提供网络恢复自动上传(NetworkMonitor 监听)
|
||||
- 崩溃恢复:App 重启时调用 RuntimeRecoveryService
|
||||
- 提供专注学习会话页的本地计时
|
||||
- 查询并展示学习分析数据
|
||||
|
||||
### Rust Document Runtime(zhixi-document-runtime)— 主链路参与者
|
||||
|
||||
**职责:**
|
||||
- V2 自动阅读会话管理(start/pause/resume/close/interrupt)
|
||||
- 活跃时间跟踪器(ActiveTimeTracker),由 iOS heartbeat tick 驱动计算 activeSecondsDelta
|
||||
- 5 种阅读事件类型的创建和推送(opened/closed/position_changed/heartbeat/marked_as_read)
|
||||
- 事件内存缓冲区管理(Pending → Exported 状态机)
|
||||
- 事件导出(export_pending_events_v2):将事件从内存交接给 iOS
|
||||
- 事件确认(ack_events_v2):iOS 本地持久化写入成功后立即调用,Rust 删除已交接事件
|
||||
- 崩溃恢复:stale event reload(Exported → Pending)、stale session cleanup
|
||||
- 缓冲区容量管理(最大 1000 条,溢出时按优先级淘汰)
|
||||
- 阅读位置模型
|
||||
|
||||
**不负责:** 网络请求、API 调用、事件上传、iOS 系统定时器创建和管理。
|
||||
|
||||
### 主 API(api-server)— 主链路参与者
|
||||
|
||||
**职责:**
|
||||
- 接收阅读事件批量上传(POST /learning/reading-events/batch,每批最多 100 条)
|
||||
- 单条事件处理管线(验证→去重→权限→入库→聚合→记录→标记)
|
||||
- 事件去重(userId + eventId 唯一约束)
|
||||
- 自动阅读会话聚合(按 clientSessionId upsert,自动处理 completed/interrupted 状态)
|
||||
- 资料阅读进度聚合(按 userId + materialId upsert)
|
||||
- 每日学习活动聚合(按 userId + localDate upsert,时区感知)
|
||||
- 学习记录创建(里程碑事件记录)
|
||||
- 异常检测和警告代码
|
||||
- 提供学习数据查询端点(/learning/*, /activity/*)
|
||||
- 提供内部管理端点(事件重放、失败事件重处理)
|
||||
|
||||
### Heavy Runtime — 下游数据消费者
|
||||
|
||||
**不直接参与学习信息收集。** 消费已聚合的学习数据,生成 AI 分析结果(掌握度评估、薄弱点识别、学习建议、测验题目、闪卡)。位于数据采集链的下游,不属于学习信息采集链路。
|
||||
|
||||
### Python RAG Worker — 上游支撑(不直接参与)
|
||||
|
||||
**不直接参与学习信息收集。** 负责文档导入后的预处理(解析→分块→嵌入→索引),产生的知识库结构化数据是阅读的前提,但不参与阅读行为的采集、传输和聚合。
|
||||
|
||||
### Admin(admin-projects)— 运维与可观测
|
||||
|
||||
**不属于学习信息采集链路的同步环节。** 职责包括:
|
||||
- 学习数据总览仪表板
|
||||
- 阅读事件/会话/进度/活动/记录查询
|
||||
- 用户时间线与诊断
|
||||
- 异常数据页(失败/警告/重复事件)
|
||||
- 事件重放(单条 + 批量)
|
||||
- 学习数据重算
|
||||
- 数据导出
|
||||
|
||||
---
|
||||
|
||||
## 5. 项目间调用关系
|
||||
|
||||
### 5.1 数据采集链路(iOS → Rust Document Runtime)
|
||||
|
||||
| 调用目的 | 方向 | 业务结果 |
|
||||
|---------|------|---------|
|
||||
| 开启自动阅读会话 | iOS → Rust | 创建 V2 ReadingSession,返回 client_session_id |
|
||||
| 推送阅读事件(opened/closed/position_changed/marked_as_read) | iOS → Rust | 事件进入内存缓冲区(Pending) |
|
||||
| 心跳 Tick | iOS → Rust | Rust 计算 activeSecondsDelta,创建 heartbeat 事件写入缓冲区 |
|
||||
| 活跃时间累计 | iOS → Rust | ActiveTimeTracker 由 iOS heartbeat tick 驱动,暂停时停止 |
|
||||
| 导出待交接事件 | iOS → Rust | 返回 Exported 状态的事件列表 |
|
||||
| 确认事件交接完成 | iOS → Rust | iOS 本地队列写入成功后立即 Ack,Rust 删除已交接事件 |
|
||||
| 崩溃恢复 | iOS → Rust | Exported 未 Ack 事件重置为 Pending;清理超时 24h 的过期会话 |
|
||||
| 暂停/恢复/关闭会话 | iOS → Rust | 会话状态切换,时间跟踪同步 |
|
||||
|
||||
### 5.2 数据上传链路(iOS 本地持久化队列 → API)
|
||||
|
||||
| 调用目的 | 方向 | 业务结果 |
|
||||
|---------|------|---------|
|
||||
| 批量上传阅读事件 | iOS 本地队列 → API | POST /learning/reading-events/batch,返回 processed/duplicate/failed |
|
||||
| 查询阅读进度 | iOS → API | GET /materials/:id/reading-progress |
|
||||
| 查询继续学习 | iOS → API | GET /learning/continue |
|
||||
| 查询学习摘要 | iOS → API | GET /learning/summary |
|
||||
| 查询学习趋势 | iOS → API | GET /learning/trend?days=N |
|
||||
| 查询学习记录 | iOS → API | GET /learning/records |
|
||||
| 查询活动摘要/连续天数/推荐 | iOS → API | GET /activity/summary, /activity/streak, /activity/recommendations |
|
||||
|
||||
### 5.3 数据处理链路(API 内部)
|
||||
|
||||
| 调用目的 | 方向 | 业务结果 |
|
||||
|---------|------|---------|
|
||||
| 事件批处理 | API Controller → Event Processor | 逐条处理,单条一个 DB 事务 |
|
||||
| 事件去重 | Event Processor → DB | 检查 userId+eventId 唯一性 |
|
||||
| 材料权限校验 | Event Processor → DB | 验证存在性、所有权、状态 |
|
||||
| 自动阅读会话聚合 | Event Processor → DB(LearningSession) | Upsert by clientSessionId |
|
||||
| 进度聚合 | Event Processor → DB(MaterialReadingProgress) | Upsert by userId+materialId |
|
||||
| 每日活动聚合 | Event Processor → DB(DailyLearningActivity) | Upsert by userId+localDate |
|
||||
| 学习记录创建 | Event Processor → DB(LearningRecord) | 里程碑事件插入 |
|
||||
| 事件重放 | API → Event Processor | 重新处理失败事件 |
|
||||
| 数据重算 | API → LearningActivityService | 用户或全局学习数据重新计算 |
|
||||
|
||||
### 5.4 Admin 查询链路(Admin → API,运维可观测)
|
||||
|
||||
| 调用目的 | 方向 | 业务结果 |
|
||||
|---------|------|---------|
|
||||
| 学习仪表板 | Admin → API | 总览 KPI |
|
||||
| 阅读事件/会话/进度/活动/记录列表 | Admin → API | 分页列表(多条件筛选+排序) |
|
||||
| 用户时间线与诊断 | Admin → API | 时序视图+完整诊断 |
|
||||
| 异常检测 | Admin → API | 失败/警告/重复事件列表 |
|
||||
| 事件重放/数据重算/导出 | Admin → API | 运维操作 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 核心业务数据
|
||||
|
||||
### 6.1 阅读事件(ReadingEvent)
|
||||
|
||||
- **谁创建:** Rust Document Runtime(在 iOS 端内存中创建),API 入库(MySQL)。
|
||||
- **谁更新:** API 更新处理状态(processing → processed/failed/duplicate)和警告代码。
|
||||
- **谁查询:** API 在批处理时查重;Admin 在事件列表和异常检测页查询。
|
||||
- **用于什么功能:** 所有学习分析的原始数据源。每条事件包含 eventId、clientSessionId、materialId、eventType、position、activeSecondsDelta、timestampMs、sequence、platform、appVersion、timezoneOffset。
|
||||
|
||||
### 6.2 自动阅读会话(LearningSession,API 聚合自 ReadingEvent)
|
||||
|
||||
- **谁创建:** API 在收到第一个 material_opened 事件时通过 upsert 创建(按 clientSessionId)。
|
||||
- **谁更新:** API 在每次事件处理中 upsert(增量 totalActiveSeconds、更新 lastPosition、更新 lastEventAt)。material_closed 事件触发状态变为 completed。30 分钟无新事件自动标记为 interrupted。
|
||||
- **谁查询:** iOS 学习主页(通过继续学习 API 间接使用);Admin 在学习会话页和用户诊断页查询。
|
||||
- **用于什么功能:** 自动阅读会话的服务端聚合记录。注意:这是 API 根据 Rust V2 ReadingSession 产生的事件聚合而来的服务端数据对象,与客户端 Rust 内存中的 ReadingSession 是不同的存储层对象。
|
||||
|
||||
### 6.3 专注学习会话(LearningSessionView 本地计时)
|
||||
|
||||
- **谁创建:** 用户主动点击"开始学习"按钮后,iOS 创建本地计时器。
|
||||
- **谁更新:** 用户操作暂停/继续/结束(含确认弹窗),计时器以 1 秒精度运行。
|
||||
- **谁查询:** iOS 学习会话页展示当前进度。
|
||||
- **用于什么功能:** 用户主动发起的专注学习时段计时。**与自动阅读会话是不同的业务对象。** 当前 iOS 是否调用专注学习会话 API(LearningSessionService)持久化仍标记为"暂未确认"。
|
||||
- **关键区别:** 自动阅读会话随进入/离开资料自动产生;专注学习会话由用户主动开始/结束。自动阅读会话已通过事件链路上报至 API;专注学习会话的 API 持久化调用链待确认。
|
||||
|
||||
### 6.4 资料阅读进度(MaterialReadingProgress)
|
||||
|
||||
- **谁创建:** API 在收到某资料第一个事件时 upsert 创建。
|
||||
- **谁更新:** API 每次事件处理中 upsert。累计 totalActiveSeconds、sessionCount。更新 lastPosition、lastProgress。marked_as_read 时设置 isMarkedRead=true、status=read。
|
||||
- **谁查询:** iOS 在进入阅读页时查询;Admin 在阅读进度页查询。
|
||||
- **用于什么功能:** 阅读位置恢复、"继续学习"推荐、阅读进度展示。
|
||||
|
||||
### 6.5 每日学习活动(DailyLearningActivity)
|
||||
|
||||
- **谁创建:** API 在收到某用户某日第一个事件时 upsert 创建。
|
||||
- **谁更新:** API 每次事件处理中 upsert。增量累加 durationSeconds、readingSeconds、materialsReadCount、markedReadCount。日期按用户时区(clientTimezoneOffsetMinutes)计算。
|
||||
- **谁查询:** API 在学习摘要/趋势/活跃热力图/连续天数计算中查询;Admin 在每日活动页查询。
|
||||
- **用于什么功能:** 日级别的学习活动聚合、趋势分析、连续天数计算、分析页数据。
|
||||
|
||||
### 6.6 学习记录(LearningRecord)
|
||||
|
||||
- **谁创建:** API 为里程碑事件(material_opened/closed/marked_as_read)创建。
|
||||
- **谁更新:** 创建后不可修改。
|
||||
- **谁查询:** iOS 在分析页查询(最近 5 条);Admin 在学习记录页查询。
|
||||
- **用于什么功能:** 用户学习时间线、分析页"最近学习记录"展示。
|
||||
|
||||
### 6.7 继续学习状态(ContinueLearning)
|
||||
|
||||
- **谁创建:** API 实时计算(查询最近阅读的未完成资料)。
|
||||
- **谁更新:** 不持久化(每次查询实时计算)。
|
||||
- **谁查询:** iOS 学习主页(优先级算法首选项)。
|
||||
- **用于什么功能:** 用户快速回到上次阅读位置继续学习。
|
||||
|
||||
### 6.8 学习摘要(LearningSummary)
|
||||
|
||||
- **谁创建:** API 实时聚合(查询 DailyLearningActivity)。
|
||||
- **谁更新:** 不持久化(每次查询实时聚合)。
|
||||
- **谁查询:** iOS 学习主页和学习分析页。
|
||||
- **用于什么功能:** 今日/本周/总计的阅读分钟、活跃天数等汇总展示。
|
||||
|
||||
### 6.9 学习趋势(LearningTrend)
|
||||
|
||||
- **谁创建:** API 实时计算(过去 N 天每日阅读时长序列)。
|
||||
- **谁更新:** 不持久化。
|
||||
- **谁查询:** iOS 分析页阅读时长趋势图。
|
||||
- **用于什么功能:** 展示用户阅读时长的日间变化趋势。
|
||||
|
||||
---
|
||||
|
||||
## 7. 查询入口
|
||||
|
||||
### 用户在哪里查看
|
||||
|
||||
- **继续学习:** iOS 学习主页主操作卡片。
|
||||
- **每周摘要:** iOS 学习主页每周摘要卡片。
|
||||
- **学习分析:** iOS 学习分析页(掌握度/总分钟/复习卡片/活跃天/阅读统计/趋势图/连续统计/学习记录/推荐/AI 综合分析)。
|
||||
- **资料阅读进度:** iOS 资料详情页(阅读进度卡片)。
|
||||
|
||||
### Admin 在哪里查看(运维可观测)
|
||||
|
||||
- **学习仪表板:** Admin 学习数据→总览(KPI 汇总)。
|
||||
- **阅读事件列表:** Admin 学习数据→阅读事件页(按用户/材料/状态/类型筛选)。
|
||||
- **学习会话列表:** Admin 学习数据→学习会话页。
|
||||
- **阅读进度/每日活动/学习记录列表:** Admin 学习数据→对应页面。
|
||||
- **用户时间线:** Admin 学习数据→用户时间线。
|
||||
- **用户诊断:** Admin 学习数据→用户诊断。
|
||||
- **异常数据:** Admin 学习数据→异常数据(失败/警告/重复三 Tab)。
|
||||
- **数据导出:** Admin 学习数据→导出。
|
||||
|
||||
### 系统内部在哪里使用
|
||||
|
||||
- **活动趋势 AI 分析:** API GET /activity/trend → Heavy Runtime 生成学习趋势洞察(Heavy Runtime 是下游消费者)。
|
||||
- **推荐系统:** API GET /activity/recommendations → 学习主页优先级算法。
|
||||
- **学习连续天数:** API GET /activity/streak → 连续天数计算。
|
||||
- **活跃热力图:** API GET /activity/heatmap → 每日阅读时长热力图。
|
||||
|
||||
---
|
||||
|
||||
## 8. 修改入口
|
||||
|
||||
### 用户主动修改
|
||||
|
||||
- **标记已读:** iOS 资料阅读页工具栏按钮。本地 MarkedReadStore 即时生效,marked_as_read 事件通过采集链路上报至 API。
|
||||
- **取消标记已读:** 本地 MarkedReadStore 即时生效。服务端同步方式暂未确认(当前事件模型只有 marked_as_read,没有 unmarked_as_read 事件类型)。
|
||||
- **开始专注学习会话:** iOS 资料阅读页工具栏"开始学习"按钮。
|
||||
- **结束专注学习会话:** iOS 学习会话页结束按钮(含确认弹窗)。
|
||||
|
||||
### Admin 人工修改(运维可观测)
|
||||
|
||||
- **事件重放:** Admin 单条或批量重放失败事件。
|
||||
- **事件重处理:** API 内部端点批量重处理失败事件。
|
||||
- **数据重算:** Admin 触发用户或全局学习数据重新计算。
|
||||
- **数据导出:** Admin 导出原始事件或会话数据。
|
||||
|
||||
### 系统自动修改
|
||||
|
||||
- **事件去重:** API 自动检测并标记重复事件为 duplicate。
|
||||
- **活跃时长封顶:** API 将超过 300 秒的 activeSecondsDelta 截断为 300 秒,添加警告。
|
||||
- **时间戳偏差检测:** API 检测客户端时间戳与服务器时间的偏差(>5 分钟),添加警告。
|
||||
- **乱序事件检测:** API 检测 sequence 不连续的事件,添加警告。
|
||||
- **会话自动关闭:** API 在事件处理前自动将 30 分钟无新事件的活跃会话标记为 interrupted。
|
||||
- **过期材料自动检测:** API 在事件处理时自动检测临时材料的过期状态。
|
||||
- **崩溃恢复:** Rust + iOS 在 App 重启时自动恢复(Rust reload + iOS 队列 reloadOnLaunch)。
|
||||
|
||||
### 系统配置修改
|
||||
|
||||
- **批次大小上限:** API 配置(每批最多 100 条)。
|
||||
- **活跃时长上限:** API 硬编码 300 秒。
|
||||
- **时间戳偏差阈值:** API 硬编码 5 分钟。
|
||||
- **会话中断超时:** API 硬编码 30 分钟。
|
||||
- **事件缓冲区上限:** Rust Document Runtime 硬编码 1000 条。
|
||||
- **上传重试策略:** iOS 硬编码(指数退避 5s×2^n,最多 3 次,最长 5 分钟)。
|
||||
|
||||
---
|
||||
|
||||
## 9. 异常与恢复
|
||||
|
||||
### 9.1 App 崩溃 / 系统杀死恢复
|
||||
|
||||
- **Rust 侧:** App 重启时调用 reload_stale_events_v2() → 所有 Exported 未 Ack 事件重置为 Pending。调用 cleanup_stale_sessions_v2(now_ms, 24h) → 清理超过 24 小时的过期会话。
|
||||
- **iOS 侧:** RuntimeRecoveryService.run() 在 App 启动时执行。处理三种场景:
|
||||
1. export 后、本地写入前崩溃 → Rust reload 恢复 Pending,重新导出
|
||||
2. 本地写入成功、Ack 前崩溃 → 重新导出后 API 通过 eventId 去重,再 Ack
|
||||
3. Ack 后、API 上传前崩溃 → 本地持久化队列重启后继续上传
|
||||
- **API 侧:** 下次事件处理时清理超过 30 分钟无新事件的活跃会话(标记为 interrupted)。
|
||||
|
||||
### 9.2 网络失败重试
|
||||
|
||||
- **iOS 本地队列:** 401 → 暂停(pending),等待 Token 刷新。403/404 → 永久失败(dead)。其他错误 → failed + 指数退避重试。重试耗尽 → dead。
|
||||
- **NetworkMonitor:** 检测到网络恢复时,自动触发本地队列 flush。
|
||||
- **API 鉴权:** Token 过期时 APIClient 自动尝试 refresh,成功后重试原请求一次。
|
||||
|
||||
### 9.3 事件去重
|
||||
|
||||
- **API 处理:** userId + eventId 唯一约束。重复事件跳过处理、不更新聚合数据,标记为 duplicate。
|
||||
- **客户端保障:** Rust V2 每个事件有 UUID v4 的 eventId,崩溃恢复时 eventId 不变,确保重传不会产生重复聚合。
|
||||
|
||||
### 9.4 事件乱序
|
||||
|
||||
- **API 处理:** 检测 sequence 不连续 → 添加 OUT_OF_ORDER_EVENT 警告。事件仍然正常处理(不拒绝)。通常由崩溃恢复后重传较早事件引起,不影响聚合结果(增量累加而非绝对值替换)。
|
||||
|
||||
### 9.5 活跃时长异常
|
||||
|
||||
- **API 处理:** activeSecondsDelta > 300 秒 → 截断为 300 秒,添加 ACTIVE_SECONDS_CAPPED 警告。Admin 异常页可筛选复核。
|
||||
|
||||
### 9.6 时间戳偏差
|
||||
|
||||
- **API 处理:** 客户端时间戳与服务器时差 > 5 分钟 → 添加 CLIENT_TIMESTAMP_SKEWED 警告,事件正常处理。
|
||||
|
||||
### 9.7 材料被删除或失去权限
|
||||
|
||||
- **API 处理:** 标记为 FATAL_MATERIAL_NOT_FOUND / FATAL_ACCESS_DENIED / FATAL_TEMPORARY_MATERIAL_EXPIRED。
|
||||
- **Admin 恢复:** 无法恢复已删除材料的关联事件。
|
||||
|
||||
### 9.8 用户切换隔离
|
||||
|
||||
- **实现方式:** 所有 API 操作基于 JWT Token 中的 userId 进行用户隔离。
|
||||
- **阅读事件:** 每个事件在 API 处理时使用当前登录用户的 userId 关联。
|
||||
- **所有聚合数据:** 按 userId 分区存储和查询,用户只能看到自己的数据。
|
||||
- **Admin:** 可通过 userId 筛选查看任一用户的数据,需 admin 权限。
|
||||
|
||||
---
|
||||
|
||||
## 10. 当前完成情况
|
||||
|
||||
统一使用以下口径:
|
||||
- **已完成:** 跨项目链路已接通,用户可以获得最终结果。
|
||||
- **部分完成:** 只有部分项目、部分页面或部分场景完成。
|
||||
- **占位实现:** 存在结构,但使用 Mock、硬编码或静态数据。
|
||||
- **暂未确认:** 无法确认完整调用链。
|
||||
|
||||
| 组件 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| Rust Document Runtime V2 自动阅读会话 | 已完成 | start/pause/resume/close/interrupt 完整生命周期 |
|
||||
| Rust Document Runtime V2 事件采集(5 种) | 已完成 | material_opened/closed/position_changed/heartbeat/marked_as_read |
|
||||
| Rust 活跃时间跟踪器 | 已完成 | ActiveTimeTracker,由 iOS heartbeat tick 驱动 |
|
||||
| Rust 事件缓冲区管理 | 已完成 | Pending → Exported,export/ack/reload |
|
||||
| iOS 15 秒心跳定时器 | 已完成 | iOS 创建 Timer,仅在 session active 且前台时触发,Tick 调用 Rust heartbeat 接口 |
|
||||
| Rust → iOS 事件交接链路 | 已完成 | export → 本地队列写入 → 立即 Ack(交接在本地完成,不依赖网络) |
|
||||
| iOS 本地上传队列 | 已完成 | JSON 持久化,独立于 Rust 缓冲区的网络上传队列 |
|
||||
| iOS 上传重试与网络恢复 | 已完成 | 指数退避 + NetworkMonitor 自动恢复 |
|
||||
| iOS 阅读位置本地缓存 | 已完成 | ReadingPositionStore |
|
||||
| iOS 标记已读本地缓存 | 已完成 | MarkedReadStore(本地即时生效) |
|
||||
| iOS 标记已读服务端同步 | 已完成 | marked_as_read 事件 → 上传链路 → API 聚合 |
|
||||
| iOS 取消标记已读服务端同步 | 暂未确认 | 当前事件模型无 unmarked_as_read,API 是否支持待确认 |
|
||||
| iOS 崩溃恢复 | 已完成 | RuntimeRecoveryService + 本地队列 reloadOnLaunch |
|
||||
| Rust 崩溃恢复 | 已完成 | stale event reload + stale session cleanup |
|
||||
| API 事件批处理端点 | 已完成 | POST /learning/reading-events/batch |
|
||||
| API 事件去重 | 已完成 | userId+eventId 唯一约束 |
|
||||
| API 事件验证 | 已完成 | 类型校验 + 时长上限 + 时间戳检测 + 乱序检测 |
|
||||
| API 权限校验 | 已完成 | 材料存在性、归属、状态、过期校验 |
|
||||
| API 自动阅读会话聚合 | 已完成 | 按 clientSessionId upsert,自动完成/中断 |
|
||||
| API 资料阅读进度聚合 | 已完成 | 按 userId+materialId upsert |
|
||||
| API 每日学习活动聚合 | 已完成 | 按 userId+localDate upsert,时区感知 |
|
||||
| API 学习记录创建 | 已完成 | 里程碑事件自动创建 |
|
||||
| API 学习摘要/趋势/连续天数 | 已完成 | GET /learning/*, GET /activity/* |
|
||||
| API 继续学习推荐 | 已完成 | GET /learning/continue |
|
||||
| API 活动推荐 | 已完成 | GET /activity/recommendations |
|
||||
| API 活跃时长封顶 | 已完成 | 超 300s 截断 + 警告码 |
|
||||
| API 时间戳偏差检测 | 已完成 | >5 分钟偏差警告 |
|
||||
| 用户切换隔离 | 已完成 | JWT userId + 所有查询按 userId 分区 |
|
||||
| Admin 学习仪表板 | 已完成 | KPI 总览(运维可观测) |
|
||||
| Admin 事件/会话/进度/活动/记录查看 | 已完成 | 列表+筛选+详情(运维可观测) |
|
||||
| Admin 用户时间线与诊断 | 已完成 | 时序视图+完整诊断(运维可观测) |
|
||||
| Admin 异常检测 | 已完成 | 失败/警告/重复三视图(运维可观测) |
|
||||
| Admin 事件重放 | 已完成 | 单条+批量(运维可观测) |
|
||||
| Admin 数据重算 | 已完成 | 触发重算(运维可观测) |
|
||||
| Admin 数据导出 | 已完成 | CSV/JSON 导出(运维可观测) |
|
||||
| iOS 专注学习会话 API 持久化 | 暂未确认 | 本地计时已完成,代码中未发现调用 LearningSessionService API 的代码 |
|
||||
446
docs/system-map/capabilities/03-资料上传与处理.md
Normal file
446
docs/system-map/capabilities/03-资料上传与处理.md
Normal file
@ -0,0 +1,446 @@
|
||||
# 03 资料上传与处理 — 跨项目完整能力分析
|
||||
|
||||
> 项目角色分类:主链路参与者(iOS、主 API、COS、Python RAG Worker、Qdrant——资料上传后必须经过这些项目才能完成处理)、运维可观测(Admin)。
|
||||
> Rust Document Runtime 不参与上传与处理链路。Heavy Runtime 不参与此链路。
|
||||
> 注意:Python RAG Worker 和 Qdrant 在本能力中是主链路参与者;在"知识库与知识点管理"和"AI 对话与知识库问答"能力中角色不同(分别为上游支撑和不参与对话上下文加载)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 能力目标
|
||||
|
||||
用户将外部学习资料(PDF、Word、Markdown、图片等)上传至知识库,系统自动完成文本解析、分块、向量索引和知识点候选提取,使资料成为可阅读、可检索、可被 AI 引用的结构化知识。
|
||||
|
||||
---
|
||||
|
||||
## 2. C 端入口
|
||||
|
||||
| 入口页面 | 触发方式 | 进入场景 |
|
||||
|---------|---------|---------|
|
||||
| 知识库详情页 | 操作菜单 → "上传" | 向已有知识库导入资料 |
|
||||
| 知识库详情页 | 操作菜单 → "添加" → 文件模式 | 以文件形式添加知识点 |
|
||||
| 添加知识点页·文件模式 | 点击"选择文件"或"图片"按钮 | 选择文件/照片作为知识点 |
|
||||
| 导入资料页 | 点击"文件导入"/"相册导入"/"链接导入" | 三种导入方式 |
|
||||
|
||||
用户可执行的操作:
|
||||
|
||||
- 从系统文件选择器选择文件(PDF、纯文本、图片等)
|
||||
- 从相册选择照片(自动压缩大于 2MB 的图片)
|
||||
- 输入 URL 进行链接导入
|
||||
- 查看上传进度
|
||||
- 查看导入任务的 AI 处理状态(处理中/就绪/失败)
|
||||
- 审核 AI 提取的知识点候选(接受/拒绝/批量接受)
|
||||
|
||||
---
|
||||
|
||||
## 3. 用户主流程
|
||||
|
||||
```
|
||||
用户选择资料
|
||||
→ iOS 校验文件类型和大小(图片 >2MB 自动压缩)
|
||||
→ iOS 调用 API 获取 COS 预签名上传 URL
|
||||
→ iOS 将文件直接 PUT 到 COS
|
||||
→ iOS 调用 API 确认上传完成(API 验证 COS 中文件存在)
|
||||
→ API 创建资料记录(KnowledgeSource)
|
||||
→ API 创建导入任务(DocumentImport,状态 QUEUED)
|
||||
→ Python RAG Worker 轮询获取导入任务
|
||||
→ Worker 下载文件 → 解析文本 → 清洗 → 分块 → 向量嵌入 → 索引到 Qdrant → 生成知识点候选
|
||||
→ Worker 更新 KnowledgeSource 的 parseStatus/indexStatus/learningStatus
|
||||
→ 用户可在资料详情页查看 AI 处理状态
|
||||
→ 用户可在导入候选审核页审核 AI 提取的知识点候选
|
||||
→ 用户接受候选 → API 创建 KnowledgeItem
|
||||
→ 资料进入可阅读、可被 AI 检索的状态
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 处理阶段与状态
|
||||
|
||||
资料上传后经历多个异步处理阶段,每个阶段有独立的状态追踪:
|
||||
|
||||
### 4.1 原文件上传状态
|
||||
|
||||
- **谁创建:** iOS 调用 API 确认上传后,API 创建 UploadedFile 记录。
|
||||
- **谁更新:** 上传完成后状态不再变化。文件删除时 API 从 COS 和数据库移除。
|
||||
- **用户在哪里看到:** iOS 上传过程中显示进度指示器;上传完成后在资料详情页看到文件名、格式、大小。
|
||||
- **Admin 在哪里看到:** Admin 文件管理页查看所有上传文件列表,可按类型筛选。
|
||||
- **失败后如何处理:** COS 上传失败时 iOS 显示错误提示,用户可重试。
|
||||
|
||||
### 4.2 文本解析状态(parseStatus)
|
||||
|
||||
- **谁创建:** API 创建 KnowledgeSource 时默认为 `pending`。
|
||||
- **谁更新:** Python RAG Worker 在处理过程中更新(pending → processing → complete/failed)。同时更新 textLength、parsedObjectKey、errorCode、errorMessage。
|
||||
- **用户在哪里看到:** iOS 资料详情页的 AI 处理状态横幅(处理中为琥珀色、就绪为绿色、失败为红色)。
|
||||
- **Admin 在哪里看到:** Admin 来源文件页的 parseStatus 列;导入监控页的步骤日志。
|
||||
- **失败后如何处理:** Admin 可触发重新解析(POST /knowledge-bases/:kbId/sources/:id/parse);导入任务自动重试最多 3 次。
|
||||
|
||||
### 4.3 向量索引状态(indexStatus)
|
||||
|
||||
- **谁创建:** API 创建 KnowledgeSource 时默认为 `pending`。
|
||||
- **谁更新:** Python RAG Worker 在嵌入和索引阶段更新(pending → processing → complete/failed)。
|
||||
- **用户在哪里看到:** iOS 不单独展示索引状态(合并在 AI 处理状态中)。
|
||||
- **Admin 在哪里看到:** Admin 来源文件页的 indexStatus 列。
|
||||
- **失败后如何处理:** 同解析失败,Admin 可触发重新解析,系统自动重试。
|
||||
|
||||
### 4.4 学习内容提取状态(learningStatus)
|
||||
|
||||
- **谁创建:** API 创建 KnowledgeSource 时默认为 `pending`。
|
||||
- **谁更新:** Python RAG Worker 在知识点候选生成完成后更新为 `complete`。
|
||||
- **用户在哪里看到:** 不直接展示;用户通过导入候选审核页间接感知(有候选 = 已完成提取)。
|
||||
- **Admin 在哪里看到:** Admin 来源文件详情中查看。
|
||||
- **失败后如何处理:** 候选生成是非致命步骤——即使失败,解析和索引仍可成功。
|
||||
|
||||
### 4.5 候选审核状态
|
||||
|
||||
- **谁创建:** Python RAG Worker 生成候选后,API 创建 ImportCandidate 记录(状态 PENDING)。
|
||||
- **谁更新:** iOS 用户操作:接受 → ACCEPTED;拒绝 → REJECTED;编辑 → EDITED。内容安全拦截 → BLOCKED。
|
||||
- **用户在哪里看到:** iOS 导入候选审核页(候选列表含置信度分数、标题、摘要)。
|
||||
- **Admin 在哪里看到:** Admin 知识运营页的候选巡检 Tab。
|
||||
- **失败后如何处理:** 被内容安全拦截的候选标记为 BLOCKED,Admin 可查看但不可恢复。
|
||||
|
||||
---
|
||||
|
||||
## 5. 项目职责
|
||||
|
||||
### iOS — 主链路参与者
|
||||
|
||||
- 提供文件选择器、相册选择器、链接输入弹窗
|
||||
- 校验文件类型和大小(图片 >2MB 自动 JPEG 压缩)
|
||||
- 调用 API 获取 COS 预签名上传 URL
|
||||
- 直接 PUT 文件到 COS
|
||||
- 调用 API 确认上传
|
||||
- 展示上传进度和 AI 处理状态
|
||||
- 提供导入候选审核界面(接受/拒绝/批量接受)
|
||||
|
||||
### 主 API — 主链路参与者
|
||||
|
||||
- 提供 COS 预签名上传 URL(POST /files/upload-url)
|
||||
- 验证文件类型和大小:iOS 端进行初步校验(文件选择器限制可选类型、图片压缩);API 端进行最终校验(允许 PDF/TXT/Markdown/CSV/XLSX/DOCX/PNG/JPEG/WebP,最大 20MB)
|
||||
- 文件名内容安全检查
|
||||
- 确认上传完成(POST /files/complete),验证 COS 中文件存在后创建记录
|
||||
- 创建 KnowledgeSource 记录并自动创建 DocumentImport 任务
|
||||
- 管理导入任务状态(Redis 实时状态 + 数据库持久化)
|
||||
- 提供导入状态查询(GET /imports/:id/status)
|
||||
- 提供候选审核 API(accept/reject/batch-accept)
|
||||
- 文件下载 URL 生成(COS 预签名链接)
|
||||
- 速率限制(文件上传端点)
|
||||
|
||||
### COS(腾讯云对象存储)— 主链路参与者
|
||||
|
||||
- 存储用户上传的原始文件
|
||||
- 提供预签名 PUT URL(iOS 直接上传,不经 API 中转)
|
||||
- 提供预签名 GET URL(iOS 下载,Python RAG Worker 下载)
|
||||
- 对象键格式:`{userId}/{YYYYMM}/{sanitizedFilename}`
|
||||
|
||||
### Python RAG Worker — 主链路参与者
|
||||
|
||||
- 轮询 API 获取待处理导入任务(每 5 秒)
|
||||
- 定期发送心跳保持任务活跃(每 30 秒)
|
||||
- 完整处理管线:下载文件 → 解析文本 → 清洗(当前仅做 >10 字符长度验证,无实质性文本清洗) → 分块 → 向量嵌入 → 索引到 Qdrant → 生成知识点候选
|
||||
- 解析器支持:PDF(PyMuPDF 提取文本层 → 若每页平均 <50 字符则回退到 SiliconFlow Qwen3-VL OCR)、DOCX(python-docx)、TXT/MD(直接读取)、CSV/XLSX(pandas 转 Markdown 表格)、图片(SiliconFlow 多模态 OCR)
|
||||
- 分块策略:递归字符分割,中文句子边界保护,Markdown 标题感知,512 token 块 + 64 token 重叠
|
||||
- 嵌入模型:BAAI/bge-m3(1024 维),通过 SiliconFlow API
|
||||
- 候选生成:DeepSeek 分析全文提取知识点(标题、摘要、内容、标签、回忆问题、难度、置信度)
|
||||
- 更新 KnowledgeSource 的 parseStatus/indexStatus/learningStatus
|
||||
|
||||
### Qdrant(向量数据库)— 主链路参与者
|
||||
|
||||
- 存储文档块的向量索引(集合 `zhixi_chunks`,1024 维,余弦距离)
|
||||
- 每个向量点携带 payload:userId、knowledgeBaseId、sourceId、chunkId、pageNumber、sectionTitle
|
||||
- 支持按 sourceId 软删除(mark_deleted)
|
||||
- 为资料范围 AI 问答和语义检索提供向量搜索能力
|
||||
|
||||
### Admin — 运维与可观测
|
||||
|
||||
- 文件管理页(查看所有上传文件,删除)
|
||||
- 来源文件页(查看所有 KnowledgeSource,按解析/索引状态筛选)
|
||||
- 导入监控页(查看所有导入任务,步骤级日志,重试失败任务)
|
||||
- 候选巡检 Tab(查看所有候选及其审核状态)
|
||||
- 分块管理 Tab(按 sourceId 查看分块详情)
|
||||
- RAG 调试 Tab(向量搜索调试)
|
||||
|
||||
### Rust Document Runtime — 不参与
|
||||
|
||||
文件上传和异步处理链路不涉及 Rust Document Runtime。Rust 仅在用户打开已上传资料进行阅读时参与文件解析。
|
||||
|
||||
### Heavy Runtime — 不参与
|
||||
|
||||
Heavy Runtime 不参与文件上传、解析、分块、索引和候选生成流程。
|
||||
|
||||
---
|
||||
|
||||
## 6. 项目间调用关系
|
||||
|
||||
### 6.1 iOS → API
|
||||
|
||||
| 调用目的 | 业务结果 |
|
||||
|---------|---------|
|
||||
| 请求上传授权 | 返回 COS 预签名 PUT URL + objectKey |
|
||||
| 确认上传完成 | API 验证 COS 文件存在,创建 UploadedFile 记录 |
|
||||
| 创建知识源 | 创建 KnowledgeSource + DocumentImport 任务(QUEUED) |
|
||||
| 查询导入状态 | 返回 Redis 实时状态(进度百分比 + 文字描述) |
|
||||
| 获取下载 URL | 返回 COS 预签名下载链接 |
|
||||
|
||||
### 6.2 iOS → COS(直接)
|
||||
|
||||
| 调用目的 | 业务结果 |
|
||||
|---------|---------|
|
||||
| 上传文件 | 文件直接 PUT 到 COS,不经 API 中转 |
|
||||
|
||||
### 6.3 Python RAG Worker → API
|
||||
|
||||
| 调用目的 | 业务结果 |
|
||||
|---------|---------|
|
||||
| 轮询待处理任务 | 获取 QUEUED 状态的导入任务 |
|
||||
| 锁定任务 | 原子转换 QUEUED → CLAIMED |
|
||||
| 心跳上报 | 保持任务活跃,防止超时回收 |
|
||||
| 更新任务状态 | 更新 Redis 进度/消息 |
|
||||
| 更新 KnowledgeSource | 更新 parseStatus/indexStatus/learningStatus |
|
||||
| 保存分块 | 批量写入 KnowledgeChunk 记录 |
|
||||
| 保存候选 | 批量写入 ImportCandidate 记录 |
|
||||
|
||||
### 6.4 Python RAG Worker → COS
|
||||
|
||||
| 调用目的 | 业务结果 |
|
||||
|---------|---------|
|
||||
| 下载文件 | 通过预签名 URL 下载原始文件用于处理 |
|
||||
|
||||
### 6.5 Python RAG Worker → Qdrant
|
||||
|
||||
| 调用目的 | 业务结果 |
|
||||
|---------|---------|
|
||||
| 写入向量 | 将文档块的嵌入向量写入 zhixi_chunks 集合 |
|
||||
| 软删除 | 标记指定 sourceId 的向量为 deleted |
|
||||
|
||||
### 6.6 Python RAG Worker → 模型服务
|
||||
|
||||
| 调用目的 | 业务结果 |
|
||||
|---------|---------|
|
||||
| 文本嵌入 | 调用 SiliconFlow BAAI/bge-m3 生成 1024 维向量 |
|
||||
| 图片 OCR | 调用 SiliconFlow Qwen3-VL 多模态模型提取图片文字 |
|
||||
| 候选生成 | 调用 DeepSeek 分析全文提取知识点候选 |
|
||||
|
||||
### 6.7 Admin → API(运维可观测)
|
||||
|
||||
| 调用目的 | 业务结果 |
|
||||
|---------|---------|
|
||||
| 查看/删除文件 | 文件管理 |
|
||||
| 查看来源文件 | 列表 + 按状态筛选 |
|
||||
| 查看导入任务 | 列表 + 步骤日志 |
|
||||
| 重试导入 | 重置失败任务为 QUEUED |
|
||||
| 查看候选 | 候选巡检 |
|
||||
| 查看分块 | 按 sourceId 查看分块详情 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 核心业务数据
|
||||
|
||||
### 7.1 上传文件(UploadedFile)
|
||||
|
||||
- **谁创建:** API 在确认上传时创建。
|
||||
- **谁更新:** 不更新(创建后不可变)。
|
||||
- **谁查询:** iOS 在上传后获取文件信息;Admin 在文件管理页查询。
|
||||
- **用途:** 记录已上传到 COS 的文件,作为 KnowledgeSource 的 fileId 引用来源。
|
||||
|
||||
### 7.2 知识源(KnowledgeSource)
|
||||
|
||||
- **谁创建:** API 在添加来源时创建(关联 fileId)。
|
||||
- **谁更新:** Python RAG Worker 更新 parseStatus/indexStatus/learningStatus。
|
||||
- **谁查询:** iOS 在知识库详情页来源 Tab;Admin 在来源文件页。
|
||||
- **用途:** 知识库中每个导入资料的记录,追踪处理状态。
|
||||
|
||||
### 7.3 导入任务(DocumentImport)
|
||||
|
||||
- **谁创建:** API 在创建 KnowledgeSource 时自动创建(状态 QUEUED)。
|
||||
- **谁更新:** Python RAG Worker 更新状态、进度、步骤日志;Admin 可重置为 QUEUED(重试)。
|
||||
- **谁查询:** iOS 查询导入状态;Admin 在导入监控页。
|
||||
- **用途:** 追踪单个文档的完整处理生命周期,从排队到完成或失败。
|
||||
|
||||
### 7.4 知识分块(KnowledgeChunk)
|
||||
|
||||
- **谁创建:** Python RAG Worker 在分块和索引阶段批量创建。
|
||||
- **谁更新:** 创建后不可修改(软删除通过 Qdrant 实现)。
|
||||
- **谁查询:** Admin 在分块管理 Tab 按 sourceId 查看;系统内部通过 Qdrant 向量搜索使用。
|
||||
- **用途:** 文档的语义分块,每个块有向量嵌入,用于资料范围 AI 问答的语义检索。
|
||||
|
||||
### 7.5 导入候选(ImportCandidate)
|
||||
|
||||
- **谁创建:** Python RAG Worker 在候选生成阶段批量创建(状态 PENDING)。
|
||||
- **谁更新:** iOS 用户操作(accept → ACCEPTED,reject → REJECTED,edit → EDITED)。内容安全拦截 → BLOCKED。
|
||||
- **谁查询:** iOS 在候选审核页按 sourceId 查询;Admin 在候选巡检 Tab 查看。
|
||||
- **用途:** AI 从文档中提取的知识点候选,等待用户审核确认。
|
||||
|
||||
### 7.6 知识点(KnowledgeItem,由候选接受生成)
|
||||
|
||||
- **谁创建:** API 在用户接受候选时创建(itemType: ai_generated)。
|
||||
- **谁更新:** 用户在编辑知识点页修改。
|
||||
- **谁查询:** iOS 在知识点详情页和知识库详情页。
|
||||
- **用途:** 用户确认后的正式知识点,进入知识库内容体系。
|
||||
|
||||
### 7.7 向量索引(Qdrant Collection)
|
||||
|
||||
- **谁创建:** Python RAG Worker 在索引阶段写入。
|
||||
- **谁更新:** 软删除通过 mark_deleted(sourceId) 实现。
|
||||
- **谁查询:** API 在资料范围 AI 问答时通过向量搜索检索相关块;Admin 通过向量管理页查看统计。
|
||||
- **用途:** 为资料范围 AI 问答提供语义级检索能力。
|
||||
|
||||
---
|
||||
|
||||
## 8. 查询入口
|
||||
|
||||
### 用户查询
|
||||
|
||||
- **上传进度:** iOS 添加知识点页/导入资料页的上传进度指示器。
|
||||
- **AI 处理状态:** iOS 资料详情页的 AI 处理状态横幅(处理中/就绪/失败)。
|
||||
- **导入候选:** iOS 导入候选审核页(列表含置信度、标题、摘要)。
|
||||
- **来源文件列表:** iOS 知识库详情页来源 Tab(含处理状态标签)。
|
||||
|
||||
### Admin 查询
|
||||
|
||||
- **文件列表:** Admin 文件管理页(按类型查看、删除)。
|
||||
- **来源文件列表:** Admin 来源文件页(按解析/索引状态筛选)。
|
||||
- **导入任务列表:** Admin 导入监控页(状态、进度、步骤日志、重试)。
|
||||
- **候选巡检:** Admin 知识运营页候选巡检 Tab。
|
||||
- **分块管理:** Admin 知识运营页分块管理 Tab(按 sourceId 查看)。
|
||||
- **RAG 调试:** Admin 知识运营页 RAG 调试 Tab(向量搜索测试)。
|
||||
|
||||
### 系统内部查询
|
||||
|
||||
- **RAG Worker 轮询任务:** Python RAG Worker 定期轮询 QUEUED 导入任务。
|
||||
- **向量搜索:** API 在资料范围 AI 问答时查询 Qdrant 获取相关块。
|
||||
- **Redis 状态查询:** API 提供导入任务实时状态(24 小时 TTL)。
|
||||
|
||||
---
|
||||
|
||||
## 9. 修改入口
|
||||
|
||||
### 用户操作
|
||||
|
||||
- **上传新文件:** iOS 导入资料页/添加知识点页。
|
||||
- **接受候选:** iOS 候选审核页接受单个候选。
|
||||
- **拒绝候选:** iOS 候选审核页拒绝单个候选。
|
||||
- **批量接受:** iOS 候选审核页"全部接受"按钮。
|
||||
- **编辑候选:** iOS 可编辑候选内容后再接受。
|
||||
|
||||
### Admin 操作
|
||||
|
||||
- **删除文件:** Admin 文件管理页删除上传文件(同时从 COS 删除)。
|
||||
- **重试导入:** Admin 导入监控页重试失败任务(重置为 QUEUED,最多 3 次系统自动重试,Admin 手动重置不占重试次数)。
|
||||
- **触发重新解析:** Admin 可触发知识源的重新解析。
|
||||
|
||||
### 系统自动修改
|
||||
|
||||
- **导入任务自动重试:** Python RAG Worker 失败时系统自动重试(最多 3 次,超时后标记 FAILED_FINAL)。
|
||||
- **过期任务回收:** 心跳超过 5 分钟的 CLAIMED 任务被重置为 QUEUED。
|
||||
- **内容安全检查:** 文件名、KB 标题、候选内容接受时自动进行敏感词检查。
|
||||
- **Redis 状态过期:** 导入任务 Redis 状态在 24 小时后自动清除。
|
||||
- **分布式锁过期:** 重复上传防护锁在 5 分钟后自动释放。
|
||||
|
||||
### 配置修改
|
||||
|
||||
- **允许的文件类型:** API 端配置(PDF/TXT/Markdown/CSV/XLSX/DOCX/PNG/JPEG/WebP)。
|
||||
- **最大文件大小:** API 端硬编码 20MB。
|
||||
- **COS 预签名 URL 有效期:** 上传 1 小时,下载 24 小时(知识点详情页 7 天)。
|
||||
- **分块参数:** Python RAG Worker 配置(512 token 块大小,64 token 重叠)。
|
||||
- **嵌入模型:** Python RAG Worker 配置(BAAI/bge-m3)。
|
||||
- **候选生成模型:** Python RAG Worker 配置(deepseek-chat,temperature 0.3)。
|
||||
|
||||
---
|
||||
|
||||
## 10. 异常与恢复
|
||||
|
||||
### 10.1 文件类型不支持
|
||||
|
||||
- **场景:** 用户选择不支持的文件类型。
|
||||
- **iOS 处理:** 文件选择器限制可选类型(PDF/纯文本/图片);API 在请求上传 URL 时二次校验,返回错误。
|
||||
- **用户感知:** iOS 提示"不支持的文件格式"。
|
||||
|
||||
### 10.2 文件过大
|
||||
|
||||
- **场景:** 文件超过 20MB 限制。
|
||||
- **iOS 处理:** 图片 >2MB 自动 JPEG 压缩;非图片文件 >20MB 时 API 拒绝。
|
||||
- **用户感知:** API 返回文件过大错误。
|
||||
|
||||
### 10.3 COS 上传失败
|
||||
|
||||
- **场景:** 网络问题或 COS 服务异常导致 PUT 失败。
|
||||
- **iOS 处理:** 显示上传错误提示,用户可重试。上传使用预签名 URL,不经过 API 中转。
|
||||
- **API 处理:** 确认上传时如果 COS 中文件不存在(headObject 失败),返回确认失败。
|
||||
|
||||
### 10.4 上传成功但 API 创建记录失败
|
||||
|
||||
- **场景:** COS 上传成功,但确认 API 调用失败(网络中断、服务错误)。
|
||||
- **结果:** 文件在 COS 中存在但数据库无记录(孤儿文件)。
|
||||
- **恢复:** 用户重新上传(生成新的 objectKey);Admin 可手动清理孤儿文件(file-cleanup 队列定期执行)。
|
||||
|
||||
### 10.5 导入任务失败
|
||||
|
||||
- **场景:** Python RAG Worker 处理过程中出错(下载失败、解析失败、API 调用失败)。
|
||||
- **系统处理:** 自动重试最多 3 次,每次重置为 QUEUED。3 次失败后标记 FAILED_FINAL。
|
||||
- **用户感知:** iOS 资料详情页 AI 处理状态显示红色"失败"横幅。
|
||||
- **Admin 恢复:** Admin 在导入监控页查看步骤日志,手动重试(不占系统重试次数)。
|
||||
|
||||
### 10.6 RAG 解析失败
|
||||
|
||||
- **场景:** PDF 损坏、DOCX 格式异常、OCR 无法识别。
|
||||
- **Worker 处理:** 解析阶段失败 → 任务标记 FAILED,更新 parseStatus 为 failed,记录 errorCode 和 errorMessage。
|
||||
- **影响范围:** 解析失败的文件无法进行后续分块、嵌入和索引。
|
||||
- **恢复:** Admin 触发重新解析;用户可尝试重新上传。
|
||||
|
||||
### 10.7 向量索引失败
|
||||
|
||||
- **场景:** Qdrant 不可用、嵌入 API 调用失败。
|
||||
- **Worker 处理:** 索引阶段失败 → 任务标记 FAILED。parseStatus 可能已 complete,但 indexStatus 为 failed。
|
||||
- **影响范围:** 资料可阅读但不可用于语义检索。
|
||||
- **恢复:** Admin 重试导入任务;系统自动重试。
|
||||
|
||||
### 10.8 重复上传
|
||||
|
||||
- **场景:** 用户短时间内上传相同文件多次。
|
||||
- **API 处理:** 使用 Redis 分布式锁(`lock:document-import:{fileName}:{timestamp}`,5 分钟 TTL)防止并发重复导入。
|
||||
- **边界:** 锁只防止并发重复;用户间隔 5 分钟后仍可上传相同文件创建新的 KnowledgeSource。
|
||||
|
||||
### 10.9 用户删除处理中资料
|
||||
|
||||
- **场景:** 用户在导入任务处理过程中删除知识源。
|
||||
- **API 处理:** KnowledgeSource 使用软删除(设置 deletedAt)。Python RAG Worker 在处理前应检查源是否已被删除(具体行为待确认)。
|
||||
- **影响:** 已生成的 KnowledgeChunk 和 ImportCandidate 可能成为孤儿数据。
|
||||
|
||||
### 10.10 候选审核失败
|
||||
|
||||
- **场景:** 接受候选时内容安全检查失败。
|
||||
- **API 处理:** 候选标记为 BLOCKED,返回原因。用户无法强制接受。
|
||||
- **Admin 查看:** Admin 可在候选巡检中看到 BLOCKED 状态的候选。
|
||||
|
||||
---
|
||||
|
||||
## 11. 当前完成状态
|
||||
|
||||
| 组件 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| iOS 文件选择与上传 | 已完成 | 文件选择器 + 相册选择器 + 链接导入 |
|
||||
| iOS 图片压缩 | 已完成 | >2MB 自动 JPEG 压缩 |
|
||||
| iOS 上传进度展示 | 已完成 | 进度指示器 |
|
||||
| iOS 候选审核界面 | 已完成 | 接受/拒绝/批量接受 |
|
||||
| iOS AI 处理状态展示 | 已完成 | 资料详情页三色横幅(处理中/就绪/失败) |
|
||||
| API COS 预签名 URL 上传流程 | 已完成 | 请求 URL → 直接 PUT → 确认 |
|
||||
| API 文件类型与大小校验 | 已完成 | 8 种类型,最大 20MB |
|
||||
| API 内容安全检查(文件名) | 已完成 | 敏感词匹配 |
|
||||
| API 速率限制 | 已完成 | 文件上传端点 |
|
||||
| API KnowledgeSource 创建与管理 | 已完成 | 含自动 DocumentImport 任务创建 |
|
||||
| API 导入状态查询 | 已完成 | Redis 实时状态(进度+消息) |
|
||||
| API 候选审核 API | 已完成 | accept/reject/batch-accept |
|
||||
| Python RAG Worker 轮询与锁定 | 已完成 | 每 5 秒轮询,心跳每 30 秒 |
|
||||
| Python RAG Worker 文本解析 | 已完成 | PDF/DOCX/TXT/MD/CSV/XLSX/图片 OCR |
|
||||
| Python RAG Worker 分块与嵌入 | 已完成 | 递归分割 + BAAI/bge-m3 |
|
||||
| Python RAG Worker 向量索引 | 已完成 | Qdrant zhixi_chunks 集合 |
|
||||
| Python RAG Worker 候选生成 | 已完成 | DeepSeek 提取知识点 |
|
||||
| Python RAG Worker 状态更新 | 已完成 | parseStatus/indexStatus/learningStatus |
|
||||
| 导入任务自动重试 | 已完成 | 最多 3 次,过期任务自动回收 |
|
||||
| Admin 文件管理 | 已完成 | 查看/删除 |
|
||||
| Admin 来源文件查看 | 已完成 | 列表 + 按状态筛选 |
|
||||
| Admin 导入监控 | 已完成 | 步骤日志 + 重试 |
|
||||
| Admin 候选巡检 | 已完成 | 列表查看 |
|
||||
| Admin 分块管理 | 已完成 | 按 sourceId 查看 |
|
||||
| Admin RAG 调试 | 部分完成 | 基础向量搜索测试工具,展示原始 JSON 响应;非生产级检索调试界面 |
|
||||
| 孤儿文件自动清理 | 暂未确认 | file-cleanup 队列存在但清理策略待确认 |
|
||||
| 处理中删除源的行为 | 暂未确认 | Worker 是否检查软删除标志待确认 |
|
||||
322
docs/system-map/capabilities/04-知识库与知识点管理.md
Normal file
322
docs/system-map/capabilities/04-知识库与知识点管理.md
Normal file
@ -0,0 +1,322 @@
|
||||
# 04 知识库与知识点管理 — 跨项目完整能力分析
|
||||
|
||||
> 项目角色分类:主链路参与者(iOS、主 API、数据库、COS——知识库 CRUD 必须经过这些项目)、上游支撑(Python RAG Worker——异步处理导入资料,不阻塞知识库管理操作)、运维可观测(Admin)。
|
||||
> Rust Document Runtime 不参与知识库管理链路。Heavy Runtime 不参与此链路。
|
||||
> 注意:Python RAG Worker 在本能力中是上游支撑(知识库 CRUD 不依赖它);在"资料上传与处理"能力中是主链路参与者。
|
||||
|
||||
---
|
||||
|
||||
## 1. 能力目标
|
||||
|
||||
用户可以创建、组织、维护个人知识库,管理其中的知识点和来源资料,通过文件夹分类、排序、搜索、公开发现和订阅来高效组织和获取学习内容。
|
||||
|
||||
---
|
||||
|
||||
## 2. C 端入口
|
||||
|
||||
| 入口页面 | 触发方式 | 功能 |
|
||||
|---------|---------|------|
|
||||
| 知识库首页 | Tab "知识库" 默认 | 查看知识库列表、筛选、搜索入口、创建入口 |
|
||||
| 知识库搜索页 | 搜索图标 | 搜索知识库和知识点 |
|
||||
| 创建知识库页 | + 按钮 / 我的页学习资产 | 创建新知识库(封面、名称、描述) |
|
||||
| 知识库详情页 | 点击知识库卡片 | 查看知识点列表/来源文件列表、管理操作 |
|
||||
| 添加知识点页 | 操作菜单"添加" | 手动/文件模式添加知识点 |
|
||||
| 知识点详情页 | 点击知识点条目 | 查看/收藏/笔记/原文 |
|
||||
| 编辑知识点页 | 工具栏菜单 | 编辑标题和内容 |
|
||||
| 文件夹管理 Sheet | 操作菜单"文件夹管理" | 创建/重命名/删除文件夹 |
|
||||
| 导入资料页 | 操作菜单"上传" | 文件/相册/链接导入 |
|
||||
| 导入候选审核页 | 导入完成后 | 审核 AI 提取的知识点候选 |
|
||||
| 发现公开库页 | "我的"页"发现公开库" | 浏览/订阅公开知识库 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 业务对象关系
|
||||
|
||||
```
|
||||
知识库(KnowledgeBase)
|
||||
├── 来源资料(KnowledgeSource)── 原始上传文件,含解析/索引/学习状态
|
||||
├── 知识点(KnowledgeItem)── 知识库的基本内容单元
|
||||
│ ├── 类型:章节(chapter)、课程(lesson)、概念(concept)、笔记(note)、导入文档(imported_doc)、AI生成(ai_generated)
|
||||
│ ├── 层级:通过 parentId 形成树状结构
|
||||
│ └── 关联:通过 sourceId 关联到来源资料
|
||||
├── 文件夹(KnowledgeFolder)── 用于组织知识点
|
||||
│ └── 同步创建 folder 类型的 KnowledgeItem(保证 iOS 兼容)
|
||||
├── 知识分块(KnowledgeChunk)── 来源资料的语义分块,含向量嵌入
|
||||
├── 导入候选(ImportCandidate)── AI 提取的知识点候选,等待审核
|
||||
├── 测验(Quiz)── 基于知识库内容生成的测验
|
||||
├── 订阅关系(KnowledgeBaseSubscription)── 用户对公开知识库的订阅
|
||||
└── AI 会话范围(ChatScope)── AI 对话可限定在知识库范围
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 用户主流程
|
||||
|
||||
### 4.1 创建知识库
|
||||
|
||||
用户点击创建按钮 → 输入名称(必填)和描述(必填)→ 可选上传封面图(从相册选择,自动裁剪为 512×512)→ 点击创建 → API 创建知识库记录(默认 private)→ 用户可在列表中看到新知识库。每个用户最多创建 20 个知识库。
|
||||
|
||||
### 4.2 浏览与筛选
|
||||
|
||||
用户进入知识库首页 → 查看知识库卡片列表(封面、名称、描述、日期、置顶标记、公开标记)→ 可通过分类筛选(全部/我的/已订阅/官方)切换视图 → 滚动到底部自动加载更多(分页 20 条/页)→ 下拉刷新。
|
||||
|
||||
### 4.3 添加资料
|
||||
|
||||
用户进入知识库详情页 → 点击操作菜单"上传" → 选择文件/相册/链接导入 → 文件上传至 COS → API 创建 KnowledgeSource → 自动创建 DocumentImport 任务 → Python RAG Worker 异步处理 → 用户可查看 AI 处理状态 → 审核 AI 提取的候选知识点。
|
||||
|
||||
### 4.4 手动添加知识点
|
||||
|
||||
用户进入添加知识点页 → 选择"手动"模式 → 输入标题和内容文字 → 保存 → API 创建 KnowledgeItem。
|
||||
|
||||
### 4.5 编辑与删除知识点
|
||||
|
||||
用户在知识库详情页点击知识点 → 进入知识点详情页查看内容 → 工具栏菜单选择编辑 → 修改标题/内容 → 保存。滑动或长按可删除知识点(单个或批量)。
|
||||
|
||||
### 4.6 批量操作
|
||||
|
||||
用户进入批量选择模式 → 逐选或全选知识点 → 点击批量删除 → 确认弹窗 → API 批量软删除。
|
||||
|
||||
### 4.7 文件夹管理
|
||||
|
||||
用户打开文件夹管理 Sheet → 查看已有文件夹列表 → 新建(输入名称)→ 重命名(滑动操作)→ 删除(滑动操作)。创建文件夹时同步创建 folder 类型的 KnowledgeItem。注意:重命名文件夹时仅更新 KnowledgeFolder 记录的 name 字段,不会同步更新对应 KnowledgeItem 的 title 字段。当前无文件夹数量上限。
|
||||
|
||||
### 4.8 排序
|
||||
|
||||
用户在知识库详情页点击排序菜单 → 选择排序方式(默认/文件大小/创建时间/更新时间)→ 知识点列表按所选方式重新排列。
|
||||
|
||||
### 4.9 搜索
|
||||
|
||||
用户点击搜索图标 → 进入搜索页 → 输入关键词。当前搜索逻辑未实现——搜索页仅展示空状态,输入关键词不触发 API 调用。
|
||||
|
||||
### 4.10 公开库发现与订阅
|
||||
|
||||
用户进入发现公开库页 → 查看所有公开知识库列表(含标题、描述、条目数)→ 点击订阅按钮 → API 创建订阅记录。用户可在知识库首页"已订阅"筛选中查看已订阅的知识库。用户不可订阅自己的知识库。取消订阅可随时操作。
|
||||
|
||||
### 4.11 删除知识库
|
||||
|
||||
用户在知识库详情页操作菜单点击"删除知识库"→ 确认弹窗 → API 软删除知识库(设置 deletedAt)。删除后知识点和来源资料仍保留在数据库中(软删除),但不再对用户可见。
|
||||
|
||||
---
|
||||
|
||||
## 5. 项目职责
|
||||
|
||||
### iOS — 主链路参与者
|
||||
|
||||
- 知识库列表展示(卡片、筛选、分页、下拉刷新)
|
||||
- 创建知识库(封面选择与裁剪、名称/描述输入)
|
||||
- 知识库详情(双 Tab:知识点 + 来源文件,排序,批量操作)
|
||||
- 知识点详情(多格式渲染、收藏、笔记、原文)
|
||||
- 添加/编辑知识点
|
||||
- 文件夹管理 Sheet
|
||||
- 搜索页(界面已搭建,逻辑未实现)
|
||||
- 公开库发现与订阅
|
||||
- 导入与候选审核
|
||||
|
||||
### 主 API — 主链路参与者
|
||||
|
||||
- 知识库 CRUD(创建/列表/详情/更新/软删除)
|
||||
- 知识库所有权校验(私有 KB 对非所有者返回 404)
|
||||
- 置顶切换
|
||||
- 知识点 CRUD(创建/列表/详情/更新/单个删除/批量删除)
|
||||
- 知识点排序
|
||||
- 公开库发现(GET /knowledge-bases/discover,含搜索参数)
|
||||
- 订阅管理(订阅/取消订阅/查看已订阅)
|
||||
- 文件夹 CRUD(创建/列表/更新/删除)
|
||||
- 知识库数量限制(每用户最多 20 个)
|
||||
- 内容安全检查(KB 标题、标签)
|
||||
|
||||
### 数据库 — 主链路参与者
|
||||
|
||||
- 存储知识库、知识点、来源资料、文件夹、订阅、导入任务等核心业务数据
|
||||
- 软删除支持(deletedAt 字段)
|
||||
- 唯一约束(userId + knowledgeBaseId 订阅防重、userId + parentId + name 文件夹防重)
|
||||
|
||||
### COS — 主链路参与者
|
||||
|
||||
- 存储知识库封面图
|
||||
- 存储知识点关联文件的内容(通过 COS URL 引用)
|
||||
|
||||
### Python RAG Worker — 上游支撑
|
||||
|
||||
- 不直接参与知识库 CRUD
|
||||
- 异步处理导入资料,生成 KnowledgeChunk、ImportCandidate
|
||||
- 用户在 RAG Worker 完成处理前即可查看和管理知识库及知识点
|
||||
|
||||
### Admin — 运维与可观测
|
||||
|
||||
- 知识库列表查看(全部 KB,含所属用户、条目数)
|
||||
- 知识库详情抽屉(元数据 + 嵌套来源文件列表)
|
||||
- 来源文件查看(全部来源,按 KB 和解析状态筛选)
|
||||
- 来源文件引用追踪(查看哪些 AI 产物引用了该来源)
|
||||
- 知识库删除
|
||||
- 用户管理(查看/状态管理)
|
||||
- 会员与配额管理
|
||||
|
||||
---
|
||||
|
||||
## 6. 权限与可见性
|
||||
|
||||
### 6.1 私有知识库
|
||||
|
||||
- **可见性:** 仅所有者可查看和操作。非所有者请求返回 404(隐藏存在性)。
|
||||
- **所有者操作:** 全部 CRUD + 置顶 + 可见性切换 + 删除。
|
||||
- **非所有者操作:** 无任何操作权限。
|
||||
|
||||
### 6.2 公开知识库
|
||||
|
||||
- **可见性:** 任何人可通过发现页查看和搜索。所有者仍可正常管理。
|
||||
- **所有者操作:** 同私有知识库。
|
||||
- **非所有者操作:** 可查看详情、订阅。不可编辑或删除。
|
||||
- **订阅:** 用户可订阅公开知识库。不可订阅自己的知识库。
|
||||
|
||||
### 6.3 官方知识库
|
||||
|
||||
- **当前状态:** API 和数据库模型支持 ownerType 字段,但 iOS 端"官方"筛选返回空数组(TODO 注释:等后端支持)。
|
||||
- **计划行为:** 由平台创建和维护的精选知识库,所有用户可查看和订阅。
|
||||
|
||||
### 6.4 删除权限
|
||||
|
||||
- **知识库删除:** 仅所有者可删除(软删除)。
|
||||
- **知识点删除:** 所有者可单个或批量删除。
|
||||
- **来源资料删除:** 服务层无所有权检查(代码缺陷),任何认证用户可通过 ID 删除任意来源。
|
||||
- **文件夹删除:** 服务层无显式所有权检查(代码缺陷),但通过 KB 所有权间接保护。
|
||||
|
||||
### 6.5 资料访问权限
|
||||
|
||||
- **所有者:** 完整读写权限。可阅读原文件、使用 AI 对话(知识库范围)。
|
||||
- **订阅者:** 可查看知识库内容。原文件阅读权限待确认(取决于 COS 文件访问控制)。
|
||||
- **非所有者非订阅者:** 对私有 KB 无任何访问权限。对公开 KB 可查看详情和订阅。
|
||||
|
||||
---
|
||||
|
||||
## 7. 查询入口
|
||||
|
||||
### 用户查询
|
||||
|
||||
- **知识库列表:** iOS 知识库首页(卡片 + 筛选 + 分页)。
|
||||
- **知识库详情:** iOS 知识库详情页(双 Tab + 排序)。
|
||||
- **知识点详情:** iOS 知识点详情页(多格式渲染)。
|
||||
- **搜索:** iOS 知识库搜索页(界面已搭建,逻辑未实现)。
|
||||
- **公开库:** iOS 发现公开库页。
|
||||
- **已订阅:** iOS 知识库首页"已订阅"筛选。
|
||||
|
||||
### Admin 查询
|
||||
|
||||
- **知识库列表:** Admin 知识库页(全部 KB,含所属用户、条目数)。
|
||||
- **知识库详情抽屉:** 元数据 + 嵌套来源文件列表 + 引用追踪。
|
||||
- **来源文件列表:** Admin 来源文件页(按 KB 和解析状态筛选)。
|
||||
- **引用追踪:** 查看特定来源被哪些 AI 产物(测验、摘要等)引用。
|
||||
|
||||
### 系统内部查询
|
||||
|
||||
- **RAG 对话上下文:** API 从 KnowledgeItem 表按知识库 ID 查询最多 30 条,构建对话上下文。
|
||||
- **导入任务关联:** API 创建 KnowledgeSource 时自动关联 DocumentImport。
|
||||
- **订阅关系:** API 在订阅和已订阅列表查询时使用。
|
||||
|
||||
---
|
||||
|
||||
## 8. 修改入口
|
||||
|
||||
### 用户修改
|
||||
|
||||
- **创建知识库:** iOS 创建知识库页 → POST /knowledge-bases。
|
||||
- **更新知识库:** iOS 知识库设置 → PATCH /knowledge-bases/:id。
|
||||
- **置顶/取消置顶:** iOS 知识库卡片操作 → POST /knowledge-bases/:id/pin。
|
||||
- **创建知识点:** iOS 添加知识点页 → POST /knowledge-items。
|
||||
- **编辑知识点:** iOS 编辑知识点页 → PATCH /knowledge-items/:id。
|
||||
- **删除知识点:** iOS 知识库详情页(单个/批量) → DELETE /knowledge-items/:id 或 POST /knowledge-items/batch-delete。
|
||||
- **文件夹操作:** iOS 文件夹管理 Sheet → POST/PATCH/DELETE /knowledge-bases/:id/folders。
|
||||
- **订阅/取消订阅:** iOS 发现公开库页 → POST/DELETE /knowledge-bases/:id/subscribe。
|
||||
- **删除知识库:** iOS 知识库详情页 → DELETE /knowledge-bases/:id。
|
||||
|
||||
### Admin 修改
|
||||
|
||||
- **删除知识库:** Admin 知识库页删除按钮(危险确认弹窗)。
|
||||
- **删除文件:** Admin 文件管理页。
|
||||
- **重试导入:** Admin 导入监控页。
|
||||
|
||||
### 系统自动修改
|
||||
|
||||
- **itemCount 维护:** 创建/删除知识点时自动更新知识库的 itemCount。
|
||||
- **软删除传播:** 删除文件夹时自动软删除子文件夹和对应的 KnowledgeItem。
|
||||
- **内容安全检查:** KB 标题和标签自动进行敏感词匹配。
|
||||
|
||||
---
|
||||
|
||||
## 9. 删除影响
|
||||
|
||||
### 9.1 删除知识库
|
||||
|
||||
- **影响范围:** 知识库本身被软删除(设置 deletedAt)。
|
||||
- **知识点:** 保留在数据库中(不被级联删除),但用户不可见。
|
||||
- **来源资料:** 保留但关联的 KB 不可访问。
|
||||
- **订阅:** 保留但已删除 KB 不出现在已订阅列表中。
|
||||
- **测验:** 保留但关联的 KB 不可访问。
|
||||
- **AI 会话:** 保留但知识库范围对话可能无法加载上下文。
|
||||
|
||||
### 9.2 删除来源资料
|
||||
|
||||
- **影响范围:** 来源资料被软删除。
|
||||
- **关联知识点:** 保留(sourceId 变为悬空引用)。
|
||||
- **关联分块:** KnowledgeChunk 保留,Qdrant 向量需手动或通过软删除标记清理。
|
||||
- **关联候选:** ImportCandidate 保留但关联的 sourceId 不可访问。
|
||||
|
||||
### 9.3 删除知识点
|
||||
|
||||
- **影响范围:** 知识点被软删除,itemCount 递减。
|
||||
- **子知识点:** 保留在数据库中(parentId 变为悬空引用)。
|
||||
- **关联笔记:** 知识点详情页的笔记入口不可用。
|
||||
- **AI 对话上下文:** 已删除知识点不再出现在上下文加载结果中。
|
||||
|
||||
### 9.4 删除文件夹
|
||||
|
||||
- **影响范围:** 文件夹被软删除,对应的 folder 类型 KnowledgeItem 也被软删除。
|
||||
- **子文件夹:** 级联软删除。
|
||||
- **文件夹内知识点:** 保留在数据库中(parentId 引用可能变为悬空)。
|
||||
|
||||
### 9.5 取消订阅
|
||||
|
||||
- **影响范围:** 订阅记录被删除。
|
||||
- **已订阅列表:** 知识库从用户的已订阅筛选中消失。
|
||||
- **其他数据:** 无影响。用户之前查看的知识库内容仍可查看(只要知识库保持公开)。
|
||||
|
||||
---
|
||||
|
||||
## 10. 当前完成状态
|
||||
|
||||
| 组件 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| iOS 创建知识库 | 已完成 | 封面、名称、描述,API 创建 |
|
||||
| iOS 知识库列表与筛选 | 部分完成 | 全部/我的/已订阅可用;"官方"筛选返回空 |
|
||||
| iOS 知识库详情(双 Tab) | 已完成 | 知识点列表 + 来源文件列表 |
|
||||
| iOS 手动添加知识点 | 已完成 | 标题 + 内容编辑 |
|
||||
| iOS 文件模式添加知识点 | 已完成 | COS 上传 + 创建知识点 |
|
||||
| iOS 知识点详情(多格式渲染) | 已完成 | 文本/Markdown/文件 |
|
||||
| iOS 编辑知识点 | 已完成 | 标题 + 内容修改 |
|
||||
| iOS 删除知识点(单个+批量) | 已完成 | 单个软删除 + 批量选择删除 |
|
||||
| iOS 文件夹管理 | 已完成 | 创建/重命名/删除 |
|
||||
| iOS 排序 | 已完成 | 4 种排序方式 |
|
||||
| iOS 搜索 | 未完成 | 搜索页界面已搭建,搜索逻辑未实现 |
|
||||
| iOS 公开库发现与订阅 | 已完成 | 查看/订阅/取消订阅 |
|
||||
| iOS 删除知识库 | 已完成 | 确认弹窗 + API 软删除 |
|
||||
| iOS 收藏知识点 | 部分完成 | UI 切换存在,后端 API 未支持(TODO) |
|
||||
| iOS 重命名知识点 | 未完成 | 菜单项存在但 action 为空(TODO) |
|
||||
| iOS 移动到文件夹 | 未完成 | 菜单项存在但 action 为空(TODO) |
|
||||
| iOS 知识库管理页 | 未完成 | 操作菜单"知识库管理"按钮 action 为空(TODO) |
|
||||
| API 知识库 CRUD | 已完成 | 创建/列表/详情/更新/软删除 |
|
||||
| API 知识库所有权校验 | 已完成 | 私有 KB 对非所有者返回 404 |
|
||||
| API 知识库数量限制 | 已完成 | 每用户最多 20 个 |
|
||||
| API 置顶切换 | 已完成 | |
|
||||
| API 公开库发现与搜索 | 已完成 | 支持标题+描述搜索 |
|
||||
| API 订阅管理 | 已完成 | 订阅/取消订阅/已订阅列表 |
|
||||
| API 知识点 CRUD | 已完成 | 创建/列表/详情/更新/单个删除/批量删除 |
|
||||
| API 知识点排序 | 已完成 | createdAt/updatedAt/fileSize/orderIndex |
|
||||
| API 文件夹 CRUD | 已完成 | 含 folder 类型 KnowledgeItem 同步;当前无文件夹数量限制 |
|
||||
| API 内容安全检查 | 已完成 | KB 标题 + 标签 + 候选内容 |
|
||||
| Admin 知识库查看 | 已完成 | 列表 + 详情抽屉 |
|
||||
| Admin 来源文件查看 | 已完成 | 按 KB 和解析状态筛选 |
|
||||
| Admin 来源文件引用追踪 | 已完成 | 查看 AI 产物引用了哪些来源 |
|
||||
| Admin 知识库删除 | 已完成 | |
|
||||
| 官方知识库 | 未完成 | API 模型支持但后端筛选未实现 |
|
||||
| API 来源资料删除权限校验 | 暂未确认 | 代码中无所有权检查(疑似缺陷) |
|
||||
| API 文件夹更新/删除权限校验 | 暂未确认 | 代码中无显式所有权检查 |
|
||||
398
docs/system-map/capabilities/05-AI对话与知识库问答.md
Normal file
398
docs/system-map/capabilities/05-AI对话与知识库问答.md
Normal file
@ -0,0 +1,398 @@
|
||||
# 05 AI 对话与知识库问答 — 跨项目完整能力分析
|
||||
|
||||
> 项目角色分类:主链路(iOS、主 API、DeepSeek 模型服务)、上游支撑(Python RAG Worker,仅为知识库内容供给,不参与对话上下文加载)、运维可观测(Admin)。
|
||||
> Qdrant 不参与对话上下文加载——所有 5 种 Scope 的上下文均来自 PostgreSQL KnowledgeItem 表。
|
||||
> Heavy Runtime 不直接参与基础 AI 对话——它负责异步 AI 分析任务(学习状态分析、测验生成等),对话链路走 AiGateway 直达模型。
|
||||
> Rust Document Runtime 不参与 AI 对话链路。
|
||||
|
||||
---
|
||||
|
||||
## 1. 能力目标
|
||||
|
||||
用户可以通过自然语言与 AI 进行学习相关的对话。对话可以限定在特定知识库、资料或知识点的范围内,AI 基于范围内知识内容回答问题,并提供来源引用。支持流式回复、思考过程展示和多会话管理。
|
||||
|
||||
---
|
||||
|
||||
## 2. C 端入口
|
||||
|
||||
| 入口页面 | 对话范围 | 触发方式 |
|
||||
|---------|---------|---------|
|
||||
| AI 反馈页 | 全局 | "深入提问"按钮 |
|
||||
| 知识库详情页 | 知识库 | 底部 AI 对话按钮 |
|
||||
| 资料阅读页 | 资料 | 工具栏 AI 按钮 |
|
||||
| 知识点详情页 | 知识点 | 工具栏菜单(如有) |
|
||||
| AI 反馈页 → AIChatPage | 全局 | "深入提问" → AIChatPage |
|
||||
| (废弃)AI 首页 | 全局 | 底部输入栏(页面无入口) |
|
||||
|
||||
---
|
||||
|
||||
## 3. 对话范围
|
||||
|
||||
### 3.1 全局对话(scopeType: global)
|
||||
|
||||
- **上下文来源:** 无知识库上下文。AI 仅基于通用知识回答。
|
||||
- **RAG 查询范围:** 不进行任何检索。
|
||||
- **会话识别:** 创建 session 时 scopeType=global 且 scopeId 为空。
|
||||
- **切换处理:** 用户从范围对话点击"新建对话"可创建全局对话。
|
||||
|
||||
### 3.2 知识库范围(scopeType: knowledge_base)
|
||||
|
||||
- **上下文来源:** 从 KnowledgeItem 表查询该知识库下的知识点(最多 30 条,每条截取前 500 字符,总计最多 4000 字符)。
|
||||
- **RAG 查询范围:** 上下文直接从 PostgreSQL 的 KnowledgeItem 表加载。所有 5 种 Scope 均不调用 Qdrant——`loadContextByScope` 在代码中完全不涉及向量搜索。
|
||||
- **会话识别:** 创建 session 时 scopeType=knowledge_base,scopeId=<kbId>。相同知识库范围的会话通过 "open-or-create" 模式复用(同一用户同一知识库只有一个活跃对话会话)。
|
||||
- **切换处理:** 用户切换到另一个知识库的对话时,创建新会话或恢复已有会话。
|
||||
|
||||
### 3.3 资料范围(scopeType: material)
|
||||
|
||||
- **上下文来源:** 按 sourceRef 匹配该资料关联的知识点。与知识库范围相同,上下文直接从 PostgreSQL 的 KnowledgeItem 表加载。Qdrant 不参与对话上下文加载。
|
||||
- **会话识别:** session 的 scopeType=material,scopeId=<sourceId>。
|
||||
- **切换处理:** 用户离开资料阅读页后,对话会话保留。下次进入同一资料时恢复。
|
||||
|
||||
### 3.4 知识点范围(scopeType: knowledge_item)
|
||||
|
||||
- **上下文来源:** 单个知识点的完整内容。
|
||||
- **RAG 查询范围:** 单个知识点本身,无需检索。
|
||||
- **会话识别:** session 的 scopeType=knowledge_item,scopeId=<itemId>。
|
||||
- **切换处理:** 每个知识点有独立会话。
|
||||
|
||||
### 3.5 范围切换机制
|
||||
|
||||
- 用户在不同入口进入 AI 对话时,系统根据当前上下文自动确定对话范围。
|
||||
- 每个范围维护独立的 ChatSession。
|
||||
- 会话列表 Sheet 可按范围过滤显示。
|
||||
- ScopeSnapshot 保存在每条消息中,确保历史消息知道其产生时的范围上下文。
|
||||
|
||||
---
|
||||
|
||||
## 4. 用户主流程
|
||||
|
||||
```
|
||||
用户进入对话(从知识库详情页/资料阅读页/AI 反馈页等入口)
|
||||
→ iOS 调用 API 创建或恢复会话(open-or-create,相同范围复用会话)
|
||||
→ 用户输入消息
|
||||
→ iOS 调用流式发送 API(POST /rag-chat/sessions/:id/stream)
|
||||
→ API 校验会话所有权
|
||||
→ API 内容安全检查(敏感词匹配)
|
||||
→ API 保存用户消息(含 scopeSnapshot)
|
||||
→ API 自动生成会话标题(首次消息时,截取前 40 字符)
|
||||
→ API 根据 scopeType 加载上下文:
|
||||
- global:空上下文
|
||||
- knowledge_base:从 KnowledgeItem 表查询最多 30 条(每条约 500 字符)
|
||||
- material/folder:按相应过滤条件查询
|
||||
- knowledge_item:查询单个知识点
|
||||
→ API 将上下文注入系统提示模板
|
||||
→ API 调用 AiGateway → 路由到 DeepSeek Provider → deepseek-v4-pro
|
||||
→ DeepSeek 流式返回(content 块 + thinking 块)
|
||||
→ API 通过 SSE 逐块转发给 iOS
|
||||
→ iOS 实时展示 AI 回复(含思考过程可折叠动画)
|
||||
→ 流式完成后 API 保存 AI 消息(含 token 计数)
|
||||
→ API 保存引用(前 5 个上下文项作为 ChatCitation)
|
||||
→ iOS 展示引用信息
|
||||
→ 用户可复制回复、重新生成、或发送新消息
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 项目职责
|
||||
|
||||
### iOS — 主链路参与者
|
||||
|
||||
- AI 对话界面(消息气泡、思考过程展示、引用展示)
|
||||
- 流式接收与实时渲染(SSE 解析)
|
||||
- 输入栏(文字输入、语音图标占位、发送按钮)
|
||||
- 会话列表 Sheet(搜索、切换、删除、归档、置顶)
|
||||
- 新建对话
|
||||
- 范围标签展示(当前对话限定范围)
|
||||
- 复制回复、重新生成
|
||||
|
||||
### 主 API — 主链路参与者
|
||||
|
||||
- 会话 CRUD(open-or-create、列表、更新、软删除)
|
||||
- 会话所有权校验
|
||||
- 消息发送(同步 + 流式)
|
||||
- 内容安全检查(输入消息和 AI 输出)
|
||||
- 上下文加载(按 scopeType 从 KnowledgeItem 表查询)
|
||||
- 系统提示构建(上下文注入)
|
||||
- AiGateway 路由(模型选择、回退、重试)
|
||||
- SSE 流式转发
|
||||
- 引用保存(ChatCitation)
|
||||
- Token 使用记录(ModelInvocationLog)
|
||||
- 自动标题生成
|
||||
|
||||
### DeepSeek 模型服务 — 主链路参与者
|
||||
|
||||
- 接收系统提示 + 用户消息 + 上下文
|
||||
- 流式生成回复(content + reasoning_content)
|
||||
- 模型:deepseek-v4-pro(primary tier),deepseek-v4-flash(cheap tier)
|
||||
- 通过 AiGateway 统一管理 API 密钥和路由
|
||||
|
||||
### Python RAG Worker — 上游支撑(间接参与)
|
||||
|
||||
- 不直接参与对话流程。负责文档导入后的处理(解析→分块→嵌入→索引),为知识库提供结构化的知识点内容。
|
||||
- RAG 处理结果(KnowledgeItem、KnowledgeChunk)是对话上下文的间接来源——KnowledgeItem 表中的内容可能来自 RAG 生成的候选知识点。
|
||||
- 注意:知识库范围对话的上下文来自 KnowledgeItem 表(PostgreSQL),**不依赖** Qdrant 向量搜索,也不依赖 RAG 的实时处理状态。
|
||||
|
||||
### Qdrant — 不参与对话上下文加载
|
||||
|
||||
- 存储文档块的向量索引,用于文档导入后的语义检索(Admin RAG 调试页使用)。
|
||||
- **不参与 AI 对话的上下文加载**——`loadContextByScope` 完全不调用 Qdrant,所有 5 种 Scope 的上下文均来自 PostgreSQL。
|
||||
|
||||
### Admin — 运维与可观测
|
||||
|
||||
- 会话日志查看(Admin 聊天日志页,查看所有会话和消息)
|
||||
- AI 网关管理(路由规则、提供商管理、回退日志)
|
||||
- AI 使用统计(调用次数、延迟、失败率、成本,按提供商和模型)
|
||||
- AI 成本管理(费用记录、按用户统计、导出)
|
||||
- 模型配置(temperature、max_tokens 等参数)
|
||||
- 内容安全审核(敏感词库、审核记录、举报管理、违规处罚)
|
||||
|
||||
### Heavy Runtime — 不直接参与
|
||||
|
||||
Heavy Runtime 负责异步 AI 分析任务(学习状态分析、薄弱点识别、测验生成、闪卡生成),通过独立的作业排队机制运作。**基础 AI 对话不经过 Heavy Runtime**,而是通过 AiGateway 直接调用 DeepSeek。
|
||||
|
||||
---
|
||||
|
||||
## 6. 会话管理
|
||||
|
||||
### 6.1 创建
|
||||
|
||||
- **方式:** open-or-create 模式。用户从入口进入对话时,iOS 调用 POST /rag-chat/sessions。
|
||||
- **复用逻辑:** 相同 scopeType + scopeId + userId 下存在未归档未删除的会话时,返回已有会话(HTTP 200)。否则创建新会话(HTTP 201)。
|
||||
- **这意味着:** 每个用户在每个知识库范围内只有一个活跃对话会话。
|
||||
|
||||
### 6.2 切换
|
||||
|
||||
- **方式:** 用户在会话列表 Sheet 中点击历史会话 → iOS 调用 API 加载该会话的消息历史。
|
||||
- **效果:** 当前对话界面切换到所选会话,范围标签更新。
|
||||
|
||||
### 6.3 搜索
|
||||
|
||||
- **方式:** 在会话列表 Sheet 中输入搜索词 → 本地过滤或 API 搜索。
|
||||
- **范围:** 当前范围内的会话。
|
||||
|
||||
### 6.4 归档
|
||||
|
||||
- **方式:** 会话列表 Sheet 中滑动 → "归档"。
|
||||
- **效果:** API 更新会话 isArchived=true。已归档会话不在默认列表中显示。
|
||||
- **恢复:** 可通过更新 isArchived=false 取消归档。
|
||||
|
||||
### 6.5 删除
|
||||
|
||||
- **方式:** 会话列表 Sheet 中滑动 → "删除"。
|
||||
- **效果:** API 软删除会话(isDeleted=true)。消息保留在数据库中但不再对用户可见。
|
||||
|
||||
### 6.6 置顶
|
||||
|
||||
- **方式:** 会话列表 Sheet 中左滑 → "置顶"/"取消置顶"。
|
||||
- **效果:** API 更新会话 isPinned 状态。置顶会话排在最前。
|
||||
|
||||
### 6.7 Scope(对话范围)
|
||||
|
||||
- 每个会话有 scopeType 和 scopeId,确定上下文来源。
|
||||
- 新建对话时,如果用户从范围入口(知识库/资料)进入,新会话继承该范围。
|
||||
- 用户也可以在对话中切换到全局模式创建新会话。
|
||||
|
||||
### 6.8 Scope Snapshot(范围快照)
|
||||
|
||||
- 每条消息保存一个 scopeSnapshot 对象:{ scopeType, scopeId, parentKnowledgeBaseId }。
|
||||
- 作用:将消息冻结到发送时的范围上下文。即使后续范围发生变化,历史消息仍知道自己引用了哪个范围的上下文。
|
||||
|
||||
### 6.9 引用(Citation)
|
||||
|
||||
- AI 回复后,系统从上下文项中提取前 5 个创建 ChatCitation。
|
||||
- 每个引用包含:chunkId(知识点 ID)、sourceTitle(标题)、excerptText(内容前 500 字符)。
|
||||
- iOS 在消息气泡中展示引用信息。
|
||||
|
||||
### 6.10 历史消息
|
||||
|
||||
- iOS 进入会话时调用 GET /rag-chat/sessions/:id/messages 加载历史。
|
||||
- 消息按时间排序,含角色(user/assistant)、内容、token 数和引用。
|
||||
|
||||
---
|
||||
|
||||
## 7. 核心业务数据
|
||||
|
||||
### 7.1 对话会话(ChatSession)
|
||||
|
||||
- **谁创建:** API 在 iOS 调用 open-or-create 时创建(或返回已有)。
|
||||
- **谁更新:** API 在每次消息发送时更新 lastMessageAt;iOS 操作更新 isPinned/isArchived/isDeleted/title/modelMode/modelId。
|
||||
- **谁查询:** iOS 获取会话列表和消息历史;Admin 在聊天日志页查看。
|
||||
- **用途:** 对话的组织单元,承载范围信息和消息列表。
|
||||
|
||||
### 7.2 对话范围(ChatScope)
|
||||
|
||||
- **概念性对象**(非独立数据库表),由 ChatSession 的 scopeType + scopeId 定义。
|
||||
- **取值:** global、knowledge_base、folder、material、knowledge_item。
|
||||
- **用途:** 确定上下文加载策略和会话唯一性。
|
||||
|
||||
### 7.3 消息(ChatMessage)
|
||||
|
||||
- **谁创建:** API 在发送流程中创建用户消息和 AI 消息。
|
||||
- **谁更新:** 创建后不可修改。
|
||||
- **谁查询:** iOS 加载会话消息历史;Admin 在聊天日志详情中查看。
|
||||
- **用途:** 对话的完整记录,含角色、内容、token 数、scopeSnapshot。
|
||||
|
||||
### 7.4 引用(ChatCitation)
|
||||
|
||||
- **谁创建:** API 在 AI 回复保存后自动创建(从前 5 个上下文项提取)。
|
||||
- **谁更新:** 创建后不可修改。
|
||||
- **谁查询:** iOS 在消息详情中展示;消息列表查询时惰性加载。
|
||||
- **用途:** 为 AI 回复提供可追溯的来源引用。
|
||||
|
||||
### 7.5 范围快照(ScopeSnapshot)
|
||||
|
||||
- **概念性对象**(嵌入在 ChatMessage 中),包含 { scopeType, scopeId, parentKnowledgeBaseId }。
|
||||
- **用途:** 冻结每条消息产生时的对话范围。
|
||||
|
||||
### 7.6 知识分块(KnowledgeChunk)
|
||||
|
||||
- **谁创建:** Python RAG Worker 在文档处理时创建。
|
||||
- **谁更新:** 不更新(软删除通过 Qdrant 实现)。
|
||||
- **谁查询:** Admin 在分块管理页查看;Qdrant 向量搜索(当前仅 Admin RAG 调试页使用,不用于对话上下文加载)。
|
||||
- **用途:** 文档的语义检索向量索引。当前不参与 AI 对话上下文构建。
|
||||
|
||||
### 7.7 模型配置(Model Configuration)
|
||||
|
||||
- **谁管理:** Admin 通过 AI 网关管理页配置路由规则和提供商。
|
||||
- **谁使用:** AiGateway 在每次对话请求时根据 tier(primary/cheap/strong)和 taskType 选择模型。
|
||||
- **当前配置:** primary tier → deepseek-v4-pro;cheap tier → deepseek-v4-flash。
|
||||
|
||||
---
|
||||
|
||||
## 8. 异常与降级
|
||||
|
||||
### 8.1 RAG 尚未处理完成
|
||||
|
||||
- **场景:** 资料已上传但 Python RAG Worker 尚未完成向量索引。
|
||||
- **影响:** 知识库范围对话的上下文来自 KnowledgeItem 表——**不受 RAG 处理状态影响**。所有 Scope 的上下文加载均不依赖 Qdrant,RAG 未完成不影响对话功能。
|
||||
|
||||
### 8.2 检索无结果
|
||||
|
||||
- **场景:** 知识库为空或范围内无匹配知识点。
|
||||
- **API 处理:** loadContextByScope 返回 isEmpty=true。系统提示注入"当前知识库中暂无相关内容"。
|
||||
- **模型行为:** AI 基于通用知识回答,可能告知用户知识库内容不足。
|
||||
|
||||
### 8.3 模型调用失败
|
||||
|
||||
- **场景:** DeepSeek API 返回错误(超时、限流、服务异常)。
|
||||
- **API 处理:** AiGateway 自动回退(fallback 到同 tier 的备用模型/提供商),最多重试 3 次。
|
||||
- **用户感知:** 如果所有重试均失败,返回错误提示。Admin 可在回退日志中查看详情。
|
||||
|
||||
### 8.4 流式响应中断
|
||||
|
||||
- **场景:** SSE 连接在网络问题或客户端断开时中断。
|
||||
- **API 处理:** 检测 res.destroyed,优雅停止流式输出。已生成的部分内容可能不保存为完整消息(取决于中断时机)。
|
||||
- **iOS 处理:** 显示连接中断提示。用户可重新发送消息。
|
||||
|
||||
### 8.5 用户取消生成
|
||||
|
||||
- **场景:** 用户在 AI 生成过程中取消(iOS 断开 SSE 连接或发送取消请求)。
|
||||
- **API 处理:** 检测连接断开,停止流式输出。
|
||||
- **影响:** 部分生成的内容不保存。用户可重新发送。
|
||||
|
||||
### 8.6 会话被删除
|
||||
|
||||
- **场景:** 用户或 Admin 删除会话。
|
||||
- **API 处理:** 软删除(isDeleted=true)。消息保留但不可见。
|
||||
- **用户感知:** 会话从列表中消失。已删除会话不可恢复(当前无回收站功能)。
|
||||
|
||||
### 8.7 资料被删除
|
||||
|
||||
- **场景:** 对话引用的知识库/资料/知识点被删除。
|
||||
- **API 处理:** 上下文加载时自动过滤已删除项。历史消息的 scopeSnapshot 仍保留原范围信息,但该范围可能不再可访问。
|
||||
- **用户感知:** 新对话中该范围无上下文可用。历史消息仍可查看但引用可能失效。
|
||||
|
||||
### 8.8 无权限
|
||||
|
||||
- **场景:** 用户尝试访问其他用户的会话。
|
||||
- **API 处理:** 会话所有权校验失败,返回 403/404。
|
||||
- **用户感知:** 无法查看或操作非自己的会话。
|
||||
|
||||
### 8.9 Token 超限
|
||||
|
||||
- **场景:** 上下文 + 对话历史超过模型上下文窗口。
|
||||
- **API 处理:** 上下文加载有 4000 字符硬限制。长对话历史可能需要截断(具体策略待确认)。
|
||||
- **用户感知:** 较早的对话内容可能不被模型考虑。
|
||||
|
||||
### 8.10 模型 API Key 无效
|
||||
|
||||
- **场景:** 平台 DeepSeek API Key 过期或余额不足。
|
||||
- **API 处理:** AiGateway 调用失败。如果用户配置了自己的 API Key,可回退到用户 Key。
|
||||
- **Admin 处理:** Admin 在密钥管理页更新或轮换 Key。
|
||||
- **用户感知:** 对话报错。用户可在 AI 设置中提供自己的 DeepSeek Key。
|
||||
|
||||
### 8.11 DeepSeek 服务不可用
|
||||
|
||||
- **场景:** DeepSeek API 全面不可用。
|
||||
- **API 处理:** AiGateway 尝试所有提供商后失败。
|
||||
- **用户感知:** 对话完全不可用,显示服务异常提示。
|
||||
- **Admin 处理:** Admin 在 AI 网关管理页监控提供商状态,配置备用提供商。
|
||||
|
||||
---
|
||||
|
||||
## 9. 查询与管理入口
|
||||
|
||||
### 用户查询
|
||||
|
||||
- **会话列表:** iOS 对话页工具栏 → 会话列表 Sheet(搜索、筛选)。
|
||||
- **消息历史:** iOS 对话页加载历史消息。
|
||||
- **引用信息:** iOS 消息气泡中展示。
|
||||
- **AI 使用统计:** iOS 端当前未展示(无用户可见的 token 用量或成本页面)。
|
||||
|
||||
### Admin 查询
|
||||
|
||||
- **会话日志:** Admin 聊天日志页 → 查看所有会话(含用户 ID、知识库 ID、消息数)。
|
||||
- **消息详情:** Admin 聊天日志页 → 点击会话查看全部消息(角色、内容预览、token 数、时间)。
|
||||
- **AI 网关管理:** Admin AI 网关页(路由规则 CRUD、提供商启用/禁用、回退日志)。
|
||||
- **AI 使用统计:** Admin 指标页(按提供商/模型的调用次数、延迟、失败率、成本)。
|
||||
- **AI 成本管理:** Admin 计费页(费用记录 CRUD、按用户统计、导出 CSV)。
|
||||
- **内容安全审核:** Admin 内容安全页(敏感词库、审核记录、举报管理、违规处罚)。
|
||||
|
||||
### 系统内部查询与管理
|
||||
|
||||
- **AiGateway 路由:** 每次对话请求时自动查询路由规则和提供商配置。
|
||||
- **Token 使用记录:** AiGateway 自动记录每次调用的 inputTokens/outputTokens/延迟/成本到 ModelInvocationLog。
|
||||
- **每日使用聚合:** 系统自动聚合用户和平台的每日 AI 使用量(UserAiUsageDaily、PlatformAiBudgetDaily)。
|
||||
- **配额检查:** 发送消息前检查用户每日配额和平台预算。
|
||||
|
||||
---
|
||||
|
||||
## 10. 当前完成状态
|
||||
|
||||
| 组件 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| iOS 流式对话界面 | 已完成 | SSE 解析 + 思考过程展示 + 引用展示 |
|
||||
| iOS 消息气泡渲染 | 已完成 | 用户消息紫色渐变 + AI 消息含思考折叠 |
|
||||
| iOS 复制/重新生成 | 已完成 | 复制到剪贴板 + 重新发送 |
|
||||
| iOS 会话列表 Sheet | 已完成 | 搜索、切换、删除、归档、置顶 |
|
||||
| iOS 新建对话 | 已完成 | 强制创建新会话 |
|
||||
| iOS 范围标签展示 | 已完成 | 对话顶部显示当前范围 |
|
||||
| iOS 全局对话 | 已完成 | 无上下文对话 |
|
||||
| iOS 知识库范围对话 | 已完成 | 从知识库详情页底部按钮进入 |
|
||||
| iOS 资料范围对话 | 已完成 | 从资料阅读页工具栏 AI 按钮进入 |
|
||||
| iOS 知识点范围对话 | 暂未确认 | API scopeType=knowledge_item 已定义;iOS 知识点详情页工具栏菜单未发现直接 AI 对话入口,可能需从知识点详情页手动跳转 |
|
||||
| API open-or-create 会话 | 已完成 | 相同范围复用已有会话 |
|
||||
| API 内容安全检查 | 已完成 | 输入消息 + AI 输出敏感词匹配 |
|
||||
| API 上下文加载(KnowledgeItem 表) | 已完成 | 按 scopeType 查询最多 30 条 |
|
||||
| API 系统提示构建 | 已完成 | 上下文注入到提示模板 |
|
||||
| API AiGateway 路由 | 已完成 | tier 路由 + 回退 + 重试 |
|
||||
| API SSE 流式转发 | 已完成 | Content-Type: text/event-stream |
|
||||
| API 引用保存 | 已完成 | 前 5 个上下文项 → ChatCitation |
|
||||
| API 自动标题生成 | 已完成 | 首次消息截取前 40 字符 |
|
||||
| API Token 使用记录 | 已完成 | ModelInvocationLog |
|
||||
| DeepSeek 模型调用 | 已完成 | deepseek-v4-pro(primary)、deepseek-v4-flash(cheap) |
|
||||
| Qdrant 参与对话上下文加载 | 未完成 | `loadContextByScope` 完全不调用 Qdrant;所有 5 种 Scope 上下文均来自 PostgreSQL KnowledgeItem 表 |
|
||||
| 联网搜索 | 暂未确认 | 未发现联网搜索功能实现 |
|
||||
| 深度思考 | 已完成 | DeepSeek reasoning_content → SSE thinking 块 → iOS 思考过程展示 |
|
||||
| 文件附件 | 暂未确认 | 未发现对话中上传文件功能 |
|
||||
| 导图 | 暂未确认 | 未发现 AI 生成导图功能 |
|
||||
| 分享 | 暂未确认 | 未发现对话分享功能 |
|
||||
| 生成笔记 | 暂未确认 | 未发现从对话生成笔记功能 |
|
||||
| Admin 会话日志查看 | 已完成 | 聊天日志页 |
|
||||
| Admin AI 网关管理 | 已完成 | 路由规则 + 提供商 + 回退日志 |
|
||||
| Admin AI 使用统计 | 已完成 | 按提供商/模型的调用统计 |
|
||||
| Admin AI 成本管理 | 已完成 | 费用记录 + 按用户统计 + 导出 |
|
||||
| Admin 内容安全审核 | 已完成 | 敏感词库 + 审核记录 + 举报 + 违规 |
|
||||
| 用户 AI 用量展示 | 未完成 | iOS 端无 token 用量或配额展示 |
|
||||
| 用户自定义 API Key | 已完成 | iOS 设置页 → AI 设置 → 输入自己的 DeepSeek Key |
|
||||
| 平台预算回退 | 已完成 | 平台预算不足时自动回退到用户 Key |
|
||||
120
docs/system-map/capabilities/06-内容与对话项目矩阵.md
Normal file
120
docs/system-map/capabilities/06-内容与对话项目矩阵.md
Normal file
@ -0,0 +1,120 @@
|
||||
# 06 内容与对话项目矩阵
|
||||
|
||||
> 三项业务能力(资料上传与处理、知识库与知识点管理、AI 对话与知识库问答)在各项目中的职责分布。
|
||||
> 项目角色:主链路参与者、上游支撑、下游消费、运维可观测。
|
||||
|
||||
---
|
||||
|
||||
## 一、资料上传与处理 — 项目参与矩阵
|
||||
|
||||
| 业务环节 | iOS | 主 API | COS | Python RAG Worker | Qdrant | Admin(运维可观测) |
|
||||
|---------|-----|--------|-----|-------------------|--------|-------------------|
|
||||
| 文件选择 | 系统文件选择器/相册/链接输入 | — | — | — | — | — |
|
||||
| 文件校验与压缩 | 校验类型;图片 >2MB 自动 JPEG 压缩 | 校验文件类型(8 种)和大小(≤20MB) | — | — | — | — |
|
||||
| 上传授权 | 调用 API 获取预签名 URL | 生成 COS 预签名 PUT URL(1 小时有效),内容安全检查文件名 | 提供预签名 URL 能力 | — | — | — |
|
||||
| 文件上传 | 直接 PUT 文件到 COS | — | 接收文件数据 | — | — | — |
|
||||
| 上传确认 | 调用 API 确认 | 验证 COS 中文件存在,创建 UploadedFile 记录 | 供 headObject 验证 | — | — | — |
|
||||
| 创建资料记录 | — | 创建 KnowledgeSource + DocumentImport(QUEUED),Redis 状态初始化 | — | — | — | — |
|
||||
| 异步处理 | — | 管理导入任务状态,提供查询端点 | 存储原始文件供 Worker 下载 | 轮询→锁定→下载→解析→清洗→分块→嵌入→索引→生成候选 | 存储向量索引(zhixi_chunks 集合,1024 维) | 监控导入任务(步骤日志、重试) |
|
||||
| 状态展示 | 资料详情页 AI 处理状态横幅 | 提供 parseStatus/indexStatus/learningStatus 查询 | — | 更新 KnowledgeSource 处理状态 | — | 查看来源文件状态 |
|
||||
| 候选审核 | 接受/拒绝/批量接受候选 | 候选审核 API,内容安全检查 | — | 生成候选(DeepSeek 提取知识点) | — | 候选巡检 |
|
||||
| 失败处理 | 展示错误提示 | 自动重试(最多 3 次)+ 过期任务回收 | — | 失败时更新状态和错误信息 | — | 手动重试导入 |
|
||||
| 文件删除 | 来源文件删除 | 软删除;Admin 可从 COS 删除 | 删除对象 | — | 软删除向量标记 | 文件管理页删除 |
|
||||
|
||||
---
|
||||
|
||||
## 二、知识库与知识点管理 — 项目参与矩阵
|
||||
|
||||
| 业务环节 | iOS | 主 API | 数据库 | COS | Python RAG Worker | Admin(运维可观测) |
|
||||
|---------|-----|--------|--------|-----|-------------------|-------------------|
|
||||
| 创建知识库 | 封面选择+裁剪、名称/描述输入 | 创建 KB 记录(默认 private),限制 20 个/用户 | 存储 KB 记录 | 存储封面图 | — | — |
|
||||
| 知识库列表 | 卡片列表+筛选+分页+下拉刷新 | 分页查询,支持 visibility/ownerType 筛选 | 查询+排序 | — | — | 查看全部 KB |
|
||||
| 知识库详情 | 双 Tab(知识点+来源文件)+排序 | 提供详情查询+知识点列表+来源列表 | 关联查询 | — | — | 详情抽屉+来源文件列表 |
|
||||
| 知识库更新/删除 | 更新信息/确认弹窗删除 | 所有权校验,软删除 | 更新/软删除 | — | — | 可删除 KB |
|
||||
| 添加知识点 | 手动模式(标题+内容)+文件模式 | 创建 KnowledgeItem | 存储记录 | 文件模式下存储内容 | — | — |
|
||||
| 知识点编辑 | 标题+内容编辑 | 白名单字段更新 | 更新记录 | — | — | — |
|
||||
| 知识点删除 | 单个删除+批量选择删除 | 单个软删除+批量软删除 | 软删除+itemCount 递减 | — | — | — |
|
||||
| 文件夹管理 | Sheet 弹窗(创建/重命名/删除) | 文件夹 CRUD,同步创建 folder 类型 KnowledgeItem | 存储文件夹+同步 KnowledgeItem | — | — | — |
|
||||
| 排序 | 排序菜单(4 种方式) | 排序参数查询 | ORDER BY 排序 | — | — | — |
|
||||
| 搜索 | 搜索页界面(逻辑未实现) | 公开库支持标题+描述搜索 | 全文搜索未实现 | — | — | — |
|
||||
| 公开库发现 | 公开库列表+订阅/取消订阅 | 发现 API,订阅管理 | 存储订阅关系 | — | — | — |
|
||||
| 权限校验 | — | 所有权校验(私有 KB 返回 404) | — | — | — | Admin 权限分级 |
|
||||
| 内容安全 | — | KB 标题+标签敏感词检查 | — | — | — | 敏感词库管理 |
|
||||
|
||||
---
|
||||
|
||||
## 三、AI 对话与知识库问答 — 项目参与矩阵
|
||||
|
||||
| 业务环节 | iOS | 主 API | DeepSeek 模型 | Python RAG Worker | Admin(运维可观测) |
|
||||
|---------|-----|--------|-------------|-------------------|-------------------|
|
||||
| 会话创建/恢复 | 调用 API open-or-create | open-or-create 逻辑(相同范围复用) | — | — | — |
|
||||
| 消息发送 | 输入文字,调用流式 API | 校验→内容安全→保存用户消息→加载上下文→构建提示→调用模型 | — | — | — |
|
||||
| 上下文加载 | — | 按 scopeType 从 KnowledgeItem 表查询(最多 30 条×500 字符),完全不调用 Qdrant | — | 知识点内容来自 RAG 处理结果(间接供给) | — |
|
||||
| 模型调用 | — | AiGateway 路由→DeepSeek Provider | 流式生成(content+reasoning_content) | — | — | — |
|
||||
| 流式展示 | SSE 解析+实时渲染+思考过程折叠 | SSE 流式转发 | 提供流式响应 | — | — | — |
|
||||
| 引用展示 | 消息气泡中展示引用 | 保存前 5 个上下文项为 ChatCitation | — | — | — | — |
|
||||
| 会话管理 | 列表+搜索+切换+删除+归档+置顶 | 会话 CRUD+所有权校验 | — | — | — | 查看所有会话和消息 |
|
||||
| 内容安全 | — | 输入消息+AI 输出敏感词匹配 | — | — | — | 敏感词库+审核记录+举报+违规 |
|
||||
| 模型路由 | — | AiGateway:tier 路由+回退+重试(最多 3 次) | — | — | — | 路由规则 CRUD+提供商管理+回退日志 |
|
||||
| Token 与成本 | — | 记录 ModelInvocationLog+每日聚合 | — | — | — | 调用统计+成本管理+导出 |
|
||||
| 用户 API Key | 设置页输入自己的 Key | 加密存储+测试+回退使用 | — | — | — | — |
|
||||
| 联网搜索 | 暂未确认 | 暂未确认 | — | — | — | — |
|
||||
| 文件附件 | 暂未确认 | 暂未确认 | — | — | — | — |
|
||||
| 导图/分享/生成笔记 | 暂未确认 | 暂未确认 | — | — | — | — |
|
||||
|
||||
---
|
||||
|
||||
## 四、项目角色分类
|
||||
|
||||
### 主链路参与者
|
||||
|
||||
| 项目 | 资料上传与处理 | 知识库与知识点管理 | AI 对话与知识库问答 |
|
||||
|------|-------------|----------------|-----------------|
|
||||
| iOS | 文件选择、校验、上传、候选审核 | 知识库/知识点/文件夹全界面 | 对话界面、会话管理、流式渲染 |
|
||||
| 主 API | 上传授权、确认、资料记录、导入任务管理 | 全部 CRUD、权限校验、搜索(部分) | 会话管理、上下文加载、模型路由、SSE 转发、内容安全 |
|
||||
| COS | 文件存储和预签名 URL | 封面图和文件内容存储 | — |
|
||||
| 数据库 | UploadedFile/DocumentImport 记录 | KnowledgeBase/Item/Folder/Source 全部 | ChatSession/Message/Citation 记录 |
|
||||
| DeepSeek | — | — | 模型推理(deepseek-v4-pro) |
|
||||
|
||||
### 上游支撑
|
||||
|
||||
| 项目 | 资料上传与处理 | 知识库与知识点管理 | AI 对话与知识库问答 |
|
||||
|------|-------------|----------------|-----------------|
|
||||
| Python RAG Worker | 文档解析、分块、嵌入、候选生成 | 异步处理,不阻塞知识库 CRUD | 知识库内容供给(KnowledgeItem 来自 RAG 候选审核);不参与对话上下文加载 |
|
||||
| Qdrant | 向量索引存储 | — | 不参与对话上下文加载;当前仅 Admin RAG 调试页使用 |
|
||||
|
||||
### 下游消费
|
||||
|
||||
| 项目 | 资料上传与处理 | 知识库与知识点管理 | AI 对话与知识库问答 |
|
||||
|------|-------------|----------------|-----------------|
|
||||
| Heavy Runtime | 不参与 | 不参与 | **不直接参与基础对话**(负责异步 AI 分析) |
|
||||
|
||||
### 运维与可观测
|
||||
|
||||
| 项目 | 资料上传与处理 | 知识库与知识点管理 | AI 对话与知识库问答 |
|
||||
|------|-------------|----------------|-----------------|
|
||||
| Admin | 文件管理、导入监控(步骤日志+重试)、候选巡检、分块管理 | KB 查看/删除、来源文件查看、引用追踪 | 会话日志、AI 网关管理、使用统计、成本管理、内容安全审核 |
|
||||
|
||||
---
|
||||
|
||||
## 五、关键架构发现
|
||||
|
||||
### 5.1 RAG 聊天的上下文不来自 Qdrant
|
||||
|
||||
所有 5 种 Scope(global、knowledge_base、folder、material、knowledge_item)的对话上下文均直接从 PostgreSQL 的 KnowledgeItem 表加载(最多 30 条,每条截取 500 字符,总计最多 4000 字符)。`loadContextByScope` 完全不调用 Qdrant,不存在任何 Scope 使用向量语义搜索。Qdrant 向量索引当前仅用于 Admin RAG 调试页的向量搜索测试。"RAG Chat"中的"RAG"指的是通过 scope 进行结构化检索(从 KnowledgeItem 表查询),而非向量语义搜索。
|
||||
|
||||
### 5.2 基础 AI 对话不经过 Heavy Runtime
|
||||
|
||||
对话链路:iOS → API → AiGateway → DeepSeek。Heavy Runtime 负责异步 AI 分析任务(学习状态分析、薄弱点识别、测验生成等),通过独立的作业轮询机制运作。
|
||||
|
||||
### 5.3 文件上传与处理是完全异步的
|
||||
|
||||
用户上传文件后立即返回,后续的解析、分块、嵌入、索引、候选生成全部由 Python RAG Worker 异步完成。用户可通过资料详情页查看处理状态。
|
||||
|
||||
### 5.4 Open-or-create 确保每个范围只有一个活跃会话
|
||||
|
||||
相同 scopeType + scopeId + userId 下只存在一个未归档未删除的会话。这意味着用户每次从同一知识库进入 AI 对话时,都会恢复之前的对话历史。
|
||||
|
||||
### 5.5 知识库范围对话不等待 RAG
|
||||
|
||||
即使 Python RAG Worker 尚未完成文档处理,知识库范围对话仍可使用——上下文来自用户已手动添加或已通过候选审核的知识点(KnowledgeItem 表),不需要等待 RAG 的向量索引完成。Qdrant 向量索引不参与任何 Scope 的对话上下文构建。
|
||||
79
docs/system-map/ios/00-iOS-C端总览.md
Normal file
79
docs/system-map/ios/00-iOS-C端总览.md
Normal file
@ -0,0 +1,79 @@
|
||||
# 知习 iOS C 端总览
|
||||
|
||||
> **分析范围:** 仅 iOS 项目(AIStudyApp),不包含 API、Rust、RAG、Admin 或其他仓库。
|
||||
> **分析日期:** 2026-06-19
|
||||
> **分析阶段:** 第一阶段完成 — C 端业务盘点与能力定稿
|
||||
|
||||
---
|
||||
|
||||
## 一、项目概况
|
||||
|
||||
知习(ZhiXi)iOS 是一款 AI 驱动的系统化学习应用,基于 SwiftUI 构建,支持深色/浅色主题。当前版本仅支持 Apple ID 登录。业务主数据以云端 API 为主,部分阅读上下文、上传队列和笔记当前保存在本地。
|
||||
|
||||
## 二、用户生命周期
|
||||
|
||||
```
|
||||
首次启动 → Splash(会话恢复)
|
||||
→ Welcome(欢迎页)
|
||||
→ Login(Apple ID 登录)
|
||||
→ Onboarding(4 步引导:输入知识 / 主动输出 / AI 分析 / 掌握知识)
|
||||
→ GoalSetup(设定学习目标 / 方法 / 时间)
|
||||
→ 主界面(4 Tab)
|
||||
```
|
||||
|
||||
已登录用户再次启动时直接进入主界面。账号被禁用或注销后进入对应状态页。
|
||||
|
||||
## 三、底部导航(一级模块)
|
||||
|
||||
| Tab | 名称 | 说明 |
|
||||
|-----|------|------|
|
||||
| 1 | 学习 | 学习工作台:今日任务、继续学习、复习卡片、自我测试、每周摘要 |
|
||||
| 2 | 知识库 | 个人知识库管理:创建、导入、搜索、浏览知识点、AI 对话 |
|
||||
| 3 | 分析 | 学习数据分析:掌握度、阅读趋势、薄弱知识点、学习推荐 |
|
||||
| 4 | 我的 | 个人中心:资料编辑、设置、通知、学习方法、目标、反馈 |
|
||||
|
||||
## 四、页面总览
|
||||
|
||||
### 4.1 统计口径
|
||||
|
||||
本阶段盘点范围包括所有用户可访问的页面、弹窗和确认对话框,按入口类型划分:
|
||||
|
||||
| 入口类型 | 数量 | 说明 |
|
||||
|---------|------|------|
|
||||
| 独立 Push 页面(可路由) | 32 | 通过 NavigationStack + Route 枚举跳转的页面 |
|
||||
| 启动/登录流程页面(不可路由) | 6 | 启动页、欢迎页、登录页、账号状态页、引导页、目标设置页 |
|
||||
| Sheet / 弹窗 | 6 | 从页面中弹出的非独立页面 |
|
||||
| 确认弹窗(Alert/ConfirmationDialog) | 8 | 各类确认/输入弹窗 |
|
||||
| 代码存在但无导航入口的页面 | 2 | AIHomeView(已废弃)、RecallTestPage(无入口) |
|
||||
| **总计可盘点对象** | **54** | |
|
||||
|
||||
### 4.2 独立 Push 页面完成情况
|
||||
|
||||
| 完成情况 | 数量 | 占比 |
|
||||
|---------|------|------|
|
||||
| 已完成 | 17 | 53% |
|
||||
| 部分完成 | 8 | 25% |
|
||||
| 占位实现 | 7 | 22% |
|
||||
| **合计** | **32** | 100% |
|
||||
|
||||
> "占位实现"指页面框架存在但使用硬编码 mock 数据,未接通后端。
|
||||
|
||||
## 五、关键发现
|
||||
|
||||
1. **AI 学习闭环已具雏形:** 知识库 → 阅读 → AI 分析薄弱点 → 主动回忆 → 复习卡片,形成完整的学习链路。
|
||||
2. **文档阅读基础设施较完善:** 通过 Rust FFI 支持 Markdown、文本、PDF、EPUB、图片、Office 文件的解析和阅读,具备阅读位置记录、事件上报等能力。
|
||||
3. **AI 相关页面 mock 较多:** 回忆测试、薄弱点分析、AI 反馈、今日思考等页面的展示数据均为硬编码,未接入真实 AI 分析结果。
|
||||
4. **AI 首页(AIHomeView)未被引用:** 该页面代码完整但未接入任何导航入口,属于废弃页面。
|
||||
5. **知识库管理功能较完整:** 创建、导入、知识点增删改查、分类管理、公开库发现、订阅等基础功能已接通 API。
|
||||
6. **通知系统有界面但功能有限:** 通知列表可查看和标记已读,但设置页面中通知开关状态存在绑定异常。
|
||||
7. **部分功能标注 TODO:** 知识点重命名、移动到文件夹、收藏、知识库管理页、官方知识库筛选等功能未实现。
|
||||
8. **无离线模式:** 应用设计为在线优先,无本地数据持久化策略,仅在阅读上下文方面有基础离线缓存。
|
||||
9. **部分 API 端点已就绪但 C 端无入口:** WaitlistService(waitlist 加入/统计)API 服务代码完整但无任何页面调用;UserService 账号注销(requestAccountDeletion/cancelDeletion)API 已就绪但设置页未提供注销入口;UserService 设备管理(listDevices/removeDevice)API 已就绪但设置页"登录设备管理"行为空(导航自引用)。
|
||||
|
||||
## 六、关联文档
|
||||
|
||||
- [01-iOS页面地图.md](./01-iOS页面地图.md) — 全部页面的详细描述
|
||||
- [02-iOS页面功能总表.md](./02-iOS页面功能总表.md) — 页面功能汇总表
|
||||
- [03-C端业务能力初步清单.md](./03-C端业务能力初步清单.md) — 第一阶段初步归类(草稿,正式能力以 04 为准)
|
||||
- [04-C端正式业务能力树.md](./04-C端正式业务能力树.md) — 正式 C 端业务能力三层树(主索引)
|
||||
- [05-页面与业务能力矩阵.md](./05-页面与业务能力矩阵.md) — 页面与业务能力双向矩阵
|
||||
786
docs/system-map/ios/01-iOS页面地图.md
Normal file
786
docs/system-map/ios/01-iOS页面地图.md
Normal file
@ -0,0 +1,786 @@
|
||||
# 01 iOS 页面地图
|
||||
|
||||
> 按用户可见的页面层级整理,不按代码目录组织。
|
||||
|
||||
---
|
||||
|
||||
## 一、启动与登录流程
|
||||
|
||||
### 1.1 启动页(SplashScreen)
|
||||
|
||||
- **页面作用:** 应用启动时显示品牌标识,后台静默恢复登录会话。
|
||||
- **页面入口:** 应用冷启动时的默认展示。
|
||||
- **页面组成:** 深色渐变背景、品牌图标(大脑)、"知习"标题、加载指示器。
|
||||
- **用户可执行操作:** 无(自动跳转)。
|
||||
- **自动执行功能:** 从系统钥匙串读取 Token → 调用 API 校验 → 恢复会话或跳转到登录页。
|
||||
- **可跳转页面:** 自动跳转至 Welcome 页(未登录)或主界面(已登录)。
|
||||
- **页面主要状态:** 仅展示态。会话恢复中 / 恢复完成自动跳转。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 1.2 欢迎页(WelcomePage)
|
||||
|
||||
- **页面作用:** 向新用户介绍产品核心功能,引导进入登录流程。
|
||||
- **页面入口:** 未登录用户从启动页自动跳转,或已登录用户退出后进入。
|
||||
- **页面组成:** 页面渐变背景、装饰光晕、"AI 驱动"标签、主标题"用 AI 重新定义你的学习方式"、三个功能介绍卡片(主动回忆、费曼解释、AI 分析)、"开始使用"按钮。
|
||||
- **用户可执行操作:** 点击"开始使用"进入登录页。
|
||||
- **自动执行功能:** 无。
|
||||
- **可跳转页面:** LoginPage(登录页)。
|
||||
- **页面主要状态:** 仅展示态。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 1.3 登录页(LoginPage)
|
||||
|
||||
- **页面作用:** 用户使用 Apple ID 登录应用。
|
||||
- **页面入口:** 欢迎页点击"开始使用"。
|
||||
- **页面组成:** 页面渐变背景、品牌图标、欢迎文案、"使用 Apple 账号登录以同步学习数据"提示、Sign in with Apple 按钮、错误信息区域、登录中取消按钮覆盖层。
|
||||
- **用户可执行操作:** Apple ID 登录、取消登录。
|
||||
- **自动执行功能:** 登录成功后自动保存 Token 至钥匙串、切换会话状态。
|
||||
- **可跳转页面:** 登录成功 → Onboarding 页(首次)或主界面(已设定目标)。
|
||||
- **页面主要状态:** 待登录 / 登录中 / 登录失败(显示错误提示)。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 1.4 账号状态页(AccountStatusView)
|
||||
|
||||
- **页面作用:** 当账号被禁用或已注销时,向用户展示状态说明。
|
||||
- **页面入口:** 启动时 AuthManager 检测到账号为 disabled 或 deleted 状态。
|
||||
- **页面组成:** 页面渐变背景、状态图标、标题文案、说明文字、"返回首页"按钮。
|
||||
- **用户可执行操作:** 点击"返回首页"回到未登录状态,可重新登录。
|
||||
- **自动执行功能:** 无。
|
||||
- **可跳转页面:** 回到 Welcome 页。
|
||||
- **页面主要状态:** 禁用态 / 注销态(两种展示略有不同)。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 1.5 引导页(OnboardingPage)
|
||||
|
||||
- **页面作用:** 首次登录后展示产品价值,引导用户理解产品核心流程。
|
||||
- **页面入口:** 首次登录成功后自动跳转。
|
||||
- **页面组成:** 页面渐变背景、4 步引导指示器、步骤标题与说明、"下一步"/"开始使用"按钮、"跳过"链接。四步分别为:输入知识、主动输出、AI 分析、掌握知识。
|
||||
- **用户可执行操作:** 点击"下一步"依次浏览、点击"跳过"直接结束。
|
||||
- **自动执行功能:** 无。
|
||||
- **可跳转页面:** GoalSetupPage(目标设置页)或直接进入主界面(跳过)。
|
||||
- **页面主要状态:** 展示第1-4步。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 1.6 目标设置页(GoalSetupPage)
|
||||
|
||||
- **页面作用:** 用户设定学习目标、偏好方法和每日学习时间。
|
||||
- **页面入口:** Onboarding 完成后自动跳转,或从"我的"→"学习目标设置"进入。
|
||||
- **页面组成:** 页面渐变背景、标题"设定你的学习目标"、四个学习目标选项(备考考试/职业技能/通识学习/自定义)、三种学习方法多选(间隔回忆/费曼技巧/AI 分析)、四个每日学习时间选项(15分钟/30分钟/1小时/不限制)、"开始学习"按钮。
|
||||
- **用户可执行操作:** 选择学习目标、选择学习方法、选择每日时间、确认进入主界面。
|
||||
- **自动执行功能:** 确认后将目标通过 API 保存至用户偏好。
|
||||
- **可跳转页面:** 主界面 ContentView。
|
||||
- **页面主要状态:** 选择中(单选目标、多选方法、单选时间)/ 已确认。
|
||||
- **当前完成情况:** 部分完成(学习目标和方法通过 API 保存;每日学习时长仅保存在本地 @State,缺乏可靠持久化)
|
||||
|
||||
---
|
||||
|
||||
## 二、学习(底部导航 Tab 1)
|
||||
|
||||
### 2.1 学习主页(StudyHomeView)
|
||||
|
||||
- **页面作用:** 学习工作台,聚合展示今日学习任务、复习卡片、自我测试等学习入口。
|
||||
- **页面入口:** 底部导航"学习" Tab(默认选中)。
|
||||
- **页面组成:**
|
||||
- 标题栏:页面标题"学习"(实际未显示明显标题)
|
||||
- 连续学习天数(火焰图标 + 天数)
|
||||
- 主操作卡片(动态变化,见下)
|
||||
- 今日复习卡片(卡片数 + 预计时长)
|
||||
- 自我测试卡片(可用测验数)
|
||||
- 每周摘要卡片(本周分钟数 / 复习卡片数 / 活跃天数 / 连续天数)
|
||||
- 底部"查看完整分析"链接
|
||||
- **用户可执行操作:**
|
||||
- 点击主操作卡片(根据优先级不同,操作不同)
|
||||
- 点击复习卡片入口
|
||||
- 点击自我测试入口
|
||||
- 点击每周摘要区域查看详细分析
|
||||
- 下拉刷新
|
||||
- **自动执行功能:** 页面加载时自动计算优先级最高的学习操作(继续学习 > 今日复习 > 自我测试 > 开始学习 > 空状态引导)
|
||||
- **可跳转页面:**
|
||||
- MaterialReaderView(资料阅读,继续学习时)
|
||||
- ReviewCardView(复习卡片)
|
||||
- QuizTakerView(自我测试)
|
||||
- QuizListView(测验列表)
|
||||
- ActiveRecallView(主动回忆)
|
||||
- 切换到"知识库" Tab
|
||||
- **页面主要状态:** 加载中 / 加载失败(错误提示 + 重试按钮)/ 已加载·有任务 / 已加载·空状态。
|
||||
> 注:View 支持 error 状态展示,但 ViewModel 中所有 API 调用使用 try? 吞错,error 状态在实际运行中永不可达。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 2.2 学习会话页(LearningSessionView)
|
||||
|
||||
- **页面作用:** 专注学习计时器,记录单次学习时长。
|
||||
- **页面入口:** 从学习主页或资料阅读页的学习任务入口进入。
|
||||
- **页面组成:** 环形计时器(带动画渐变环)、任务信息卡片(任务名称、类型、建议时长 30 分钟、今日已学时长)、提示卡片、底部状态栏"学习中…"、暂停/继续按钮、结束按钮。
|
||||
- **用户可执行操作:** 暂停/继续计时、结束学习。
|
||||
- **自动执行功能:** 进入页面自动开始计时(1秒精度),学习结束时自动展示庆祝动画。
|
||||
- **可跳转页面:** 无(结束学习后展示庆祝动画,用户可返回)。
|
||||
- **页面主要状态:** 计时中 / 已暂停 / 学习完成(庆祝动画覆盖层)。
|
||||
- **当前完成情况:** 暂未确认(本地计时功能完成,但代码中未发现调用 LearningSessionService API 保存学习记录的代码,学习时长可能不持久化到服务端)
|
||||
|
||||
---
|
||||
|
||||
### 2.3 复习卡片页(ReviewCardView)
|
||||
|
||||
- **页面作用:** 基于间隔重复的闪卡复习。
|
||||
- **页面入口:** 学习主页"今日复习"入口、AI 快捷操作。
|
||||
- **页面组成:** 进度条、卡片正面(问题)、卡片反面(答案 + 出处)、自评按钮组("完全不会"/"有点难"/"基本会"/"很简单")。
|
||||
- **用户可执行操作:** 点击卡片翻转查看答案、点击自评按钮评分、自动跳至下一张。
|
||||
- **自动执行功能:** 评分后自动前进到下一张卡片,全部完成后自动展示庆祝动画。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 卡片正面 / 卡片反面(含自评按钮)/ 全部完成(庆祝动画覆盖层)。
|
||||
- **当前完成情况:** 占位实现(展示 3 张机器学习相关硬编码卡片,未接通 ReviewViewModel 和 API)
|
||||
|
||||
---
|
||||
|
||||
### 2.4 主动回忆页(ActiveRecallView)
|
||||
|
||||
- **页面作用:** 用户主动输出知识点内容,由 AI 评估掌握程度。
|
||||
- **页面入口:** 学习主页底部链接或 AI 快捷操作。
|
||||
- **页面组成:** 进度条、问题卡片(含题目类型标签:语音/文字 和来源)、回答输入区(TextEditor 或语音占位按钮)、提交按钮、提交确认区("下一题"/"查看 AI 分析"按钮)。
|
||||
- **用户可执行操作:** 输入文字答案、提交答案、查看 AI 分析、进入下一题。
|
||||
- **自动执行功能:** 提交答案后展示"AI 正在分析你的回答…"思考动画覆盖层,全部完成后展示庆祝动画。
|
||||
- **可跳转页面:** AIFeedbackPageView(AI 反馈页)。
|
||||
- **页面主要状态:** 答题模式 / 答案已提交 / AI 分析中(覆盖层)/ 全部完成(庆祝动画覆盖层)。
|
||||
- **当前完成情况:** 占位实现(3 道硬编码机器学习题目,第 3 题标记为语音类型但语音功能未实现)
|
||||
|
||||
---
|
||||
|
||||
## 三、知识库(底部导航 Tab 2)
|
||||
|
||||
### 3.1 知识库首页(LibraryHomeView)
|
||||
|
||||
- **页面作用:** 展示和管理用户的知识库列表。
|
||||
- **页面入口:** 底部导航"知识库" Tab。
|
||||
- **页面组成:** 标题"知识库"、搜索按钮、创建按钮、搜索栏、筛选分类横条(全部/我的/已订阅/官方)、知识库卡片列表(封面图、名称、描述、日期、可见性标签、置顶标记)。
|
||||
- **用户可执行操作:**
|
||||
- 点击知识库卡片进入详情
|
||||
- 点击搜索按钮进入搜索
|
||||
- 点击创建按钮新建知识库
|
||||
- 切换筛选分类
|
||||
- 下拉刷新
|
||||
- 无限滚动加载更多
|
||||
- **自动执行功能:** 页面加载时自动拉取知识库列表。
|
||||
- **可跳转页面:**
|
||||
- LibraryDetailPage(知识库详情)
|
||||
- LibrarySearchView(搜索)
|
||||
- CreateLibraryPage(创建知识库)
|
||||
- **页面主要状态:** 加载中 / 各分类的空状态(文案不同)/ 已加载·有数据 / 分页加载更多中 / 刷新中。
|
||||
- **当前完成情况:** 部分完成("官方"筛选返回空数组,待后端支持;搜索页仅展示空状态,未实现搜索逻辑)
|
||||
|
||||
---
|
||||
|
||||
### 3.2 知识库搜索页(LibrarySearchView)
|
||||
|
||||
- **页面作用:** 搜索知识库和知识点。
|
||||
- **页面入口:** 知识库首页点击搜索图标。
|
||||
- **页面组成:** 搜索输入框、空白搜索区域。
|
||||
- **用户可执行操作:** 输入搜索关键词(实际搜索逻辑未实现)。
|
||||
- **自动执行功能:** 无。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 搜索前空状态。
|
||||
- **当前完成情况:** 部分完成(页面框架和输入框已搭建,搜索逻辑未实现)
|
||||
|
||||
---
|
||||
|
||||
### 3.3 知识库详情页(LibraryDetailPage)
|
||||
|
||||
- **页面作用:** 查看知识库内容,管理知识点和来源文件。
|
||||
- **页面入口:** 知识库首页点击知识库卡片。
|
||||
- **页面组成:**
|
||||
- 知识库信息头部(封面、标题、描述、元数据行)
|
||||
- 两个标签页切换:知识点 Tab / 来源 Tab
|
||||
- **知识点 Tab:** 知识点列表(类型图标、类型标签、日期、学习进度)、排序菜单、操作菜单、批量选择模式
|
||||
- **来源 Tab:** 来源文件列表(含阅读状态标签、删除按钮)
|
||||
- 底部 AI 对话按钮(知识库范围)
|
||||
- 文件夹管理入口(Sheet)
|
||||
- **用户可执行操作:**
|
||||
- 切换知识点/来源 Tab
|
||||
- 点击知识点进入详情
|
||||
- 长按/滑动删除知识点
|
||||
- 批量选择与批量删除
|
||||
- 切换排序方式(默认/文件大小/创建时间/更新时间)
|
||||
- 点击上传导入资料
|
||||
- 打开文件夹管理弹窗
|
||||
- 点击底部 AI 对话按钮
|
||||
- 点击来源文件进入资料阅读
|
||||
- 删除来源文件
|
||||
- 点击"知识库管理"(操作菜单中存在,但 action 为空 TODO,未实现)
|
||||
- **自动执行功能:** 页面加载时自动拉取知识点列表和来源列表。
|
||||
- **可跳转页面:**
|
||||
- KnowledgeDetailPage(知识点详情)
|
||||
- ImportPage(导入资料)
|
||||
- AddKnowledgePage(添加知识点)
|
||||
- QuizListView(生成测验)
|
||||
- AIChatPage(AI 对话,知识库范围)
|
||||
- MaterialReaderView(资料阅读)
|
||||
- FolderManageView(文件夹管理,Sheet 弹窗)
|
||||
- **页面主要状态:**
|
||||
- 加载中 / 加载失败
|
||||
- 知识点 Tab·有数据 / 知识点 Tab·空
|
||||
- 来源 Tab·有数据 / 来源 Tab·空
|
||||
- 批量选择模式
|
||||
- 删除确认弹窗
|
||||
- **当前完成情况:** 部分完成(知识点重命名 TODO、移动到文件夹 TODO、知识库管理页 TODO、收藏状态切换 TODO)
|
||||
|
||||
---
|
||||
|
||||
### 3.4 创建知识库页(CreateLibraryPage)
|
||||
|
||||
- **页面作用:** 创建新的知识库。
|
||||
- **页面入口:** 知识库首页点击创建按钮、"我的"页学习资产入口。
|
||||
- **页面组成:** 封面图区域(可点击上传)、知识库名称输入框(必填)、描述输入框(必填)、创建按钮。
|
||||
- **用户可执行操作:** 从相册选择封面图(自动裁剪为 512×512)、输入名称和描述、点击创建。
|
||||
- **自动执行功能:** 封面上传时自动调整图片尺寸。
|
||||
- **可跳转页面:** 无(创建成功后返回上一页)。
|
||||
- **页面主要状态:** 编辑中(名称/描述为空时按钮禁用)/ 封面上传中 / 创建中。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 3.5 添加知识点页(AddKnowledgePage)
|
||||
|
||||
- **页面作用:** 向知识库添加新的知识点。
|
||||
- **页面入口:** 知识库详情页操作菜单中的"添加"。
|
||||
- **页面组成:** "内容来源"分段选择器(手动 / 文件)、手动模式下的标题输入框和内容编辑器、文件模式下的"选择文件"/"图片"按钮、已选文件列表(可移除)、上传进度指示器、保存按钮。
|
||||
- **用户可执行操作:**
|
||||
- 手动模式:输入标题和内容文字,点击保存。
|
||||
- 文件模式:选择文件(PDF/纯文本/图片)、选择照片、移除已选文件、批量保存。
|
||||
- **自动执行功能:** 文件模式下自动检测 MIME 类型,大于 2MB 的图片自动压缩,文件上传至腾讯云 COS。
|
||||
- **可跳转页面:** 无(保存成功后返回上一页)。
|
||||
- **页面主要状态:** 手动模式 / 文件模式 / 文件上传中 / 保存中。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 3.6 知识点详情页(KnowledgeDetailPage)
|
||||
|
||||
- **页面作用:** 查看知识点详细内容,支持多种文件格式渲染。
|
||||
- **页面入口:** 知识库详情页点击知识点。
|
||||
- **页面组成:** 根据内容类型不同展示不同渲染方式:
|
||||
- URL 型知识点:嵌入 MaterialReaderView 渲染
|
||||
- 纯文本知识点:直接文本渲染(支持 Markdown)
|
||||
- 图片/PDF/Word/Excel/PPT/ePub:对应原生阅读器或系统预览
|
||||
- 工具栏菜单(笔记、预览选项、阅读原文按钮)
|
||||
- **用户可执行操作:** 阅读内容、查看原文、添加笔记、收藏(UI 存在但后端未支持)。
|
||||
- **自动执行功能:** 加载知识点内容,自动从 COS 下载文件(带过期 URL 重新获取逻辑)。
|
||||
- **可跳转页面:** MaterialReaderView。
|
||||
- **页面主要状态:** 加载中 / 错误(显示概要回退文字 + 重试按钮)/ 内容已就绪。
|
||||
- **当前完成情况:** 部分完成(收藏切换有 UI 但后端 API 未支持,收藏标记为 TODO)
|
||||
|
||||
---
|
||||
|
||||
### 3.7 编辑知识点页(EditKnowledgePage)
|
||||
|
||||
- **页面作用:** 编辑知识点标题和内容。
|
||||
- **页面入口:** 知识点详情页工具栏菜单。
|
||||
- **页面组成:** 标题输入框、内容编辑器、保存按钮。
|
||||
- **用户可执行操作:** 修改标题和内容、保存。
|
||||
- **自动执行功能:** 无。
|
||||
- **可跳转页面:** 无(保存后返回)。
|
||||
- **页面主要状态:** 编辑中 / 保存中。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 3.8 导入资料页(ImportPage)
|
||||
|
||||
- **页面作用:** 向知识库导入外部资料。
|
||||
- **页面入口:** 知识库详情页操作菜单中的"导入"。
|
||||
- **页面组成:** 三种导入方式入口:文件导入、相册导入、链接导入。自动检测或提示选择目标知识库。
|
||||
- **用户可执行操作:**
|
||||
- 文件导入:选择 PDF 或纯文本文件
|
||||
- 相册导入:选择照片
|
||||
- 链接导入:输入 URL(通过弹窗)
|
||||
- **自动执行功能:** 自动选择第一个知识库,无知识库时提示用户创建。
|
||||
- **可跳转页面:** ImportReviewPage(导入候选审核页)。
|
||||
- **页面主要状态:** 选择导入方式 / 导入中 / 导入失败(错误横幅)。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 3.9 导入候选审核页(ImportReviewPage)
|
||||
|
||||
- **页面作用:** 审核 AI 从导入资料中提取的知识点候选。
|
||||
- **页面入口:** 导入资料完成后自动跳转。
|
||||
- **页面组成:** 候选知识点列表(含置信度分数)、每条候选可展开查看详情、接受/拒绝按钮、"全部接受"按钮。
|
||||
- **用户可执行操作:** 接受单个候选、拒绝单个候选、批量全部接受。
|
||||
- **自动执行功能:** 加载该来源的导入候选列表。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 加载中 / 无待审核候选 / 有待审核列表。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 3.10 发现公开库页(DiscoverView)
|
||||
|
||||
- **页面作用:** 浏览和订阅其他用户公开的知识库。
|
||||
- **页面入口:** "我的"页"发现公开库"入口。
|
||||
- **页面组成:** 公开知识库列表(标题、描述、知识条目数)、每条右侧有订阅/取消订阅按钮。
|
||||
- **用户可执行操作:** 订阅知识库、取消订阅。
|
||||
- **自动执行功能:** 加载公开知识库列表。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 加载中 / 空(无公开知识库)/ 已加载。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 3.11 文件夹管理(FolderManageView)
|
||||
|
||||
- **页面作用:** 管理知识库内的文件夹/分类。
|
||||
- **页面入口:** 知识库详情页操作菜单中的"文件夹管理"(以 Sheet 形式弹出)。
|
||||
- **页面组成:** 文件夹列表(含名称)、新建按钮、每条可滑动操作(重命名、删除)。
|
||||
- **用户可执行操作:** 创建文件夹(通过弹窗输入名称)、重命名文件夹、删除文件夹。
|
||||
- **自动执行功能:** 加载该知识库的文件夹列表。
|
||||
- **可跳转页面:** 无(Sheet 内操作)。
|
||||
- **页面主要状态:** 文件夹列表 / 新建弹窗 / 重命名弹窗。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
## 四、分析(底部导航 Tab 3)
|
||||
|
||||
### 4.1 学习分析页(AnalysisHomeView)
|
||||
|
||||
- **页面作用:** 展示学习数据分析和趋势洞察。
|
||||
- **页面入口:** 底部导航"分析" Tab。
|
||||
- **页面组成:**
|
||||
- 标题"学习分析"+ 日期范围筛选("近 7 天")
|
||||
- 4 个统计徽章:综合掌握 / 总分钟 / 复习卡片 / 活跃天
|
||||
- 4 个阅读统计徽章:今日阅读 / 本周阅读 / 已读资料 / 阅读资料
|
||||
- 掌握度趋势折线图(含动画)
|
||||
- 阅读时长趋势柱状图
|
||||
- 本周学习活跃柱状图
|
||||
- 连续学习统计(当前连续/最长连续/最后活跃)
|
||||
- 最近学习记录列表(最多 5 条)
|
||||
- 学习推荐列表(含优先级标签)
|
||||
- 继续阅读入口
|
||||
- AI 综合分析文字摘要
|
||||
- 薄弱知识点列表(最多 5 条)
|
||||
- **用户可执行操作:**
|
||||
- 点击薄弱知识点查看详情(跳转 WeakPointsPage)
|
||||
- 点击继续阅读入口(跳转 MaterialReaderView)
|
||||
- 下拉刷新数据
|
||||
- **自动执行功能:** 页面加载时自动并行拉取活动概览、趋势、连续天数、推荐、阅读数据等。
|
||||
- **可跳转页面:**
|
||||
- WeakPointsPage(薄弱知识点详情)
|
||||
- MaterialReaderView(继续阅读)
|
||||
- **页面主要状态:** 加载中 / 加载失败(错误提示 + 重试按钮)/ 已加载·有数据 / 部分数据为空时隐藏对应区域。
|
||||
- **当前完成情况:** 部分完成(掌握度趋势折线图和每周活跃柱状图使用编译时硬编码的 7 天数据,未从 ViewModel API 数据读取,属于占位实现;其他数据来自 API)
|
||||
|
||||
---
|
||||
|
||||
## 五、我的(底部导航 Tab 4)
|
||||
|
||||
### 5.1 个人中心页(ProfileView)
|
||||
|
||||
- **页面作用:** 用户个人信息与功能入口集合。
|
||||
- **页面入口:** 底部导航"我的" Tab。
|
||||
- **页面组成:**
|
||||
- 顶部导航栏:标题"我的"、发现公开库按钮、通知图标、设置图标
|
||||
- 个人资料卡片(头像、昵称、邮箱、活跃天/复习卡片/分钟统计)
|
||||
- 功能菜单:学习目标设置、复习提醒、学习方法偏好、帮助与反馈
|
||||
- 学习资产区域:知识库/条目/卡片计数、发现公开库入口、消息中心入口、存储空间展示
|
||||
- **用户可执行操作:**
|
||||
- 点击资料卡片进入编辑资料
|
||||
- 点击各菜单项进入对应子页面
|
||||
- 点击通知图标进入通知列表
|
||||
- 点击设置图标进入设置
|
||||
- **自动执行功能:** 页面加载时自动拉取用户资料、活动摘要、资产和存储统计。
|
||||
- **可跳转页面:**
|
||||
- EditProfilePage(编辑资料)
|
||||
- GoalSettingDetailView(学习目标设置)
|
||||
- SettingsView(设置,从复习提醒行进入也是设置)
|
||||
- MethodPreferenceView(学习方法偏好)
|
||||
- FeedbackFormView(帮助与反馈)
|
||||
- CreateLibraryPage(学习资产入口)
|
||||
- DiscoverView(发现公开库)
|
||||
- NotificationListView(通知列表/消息中心)
|
||||
- **页面主要状态:** 加载中 / 已加载(含默认值和占位信息)。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 5.2 编辑资料页(EditProfilePage)
|
||||
|
||||
- **页面作用:** 编辑个人资料信息。
|
||||
- **页面入口:** 个人中心页点击资料卡片。
|
||||
- **页面组成:**
|
||||
- 头像区域(可点击上传,自动裁剪为正方形 256×256)
|
||||
- 基本信息区:昵称输入框、学习身份输入框
|
||||
- 学习档案区:学习方向输入框、当前目标输入框
|
||||
- 个人简介输入框
|
||||
- 保存按钮(含加载状态)
|
||||
- **用户可执行操作:** 从相册选择头像、编辑各文本字段、保存。
|
||||
- **自动执行功能:** 头像选择后自动裁剪上传。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 加载中(加载现有资料)/ 编辑中 / 头像上传中 / 保存中 / 错误提示。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 5.3 设置页(SettingsView)
|
||||
|
||||
- **页面作用:** 应用全局设置。
|
||||
- **页面入口:** 个人中心页点击设置图标或"复习提醒"行。
|
||||
- **页面组成:**
|
||||
- 外观与语言区:外观模式选择(跟随系统/深色/浅色)、语言
|
||||
- 学习设置区:学习目标(导航)、方法偏好(导航)
|
||||
- 复习提醒区:提醒开关、提醒时间选择器、间隔天数选择器
|
||||
- 通知设置区:复习提醒开关、导入完成通知开关、系统通知开关
|
||||
- 数据与存储区:存储空间、iCloud 同步开关
|
||||
- 账号区:个人信息、设备管理
|
||||
- 帮助与反馈、隐私政策、用户协议
|
||||
- 退出登录按钮(带确认弹窗)
|
||||
- 底部关于信息(版本号)
|
||||
- **用户可执行操作:** 切换外观模式、设置复习提醒时间和间隔天数、切换通知开关、iCloud 同步开关、退出登录、跳转子页面。
|
||||
- **自动执行功能:** 外观模式变更时自动保存至用户偏好 API。
|
||||
- **可跳转页面:**
|
||||
- GoalSettingDetailView(学习目标设置)
|
||||
- MethodPreferenceView(方法偏好)
|
||||
- **页面主要状态:** 各开关状态、退出登录确认弹窗。
|
||||
- **当前完成情况:** 部分完成(三个通知开关绑定到同一个 $reviewReminder 变量,存在明确 bug;"设备管理"、"隐私政策"、"用户协议"入口无导航目标;"存储空间"行导航目标为 Route.settings 自身,形成无效自引用;"登录设备管理"行同理,导航目标也为 Route.settings 自身)
|
||||
|
||||
---
|
||||
|
||||
### 5.4 学习目标设置页(GoalSettingDetailView)
|
||||
|
||||
- **页面作用:** 配置学习目标和每日学习时长。
|
||||
- **页面入口:** 设置页"学习目标"或"我的"页"学习目标设置"。
|
||||
- **页面组成:** 四个学习目标选项(备考考试/职业技能/通识学习/自定义)、四个每日学习时间选项(15分钟/30分钟/1小时/不限制)。
|
||||
- **用户可执行操作:** 选择目标和时间,保存。
|
||||
- **自动执行功能:** 保存至用户 API。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 当前选中态展示。
|
||||
- **当前完成情况:** 部分完成(学习目标选择通过 API 保存,但每日学习时长 dailyMins 仅保存在本地 @State 变量,不通过 API 持久化,下次进入恢复默认"30 分钟")
|
||||
|
||||
---
|
||||
|
||||
### 5.5 学习方法偏好页(MethodPreferenceView)
|
||||
|
||||
- **页面作用:** 配置偏好的学习方式。
|
||||
- **页面入口:** 设置页或"我的"页"学习方法偏好"。
|
||||
- **页面组成:** 四种方法选项(间隔回忆/费曼技巧/AI分析/主动回忆),多选框形式。
|
||||
- **用户可执行操作:** 多选/取消方法,保存。
|
||||
- **自动执行功能:** 保存至用户偏好 API。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 选中/未选中。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 5.6 通知列表页(NotificationListView)
|
||||
|
||||
- **页面作用:** 查看和管理系统通知。
|
||||
- **页面入口:** "我的"页通知图标或消息中心入口。
|
||||
- **页面组成:** 通知列表按日期分组(今天/本周/更早),每条通知含类型图标、标题、内容、时间、已读/未读状态。顶部"全部已读"按钮。
|
||||
- **用户可执行操作:** 点击单条通知标记为已读、点击"全部已读"。
|
||||
- **自动执行功能:** 加载通知列表。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 加载中 / 有通知 / 无通知。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 5.7 帮助与反馈页(FeedbackFormView)
|
||||
|
||||
- **页面作用:** 用户提交反馈和问题报告。
|
||||
- **页面入口:** "我的"页"帮助与反馈"、设置页"帮助与反馈"。
|
||||
- **页面组成:** 反馈类型选择器(Bug反馈/功能建议/内容问题/其他)、内容输入框、提交按钮。
|
||||
- **用户可执行操作:** 选择反馈类型、输入描述文字、提交。
|
||||
- **自动执行功能:** 提交至反馈 API。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 编辑中 / 提交中 / 已提交(可继续提交新的)。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
## 六、AI 辅助功能(跨模块访问)
|
||||
|
||||
### 6.1 AI 对话页(AIChatPage)
|
||||
|
||||
- **页面作用:** 与 AI 进行学习相关的对话互动。
|
||||
- **页面入口:** 知识库详情页底部 AI 对话按钮、AI 反馈页"深入提问"、资料阅读页工具栏 AI 按钮(多处入口,均可附带对话范围上下文)。
|
||||
- **页面组成:**
|
||||
- 对话消息列表(用户消息紫色渐变气泡、AI 消息含思考过程和内容)
|
||||
- AI 思考过程区(可折叠、含流式输出动画)
|
||||
- 范围标签(当对话限定在特定知识库/资料时显示)
|
||||
- 工具栏按钮(新建对话、会话列表)
|
||||
- 底部输入栏(文字输入框、语音图标(占位)、发送按钮)
|
||||
- AI 回复完成后显示"复制"和"重新生成"按钮
|
||||
- **用户可执行操作:**
|
||||
- 发送文字消息
|
||||
- 查看 AI 思考过程
|
||||
- 复制 AI 回复
|
||||
- 重新生成回复
|
||||
- 新建对话
|
||||
- 打开会话列表 Sheet
|
||||
- 在会话列表中搜索、删除、归档会话
|
||||
- **自动执行功能:** 流式接收 AI 回复并实时展示,自动创建或恢复对话会话。
|
||||
- **可跳转页面:** 无(页面内操作)。
|
||||
- **页面主要状态:**
|
||||
- 创建会话中 / 会话创建失败
|
||||
- 消息列表(含滚动加载历史)
|
||||
- AI 回复流式输出中(含思考动画)
|
||||
- 会话列表 Sheet(搜索、筛选、编辑操作)
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 6.2 每日思考页(DailyThinkingPage)
|
||||
|
||||
- **页面作用:** 展示一道每日思考题,用户提交回答后获取 AI 反馈。
|
||||
- **页面入口:** AI 反馈页"再来一题"。
|
||||
- **页面组成:** 思考题目(硬编码:"Transformer 中的注意力机制")、评估要点提示、回答输入框、"提交获取 AI 反馈"按钮。
|
||||
- **用户可执行操作:** 输入答案、提交获取 AI 反馈。
|
||||
- **自动执行功能:** 无。
|
||||
- **可跳转页面:** AIFeedbackPageView。
|
||||
- **页面主要状态:** 回答中 / 提交后跳转。
|
||||
- **当前完成情况:** 占位实现(题目硬编码,无 ViewModel,无动态题目来源。注:submitted 状态变量在代码中从未被设置为 true,提交按钮始终可见,可能导致用户重复提交)
|
||||
|
||||
---
|
||||
|
||||
### 6.3 AI 反馈页(AIFeedbackPageView)
|
||||
|
||||
- **页面作用:** 展示 AI 对用户回答的分析评分和建议。
|
||||
- **页面入口:** 主动回忆完成后、每日思考提交后、回忆测试提交后。
|
||||
- **页面组成(两阶段):**
|
||||
- 分析中:动画步骤指示器("解析你的回答结构…"等 4 步,约 5 秒)
|
||||
- 分析结果:得分圆环、掌握度评价文字、用户原始回答、答对的部分列表、需要完善的内容、参考答案要点、"加入待巩固"按钮、"深入提问"按钮、"再来一题"按钮
|
||||
- **用户可执行操作:** 查看分析结果、加入待巩固(跳转学习主页)、深入提问(跳转 AI 对话)、再来一题(跳转每日思考)。
|
||||
- **自动执行功能:** 模拟分析过程(5 秒后自动展示结果)。
|
||||
- **可跳转页面:** StudyHomeView、AIChatPage、DailyThinkingPage。
|
||||
- **页面主要状态:** 分析中 / 分析结果。
|
||||
- **当前完成情况:** 占位实现(得分 78/100 硬编码,所有分析文字硬编码,未接通真实 AI 分析 API)
|
||||
|
||||
---
|
||||
|
||||
### 6.4 薄弱知识点页(WeakPointsPage)
|
||||
|
||||
- **页面作用:** 展示用户的薄弱知识点列表。
|
||||
- **页面入口:** 学习分析页薄弱知识点区域"全部"链接。
|
||||
- **页面组成:** 薄弱知识点列表,每项含掌握度分数、知识点名称、所属知识库、优先级标签(高/中)。
|
||||
- **用户可执行操作:** 查看列表。
|
||||
- **自动执行功能:** 无。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 展示态。
|
||||
- **当前完成情况:** 占位实现(5 个硬编码知识点,主题为贝叶斯定理/正态分布/词根/Covariance/梯度下降,无 ViewModel,未接通 API)
|
||||
|
||||
---
|
||||
|
||||
### 6.5 AI 首页(AIHomeView)
|
||||
|
||||
- **页面作用:** 原本设计为 AI 功能的聚合首页,包含快速操作入口、每日思考题和 AI 输入。
|
||||
- **页面入口:** 代码中无任何页面跳转到此页——该页面未接入导航系统,属于废弃页面。
|
||||
- **页面组成:** 日期 + 服务器状态、Hero 区、Rive 动画占位、4 个快捷操作按钮、每日思考卡片、推荐问题列表、底部输入栏。
|
||||
- **用户可执行操作:** (理论上的操作,实际不可达)
|
||||
- **自动执行功能:** 健康检查服务器状态。
|
||||
- **可跳转页面:** (理论上)ActiveRecallView、WeakPointsPage、AIChatPage、ReviewCardView、DailyThinkingPage。
|
||||
- **页面主要状态:** 服务器在线/检查中/离线。
|
||||
- **当前完成情况:** 占位实现(已废弃,无导航入口。Rive 动画标注为占位,推荐问题硬编码)
|
||||
|
||||
---
|
||||
|
||||
### 6.6 回忆测试页(RecallTestPage)
|
||||
|
||||
- **页面作用:** 用户对特定知识点进行回忆测试,输入理解后提交,获取 AI 反馈。
|
||||
- **页面入口:** 代码中无任何页面跳转到此页——Route 枚举中无对应 case,属于代码存在但无导航入口的页面。
|
||||
- **页面组成:** 提示文字(硬编码:"请回忆并写下你对「偏差-方差权衡」的理解")、TextEditor 回答输入框、"提交"按钮。
|
||||
- **用户可执行操作:** (理论上的操作,实际不可达)输入答案、提交获取 AI 反馈。
|
||||
- **自动执行功能:** 无。
|
||||
- **可跳转页面:** (理论上)AIFeedbackPageView。
|
||||
- **页面主要状态:** 编辑中 / 提交后跳转。
|
||||
- **当前完成情况:** 占位实现(无导航入口,题目硬编码,无 ViewModel。注:submitted 状态变量在代码中从未被设置为 true,提交按钮始终可见,可能导致用户重复提交)
|
||||
|
||||
---
|
||||
|
||||
## 七、测验功能(跨模块访问)
|
||||
|
||||
### 7.1 测验列表页(QuizListView)
|
||||
|
||||
- **页面作用:** 查看知识库下的所有测验,并可以生成新测验。
|
||||
- **页面入口:** 知识库详情页操作菜单中的"测验"。
|
||||
- **页面组成:** 测验列表(含测验标题等信息)、空状态提示("暂无测验"+"生成测验"按钮)、"生成新测验"按钮。
|
||||
- **用户可执行操作:** 生成新测验、点击已有测验进入作答。
|
||||
- **自动执行功能:** 加载该知识库的测验列表。
|
||||
- **可跳转页面:** QuizTakerView(测验作答)。
|
||||
- **页面主要状态:** 加载中 / 空(引导生成)/ 有测验列表 / 生成失败(Toast 提示)。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 7.2 测验作答页(QuizTakerView)
|
||||
|
||||
- **页面作用:** 逐题作答。
|
||||
- **页面入口:** 测验列表点击测验、学习主页自我测试入口。
|
||||
- **页面组成:** 进度条(当前题号/总题数)、题目题干、选项/答案区。支持三种题型:选择题(A/B/C/D 单选)、判断题(正确/错误按钮)、填空题(文本输入)。
|
||||
- **用户可执行操作:** 选择题选择答案、判断正误、输入填空答案、上一题/下一题导航、提交全部答案。
|
||||
- **自动执行功能:** 提交后自动计算得分。
|
||||
- **可跳转页面:** QuizResultView(测验结果)。
|
||||
- **页面主要状态:** 答题中 / 提交中。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 7.3 测验结果页(QuizResultView)
|
||||
|
||||
- **页面作用:** 展示测验得分和详细答题情况。
|
||||
- **页面入口:** 测验作答提交后自动跳转。
|
||||
- **页面组成:** 大号得分数字(低于 60 分红色、高于 60 分绿色)、正确/总题数统计、"重新测验"按钮、逐题详细结果(正确/错误标记 + 解析)。
|
||||
- **用户可执行操作:** 查看每道题的结果和解析、点击重新测验。
|
||||
- **自动执行功能:** 加载测验结果详情。
|
||||
- **可跳转页面:** 无(重新测验回到 QuizTakerView 或 QuizListView)。
|
||||
- **页面主要状态:** 加载中 / 结果已加载。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
## 八、资料阅读(跨模块访问)
|
||||
|
||||
### 8.1 资料阅读页(MaterialReaderView)
|
||||
|
||||
- **页面作用:** 阅读学习资料,支持多种文件格式。
|
||||
- **页面入口:** 学习主页"继续学习"、学习分析页"继续阅读"、知识库详情页来源文件、知识点详情页。
|
||||
- **页面组成:**
|
||||
- 根据文件类型不同展示不同内容:
|
||||
- Markdown/文本/图片:原生渲染(标题、段落、列表、代码块、引用、表格、图片)
|
||||
- PDF/Word/Excel:系统预览按钮(QuickLook)
|
||||
- PowerPoint:外部打开按钮(ShareLink)
|
||||
- 不支持的格式:提示文字
|
||||
- 工具栏按钮:标记已读、AI 对话(资料范围)、资料详情、开始学习会话、知识提取
|
||||
- 笔记功能入口(Sheet)
|
||||
- 解析状态 Toast
|
||||
- **用户可执行操作:**
|
||||
- 阅读/滚动内容
|
||||
- 标记已读/取消标记
|
||||
- 打开 AI 对话(资料范围)
|
||||
- 查看资料详情
|
||||
- 开始学习会话
|
||||
- 添加笔记
|
||||
- QuickLook 预览(PDF/Office)
|
||||
- 外部打开(PowerPoint)
|
||||
- **自动执行功能:**
|
||||
- 自动记录阅读位置(2 秒防抖上报)
|
||||
- 自动开始/暂停/恢复阅读会话(前后台切换)
|
||||
- 自动心跳上报(15 秒间隔)
|
||||
- 优先恢复上次阅读位置(API > 本地缓存 > 会话位置)
|
||||
- 文件不存在时自动从 COS 下载
|
||||
- 后台时自动导出并上传阅读事件
|
||||
- **可跳转页面:**
|
||||
- AIChatPage(资料范围对话)
|
||||
- MaterialDetailView(资料详情)
|
||||
- LearningSessionView(学习会话)
|
||||
- **页面主要状态:** 加载中 / 加载失败(重试)/ 已加载·按格式渲染 / 解析状态 Toast。
|
||||
- **当前完成情况:** 部分完成(核心功能已就位,解析触发使用 60×2s 硬编码轮询,存在改进空间)
|
||||
|
||||
---
|
||||
|
||||
### 8.2 资料详情页(MaterialDetailView)
|
||||
|
||||
- **页面作用:** 展示资料的元数据、处理状态和学习统计。
|
||||
- **页面入口:** 资料阅读页工具栏"信息"按钮。
|
||||
- **页面组成:**
|
||||
- "原始文件"区域:AI 处理状态横幅(处理中/就绪/失败)、文件元数据(名称、格式、大小、上传日期)、阅读进度卡片
|
||||
- "学习内容"区域:知识点计数、测验计数
|
||||
- **用户可执行操作:** 查看文件信息、查看阅读进度、查看关联学习内容。
|
||||
- **自动执行功能:** 并行加载知识库详情、知识点列表、测验列表、阅读进度。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:**
|
||||
- AI 处理状态:处理中(琥珀色横幅)/ 就绪(绿色横幅)/ 失败(红色横幅)
|
||||
- 数据加载中
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
## 九、弹窗与 Sheet
|
||||
|
||||
### 9.1 快速笔记(QuickNoteSheet)
|
||||
|
||||
- **页面作用:** 在阅读过程中快速添加笔记。
|
||||
- **页面入口:** 资料阅读页工具栏笔记按钮(以 Sheet 形式弹出)。
|
||||
- **页面组成:** 资料上下文头部、笔记内容 TextEditor(自动聚焦)、取消/保存按钮。
|
||||
- **用户可执行操作:** 输入笔记文字、保存或取消。
|
||||
- **自动执行功能:** 自动获取当前阅读位置作为笔记锚点。
|
||||
- **可跳转页面:** 无(Sheet 内操作)。
|
||||
- **页面主要状态:** 编辑中 / 保存后关闭。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 9.2 系统预览(QuickLook)
|
||||
|
||||
- **页面作用:** 使用系统 QuickLook 预览 PDF、Word、Excel 等 Office 文件。
|
||||
- **页面入口:** 资料阅读页中非原生支持格式的"系统预览"按钮(以 Sheet 形式弹出)。
|
||||
- **页面组成:** 系统原生 QLPreviewController。
|
||||
- **用户可执行操作:** 系统标准的文件预览操作。
|
||||
- **自动执行功能:** 无。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 加载中 / 预览中。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 9.3 AI 会话列表 Sheet
|
||||
|
||||
- **页面作用:** 浏览和管理历史 AI 对话会话。
|
||||
- **页面入口:** AI 对话页工具栏"会话列表"按钮(以 Sheet 形式弹出,支持 .medium 和 .large 展示高度)。
|
||||
- **页面组成:** 可搜索会话列表,每条显示会话范围和最后消息时间;支持滑动操作(删除、归档)。
|
||||
- **用户可执行操作:** 搜索会话、切换会话、删除会话、归档会话。
|
||||
- **自动执行功能:** 根据当前对话范围过滤会话列表。
|
||||
- **可跳转页面:** 选择会话后关闭 Sheet 并加载对应对话。
|
||||
- **页面主要状态:** 会话列表 / 搜索中 / 空列表。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 9.4 封面选择 Sheet
|
||||
|
||||
- **页面作用:** 为知识库选择封面图片。
|
||||
- **页面入口:** 创建知识库页封面区域点击(以 Sheet 形式弹出,固定高度 220pt)。
|
||||
- **页面组成:** "从相册选择"选项。
|
||||
- **用户可执行操作:** 打开系统相册选择图片。
|
||||
- **自动执行功能:** 图片自动缩放为 512×512。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 选择中。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 9.5 链接导入弹窗
|
||||
|
||||
- **页面作用:** 输入 URL 以导入链接内容。
|
||||
- **页面入口:** 导入资料页"链接导入"按钮(以 Alert 形式弹出,含输入框)。
|
||||
- **页面组成:** 输入框(URL)、确认/取消按钮。
|
||||
- **用户可执行操作:** 输入链接地址、确认导入。
|
||||
- **自动执行功能:** 无。
|
||||
- **可跳转页面:** 无。
|
||||
- **页面主要状态:** 输入中。
|
||||
- **当前完成情况:** 已完成
|
||||
|
||||
---
|
||||
|
||||
### 9.6 各类确认弹窗
|
||||
|
||||
以下为各页面中使用的系统 Alert 确认弹窗:
|
||||
|
||||
| 弹窗 | 所在页面 | 触发操作 |
|
||||
|------|---------|---------|
|
||||
| 删除知识库确认 | LibraryDetailPage | 操作菜单"删除知识库" |
|
||||
| 批量删除确认 | LibraryDetailPage | 批量选择后点击删除 |
|
||||
| 新建文件夹 | FolderManageView | 点击"新建" |
|
||||
| 重命名文件夹 | FolderManageView | 滑动->重命名 |
|
||||
| 退出登录确认 | SettingsView | 点击"退出登录" |
|
||||
| 结束学习确认 | LearningSessionView | 点击"结束"(confirmationDialog) |
|
||||
|
||||
以上确认弹窗均已完成。
|
||||
263
docs/system-map/ios/02-iOS页面功能总表.md
Normal file
263
docs/system-map/ios/02-iOS页面功能总表.md
Normal file
@ -0,0 +1,263 @@
|
||||
# 02 iOS 页面功能总表
|
||||
|
||||
> 按页面逐一列出所有用户可见的功能点。
|
||||
|
||||
---
|
||||
|
||||
## 启<><E590AF>与登录
|
||||
|
||||
| 所属模块 | 所属页面 | 功能名称 | 触发方式 | 功能结果 | 是否跨页面 | 当前完成情况 | 备注 |
|
||||
|---------|---------|---------|---------|---------|-----------|------------|------|
|
||||
| 启动 | 启动页 | 自动恢复登录会话 | 自动(应用启动) | 读取钥匙串 Token,调用 API 校验,恢复登录或跳转登录页 | 是 | 已完成 | |
|
||||
| 登录 | 欢迎页 | 查看产品功能介绍 | 页面展示 | 了解产品核心功能 | 否 | 已完成 | |
|
||||
| 登录 | 欢迎页 | 进入登录流程 | 点击"开始使用"按钮 | 跳转登录页 | 是 | 已完成 | |
|
||||
| 登录 | 登录页 | Apple ID 登录 | 点击 Sign in with Apple 按钮 | 调用 Apple 认证,获取 Token,登录成功 | 是 | 已完成 | 支持 nonce 验证 |
|
||||
| 登录 | 登录页 | 取消登录 | 点击"取消"按钮(登录中时显示) | 取消登录任务 | 否 | 已完成 | |
|
||||
| 登录 | 账号状态页 | 查看账号状态说明 | 页面展示 | 了解账号被禁用/已注销的原因 | 否 | 已完成 | |
|
||||
| 登录 | 账号状态页 | 返回登录页 | 点击"返回首页"按钮 | 回到未登录状态 | 是 | 已完成 | |
|
||||
| 引导 | 引导页 | 浏览产品引导 | 点击"下一步"依次浏览 4 步 | 了解产品核心流程 | 否 | 已完成 | |
|
||||
| 引导 | 引导页 | 跳过引导 | 点击"跳过"链接 | 直接进入目标设置 | 是 | 已完成 | |
|
||||
| 引导 | 目标设置页 | 选择学习目标 | 点击四选一目标 | 选中学习目标 | 否 | 已完成 | |
|
||||
| 引导 | 目标设置页 | 选择学习方法 | 点击多选方法 | 选中学习偏好方法 | 否 | 已完成 | |
|
||||
| 引导 | 目标设置页 | 选择每日学习时间 | 点击四选一时间 | 选中每日时长 | 否 | 部分完成 | 选择和进入主界面已完成,但每日学习时长仅保存在本地 @State,没有可靠持久化 |
|
||||
| 引导 | 目标设置页 | 确认并开始学习 | 点击"开始学习"按钮 | 进入主界面 | 是 | 部分完成 | 进入主界面已完成,但每日学习时长未持久化 |
|
||||
|
||||
---
|
||||
|
||||
## 学习 Tab
|
||||
|
||||
| 所属模块 | 所属页面 | 功能名称 | 触发方式 | 功能结果 | 是否跨页面 | 当前完成情况 | 备注 |
|
||||
|---------|---------|---------|---------|---------|-----------|------------|------|
|
||||
| 学习 | 学习主页 | 查看连续学习天数 | 页面展示 | 查看连续天数和火焰图标 | 否 | 已完成 | |
|
||||
| 学习 | 学习主页 | 继续上次学习 | 点击主操作卡片(优先级最高时) | 跳转到资料阅读页继续阅读 | 是 | 已完成 | 优先级自动计算 |
|
||||
| 学习 | 学习主页 | 开始今日复习 | 点击主操作卡片或复习卡片 | 跳转复习卡片页 | 是 | 部分完成 | 入口正常,内容页为占位 |
|
||||
| 学习 | 学习主页 | 进行自我测试 | 点击主操作卡片或测试卡片 | 跳转测验作答页 | 是 | 已完成 | |
|
||||
| 学习 | 学习主页 | 创建知识库引导 | 点击主操作卡片(空状态时) | 切换到知识库 Tab | 是 | 已完成 | |
|
||||
| 学习 | 学习主页 | 探索公开知识库 | 点击辅助按钮(空状态时) | 切换到知识库 Tab | 是 | 已完成 | |
|
||||
| 学习 | 学习主页 | 查看每周摘要 | 页面展示 | 查看本周分钟数、复习卡片数、活跃天数、连续天数 | 否 | 已完成 | |
|
||||
| 学习 | 学习主页 | 查看完整分析 | 点击底部链接 | 跳转主动回忆页 | 是 | 已完成 | 入口存在,跳转目标为占位页 |
|
||||
| 学习 | 学习主页 | 下拉刷新 | 手势下拉 | 重新加载学习数据 | 否 | 已完成 | |
|
||||
| 学习 | 学习会话页 | 专注计时学习 | 自动开始 | 计时学习时长,1 秒精度 | 否 | 暂未确认 | 默认 30 分钟;本地计时完成,但代码中未发现调用 LearningSessionService API 保存学习记录 |
|
||||
| 学习 | 学习会话页 | 暂停学习 | 点击暂停按钮 | 暂停计时 | 否 | 已完成 | |
|
||||
| 学习 | 学习会话页 | 继续学习 | 点击继续按钮 | 恢复计时 | 否 | 已完成 | |
|
||||
| 学习 | 学习会话页 | 结束学习 | 点击结束按钮,确认弹窗 | 结束计时,展示庆祝动画 | 否 | 已完成 | |
|
||||
| 学习 | 学习会话页 | 查看庆祝动画 | 自动(学习结束时) | 展示学习完成庆祝效果 | 否 | 已完成 | |
|
||||
|
||||
---
|
||||
|
||||
## 知识库 Tab
|
||||
|
||||
| 所属模块 | 所属页面 | 功能名称 | 触发方式 | 功能结果 | 是否跨页面 | 当前完成情况 | 备注 |
|
||||
|---------|---------|---------|---------|---------|-----------|------------|------|
|
||||
| 知识库 | 知识库首页 | 查看知识库列表 | 页面加载 | 查看知识库卡片(封面、名称、描述、日期、标签) | 否 | 已完成 | |
|
||||
| 知识库 | 知识库首页 | 筛选知识库 | 点击筛选分类(全部/我的/已订阅/官方) | 按分类过滤列表 | 否 | 部分完成 | "官方"筛选返回空数据 |
|
||||
| 知识库 | 知识库首页 | 搜索知识库 | 点击搜索图标 | 跳转搜索页 | 是 | 部分完成 | 搜索逻辑未实现 |
|
||||
| 知识库 | 知识库首页 | 创建知识库 | 点击创建按钮 | 跳转创建知识库页 | 是 | 已完成 | |
|
||||
| 知识库 | 知识库首页 | 查看知识库详情 | 点击知识库卡片 | 跳转知识库详情页 | 是 | 已完成 | |
|
||||
| 知识库 | 知识库首页 | 下拉刷新 | 手势下拉 | 刷新列表 | 否 | 已完成 | |
|
||||
| 知识库 | 知识库首页 | 加载更多 | 滚动到底部 | 分页加载更多知识库 | 否 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 查看知识库信息 | 页面加载 | 查看封面、标题、描述、元数据 | 否 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 浏览知识点列表 | 页面展示(默认 Tab) | 查看知识点列表(类型图标、标签、日期) | 否 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 浏览来源文件列表 | 切换到"来源"Tab | 查看来源文件列表(阅读状态标签) | 否 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 查看知识点详情 | 点击知识点条目 | 跳转知识点详情页 | 是 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 删除知识点 | 滑动/长按删除 | 删除知识点 | 否 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 批量删除知识点 | 进入批量选择模式,选中多个,点击删除 | 批量删除选中的知识点 | 否 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 批量选择模式 | 点击工具栏"批量选择" | 进入多选模式,可全选和逐选 | 否 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 切换排序方式 | 点击排序菜单 | 按默认/文件大小/创建时间/更新时间排序 | 否 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 导入资料 | 操作菜单→"上传" | 跳转导入资料页 | 是 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 添加知识点 | 操作菜单→"添加" | 跳转添加知识点页 | 是 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 生成测验 | 操作菜单→"测验" | 跳转测验列表页 | 是 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 管理文件夹 | 操作菜单→"文件夹管理" | 弹出文件夹管理 Sheet | 是(Sheet) | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 与 AI 对话 | 点击底部 AI 按钮 | 跳转 AI 对话页(知识库范围) | 是 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 阅读来源文件 | 点击来源文件条目 | 跳转资料阅读页 | 是 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 删除来源文件 | 来源文件滑动删除 | 删除来源文件 | 否 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 删除知识库 | 操作菜单→"删除知识库",确认弹窗 | 删除整个知识库 | 否 | 已完成 | |
|
||||
| 知识库 | 知识库详情页 | 重命名知识点 | (预留菜单项) | TODO,未实现 | 否 | 未完成 | 代码中标注 TODO |
|
||||
| 知识库 | 知识库详情页 | 移动知识点到文件夹 | (预留菜单项) | TODO,未实现 | 否 | 未完成 | 代码中标注 TODO |
|
||||
| 知识库 | 知识库详情页 | 知识库管理 | (预留菜单项) | TODO,未实现 | 是 | 未完成 | 代码中标注 TODO |
|
||||
| 知识库 | 创建知识库页 | 上传封面图 | 点击封面区域→相册选择 | 选中图片自动裁剪为 512×512 | 否 | 已完成 | |
|
||||
| 知识库 | 创建知识库页 | 输入知识库名称 | 文本输入 | 填写名称 | 否 | 已完成 | 必填 |
|
||||
| 知识库 | 创建知识库页 | 输入知识库描述 | 文本输入 | 填写描述 | 否 | 已完成 | 必填 |
|
||||
| 知识库 | 创建知识库页 | 确认创建 | 点击创建按钮 | 调用 API 创建知识库,返回上一页 | 否 | 已完成 | 名称或描述为空时禁用 |
|
||||
| 知识库 | 添加知识点页 | 手动添加知识点 | 选择"手动"模式,输入标题+内容,保存 | 创建文本型知识点 | 否 | 已完成 | |
|
||||
| 知识库 | 添加知识点页 | 文件添加知识点 | 选择"文件"模式,选择文件/图片,批量保存 | 上传文件并创建知识点 | 否 | 已完成 | 支持 PDF/文本/图片,图片自动压缩 |
|
||||
| 知识库 | 添加知识点页 | 移除已选文件 | 点击文件旁的移除按钮 | 从待上传列表中移除该文件 | 否 | 已完成 | |
|
||||
| 知识库 | 知识点详情页 | 阅读知识点内容 | 页面展示 | 按类型渲染内容(文本/Markdown/文件) | 否 | 已完成 | 支持多种文件格式 |
|
||||
| 知识库 | 知识点详情页 | 收藏知识点 | 工具栏菜单→"收藏" | 切换收藏状态(UI 已实现) | 否 | 部分完成 | 后端 API 未支持,标记 TODO |
|
||||
| 知识库 | 知识点详情页 | 添加笔记 | 工具栏菜单→"笔记" | 跳转笔记编辑 | 否 | 已完成 | |
|
||||
| 知识库 | 知识点详情页 | 查看原文 | 工具栏→"阅读原文"(文本型内容) | 切换到原文模式 | 否 | 已完成 | |
|
||||
| 知识库 | 知识点详情页 | 系统预览文件 | 自动(平台预览模式) | 使用系统预览查看文件 | 否 | 已完成 | PDF/Word/Excel |
|
||||
| 知识库 | 编辑知识点页 | 编辑标题 | 文本输入 | 修改标题 | 否 | 已完成 | |
|
||||
| 知识库 | 编辑知识点页 | 编辑内容 | 文本编辑器 | 修改内容 | 否 | 已完成 | |
|
||||
| 知识库 | 编辑知识点页 | 保存修改 | 点击保存按钮 | 调用 API 更新知识点 | 否 | 已完成 | |
|
||||
| 知识库 | 导入资料页 | 文件导入 | 点击"文件导入"→选择文件 | 导入 PDF 或纯文本文件 | 否 | 已完成 | |
|
||||
| 知识库 | 导入资料页 | 相册导入 | 点击"相册导入"→选择照片 | 从相册导入图片 | 否 | 已完成 | |
|
||||
| 知识库 | 导入资料页 | 链接导入 | 点击"链接导入"→输入 URL | 导入链接内容 | 否 | 已完成 | 通过 Alert 弹窗输入 URL |
|
||||
| 知识库 | 导入候选审核页 | 查看导入候选 | 页面加载 | 查看 AI 从导入资料中提取的知识点候选(含置信度) | 否 | 已完成 | |
|
||||
| 知识库 | 导入候选审核页 | 接受单个候选 | 展开候选→点击"接受" | 接受该知识点 | 否 | 已完成 | |
|
||||
| 知识库 | 导入候选审核页 | 拒绝单个候选 | 展开候选→点击"拒绝" | 拒绝该知识点 | 否 | 已完成 | |
|
||||
| 知识库 | 导入候选审核页 | 批量接受全部 | 点击"全部接受"按钮 | 接受所有候选知识点 | 否 | 已完成 | |
|
||||
| 知识库 | 发现公开库页 | 浏览公开库 | 页面加载 | 查看可订阅的公开知识库列表 | 否 | 已完成 | |
|
||||
| 知识库 | 发现公开库页 | 订阅知识库 | 点击订阅按钮 | 订阅该知识库 | 否 | 已完成 | |
|
||||
| 知识库 | 发现公开库页 | 取消订阅 | 点击取消订阅按钮 | 取消订阅 | 否 | 已完成 | |
|
||||
| 知识库 | 文件夹管理 | 查看文件夹列表 | Sheet 展示 | 查看该知识库的文件夹列表 | 否 | 已完成 | |
|
||||
| 知识库 | 文件夹管理 | 新建文件夹 | 点击"新建"→输入名称 | 创建新文件夹 | 否 | 已完成 | |
|
||||
| 知识库 | 文件夹管理 | 重命名文件夹 | 滑动→"重命名"→输入名称 | 修改文件夹名称 | 否 | 已完成 | |
|
||||
| 知识库 | 文件夹管理 | 删除文件夹 | 滑动→"删除" | 删除文件夹 | 否 | 已完成 | |
|
||||
|
||||
---
|
||||
|
||||
## 分析 Tab
|
||||
|
||||
| 所属模块 | 所属页面 | 功能名称 | 触发方式 | 功能结果 | 是否跨页面 | 当前完成情况 | 备注 |
|
||||
|---------|---------|---------|---------|---------|-----------|------------|------|
|
||||
| 分析 | 学习分析页 | 查看综合掌握度 | 页面展示 | 查看掌握度百分比 | 否 | 已完成 | |
|
||||
| 分析 | 学习分析页 | 查看总学习分钟 | 页面展示 | 查看累计学习时长 | 否 | 已完成 | |
|
||||
| 分析 | 学习分析页 | 查看复习卡片数 | 页面展示 | 查看累计复习卡片数 | 否 | 已完成 | |
|
||||
| 分析 | 学习分析页 | 查看活跃天数 | 页面展示 | 查看活跃学习天数 | 否 | 已完成 | |
|
||||
| 分析 | 学习分析页 | 查看阅读统计 | 页面展示 | 查看今日/本周阅读时长、已读/阅读资料数 | 否 | 已完成 | |
|
||||
| 分析 | 学习分析页 | 查看掌握度趋势图 | 页面展示(含动画) | 查看 7 天掌握度趋势折线图 | 否 | 占位实现 | ZXChartView 使用编译时硬编码的 7 天数据,未接入 ViewModel API 返回的真实趋势数据 |
|
||||
| 分析 | 学习分析页 | 查看阅读时长趋势 | 页面展示 | 查看阅读时长趋势柱状图 | 否 | 已完成 | 数据来源为 API |
|
||||
| 分析 | 学习分析页 | 查看每周学习活跃 | 页面展示(含动画) | 查看每周每天学习活跃柱状图 | 否 | 占位实现 | ZXWeekBarChart 使用编译时硬编码的 7 天数据,未接入 ViewModel API 返回的真实 heatmap 数据 |
|
||||
| 分析 | 学习分析页 | 查看连续学习统计 | 页面展示 | 查看当前连续、最长连续、最后活跃日期 | 否 | 已完成 | |
|
||||
| 分析 | 学习分析页 | 查看最近学习记录 | 页面展示 | 查看最近 5 条学习记录 | 否 | 已完成 | |
|
||||
| 分析 | 学习分析页 | 查看学习推荐 | 页面展示 | 查看 AI 推荐的学习行动(含优先级) | 否 | 已完成 | |
|
||||
| 分析 | 学习分析页 | 继续阅读 | 点击"继续阅读"卡片 | 跳转资料阅读页 | 是 | 已完成 | |
|
||||
| 分析 | 学习分析页 | 查看 AI 综合分析 | 页面展示 | 查看 AI 生成的综合学习分析文字 | 否 | 已完成 | 文字由数据动态拼接 |
|
||||
| 分析 | 学习分析页 | 查看薄弱知识点列表 | 页面展示 | 查看最多 5 个薄弱知识点 | 否 | 已完成 | |
|
||||
| 分析 | 学习分析页 | 查看全部薄弱知识点 | 点击"全部 N 个"链接 | 跳转薄弱知识点页 | 是 | 已完成 | |
|
||||
| 分析 | 学习分析页 | 下拉刷新 | 手势下拉 | 重新加载分析数据 | 否 | 已完成 | |
|
||||
|
||||
---
|
||||
|
||||
## 我的 Tab
|
||||
|
||||
| 所属模块 | 所属页面 | 功能名称 | 触发方式 | 功能结果 | 是否跨页面 | 当前完成情况 | 备注 |
|
||||
|---------|---------|---------|---------|---------|-----------|------------|------|
|
||||
| 我的 | 个人中心页 | 查看个人资料 | 页面展示 | 查看头像、昵称、邮箱、学习统计 | 否 | 已完成 | |
|
||||
| 我的 | 个人中心页 | 编辑个人资料 | 点击资料卡片 | 跳转编辑资料页 | 是 | 已完成 | |
|
||||
| 我的 | 个人中心页 | 设置学习目标 | 点击"学习目标设置" | 跳转学习目标设置页 | 是 | 已完成 | |
|
||||
| 我的 | 个人中心页 | 设置复习提醒 | 点击"复习提醒" | 跳转设置页 | 是 | 已完成 | |
|
||||
| 我的 | 个人中心页 | 设置学习方法偏好 | 点击"学习方法偏好" | 跳转方法偏好页 | 是 | 已完成 | |
|
||||
| 我的 | 个人中心页 | 帮助与反馈 | 点击"帮助与反馈" | 跳转反馈页 | 是 | 已完成 | |
|
||||
| 我的 | 个人中心页 | 查看学习资产 | 页面展示 | 查看知识库/条目/卡片数量 | 否 | 已完成 | |
|
||||
| 我的 | 个人中心页 | 发现公开库 | 点击"发现公开库" | 跳转发现公开库页 | 是 | 已完成 | |
|
||||
| 我的 | 个人中心页 | 查看消息中心 | 点击"消息中心" | 跳转通知列表页 | 是 | 已完成 | |
|
||||
| 我的 | 个人中心页 | 查看存储空间 | 页面展示 | 查看已用/总容量 | 否 | 已完成 | |
|
||||
| 我的 | 个人中心页 | 打开通知列表 | 点击通知图标 | 跳转通知列表页 | 是 | 已完成 | |
|
||||
| 我的 | 个人中心页 | 打开设置 | 点击设置图标 | 跳转设置页 | 是 | 已完成 | |
|
||||
| 我的 | 编辑资料页 | 上传头像 | 点击头像→相册选择 | 选择并上传新头像(256×256) | 否 | 已完成 | |
|
||||
| 我的 | 编辑资料页 | 编辑昵称 | 文本输入 | 修改昵称 | 否 | 已完成 | |
|
||||
| 我的 | 编辑资料页 | 编辑学习身份 | 文本输入 | 修改学习身份 | 否 | 已完成 | |
|
||||
| 我的 | 编辑资料页 | 编辑学习方向 | 文本输入 | 修改学习方向 | 否 | 已完成 | |
|
||||
| 我的 | 编辑资料页 | 编辑当前目标 | 文本输入 | 修改当前目标 | 否 | 已完成 | |
|
||||
| 我的 | 编辑资料页 | 编辑个人简介 | 文本输入 | 修改个人简介 | 否 | 已完成 | |
|
||||
| 我的 | 编辑资料页 | 保存资料 | 点击保存按钮 | 调用 API 更新资料 | 否 | 已完成 | |
|
||||
| 我的 | 设置页 | 切换外观模式 | 点击三种外观选项 | 切换深色/浅色/跟随系统 | 否 | 已完成 | 即时生效并保存至 API |
|
||||
| 我的 | 设置页 | 设置复习提醒时间 | 选择提醒时间 | 设定每日复习提醒时间 | 否 | 已完成 | |
|
||||
| 我的 | 设置页 | 设置提醒间隔天数 | 选择间隔天数 | 设定复习间隔(1/2/3/5/7天) | 否 | 已完成 | |
|
||||
| 我的 | 设置页 | 切换复习提醒开关 | 点击开关 | 开启/关闭复习提醒 | 否 | 已完成 | |
|
||||
| 我的 | 设置页 | 切换导入完成通知 | 点击开关 | 开启/关闭导入完成通知 | 否 | 部分完成(存在 bug) | 三个通知开关(复习提醒/导入完成/系统通知)全部绑定到同一个 $reviewReminder 变量,需修复为各自独立绑定 |
|
||||
| 我的 | 设置页 | 切换系统通知 | 点击开关 | 开启/关闭系统通知 | 否 | 部分完成(存在 bug) | 同上,三个通知开关绑定到同一状态变量 |
|
||||
| 我的 | 设置页 | 切换 iCloud 同步 | 点击开关 | 开启/关闭 iCloud 同步 | 否 | 暂未确认 | 开关 UI 存在但后端实现待确认 |
|
||||
| 我的 | 设置页 | 查看设备管理 | 点击"设备管理" | 待确认 | 是 | 未完成 | 无导航目标 |
|
||||
| 我的 | 设置页 | 查看隐私政策 | 点击"隐私政策" | 待确认 | 是 | 未完成 | 无导航目标 |
|
||||
| 我的 | 设置页 | 查看用户协议 | 点击"用户协议" | 待确认 | 是 | 未完成 | 无导航目标 |
|
||||
| 我的 | 设置页 | 退出登录 | 点击"退出登录",确认弹窗 | 清除 Token,回到未登录状态 | 是 | 已完成 | |
|
||||
| 我的 | 学习目标设置页 | 修改学习目标 | 点击目标选项 | 选中新学习目标并保存 | 否 | 已完成 | |
|
||||
| 我的 | 学习目标设置页 | 修改每日时长 | 点击时长选项 | 选中新时长(仅本地 @State,不通过 API 持久化) | 否 | 部分完成 | UI 选择完成,但选择结果不通过 API 保存,下次进入恢复默认"30 分钟" |
|
||||
| 我的 | 方法偏好页 | 切换学习方法 | 点击复选框 | 选中/取消学习方法并保存 | 否 | 已完成 | 支持多选 |
|
||||
| 我的 | 通知列表页 | 查看通知列表 | 页面展示 | 按日期分组查看通知 | 否 | 已完成 | |
|
||||
| 我的 | 通知列表页 | 标记单条已读 | 点击通知条目 | 该通知标记为已读 | 否 | 已完成 | |
|
||||
| 我的 | 通知列表页 | 全部标记已读 | 点击"全部已读"按钮 | 所有通知标记为已读 | 否 | 已完成 | |
|
||||
| 我的 | 反馈页 | 选择反馈类型 | 点击类型选项 | 选中反馈类型(Bug/建议/内容/其他) | 否 | 已完成 | |
|
||||
| 我的 | 反馈页 | 输入反馈内容 | 文本编辑器 | 填写反馈描述 | 否 | 已完成 | |
|
||||
| 我的 | 反馈页 | 提交反馈 | 点击提交按钮 | 调用 API 提交反馈 | 否 | 已完成 | |
|
||||
|
||||
---
|
||||
|
||||
## AI 辅助功能
|
||||
|
||||
| 所属模块 | 所属页面 | 功能名称 | 触发方式 | 功能结果 | 是否跨页面 | 当前完成情况 | 备注 |
|
||||
|---------|---------|---------|---------|---------|-----------|------------|------|
|
||||
| AI | AI 对话页 | 发送学习问题 | 输入文字,点击发送 | AI 回复(流式输出) | 否 | 已完成 | |
|
||||
| AI | AI 对话页 | 查看 AI 思考过程 | 页面展示(可折叠) | 了解 AI 推理过程 | 否 | 已完成 | 含流式动画 |
|
||||
| AI | AI 对话页 | 复制 AI 回复 | 点击"复制"按钮 | 复制到剪贴板 | 否 | 已完成 | |
|
||||
| AI | AI 对话页 | 重新生成回复 | 点击"重新生成"按钮 | AI 重新生成回复 | 否 | 已完成 | |
|
||||
| AI | AI 对话页 | 新建对话 | 点击工具栏新建按钮 | 创建新的对话会话 | 否 | 已完成 | |
|
||||
| AI | AI 对话页 | 查看会话列表 | 点击工具栏会话列表按钮 | 弹出会话列表 Sheet | 否 | 已完成 | |
|
||||
| AI | AI 对话页 | 切换历史会话 | 点击会话列表中的条目 | 加载该会话的消息历史 | 否 | 已完成 | |
|
||||
| AI | AI 对话页 | 搜索会话 | 在会话列表中输入搜索词 | 过滤会话列表 | 否 | 已完成 | |
|
||||
| AI | AI 对话页 | 删除会话 | 滑动→删除 | 删除该会话 | 否 | 已完成 | |
|
||||
| AI | AI 对话页 | 归档会话 | 滑动→归档 | 归档该会话 | 否 | 已完成 | |
|
||||
| AI | AI 对话页 | 置顶/取消置顶会话 | 左滑→置顶/取消置顶 | 切换会话置顶状态 | 否 | 已完成 | |
|
||||
| AI | AI 对话页 | 查看对话范围标签 | 页面展示 | 了解当前对话限定范围(知识库/资料等) | 否 | 已完成 | |
|
||||
| AI | 每日思考页 | 查看每日思考题 | 页面展示 | 查看今日 AI 出的思考题 | 否 | 占位实现 | 题目硬编码 |
|
||||
| AI | 每日思考页 | 提交回答 | 输入答案,点击"提交获取 AI 反馈" | 跳转 AI 反馈页 | 是 | 占位实现 | |
|
||||
| AI | AI 反馈页 | 查看 AI 分析步骤 | 自动(5 秒动画) | 展示分析进度动画 | 否 | 占位实现 | 硬编码等待 5 秒 |
|
||||
| AI | AI 反馈页 | 查看分析评分 | 页面展示 | 查看得分圆环和掌握度评价 | 否 | 占位实现 | 得分 78/100 硬编码 |
|
||||
| AI | AI 反馈页 | 查看答对/答错分析 | 页面展示 | 查看答对部分和需要完善的内容列表 | 否 | 占位实现 | 分析文字硬编码 |
|
||||
| AI | AI 反馈页 | 加入待巩固 | 点击"加入待巩固"按钮 | 跳转学习主页 | 是 | 占位实现 | |
|
||||
| AI | AI 反馈页 | 深入提问 | 点击"深入提问"按钮 | 跳转 AI 对话页 | 是 | 已完成 | |
|
||||
| AI | AI 反馈页 | 再来一题 | 点击"再来一题"按钮 | 跳转每日思考页 | 是 | 已完成 | |
|
||||
| AI | 薄弱知识点页 | 查看薄弱知识点列表 | 页面展示 | 查看掌握度低的易错知识点(含优先级) | 否 | 占位实现 | 5 个硬编码条目,未接 API |
|
||||
| AI | AI 首页 | (已废弃) | 无入口 | — | — | 占位实现 | 页面代码完整但未接入任何导航 |
|
||||
| AI | 回忆测试页 | 查看回忆测试题 | 页面展示 | 查看回忆测试题目 | 否 | 占位实现 | 题目硬编码"偏差-方差权衡" |
|
||||
| AI | 回忆测试页 | 提交回答获取 AI 反馈 | 输入答案,点击"提交"按钮 | 跳转 AI 反馈页 | 是 | 占位实现 | 无导航入口,代码存在但未接入 Route 枚举 |
|
||||
|
||||
---
|
||||
|
||||
## 测验功能
|
||||
|
||||
| 所属模块 | 所属页面 | 功能名称 | 触发方式 | 功能结果 | 是否跨页面 | 当前完成情况 | 备注 |
|
||||
|---------|---------|---------|---------|---------|-----------|------------|------|
|
||||
| 测验 | 测验列表页 | 查看测验列表 | 页面加载 | 查看该知识库的所有测验 | 否 | 已完成 | |
|
||||
| 测验 | 测验列表页 | 生成新测验 | 点击"生成新测验"按钮 | 调用 AI 生成测验 | 否 | 已完成 | 失败时 Toast 提示 |
|
||||
| 测验 | 测验列表页 | 开始作答 | 点击已有测验 | 跳转测验作答页 | 是 | 已完成 | |
|
||||
| 测验 | 测验作答页 | 回答选择题 | 点击 A/B/C/D 选项 | 选中答案,视觉反馈 | 否 | 已完成 | |
|
||||
| 测验 | 测验作答页 | 回答判断题 | 点击正确/错误按钮 | 选中答案 | 否 | 已完成 | |
|
||||
| 测验 | 测验作答页 | 回答填空题 | 输入文字答案 | 填写答案 | 否 | 已完成 | |
|
||||
| 测验 | 测验作答页 | 题目导航 | 点击上一题/下一题 | 切换题目 | 否 | 已完成 | |
|
||||
| 测验 | 测验作答页 | 提交全部答案 | 点击提交按钮(最后一题) | 提交所有答案,跳转结果页 | 是 | 已完成 | |
|
||||
| 测验 | 测验结果页 | 查看得分 | 页面展示 | 查看总分和正确/总题数 | 否 | 已完成 | 低于 60 分红色,以上绿色 |
|
||||
| 测验 | 测验结果页 | 查看逐题详情 | 页面展示 | 查看每道题的正确/错误标记和解析 | 否 | 已完成 | |
|
||||
| 测验 | 测验结果页 | 重新测验 | 点击"重新测验"按钮 | 重新进入作答 | 是 | 已完成 | |
|
||||
|
||||
---
|
||||
|
||||
## 复习功能
|
||||
|
||||
| 所属模块 | 所属页面 | 功能名称 | 触发方式 | 功能结果 | 是否跨页面 | 当前完成情况 | 备注 |
|
||||
|---------|---------|---------|---------|---------|-----------|------------|------|
|
||||
| 复习 | 复习卡片页 | 翻转卡片 | 点击卡片 | 卡片翻转显示答案和出处 | 否 | 占位实现 | 3 张硬编码卡片 |
|
||||
| 复习 | 复习卡片页 | 自评掌握度 | 点击四个等级按钮 | 记录自评,自动进入下一张 | 否 | 占位实现 | |
|
||||
| 复习 | 复习卡片页 | 查看进度 | 页面展示 | 查看当前进度条 | 否 | 占位实现 | |
|
||||
| 复习 | 复习卡片页 | 完成庆祝 | 自动(全部卡片完成后) | 展示庆祝动画覆盖层 | 否 | 占位实现 | |
|
||||
| 复习 | 主动回忆页 | 文字作答 | 输入文字答案,点击提交 | 提交答案 | 否 | 占位实现 | 3 道硬编码问题 |
|
||||
| 复习 | 主动回忆页 | 语音作答 | 点击语音图标(占位) | 未实现 | 否 | 占位实现 | 仅展示占位 UI |
|
||||
| 复习 | 主动回忆页 | 查看下一题 | 点击"下一题"按钮 | 进入下一道问题 | 否 | 占位实现 | |
|
||||
| 复习 | 主动回忆页 | 查看 AI 分析 | 点击"查看 AI 分析"按钮(末题) | 跳转 AI 反馈页 | 是 | 占位实现 | |
|
||||
|
||||
---
|
||||
|
||||
## 资料阅读
|
||||
|
||||
| 所属模块 | 所属页面 | 功能名称 | 触发方式 | 功能结果 | 是否跨页面 | 当前完成情况 | 备注 |
|
||||
|---------|---------|---------|---------|---------|-----------|------------|------|
|
||||
| 阅读 | 资料阅读页 | 阅读 Markdown 内容 | 页面展示 | 渲染 Markdown(标题/段落/列表/代码/引用/表格/图片) | 否 | 已完成 | Rust FFI |
|
||||
| 阅读 | 资料阅读页 | 阅读文本内容 | 页面展示 | 渲染纯文本内容 | 否 | 已完成 | |
|
||||
| 阅读 | 资料阅读页 | 查看图片 | 页面展示 | 显示图片内容 | 否 | 已完成 | |
|
||||
| 阅读 | 资料阅读页 | 系统预览 PDF/Office | 点击"系统预览"按钮 | 弹出 QuickLook Sheet | 是(Sheet) | 已完成 | |
|
||||
| 阅读 | 资料阅读页 | 外部打开文件 | 点击"外部打开"(PPT 等) | 通过系统分享打开 | 否 | 已完成 | |
|
||||
| 阅读 | 资料阅读页 | 标记已读 | 点击工具栏标记按钮 | 切换已读/未读状态 | 否 | 已完成 | 本地缓存 + 事件上报 |
|
||||
| 阅读 | 资料阅读页 | AI 对话 | 点击工具栏 AI 按钮 | 跳转 AI 对话页(资料范围) | 是 | 已完成 | |
|
||||
| 阅读 | 资料阅读页 | 查看资料详情 | 点击工具栏信息按钮 | 跳转资料详情页 | 是 | 已完成 | |
|
||||
| 阅读 | 资料阅读页 | 开始学习会话 | 点击工具栏学习按钮 | 启动学习计时会话 | 否 | 已完成 | |
|
||||
| 阅读 | 资料阅读页 | 添加笔记 | 点击工具栏笔记按钮 | 弹出快速笔记 Sheet | 是(Sheet) | 已完成 | 自动记录锚点位置 |
|
||||
| 阅读 | 资料阅读页 | 恢复阅读位置 | 自动 | 恢复到上次阅读位置 | 否 | 已完成 | 优先级:API > 本地 > 会话 |
|
||||
| 阅读 | 资料阅读页 | 自动旋转/暂停阅读会话 | 自动(前台/后台切换) | 管理阅读会话状态 | 否 | 已完成 | |
|
||||
| 阅读 | 快速笔记 Sheet | 创建笔记 | 输入文字,点击保存 | 保存笔记(本地 UserDefaults 存储) | 否 | 已完成 | 含锚点信息 |
|
||||
| 阅读 | 资料详情页 | 查看 AI 处理状态 | 页面展示 | 查看文件 AI 处理进度(处理中/就绪/失败) | 否 | 已完成 | |
|
||||
| 阅读 | 资料详情页 | 查看文件元数据 | 页面展示 | 查看文件名、格式、大小、上传日期 | 否 | 已完成 | |
|
||||
| 阅读 | 资料详情页 | 查看阅读进度 | 页面展示 | 查看已读时长、阅读会话数等 | 否 | 已完成 | |
|
||||
| 阅读 | 资料详情页 | 查看学习内容统计 | 页面展示 | 查看关联的知识点数和测验数 | 否 | 已完成 | |
|
||||
297
docs/system-map/ios/03-C端业务能力初步清单.md
Normal file
297
docs/system-map/ios/03-C端业务能力初步清单.md
Normal file
@ -0,0 +1,297 @@
|
||||
# 03 C 端业务能力初步清单
|
||||
|
||||
> **本文档为第一阶段初步归类结果。正式业务能力分类以《04-C端正式业务能力树.md》为准。本文档仅用于保留盘点过程,不作为后续系统地图的主索引。**
|
||||
|
||||
> 基于 iOS 页面功能进行归并,形成业务能力目录。
|
||||
> 本阶段仅分析 iOS 项目,不涉及 API、Rust、RAG 或 Admin 仓库。
|
||||
|
||||
---
|
||||
|
||||
## 1. 账号与用户
|
||||
|
||||
**能力说明:** 用户注册、登录、会话管理、账号状态管理、个人资料维护。
|
||||
|
||||
**关联页面:**
|
||||
- 启动页(会话恢复)
|
||||
- 登录页(Apple ID 登录)
|
||||
- 账号状态页(禁用/注销展示)
|
||||
- 编辑资料页(昵称、头像、学习身份、方向、目标、简介)
|
||||
- 设置页(退出登录、账号信息)
|
||||
|
||||
**当前完成度:** 部分完成。核心登录和个人资料维护已完成。以下功能缺失或未接入:设备管理无 C 端入口、账号注销无 C 端入口(API 已就绪)、隐私政策和用户协议页面未接入。
|
||||
|
||||
---
|
||||
|
||||
## 2. 新手引导与目标设定
|
||||
|
||||
**能力说明:** 首次使用时的产品价值传递、学习目标和偏好配置。
|
||||
|
||||
**关联页面:**
|
||||
- 欢迎页(功能介绍)
|
||||
- 引导页(4 步产品引导)
|
||||
- 目标设置页(学习目标/方法/时间)
|
||||
- 学习目标设置页(后续修改)
|
||||
- 方法偏好页(后续修改)
|
||||
|
||||
**当前完成度:** 部分完成。引导流程和目标设置 UI 已完成,但每日学习时长 dailyMins 仅保存在本地 @State 变量,不通过 API 持久化,用户下次进入恢复默认值。
|
||||
|
||||
---
|
||||
|
||||
## 3. 知识库管理
|
||||
|
||||
**能力说明:** 知识库的创建、浏览、搜索、筛选、订阅、删除,以及知识库级别的操作入口。
|
||||
|
||||
**关联页面:**
|
||||
- 知识库首页(列表、筛选、搜索、创建入口)
|
||||
- 知识库搜索页(搜索,待完善)
|
||||
- 创建知识库页(封面、名称、描述)
|
||||
- 发现公开库页(浏览、订阅/取消订阅)
|
||||
- 知识库详情页(部分操作:删除知识库、文件夹管理入口)
|
||||
|
||||
**当前完成度:** 部分完成。搜索逻辑未实现,官方知识库筛选未支持,知识库管理页未实现。
|
||||
|
||||
---
|
||||
|
||||
## 4. 知识点管理
|
||||
|
||||
**能力说明:** 知识点是知识库的基本单元,支持增删改查、多种添加方式(手动/文件/图片/链接)、收藏、笔记。
|
||||
|
||||
**关联页面:**
|
||||
- 知识库详情页·知识点 Tab(列表、排序、删除、批量删除、批量选择)
|
||||
- 添加知识点页(手动、文件、图片)
|
||||
- 知识点详情页(查看、收藏、笔记、原文)
|
||||
- 编辑知识点页(修改标题和内容)
|
||||
|
||||
**当前完成度:** 部分完成。收藏功能后端 API 未支持,重命名 TODO,移动到文件夹 TODO。
|
||||
|
||||
---
|
||||
|
||||
## 5. 资料上传
|
||||
|
||||
**能力说明:** 将外部文件(PDF、文本、图片、链接)上传至知识库,支持多种导入方式,AI 自动提取知识点候选。
|
||||
|
||||
**关联页面:**
|
||||
- 导入资料页(文件导入、相册导入、链接导入)
|
||||
- 导入候选审核页(审核 AI 提取的知识点候选:接受/拒绝/全部接受)
|
||||
|
||||
**当前完成度:** 已完成。
|
||||
|
||||
---
|
||||
|
||||
## 6. 文档阅读
|
||||
|
||||
**能力说明:** 阅读学习资料,支持 Markdown、纯文本、PDF、EPUB、图片、Word、Excel、PowerPoint 等多种格式,具备阅读位置记录与恢复、阅读行为跟踪能力。
|
||||
|
||||
**关联页面:**
|
||||
- 资料阅读页(多种格式渲染、标记已读、阅读位置恢复、阅读会话管理)
|
||||
- 资料详情页(文件 AI 处理状态、元数据、阅读进度、关联学习内容统计)
|
||||
- 系统预览(QuickLook,PDF/Office)
|
||||
- 外部打开(ShareLink,PPT)
|
||||
|
||||
**当前完成度:** 已完成(核心阅读功能)。解析触发使用了 60×2s 硬编码轮询。
|
||||
|
||||
---
|
||||
|
||||
## 7. 阅读笔记
|
||||
|
||||
**能力说明:** 在阅读过程中快速创建笔记,自动记录锚点位置(材料/段落/行/页)。
|
||||
|
||||
**关联页面:**
|
||||
- 快速笔记 Sheet(创建笔记、自动锚点记录)
|
||||
- 知识点详情页(从知识点进入笔记)
|
||||
|
||||
**当前完成度:** 已完成。笔记存储在本地 UserDefaults。
|
||||
|
||||
---
|
||||
|
||||
## 8. 学习信息收集
|
||||
|
||||
**能力说明:** 收集用户在学习过程中的行为数据(阅读行为、学习时长、阅读位置、标记已读等),经客户端缓冲、批量上传、服务端聚合后,用于学习分析和继续学习推荐。这是学习数据管道的上位业务能力,包含以下子能力:
|
||||
|
||||
- **阅读行为采集:** 在资料阅读过程中自动跟踪用户的阅读事件(打开/关闭/翻页/心跳/标记已读),由 Rust Document Runtime V2 会话管理驱动,含崩溃恢复和离线重试队列。
|
||||
- **专注学习会话:** 用户主动开始的计时学习,跟踪学习时长。
|
||||
- **本地事件队列:** iOS 端通过本地上传队列管理阅读事件的暂存、去重和重试。
|
||||
- **上传与重试:** 将阅读事件批量上传至服务端,含网络恢复自动重试机制。
|
||||
- **服务端聚合:** 服务端将原始阅读事件聚合为学习会话、资料阅读进度、每日学习活动和学 习记录。
|
||||
|
||||
**关联页面:**
|
||||
- 资料阅读页(阅读行为采集、阅读会话管理、位置记录、心跳上报、标记已读)
|
||||
- 学习会话页(专注计时、暂停、结束)
|
||||
- 分析页(学习摘要、趋势、连续统计等消费端展示)
|
||||
- 学习主页(继续学习推荐、每周摘要)
|
||||
|
||||
**当前完成度:** 部分完成。阅读行为采集(Rust FFI V2 + 本地上传队列 + 服务端聚合)已完成;专注学习会话(LearningSessionView)的本地计时已完成,但代码中未发现调用 LearningSessionService API 保存学习记录的代码,服务端持久化暂未确认。
|
||||
|
||||
---
|
||||
|
||||
## 9. 继续学习
|
||||
|
||||
**能力说明:** 根据用户最近的学习状态,智能推荐下一步学习任务(继续阅读、今日复习、自我测试、开始学习)。
|
||||
|
||||
**关联页面:**
|
||||
- 学习主页(优先级算法:继续学习 > 今日复习 > 自我测试 > 开始学习 > 空状态)
|
||||
- 分析页(继续阅读入口)
|
||||
|
||||
**当前完成度:** 已完成。
|
||||
|
||||
---
|
||||
|
||||
## 10. AI 对话
|
||||
|
||||
**能力说明:** 与 AI 进行学习相关的自然语言对话,支持流式回复、思考过程展示、多会话管理、范围限定(知识库/资料/全局)。
|
||||
|
||||
**关联页面:**
|
||||
- AI 对话页(发送消息、流式接收、思考过程、复制、重新生成、新建会话、会话列表与管理)
|
||||
- AI 会话列表 Sheet(搜索、切换、删除、归档)
|
||||
|
||||
**当前完成度:** 已完成。
|
||||
|
||||
---
|
||||
|
||||
## 11. 主动回忆与 AI 反馈
|
||||
|
||||
**能力说明:** 用户对知识点进行主动输出(文字或语音回答),由 AI 评估掌握程度并给出评分、分析和改进建议。主动回忆 → AI 反馈是一个连续的用户体验流程。
|
||||
|
||||
**关联页面:**
|
||||
- 主动回忆页(文字作答、语音作答占位、提交、AI 分析覆盖层、庆祝动画)
|
||||
- AI 反馈页(分析动画、得分、答对/答错拆解、参考答案、加入待巩固、深入提问、再来一题)
|
||||
- 每日思考页(查看思考题、提交回答获取 AI 反馈)
|
||||
- 回忆测试页(查看测试题、提交获取 AI 反馈,无导航入口)
|
||||
- 薄弱知识点页(薄弱点列表含掌握度分数和优先级)
|
||||
- 分析页(AI 综合分析文字摘要)
|
||||
|
||||
**当前完成度:** 占位实现。主动回忆页使用 3 道硬编码问题,语音回答为占位 UI;AI 反馈页得分和文字硬编码(78/100);薄弱知识点页 5 条数据硬编码;每日思考页和回忆测试页题目硬编码。上述页面均未接通真实 AI 分析 API。
|
||||
|
||||
---
|
||||
|
||||
## 12. 学习分析
|
||||
|
||||
**能力说明:** 以图表和数字形式展示用户的学习数据分析结果,包括掌握度趋势、阅读趋势、连续学习统计、学习推荐等。
|
||||
|
||||
**关联页面:**
|
||||
- 学习分析页(统计徽章、掌握度趋势图、阅读时长趋势图、每周活跃图、连续统计、学习记录、学习推荐)
|
||||
|
||||
**当前完成度:** 部分完成。API 数据已接入,但掌握度趋势图和每周活跃柱状图的图表数据为硬编码 mock,未使用 API 返回的真实数据渲染。
|
||||
|
||||
---
|
||||
|
||||
## 13. 题目与测验
|
||||
|
||||
**能力说明:** AI 根据知识库内容生成测验题目,支持选择题、判断题、填空题,用户逐题作答,查看得分和逐题解析。
|
||||
|
||||
**关联页面:**
|
||||
- 测验列表页(查看、生成)
|
||||
- 测验作答页(选择/判断/填空、导航、提交)
|
||||
- 测验结果页(得分、逐题详情、重新测验)
|
||||
|
||||
**当前完成度:** 已完成。
|
||||
|
||||
---
|
||||
|
||||
## 14. 间隔复习
|
||||
|
||||
**能力说明:** 基于间隔重复算法,以闪卡形式帮助用户复习知识点,用户自评掌握程度以调整复习计划。
|
||||
|
||||
**关联页面:**
|
||||
- 复习卡片页(翻转卡片、自评四个等级、进度条、庆祝动画)
|
||||
|
||||
**当前完成度:** 占位实现。使用 3 张硬编码卡片,未接通 ReviewViewModel 和 API。ReviewViewModel 和 ReviewPlanViewModel 代码已就绪。
|
||||
|
||||
---
|
||||
|
||||
## 15. 存储空间管理
|
||||
|
||||
**能力说明:** 展示用户的存储空间使用情况和学习资产统计。注:当前代码中无会员/订阅/付费墙/内购实现。
|
||||
|
||||
**关联页面:**
|
||||
- 个人中心页(存储空间展示、学习资产统计)
|
||||
- 设置页(iCloud 同步开关,待确认)
|
||||
|
||||
**当前完成度:** 部分完成。存储展示基本完成,iCloud 同步实际后端能力待确认。
|
||||
|
||||
---
|
||||
|
||||
## 16. 消息与通知
|
||||
|
||||
**能力说明:** 系统通知的接收、列表查看、已读标记,以及通知偏好设置。
|
||||
|
||||
**关联页面:**
|
||||
- 通知列表页(分组展示、标记已读、全部已读)
|
||||
- 设置页(复习提醒、导入完成通知、系统通知开关)
|
||||
|
||||
**当前完成度:** 部分完成。通知开关绑定存在疑似 bug(多个开关共用同一个状态变量)。
|
||||
|
||||
---
|
||||
|
||||
## 17. 设置与合规
|
||||
|
||||
**能力说明:** 应用外观、语言、学习偏好、复习提醒、数据同步等全局设置,以及隐私政策、用户协议等合规入口。
|
||||
|
||||
**关联页面:**
|
||||
- 设置页(外观切换、复习提醒、通知、存储、iCloud 同步、退出登录)
|
||||
- 设置页合规入口(隐私政策、用户协议——导航未接入)
|
||||
|
||||
**当前完成度:** 部分完成。隐私政策、用户协议、设备管理页面入口无导航目标。
|
||||
|
||||
---
|
||||
|
||||
## 18. 帮助与反馈
|
||||
|
||||
**能力说明:** 用户提交 Bug 反馈、功能建议、内容问题等。
|
||||
|
||||
**关联页面:**
|
||||
- 反馈页(选择反馈类型、输入描述、提交)
|
||||
|
||||
**当前完成度:** 已完成。
|
||||
|
||||
---
|
||||
|
||||
## 能力汇总
|
||||
|
||||
| 序号 | 能力名称 | 完成度 | 关键缺失 |
|
||||
|------|---------|--------|---------|
|
||||
| 1 | 账号与用户 | 部分完成 | 设备管理无入口、账号注销无 C 端入口、合规页面未接入 |
|
||||
| 2 | 新手引导与目标设定 | 部分完成 | 每日学习时长缺乏可靠持久化 |
|
||||
| 3 | 知识库管理 | 部分完成 | 搜索逻辑、官方库筛选、KB管理页 |
|
||||
| 4 | 知识点管理 | 部分完成 | 收藏 API、重命名、移动到文件夹 |
|
||||
| 5 | 资料上传 | 已完成 | — |
|
||||
| 6 | 文档阅读 | 已完成 | 解析触发轮询可优化 |
|
||||
| 7 | 阅读笔记 | 已完成 | 笔记存储在本地 UserDefaults |
|
||||
| 8 | 学习信息收集 | 部分完成 | 阅读行为采集已完成;LearningSessionView 服务端持久化暂未确认 |
|
||||
| 9 | 继续学习 | 已完成 | — |
|
||||
| 10 | AI 对话 | 已完成 | — |
|
||||
| 11 | 主动回忆与 AI 反馈 | 占位实现 | 全部数据硬编码,语音未实现,未接真实 AI API |
|
||||
| 12 | 学习分析 | 部分完成 | 图表数据为 mock(占位实现) |
|
||||
| 13 | 题目与测验 | 已完成 | — |
|
||||
| 14 | 间隔复习 | 占位实现 | 全部数据硬编码,未接 API |
|
||||
| 15 | 存储空间管理 | 部分完成 | iCloud 同步待确认 |
|
||||
| 16 | 消息与通知 | 部分完成 | 通知开关绑定 bug |
|
||||
| 17 | 设置与合规 | 部分完成 | 合规页面入口缺失 |
|
||||
| 18 | 帮助与反馈 | 已完成 | — |
|
||||
|
||||
---
|
||||
|
||||
## 业务能力依赖关系(初步)
|
||||
|
||||
```
|
||||
账号与用户
|
||||
└─ 新手引导与目标设定
|
||||
└─ 知识库管理
|
||||
├─ 知识点管理
|
||||
│ └─ 阅读笔记(知识点详情页笔记入口)
|
||||
├─ 资料上传 → 文档阅读
|
||||
│ ├─ 阅读笔记
|
||||
│ ├─ 学习信息收集(阅读行为采集 → 服务端聚合)
|
||||
│ │ └─ 学习分析
|
||||
│ ├─ AI 对话(资料范围对话)
|
||||
│ └─ 题目与测验(解析完成后进入测验)
|
||||
└─ AI 对话(知识库范围对话)
|
||||
├─ 继续学习 → 文档阅读 / 题目与测验
|
||||
│ └─ 主动回忆与 AI 反馈 → 间隔复习(加入待巩固)
|
||||
├─ 学习分析
|
||||
└─ 存储空间管理
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
> **下一阶段待办:** 扩展到 API、Rust、RAG、Admin 仓库的业务能力分析。
|
||||
259
docs/system-map/ios/04-C端正式业务能力树.md
Normal file
259
docs/system-map/ios/04-C端正式业务能力树.md
Normal file
@ -0,0 +1,259 @@
|
||||
# 04 C 端正式业务能力树
|
||||
|
||||
> 基于 iOS 页面地图和功能总表,按业务领域→业务能力→子能力的三层结构整理。
|
||||
> 不按代码目录组织,不写代码文件路径、类名。
|
||||
|
||||
---
|
||||
|
||||
## 1. 账号与用户
|
||||
|
||||
**能力说明:** 用户注册登录、会话管理、账号状态处理、个人资料维护。
|
||||
|
||||
```
|
||||
账号与用户
|
||||
├── 注册与登录
|
||||
│ ├── Apple ID 登录(含 nonce 验证)
|
||||
│ ├── 自动会话恢复(Keychain Token → API 校验)
|
||||
│ └── Token 刷新(401 自动重试)
|
||||
├── 账号状态管理
|
||||
│ ├── 账号禁用展示
|
||||
│ └── 账号注销展示
|
||||
├── 个人资料维护
|
||||
│ ├── 头像上传与裁剪
|
||||
│ ├── 昵称编辑
|
||||
│ ├── 学习身份/方向/目标编辑
|
||||
│ └── 个人简介编辑
|
||||
└── 账号安全与设备
|
||||
├── 登录设备查看(API 已就绪,C 端入口未实现)
|
||||
├── 移除登录设备(API 已就绪,C 端入口未实现)
|
||||
└── 账号注销(API 已就绪,C 端入口未实现)
|
||||
```
|
||||
|
||||
**当前完成度:** 部分完成
|
||||
|
||||
- 已完成:Apple ID 登录、会话恢复、Token 刷新、账号禁用/注销展示、个人资料查看与编辑
|
||||
- 未完成:登录设备查看/移除无 C 端入口(API 已就绪)、账号注销无 C 端入口(API 已就绪)、隐私政策和用户协议页面未接入
|
||||
|
||||
---
|
||||
|
||||
## 2. 内容获取与管理
|
||||
|
||||
**能力说明:** 用户构建和管理个人学习知识库的完整能力,包括知识库的创建浏览、知识点的增删改查、外部资料的导入。
|
||||
|
||||
```
|
||||
内容获取与管理
|
||||
├── 知识库管理
|
||||
│ ├── 创建知识库(封面、名称、描述)
|
||||
│ ├── 浏览知识库列表(无限滚动分页)
|
||||
│ ├── 筛选知识库(全部/我的/已订阅/官方)
|
||||
│ ├── 搜索知识库(搜索逻辑未实现)
|
||||
│ ├── 查看知识库详情(双 Tab:知识点 + 来源文件)
|
||||
│ ├── 删除知识库
|
||||
│ ├── 订阅/取消订阅公开知识库
|
||||
│ └── 发现公开知识库
|
||||
├── 知识点管理
|
||||
│ ├── 手动添加知识点(标题 + 内容)
|
||||
│ ├── 文件添加知识点(PDF/文本/图片,自动上传 COS)
|
||||
│ ├── 查看知识点详情(多格式渲染:文本/Markdown/文件)
|
||||
│ ├── 编辑知识点(标题 + 内容)
|
||||
│ ├── 删除知识点(单个 + 批量)
|
||||
│ ├── 排序知识点(默认/大小/创建时间/更新时间)
|
||||
│ ├── 收藏知识点(UI 已实现,后端 API 未支持)
|
||||
│ ├── 重命名知识点(TODO)
|
||||
│ └── 移动知识点到文件夹(TODO)
|
||||
├── 资料上传
|
||||
│ ├── 文件导入(PDF/纯文本 → COS 上传)
|
||||
│ ├── 相册导入(图片 → 压缩 → COS 上传)
|
||||
│ ├── 链接导入(输入 URL)
|
||||
│ └── 导入候选审核(AI 提取知识点 → 接受/拒绝/批量接受)
|
||||
└── 文件夹管理
|
||||
├── 创建文件夹
|
||||
├── 重命名文件夹
|
||||
└── 删除文件夹
|
||||
```
|
||||
|
||||
**当前完成度:** 部分完成
|
||||
|
||||
- 已完成:创建知识库、列表浏览、详情查看、知识点增删改查、批量操作、资料导入(三种方式)、导入候选审核、文件夹管理、公开库订阅
|
||||
- 未完成:搜索逻辑、官方筛选、收藏 API、重命名、移动到文件夹、知识库管理页
|
||||
|
||||
---
|
||||
|
||||
## 3. 学习执行
|
||||
|
||||
**能力说明:** 用户执行学习行为本身的能力,包括阅读资料、收集学习行为数据、做笔记。
|
||||
|
||||
```
|
||||
学习执行
|
||||
├── 文档阅读
|
||||
│ ├── 多格式渲染(Markdown/文本/图片/EPUB/PDF/Word/Excel/PPT)
|
||||
│ ├── 系统预览(QuickLook,PDF/Word/Excel)
|
||||
│ ├── 外部打开(ShareLink,PPT)
|
||||
│ ├── 标记已读/取消标记
|
||||
│ ├── 阅读位置记录与恢复(API → 本地 → 会话三级优先级)
|
||||
│ ├── 阅读会话管理(打开/暂停/恢复/关闭,前后台自动切换)
|
||||
│ ├── 资料详情查看(AI 处理状态、文件元数据、阅读进度)
|
||||
│ └── 触发知识提取(解析,60×2s 轮询)
|
||||
├── 学习信息收集
|
||||
│ ├── 阅读行为采集(Rust FFI V2:material_opened/closed/position_changed/heartbeat/marked_as_read)
|
||||
│ ├── 专注学习会话(计时器、暂停/继续/结束、庆祝动画)
|
||||
│ ├── 本地上传队列(事件暂存、去重、崩溃恢复)
|
||||
│ └── 上传与重试(批量上传、网络恢复自动重试、401 暂停)
|
||||
└── 阅读笔记
|
||||
├── 创建笔记(自动记录锚点位置)
|
||||
└── 查看笔记(知识点详情页笔记入口)
|
||||
```
|
||||
|
||||
**当前完成度:** 部分完成
|
||||
|
||||
- 已完成:文档多格式渲染、阅读位置记录恢复、阅读会话管理、阅读行为采集(Rust FFI V2 + 上传队列)、阅读笔记
|
||||
- 暂未确认:专注学习会话的 API 持久化(LearningSessionView 本地计时完成,服务端保存待确认)
|
||||
- 待优化:解析触发使用硬编码 60×2s 轮询
|
||||
|
||||
---
|
||||
|
||||
## 4. AI 学习辅助
|
||||
|
||||
**能力说明:** AI 作为学习伙伴,通过对话、主动回忆、分析反馈等方式辅助用户学习。
|
||||
|
||||
```
|
||||
AI 学习辅助
|
||||
├── AI 对话
|
||||
│ ├── 发送学习问题(流式接收 AI 回复)
|
||||
│ ├── 查看 AI 思考过程(可折叠,含流式动画)
|
||||
│ ├── 复制/重新生成 AI 回复
|
||||
│ ├── 多会话管理(新建、切换、搜索、删除、归档、置顶)
|
||||
│ └── 对话范围限定(知识库/资料/全局)
|
||||
└── 主动回忆与 AI 反馈
|
||||
├── 主动回忆(文字作答、语音作答占位)
|
||||
├── 每日思考(查看思考题、提交回答)
|
||||
├── 回忆测试(代码存在但无导航入口)
|
||||
├── AI 分析反馈(评分、答对/答错拆解、参考答案、加入待巩固)
|
||||
└── 薄弱知识点展示(掌握度分数、优先级标签)
|
||||
```
|
||||
|
||||
**当前完成度:** 部分完成
|
||||
|
||||
- 已完成:AI 对话全部功能(流式对话、思考过程、会话管理、范围限定)
|
||||
- 占位实现:主动回忆(硬编码问题)、AI 反馈(得分 78/100 硬编码)、每日思考(硬编码题目)、薄弱知识点(硬编码数据)、回忆测试(无入口 + 硬编码)
|
||||
|
||||
---
|
||||
|
||||
## 5. 测验与复习
|
||||
|
||||
**能力说明:** 通过 AI 生成测验和基于间隔重复的复习,帮助用户巩固知识。
|
||||
|
||||
```
|
||||
测验与复习
|
||||
├── 题目与测验
|
||||
│ ├── AI 生成测验(基于知识库内容)
|
||||
│ ├── 测验作答(选择题/判断题/填空题)
|
||||
│ ├── 测验结果(得分、逐题详情与解析)
|
||||
│ └── 重新测验
|
||||
└── 间隔复习
|
||||
├── 闪卡翻转(正面问题 → 反面答案)
|
||||
├── 自评掌握度(四个等级)
|
||||
└── 完成庆祝
|
||||
```
|
||||
|
||||
**当前完成度:** 测验已完成;间隔复习为占位实现
|
||||
|
||||
- 已完成:测验生成、作答(三种题型)、结果展示、重新测验
|
||||
- 占位实现:间隔复习(硬编码卡片,未接通 API)
|
||||
- 注:ReviewViewModel 和 ReviewPlanViewModel 代码已就绪,但未与 View 连接
|
||||
|
||||
---
|
||||
|
||||
## 6. 学习结果与分析
|
||||
|
||||
**能力说明:** 展示学习数据分析结果,并提供智能的下一步学习推荐。
|
||||
|
||||
```
|
||||
学习结果与分析
|
||||
├── 学习分析
|
||||
│ ├── 统计徽章(掌握度/总分钟/复习卡片/活跃天/阅读统计)
|
||||
│ ├── 趋势图表(掌握度趋势、阅读时长趋势、每周活跃)
|
||||
│ ├── 连续学习统计(当前连续/最长连续/最后活跃)
|
||||
│ ├── 学习记录列表(最近 5 条)
|
||||
│ ├── AI 综合分析(文字摘要)
|
||||
│ └── 学习推荐(优先级标签)
|
||||
└── 继续学习
|
||||
└── 优先级算法(继续学习 > 未完成会话 > 今日复习 > 自我测试 > 开始学习 > 空状态引导)
|
||||
```
|
||||
|
||||
**当前完成度:** 部分完成
|
||||
|
||||
- 已完成:统计徽章、阅读时长趋势图、连续统计、学习记录、学习推荐、继续学习算法、AI 综合分析文字
|
||||
- 占位实现:掌握度趋势折线图(硬编码数据)、每周活跃柱状图(硬编码数据)
|
||||
|
||||
---
|
||||
|
||||
## 7. 消息与设置
|
||||
|
||||
**能力说明:** 管理应用全局设置、通知偏好和系统通知查看。
|
||||
|
||||
```
|
||||
消息与设置
|
||||
├── 设置与应用偏好
|
||||
│ ├── 外观切换(深色/浅色/跟随系统,即时生效 API 保存)
|
||||
│ ├── 复习提醒设置(提醒时间 + 间隔天数)
|
||||
│ ├── 通知开关(复习提醒/导入完成/系统通知)
|
||||
│ ├── 存储空间展示
|
||||
│ ├── iCloud 同步开关(待确认)
|
||||
│ └── 退出登录
|
||||
├── 消息与通知
|
||||
│ ├── 通知列表(按日期分组:今天/本周/更早)
|
||||
│ ├── 标记已读(单条 + 全部)
|
||||
│ └── 按类型显示图标颜色(10+ 种类型)
|
||||
└── 学习偏好配置
|
||||
├── 学习目标设置(4 选 1,API 保存)
|
||||
├── 每日学习时长(4 选 1,仅本地 @State,不持久化)
|
||||
└── 学习方法偏好(多选,API 保存)
|
||||
```
|
||||
|
||||
**当前完成度:** 部分完成
|
||||
|
||||
- 已完成:外观切换、复习提醒设置、通知列表与已读标记、学习目标保存、方法偏好保存、退出登录
|
||||
- 存在 bug:三个通知开关绑定到同一状态变量
|
||||
- 待确认:iCloud 同步实际后端能力
|
||||
- 部分完成:每日学习时长不持久化
|
||||
|
||||
---
|
||||
|
||||
## 8. 合规与支持
|
||||
|
||||
**能力说明:** 用户反馈提交和合规相关页面入口。
|
||||
|
||||
```
|
||||
合规与支持
|
||||
├── 帮助与反馈
|
||||
│ ├── 选择反馈类型(Bug/建议/内容/其他)
|
||||
│ ├── 输入反馈内容
|
||||
│ └── 提交反馈
|
||||
├── 隐私政策(入口未接入)
|
||||
└── 用户协议(入口未接入)
|
||||
```
|
||||
|
||||
**当前完成度:** 部分完成
|
||||
|
||||
- 已完成:帮助与反馈
|
||||
- 未完成:隐私政策页面、用户协议页面
|
||||
|
||||
---
|
||||
|
||||
## 业务能力汇总表
|
||||
|
||||
| 序号 | 业务领域 | 业务能力数 | 完成度 | 关键缺失 |
|
||||
|------|---------|-----------|--------|---------|
|
||||
| 1 | 账号与用户 | 4 | 部分完成 | 设备管理无入口、账号注销无入口、合规页面未接入 |
|
||||
| 2 | 内容获取与管理 | 4 | 部分完成 | 搜索逻辑、官方库筛选、KB管理页、收藏API、重命名、移动到文件夹 |
|
||||
| 3 | 学习执行 | 3 | 部分完成 | LearningSessionView API持久化暂未确认 |
|
||||
| 4 | AI 学习辅助 | 2 | 部分完成 | 主动回忆与AI反馈全部硬编码 |
|
||||
| 5 | 测验与复习 | 2 | 部分完成 | 间隔复习硬编码未接API |
|
||||
| 6 | 学习结果与分析 | 2 | 部分完成 | 图表数据为占位实现 |
|
||||
| 7 | 消息与设置 | 3 | 部分完成 | 通知开关bug、合规入口缺失、每日时长不持久化 |
|
||||
| 8 | 合规与支持 | 1(+2) | 部分完成 | 隐私政策、用户协议入口未接入 |
|
||||
|
||||
---
|
||||
|
||||
> **阶段划分说明:** 本能力树为 C 端视角。跨项目的完整能力展开仅对"文档阅读"和"学习信息收集"两个能力进行了试点分析(见 capabilities/ 目录)。
|
||||
133
docs/system-map/ios/05-页面与业务能力矩阵.md
Normal file
133
docs/system-map/ios/05-页面与业务能力矩阵.md
Normal file
@ -0,0 +1,133 @@
|
||||
# 05 页面与业务能力矩阵
|
||||
|
||||
> 双向矩阵:每个页面关联的业务能力 / 每个业务能力涉及的页面。
|
||||
|
||||
---
|
||||
|
||||
## 一、页面 → 业务能力
|
||||
|
||||
| 页面 | 业务领域 | 主要关联业务能力 |
|
||||
|------|---------|----------------|
|
||||
| 启动页 | 账号与用户 | 注册与登录(会话恢复) |
|
||||
| 欢迎页 | 账号与用户 | 注册与登录(引导入口) |
|
||||
| 登录页 | 账号与用户 | 注册与登录(Apple ID 登录) |
|
||||
| 账号状态页 | 账号与用户 | 账号状态管理 |
|
||||
| 引导页 | 账号与用户 | 注册与登录(首次引导) |
|
||||
| 目标设置页 | 账号与用户 | 个人资料维护、学习偏好配置 |
|
||||
| 学习主页 | 学习执行、学习结果与分析 | 继续学习、学习分析 |
|
||||
| 学习会话页 | 学习执行 | 学习信息收集(专注学习会话) |
|
||||
| 复习卡片页 | 测验与复习 | 间隔复习 |
|
||||
| 主动回忆页 | AI 学习辅助 | 主动回忆与 AI 反馈 |
|
||||
| 知识库首页 | 内容获取与管理 | 知识库管理 |
|
||||
| 知识库搜索页 | 内容获取与管理 | 知识库管理(搜索) |
|
||||
| 知识库详情页 | 内容获取与管理、AI 学习辅助 | 知识库管理、知识点管理、文件夹管理、AI 对话 |
|
||||
| 创建知识库页 | 内容获取与管理 | 知识库管理(创建) |
|
||||
| 添加知识点页 | 内容获取与管理 | 知识点管理 |
|
||||
| 知识点详情页 | 内容获取与管理、学习执行 | 知识点管理、文档阅读、阅读笔记 |
|
||||
| 编辑知识点页 | 内容获取与管理 | 知识点管理 |
|
||||
| 导入资料页 | 内容获取与管理 | 资料上传 |
|
||||
| 导入候选审核页 | 内容获取与管理 | 资料上传(导入候选审核) |
|
||||
| 发现公开库页 | 内容获取与管理 | 知识库管理(订阅/发现) |
|
||||
| 文件夹管理 Sheet | 内容获取与管理 | 文件夹管理 |
|
||||
| 学习分析页 | 学习结果与分析 | 学习分析 |
|
||||
| 个人中心页 | 账号与用户、消息与设置 | 个人资料维护、存储空间管理、消息与通知 |
|
||||
| 编辑资料页 | 账号与用户 | 个人资料维护 |
|
||||
| 设置页 | 消息与设置、合规与支持 | 设置与应用偏好、消息与通知、合规入口 |
|
||||
| 学习目标设置页 | 消息与设置 | 学习偏好配置(学习目标) |
|
||||
| 方法偏好页 | 消息与设置 | 学习偏好配置(学习方法) |
|
||||
| 通知列表页 | 消息与设置 | 消息与通知 |
|
||||
| 反馈页 | 合规与支持 | 帮助与反馈 |
|
||||
| AI 对话页 | AI 学习辅助 | AI 对话 |
|
||||
| AI 对话会话列表 Sheet | AI 学习辅助 | AI 对话(多会话管理) |
|
||||
| 每日思考页 | AI 学习辅助 | 主动回忆与 AI 反馈 |
|
||||
| AI 反馈页 | AI 学习辅助 | 主动回忆与 AI 反馈 |
|
||||
| 薄弱知识点页 | AI 学习辅助 | 主动回忆与 AI 反馈 |
|
||||
| 回忆测试页(无入口) | AI 学习辅助 | 主动回忆与 AI 反馈 |
|
||||
| AI 首页(已废弃) | AI 学习辅助 | AI 对话、主动回忆与 AI 反馈 |
|
||||
| 测验列表页 | 测验与复习 | 题目与测验 |
|
||||
| 测验作答页 | 测验与复习 | 题目与测验 |
|
||||
| 测验结果页 | 测验与复习 | 题目与测验 |
|
||||
| 资料阅读页 | 学习执行、AI 学习辅助 | 文档阅读、学习信息收集、阅读笔记、AI 对话 |
|
||||
| 资料详情页 | 学习执行 | 文档阅读 |
|
||||
| 快速笔记 Sheet | 学习执行 | 阅读笔记 |
|
||||
| 系统预览 Sheet | 学习执行 | 文档阅读(系统预览) |
|
||||
|
||||
---
|
||||
|
||||
## 二、业务能力 → 页面
|
||||
|
||||
### 1. 账号与用户
|
||||
|
||||
| 子能力 | 关联页面 |
|
||||
|--------|---------|
|
||||
| 注册与登录 | 启动页、欢迎页、登录页、引导页 |
|
||||
| 账号状态管理 | 账号状态页 |
|
||||
| 个人资料维护 | 目标设置页、个人中心页、编辑资料页 |
|
||||
|
||||
### 2. 内容获取与管理
|
||||
|
||||
| 子能力 | 关联页面 |
|
||||
|--------|---------|
|
||||
| 知识库管理 | 知识库首页、知识库搜索页、知识库详情页、创建知识库页、发现公开库页 |
|
||||
| 知识点管理 | 知识库详情页、添加知识点页、知识点详情页、编辑知识点页 |
|
||||
| 资料上传 | 导入资料页、导入候选审核页 |
|
||||
| 文件夹管理 | 文件夹管理 Sheet |
|
||||
|
||||
### 3. 学习执行
|
||||
|
||||
| 子能力 | 关联页面 |
|
||||
|--------|---------|
|
||||
| 文档阅读 | 资料阅读页、资料详情页、知识点详情页、系统预览 Sheet |
|
||||
| 学习信息收集 | 资料阅读页、学习会话页(自动执行,用户不直接感知此能力) |
|
||||
| 阅读笔记 | 快速笔记 Sheet、知识点详情页 |
|
||||
|
||||
### 4. AI 学习辅助
|
||||
|
||||
| 子能力 | 关联页面 |
|
||||
|--------|---------|
|
||||
| AI 对话 | AI 对话页、AI 对话会话列表 Sheet、资料阅读页(工具栏 AI 按钮)、知识库详情页(底部 AI 按钮) |
|
||||
| 主动回忆与 AI 反馈 | 主动回忆页、每日思考页、AI 反馈页、薄弱知识点页、回忆测试页(无入口) |
|
||||
|
||||
### 5. 测验与复习
|
||||
|
||||
| 子能力 | 关联页面 |
|
||||
|--------|---------|
|
||||
| 题目与测验 | 测验列表页、测验作答页、测验结果页 |
|
||||
| 间隔复习 | 复习卡片页 |
|
||||
|
||||
### 6. 学习结果与分析
|
||||
|
||||
| 子能力 | 关联页面 |
|
||||
|--------|---------|
|
||||
| 学习分析 | 学习分析页 |
|
||||
| 继续学习 | 学习主页、学习分析页(继续阅读入口) |
|
||||
|
||||
### 7. 消息与设置
|
||||
|
||||
| 子能力 | 关联页面 |
|
||||
|--------|---------|
|
||||
| 设置与应用偏好 | 设置页、个人中心页 |
|
||||
| 消息与通知 | 通知列表页、个人中心页(消息中心入口)、设置页(通知开关) |
|
||||
| 学习偏好配置 | 学习目标设置页、方法偏好页、目标设置页 |
|
||||
|
||||
### 8. 合规与支持
|
||||
|
||||
| 子能力 | 关联页面 |
|
||||
|--------|---------|
|
||||
| 帮助与反馈 | 反馈页 |
|
||||
| 合规入口 | 设置页(隐私政策/用户协议/设备管理,均未接入) |
|
||||
|
||||
---
|
||||
|
||||
## 三、跨页面业务能力分布
|
||||
|
||||
以下能力横跨多个页面,说明其完整链路:
|
||||
|
||||
| 业务能力 | 跨页面链路 |
|
||||
|---------|-----------|
|
||||
| 文档阅读 | 知识库详情页(来源文件入口)→ 资料阅读页(阅读、笔记、AI 对话)→ 资料详情页(查看元数据)→ 系统预览(PDF/Office) |
|
||||
| 学习信息收集 | 资料阅读页(阅读行为采集)→ 学习会话页(专注计时)→ 分析页(消费数据展示) |
|
||||
| AI 对话 | 知识库详情页(知识库范围)→ AI 对话页 → 会话列表 Sheet;资料阅读页(资料范围)→ AI 对话页 |
|
||||
| 主动回忆与 AI 反馈 | 主动回忆页 → AI 反馈页 → 每日思考页 / AI 对话页 / 学习主页 |
|
||||
| 资料上传 | 导入资料页(文件/相册/链接)→ 导入候选审核页(审核 AI 提取的知识点) |
|
||||
| 测验 | 知识库详情页(测验入口)→ 测验列表页 → 测验作答页 → 测验结果页 |
|
||||
242
docs/system-map/ios/review/00-审查总报告.md
Normal file
242
docs/system-map/ios/review/00-审查总报告.md
Normal file
@ -0,0 +1,242 @@
|
||||
# 00 审查总报告
|
||||
|
||||
> 审查对象:知习 iOS 项目第一阶段系统地图(4 份文档)
|
||||
> 审查日期:2026-06-19
|
||||
> 审查方法:独立代码扫描 → 独立基线建立 → 与已有文档逐项比对
|
||||
> 审查范围:AIStudyApp/AIStudyApp/ 目录下全部 64 个 .swift 文件(不含 Tests 和自动生成代码)
|
||||
|
||||
---
|
||||
|
||||
## 一、审查范围
|
||||
|
||||
### 1.1 已检查的文件
|
||||
|
||||
- `AIStudyAppApp.swift` — App 入口、所有页面定义
|
||||
- `ContentView.swift` — Tab 根结构、共享组件
|
||||
- `Core/Navigation/Route.swift` — 全部路由定义(28 个 case)
|
||||
- `Core/Auth/AuthManager.swift` — 会话状态机(8 种状态)
|
||||
- `Core/Models/APIModels.swift` — 全部 54 个 API 模型
|
||||
- `Core/Models/AppContext.swift` — 设备/运行时上下文
|
||||
- `Core/Network/APIClient.swift` — HTTP 客户端、Token 刷新
|
||||
- `Core/Services/APIService.swift` — 全部 18 个服务类
|
||||
- `Core/Services/FileUploadService.swift` — 文件上传
|
||||
- `Core/Services/ReadingAPI.swift` — 阅读相关 API
|
||||
- `Core/Services/NetworkMonitor.swift` — 网络状态监控
|
||||
- `Core/DesignSystem/DesignTokens.swift` — 设计系统
|
||||
- `Core/DesignSystem/ZXToast.swift` — Toast 系统
|
||||
- `Core/Security/KeychainHelper.swift` — (已通过 AuthManager 间接审查)
|
||||
- `Core/Security/LocalCache.swift` — 本地缓存
|
||||
- `Core/Security/FileCache.swift` — 文件缓存
|
||||
- `Features/Study/` 全部 7 个文件
|
||||
- `Features/Library/` 全部 5 个文件
|
||||
- `Features/Profile/` 全部 8 个文件
|
||||
- `Features/AI/` 全部 10 个文件
|
||||
- `Features/Analysis/` 全部 2 个文件
|
||||
- `Features/Quiz/` 1 个文件(QuizViews.swift)
|
||||
- `Features/MaterialReader/` 全部 12 个文件
|
||||
|
||||
### 1.2 已检查的入口类型
|
||||
|
||||
- [x] Tab(4 个:学习/知识库/分析/我的)
|
||||
- [x] Push(NavigationLink via Route,25 个路由目标)
|
||||
- [x] Sheet(6 个)
|
||||
- [x] FullScreenCover(未发现)
|
||||
- [x] Alert(6 个)
|
||||
- [x] ConfirmationDialog(1 个)
|
||||
- [x] ContextMenu(1 处)
|
||||
- [x] Menu(1 处)
|
||||
- [x] Deep Link(未配置)
|
||||
- [x] Universal Link(未配置)
|
||||
- [x] URL Scheme(未配置)
|
||||
- [x] 通知点击路由(未实现)
|
||||
- [x] Debug 页面(仅 Route.destination 的 DEBUG 覆盖层)
|
||||
- [x] 条件渲染页面(基于 session/onboarding/数据状态的 7 种分支)
|
||||
- [x] iPhone/iPad 差异(仅在 AppContext 中标记 deviceType)
|
||||
- [x] Feature Flag(未发现)
|
||||
|
||||
### 1.3 未检查的项
|
||||
|
||||
- .xcodeproj 详细配置(Capabilities、Build Settings)
|
||||
- .entitlements 文件全文(推送通知、iCloud 等 Capability)
|
||||
- 第三方依赖(Rive 动画 SDK 等)
|
||||
- Rust FFI 二进制内部逻辑(ZxDocumentRuntime.xcframework)
|
||||
|
||||
---
|
||||
|
||||
## 二、独立盘点统计
|
||||
|
||||
| 统计项 | 数量 |
|
||||
|--------|------|
|
||||
| 一级模块(Tab) | 4 |
|
||||
| 独立 Push 页面(可路由) | 32 |
|
||||
| Tab 内嵌页面(不可路由) | 6(启动/登录流程页面) |
|
||||
| Sheet / 弹窗 | 10 |
|
||||
| 确认弹窗(Alert/ConfirmationDialog) | 8 |
|
||||
| 代码存在但无导航入口的页面 | 2(AIHomeView, RecallTestPage) |
|
||||
| 页面功能点 | ~180 |
|
||||
| API 服务类 | 18 |
|
||||
| 初步业务能力 | 20 |
|
||||
|
||||
---
|
||||
|
||||
## 三、审查结论
|
||||
|
||||
**审查结论:有条件通过**
|
||||
|
||||
### 不满足"通过"的哪些门禁条件?
|
||||
|
||||
| 门禁条件 | 满足? | 说明 |
|
||||
|---------|--------|------|
|
||||
| 所有导航入口已检查 | 是 | Tab/Push/Sheet/Alert/条件渲染均检查 |
|
||||
| 所有用户可访问页面已进入基线 | 是 | 32 个路由页面 + 6 个启动/登录页均已盘点 |
|
||||
| Sheet/弹窗/隐藏入口已检查 | 是 | 10 个 Sheet + 8 个 Alert + ContextMenu/Menu 均已盘点 |
|
||||
| 页面功能均进入功能基线 | 是 | ~180 个功能点均已盘点 |
|
||||
| 页面与业务能力完成双向覆盖检查 | 是 | 见 06-页面能力覆盖矩阵.md |
|
||||
| Mock/占位/废弃实现没有被误判为已完成 | **否** | 4 处 P0 误判(见第四节) |
|
||||
| 所有"暂未确认"均被明确列出 | 是 | 3 项暂未确认 |
|
||||
| 严重遗漏为 0 | **否** | 1 个页面遗漏(RecallTestPage) |
|
||||
| P0 修正项为 0 | **否** | 4 项 P0 修正 |
|
||||
| 已有文档和独立基线差异已全部处理 | 是 | 16 项差异全部列入待修正清单 |
|
||||
|
||||
---
|
||||
|
||||
## 四、严重问题(P0 — 会导致系统地图明显失真)
|
||||
|
||||
### 4.1 功能状态误判-图表数据为占位
|
||||
|
||||
- **问题:** 文档将"查看掌握度趋势图"和"查看每周学习活跃"均标记为"部分完成"
|
||||
- **实际:** ZXChartView 和 ZXWeekBarChart 使用完全硬编码的编译时数据,ViewModel 的 API 返回数据被忽略。应标记为"占位实现"
|
||||
- **影响:** 分析页给人的印象是"图表数据已接入但需优化",实际情况是"图表数据完全未接入 API"
|
||||
|
||||
### 4.2 功能状态误判-每日学习时长不持久化
|
||||
|
||||
- **问题:** GoalSettingDetailView 的"修改每日时长"标记为"已完成"
|
||||
- **实际:** dailyMins 只保存在本地 @State 变量,不通过 API 持久化,用户下次进入恢复默认"30 分钟"
|
||||
- **影响:** 给人"目标设置功能完整"的假象
|
||||
|
||||
### 4.3 设置页通知开关标记为"暂未确认"
|
||||
|
||||
- **问题:** 三个通知开关绑定 bug 被标记为"暂未确认"
|
||||
- **实际:** 代码中"复习提醒"、"导入完成通知"、"系统通知"三个 Toggle 全部绑定到同一个 `$reviewReminder`,这是明确的代码 bug
|
||||
- **影响:** 将确定性 bug 降级为不确定性疑点,降低修正优先级
|
||||
|
||||
### 4.4 文档页面/弹窗统计数字口径不明确
|
||||
|
||||
- **问题:** 总览文档称"43 个页面/弹窗",但未说明统计口径
|
||||
- **实际:** 独立基线盘点出 38 个 Push 页面 + 10 个 Sheet/弹窗 + 8 个确认弹窗
|
||||
- **建议:** 明确统计口径(是否含弹窗?是否含废弃页面?)并更新数字
|
||||
|
||||
---
|
||||
|
||||
## 五、一般问题(P1/P2)
|
||||
|
||||
### P1 — 遗漏项(4 项)
|
||||
|
||||
1. 遗漏 RecallTestPage(代码存在,无入口,应为占位实现)
|
||||
2. 遗漏 AIChatPage 会话置顶/取消置顶功能
|
||||
3. 遗漏 WaitlistService API 已就绪但 C 端无入口
|
||||
4. 遗漏 UserService 账号注销 API 已就绪但无 C 端入口
|
||||
|
||||
### P2 — 命名、描述、辅助状态问题(8 项)
|
||||
|
||||
1. 业务能力"会员与额度"命名不准确 → 应改为"存储空间管理"
|
||||
2. 建议合并"主动回忆"与"AI 学习分析"为一个业务能力
|
||||
3. StudyHomeViewModel error 状态永不可达(View 有但 ViewModel 不设置)
|
||||
4. DailyThinkingPage submitted 变量永不为 true
|
||||
5. 设置页"存储空间"和"登录设备管理"自引用导航
|
||||
6. 知识库详情页"知识库管理"按钮为 TODO
|
||||
7. 业务能力依赖关系图缺少交叉引用
|
||||
8. 文件夹新建/重命名 Alert 未列入确认弹窗表
|
||||
|
||||
---
|
||||
|
||||
## 六、遗漏项汇总
|
||||
|
||||
| 类型 | 数量 | 明细 |
|
||||
|------|------|------|
|
||||
| 遗漏页面 | 1 | RecallTestPage |
|
||||
| 遗漏功能 | 4 | 会话置顶、AIHomeView 子功能、解析触发、MaterialReaderView COS 下载 |
|
||||
| 遗漏 Sheet/弹窗 | 1 | 文件夹新建/重命名 Alert |
|
||||
| 遗漏 API-页面入口 | 3 | WaitlistService、账号注销、设备管理 |
|
||||
|
||||
---
|
||||
|
||||
## 七、错误项汇总
|
||||
|
||||
| 类型 | 数量 | 明细 |
|
||||
|------|------|------|
|
||||
| 状态误判 | 4 | 掌握度趋势图(部分→占位)、每周活跃图(部分→占位)、每日时长(已完成→部分)、通知开关(暂未确认→部分+bug) |
|
||||
| 命名错误 | 1 | 会员与额度 → 存储空间管理 |
|
||||
| 分类建议 | 2 | 主动回忆+AI 分析建议合并、能力依赖图缺少交叉引用 |
|
||||
|
||||
---
|
||||
|
||||
## 八、待确认项
|
||||
|
||||
| 序号 | 待确认内容 | 原因 |
|
||||
|------|-----------|------|
|
||||
| U01 | LearningSessionView 是否调用 API 保存学习记录 | 代码中未发现 LearningSessionService.start/end 的直接调用,但可能在 Rust FFI 或 ViewModel 中有间接调用 |
|
||||
| U02 | SettingsView iCloud 同步开关实际后端支持情况 | Toggle UI 存在但仅改变本地 @State,无法确认后端是否有对应能力 |
|
||||
| U03 | 分析页"近 7 天"日期范围筛选是否可切换 | UI 中展示了日期范围标签但未发现切换逻辑 |
|
||||
|
||||
---
|
||||
|
||||
## 九、修正优先级
|
||||
|
||||
### P0(4 项)— 影响整体地图正确性
|
||||
|
||||
1. 分析页图表数据状态修正(部分完成 → 占位实现)
|
||||
2. 每日学习时长持久化状态修正(已完成 → 部分完成)
|
||||
3. 设置页通知开关 bug 状态修正(暂未确认 → 部分完成,存在 bug)
|
||||
4. 总览页统计数字口径明确化
|
||||
|
||||
### P1(4 项)— 遗漏主要页面或业务能力
|
||||
|
||||
5. 补充 RecallTestPage 到页面地图和功能表
|
||||
6. 补充 AIChatPage 会话置顶功能
|
||||
7. 标注 WaitlistService 状态
|
||||
8. 标注账号注销 API 状态
|
||||
|
||||
### P2(8 项)— 命名、描述、辅助状态完善
|
||||
|
||||
9. 重命名"会员与额度"为"存储空间管理"
|
||||
10. 考虑合并"主动回忆"与"AI 学习分析"
|
||||
11-16. 其他描述性补充
|
||||
|
||||
---
|
||||
|
||||
## 十、最终判断
|
||||
|
||||
### 总体评价
|
||||
|
||||
- **已有文档的代码覆盖率高**(页面覆盖率约 95%,功能覆盖率约 95%)
|
||||
- **核心流程描述准确**(用户生命周期、Tab 结构、路由系统)
|
||||
- **Mock/占位实现识别基本正确**(AI 相关页面正确标记为占位实现)
|
||||
|
||||
### 主要不足
|
||||
|
||||
1. **分析页图表状态被低估**(占位实现被标记为部分完成)
|
||||
2. **设置页通知 bug 被降级为"暂未确认"**
|
||||
3. **GoalSettingDetailView 学习时长不持久化未被发现**
|
||||
4. **1 个代码页面、2 个 API 端点、1 个交互功能的遗漏**
|
||||
|
||||
### 是否可以进入下一阶段?
|
||||
|
||||
**可以进入下一阶段的"跨项目业务能力展开",但建议先完成 4 项 P0 修正。**
|
||||
|
||||
原因:
|
||||
- 已有文档的整体架构和页面覆盖是准确的,作为后续分析的基础足够可靠
|
||||
- P0 问题集中在对少数具体功能的状态判断上,不影响整体地图的结构正确性
|
||||
- 未发现系统性的页面遗漏或归类错误
|
||||
- Mock/占位/废弃实现的识别框架是正确的,只需修正个别判断
|
||||
- P1/P2 问题不阻塞跨项目分析,可在第二阶段的盘点中一并修正
|
||||
|
||||
### 门禁复查
|
||||
|
||||
| 门禁 | 修正前 | 修正 P0 后 |
|
||||
|------|--------|-----------|
|
||||
| 严重遗漏为 0 | 否(1 项 P1) | 是 |
|
||||
| P0 修正项为 0 | 否(4 项) | 是 |
|
||||
| Mock/占位未误判 | 否 | 是(修正 4 处后) |
|
||||
|
||||
**完成 4 项 P0 修正后可达"通过"标准。**
|
||||
314
docs/system-map/ios/review/01-独立页面基线.md
Normal file
314
docs/system-map/ios/review/01-独立页面基线.md
Normal file
@ -0,0 +1,314 @@
|
||||
# 01 独立页面基线
|
||||
|
||||
> 本文件不参考已有系统地图文档,完全基于代码扫描独立建立。
|
||||
> 扫描日期:2026-06-19
|
||||
> 扫描范围:AIStudyApp/AIStudyApp/ 目录下全部 .swift 文件(不含 Tests 和 Generated)
|
||||
|
||||
---
|
||||
|
||||
## 一、独立盘点统计
|
||||
|
||||
| 统计项 | 数量 |
|
||||
|--------|------|
|
||||
| 一级模块(Tab) | 4 |
|
||||
| 独立页面(含可路由页面) | 32 |
|
||||
| Sheet / 弹窗 | 10 |
|
||||
| 确认弹窗(Alert/ConfirmationDialog) | 8 |
|
||||
| 页面内嵌子视图(非独立路由) | 2 |
|
||||
| 代码存在但无入口的页面 | 1 |
|
||||
| 页面功能点(估算) | ~180 |
|
||||
|
||||
---
|
||||
|
||||
## 二、应用根结构
|
||||
|
||||
### 2.1 入口点
|
||||
|
||||
- `AIStudyAppApp.swift` 是 `@main` 入口。
|
||||
- 使用 `WindowGroup`,`UIApplicationSupportsMultipleScenes = false`。
|
||||
- 无 URL Scheme、Universal Link、Deep Link 配置(Info.plist 中无相关条目)。
|
||||
- 无通知点击路由(未发现 `UNUserNotificationCenter` delegate 或 `onOpenURL`)。
|
||||
- 无"恢复上次页面"逻辑(每次启动由 AuthManager 状态决定初始页面)。
|
||||
|
||||
### 2.2 会话状态机(AuthManager.AppSession)
|
||||
|
||||
```
|
||||
unknown → SplashScreen
|
||||
unauthenticated → PreLoginFlow (WelcomePage → LoginPage)
|
||||
authenticating / refreshing → SplashScreen
|
||||
authenticated → ContentView (if hasCompletedOnboarding) else PostLoginOnboardingFlow
|
||||
disabled → AccountStatusView (禁用)
|
||||
deleted → AccountStatusView (注销)
|
||||
expired → PreLoginFlow
|
||||
```
|
||||
|
||||
### 2.3 Tab 根结构(ContentView)
|
||||
|
||||
```
|
||||
TabView(selection: $selectedTab)
|
||||
├─ "学习" (tag: "study") → NavigationStack → StudyHomeView
|
||||
├─ "知识库" (tag: "library") → NavigationStack → LibraryHomeView
|
||||
├─ "分析" (tag: "analysis") → NavigationStack → AnalysisHomeView
|
||||
└─ "我的" (tag: "profile") → NavigationStack → ProfileView
|
||||
```
|
||||
|
||||
所有 Tab 使用 NavigationStack + `.navigationDestination(for: Route.self)` 统一路由。
|
||||
|
||||
### 2.4 条件性入口
|
||||
|
||||
| 条件 | 影响的页面/行为 |
|
||||
|------|----------------|
|
||||
| hasCompletedOnboarding = false | 显示 PostLoginOnboardingFlow (OnboardingPage → GoalSetupPage) |
|
||||
| hasCompletedOnboarding = true | 直接进入 ContentView |
|
||||
| session = .disabled | 显示 AccountStatusView(禁用) |
|
||||
| session = .deleted | 显示 AccountStatusView(注销) |
|
||||
| session = .expired / .unauthenticated | 显示 PreLoginFlow |
|
||||
| selectedTab 值变化 | StudyHomeView 通过 Binding 接收,可被其他 Tab 修改 |
|
||||
| 有 continueLearning API 数据 | 学习主页显示"继续上次学习"卡片 |
|
||||
| reviewCards.count > 0 | 学习主页显示"今日复习"卡片 |
|
||||
| quizzes.count > 0 | 学习主页显示"资料自测"卡片 |
|
||||
| knowledgeBases.count > 0 | 学习主页显示"开始学习"卡片 |
|
||||
| 以上全为空 | 学习主页显示空状态引导 |
|
||||
| iPhone / iPad | AppContext 中记录 deviceType,但不影响页面布局 |
|
||||
| Debug / Release | DEBUG 宏仅在 Route.destination 中用于显示页面标签覆盖层 |
|
||||
|
||||
---
|
||||
|
||||
## 三、完整页面清单(按入口类型分类)
|
||||
|
||||
### 3.1 启动/登录流程页面
|
||||
|
||||
| 序号 | 页面 | Swift 类型 | 入口方式 | 是否可路由 |
|
||||
|------|------|-----------|---------|-----------|
|
||||
| P01 | 启动页 | SplashScreen | 应用冷启动(session = .unknown/.authenticating/.refreshing) | 否 |
|
||||
| P02 | 欢迎页 | WelcomePage | PreLoginFlow step 0 | 否 |
|
||||
| P03 | 登录页 | LoginPage | PreLoginFlow step 1 | 否 |
|
||||
| P04 | 账号禁用页 | AccountStatusView | session = .disabled | 否 |
|
||||
| P05 | 账号注销页 | AccountStatusView | session = .deleted | 否 |
|
||||
| P06 | 引导页 | OnboardingPage | PostLoginOnboardingFlow step 0 | 否 |
|
||||
| P07 | 目标设置页 | GoalSetupPage | PostLoginOnboardingFlow step 1 | 否 |
|
||||
|
||||
### 3.2 学习 Tab 页面(NavigationLink Push)
|
||||
|
||||
| 序号 | 页面 | Route 枚举 | 入口 |
|
||||
|------|------|-----------|------|
|
||||
| P08 | 学习主页 | Route.studyHome | Tab "学习" 默认 |
|
||||
| P09 | 学习会话页 | Route.learningSession | 资料阅读页工具栏 |
|
||||
| P10 | 复习卡片页 | Route.reviewCard | 学习主页 / AIHomeView |
|
||||
| P11 | 主动回忆页 | Route.activeRecall | 学习主页底部链接 / AIHomeView |
|
||||
|
||||
### 3.3 知识库 Tab 页面(NavigationLink Push)
|
||||
|
||||
| 序号 | 页面 | Route 枚举 | 入口 |
|
||||
|------|------|-----------|------|
|
||||
| P12 | 知识库首页 | Tab "知识库" 直接渲染 | Tab "知识库" |
|
||||
| P13 | 知识库搜索页 | Route.librarySearch | 知识库首页搜索图标 |
|
||||
| P14 | 知识库详情页 | Route.libraryDetail | 知识库首页卡片点击 |
|
||||
| P15 | 创建知识库页 | Route.libraryCreate | 知识库首页 + 按钮 / 我的页学习资产 |
|
||||
| P16 | 添加知识点页 | Route.addKnowledge | 知识库详情页操作菜单"添加" |
|
||||
| P17 | 知识点详情页 | Route.knowledgeDetail | 知识库详情页点击知识点 |
|
||||
| P18 | 编辑知识点页 | Route.editKnowledge | 知识点详情页工具栏菜单 |
|
||||
| P19 | 导入资料页 | Route.libraryImport | 知识库详情页操作菜单"上传" |
|
||||
| P20 | 导入候选审核页 | Route.importReview | 导入资料完成后 |
|
||||
| P21 | 发现公开库页 | Route.discoverPublic | 我的页"发现公开库" |
|
||||
|
||||
### 3.4 分析 Tab 页面
|
||||
|
||||
| 序号 | 页面 | Route 枚举 | 入口 |
|
||||
|------|------|-----------|------|
|
||||
| P22 | 学习分析页 | Tab "分析" 直接渲染 | Tab "分析" |
|
||||
|
||||
### 3.5 我的 Tab 页面
|
||||
|
||||
| 序号 | 页面 | Route 枚举 | 入口 |
|
||||
|------|------|-----------|------|
|
||||
| P23 | 个人中心页 | Tab "我的" 直接渲染 | Tab "我的" |
|
||||
| P24 | 编辑资料页 | Route.editProfile | 个人中心页资料卡片 / 设置页 |
|
||||
| P25 | 设置页 | Route.settings | 个人中心页设置图标 / 复习提醒行 |
|
||||
| P26 | 学习目标设置页 | Route.goalSetting | 设置页 / 我的页 |
|
||||
| P27 | 学习方法偏好页 | Route.methodPreference | 设置页 / 我的页 |
|
||||
| P28 | 通知列表页 | Route.notificationList | 我的页通知图标 / 消息中心 |
|
||||
| P29 | 帮助与反馈页 | Route.feedbackForm | 我的页 / 设置页 |
|
||||
|
||||
### 3.6 AI 辅助页面(跨模块 Push)
|
||||
|
||||
| 序号 | 页面 | Route 枚举 | 入口 |
|
||||
|------|------|-----------|------|
|
||||
| P30 | AI 对话页 | Route.aiChat | 知识库详情页底部 / 资料阅读页工具栏 / AI 反馈页 |
|
||||
| P31 | 每日思考页 | Route.dailyThinking | AI 反馈页"再来一题" / AIHomeView |
|
||||
| P32 | AI 反馈页 | Route.aiFeedback | 主动回忆完成后 / 每日思考提交后 |
|
||||
| P33 | 薄弱知识点页 | Route.weakPoints | 分析页"全部 N 个"链接 / AIHomeView |
|
||||
|
||||
### 3.7 测验页面
|
||||
|
||||
| 序号 | 页面 | Route 枚举 | 入口 |
|
||||
|------|------|-----------|------|
|
||||
| P34 | 测验列表页 | Route.quizList | 知识库详情页操作菜单"测验" |
|
||||
| P35 | 测验作答页 | Route.quizTake | 测验列表点击 / 学习主页自我测试 |
|
||||
| P36 | 测验结果页 | Route.quizResult | 测验作答提交后 |
|
||||
|
||||
### 3.8 资料阅读页面
|
||||
|
||||
| 序号 | 页面 | Route 枚举 | 入口 |
|
||||
|------|------|-----------|------|
|
||||
| P37 | 资料阅读页 | Route.materialReader | 学习主页"继续学习" / 分析页"继续阅读" / 来源文件 / 知识点详情 |
|
||||
| P38 | 资料详情页 | Route.materialDetail | 资料阅读页工具栏"信息"按钮 |
|
||||
|
||||
### 3.9 Sheet / 弹窗(非独立 Push 页面)
|
||||
|
||||
| 序号 | 名称 | 类型 | 所在页面 | 入口 |
|
||||
|------|------|------|---------|------|
|
||||
| S01 | AI 会话列表 Sheet | .sheet (medium/large) | AIChatPage | 工具栏"会话列表"按钮 |
|
||||
| S02 | 快速笔记 Sheet | .sheet | MaterialReaderView | 工具栏笔记按钮 |
|
||||
| S03 | 系统预览 (QuickLook) | .sheet (QLPreviewController) | MaterialReaderView | "系统预览"按钮 |
|
||||
| S04 | 封面选择 Sheet | .sheet (height 220) | CreateLibraryPage | 封面区域点击 |
|
||||
| S05 | 文件夹管理 Sheet | .sheet | LibraryDetailPage | 操作菜单"文件夹管理" |
|
||||
| S06 | 链接导入 Alert | .alert (with TextField) | ImportPage | "链接导入"按钮 |
|
||||
|
||||
### 3.10 确认弹窗(Alert / ConfirmationDialog)
|
||||
|
||||
| 序号 | 名称 | 类型 | 所在页面 |
|
||||
|------|------|------|---------|
|
||||
| A01 | 结束学习确认 | ConfirmationDialog | LearningSessionView |
|
||||
| A02 | 删除知识库确认 | Alert | LibraryDetailPage |
|
||||
| A03 | 批量删除确认 | Alert | LibraryDetailPage |
|
||||
| A04 | 新建文件夹 | Alert (with TextField) | FolderManageView |
|
||||
| A05 | 重命名文件夹 | Alert (with TextField) | FolderManageView |
|
||||
| A06 | 退出登录确认 | Alert | SettingsView |
|
||||
| A07 | 新建分类 | Alert (with TextField) | FolderManageView |
|
||||
| A08 | 链接导入 | Alert (with TextField) | ImportPage |
|
||||
|
||||
### 3.11 代码存在但无入口的页面
|
||||
|
||||
| 名称 | Swift 类型 | 情况说明 |
|
||||
|------|-----------|---------|
|
||||
| AI 首页 | AIHomeView | 完整页面代码,含 NavigationLink 到 AIChatPage/ActiveRecallView/WeakPointsPage/ReviewCardView/DailyThinkingPage,但 Route 中无对应 case,无任何其他页面跳转到此页 |
|
||||
|
||||
---
|
||||
|
||||
## 四、入口类型检查清单
|
||||
|
||||
| 入口类型 | 是否检查 | 发现情况 |
|
||||
|---------|---------|---------|
|
||||
| Tab | 是 | 4 个:学习、知识库、分析、我的 |
|
||||
| Push (NavigationLink via Route) | 是 | 约 25 个路由目标 |
|
||||
| Sheet | 是 | 6 个 Sheet |
|
||||
| FullScreenCover | 是 | 未发现 |
|
||||
| Alert | 是 | 6 个 Alert |
|
||||
| ConfirmationDialog | 是 | 1 个 |
|
||||
| Popover | 是 | 未发现 |
|
||||
| ContextMenu | 是 | LibraryDetailPage 知识点行 |
|
||||
| Menu | 是 | LibraryDetailPage 工具栏 |
|
||||
| Deep Link | 是 | 未配置 |
|
||||
| Universal Link | 是 | 未配置 |
|
||||
| URL Scheme | 是 | 未配置 |
|
||||
| 通知点击路由 | 是 | 未发现 |
|
||||
| Debug 页面 | 是 | 仅 DEBUG 标签覆盖层,无专用调试页面 |
|
||||
| 条件渲染页面 | 是 | 基于 session / onboarding / 数据状态的 7 种分支 |
|
||||
| iPhone/iPad 差异 | 是 | 仅在 AppContext 记录,无布局差异 |
|
||||
| Feature Flag | 是 | 未发现 |
|
||||
| 管理员/内部账号 | 是 | 未发现 |
|
||||
| 首次启动 vs 非首次 | 是 | hasCompletedOnboarding @AppStorage |
|
||||
|
||||
---
|
||||
|
||||
## 五、页面跳转关系(基于 Route 枚举和 NavigationLink 分析)
|
||||
|
||||
### 5.1 Tab 内跳转
|
||||
|
||||
| 源页面 | 目标页面 | Route |
|
||||
|--------|---------|-------|
|
||||
| StudyHomeView | MaterialReaderView | .materialReader |
|
||||
| StudyHomeView | ReviewCardView | .reviewCard |
|
||||
| StudyHomeView | QuizTakerView | .quizTake |
|
||||
| StudyHomeView | QuizListView | .quizList |
|
||||
| StudyHomeView | ActiveRecallView | .activeRecall |
|
||||
| StudyHomeView | 切换到 library Tab | selectedTab 绑定 |
|
||||
| LibraryHomeView | LibrarySearchView | .librarySearch |
|
||||
| LibraryHomeView | CreateLibraryPage | .libraryCreate |
|
||||
| LibraryHomeView | LibraryDetailPage | .libraryDetail |
|
||||
| LibraryDetailPage | KnowledgeDetailPage | .knowledgeDetail |
|
||||
| LibraryDetailPage | EditKnowledgePage | .editKnowledge |
|
||||
| LibraryDetailPage | ImportPage | .libraryImport |
|
||||
| LibraryDetailPage | AddKnowledgePage | .addKnowledge |
|
||||
| LibraryDetailPage | QuizListView | .quizList |
|
||||
| LibraryDetailPage | AIChatPage | .aiChat |
|
||||
| LibraryDetailPage | MaterialReaderView | .materialReader |
|
||||
| LibraryDetailPage | FolderManageView (Sheet) | - |
|
||||
| CreateLibraryPage | 封面选择 Sheet | - |
|
||||
| AddKnowledgePage | (文件选择器/相册) | 系统组件 |
|
||||
| KnowledgeDetailPage | MaterialReaderView | .materialReader |
|
||||
| KnowledgeDetailPage | QuickLook (Sheet) | - |
|
||||
| KnowledgeDetailPage | QuickNoteSheet | - |
|
||||
| ImportPage | ImportReviewPage | .importReview |
|
||||
| ImportPage | (文件选择器/相册/链接Alert) | 系统组件 |
|
||||
| AnalysisHomeView | WeakPointsPage | .weakPoints |
|
||||
| AnalysisHomeView | MaterialReaderView | .materialReader |
|
||||
| ProfileView | EditProfilePage | .editProfile |
|
||||
| ProfileView | GoalSettingDetailView | .goalSetting |
|
||||
| ProfileView | SettingsView | .settings |
|
||||
| ProfileView | MethodPreferenceView | .methodPreference |
|
||||
| ProfileView | FeedbackFormView | .feedbackForm |
|
||||
| ProfileView | CreateLibraryPage | .libraryCreate |
|
||||
| ProfileView | DiscoverView | .discoverPublic |
|
||||
| ProfileView | NotificationListView | .notificationList |
|
||||
| SettingsView | GoalSettingDetailView | .goalSetting |
|
||||
| SettingsView | MethodPreferenceView | .methodPreference |
|
||||
| SettingsView | EditProfilePage | .editProfile |
|
||||
| SettingsView | FeedbackFormView | .feedbackForm |
|
||||
|
||||
### 5.2 跨模块跳转
|
||||
|
||||
| 源页面 | 目标页面 | 触发方式 |
|
||||
|--------|---------|---------|
|
||||
| ActiveRecallView | AIFeedbackPageView | 提交完所有回答后"查看 AI 分析" |
|
||||
| AIFeedbackPageView | StudyHomeView | "加入待巩固" |
|
||||
| AIFeedbackPageView | AIChatPage | "深入提问" |
|
||||
| AIFeedbackPageView | DailyThinkingPage | "再来一题" |
|
||||
| DailyThinkingPage | AIFeedbackPageView | 提交回答后 |
|
||||
| MaterialReaderView | AIChatPage | 工具栏 AI 按钮 |
|
||||
| MaterialReaderView | MaterialDetailView | 工具栏信息按钮 |
|
||||
| MaterialReaderView | LearningSessionView | 工具栏学习按钮 |
|
||||
| MaterialReaderView | QuickNoteSheet | 工具栏笔记按钮 |
|
||||
| AIHomeView | AIChatPage | NavigationLink(页面自身无入口) |
|
||||
| AIHomeView | ActiveRecallView | NavigationLink(页面自身无入口) |
|
||||
| AIHomeView | WeakPointsPage | NavigationLink(页面自身无入口) |
|
||||
| AIHomeView | ReviewCardView | NavigationLink(页面自身无入口) |
|
||||
| AIHomeView | DailyThinkingPage | NavigationLink(页面自身无入口) |
|
||||
|
||||
---
|
||||
|
||||
## 六、API 服务清单(每个对应一组后端端点)
|
||||
|
||||
| 服务类 | 主要端点 | 被哪些页面使用 |
|
||||
|--------|---------|--------------|
|
||||
| AuthService | /auth/apple, /auth/refresh, /auth/logout | LoginPage, AuthManager |
|
||||
| UserService | /users/me (GET/PATCH), /users/me/preferences, /users/me/profile, /users/me/deletion-request, /users/me/devices, /users/me/assets-summary, /users/me/storage | ProfileView, EditProfilePage, SettingsView, GoalSettingDetailView, MethodPreferenceView |
|
||||
| KnowledgeBaseService | /knowledge-bases (CRUD), /knowledge-bases/subscribed, /knowledge-bases/:id/subscribe | LibraryHomeView, LibraryDetailPage, CreateLibraryPage, DiscoverView, StudyHomeView |
|
||||
| KnowledgeItemService | /knowledge-items (CRUD, batch-delete) | LibraryDetailPage, AddKnowledgePage, KnowledgeDetailPage, EditKnowledgePage |
|
||||
| KnowledgeFolderService | /knowledge-bases/:id/folders (CRUD) | FolderManageView |
|
||||
| KnowledgeSourceService | /knowledge-bases/:id/sources (CRUD, parse) | LibraryDetailPage, MaterialReaderView |
|
||||
| DocumentImportService | /imports (create, status) | ImportPage |
|
||||
| ImportCandidateService | /import-candidates (list, accept, reject, batch-accept) | ImportReviewPage |
|
||||
| QuizService | /quizzes (generate, list, detail, start, submit, results, history) | QuizListView, QuizTakerView, QuizResultView |
|
||||
| RagChatService | /rag-chat/sessions (CRUD, messages, stream) | AIChatPage |
|
||||
| ActiveRecallService | /active-recalls (list, submit) | ActiveRecallView |
|
||||
| AIAnalysisService | /ai-analysis | (ViewModel 中有调用,但 ActiveRecallView 使用硬编码数据) |
|
||||
| ReviewService | /reviews (due, submit, generate-cards) | ReviewCardView (View 中硬编码,ViewModel 调用 API) |
|
||||
| FocusItemService | /focus-items (list, update, complete) | AnalysisHomeView (via ActivityViewModel) |
|
||||
| ActivityService | /activity (summary, heatmap, trend, streak, recommendations) | AnalysisHomeView, ProfileView, StudyHomeView |
|
||||
| LearningSessionService | /learning-sessions (list, start, end) | LearningSessionView, StudyHomeView |
|
||||
| ReadingAPIService | /learning/reading-events/batch, /materials/:id/reading-progress, /learning/continue, /learning/summary, /learning/trend, /learning/records | MaterialReaderView, StudyHomeView, AnalysisHomeView |
|
||||
| FileUploadService | /files/upload-url, /files/complete, /files/:id | CreateLibraryPage, AddKnowledgePage, ImportPage, EditProfilePage |
|
||||
| FeedbackService | /feedback | FeedbackFormView |
|
||||
| NotificationService | /notifications (list, markRead, markAllRead, preferences, push-token) | NotificationListView, SettingsView |
|
||||
| WaitlistService | /waitlist | (API 定义存在,iOS 代码中未发现使用入口) |
|
||||
|
||||
---
|
||||
|
||||
## 七、免责说明
|
||||
|
||||
- 本基线完全基于对 AIStudyApp/AIStudyApp/ 目录下全部 64 个 .swift 文件的逐文件阅读建立。
|
||||
- 未检查 .xcassets、.entitlements、.xcodeproj 中的详细配置。
|
||||
- iOS 推送通知的深度链接处理在代码中未发现,但可能在 Capabilities 中配置(未检查 .entitlements 文件全文)。
|
||||
- WaitlistService 代码存在但未在任何 View 或 ViewModel 中使用,判定为无 C 端入口。
|
||||
537
docs/system-map/ios/review/02-独立功能基线.md
Normal file
537
docs/system-map/ios/review/02-独立功能基线.md
Normal file
@ -0,0 +1,537 @@
|
||||
# 02 独立功能基线
|
||||
|
||||
> 完全基于代码扫描独立建立,不参考已有系统地图文档。
|
||||
> 每项功能标注:已完成 / 部分完成 / 占位实现 / 未完成 / 暂未确认
|
||||
|
||||
---
|
||||
|
||||
## 一、启动与登录流程
|
||||
|
||||
### P01 启动页 (SplashScreen)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 展示品牌标识 | 已完成 | 渐变背景 + 大脑图标 + "知习" + ProgressView |
|
||||
| 自动恢复登录会话 | 已完成 | AuthManager.restoreSession() 读取 Keychain Token → /users/me 校验 |
|
||||
| Token 刷新 | 已完成 | /auth/refresh 端点,APIClient 401 自动重试 |
|
||||
| 会话过期处理 | 已完成 | session = .expired → PreLoginFlow |
|
||||
| 账号禁用/注销检测 | 已完成 | /users/me 返回特定 errorCode → 切到对应 AccountStatusView |
|
||||
|
||||
### P02 欢迎页 (WelcomePage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 产品功能介绍 | 已完成 | "AI 驱动"标签 + 主标题 + 3 个 FeatureRow(主动回忆、费曼解释、AI 分析) |
|
||||
| 进入登录 | 已完成 | "开始使用" → LoginPage |
|
||||
|
||||
### P03 登录页 (LoginPage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| Apple ID 登录 | 已完成 | SignInWithAppleButton → AuthService.appleLogin |
|
||||
| nonce 验证 | 已完成 | SHA256(nonce) 传入 Apple 请求 |
|
||||
| 登录中取消 | 已完成 | 取消按钮 + Task.cancel() |
|
||||
| 登录错误提示 | 已完成 | 红色错误横幅,显示具体错误信息 |
|
||||
| Token 存储 | 已完成 | KeychainHelper.save |
|
||||
|
||||
### P04/P05 账号状态页 (AccountStatusView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 禁用状态展示 | 已完成 | icon + title + message + "返回首页" |
|
||||
| 注销状态展示 | 已完成 | 同上,文案不同 |
|
||||
| 返回首页 | 已完成 | onBackToLogin → session = .unauthenticated |
|
||||
|
||||
### P06 引导页 (OnboardingPage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 4 步引导浏览 | 已完成 | 输入知识 / 主动输出 / AI 分析 / 掌握知识 |
|
||||
| 跳过引导 | 已完成 | "跳过" → onContinue |
|
||||
| 步骤指示器 | 已完成 | 4 个圆角矩形进度条 |
|
||||
|
||||
### P07 目标设置页 (GoalSetupPage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 选择学习目标(4 选 1) | 已完成 | 备考考试/职业技能/通识学习/自定义 |
|
||||
| 选择学习方法(多选) | 已完成 | 间隔回忆/费曼技巧/AI 分析 |
|
||||
| 选择每日学习时间(4 选 1) | 已完成 | 15分钟/30分钟/1小时/不限制 |
|
||||
| 确认并开始 | 已完成 | "开始学习" → onComplete(true) → hasCompletedOnboarding = true |
|
||||
|
||||
---
|
||||
|
||||
## 二、学习 Tab (StudyHomeView + 子页面)
|
||||
|
||||
### P08 学习主页 (StudyHomeView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看连续学习天数 | 已完成 | streakDays 从 API 获取,火焰图标 + "X 天连续" |
|
||||
| 继续上次学习 | 已完成 | MainAction.continueSession → MaterialReaderView,优先级最高 |
|
||||
| 今日复习入口 | 部分完成 | 入口正常 → ReviewCardView,但 ReviewCardView 使用硬编码数据 |
|
||||
| 资料自测入口 | 已完成 | MainAction.selfTest → QuizTakerView |
|
||||
| 空状态引导(创建/探索知识库) | 已完成 | 切换到 library Tab |
|
||||
| 查看每周摘要 | 已完成 | 本周分钟/复习卡片/活跃天数/连续天数 |
|
||||
| 查看完整分析 | 已完成 | → Route.activeRecall(目标页为占位实现) |
|
||||
| 下拉刷新 | 已完成 | .refreshable |
|
||||
| 加载状态 | 已完成 | ProgressView |
|
||||
| 错误状态 | 部分完成 | View 支持 error 状态,但 ViewModel 永远不会设置 error(所有 API 用 try? 吞错) |
|
||||
| 优先级自动计算 | 已完成 | 继续学习 > 未完成会话 > 今日复习 > 自测 > 开始学习 > 空状态 |
|
||||
|
||||
### P09 学习会话页 (LearningSessionView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 专注计时(1 秒精度) | 已完成 | Timer.publish(every: 1) |
|
||||
| 环形进度动画 | 已完成 | Circle.trim + AngularGradient 动画,上限 30 分钟 |
|
||||
| 暂停/继续 | 已完成 | isRunning/isPaused 切换 |
|
||||
| 结束学习(含确认弹窗) | 已完成 | ConfirmationDialog → 结束并保存 |
|
||||
| 庆祝动画 | 已完成 | ZXCelebrationView |
|
||||
| 学习时长保存到 API | 暂未确认 | LearningSessionView 不直接调用 API,也未发现调用 LearningSessionService.start/end 的代码 |
|
||||
|
||||
### P10 复习卡片页 (ReviewCardView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 卡片翻转 | 占位实现 | 点击翻转动画正常,但使用 3 张硬编码 ReviewCardItem |
|
||||
| 自评四个等级 | 占位实现 | "完全不会"/"有点难"/"基本会"/"很简单"按钮 |
|
||||
| 进度条 | 占位实现 | 正常展示但基于硬编码数据 |
|
||||
| 完成庆祝 | 占位实现 | ZXCelebrationView |
|
||||
| 调用 Review API | 未完成 | ReviewViewModel.loadDueCards() 被调用但结果被忽略,View 使用硬编码 ReviewCardItem |
|
||||
|
||||
### P11 主动回忆页 (ActiveRecallView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 文字作答 | 占位实现 | TextEditor + 提交按钮,但使用 3 道硬编码 RecallQuestion |
|
||||
| 语音作答 | 占位实现 | 展示麦克风图标和提示文字,无实际录音功能 |
|
||||
| 提交答案 | 占位实现 | 本地状态更新,不调用 API |
|
||||
| AI 分析动画 | 占位实现 | ZXThinkingOverlay 展示,2 秒后自动消失 |
|
||||
| 查看 AI 分析结果 | 占位实现 | → AIFeedbackPageView(本身为占位实现) |
|
||||
| 庆祝动画 | 占位实现 | ZXCelebrationView |
|
||||
| 题目来源标签 | 占位实现 | 展示硬编码来源文字 |
|
||||
|
||||
---
|
||||
|
||||
## 三、知识库 Tab
|
||||
|
||||
### P12 知识库首页 (LibraryHomeView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看知识库列表 | 已完成 | LibraryViewModel.loadKnowledgeBases() → KnowledgeBaseService.list() |
|
||||
| 筛选分类(全部/我的/已订阅/官方) | 部分完成 | "官方"筛选返回空数组(TODO 注释:等后端支持) |
|
||||
| 搜索入口 | 部分完成 | 搜索按钮 → LibrarySearchView(搜索逻辑未实现) |
|
||||
| 创建知识库入口 | 已完成 | + 按钮 → CreateLibraryPage |
|
||||
| 查看知识库详情 | 已完成 | 卡片点击 → LibraryDetailPage |
|
||||
| 下拉刷新 | 已完成 | .refreshable |
|
||||
| 无限滚动分页 | 已完成 | ZXLoadMoreFooter |
|
||||
| 知识库卡片:封面/名称/描述/日期/置顶/公开 | 已完成 | ZLibraryCard 完整展示 |
|
||||
|
||||
### P13 知识库搜索页 (LibrarySearchView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 搜索输入框 | 已完成 | TextField 已搭建 |
|
||||
| 搜索逻辑 | 未完成 | query 变化时不触发任何 API 调用,结果区域始终为空 |
|
||||
| 空状态提示 | 已完成 | "搜索知识点、知识库或标签" |
|
||||
|
||||
### P14 知识库详情页 (LibraryDetailPage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看知识库信息头部 | 已完成 | 封面/标题/描述/来源/文件数/创建/更新日期 |
|
||||
| 知识点列表(Tab 0) | 已完成 | KnowledgeItemService.list() |
|
||||
| 知识点排序 | 已完成 | 默认/文件大小/创建时间/更新时间 |
|
||||
| 来源文件列表(Tab 1) | 已完成 | KnowledgeSourceService.list() |
|
||||
| 来源文件阅读状态标签 | 已完成 | "已读"/"阅读中" |
|
||||
| 查看知识点详情 | 已完成 | → KnowledgeDetailPage |
|
||||
| 删除单个知识点 | 已完成 | contextMenu 删除 → KnowledgeItemService.delete() |
|
||||
| 批量选择/删除 | 已完成 | isSelectMode + batchDeleteItems |
|
||||
| 导入资料入口 | 已完成 | 操作菜单 → ImportPage |
|
||||
| 添加知识点入口 | 已完成 | 操作菜单 → AddKnowledgePage |
|
||||
| 生成测验入口 | 已完成 | 操作菜单 → QuizListView |
|
||||
| 文件夹管理入口 | 已完成 | 操作菜单 → FolderManageView Sheet |
|
||||
| AI 对话入口 | 已完成 | 底部 AI 按钮 → AIChatPage (知识库范围) |
|
||||
| 删除来源文件 | 已完成 | 来源文件行删除按钮 |
|
||||
| 删除知识库 | 已完成 | 确认弹窗 → KnowledgeBaseService.delete() |
|
||||
| 知识点重命名 | 未完成 | contextMenu 中有"重命名"按钮,但 action 为空(// TODO: rename) |
|
||||
| 移动到文件夹 | 未完成 | contextMenu 中有"移动到"按钮,但 action 为空(// TODO: move to folder) |
|
||||
| 知识库管理页 | 未完成 | 操作菜单"知识库管理"按钮 action 为空(// TODO: knowledge base management page) |
|
||||
|
||||
### P15 创建知识库页 (CreateLibraryPage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 上传封面图 | 已完成 | PhotosPicker → 裁剪 512x512 → COS 上传 |
|
||||
| 输入名称(必填) | 已完成 | TextField + 必填校验 |
|
||||
| 输入描述(必填) | 已完成 | TextEditor + 必填校验 |
|
||||
| 创建知识库 | 已完成 | KnowledgeBaseService.create() → Toast 反馈 |
|
||||
|
||||
### P16 添加知识点页 (AddKnowledgePage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 手动模式(标题+内容) | 已完成 | TextField + TextEditor → KnowledgeItemService.create() |
|
||||
| 文件模式(选择文件) | 已完成 | fileImporter → COS 上传 → 创建知识点 |
|
||||
| 图片模式(选择照片) | 已完成 | PhotosPicker → JPEG 压缩 → COS 上传 → 创建知识点 |
|
||||
| 多文件批量添加 | 已完成 | 支持多选,逐个上传,显示进度 |
|
||||
| 移除已选文件 | 已完成 | xmark 按钮 → 从 selectedFiles 移除 |
|
||||
|
||||
### P17 知识点详情页 (KnowledgeDetailPage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| URL 型知识点渲染 | 已完成 | COS 下载 → 本地缓存 → MaterialReaderView 嵌入 |
|
||||
| 纯文本渲染 | 已完成 | 直接 Text 渲染 |
|
||||
| 文件类型自动检测 | 已完成 | 从扩展名/MIME 推断 MaterialType |
|
||||
| COS 过期 URL 重取 | 已完成 | 检测 <Error> XML → 重新 fetch item → 获取新签名 URL |
|
||||
| 错误状态(含摘要回退) | 已完成 | 显示错误 + 摘要文字 + 重试按钮 |
|
||||
| 阅读原文件 | 已完成 | NavigationLink → MaterialReaderView |
|
||||
| 笔记入口 | 已完成 | 工具栏菜单 → showNoteSheet |
|
||||
| 系统预览(PDF/Word/Excel) | 已完成 | 工具栏菜单 → QuickLook |
|
||||
| 收藏切换 | 部分完成 | isFavorited 状态切换有 UI,但 toggleFavorite() 中有 TODO 注释:后端 API 未支持 |
|
||||
|
||||
### P18 编辑知识点页 (EditKnowledgePage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 修改标题 | 已完成 | TextField → KnowledgeItemService.update() |
|
||||
| 修改内容 | 已完成 | TextEditor → KnowledgeItemService.update() |
|
||||
| 保存 | 已完成 | "保存修改"按钮 → API 调用 |
|
||||
|
||||
### P19 导入资料页 (ImportPage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 文件导入(PDF/纯文本) | 已完成 | fileImporter → COS 上传 → KnowledgeSourceService.add() |
|
||||
| 相册导入 | 部分完成 | PhotosPicker → COS 上传 → DocumentImportService.create(),但未发现后续 AI OCR 处理流程 |
|
||||
| 链接导入 | 已完成 | Alert 弹窗输入 URL → DocumentImportService.create() |
|
||||
| 自动选择目标知识库 | 已完成 | 加载第一个知识库,无则提示创建 |
|
||||
| 导入错误提示 | 已完成 | 红色错误横幅 |
|
||||
| 导入进度提示 | 已完成 | statusMessage + ProgressView |
|
||||
|
||||
### P20 导入候选审核页 (ImportReviewPage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看候选列表(含置信度) | 已完成 | ImportCandidateService.listBySource() |
|
||||
| 展开查看候选详情 | 已完成 | expandedId 切换 |
|
||||
| 接受单个候选 | 已完成 | ImportCandidateService.accept() |
|
||||
| 拒绝单个候选 | 已完成 | ImportCandidateService.reject() |
|
||||
| 批量全部接受 | 已完成 | ImportCandidateService.batchAccept() |
|
||||
| 空候选状态 | 已完成 | "没有待审批的候选" |
|
||||
|
||||
### P21 发现公开库页 (DiscoverView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看公开知识库列表 | 已完成 | KnowledgeBaseService.discover() |
|
||||
| 订阅知识库 | 已完成 | KnowledgeBaseService.subscribe() |
|
||||
| 取消订阅 | 已完成 | KnowledgeBaseService.unsubscribe() |
|
||||
| 空状态 | 已完成 | "暂无公开知识库" |
|
||||
|
||||
### S05 文件夹管理 Sheet (FolderManageView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看文件夹列表 | 已完成 | KnowledgeFolderService.list() |
|
||||
| 新建文件夹 | 已完成 | Alert 输入 → KnowledgeFolderService.create() |
|
||||
| 重命名文件夹 | 已完成 | Swipe → Alert 输入 → KnowledgeFolderService.update() |
|
||||
| 删除文件夹 | 已完成 | Swipe 删除 → KnowledgeFolderService.delete() |
|
||||
|
||||
---
|
||||
|
||||
## 四、分析 Tab
|
||||
|
||||
### P22 学习分析页 (AnalysisHomeView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 综合掌握度 | 已完成 | ActivityService.summary().dailyAverage |
|
||||
| 总学习分钟 | 已完成 | ActivityService.summary().totalMinutes |
|
||||
| 复习卡片数 | 已完成 | ActivityService.summary().totalCardsReviewed |
|
||||
| 活跃天数 | 已完成 | ActivityService.summary().activeDays |
|
||||
| 今日/本周阅读统计 | 已完成 | ReadingAPIService.getLearningSummary() |
|
||||
| 掌握度趋势折线图 | 占位实现 | ZXChartView 使用硬编码数据 [(一,0.62)...(今,0.78)],未使用 API |
|
||||
| 阅读时长趋势柱状图 | 已完成 | 使用 API 返回的 LearningTrendResponse.series |
|
||||
| 本周学习活跃柱状图 | 占位实现 | ZXWeekBarChart 使用硬编码数据,未使用 API |
|
||||
| 连续学习统计 | 已完成 | ActivityService.streak() |
|
||||
| 最近学习记录(5 条) | 已完成 | ReadingAPIService.getLearningRecords() |
|
||||
| 学习推荐(3 条) | 已完成 | ActivityService.recommendations() |
|
||||
| 继续阅读入口 | 已完成 | → MaterialReaderView |
|
||||
| AI 综合分析文字 | 已完成 | 动态拼接 summary 数据 |
|
||||
| 薄弱知识点列表(5 条) | 已完成 | FocusItemService.list() |
|
||||
| 查看全部薄弱知识点 | 已完成 | → WeakPointsPage(目标页为占位实现) |
|
||||
| 下拉刷新 | 已完成 | .refreshable |
|
||||
| 日期范围筛选 | 暂未确认 | "近 7 天" 标签展示但无实际切换逻辑 |
|
||||
|
||||
---
|
||||
|
||||
## 五、我的 Tab
|
||||
|
||||
### P23 个人中心页 (ProfileView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看个人资料(头像/昵称/邮箱) | 已完成 | UserService.myProfile() |
|
||||
| 查看学习统计(活跃天/卡片/分钟) | 已完成 | ActivityService.summary() |
|
||||
| 查看学习资产(库/条目/卡片计数) | 已完成 | UserService.fetchAssets() |
|
||||
| 查看存储空间 | 已完成 | UserService.fetchStorage() |
|
||||
| 编辑资料入口 | 已完成 | → EditProfilePage |
|
||||
| 学习目标设置入口 | 已完成 | → GoalSettingDetailView |
|
||||
| 复习提醒入口 | 已完成 | → SettingsView |
|
||||
| 学习方法偏好入口 | 已完成 | → MethodPreferenceView |
|
||||
| 帮助与反馈入口 | 已完成 | → FeedbackFormView |
|
||||
| 发现公开库入口 | 已完成 | → DiscoverView |
|
||||
| 消息中心入口 | 已完成 | → NotificationListView |
|
||||
| 通知图标入口 | 已完成 | → NotificationListView |
|
||||
| 设置图标入口 | 已完成 | → SettingsView |
|
||||
| 创建知识库入口(学习资产行) | 已完成 | → CreateLibraryPage |
|
||||
|
||||
### P24 编辑资料页 (EditProfilePage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 上传头像 | 已完成 | PhotosPicker → 256x256 裁剪 → COS 上传 |
|
||||
| 编辑昵称 | 已完成 | TextField |
|
||||
| 编辑学习身份 | 已完成 | TextField |
|
||||
| 编辑学习方向 | 已完成 | TextField |
|
||||
| 编辑当前目标 | 已完成 | TextField |
|
||||
| 编辑个人简介 | 已完成 | TextEditor |
|
||||
| 保存 | 已完成 | UserService.updateProfile() + updateProfileDetail() |
|
||||
|
||||
### P25 设置页 (SettingsView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 切换外观模式 | 已完成 | system/dark/light 循环切换 → UserService.updatePreferences() |
|
||||
| 语言显示 | 已完成 | 展示"简体中文" |
|
||||
| 学习目标设置入口 | 已完成 | → GoalSettingDetailView |
|
||||
| 方法偏好入口 | 已完成 | → MethodPreferenceView |
|
||||
| 复习提醒开关 | 已完成 | Toggle + 条件显示提醒时间/间隔天数选择器 |
|
||||
| 复习提醒时间选择 | 已完成 | SegmentedPicker: 08:00/12:00/18:00/20:00/21:00 |
|
||||
| 间隔天数选择 | 已完成 | SegmentedPicker: 1/2/3/5/7 天 |
|
||||
| 通知开关 | 部分完成 | 三个通知开关(复习提醒/导入完成/系统通知)全部绑定到同一个 $reviewReminder 变量,疑似 bug |
|
||||
| 存储空间展示 | 已完成 | profileVM.formattedStorage |
|
||||
| iCloud 同步开关 | 暂未确认 | Toggle UI 存在,切换仅改变本地 @State,未调用任何 API |
|
||||
| 个人资料入口 | 已完成 | → EditProfilePage |
|
||||
| 设备管理入口 | 未完成 | "登录设备管理"行 → Route.settings(指向自身),无实际设备管理页面 |
|
||||
| 帮助与反馈入口 | 已完成 | → FeedbackFormView |
|
||||
| 隐私政策入口 | 未完成 | "隐私政策"行无任何导航动作(无 NavigationLink/Button action) |
|
||||
| 用户协议入口 | 未完成 | "用户协议"行无任何导航动作 |
|
||||
| 退出登录 | 已完成 | 确认弹窗 → authManager.signOut() |
|
||||
| 版本号展示 | 已完成 | "知习 v1.0" |
|
||||
|
||||
### P26 学习目标设置页 (GoalSettingDetailView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 选择学习目标 | 已完成 | 4 选 1 → UserService.updateProfileDetail(currentGoal) |
|
||||
| 选择每日学习时长 | 部分完成 | 4 选 1 UI 存在,但 dailyMins 只保存在本地 @State,不通过 API 持久化 |
|
||||
|
||||
### P27 学习方法偏好页 (MethodPreferenceView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 多选学习方法 | 已完成 | 4 种方法多选 → UserService.updatePreferences(preferredMethods) |
|
||||
| 保存 | 已完成 | "保存"按钮 → API 调用 |
|
||||
|
||||
### P28 通知列表页 (NotificationListView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看通知列表(按日期分组) | 已完成 | NotificationService.list(),分组为今天/本周/更早 |
|
||||
| 按类型显示图标和颜色 | 已完成 | 10+ 种通知类型映射 |
|
||||
| 标记单条已读 | 已完成 | NotificationService.markRead() |
|
||||
| 全部标记已读 | 已完成 | NotificationService.markAllRead() |
|
||||
| 下拉刷新 | 已完成 | .refreshable |
|
||||
| 空状态 | 已完成 | "暂无通知" |
|
||||
|
||||
### P29 帮助与反馈页 (FeedbackFormView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 选择反馈类型 | 已完成 | Bug 反馈/功能建议/内容问题/其他 |
|
||||
| 输入反馈内容 | 已完成 | TextEditor |
|
||||
| 提交反馈 | 已完成 | FeedbackService.submit() |
|
||||
|
||||
---
|
||||
|
||||
## 六、AI 辅助功能
|
||||
|
||||
### P30 AI 对话页 (AIChatPage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 发送文字消息 | 已完成 | → RagChatService.sendMessageStream() |
|
||||
| 流式接收 AI 回复 | 已完成 | AsyncThrowingStream SSE 解析 |
|
||||
| 查看 AI 思考过程(可折叠) | 已完成 | ThinkingSection 组件 |
|
||||
| 复制 AI 回复 | 已完成 | UIPasteboard.general.string |
|
||||
| 重新生成回复 | 已完成 | onRegenerate → vm.send() |
|
||||
| 新建对话 | 已完成 | vm.createNewSession() |
|
||||
| 会话列表 Sheet | 已完成 | .sheet 展示 ChatSession 列表 |
|
||||
| 切换历史会话 | 已完成 | vm.loadSession(id) |
|
||||
| 搜索会话 | 已完成 | 会话列表中有搜索功能 |
|
||||
| 删除会话 | 已完成 | swipe → RagChatService.deleteSession() |
|
||||
| 归档会话 | 已完成 | swipe → UpdateChatSessionRequest(isArchived: true) |
|
||||
| 置顶/取消置顶 | 已完成 | swipe → UpdateChatSessionRequest(isPinned:) |
|
||||
| 对话范围标签 | 已完成 | scopeLabel 显示在消息列表顶部 |
|
||||
| 创建会话中状态 | 已完成 | ProgressView + "正在准备 AI 助手..." |
|
||||
| 会话创建失败状态 | 已完成 | 错误图标 + 文字 |
|
||||
|
||||
### P31 每日思考页 (DailyThinkingPage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看思考题目 | 占位实现 | 题目硬编码:"解释'注意力机制'在 Transformer 中的作用" |
|
||||
| 输入回答 | 已完成 | TextEditor |
|
||||
| 提交获取 AI 反馈 | 占位实现 | → AIFeedbackPageView(本身为占位实现)。注意:submitted 状态变量从未被设置为 true,提交按钮始终可见 |
|
||||
|
||||
### P32 AI 反馈页 (AIFeedbackPageView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| AI 分析进度动画 | 占位实现 | 4 步动画 + 硬编码 5 秒等待 |
|
||||
| 得分展示 | 占位实现 | 78/100 硬编码,圆环进度 0.78 |
|
||||
| 掌握度评价 | 占位实现 | "良好掌握" 硬编码 |
|
||||
| 答对/答错分析 | 占位实现 | 2 条硬编码文字 |
|
||||
| 加入待巩固 | 占位实现 | → StudyHomeView |
|
||||
| 深入提问 | 已完成 | → AIChatPage(AIChatPage 本身已完成) |
|
||||
| 再来一题 | 已完成 | → DailyThinkingPage(DailyThinkingPage 本身为占位实现) |
|
||||
|
||||
### P33 薄弱知识点页 (WeakPointsPage)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看薄弱知识点列表 | 占位实现 | 5 个硬编码 ZXWeakRow(贝叶斯定理/正态分布/词根/Covariance/梯度下降) |
|
||||
| 优先级标签 | 占位实现 | 硬编码"高"/"中"优先级 |
|
||||
|
||||
### (废弃)AI 首页 (AIHomeView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 服务器状态检查 | 已完成 | APIClient.shared.request("/") 健康检查 |
|
||||
| 快速操作入口 | 已完成 | 4 个 NavigationLink 到 activeRecall/weakPoints/aiChat/reviewCard |
|
||||
| 每日思考卡片 | 占位实现 | 硬编码题目 |
|
||||
| 推荐问题列表 | 占位实现 | 3 条硬编码推荐文字 |
|
||||
| 底部输入栏 | 已完成 | 输入 → NavigationLink 到 AIChatPage |
|
||||
| 整体页面 | 占位实现 | **代码完整但无任何导航入口**,Route 枚举中无对应 case,无任何页面跳转到此 |
|
||||
|
||||
---
|
||||
|
||||
## 七、测验功能
|
||||
|
||||
### P34 测验列表页 (QuizListView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看测验列表 | 已完成 | QuizService.list(knowledgeBaseId:) |
|
||||
| 生成新测验 | 已完成 | QuizService.generate(),失败时 Toast |
|
||||
| 空状态引导 | 已完成 | "暂无测验" + "生成测验"按钮 |
|
||||
| 开始作答 | 已完成 | → QuizTakerView |
|
||||
|
||||
### P35 测验作答页 (QuizTakerView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 选择题作答(A/B/C/D) | 已完成 | 选项按钮,选中高亮 |
|
||||
| 判断题作答 | 已完成 | "正确"/"错误"按钮 |
|
||||
| 填空题作答 | 已完成 | TextField |
|
||||
| 上一题/下一题导航 | 已完成 | 按钮导航 |
|
||||
| 进度条 | 已完成 | GeometryReader 进度条 |
|
||||
| 提交答案 | 已完成 | QuizService.submit() |
|
||||
| 提交失败 Toast | 已完成 | ZXToastManager.shared.error("提交失败") |
|
||||
|
||||
### P36 测验结果页 (QuizResultView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看得分 | 已完成 | 大号数字,>=60 绿色,<60 红色 |
|
||||
| 查看正确/总题数 | 已完成 | "答对 X/Y 题" |
|
||||
| 查看逐题详情(正确/错误标记+解析) | 已完成 | ForEach 遍历 answers |
|
||||
| 重新测验 | 已完成 | → QuizTakerView |
|
||||
|
||||
---
|
||||
|
||||
## 八、资料阅读
|
||||
|
||||
### P37 资料阅读页 (MaterialReaderView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| Markdown 渲染 | 已完成 | Rust FFI parseMarkdown → DocumentBlockView |
|
||||
| 纯文本渲染 | 已完成 | Rust FFI parseText → DocumentBlockView |
|
||||
| 图片显示 | 已完成 | UIImage + 元信息 |
|
||||
| PDF/Word/Excel 系统预览 | 已完成 | QuickLook Sheet |
|
||||
| PowerPoint 外部打开 | 已完成 | ShareLink |
|
||||
| 不支持格式提示 | 已完成 | "暂不支持此格式" |
|
||||
| 标记已读 | 已完成 | 本地 MarkedReadStore + 事件上报 |
|
||||
| AI 对话(资料范围) | 已完成 | → AIChatPage 带 ChatEntryContext(.material) |
|
||||
| 查看资料详情 | 已完成 | → MaterialDetailView |
|
||||
| 开始学习会话 | 已完成 | → LearningSessionView |
|
||||
| 添加笔记 | 已完成 | → QuickNoteSheet,含锚点记录 |
|
||||
| 恢复阅读位置 | 已完成 | API → 本地 → 会话 三级优先级 |
|
||||
| 自动记录阅读位置(2s 防抖) | 已完成 | reportScrollPosition |
|
||||
| 前后台会话管理 | 已完成 | scenePhase → pause/resume |
|
||||
| 心跳上报(15s) | 已完成 | Rust FFI |
|
||||
| COS 自动下载 | 已完成 | 文件不存在时自动从 COS 下载 |
|
||||
| 解析触发 | 部分完成 | 60×2s 硬编码轮询,硬编码超时逻辑 |
|
||||
| 阅读进度标记 | 已完成 | API reading-progress 查询 |
|
||||
|
||||
### P38 资料详情页 (MaterialDetailView)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| AI 处理状态横幅 | 已完成 | 处理中(琥珀色)/就绪(绿色)/失败(红色) |
|
||||
| 文件元数据展示 | 已完成 | 文件名、格式、大小、上传日期 |
|
||||
| 阅读进度卡片 | 已完成 | 阅读状态 + 累计阅读时长 |
|
||||
| 知识点/测验计数 | 已完成 | statBox 展示 |
|
||||
|
||||
---
|
||||
|
||||
## 九、弹窗与 Sheet
|
||||
|
||||
### S01 AI 会话列表 Sheet
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 查看会话列表 | 已完成 | RagChatService.listSessions() |
|
||||
| 切换会话 | 已完成 | 点击 → vm.loadSession() |
|
||||
| 搜索会话 | 已完成 | 搜索输入 |
|
||||
| 删除会话 | 已完成 | swipe 删除 |
|
||||
| 归档会话 | 已完成 | swipe 归档 |
|
||||
| 置顶/取消置顶 | 已完成 | swipe 置顶 |
|
||||
| 新建会话 | 已完成 | + 按钮 |
|
||||
|
||||
### S02 快速笔记 Sheet (QuickNoteSheet)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| 输入笔记文字 | 已完成 | TextEditor(自动聚焦) |
|
||||
| 保存笔记 | 已完成 | UserDefaults 存储,含锚点信息 |
|
||||
| 取消 | 已完成 | dismiss() |
|
||||
|
||||
### S03 系统预览 (QuickLook)
|
||||
|
||||
| 功能 | 状态 | 判定依据 |
|
||||
|------|------|---------|
|
||||
| PDF/Office 预览 | 已完成 | QLPreviewController |
|
||||
|
||||
---
|
||||
|
||||
## 十、统计
|
||||
|
||||
| 统计项 | 已完成 | 部分完成 | 占位实现 | 未完成 | 暂未确认 |
|
||||
|--------|--------|---------|---------|--------|---------|
|
||||
| 启动/登录功能 | 16 | 0 | 0 | 0 | 0 |
|
||||
| 学习 Tab 功能 | 8 | 2 | 6 | 1 | 1 |
|
||||
| 知识库 Tab 功能 | 30 | 3 | 0 | 3 | 0 |
|
||||
| 分析 Tab 功能 | 12 | 0 | 2 | 0 | 1 |
|
||||
| 我的 Tab 功能 | 24 | 2 | 0 | 3 | 1 |
|
||||
| AI 辅助功能 | 12 | 0 | 10 | 0 | 0 |
|
||||
| 测验功能 | 11 | 0 | 0 | 0 | 0 |
|
||||
| 资料阅读功能 | 17 | 1 | 0 | 0 | 0 |
|
||||
| Sheet/弹窗功能 | 9 | 0 | 0 | 0 | 0 |
|
||||
| **总计** | **139** | **8** | **18** | **7** | **3** |
|
||||
189
docs/system-map/ios/review/03-页面差异清单.md
Normal file
189
docs/system-map/ios/review/03-页面差异清单.md
Normal file
@ -0,0 +1,189 @@
|
||||
# 03 页面差异清单
|
||||
|
||||
> 将独立页面基线(review/01-独立页面基线.md)与已有文档(01-iOS页面地图.md)逐项比对。
|
||||
|
||||
---
|
||||
|
||||
## 一、文档已覆盖且正确的页面(一致项)
|
||||
|
||||
以下页面在文档中描述正确,与代码实现一致:
|
||||
|
||||
| 文档章节 | 文档页面名 | 代码类型 | 判定 |
|
||||
|---------|-----------|---------|------|
|
||||
| 1.1 | 启动页 (SplashScreen) | SplashScreen | 一致 |
|
||||
| 1.2 | 欢迎页 (WelcomePage) | WelcomePage | 一致 |
|
||||
| 1.3 | 登录页 (LoginPage) | LoginPage | 一致 |
|
||||
| 1.4 | 账号状态页 (AccountStatusView) | AccountStatusView | 一致 |
|
||||
| 1.5 | 引导页 (OnboardingPage) | OnboardingPage | 一致 |
|
||||
| 1.6 | 目标设置页 (GoalSetupPage) | GoalSetupPage | 一致 |
|
||||
| 2.1 | 学习主页 (StudyHomeView) | StudyHomeView | 一致 |
|
||||
| 2.2 | 学习会话页 (LearningSessionView) | LearningSessionView | 一致 |
|
||||
| 2.3 | 复习卡片页 (ReviewCardView) | ReviewCardView | 一致 |
|
||||
| 2.4 | 主动回忆页 (ActiveRecallView) | ActiveRecallView | 一致 |
|
||||
| 3.1 | 知识库首页 (LibraryHomeView) | LibraryHomeView | 一致 |
|
||||
| 3.2 | 知识库搜索页 (LibrarySearchView) | LibrarySearchView | 一致 |
|
||||
| 3.3 | 知识库详情页 (LibraryDetailPage) | LibraryDetailPage | 一致 |
|
||||
| 3.4 | 创建知识库页 (CreateLibraryPage) | CreateLibraryPage | 一致 |
|
||||
| 3.5 | 添加知识点页 (AddKnowledgePage) | AddKnowledgePage | 一致 |
|
||||
| 3.6 | 知识点详情页 (KnowledgeDetailPage) | KnowledgeDetailPage | 一致 |
|
||||
| 3.7 | 编辑知识点页 (EditKnowledgePage) | EditKnowledgePage | 一致 |
|
||||
| 3.8 | 导入资料页 (ImportPage) | ImportPage | 一致 |
|
||||
| 3.9 | 导入候选审核页 (ImportReviewPage) | ImportReviewPage | 一致 |
|
||||
| 3.10 | 发现公开库页 (DiscoverView) | DiscoverView | 一致 |
|
||||
| 3.11 | 文件夹管理 (FolderManageView) | FolderManageView | 一致 |
|
||||
| 4.1 | 学习分析页 (AnalysisHomeView) | AnalysisHomeView | 一致 |
|
||||
| 5.1 | 个人中心页 (ProfileView) | ProfileView | 一致 |
|
||||
| 5.2 | 编辑资料页 (EditProfilePage) | EditProfilePage | 一致 |
|
||||
| 5.3 | 设置页 (SettingsView) | SettingsView | 一致 |
|
||||
| 5.4 | 学习目标设置页 (GoalSettingDetailView) | GoalSettingDetailView | 一致 |
|
||||
| 5.5 | 学习方法偏好页 (MethodPreferenceView) | MethodPreferenceView | 一致 |
|
||||
| 5.6 | 通知列表页 (NotificationListView) | NotificationListView | 一致 |
|
||||
| 5.7 | 帮助与反馈页 (FeedbackFormView) | FeedbackFormView | 一致 |
|
||||
| 6.1 | AI 对话页 (AIChatPage) | AIChatPage | 一致 |
|
||||
| 6.2 | 每日思考页 (DailyThinkingPage) | DailyThinkingPage | 一致 |
|
||||
| 6.3 | AI 反馈页 (AIFeedbackPageView) | AIFeedbackPageView | 一致 |
|
||||
| 6.4 | 薄弱知识点页 (WeakPointsPage) | WeakPointsPage | 一致 |
|
||||
| 6.5 | AI 首页 (AIHomeView) | AIHomeView | 一致(正确标记为废弃) |
|
||||
| 7.1 | 测验列表页 (QuizListView) | QuizListView | 一致 |
|
||||
| 7.2 | 测验作答页 (QuizTakerView) | QuizTakerView | 一致 |
|
||||
| 7.3 | 测验结果页 (QuizResultView) | QuizResultView | 一致 |
|
||||
| 8.1 | 资料阅读页 (MaterialReaderView) | MaterialReaderView | 一致 |
|
||||
| 8.2 | 资料详情页 (MaterialDetailView) | MaterialDetailView | 一致 |
|
||||
| 9.1 | 快速笔记 (QuickNoteSheet) | QuickNoteSheet | 一致 |
|
||||
| 9.2 | 系统预览 (QuickLook) | QuickLookPreview | 一致 |
|
||||
| 9.3 | AI 会话列表 Sheet | AIChatPage 内 Sheet | 一致 |
|
||||
| 9.4 | 封面选择 Sheet | CreateLibraryPage 内 Sheet | 一致 |
|
||||
| 9.5 | 链接导入弹窗 | ImportPage 内 Alert | 一致 |
|
||||
| 9.6 | 各类确认弹窗 | 多个 Alert/ConfirmationDialog | 一致 |
|
||||
|
||||
**一致页面数:43 个(含 6 个 Sheet/弹窗)**
|
||||
|
||||
---
|
||||
|
||||
## 二、代码存在但文档遗漏的页面
|
||||
|
||||
### 遗漏 1:RecallTestPage
|
||||
|
||||
- **代码位置:** `Features/AI/RecallTestPage.swift`
|
||||
- **页面作用:** 独立的回忆测试页面,用户输入对特定知识点的理解,提交后跳转 AI 反馈页。
|
||||
- **入口:** 代码中有 Route 定义但**未被任何 NavigationLink 引用**。Route 枚举中有 `aiFeedback` case,但未发现 `recallTest` case。
|
||||
- **实际状态:** 代码存在但无导航入口(类似 AIHomeView 的情况)。
|
||||
- **应出现在:** 01-iOS页面地图.md → 第六章 AI 辅助功能
|
||||
- **建议补到位置:** 新增 6.6 节"回忆测试页(RecallTestPage)"
|
||||
- **建议状态:** 占位实现(无导航入口 + 题目硬编码)
|
||||
|
||||
### 遗漏 2:Route.studyHome 独立页面
|
||||
|
||||
- **代码位置:** Route.swift `case studyHome`
|
||||
- **说明:** Route 中定义了 `studyHome` 路由目标(指向 StudyHomeView(selectedTab: .constant("study"))),可被 NavigationLink 跳转到学习主页的独立副本。虽然与 Tab 1 的学习主页渲染同一 View,但路由跳转会 push 一个新的 NavigationStack 副本。
|
||||
- **文档处理:** 文档将 StudyHomeView 仅归入 Tab 页面,未提及它也可作为 Push 路由目标。
|
||||
- **建议:** 在页面跳转关系中标注 StudyHomeView 可被 Route.studyHome 推入导航栈。
|
||||
|
||||
---
|
||||
|
||||
## 三、文档记录但当前不可访问的页面
|
||||
|
||||
无。所有文档记录的页面在代码中均有对应的入口。
|
||||
|
||||
---
|
||||
|
||||
## 四、文档记录为"已完成",但实际为"部分完成"或"占位实现"的页面
|
||||
|
||||
| 文档页面 | 文档状态 | 实际状态 | 差异说明 |
|
||||
|---------|---------|---------|---------|
|
||||
| 学习会话页 (2.2) | 已完成 | 暂未确认 | 文档称"已完成"。页面计时功能完成,但**未发现调用 LearningSessionService.start/end 保存学习记录到 API 的代码**,学习时长仅在本地计时。 |
|
||||
| 复习卡片页 (2.3) | 占位实现 | 占位实现 | 状态一致,但文档说 ReviewViewModel 和 ReviewPlanViewModel 代码已就绪。实际情况:ReviewCardView 完全忽略 ViewModel 的数据,使用不同类型的硬编码结构体 ReviewCardItem。 |
|
||||
| 主动回忆页 (2.4) | 占位实现 | 占位实现 | 状态一致。 |
|
||||
| 知识库首页 (3.1) | 部分完成 | 部分完成 | 状态一致。 |
|
||||
| 知识库详情页 (3.3) | 部分完成 | 部分完成 | 状态一致。 |
|
||||
| 学习分析页 (4.1) | 部分完成 | 部分完成 | 状态一致。但需补充:**每日学习时长(dailyMins)保存逻辑缺失**(GoalSettingDetailView 中 dailyMins 仅保存在本地 @State)。 |
|
||||
| 设置页 (5.3) | 部分完成 | 部分完成 | 状态一致。需补充:"存储空间"行 → Route.settings(自引用),"登录设备管理" → Route.settings(自引用),均无实际导航目标。 |
|
||||
| AI 反馈页 (6.3) | 占位实现 | 占位实现 | 状态一致。 |
|
||||
| 薄弱知识点页 (6.4) | 占位实现 | 占位实现 | 状态一致。 |
|
||||
| 资料阅读页 (8.1) | 部分完成 | 部分完成 | 状态一致。 |
|
||||
| 每日思考页 (6.2) | 占位实现 | 占位实现 | 状态一致。但需补充:`submitted` 状态变量从未被设置为 true,提交按钮始终可见(这可能导致 UI 行为异常)。 |
|
||||
|
||||
---
|
||||
|
||||
## 五、文档重复记录的页面
|
||||
|
||||
无发现。文档每个页面只记录一次。
|
||||
|
||||
---
|
||||
|
||||
## 六、页面名称不同但实际为同一个页面的情况
|
||||
|
||||
无发现。文档页面名称与代码类型名称一一对应。
|
||||
|
||||
---
|
||||
|
||||
## 七、页面被错误归入业务模块的情况
|
||||
|
||||
| 页面 | 文档归类 | 建议归类 | 原因 |
|
||||
|------|---------|---------|------|
|
||||
| 创建知识库页 | 知识库 Tab | 正确 | 入口来自知识库首页和我的页 |
|
||||
| 学习会话页 | 学习 Tab | 正确 | 入口来自资料阅读页 |
|
||||
| 主动回忆页 | 学习 Tab | 正确 | 入口来自学习主页 |
|
||||
|
||||
无严重归类错误。
|
||||
|
||||
---
|
||||
|
||||
## 八、Sheet、弹窗、隐藏入口遗漏检查
|
||||
|
||||
### 已记录的 Sheet/弹窗(9.1-9.6)
|
||||
|
||||
| 文档项目 | 覆盖情况 |
|
||||
|---------|---------|
|
||||
| 快速笔记 (9.1) | 已覆盖 |
|
||||
| 系统预览 (9.2) | 已覆盖 |
|
||||
| AI 会话列表 Sheet (9.3) | 已覆盖 |
|
||||
| 封面选择 Sheet (9.4) | 已覆盖 |
|
||||
| 链接导入弹窗 (9.5) | 已覆盖 |
|
||||
| 各类确认弹窗 (9.6) | 已覆盖 6 个中的 6 个 |
|
||||
|
||||
### 遗漏的 Sheet/弹窗
|
||||
|
||||
| 遗漏项 | 所在页面 | 说明 |
|
||||
|--------|---------|------|
|
||||
| 文件夹新建/重命名 Alert | FolderManageView | "新建分类" + "重命名"两个带 TextField 的 Alert,文档在 9.6 确认弹窗表格中未列出 |
|
||||
|
||||
建议在 9.6 确认弹窗表格中补充:
|
||||
- 新建分类(FolderManageView)
|
||||
- 重命名分类(FolderManageView)
|
||||
|
||||
---
|
||||
|
||||
## 九、页面入口和跳转关系错误
|
||||
|
||||
| 错误位置 | 文档描述 | 实际代码 | 严重程度 |
|
||||
|---------|---------|---------|---------|
|
||||
| 学习主页"查看完整分析" → ActiveRecallView | 文档:跳转主动回忆页 | 代码:`Route.activeRecall` → ActiveRecallView | **正确**(但主动回忆页为占位实现) |
|
||||
| 学习主页"自我测试" → QuizTakerView | 文档:跳转测验作答页 | 代码:MainAction.selfTest → Route.quizTake(quizId:) | **正确** |
|
||||
| 学习主页"自我测试"小卡片 → QuizListView | 文档未明确 | 代码:Route.quizList(knowledgeBaseId: "") | **需补充**,知识库 ID 为空字符串可能导致异常 |
|
||||
| 设置页"复习提醒" → SettingsView | 文档:跳转设置页(从我的页复习提醒行) | 代码:`Route.settings` → SettingsView | **正确但奇怪**:从设置页的"复习提醒"行再次跳转 SettingsView 形成自引用 |
|
||||
|
||||
---
|
||||
|
||||
## 十、页面状态遗漏
|
||||
|
||||
| 遗漏状态 | 所在页面 | 说明 |
|
||||
|---------|---------|------|
|
||||
| LearningSessionView 未保存学习记录到 API | 学习会话页 | 文档标记为"已完成",但缺少 API 持久化,用户在分析页看不到本次学习数据 |
|
||||
| StudyHomeViewModel 永不为 error | 学习主页 | error 状态代码存在但 ViewModel 中所有 API 调用用 try? 吞错,error 状态永不可达 |
|
||||
| DailyThinkingPage submitted 永不为 true | 每日思考页 | 提交按钮始终可见,可能导致用户重复提交 |
|
||||
| GoalSettingDetailView dailyMins 不持久化 | 学习目标设置页 | 每日时长选择不通过 API 保存,下次进入恢复默认"30 分钟" |
|
||||
|
||||
---
|
||||
|
||||
## 十一、总体评估
|
||||
|
||||
| 评估维度 | 结果 |
|
||||
|---------|------|
|
||||
| 文档页面覆盖率 | 43/45 (95.6%) — 遗漏 RecallTestPage + studyHome 路由 |
|
||||
| 页面状态准确率 | 38/43 (88.4%) — 5 个页面状态描述与代码存在差异 |
|
||||
| Sheet/弹窗覆盖率 | 8/9 (88.9%) — 遗漏 1 个确认弹窗组合 |
|
||||
| 跳转关系准确率 | 基本正确,1 处需补充说明 |
|
||||
| 页面状态描述完整度 | 需补充 4 处状态遗漏 |
|
||||
|
||||
**结论:页面地图文档整体质量较高,覆盖率 95%+。主要问题集中在页面完成状态的部分误判,以及个别状态的遗漏。**
|
||||
140
docs/system-map/ios/review/04-功能差异清单.md
Normal file
140
docs/system-map/ios/review/04-功能差异清单.md
Normal file
@ -0,0 +1,140 @@
|
||||
# 04 功能差异清单
|
||||
|
||||
> 将独立功能基线(review/02-独立功能基线.md)与已有文档(02-iOS页面功能总表.md)逐项比对。
|
||||
|
||||
---
|
||||
|
||||
## 一、功能遗漏清单
|
||||
|
||||
### 遗漏 1:学习主页 selfTestSmallCard → QuizListView (kbId="")
|
||||
|
||||
- **文档覆盖:** 文档记录"进行自我测试"功能(点击主操作卡片或测试卡片)
|
||||
- **遗漏:** 文档未说明 smallCard 跳转 QuizListView 时 knowledgeBaseId 为空字符串,可能导致不正确的行为
|
||||
- **应补到:** 02-iOS页面功能总表.md → 学习 Tab → "进行自我测试"
|
||||
- **建议补充说明:** "注:辅助卡片自测入口使用空 knowledgeBaseId,可能在 quizList 中显示空列表"
|
||||
|
||||
### 遗漏 2:GoalSettingDetailView 每日学习时长不持久化
|
||||
|
||||
- **文档覆盖:** 文档 5.4 节记录 GoalSettingDetailView 的"修改每日时长"功能为"已完成"
|
||||
- **实际:** dailyMins 只保存在本地 @State 变量,未通过 API 持久化
|
||||
- **应补到:** 02-iOS页面功能总表.md → 我的 Tab → "修改每日时长"
|
||||
- **建议状态修正:** 已完成为 → 部分完成(UI 完成,数据不持久化)
|
||||
|
||||
### 遗漏 3:RecallTestPage 功能未记录
|
||||
|
||||
- **文档覆盖:** 未记录
|
||||
- **实际:** RecallTestPage 代码存在(Features/AI/RecallTestPage.swift),含:
|
||||
- 查看回忆测试题(硬编码)
|
||||
- 输入回答
|
||||
- 提交获取 AI 反馈(→ AIFeedbackPageView)
|
||||
- **建议补到:** 02-iOS页面功能总表.md → AI 辅助功能 → 新增"回忆测试页"行
|
||||
- **建议状态:** 占位实现(无导航入口,题目硬编码)
|
||||
|
||||
### 遗漏 4:AIChatPage 置顶/取消置顶会话
|
||||
|
||||
- **文档覆盖:** 文档记录"删除会话"和"归档会话"
|
||||
- **遗漏:** 未记录置顶/取消置顶功能(swipeActions(edge: .leading))
|
||||
- **应补到:** 02-iOS页面功能总表.md → AI 辅助功能 → AI 对话页
|
||||
- **建议新增行:** "置顶/取消置顶会话 | 左滑→置顶/取消置顶 | 切换会话置顶状态"
|
||||
|
||||
### 遗漏 5:MaterialReaderView 解析触发 + 轮询
|
||||
|
||||
- **文档覆盖:** 文档在"阅读 Markdown 内容"等行标注已完成
|
||||
- **遗漏:** 文档未将"触发 AI 知识提取(解析)"作为独立功能记录,工具栏 brain 按钮触发 60×2s 轮询是一个重要功能
|
||||
- **建议补到:** 02-iOS页面功能总表.md → 资料阅读 → 新增行
|
||||
- **建议新增行:** "触发知识提取 | 点击工具栏大脑按钮 | 提交解析任务,轮询进度(60×2s) | 部分完成 | 轮询使用硬编码次数和间隔"
|
||||
|
||||
### 遗漏 6:AIHomeView 的全部功能(虽已废弃)
|
||||
|
||||
- **文档覆盖:** 文档记录了 AIHomeView 为占位实现/已废弃,但功能总表中将其合并入一行"AI 首页(已废弃)"
|
||||
- **遗漏:** 该页面内有具体的子功能(服务器状态检查、快速操作入口、每日思考卡片、推荐问题列表),但功能总表未展开
|
||||
- **评估:** 这对于已废弃页面是合理的简化处理,不做强制修正要求
|
||||
|
||||
---
|
||||
|
||||
## 二、功能状态误判
|
||||
|
||||
| 文档功能 | 文档状态 | 实际状态 | 判定依据 |
|
||||
|---------|---------|---------|---------|
|
||||
| 学习会话-专注计时学习 | 已完成 | 暂未确认 | 本地计时完成,但未发现调用 LearningSessionService API 保存学习记录 |
|
||||
| 学习主页-开始今日复习 | 部分完成 | 部分完成 | 入口正常,ReviewCardView 为占位实现。文档正确标记。 |
|
||||
| 学习主页-查看完整分析 | 已完成 | 已完成 | 入口存在,跳转到 ActiveRecallView(本身为占位实现)。**文档正确标记了跳转目标的状态,但入口本身已完成。** |
|
||||
| 学习主页-探索公开知识库 | 已完成 | 已完成 | 切换到 library Tab |
|
||||
| 分析页-查看掌握度趋势图 | 部分完成 | 占位实现 | **应为占位实现**,ZXChartView 使用完全硬编码的 7 天数据 `[("一", 0.62)...]`,ViewModel 的 trend 数据被忽略 |
|
||||
| 分析页-查看每周学习活跃 | 部分完成 | 占位实现 | **应为占位实现**,ZXWeekBarChart 使用完全硬编码数据,ViewModel 的 heatmap 数据被忽略 |
|
||||
| 分析页-查看 AI 综合分析 | 已完成 | 已完成 | 动态拼接 API 数据,非 AI 生成 |
|
||||
| 分析页-查看全部薄弱知识点 | 已完成 | 已完成 | 跳转到 WeakPointsPage(本身为占位实现) |
|
||||
| 设置页-切换导入完成通知 | 暂未确认 | 部分完成 | 三个通知开关全部绑定到同一个 $reviewReminder 变量,是明确的 **bug** 而非待确认 |
|
||||
| 设置页-切换系统通知 | 暂未确认 | 部分完成 | 同上 |
|
||||
| 设置页-切换 iCloud 同步 | 暂未确认 | 暂未确认 | 仅改变本地 @State,无 API 调用 |
|
||||
| GoalSettingDetailView-修改每日时长 | 已完成 | 部分完成 | dailyMins 不持久化 |
|
||||
| 每日思考页-提交回答 | 占位实现 | 占位实现 | 状态一致,但 submitted 变量 bug 未记录 |
|
||||
|
||||
---
|
||||
|
||||
## 三、自动触发功能遗漏
|
||||
|
||||
文档功能总表主要记录了用户主动触发的功能,以下自动触发功能在文档中有部分遗漏:
|
||||
|
||||
| 自动功能 | 文档覆盖 | 建议 |
|
||||
|---------|---------|------|
|
||||
| MaterialReaderView 进入时自动恢复阅读位置 | 已覆盖("恢复阅读位置"行) | — |
|
||||
| MaterialReaderView 前后台切换暂停/恢复会话 | 已覆盖 | — |
|
||||
| MaterialReaderView 自动从 COS 下载文件 | 未明确记录 | 建议在"阅读 Markdown 内容"备注中补充 |
|
||||
| MaterialReaderView COS 过期 URL 重取 | 未明确记录 | 建议补充 |
|
||||
| 学习主页优先级自动计算 | 已覆盖 | — |
|
||||
| StudyHomeViewModel 错误状态永不可达 | 未记录 | 建议在备注中说明 ViewModel 的 try? 吞错行为 |
|
||||
|
||||
---
|
||||
|
||||
## 四、搜索、筛选、排序、分页等辅助功能检查
|
||||
|
||||
| 功能 | 页面 | 文档覆盖 | 备注 |
|
||||
|------|------|---------|------|
|
||||
| 知识库搜索 | LibraryHomeView | 已覆盖(但标为部分完成) | 搜索页搜索逻辑未实现 |
|
||||
| 知识库分类筛选 | LibraryHomeView | 已覆盖 | 4 个分类 chips |
|
||||
| 知识库分页加载 | LibraryHomeView | 已覆盖 | 无限滚动 |
|
||||
| 知识点排序 | LibraryDetailPage | 已覆盖 | 4 种排序 |
|
||||
| 知识点批量选择 | LibraryDetailPage | 已覆盖 | |
|
||||
| 会话搜索 | AIChatPage Sheet | 已覆盖 | |
|
||||
| 通知列表无筛选 | NotificationListView | 未记录筛选 | 无筛选功能,合理 |
|
||||
| 测验列表无筛选 | QuizListView | 未记录筛选 | 无筛选功能,合理 |
|
||||
|
||||
---
|
||||
|
||||
## 五、API 调用存在但无页面入口
|
||||
|
||||
### WaitlistService
|
||||
|
||||
- **API 端点:** /waitlist (POST), /waitlist/stats (GET)
|
||||
- **代码存在:** APIService.swift 中 WaitlistService 类完整定义
|
||||
- **页面入口:** 无任何 View 或 ViewModel 调用 WaitlistService
|
||||
- **文档记录:** 文档未提及 waitlist 功能
|
||||
- **建议:** 在系统地图中标注"Waitlist API 已就绪但 C 端无入口"(或在总览中标注为后端预留能力)
|
||||
|
||||
### UserService.requestAccountDeletion / cancelDeletion
|
||||
|
||||
- **API 端点:** /users/me/deletion-request (POST/DELETE)
|
||||
- **页面入口:** 无任何页面调用这两个方法
|
||||
- **文档记录:** 未提及注销账号功能
|
||||
- **建议:** 补充到设置页的未完成功能列表
|
||||
|
||||
### UserService.listDevices / removeDevice
|
||||
|
||||
- **API 端点:** /users/me/devices (GET/DELETE)
|
||||
- **页面入口:** 设置页有"登录设备管理"行但无导航目标(→ Route.settings 自引用)
|
||||
- **建议:** 标注为"API 已就绪,设备管理页面未实现"
|
||||
|
||||
---
|
||||
|
||||
## 六、总体评估
|
||||
|
||||
| 评估维度 | 结果 |
|
||||
|---------|------|
|
||||
| 功能总表覆盖率 | 约 95%,遗漏约 6 个功能点 |
|
||||
| 功能状态准确率 | 约 90%,7 个功能的状态需要修正 |
|
||||
| 自动触发功能覆盖 | 基本完整,2 处建议补充 |
|
||||
| 辅助功能覆盖 | 完整 |
|
||||
| API-页面映射完整性 | 3 个 API 有端点无页面入口需标注 |
|
||||
|
||||
**结论:功能总表文档覆盖较全面,主要问题是若干功能的状态标记偏乐观(部分图表数据被标记为"部分完成"但实际为"占位实现"),以及少数自动触发功能和 API-页面不一致未记录。**
|
||||
272
docs/system-map/ios/review/05-业务能力归类审查.md
Normal file
272
docs/system-map/ios/review/05-业务能力归类审查.md
Normal file
@ -0,0 +1,272 @@
|
||||
# 05 业务能力归类审查
|
||||
|
||||
> 审查对象:已有文档 `03-C端业务能力初步清单.md`
|
||||
> 审查方法:先独立归类,再与文档比对
|
||||
|
||||
---
|
||||
|
||||
## 一、独立业务能力归类
|
||||
|
||||
基于代码扫描独立建立的业务能力清单:
|
||||
|
||||
### 能力 1:账号注册与登录
|
||||
|
||||
- **代码依据:** Apple ID 登录(LoginPage)、会话恢复(SplashScreen/AuthManager)、Token 刷新(APIClient)、账号禁用/注销状态处理(AccountStatusView)
|
||||
- **用户目标:** 使用 Apple ID 安全登录,会话自动恢复
|
||||
- **关联页面:** P01, P03, P04, P05
|
||||
- **独立判定:** 已存在,核心流程完整
|
||||
|
||||
### 能力 2:新手引导与目标设定
|
||||
|
||||
- **代码依据:** WelcomePage → OnboardingPage → GoalSetupPage 流程
|
||||
- **用户目标:** 首次使用时了解产品价值,设定个性化学习目标
|
||||
- **关联页面:** P02, P06, P07, P26, P27
|
||||
- **独立判定:** 已存在
|
||||
|
||||
### 能力 3:个人资料维护
|
||||
|
||||
- **代码依据:** EditProfilePage(头像/昵称/身份/方向/目标/简介)+ ProfileView(查看)
|
||||
- **用户目标:** 维护个人档案信息
|
||||
- **关联页面:** P23, P24
|
||||
- **独立判定:** 已存在
|
||||
|
||||
### 能力 4:知识库浏览与管理
|
||||
|
||||
- **代码依据:** LibraryHomeView(列表/筛选/分页)、LibraryDetailPage(详情/排序/删除)、CreateLibraryPage(创建)、DiscoverView(公开库发现/订阅)
|
||||
- **用户目标:** 创建、浏览、管理个人知识库,发现和订阅公开知识库
|
||||
- **关联页面:** P12, P14, P15, P21
|
||||
- **独立判定:** 已存在。部分功能未完成(官方库筛选、KB 管理页、搜索逻辑)
|
||||
|
||||
### 能力 5:知识点管理
|
||||
|
||||
- **代码依据:** LibraryDetailPage 知识点 Tab(列表/排序/删除/批量操作)、AddKnowledgePage(手动/文件/图片添加)、KnowledgeDetailPage(查看)、EditKnowledgePage(编辑)
|
||||
- **用户目标:** 在知识库中增删改查知识点
|
||||
- **关联页面:** P14, P16, P17, P18
|
||||
- **独立判定:** 已存在。收藏 API 未支持、重命名/移动到文件夹为 TODO
|
||||
|
||||
### 能力 6:资料上传与处理
|
||||
|
||||
- **代码依据:** ImportPage(文件/相册/链接导入)、ImportReviewPage(AI 候选审批)
|
||||
- **用户目标:** 将外部资料导入知识库,审核 AI 提取的知识点
|
||||
- **关联页面:** P19, P20
|
||||
- **独立判定:** 已存在
|
||||
|
||||
### 能力 7:文档阅读
|
||||
|
||||
- **代码依据:** MaterialReaderView(多格式渲染/位置恢复/标记已读)、MaterialDetailView(处理状态/元数据)、QuickLook(系统预览)、ShareLink(外部打开)
|
||||
- **用户目标:** 阅读学习资料,支持多种格式
|
||||
- **关联页面:** P37, P38, S03
|
||||
- **独立判定:** 已存在
|
||||
|
||||
### 能力 8:阅读笔记
|
||||
|
||||
- **代码依据:** QuickNoteSheet(创建笔记/自动锚点记录)
|
||||
- **用户目标:** 在阅读过程中记笔记
|
||||
- **关联页面:** S02
|
||||
- **独立判定:** 已存在。本地存储(UserDefaults),未同步到服务端
|
||||
|
||||
### 能力 9:阅读行为跟踪
|
||||
|
||||
- **代码依据:** ReadingRuntimeSessionManager + ReadingEventCollector + ReadingPositionStore
|
||||
- **用户目标:** 自动记录阅读行为,用于分析
|
||||
- **关联页面:** P37(自动执行)
|
||||
- **独立判定:** 已存在
|
||||
|
||||
### 能力 10:学习信息收集
|
||||
|
||||
- **代码依据:** LearningSessionView(计时)、MaterialReaderView(阅读会话)
|
||||
- **用户目标:** 记录学习时长和阅读行为
|
||||
- **关联页面:** P09, P37
|
||||
- **独立判定:** 已存在。但 LearningSessionView 未发现 API 保存调用,需确认学习会话数据是否真正被收集
|
||||
|
||||
### 能力 11:继续学习
|
||||
|
||||
- **代码依据:** StudyHomeView 优先级算法(ContinueLearningResponse → MainAction.continueSession)
|
||||
- **用户目标:** 从上次中断处继续学习
|
||||
- **关联页面:** P08
|
||||
- **独立判定:** 已存在
|
||||
|
||||
### 能力 12:AI 对话
|
||||
|
||||
- **代码依据:** AIChatPage(流式对话/思考过程/多会话管理/范围限定)
|
||||
- **用户目标:** 与 AI 进行学习相关对话
|
||||
- **关联页面:** P30, S01
|
||||
- **独立判定:** 已存在
|
||||
|
||||
### 能力 13:题目与测验
|
||||
|
||||
- **代码依据:** QuizListView(查看/生成)、QuizTakerView(作答/提交)、QuizResultView(结果/解析)
|
||||
- **用户目标:** 通过测验检验学习效果
|
||||
- **关联页面:** P34, P35, P36
|
||||
- **独立判定:** 已存在
|
||||
|
||||
### 能力 14:学习分析
|
||||
|
||||
- **代码依据:** AnalysisHomeView(统计徽章/趋势图/连续统计/学习记录/推荐/薄弱点)
|
||||
- **用户目标:** 查看学习数据分析和趋势
|
||||
- **关联页面:** P22
|
||||
- **独立判定:** 已存在。掌握度趋势图和每周活跃图为占位实现
|
||||
|
||||
### 能力 15:主动回忆与 AI 反馈
|
||||
|
||||
- **代码依据:** ActiveRecallView → AIFeedbackPageView 链路
|
||||
- **用户目标:** 主动输出知识,获得 AI 评估反馈
|
||||
- **关联页面:** P11, P32, P31
|
||||
- **独立判定:** 占位实现(全部使用硬编码数据)
|
||||
|
||||
### 能力 16:间隔复习
|
||||
|
||||
- **代码依据:** ReviewCardView(闪卡翻转/自评)
|
||||
- **用户目标:** 基于间隔重复的闪卡复习
|
||||
- **关联页面:** P10
|
||||
- **独立判定:** 占位实现(硬编码数据,未接通 API)
|
||||
|
||||
### 能力 17:学习会话计时
|
||||
|
||||
- **代码依据:** LearningSessionView(专注计时/暂停/结束/庆祝)
|
||||
- **用户目标:** 记录专注学习时长
|
||||
- **关联页面:** P09
|
||||
- **独立判定:** 部分完成(本地计时完成,API 持久化待确认)
|
||||
|
||||
### 能力 18:消息与通知
|
||||
|
||||
- **代码依据:** NotificationListView(分组展示/已读标记)、SettingsView(通知开关)
|
||||
- **用户目标:** 接收系统通知,管理通知偏好
|
||||
- **关联页面:** P28, P25
|
||||
- **独立判定:** 已存在。通知开关存在绑定 bug
|
||||
|
||||
### 能力 19:设置与应用偏好
|
||||
|
||||
- **代码依据:** SettingsView(外观/语言/复习提醒/通知/存储/iCloud/退出登录)
|
||||
- **用户目标:** 管理应用全局设置
|
||||
- **关联页面:** P25, P26, P27
|
||||
- **独立判定:** 已存在。合规页面入口缺失、设备管理未实现
|
||||
|
||||
### 能力 20:帮助与反馈
|
||||
|
||||
- **代码依据:** FeedbackFormView(类型选择/内容输入/提交)
|
||||
- **用户目标:** 提交问题和建议
|
||||
- **关联页面:** P29
|
||||
- **独立判定:** 已存在
|
||||
|
||||
### 能力 21:存储空间管理
|
||||
|
||||
- **代码依据:** ProfileView 存储空间展示 + SettingsView iCloud 同步开关
|
||||
- **用户目标:** 了解和控制存储使用
|
||||
- **关联页面:** P23, P25
|
||||
- **独立判定:** 部分存在(展示完成,iCloud 同步待确认)
|
||||
|
||||
---
|
||||
|
||||
## 二、与已有文档的能力对比
|
||||
|
||||
### 完全一致的能力(14 项)
|
||||
|
||||
| 序号 | 独立能力 | 文档能力 | 判定 |
|
||||
|------|---------|---------|------|
|
||||
| 1 | 账号注册与登录 | 1. 账号与用户 | 一致 |
|
||||
| 2 | 新手引导与目标设定 | 2. 新手引导与目标设定 | 一致 |
|
||||
| 3 | 知识库浏览与管理 | 3. 知识库管理 | 一致 |
|
||||
| 4 | 知识点管理 | 4. 知识点管理 | 一致 |
|
||||
| 5 | 资料上传与处理 | 5. 资料上传 | 一致 |
|
||||
| 6 | 文档阅读 | 6. 文档阅读 | 一致 |
|
||||
| 7 | 阅读笔记 | 7. 阅读笔记 | 一致 |
|
||||
| 8 | 阅读行为跟踪 | 8. 阅读行为跟踪 | 一致 |
|
||||
| 9 | 学习信息收集 | 9. 学习信息收集 | 一致 |
|
||||
| 10 | 继续学习 | 10. 继续学习 | 一致 |
|
||||
| 11 | AI 对话 | 11. AI 对话 | 一致 |
|
||||
| 12 | 题目与测验 | 14. 题目与测验 | 一致 |
|
||||
| 13 | 帮助与反馈 | 20. 帮助与反馈 | 一致 |
|
||||
| 14 | 设置与应用偏好 | 19. 设置与合规 | 基本一致 |
|
||||
|
||||
### 需要调整的能力(6 项)
|
||||
|
||||
| 独立能力 | 文档对应 | 问题 | 建议 |
|
||||
|---------|---------|------|------|
|
||||
| 个人资料维护 | 合并入"1. 账号与用户" | 文档将个人资料维护合并入账号与用户能力。独立判定认为这是可接受的归类,但边界稍显模糊。 | 可保持现状,或拆分出"个人资料维护"子能力 |
|
||||
| 主动回忆与 AI 反馈 | 15. 主动回忆 + 12. AI 学习分析 | 文档将"主动回忆"和"AI 学习分析"分为两个独立能力。独立判定认为主动回忆 → AI 反馈是一个连续流程,不应强行拆分。 | 建议将"15. 主动回忆"与"12. AI 学习分析"合并为"主动回忆与 AI 反馈" |
|
||||
| 间隔复习 | 16. 间隔复习 | 一致 | — |
|
||||
| 学习分析 | 13. 学习分析 | 一致 | — |
|
||||
| 学习会话计时 | 无独立条目 | 文档将学习会话计时合并入"9. 学习信息收集"。独立判定认为学习会话计时是一个有独立 UI 的用户行为,宜作为独立能力或子能力。 | 建议在"学习信息收集"能力下明确标注"学习会话计时"子项 |
|
||||
| 消息与通知 | 18. 消息与通知 | 一致 | — |
|
||||
| 存储空间管理 | 合并入"17. 会员与额度" | 文档将其归入"会员与额度"。独立判定认为当前代码中无会员/订阅/付费功能,命名为"会员与额度"不准确。 | 建议重命名为"存储与额度"或"存储空间管理" |
|
||||
|
||||
### 文档有但未发现代码支持的能力(1 项)
|
||||
|
||||
| 文档能力 | 判定 | 说明 |
|
||||
|---------|------|------|
|
||||
| 17. 会员与额度 | 未发现会员/订阅相关代码 | 代码中无内购、订阅、付费墙、会员等级等实现。存储展示和 iCloud 同步开关存在,但被描述为"会员与额度"不准确。 |
|
||||
|
||||
---
|
||||
|
||||
## 三、能力归类质量检查
|
||||
|
||||
### 以技术模块命名检查
|
||||
|
||||
| 文档能力名 | 是否以技术模块命名 | 判定 |
|
||||
|-----------|-----------------|------|
|
||||
| 账号与用户 | 否 | 通过 |
|
||||
| 知识库管理 | 否 | 通过 |
|
||||
| 阅读行为跟踪 | 边缘 | 偏技术,建议改为"阅读进度同步"或保持 |
|
||||
| AI 对话 | 否 | 通过 |
|
||||
| AI 学习分析 | 否 | 通过 |
|
||||
|
||||
### 闭环拆分过度/不足检查
|
||||
|
||||
| 文档能力 | 问题 |
|
||||
|---------|------|
|
||||
| 主动回忆 + AI 学习分析 | 拆分过度。主动回忆提交 → AI 反馈是一个连续用户体验,不应分为两个能力 |
|
||||
| 阅读行为跟踪 + 学习信息收集 | 边界模糊。两者都涉及数据收集,调用相同的底层 FFI 和 API |
|
||||
| 文档阅读 + 阅读笔记 + 阅读行为跟踪 | 三个能力高度耦合在 MaterialReaderView 中,是否过度拆分值得商榷 |
|
||||
|
||||
### 按页面名称命名检查
|
||||
|
||||
| 文档能力 | 是否直接使用页面名 | 判定 |
|
||||
|---------|-----------------|------|
|
||||
| 继续学习 | 否(StudyHomeView 的功能,非页面名) | 通过 |
|
||||
| 题目与测验 | 否 | 通过 |
|
||||
| 主动回忆 | 是(与页面同名) | **建议改为"主动回忆与 AI 评估"** |
|
||||
|
||||
---
|
||||
|
||||
## 四、文档业务能力依赖关系图审查
|
||||
|
||||
文档中的依赖关系图:
|
||||
|
||||
```
|
||||
账号与用户
|
||||
└─ 新手引导与目标设定
|
||||
└─ 知识库管理
|
||||
├─ 知识点管理
|
||||
├─ 资料上传 → 文档阅读
|
||||
│ ├─ 阅读笔记
|
||||
│ └─ 阅读行为跟踪 → 学习信息收集
|
||||
└─ 题目与测验
|
||||
├─ AI 对话
|
||||
├─ 继续学习 → 主动回忆 / 间隔复习 / 文档阅读
|
||||
│ └─ AI 学习分析
|
||||
└─ 学习分析
|
||||
└─ AI 学习分析
|
||||
```
|
||||
|
||||
审查意见:
|
||||
1. "AI 对话"应在"知识库管理"下有分支(知识库范围对话)。
|
||||
2. "AI 对话"也应在"文档阅读"下有分支(资料范围对话)。
|
||||
3. "题目与测验"应在"文档阅读"下有分支(从资料阅读触发解析后进入测验)。
|
||||
4. "阅读笔记"也应关联到"知识点管理"(知识点详情页有笔记入口)。
|
||||
5. "主动回忆 → AI 学习分析 → 间隔复习"应形成环路(分析后加入待巩固)。
|
||||
6. "学习分析"应在"学习信息收集"之后,而非独立于信息收集。
|
||||
|
||||
---
|
||||
|
||||
## 五、总体评估
|
||||
|
||||
| 评估维度 | 结果 |
|
||||
|---------|------|
|
||||
| 能力数量合理度 | 20 项基本合理,建议合并"主动回忆"与"AI 学习分析" |
|
||||
| 能力命名准确度 | 17/20 准确,1 个偏技术(阅读行为跟踪),1 个以页面命名(主动回忆),1 个不准确(会员与额度) |
|
||||
| 能力边界清晰度 | 阅读相关 3 个能力(文档阅读/阅读笔记/阅读行为跟踪)边界可讨论 |
|
||||
| 依赖关系准确度 | 基本正确,若干分支缺失 |
|
||||
| 遗漏能力 | 无重大遗漏,学习会话计时建议作为子能力标注 |
|
||||
|
||||
**结论:业务能力归类文档整体合理,主要问题是"会员与额度"命名不准确(当前无会员功能)、"主动回忆"与"AI 学习分析"建议合并、依赖关系图缺少几个交叉引用。**
|
||||
104
docs/system-map/ios/review/06-页面能力覆盖矩阵.md
Normal file
104
docs/system-map/ios/review/06-页面能力覆盖矩阵.md
Normal file
@ -0,0 +1,104 @@
|
||||
# 06 页面能力覆盖矩阵
|
||||
|
||||
> 双向覆盖检查:页面→能力 + 能力→页面
|
||||
|
||||
---
|
||||
|
||||
## 一、页面→能力覆盖(每个页面至少归属一个业务能力)
|
||||
|
||||
| 页面 | 归属业务能力 | 主要功能 | 文档是否覆盖 | 状态判断是否正确 |
|
||||
|------|------------|---------|------------|----------------|
|
||||
| P01 启动页 | 账号注册与登录 | 自动恢复会话 | 是 | 是 |
|
||||
| P02 欢迎页 | 新手引导与目标设定 | 产品介绍、引导登录 | 是 | 是 |
|
||||
| P03 登录页 | 账号注册与登录 | Apple ID 登录 | 是 | 是 |
|
||||
| P04/P05 账号状态页 | 账号注册与登录 | 禁用/注销状态展示 | 是 | 是 |
|
||||
| P06 引导页 | 新手引导与目标设定 | 4 步产品引导 | 是 | 是 |
|
||||
| P07 目标设置页 | 新手引导与目标设定 | 设定目标/方法/时间 | 是 | 是 |
|
||||
| P08 学习主页 | 继续学习、学习分析 | 优先级算法、今日任务、每周摘要 | 是 | 是 |
|
||||
| P09 学习会话页 | 学习信息收集 | 专注计时 | 是 | 状态偏乐观(API 保存待确认) |
|
||||
| P10 复习卡片页 | 间隔复习 | 闪卡翻转、自评 | 是 | 是(标记为占位实现) |
|
||||
| P11 主动回忆页 | 主动回忆与 AI 反馈 | 文字/语音作答 | 是 | 是(标记为占位实现) |
|
||||
| P12 知识库首页 | 知识库浏览与管理 | 列表/筛选/分页 | 是 | 是 |
|
||||
| P13 知识库搜索页 | 知识库浏览与管理 | 搜索 | 是 | 是 |
|
||||
| P14 知识库详情页 | 知识库浏览与管理、知识点管理 | 双 Tab/排序/批量操作/删除 | 是 | 是 |
|
||||
| P15 创建知识库页 | 知识库浏览与管理 | 创建知识库 | 是 | 是 |
|
||||
| P16 添加知识点页 | 知识点管理 | 手动/文件/图片添加 | 是 | 是 |
|
||||
| P17 知识点详情页 | 知识点管理、文档阅读 | 查看/渲染/收藏/笔记 | 是 | 部分(收藏 API 未支持) |
|
||||
| P18 编辑知识点页 | 知识点管理 | 编辑标题/内容 | 是 | 是 |
|
||||
| P19 导入资料页 | 资料上传与处理 | 文件/相册/链接导入 | 是 | 是 |
|
||||
| P20 导入候选审核页 | 资料上传与处理 | 候选审批 | 是 | 是 |
|
||||
| P21 发现公开库页 | 知识库浏览与管理 | 浏览/订阅公开库 | 是 | 是 |
|
||||
| P22 学习分析页 | 学习分析 | 统计/趋势图/记录/推荐/薄弱点 | 是 | 部分(趋势图为占位) |
|
||||
| P23 个人中心页 | 个人资料维护、设置与应用偏好 | 资料/菜单/资产/存储 | 是 | 是 |
|
||||
| P24 编辑资料页 | 个人资料维护 | 头像/昵称/身份/目标 | 是 | 是 |
|
||||
| P25 设置页 | 设置与应用偏好、消息与通知 | 外观/复习/通知/存储/退出 | 是 | 部分(通知开关 bug,合规入口缺失) |
|
||||
| P26 学习目标设置页 | 新手引导与目标设定 | 修改目标/时长 | 是 | 否(dailyMins 不持久化,文档标已完成) |
|
||||
| P27 方法偏好页 | 新手引导与目标设定 | 多选方法 | 是 | 是 |
|
||||
| P28 通知列表页 | 消息与通知 | 查看/标记已读/全部已读 | 是 | 是 |
|
||||
| P29 帮助与反馈页 | 帮助与反馈 | 选择类型/输入/提交 | 是 | 是 |
|
||||
| P30 AI 对话页 | AI 对话 | 流式对话/会话管理 | 是 | 是 |
|
||||
| P31 每日思考页 | 主动回忆与 AI 反馈 | 查看题目/提交回答 | 是 | 是(标记为占位) |
|
||||
| P32 AI 反馈页 | 主动回忆与 AI 反馈 | 分析评分/建议/导航 | 是 | 是(标记为占位) |
|
||||
| P33 薄弱知识点页 | 学习分析 | 查看薄弱点列表 | 是 | 是(标记为占位) |
|
||||
| (废) AIHomeView | AI 对话、主动回忆、间隔复习、学习分析 | 快速操作/思考题/推荐 | 是(标记为废弃) | 是 |
|
||||
| P34 测验列表页 | 题目与测验 | 查看/生成测验 | 是 | 是 |
|
||||
| P35 测验作答页 | 题目与测验 | 选择/判断/填空作答 | 是 | 是 |
|
||||
| P36 测验结果页 | 题目与测验 | 得分/逐题详情/重测 | 是 | 是 |
|
||||
| P37 资料阅读页 | 文档阅读、阅读笔记、阅读行为跟踪、学习信息收集、AI 对话 | 多格式渲染/位置恢复/标记已读/AI/笔记 | 是 | 是 |
|
||||
| P38 资料详情页 | 文档阅读 | AI 处理状态/元数据/进度 | 是 | 是 |
|
||||
| S01 会话列表 Sheet | AI 对话 | 会话搜索/切换/删除/归档/置顶 | 是 | 遗漏置顶功能 |
|
||||
| S02 快速笔记 Sheet | 阅读笔记 | 创建笔记/锚点记录 | 是 | 是 |
|
||||
| S03 系统预览 | 文档阅读 | PDF/Office 预览 | 是 | 是 |
|
||||
| S04 封面选择 Sheet | 知识库浏览与管理 | 相册选择封面 | 是 | 是 |
|
||||
| S05 文件夹管理 Sheet | 知识库浏览与管理 | 文件夹 CRUD | 是 | 是 |
|
||||
| (无入口) RecallTestPage | 主动回忆与 AI 反馈 | 回忆测试 | 否 | 遗漏 |
|
||||
| (无入口) WaitlistService | 未归类 | waitlist 加入/统计 | 否 | 遗漏(API 存在但无 C 端入口) |
|
||||
|
||||
---
|
||||
|
||||
## 二、能力→页面覆盖(每个能力是否有实际页面入口)
|
||||
|
||||
| 业务能力 | 有页面入口? | 关联页面 | 遗漏关联页面 | 错误关联 |
|
||||
|---------|------------|---------|------------|---------|
|
||||
| 账号注册与登录 | 是 | P01,P03,P04,P05 | 无 | 无 |
|
||||
| 新手引导与目标设定 | 是 | P02,P06,P07,P26,P27 | 无 | 无 |
|
||||
| 知识库浏览与管理 | 是 | P12,P14,P15,P21,S04,S05 | 遗漏 P13(搜索页) | 无 |
|
||||
| 知识点管理 | 是 | P14,P16,P17,P18 | 无 | 无 |
|
||||
| 资料上传与处理 | 是 | P19,P20 | 无 | 无 |
|
||||
| 文档阅读 | 是 | P17,P37,P38,S03 | 无 | 无 |
|
||||
| 阅读笔记 | 是 | S02,P37 | 遗漏 P17(知识点详情页笔记入口) | 无 |
|
||||
| 阅读行为跟踪 | 是(自动) | P37 | 无 | 无 |
|
||||
| 学习信息收集 | 是(自动) | P09,P37 | 无 | 无 |
|
||||
| 继续学习 | 是 | P08,P22 | 无 | 无 |
|
||||
| AI 对话 | 是 | P30,S01,P37 | 遗漏 P14(知识库范围 AI 对话) | 无 |
|
||||
| 题目与测验 | 是 | P34,P35,P36 | 无 | 无 |
|
||||
| 学习分析 | 是 | P22,P33 | 无 | 无 |
|
||||
| 主动回忆与 AI 反馈 | 是(占位) | P11,P31,P32 | 遗漏 RecallTestPage | 无 |
|
||||
| 间隔复习 | 是(占位) | P10 | 无 | 无 |
|
||||
| 学习会话计时 | 是 | P09 | 无 | 无 |
|
||||
| 消息与通知 | 是 | P28,P25 | 无 | 无 |
|
||||
| 设置与应用偏好 | 是 | P25,P26,P27 | 无 | 无 |
|
||||
| 帮助与反馈 | 是 | P29 | 无 | 无 |
|
||||
| 存储空间管理 | 是 | P23,P25 | 无 | 无 |
|
||||
| 会员与额度(文档命名) | — | — | 无实际会员/订阅代码 | 文档将存储+资产归入此项不准确 |
|
||||
|
||||
---
|
||||
|
||||
## 三、无法归类的页面或功能
|
||||
|
||||
| 对象 | 问题 | 建议 |
|
||||
|------|------|------|
|
||||
| WaitlistService | API 完整但无 C 端入口 | 在系统地图中标注为"后端已就绪,C 端未接入" |
|
||||
| RecallTestPage | 代码存在但无导航入口 | 归类到"主动回忆与 AI 反馈",标注为占位实现 |
|
||||
| AIHomeView | 已废弃,无法归类到实际能力 | 保持现状,作为废弃页面参考 |
|
||||
| UserService.requestAccountDeletion | API 存在但无页面入口 | 在"账号与用户"能力中标注"账号注销 API 已就绪,C 端入口未实现" |
|
||||
|
||||
---
|
||||
|
||||
## 四、双向覆盖检查结论
|
||||
|
||||
- **页面→能力:** 43/43 个可访问页面均已归属至少一个业务能力。RecallTestPage(无入口)未归属。
|
||||
- **能力→页面:** 19/20 个能力有实际页面入口。"会员与额度"能力无实际会员/订阅代码支持。
|
||||
- **遗漏关联页面:** 5 处(知识库搜索页、知识点详情页笔记入口、知识库范围 AI 对话、RecallTestPage、WaitlistService)
|
||||
- **错误关联:** 无
|
||||
- **状态判断错误:** 2 处(学习会话 API 保存、GoalSetting dailyMins 持久化)
|
||||
150
docs/system-map/ios/review/07-待修正文档清单.md
Normal file
150
docs/system-map/ios/review/07-待修正文档清单.md
Normal file
@ -0,0 +1,150 @@
|
||||
# 07 待修正文档清单
|
||||
|
||||
> 列出所有需要在已有系统地图文档中修正的条目,按优先级排序。
|
||||
|
||||
---
|
||||
|
||||
## P0 — 影响整体地图正确性(必须修正)
|
||||
|
||||
### P0-1:每日学习时长不持久化 → 02-iOS页面功能总表
|
||||
|
||||
- **涉及文档:** 02-iOS页面功能总表.md
|
||||
- **位置:** 我的 Tab → "修改每日时长"
|
||||
- **当前状态:** 已完成
|
||||
- **修正为:** 部分完成
|
||||
- **原因:** GoalSettingDetailView 中 dailyMins 只保存在本地 @State 变量,未通过 API 持久化。用户下次进入设置页时恢复默认值"30 分钟"。
|
||||
- **备注栏补充:** "UI 选择完成,但选择结果不通过 API 保存"
|
||||
|
||||
### P0-2:分析页图表数据为占位实现 → 02-iOS页面功能总表
|
||||
|
||||
- **涉及文档:** 02-iOS页面功能总表.md
|
||||
- **位置:** 分析 Tab → "查看掌握度趋势图" 和 "查看每周学习活跃"
|
||||
- **当前状态:** 部分完成
|
||||
- **修正为:** 占位实现
|
||||
- **原因:** ZXChartView 使用硬编码 `[("一", 0.62), ...]` 数据,ZXWeekBarChart 使用硬编码 `[("一", 0.3), ...]` 数据。两组数据均未从 ViewModel 的 API 数据读取,属于完全占位实现。
|
||||
- **备注栏补充:** "图表组件使用编译时硬编码的 7 天数据,未接入 ViewModel API 返回的真实数据"
|
||||
|
||||
### P0-3:设置页通知开关绑定 bug → 02-iOS页面功能总表
|
||||
|
||||
- **涉及文档:** 02-iOS页面功能总表.md
|
||||
- **位置:** 我的 Tab → "切换导入完成通知"、"切换系统通知"
|
||||
- **当前状态:** 暂未确认
|
||||
- **修正为:** 部分完成(存在 bug)
|
||||
- **原因:** SettingsView 中"复习提醒"、"导入完成通知"、"系统通知"三个 Toggle 全部绑定到同一个 `$reviewReminder` 变量(见 SettingsView.swift:61-65)。这不是"待确认",而是明确的代码 bug。
|
||||
- **修正状态描述:** "三个通知开关绑定到同一状态变量,需修复为各自独立绑定"
|
||||
|
||||
### P0-4:文档声称的页面总数与实际不符
|
||||
|
||||
- **涉及文档:** 00-iOS-C端总览.md
|
||||
- **位置:** 第四节"页面总览"
|
||||
- **当前描述:** "共盘点出 43 个页面/弹窗"(已完成 19 + 部分完成 13 + 占位实现 7 + 暂未确认 1 + 未完成 3)
|
||||
- **实际:** 独立基线盘点出 38 个独立 Push 页面 + 10 个 Sheet/弹窗 + 8 个确认弹窗 + 1 个废弃页面 = 总计约 47 个可盘点对象(含弹窗)
|
||||
- **说明:** 文档的"43"如果指页面+弹窗,则遗漏了 RecallTestPage(代码存在无入口)、部分 Alert 弹窗。建议明确统计口径并更新数字。
|
||||
|
||||
---
|
||||
|
||||
## P1 — 遗漏主要页面或业务能力
|
||||
|
||||
### P1-1:遗漏 RecallTestPage
|
||||
|
||||
- **涉及文档:** 01-iOS页面地图.md, 02-iOS页面功能总表.md
|
||||
- **遗漏对象:** RecallTestPage (Features/AI/RecallTestPage.swift)
|
||||
- **应补到位置:** 01 第六章 AI 辅助功能,新增 6.6 节"回忆测试页"
|
||||
- **建议状态:** 占位实现(无导航入口 + 题目硬编码)
|
||||
- **功能表补充:** 查看回忆测试题、输入回答、提交获取 AI 反馈(→ AIFeedbackPageView)
|
||||
|
||||
### P1-2:遗漏 AIChatPage 会话置顶功能
|
||||
|
||||
- **涉及文档:** 02-iOS页面功能总表.md
|
||||
- **遗漏对象:** AI 对话页 → 会话列表 Sheet → 左滑置顶/取消置顶
|
||||
- **应补到位置:** AI 辅助功能 → AI 对话页
|
||||
- **新增行:** "置顶/取消置顶会话 | 左滑→置顶/取消置顶 | 切换会话置顶状态 | 已完成"
|
||||
|
||||
### P1-3:遗漏 WaitlistService API 已就绪但 C 端无入口
|
||||
|
||||
- **涉及文档:** 00-iOS-C端总览.md 或 03-C端业务能力初步清单.md
|
||||
- **遗漏对象:** WaitlistService(/waitlist POST, /waitlist/stats GET)
|
||||
- **说明:** API 服务代码完整但无任何 View/ViewModel 调用。应标注为"后端已就绪,C 端入口未实现"。
|
||||
|
||||
### P1-4:遗漏账号注销 API 已就绪但无入口
|
||||
|
||||
- **涉及文档:** 03-C端业务能力初步清单.md → 账号与用户
|
||||
- **遗漏对象:** UserService.requestAccountDeletion() 和 cancelDeletion()
|
||||
- **说明:** API 端点 /users/me/deletion-request POST/DELETE 已就绪,但设置页及其他页面均未提供注销账号入口。
|
||||
- **建议:** 在"账号与用户"能力中补充"账号注销 API 已就绪,C 端入口未实现"
|
||||
|
||||
---
|
||||
|
||||
## P2 — 命名、描述、辅助状态问题
|
||||
|
||||
### P2-1:业务能力"会员与额度"命名不准确 → 03
|
||||
|
||||
- **涉及文档:** 03-C端业务能力初步清单.md
|
||||
- **当前命名:** 17. 会员与额度
|
||||
- **修正为:** 存储空间管理(或"存储与额度")
|
||||
- **原因:** 代码中无任何会员/订阅/付费墙/内购实现。该能力实际包含的功能仅为存储空间展示和学习资产统计。
|
||||
|
||||
### P2-2:建议合并"主动回忆"与"AI 学习分析" → 03
|
||||
|
||||
- **涉及文档:** 03-C端业务能力初步清单.md
|
||||
- **当前:** 15. 主动回忆 和 12. AI 学习分析 为两个独立能力
|
||||
- **建议:** 合并为"主动回忆与 AI 反馈"
|
||||
- **原因:** 主动回忆 → AI 反馈是一个连续用户体验流程,不应拆分为两个独立业务能力
|
||||
|
||||
### P2-3:StudyHomeViewModel 错误状态永不可达 → 01
|
||||
|
||||
- **涉及文档:** 01-iOS页面地图.md
|
||||
- **位置:** 2.1 学习主页 → 页面主要状态
|
||||
- **当前描述:** "加载中 / 错误 / 已加载·有任务 / 已加载·空状态"
|
||||
- **补充说明:** "注:View 支持 error 状态展示,但 ViewModel 中所有 API 调用使用 try? 吞错,error 状态在实际运行中永不可达"
|
||||
|
||||
### P2-4:DailyThinkingPage submitted 变量 bug → 01
|
||||
|
||||
- **涉及文档:** 01-iOS页面地图.md
|
||||
- **位置:** 6.2 每日思考页
|
||||
- **补充说明:** "注:submitted 状态变量在代码中从未被设置为 true,提交按钮始终可见,可能导致用户重复提交"
|
||||
|
||||
### P2-5:设置页自引用导航 → 01
|
||||
|
||||
- **涉及文档:** 01-iOS页面地图.md
|
||||
- **位置:** 5.3 设置页
|
||||
- **当前描述:** "存储空间"行和"登录设备管理"行 → Route.settings
|
||||
- **补充说明:** "存储空间"和"登录设备管理"导航目标均为 Route.settings(指向设置页自身),形成无效的自引用
|
||||
|
||||
### P2-6:知识库详情页操作菜单"知识库管理"按钮 → 01
|
||||
|
||||
- **涉及文档:** 01-iOS页面地图.md
|
||||
- **位置:** 3.3 知识库详情页
|
||||
- **当前描述:** 用户可执行操作中未包含此按钮
|
||||
- **补充说明:** 操作菜单中存在"知识库管理"按钮,但 action 为空(// TODO),属未实现功能
|
||||
|
||||
### P2-7:业务能力依赖关系图缺少交叉引用 → 03
|
||||
|
||||
- **涉及文档:** 03-C端业务能力初步清单.md
|
||||
- **位置:** "业务能力依赖关系(初步)"
|
||||
- **补充以下分支:**
|
||||
- AI 对话 → 知识库管理(知识库范围对话)
|
||||
- AI 对话 → 文档阅读(资料范围对话)
|
||||
- 文档阅读 → 题目与测验(解析完成后进入测验)
|
||||
- 阅读笔记 → 知识点管理(知识点详情页笔记入口)
|
||||
- 主动回忆 → 间隔复习(AI 分析后加入待巩固 → 安排间隔复习)
|
||||
- 学习分析 → 学习信息收集(分析依赖信息收集数据)
|
||||
|
||||
### P2-8:文件夹新建/重命名 Alert 未列入确认弹窗表 → 01
|
||||
|
||||
- **涉及文档:** 01-iOS页面地图.md 9.6 节"各类确认弹窗"表格
|
||||
- **补充行:**
|
||||
- 新建分类 | FolderManageView | 点击"新建"
|
||||
- 重命名分类 | FolderManageView | 滑动→重命名
|
||||
|
||||
---
|
||||
|
||||
## 修正优先级汇总
|
||||
|
||||
| 优先级 | 数量 | 影响范围 |
|
||||
|--------|------|---------|
|
||||
| P0 | 4 | 状态误判会导致整体地图失真 |
|
||||
| P1 | 4 | 遗漏主要页面/功能/API 入口 |
|
||||
| P2 | 8 | 命名、描述、辅助状态完善 |
|
||||
|
||||
**总计待修正项:16 项**
|
||||
475
docs/system-map/review/07-内容与对话能力审查报告.md
Normal file
475
docs/system-map/review/07-内容与对话能力审查报告.md
Normal file
@ -0,0 +1,475 @@
|
||||
# 内容与对话能力审查报告
|
||||
|
||||
> 审查日期:2026-06-19
|
||||
> 审查范围:4 份跨项目能力文档
|
||||
> 审查方法:独立扫描所有相关仓库代码 → 独立还原三条业务链路 → 与文档逐项比对
|
||||
|
||||
---
|
||||
|
||||
## 1. 审查范围
|
||||
|
||||
### 1.1 已检查的仓库与模块
|
||||
|
||||
| 仓库 | 已检查的模块/文件 | 检查深度 |
|
||||
|------|-----------------|---------|
|
||||
| **iOS (AIStudyApp)** | 全部 64 个 .swift 文件(Features/AI, Features/Library, Features/MaterialReader, Features/Quiz, Features/Profile, Features/Study, Core/) | 逐文件阅读 |
|
||||
| **主 API (api-server)** | Prisma schema (2221 行完整模型)、rag-chat.service.ts、document-import.service.ts、knowledge-base.service.ts、knowledge-source.service.ts、knowledge-items.service.ts、files.service.ts、import-candidate 模块 | 逐文件阅读 |
|
||||
| **Python RAG Worker** | 全部 10 个 .py 文件(main.py, config.py, api_client.py, parser.py, chunker.py, embedder.py, indexer.py, candidate_generator.py, reranker.py, pipelines/import_pipeline.py) | 逐文件阅读 |
|
||||
| **Admin (admin-projects)** | App.tsx 路由、全部 ~40 个页面组件、全部 service 模块 | Agent 全面探索 |
|
||||
| **Prisma Schema** | 全部 120+ 数据模型定义 | 逐模型检查 |
|
||||
| **COS** | 通过 files.service.ts 和 Python RAG Worker 的 download_file 间接检查 | 间接验证 |
|
||||
| **Qdrant** | 通过 indexer.py 的 upsert_points / search / mark_deleted 间接检查 | 间接验证 |
|
||||
| **Rust Document Runtime** | 检查文档声称的参与环节 | 确认不参与上传/处理/AI对话链路 |
|
||||
| **Heavy Runtime** | 检查文档声称的参与环节 | 确认不参与基础对话链路 |
|
||||
|
||||
### 1.2 已检查的文档
|
||||
|
||||
- `03-资料上传与处理.md`
|
||||
- `04-知识库与知识点管理.md`
|
||||
- `05-AI对话与知识库问答.md`
|
||||
- `06-内容与对话项目矩阵.md`
|
||||
|
||||
---
|
||||
|
||||
## 2. 审查方法
|
||||
|
||||
### 2.1 独立还原方法
|
||||
|
||||
1. **链路一(资料上传与处理):** 从 iOS 文件选择入口 → API 预签名 URL → COS PUT → 确认上传 → KnowledgeSource 创建 → DocumentImport 入队 → Python RAG Worker 轮询/认领/下载/解析/分块/嵌入/索引/候选生成 → 候选审核 → 各状态位更新,逐环节检查代码调用链。
|
||||
2. **链路二(知识库与知识点管理):** 从 Prisma 数据模型出发,检查 KnowledgeBase/KnowledgeItem/KnowledgeSource/KnowledgeFolder/DocumentImport/ImportCandidate 之间的关系、CRUD 实现、权限校验、级联删除行为。
|
||||
3. **链路三(AI 对话与知识库问答):** 从 rag-chat.service.ts 出发,检查会话 open-or-create、5 种 scope 的上下文加载、AiGateway 路由、SSE 流式传输、Citation 生成,逐行核对代码与文档描述。
|
||||
|
||||
### 2.2 双向覆盖检查方法
|
||||
|
||||
- **文档→代码:** 对文档中每一项关于"已完成"的声明,在代码中寻找对应的实现证据。
|
||||
- **代码→文档:** 从代码中扫描出的所有 API 端点、服务方法和 Admin 页面,反向检查是否在文档中有对应记录。
|
||||
|
||||
### 2.3 跨文档一致性检查方法
|
||||
|
||||
- 逐份文档提取关于同一项目职责、同一业务对象、同一状态的描述,进行横向比对。
|
||||
|
||||
---
|
||||
|
||||
## 3. 独立还原的真实业务链路
|
||||
|
||||
### 3.1 链路一:资料上传与处理
|
||||
|
||||
**基于代码的独立还原:**
|
||||
|
||||
```
|
||||
1. iOS 文件选择 → ImportPage / AddKnowledgePage
|
||||
2. iOS → POST /files/upload-url (filename, mimeType, sizeBytes)
|
||||
3. API 内容安全检查文件名 → COS 生成预签名 PUT URL (1h 有效)
|
||||
4. iOS 直接 PUT 文件到 COS
|
||||
5. iOS → POST /files/complete (objectKey) → API headObject 验证 → 创建 UploadedFile 记录
|
||||
6. iOS → POST /knowledge-bases/:id/sources (fileId, type, title, ...)
|
||||
7. KnowledgeSourceService.addSource():
|
||||
- 创建 KnowledgeSource 记录 (parseStatus/indexStatus/learningStatus = "pending")
|
||||
- 自动创建 DocumentImport 记录 (status = "QUEUED")
|
||||
- Redis 状态初始化 (key: job:document-import:{id}:status/progress/message)
|
||||
- 入队到 'document-import' 队列
|
||||
8. Python RAG Worker (每 5s 轮询):
|
||||
- GET /internal/rag/jobs/next → 获取 QUEUED 任务
|
||||
- POST /internal/rag/jobs/{id}/claim → 认领
|
||||
- 启动心跳 (每 30s POST /internal/rag/jobs/{id}/heartbeat)
|
||||
- run_import():
|
||||
a. DOWNLOADING: 从 COS 下载文件
|
||||
b. PARSING: parse_document(file_path, mime_type)
|
||||
- PDF → PyMuPDF 文本提取 / OCR 回退 (SiliconFlow Qwen3-VL)
|
||||
- DOCX → python-docx
|
||||
- TXT/MD → 直接读取
|
||||
- CSV/XLSX → pandas → Markdown table
|
||||
- Images → SiliconFlow Qwen3-VL OCR
|
||||
c. CLEANING: (当前为占位——无实际清洗逻辑)
|
||||
d. CHUNKING: 递归字符分割 (512 tokens, 64 overlap, 中文句子边界保护)
|
||||
e. EMBEDDING: SiliconFlow BAAI/bge-m3 (1024维, 批次50, 重试2次)
|
||||
f. INDEXING: Qdrant upsert_points + API save_chunks (KnowledgeChunk 记录)
|
||||
g. GENERATING_CANDIDATES: DeepSeek deepseek-chat (temperature 0.3) 非致命步骤
|
||||
h. COMPLETED: update_job_status("COMPLETED", {progress: 100})
|
||||
9. 用户审核候选 → ImportCandidateService.accept/reject/batch-accept
|
||||
10. 接受候选 → API 创建 KnowledgeItem (itemType: ai_generated)
|
||||
```
|
||||
|
||||
**关键确认:**
|
||||
- parseStatus/indexStatus/learningStatus 三者独立追踪,由 Python RAG Worker 在管线不同阶段更新
|
||||
- 候选生成是非致命步骤——即使失败,解析和索引仍可成功
|
||||
- 原文件在 RAG 完成前即可阅读(MaterialReaderView 直接渲染文件,不等待 RAG)
|
||||
- Admin 导入监控页 (ImportMonitor.tsx) 支持查看步骤日志和重试
|
||||
|
||||
### 3.2 链路二:知识库与知识点管理
|
||||
|
||||
**基于代码的独立还原:**
|
||||
|
||||
```
|
||||
数据对象关系 (Prisma Schema):
|
||||
KnowledgeBase
|
||||
├── KnowledgeSource[] (1:N, 含 parseStatus/indexStatus/learningStatus)
|
||||
├── KnowledgeItem[] (1:N, 含 parentId 树状结构)
|
||||
├── KnowledgeFolder[] (1:N, 含 parentId 树状结构)
|
||||
├── KnowledgeChunk[] (1:N, 含 externalVectorId → Qdrant)
|
||||
├── ImportCandidate[] (1:N, 含 status: PENDING/ACCEPTED/REJECTED)
|
||||
├── KnowledgeBaseSubscription[] (1:N, userId+KBId 唯一约束)
|
||||
└── Quiz[] (1:N)
|
||||
|
||||
KnowledgeSource
|
||||
├── file: UploadedFile (1:1)
|
||||
├── items: KnowledgeItem[] (1:N, 通过 sourceId)
|
||||
├── chunks: KnowledgeChunk[] (1:N)
|
||||
└── candidates: ImportCandidate[] (1:N)
|
||||
|
||||
核心权限:
|
||||
- KB 创建: 每用户最多 20 个 (MAX_KNOWLEDGE_BASE_COUNT)
|
||||
- KB 所有权: userId 匹配校验,非所有者对私有 KB 返回 404
|
||||
- KB 删除: 仅所有者,软删除 (deletedAt)
|
||||
- 知识点删除: 所有者校验,itemCount 自动维护
|
||||
- 来源资料删除: KnowledgeSourceService.remove() 无所有权检查 (代码缺陷)
|
||||
- 文件夹更新/删除: updateFolder/deleteFolder 无显式所有权检查
|
||||
- 订阅: 不可订阅自己的 KB,KB 必须为公开且未删除
|
||||
|
||||
当前未实现的功能:
|
||||
- "官方"知识库: ownerType 字段存在,但无实际官方 KB 创建逻辑
|
||||
- 搜索: 仅 discover 端点支持 LIKE 查询 (title/description),无全文搜索
|
||||
- 收藏: Favorite 表存在但有 iOS 端 TODO 标记
|
||||
- 重命名/移动到文件夹: iOS contextMenu action 为空
|
||||
- 知识库管理页: iOS 操作菜单按钮 action 为空
|
||||
```
|
||||
|
||||
### 3.3 链路三:AI 对话与知识库问答
|
||||
|
||||
**基于代码的独立还原(rag-chat.service.ts 逐行分析):**
|
||||
|
||||
```
|
||||
五种 Scope 类型及上下文加载:
|
||||
|
||||
1. global:
|
||||
- 上下文: 空 (直接返回 isEmpty: true)
|
||||
- 代码: loadContextByScope → case 'global' → { text: '', citations: [], isEmpty: true }
|
||||
- iOS 入口: 从 AI 反馈页"深入提问"→ AIChatPage (context: nil)
|
||||
|
||||
2. knowledge_base:
|
||||
- 上下文: prisma.knowledgeItem.findMany({ knowledgeBaseId: kbId, deletedAt: null })
|
||||
- 查询: PostgreSQL KnowledgeItem 表 (非 Qdrant!)
|
||||
- 限制: 30 条, 每条约 500 字符, 总计最多 4000 字符
|
||||
- iOS 入口: 知识库详情页底部 AI 对话按钮
|
||||
|
||||
3. material:
|
||||
- 上下文: prisma.knowledgeItem.findMany({ knowledgeBaseId: kbId, sourceRef: scopeId })
|
||||
- 查询: PostgreSQL KnowledgeItem 表, 按 sourceRef 过滤
|
||||
- iOS 入口: 资料阅读页工具栏 AI 按钮
|
||||
|
||||
4. knowledge_item:
|
||||
- 上下文: prisma.knowledgeItem.findMany({ id: scopeId })
|
||||
- 查询: PostgreSQL KnowledgeItem 表, 单条知识点
|
||||
- iOS 入口: 知识点详情页工具栏菜单 (代码中 scopeType=knowledge_item 存在但 iOS 入口待确认)
|
||||
|
||||
5. folder:
|
||||
- 上下文: prisma.knowledgeItem.findMany({ knowledgeBaseId: kbId, parentId: scopeId })
|
||||
- 查询: PostgreSQL KnowledgeItem 表, 按父文件夹过滤
|
||||
|
||||
会话机制:
|
||||
- open-or-create: 相同 scopeType + scopeId + userId 复用未删除未归档会话
|
||||
- forceCreate: 跳过查找,强制创建新会话
|
||||
- ScopeSnapshot: 每条消息保存 { scopeType, scopeId, parentKnowledgeBaseId }
|
||||
- Citation: 从 context.citations 前 5 个提取 (chunkId = item.id, sourceTitle, excerptText)
|
||||
- 自动标题: 首次消息截取前 40 字符
|
||||
|
||||
模型调用:
|
||||
- AiGateway.generate() / generateStream()
|
||||
- tier: 'primary' → DeepSeek deepseek-v4-pro
|
||||
- promptKey: 'rag-chat', promptVersion: 'v1'
|
||||
- 流式: SSE 逐块转发 (type: 'content' | 'thinking' | 'error' | 'done')
|
||||
- 无 Heavy Runtime 参与
|
||||
|
||||
内容安全:
|
||||
- 输入检查: this.safety?.check(content, { contentType: 'rag_input' })
|
||||
- AI 输出: 不检查 (仅输入被检查)
|
||||
|
||||
Qdrant 参与: 无。知识库范围对话的上下文完全来自 PostgreSQL KnowledgeItem 表。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 总体结论
|
||||
|
||||
**审查结论:有条件通过**
|
||||
|
||||
### 不满足"通过"的关键原因
|
||||
|
||||
| 门禁条件 | 满足? | 说明 |
|
||||
|---------|--------|------|
|
||||
| P0 问题为零 | **否** | 1 项 P0(见第 5 节) |
|
||||
| 没有将未实现功能标记为已完成 | 是 | 文档对未完成项标记基本准确 |
|
||||
| 没有错误描述项目职责 | 是 | 项目角色分配正确 |
|
||||
| 没有错误描述数据流向 | 是 | 数据流描述与代码一致 |
|
||||
| 没有把 RAG 作为原文件阅读前置条件 | 是 | 文档正确指出 RAG 不阻塞阅读 |
|
||||
| 没有把 Heavy Runtime 默认写入基础对话链 | 是 | 文档正确指出 Heavy Runtime 不参与 |
|
||||
| 上传/解析/索引/学习提取/候选审核状态已明确区分 | 是 | 五种状态分别描述 |
|
||||
| 知识库/来源资料/知识点/文件夹/订阅关系清晰 | 是 | 关系描述基本准确 |
|
||||
| 四类对话 Scope 的实际状态清晰 | 是 | 五种 Scope 的上下文来源均正确描述 |
|
||||
| 所有暂未确认项均已明确标记 | 是 | 7 项暂未确认均已列出 |
|
||||
|
||||
---
|
||||
|
||||
## 5. P0 严重问题
|
||||
|
||||
### P0-1:文档 05 声称知识库对话"不通过 Qdrant 向量搜索"——实际确认正确,但资料范围的 Qdrant 语义检索被标注为"暂未确认",而代码中明确未启用
|
||||
|
||||
- **涉及文档:** 05-AI对话与知识库问答.md 第 3.3 节
|
||||
- **文档当前描述:** "如果 Python RAG Worker 已完成向量索引,可通过 Qdrant 进行语义检索补充上下文(具体是否启用 Qdrant 取决于 API 实现,当前代码中资料范围上下文的加载方式与知识库范围类似,以 KnowledgeItem 为主)"
|
||||
- **实际情况:** rag-chat.service.ts 的 `loadContextByScope` 方法中,`case 'material'` 仅查询 `prisma.knowledgeItem.findMany({ sourceRef: scopeId })`,**完全不涉及 Qdrant**。Qdrant 的 `search()` 函数虽然在 indexer.py 中已实现,但在 rag-chat.service.ts 中零引用。
|
||||
- **影响:** 文档暗示资料范围对话"可能"使用 Qdrant 语义检索,给读者造成该功能存在但不稳定的印象。实际上该功能**未被实现**——资料范围对话从不调用 Qdrant。
|
||||
- **建议修正:** 将第 3.3 节中关于 Qdrant 的描述改为明确结论:"资料范围对话的上下文**完全来自 PostgreSQL KnowledgeItem 表**,不涉及 Qdrant 向量搜索。Qdrant 语义检索已实现但**未集成到对话链路**。"
|
||||
- **修正优先级:** P0 — 涉及核心数据流向描述
|
||||
|
||||
---
|
||||
|
||||
## 6. P1 主要问题
|
||||
|
||||
### P1-1:文档 03 声称"API 验证文件类型(8 种)和大小(最大 20MB)" —— files.service.ts 中未发现验证
|
||||
|
||||
- **涉及文档:** 03-资料上传与处理.md 第 5 节"主 API"
|
||||
- **文档描述:** "验证文件类型(PDF/TXT/Markdown/CSV/XLSX/DOCX/PNG/JPEG/WebP)和大小(最大 20MB)"
|
||||
- **实际情况:** files.service.ts 的 `requestUploadUrl()` 方法仅执行内容安全检查(文件名敏感词),未进行文件类型白名单校验或大小检查。类型/大小校验可能在 Controller 层的 DTO 或 Guard 中进行。
|
||||
- **建议修正:** 若校验确实存在(需进一步确认 DTO/Guard),补充具体位置;若不存在,修正为"暂未确认"或标注实际校验范围。
|
||||
- **修正优先级:** P1
|
||||
|
||||
### P1-2:文档 03 声称"清理"步骤在管线中执行——实际为空操作
|
||||
|
||||
- **涉及文档:** 03-资料上传与处理.md 第 3 节用户主流程
|
||||
- **文档描述:** 流程中包含"清洗"步骤
|
||||
- **实际情况:** import_pipeline.py 第 63 行 `await update_job_status(job_id, "CLEANING", ...)` 仅设置状态和进度百分比,**无任何实际文本清洗逻辑**。注释为 `# 3. 清洗` 但之后立即进入分块阶段。
|
||||
- **建议修正:** 在管线描述中标注"清洗步骤当前为占位(仅更新状态,无实际逻辑)"。
|
||||
- **修正优先级:** P1
|
||||
|
||||
### P1-3:文档 04 声称"文件夹创建时间步创建 folder 类型的 KnowledgeItem"——但更新文件夹名称时 KnowledgeItem 标题不更新
|
||||
|
||||
- **涉及文档:** 04-知识库与知识点管理.md 第 4.7 节
|
||||
- **文档描述:** 文件夹操作包括重命名
|
||||
- **实际情况:** `createFolder()` 同步创建 folder 类型的 KnowledgeItem(标题 = 文件夹名称),且 `deleteFolder()` 也同步删除 KnowledgeItem。但 `updateFolder()` 仅更新 KnowledgeFolder 记录,**不同步更新对应的 KnowledgeItem 标题**,导致重命名后文件夹和对应 KnowledgeItem 的标题不一致。
|
||||
- **建议修正:** 在文档中标注"重命名文件夹时,对应的 folder 类型 KnowledgeItem 标题不会同步更新"。
|
||||
- **修正优先级:** P1
|
||||
|
||||
### P1-4:文档 04 缺失对文件夹创建数量限制的描述
|
||||
|
||||
- **涉及文档:** 04-知识库与知识点管理.md
|
||||
- **遗漏:** 代码中未发现文件夹创建数量的上限限制,也未发现每 KB 的文件夹数量限制。
|
||||
- **建议:** 标注为"文件夹创建数量无明确限制"。
|
||||
- **修正优先级:** P1
|
||||
|
||||
---
|
||||
|
||||
## 7. P2 一般问题
|
||||
|
||||
### P2-1:文档 03 中"RAG 解析失败"一节描述 PDF OCR 为"回退"——与实际代码顺序相反
|
||||
|
||||
- **文档描述:** "PDF 通过 PyMuPDF + OCR 回退"
|
||||
- **实际代码 (parser.py):** PDF 先检查 `pdf_needs_ocr()` (<50 字符/页),若需要 OCR 则先用 PyMuPDF 提取文本,若结果 <100 字符才用 SiliconFlow OCR。顺序是:PyMuPDF 文本提取 → 不够则 OCR,而非"OCR 回退"。
|
||||
- **建议修正:** 改为"PDF 优先文本提取,不足时 OCR 补充"。
|
||||
- **修正优先级:** P2
|
||||
|
||||
### P2-2:文档 03 声称 Admin "RAG 调试"为"已完成"——实际为基础实现
|
||||
|
||||
- **涉及文档:** 03-资料上传与处理.md 第 11 节完成状态表
|
||||
- **文档状态:** "Admin RAG 调试 | 已完成 | 向量搜索测试"
|
||||
- **实际 Admin 代码:** KnowledgeOps.tsx 的 rag-debug Tab 仅有一个搜索输入框和按钮,结果通过 `message.info()` toast 展示,无结构化表格。页面注释:"完整 RAG 管道在 M3 阶段完善"。
|
||||
- **建议修正:** 状态从"已完成"改为"部分完成",备注"基础 UI 可用,结果展示为 toast 而非结构化表格"。
|
||||
- **修正优先级:** P2
|
||||
|
||||
### P2-3:文档 05 中 Qdrant 和 Python RAG Worker 的角色描述在两个文档中略有差异
|
||||
|
||||
- **文档 03 描述:** Python RAG Worker 是"主链路参与者"
|
||||
- **文档 05 描述:** Python RAG Worker 是"上游支撑(间接参与)"
|
||||
- **分析:** 从单个文档看均正确——文档 03 中 Worker 确为主链路(上传处理必须经过它),文档 05 中 Worker 为支撑(对话不依赖它)。但读者跨文档阅读时可能困惑。
|
||||
- **建议:** 在文档 06 项目矩阵中已正确区分两场景的角色。无需修改正文,但建议在 05 文档中增加一句"Worker 在对话链路中的角色与在上传链路中不同"。
|
||||
- **修正优先级:** P2
|
||||
|
||||
### P2-4:文档 04 中"API 知识库数量限制"的实际值是硬编码的
|
||||
|
||||
- **文档描述:** "每用户最多 20 个"
|
||||
- **代码验证:** `MAX_KNOWLEDGE_BASE_COUNT` 从 constants 文件导入,其值未在当前打开的代码中显示,但文档声称 20 与 iOS 早期审查发现一致。
|
||||
- **建议:** 准确。无需修改。
|
||||
- **修正优先级:** 无需修正
|
||||
|
||||
---
|
||||
|
||||
## 8. 遗漏项
|
||||
|
||||
### 8.1 遗漏入口
|
||||
|
||||
无重大遗漏。文档 03 的 C 端入口表覆盖了 iOS 所有上传入口。
|
||||
|
||||
### 8.2 遗漏功能
|
||||
|
||||
| 遗漏项 | 应出现在 | 说明 |
|
||||
|--------|---------|------|
|
||||
| KnowledgeSourceService.triggerParse() | 03 文档第 8 节"系统自动修改"或第 9 节"修改入口" | 该端点支持管理员触发重新解析,文档在 Admin 操作中提到了"触发重新解析"但未描述其具体实现(创建新 DocumentImport 并入队) |
|
||||
| ChatSession.knowledgeItemIds 字段 | 05 文档第 7.1 节 | Prisma 中 ChatSession 有 knowledgeItemIds Json? 字段(默认 []),但 rag-chat.service.ts 中使用 knowledgeItemIds 的实际行为未在文档中描述 |
|
||||
| Folder scope 对话 | 05 文档第 3 节 | 代码中明确支持 scopeType='folder',但文档仅提了 4 种 scope(global/knowledge_base/material/knowledge_item),遗漏了 folder |
|
||||
|
||||
### 8.3 遗漏业务对象
|
||||
|
||||
| 遗漏对象 | 说明 |
|
||||
|---------|------|
|
||||
| SourceReference | Prisma 中定义的 SourceReference 模型(关联 KnowledgeSource/KnowledgeChunk,追踪 AI 产物引用来源),Admin 中有引用追踪功能,但文档 03 第 7 节数据对象清单中遗漏 |
|
||||
|
||||
### 8.4 遗漏异常恢复
|
||||
|
||||
| 遗漏场景 | 应出现在 | 说明 |
|
||||
|---------|---------|------|
|
||||
| Worker 心跳超时后任务回收的具体机制 | 03 文档第 10.5 节 | 文档提到"心跳超过 5 分钟的 CLAIMED 任务被重置为 QUEUED",但未描述哪个组件执行此回收(API 定时任务?Worker 自身?) |
|
||||
|
||||
---
|
||||
|
||||
## 9. 错误项
|
||||
|
||||
### 9.1 文档 03 第 10.6 节"RAG 解析失败"描述
|
||||
|
||||
- **文档描述:** "Worker 处理:解析阶段失败 → 任务标记 FAILED"
|
||||
- **实际代码:** import_pipeline.py 中异常捕获后调用 `update_job_status(job_id, "FAILED_RETRYABLE", ...)`,不是 "FAILED"(无后缀)。状态字符串的差异可能影响重试逻辑。
|
||||
- **建议修正:** 将文档中的 "FAILED" 改为 "FAILED_RETRYABLE",或统一描述为"失败(可重试)"。
|
||||
|
||||
### 9.2 文档 05 第 3.4 节"知识点范围"描述
|
||||
|
||||
- **文档描述:** 关联页面中有"知识点详情页 → 工具栏菜单(如有)"
|
||||
- **实际代码:** KnowledgeDetailPage 的工具栏菜单在 `vm.detectedType` 存在且 previewMode 为 nativeReader 或 platformPreview 时才显示,且菜单中仅有"笔记"和"预览"选项,**未发现直接跳转到 AI 对话页的入口**。知识点范围的 AI 对话入口在 iOS 端可能不存在。
|
||||
- **建议修正:** 将"知识点详情页"从 C 端入口表中移除,或将 iOS 入口标记为"暂未确认"。
|
||||
|
||||
---
|
||||
|
||||
## 10. 跨文档冲突
|
||||
|
||||
### 冲突 1:导入任务状态命名
|
||||
|
||||
| 文档 | 状态描述 | 实际代码 |
|
||||
|------|---------|---------|
|
||||
| 03 第 4.2 节 | 文本解析状态 "pending → processing → complete/failed" | parseStatus 的可能值为 "pending"(默认),但 Worker 不更新 parseStatus,仅更新 job status 为 "PARSING" |
|
||||
| 03 第 4.3 节 | 向量索引状态 "pending → processing → complete/failed" | 同样,indexStatus 为 KnowledgeSource 字段,默认 "pending",Worker 不直接更新它 |
|
||||
|
||||
**分析:** 文档描述的状态流转(pending → processing → complete/failed)是设计意图,但 Python RAG Worker 代码中只通过 `update_job_status()` 更新 Redis 状态,KnowledgeSource 的三个状态字段(parseStatus/indexStatus/learningStatus)的更新逻辑在 API 内部的 `/internal/rag/jobs/{id}/status` 处理中——该端点代码未在本轮审查中阅读。
|
||||
|
||||
**建议:** 标注为"暂未确认 — KnowledgeSource 状态字段的更新逻辑在 API 内部端点中,需进一步检查 `/internal/rag/jobs/{id}/status` 的处理代码"。
|
||||
|
||||
### 冲突 2:Admin 角色描述
|
||||
|
||||
| 文档 | 描述 |
|
||||
|------|------|
|
||||
| 03 第 5 节 | Admin 标注为"运维与可观测" |
|
||||
| 05 第 5 节 | Admin 标注为"运维与可观测" |
|
||||
| 06 项目矩阵 | Admin 全部标注为"运维可观测" |
|
||||
|
||||
**分析:** 一致,无冲突。
|
||||
|
||||
### 冲突 3:无其他关键冲突
|
||||
|
||||
经逐项比对,03/04/05/06 四份文档之间无其他关键冲突。同一项目职责在不同文档中的描述基本一致,同一业务对象名称一致,同一能力的完成状态标记一致。
|
||||
|
||||
---
|
||||
|
||||
## 11. 暂未确认项
|
||||
|
||||
| 序号 | 内容 | 原因 | 后续需检查 |
|
||||
|------|------|------|-----------|
|
||||
| U01 | API 文件类型/大小校验的具体位置 | files.service.ts 中未发现,可能在 DTO/Guard/Pipe 层 | files.controller.ts 和 DTO 定义 |
|
||||
| U02 | KnowledgeSource 三个状态字段的实际更新逻辑 | Python RAG Worker 通过 `/internal/rag/jobs/{id}/status` 更新,但该端点的处理代码未阅读 | API 内部 RAG job status 处理端点 |
|
||||
| U03 | 导入任务自动重试(最多 3 次)的实际实现 | 文档声称 API 自动重试,但 Worker 仅标记 FAILED_RETRYABLE,重试调度逻辑的位置未确认 | API 的 job 重试调度逻辑 |
|
||||
| U04 | 孤儿文件自动清理 (file-cleanup) 的实际执行策略 | file-cleanup.processor.ts 文件存在,但未阅读 | file-cleanup.processor.ts 的具体实现 |
|
||||
| U05 | 处理中删除源时 Worker 是否检查软删除标志 | 文档标注为"暂未确认" | Python RAG Worker 在处理前是否查询 source 的 deletedAt |
|
||||
| U06 | 用户自定义 API Key 在对话中的实际使用 | 文档 05 声称支持用户自定义 DeepSeek Key,AiGateway 代码未阅读 | AiGateway 的 credential 选择逻辑 |
|
||||
| U07 | 流式响应中断时已生成部分内容的保存行为 | rag-chat.service.ts 的 sendMessageStream 在 fullContent 非空时才保存,中断时机影响是否保存 | 需实际测试 |
|
||||
|
||||
---
|
||||
|
||||
## 12. 完成度调整建议
|
||||
|
||||
| 业务能力或子能力 | 文档当前状态 | 审查建议状态 | 调整原因 |
|
||||
|----------------|------------|------------|---------|
|
||||
| 资料范围 Qdrant 语义检索 | 暂未确认 (05) | 未完成 | rag-chat.service.ts 完全不调用 Qdrant |
|
||||
| Admin RAG 调试 | 已完成 (03) | 部分完成 | UI 为基础实现,结果显示为 toast,代码注释"完整 RAG 管道在 M3 阶段完善" |
|
||||
| 文本清洗步骤 | 已完成 (03 隐含) | 占位实现 | import_pipeline.py 中 CLEANING 状态后无实际逻辑 |
|
||||
| 文件夹 Scope 对话 | 未提及 (05) | 已完成 | rag-chat.service.ts 中 folder case 已完整实现 |
|
||||
| 知识点范围对话 iOS 入口 | 暂未确认 (05) | 未完成 | iOS KnowledgeDetailPage 工具栏未发现 AI 对话入口 |
|
||||
| API 文件类型校验 | 已完成 (03) | 暂未确认 | files.service.ts 中未发现校验逻辑 |
|
||||
| SourceReference 数据对象 | 遗漏 (03 第 7 节) | 已存在 | Prisma 中已定义,Admin 中有引用追踪功能 |
|
||||
| Python RAG Worker 在对话中的角色 | 间接参与 (05) | 准确 | 不直接参与对话流程 |
|
||||
|
||||
---
|
||||
|
||||
## 13. 文档修正清单
|
||||
|
||||
### 03-资料上传与处理.md
|
||||
|
||||
| 章节 | 当前内容 | 修正方向 |
|
||||
|------|---------|---------|
|
||||
| 第 3 节流程 | "清洗"步骤 | 标注"清洗步骤当前为占位(无实际逻辑)" |
|
||||
| 第 5 节主 API | "验证文件类型(8 种)和大小(最大 20MB)" | 若未找到校验位置,改为暂未确认 |
|
||||
| 第 7.4 节 | 数据对象清单遗漏 SourceReference | 补充 SourceReference 对象描述 |
|
||||
| 第 10.6 节 | "任务标记 FAILED" | 改为 "FAILED_RETRYABLE" |
|
||||
| 第 10.2 节 | "PyMuPDF + OCR 回退" | 改为 "PyMuPDF 文本提取优先,不足时 OCR 补充" |
|
||||
| 第 11 节状态表 | Admin RAG 调试 = 已完成 | 改为"部分完成",备注基础 UI |
|
||||
| 第 11 节 | 孤儿文件清理 = 暂未确认 | 保持,但补充 file-cleanup.processor.ts 引用 |
|
||||
| 第 11 节 | 处理中删除源 = 暂未确认 | 保持 |
|
||||
|
||||
### 04-知识库与知识点管理.md
|
||||
|
||||
| 章节 | 当前内容 | 修正方向 |
|
||||
|------|---------|---------|
|
||||
| 第 4.7 节 | 文件夹重命名 | 补充"重命名文件夹时,对应 folder 类型 KnowledgeItem 标题不同步更新" |
|
||||
| 第 3 节业务对象关系 | Folder → 同步创建 folder 类型 KnowledgeItem | 补充 updateFolder 不同步的说明 |
|
||||
| 第 10 节状态表 | 来源资料删除权限 = 暂未确认 | 确认为"存在缺陷——无所有权检查" |
|
||||
|
||||
### 05-AI对话与知识库问答.md
|
||||
|
||||
| 章节 | 当前内容 | 修正方向 |
|
||||
|------|---------|---------|
|
||||
| 第 2 节 C 端入口 | 知识点详情页 → 工具栏菜单 | 移除或标记为暂未确认(iOS 端未发现入口) |
|
||||
| 第 3 节对话范围 | 仅列 4 种 scope | 补充 folder scope(代码已实现) |
|
||||
| 第 3.3 节资料范围 | Qdrant 语义检索"可能"使用 | 明确改为"不使用 Qdrant——上下文完全来自 PostgreSQL KnowledgeItem 表" |
|
||||
| 第 10 节状态表 | Qdrant 语义检索 = 暂未确认 | 改为"未完成——Qdrant 向量搜索未集成到对话链路" |
|
||||
|
||||
### 06-内容与对话项目矩阵.md
|
||||
|
||||
| 章节 | 当前内容 | 修正方向 |
|
||||
|------|---------|---------|
|
||||
| 三、Qdrant 行"资料范围语义检索时使用" | "资料范围语义检索时使用" | 与文档 05 保持一致——标注为"未启用" |
|
||||
|
||||
---
|
||||
|
||||
## 14. 审查门禁结果
|
||||
|
||||
| 门禁条件 | 结果 | 说明 |
|
||||
|---------|------|------|
|
||||
| 三条业务链路已独立还原 | 满足 | 逐链路从代码验证 |
|
||||
| 所有相关仓库已检查 | 满足 | iOS、API、Python RAG Worker、Admin、Prisma Schema、COS、Qdrant 均已检查 |
|
||||
| 页面和调用入口已检查 | 满足 | iOS 全部入口 + API 全部端点 |
|
||||
| API 和异步任务已检查 | 满足 | REST API + Queue + Python Worker 管线 |
|
||||
| 数据对象关系已检查 | 满足 | Prisma Schema 全部 120+ 模型关系 |
|
||||
| 权限与删除影响已检查 | 满足 | 软删除级联行为、所有权校验 |
|
||||
| 异常与恢复已检查 | 满足 | 上传失败、Worker 失败、RAG 未完成、模型调用失败等 |
|
||||
| Admin 查询和操作入口已检查 | 满足 | 40+ Admin 页面全部盘点 |
|
||||
| 双向覆盖检查已完成 | 满足 | 文档→代码 + 代码→文档 |
|
||||
| 跨文档一致性检查已完成 | 满足 | 4 份文档逐项比对 |
|
||||
| P0 问题为零 | **不满足** | 1 项 P0:文档 05 资料范围 Qdrant 语义检索状态描述不准确 |
|
||||
| 未确认项已明确记录 | 满足 | 7 项暂未确认均已列出 |
|
||||
|
||||
---
|
||||
|
||||
## 15. 是否可以进入下一阶段
|
||||
|
||||
### 结论:可以进入下一阶段(AI 学习分析、主动回忆、题目与复习能力整理),但建议先完成 1 项 P0 修正。
|
||||
|
||||
**P0 阻塞项:** 文档 05 关于资料范围 Qdrant 语义检索的描述需修正——代码中 rag-chat.service.ts 完全不调用 Qdrant,文档暗示"可能启用"会造成误解。
|
||||
|
||||
**P1 问题(4 项)不阻塞下一阶段:**
|
||||
1. API 文件类型/大小校验位置待确认
|
||||
2. 文本清洗步骤为空操作
|
||||
3. 文件夹重命名不同步 KnowledgeItem 标题
|
||||
4. 文件夹创建数量无限制
|
||||
|
||||
**P2 问题(4 项)不阻塞:** 命名修正和细节补充可在后续阶段一并处理。
|
||||
|
||||
**当前文档的整体可靠性评价:**
|
||||
- 三条业务链路的主流程描述与代码一致
|
||||
- 项目职责分配正确(Rust Document Runtime 和 Heavy Runtime 的角色描述准确)
|
||||
- 数据对象关系基本正确
|
||||
- 完成状态标记在核心链路上准确,边缘功能有少量偏差
|
||||
- 跨文档一致性良好,无关键矛盾
|
||||
Loading…
x
Reference in New Issue
Block a user