# 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 重取 | 已完成 | 检测 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** |