538 lines
26 KiB
Markdown
538 lines
26 KiB
Markdown
# 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** |
|