From dc4ad424e25ea2cf9159af742858e936bca1f8e5 Mon Sep 17 00:00:00 2001 From: WangDL Date: Fri, 15 May 2026 17:30:27 +0800 Subject: [PATCH] switch API to HTTPS api.longde.cloud, remove NSAllowsArbitraryLoads, migrate docs to startup-plan Co-Authored-By: Claude Opus 4.7 --- .../AIStudyApp/Core/Network/APIConfig.swift | 2 +- AIStudyApp/Info.plist | 5 - AIStudyApp/docs/AI对话.md | 668 ----------- AIStudyApp/docs/architecture.md | 139 --- AIStudyApp/docs/gap-analysis-1.md | 157 --- AIStudyApp/docs/gap-analysis-2.md | 267 ----- AIStudyApp/docs/pages.md | 235 ---- AIStudyApp/docs/plan-ios-requirements.md | 339 ------ AIStudyApp/docs/样式规范.md | 550 --------- AIStudyApp/docs/缺失项与待补全方向.md | 1042 ----------------- 10 files changed, 1 insertion(+), 3403 deletions(-) delete mode 100644 AIStudyApp/docs/AI对话.md delete mode 100644 AIStudyApp/docs/architecture.md delete mode 100644 AIStudyApp/docs/gap-analysis-1.md delete mode 100644 AIStudyApp/docs/gap-analysis-2.md delete mode 100644 AIStudyApp/docs/pages.md delete mode 100644 AIStudyApp/docs/plan-ios-requirements.md delete mode 100644 AIStudyApp/docs/样式规范.md delete mode 100644 AIStudyApp/docs/缺失项与待补全方向.md diff --git a/AIStudyApp/AIStudyApp/Core/Network/APIConfig.swift b/AIStudyApp/AIStudyApp/Core/Network/APIConfig.swift index b848971..176a98c 100644 --- a/AIStudyApp/AIStudyApp/Core/Network/APIConfig.swift +++ b/AIStudyApp/AIStudyApp/Core/Network/APIConfig.swift @@ -5,7 +5,7 @@ import Foundation enum APIConfig { - static let baseURL = "http://81.70.187.179:3001" + static let baseURL = "https://api.longde.cloud" static let timeout: TimeInterval = 30 diff --git a/AIStudyApp/Info.plist b/AIStudyApp/Info.plist index 7b6946c..e5d22d0 100644 --- a/AIStudyApp/Info.plist +++ b/AIStudyApp/Info.plist @@ -18,11 +18,6 @@ $(MARKETING_VERSION) CFBundleVersion $(CURRENT_PROJECT_VERSION) - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/AIStudyApp/docs/AI对话.md b/AIStudyApp/docs/AI对话.md deleted file mode 100644 index a59808e..0000000 --- a/AIStudyApp/docs/AI对话.md +++ /dev/null @@ -1,668 +0,0 @@ -# 缺失项与待补全方向 - -> 基于 v0.1 创业计划文档与当前 iOS 代码对比分析 -> 整理时间:2026-05-10 - -本文档系统性列出知习 iOS App 当前在架构、页面、功能、设计等方面的缺失项,并给出优先级建议。 - ---- - -## 一、架构层缺失 - -### 1.1 MVVM 分层 - -**现状**:全部代码写在 SwiftUI View 中,无任何 ViewModel/ObservableObject/@Published。grep 搜索 ViewModel、ObservableObject、@Published 均为零结果。 - -**缺失**: -- 无 ViewModel 层,业务逻辑、状态管理、数据转换全部堆在 View 里 -- 无 Model 层,数据结构通过 View 内的局部 struct 或硬编码数据隐式定义 -- 代码不可测试,无法单独验证业务逻辑 - -**计划要求**(`官网与技术基础.md` 第 5.3 节): -``` -AIStudyApp/ -├── Features/ -│ ├── Onboarding/ -│ │ ├── Views/ ← 当前有,但无 ViewModel/Model 子目录 -│ │ ├── ViewModels/ ← 缺失 -│ │ └── Models/ ← 缺失 -``` - -### 1.2 Service 层 - -**现状**:无任何 Service 类,AI 分析、学习记录、用户管理等概念没有对应的服务抽象。 - -**缺失**: -| Service | 职责 | 涉及的计划数据实体 | -|---------|------|-------------------| -| AuthService | Apple 登录、Token 管理、会话维护 | User | -| LearningService | 学习记录 CRUD、进度追踪 | LearningSession | -| AIService | AI 分析请求代理、结果解析 | AIAnalysis | -| ReviewService | 复习任务生成、调度 | ReviewTask | -| KnowledgeService | 知识库/路径/课程查询 | KnowledgeBase, LearningPath, Lesson | -| FeedbackService | 用户反馈提交 | Feedback | - -### 1.3 Repository 层 - -**现状**:零数据持久化,所有"数据"均为 View 中硬编码的 mock。 - -**缺失**: -- 无数据访问抽象(未来可能切换 CoreData → API,需要 Repository 隔离) -- 无本地缓存层 -- 无网络数据源层 - -### 1.4 网络层 - -**现状**:无任何网络请求代码,无 APIClient,无 URLSession 调用。 - -**缺失**: -- APIClient(封装 URLSession,注入 baseURL、header、token) -- APIEndpoint(枚举化 API 路径,统一请求构建) -- APIError(统一错误模型和处理) -- 请求/响应拦截器(日志、token 刷新) -- Mock 层(本地开发和 UI 预览用) - -### 1.5 依赖注入 - -**现状**:无任何 DI 模式,Service 和 ViewModel 尚未创建,暂时不存在注入问题。但需要在架构搭建时建立模式。 - -**建议**:初期使用构造函数注入 + `@EnvironmentObject`,避免引入第三方 DI 框架。 - ---- - -## 二、核心能力缺失 - -### 2.1 Sign in with Apple - -**现状**:`LoginPage` 有 UI(手机号/邮箱/微信/Apple 入口),但 `AIStudyAppApp` 仅用 `@AppStorage("hasCompletedOnboarding")` 控制是否进入主界面,无实际认证。 - -**计划要求**:第一版登录方式仅为 Sign in with Apple(`Demo与MVP.md` 第 5.2 节)。 - -**需实现**: -- ASAuthorizationController 集成 -- 获取 appleUserId、email、displayName -- 后端验证 identityToken -- Token 本地安全存储(Keychain) -- 登录状态管理 - -### 2.2 后端 API 对接 - -**现状**:所有页面为静态 UI,无任何网络请求。 - -**计划定义的 P0 API**: -- `POST /ai/analyze-learning-input` — AI 分析用户学习输入 -- `POST /ai/chat` — AI 对话 -- 用户/知识库/学习记录/反馈 CRUD - -### 2.3 真实 AI 集成 - -**现状**:AI 相关页面全为静态文本。 - -**需对接**: -- 后端 AI Provider 抽象层(MiniMax/DeepSeek/OpenAI 等) -- 结构化 JSON 输出解析 -- AI 分析结果展示(掌握度评分、优缺点、建议) -- AI 对话流式响应 - -### 2.4 本地数据持久化 - -**现状**:零持久化实现。 - -**需实现**: -- UserDefaults / @AppStorage(简单偏好) -- Keychain(Token、敏感信息) -- 后续可考虑 CoreData 或 SwiftData(学习记录离线缓存) - -### 2.5 多语言本地化 - -**现状**:所有文案硬编码在 View 中,无 Localizable.xcstrings 文件。 - -**计划要求**(`Demo与MVP.md` 第 6 节): -- 默认简体中文 -- 预留英文 -- App UI 文案使用本地化资源 - -**需实现**: -- 创建 `Localizable.xcstrings` -- 将所有硬编码文案迁移为 `LocalizedStringKey` -- 支持语言切换 - -### 2.6 错误/加载/空状态处理 - -**现状**:无任何错误处理、加载态、空状态 UI。 - -**至少需要**: -- 网络请求 loading 指示器 -- 网络错误提示和重试按钮 -- AI 分析中的等待状态 -- 列表空状态(如知识库为空时的引导) -- 登录失败错误提示 - ---- - -## 三、页面层面差距 - -### 3.1 与计划页面对比 - -| 计划页面 | 计划优先级 | 当前状态 | 说明 | -|----------|-----------|---------|------| -| 启动页/欢迎页 | P1 | ✅ 已实现 | SplashPage + WelcomePage | -| 登录页 | P0 | ⚠️ 过度实现 | UI 包含计划不做的手机号/邮箱/微信登录 | -| 语言与偏好页 | P1 | ❌ 未实现 | 无页面 | -| 学习方向选择页 | P0 | ⚠️ 部分实现 | GoalSetupPage 有目标选择,但非学习方向选择 | -| 学习路径页 | P0 | ✅ 已实现 | LibraryDetailPage | -| 今日学习任务页 | P0 | ✅ 已实现 | StudyHomeView | -| 内容阅读页 | P0 | ✅ 已实现 | KnowledgeDetailPage | -| 主动回忆/笔记输入页 | P0 | ✅ 已实现 | DailyThinkingPage + RecallTestPage | -| AI 分析结果页 | P0 | ✅ 已实现 | AIFeedbackPage | -| AI 对话页 | P0 | ✅ 已实现 | AIChatPage | -| 复习计划页 | P0 | ❌ 未独立 | 仅在 StudyHomeView 任务列表中混合出现 | -| 学习进度页 | P1 | ✅ 已实现 | AnalysisHomeView | -| 设置页 | P1 | ⚠️ 部分实现 | ProfileView 有设置菜单,但功能入口为空 | -| 反馈页 | P1 | ❌ 未实现 | 无反馈收集入口 | - -### 3.2 复习计划页(P0 缺失) - -**计划描述**:系统生成复习任务,用户查看待复习内容,按推荐时间安排学习。 - -**当前**:复习任务混在 StudyHomeView 的任务列表里(如"高数 - 间隔复习 8 题"),缺少独立的复习计划视图。 - -**需实现**: -- 独立的 `ReviewPlanView` -- 按时间线展示待复习任务(今天、明天、本周) -- 复习项来源标注(哪个知识点的第几次复习) -- 复习完成状态追踪 - -### 3.3 反馈页(P1 缺失) - -**计划描述**:App 内反馈入口,让内测用户提交问题和建议。 - -**需实现**: -- 简洁的反馈表单(文本输入 + 分类选择) -- 提交到后端 `/feedback` 接口 -- 确认提交状态页 - -### 3.4 等待名单入口 - -**计划**:官网 `/waitlist` 页面收集用户,App 内也需要引导用户加入等待名单/申请内测。 - -**需考虑**:是否在 App 内嵌等待名单入口(如 Welcome 页或设置页)。 - ---- - -## 四、设计与交互差距 - -### 4.1 Tab 结构调整 - -**计划设计**:4 个 Tab — 学习 | 知识库 | AI助手 | 我的 - -**当前实现**:5 个 Tab — AI | 知识库 | 学习 | 分析 | 我的 - -**差异分析**: -- 当前把"学习"和"分析"拆成了两个独立 Tab -- 计划把"AI助手"独立为一个 Tab,当前 AI 已是独立 Tab -- "分析"在计划中属于"学习"Tab 下的子页面,不需要顶层 Tab - -**建议**(两种方案): -- **方案 A**:完全对齐计划 → 合并学习和分析为一个 Tab,保持 4 Tab -- **方案 B**:保留 5 Tab 结构 → 更新计划文档,论证"分析"独立为 Tab 的合理性(学习数据可视化、学习进度监控是独立价值) - -### 4.2 登录流程简化 - -**计划要求**:仅 Sign in with Apple,不做手机号/邮箱/微信登录。 - -**当前 UI**:包含 4 种登录方式入口。 - -**建议**:第一版简化为仅 Apple 登录按钮 + 跳过选项,移除手机号/邮箱/微信登录 UI。 - -### 4.3 深色模式 - -**现状**:所有页面用 `.preferredColorScheme(.dark)` 强制深色,未验证浅色模式。 - -**建议**:确认是否需要支持浅色模式。如果只做深色,在 DesignTokens 中声明 `colorScheme: .dark`。 - -### 4.4 无障碍 - -**现状**:未考虑 VoiceOver、Dynamic Type、高对比度等无障碍需求。 - -**至少需做**: -- 关键按钮添加 `.accessibilityLabel` -- 确保 Dynamic Type 下布局不破碎 -- 重点页面 VoiceOver 测试 - -### 4.5 动效 - -**计划要求**(`官网与技术基础.md` 第 6.3 节): -- P0:页面过渡、按钮反馈、加载状态、AI 分析中状态、学习完成反馈 -- P1:今日任务卡片动效、进度条更新、AI 结果分块出现 - -**当前**:仅有基础 SwiftUI 隐式动画(withAnimation),未实现任何计划中的动效。 - ---- - -## 五、数据层缺失 - -### 5.1 Model 定义 - -**现状**:所有数据通过 View 内局部变量或硬编码定义,无独立 Model 文件。 - -**计划中定义的核心实体**(`Demo与MVP.md`): - -``` -User -├── id, appleUserId, displayName, email -├── preferredLanguage, createdAt, lastLoginAt, status - -KnowledgeBase -├── id, title, description, language, targetUser -├── createdAt, updatedAt - -LearningPath -├── id, knowledgeBaseId, title, description -├── estimatedDays, order - -Lesson -├── id, pathId, title, content, objectives -├── keyPoints, recallQuestions, practicePrompt -├── order, estimatedMinutes - -LearningSession -├── id, userId, lessonId -├── startedAt, endedAt, userInput -├── aiAnalysis, masteryScore, weakPoints -├── nextSuggestion, reviewAt - -AIAnalysis -├── id, userId, sessionId -├── inputText, outputJson, masteryScore -├── weakPoints, suggestions -├── modelName, createdAt, costEstimate - -ReviewTask -├── id, userId, lessonId, sourceSessionId -├── reviewType, scheduledAt, completedAt, status - -Feedback -UserLearningProfile -``` - -**需实现**:在 `Features/*/Models/` 下创建对应的 Swift struct(需 Codable、Identifiable)。 - -### 5.2 API Contract - -**现状**:无 API 类型定义。 - -**建议**:参考计划中定义的 JSON 结构,先创建 Swift Model,再定义 API 请求/响应类型(Request/Response struct),实现前后端类型同构。 - -### 5.3 数据流规范 - -**现状**:View 直接持有 @State,无数据流管理。 - -**建议**: -- ViewModel 持有 @Published 状态 -- ViewModel 通过 Service 获取数据 -- Service 通过 Repository 访问数据源 -- View 通过 @StateObject / @ObservedObject 绑定 ViewModel - ---- - -## 六、工程化缺失 - -### 6.1 大文件拆分 - -**当前问题**: - -| 文件 | 行数 | 包含内容 | -|------|------|----------| -| `AIStudyAppApp.swift` | ~187 | 5 个完整页面 + 多个子组件 | -| `DailyThinkingPage.swift` | ~200+ | 5 个页面 + 共享组件 | -| `LibrarySubpages.swift` | ~150+ | 6 个页面 + 组件 | - -**建议**:每个页面一个文件,共享组件移到 `Shared/Components/`。 - -### 6.2 共享组件管理 - -**现状**:`ZXTabBar` 在 ContentView.swift,`ZXBackHeader` 在 DailyThinkingPage.swift,`ZXCardRow` 在 LibrarySubpages.swift,散落各处。 - -**建议**:集中到 `Shared/Components/`,建立组件目录如: -``` -Shared/Components/ -├── ZXTabBar.swift -├── ZXBackHeader.swift -├── ZXAIInputBar.swift -├── ZXScoreBox.swift -├── ZXIconBtn.swift -├── ZXCardRow.swift -├── ZXChip.swift -├── ZXQuickAction.swift -└── ZXStatBadge.swift -``` - -### 6.3 测试 - -**现状**:无任何测试代码。 - -**至少需要**: -- ViewModel 单元测试(当 ViewModel 创建后) -- Service 层单元测试(Mock Repository) -- 关键 UI 流程的 Snapshot 测试 - -### 6.4 CI/CD - -**现状**:无。 - -**建议**(后续): -- GitHub Actions / Xcode Cloud 自动构建 -- TestFlight 自动分发 - -### 6.5 崩溃监控与埋点 - -**现状**:无。 - -**建议**:接入 Firebase Crashlytics 或类似服务,至少在 TestFlight 阶段要有崩溃收集能力。 - ---- - -## 七、优先级建议 - -### P0 — 必须在接后端前完成 - -| 优先级 | 项目 | 理由 | -|--------|------|------| -| P0 | 创建 Model 层(所有数据实体) | 是 Service/ViewModel/API 的基础 | -| P0 | 创建 API Contract 类型定义 | 前后端对齐的前提 | -| P0 | 搭建 APIClient + APIEndpoint | 所有后端交互的唯一通道 | -| P0 | 实现 AuthService + Apple 登录 | 用户身份是学习记录的前提 | -| P0 | 简化登录页为纯 Apple 登录 | 对齐计划,减少不必要 UI | -| P0 | 实现复习计划独立页 | 计划标记 P0,当前缺失 | -| P0 | 拆分大文件 | 降低后续修改的认知负担 | -| P0 | 集中共享组件 | 避免组件散落导致重复开发 | -| P0 | 添加加载/错误/空状态处理 | 真机使用的基本体验保障 | - -### P1 — 与后端对接同步推进 - -| 优先级 | 项目 | 理由 | -|--------|------|------| -| P1 | 搭建 ViewModel 层(逐步迁移) | 架构分层,但不阻塞功能开发 | -| P1 | 搭建 Service 层 | 随 API 对接自然建立 | -| P1 | 实现本地化架构 | 越晚做返工越多 | -| P1 | 实现反馈页 | TestFlight 内测必须 | -| P1 | 实现 Keychain 存储 | Token 安全存储 | - -### P2 — App Store 前完成 - -| 优先级 | 项目 | 理由 | -|--------|------|------| -| P2 | Repository 层 | 当需要本地缓存 + 网络切换时再做 | -| P2 | 动效补充 | 体验优化,不阻塞功能 | -| P2 | 无障碍适配 | App Store 审核加分项 | -| P2 | 测试 | 用户量增长后需要 | -| P2 | Tab 结构调整决策 | 需要更多用户反馈来决策 | - ---- - -## 八、总结 - -当前 iOS 项目完成了 UI 层的全量搭建(21 页),但缺少"能让产品真正运转"的架构底座和数据能力。核心矛盾是: - -> UI 超前,架构滞后。页面能点,但无数据、无认证、无 AI、无服务。 - -接下来最合理的推进顺序: - -``` -1. 建 Model 层(夯实数据基础) - ↓ -2. 搭网络层 + Apple 登录(接通身份和通信) - ↓ -3. 后端 API 逐个对接(AI 分析和学习记录最先) - ↓ -4. 重构 ViewModel 层(顺带解决架构问题) - ↓ -5. 补充缺失页面(复习计划、反馈) - ↓ -6. 本地化 + 动效 + 测试(打磨) -``` - -一句话:**先把骨架搭对,再长肉。** - -对,**登录第一版只保留苹果登录**,这是最正确的决策。 - -你整理的文档里也已经明确写了:当前 `LoginPage` 虽然有手机号、邮箱、微信、Apple 入口,但第一版计划要求只做 Sign in with Apple,并且需要实现 Apple 授权、后端验证、Keychain 存 token 和登录状态管理。 -文档后面也建议把登录页简化为 **仅 Apple 登录按钮 + 可选跳过入口**,移除手机号、邮箱、微信登录 UI。 - ---- - -# 登录页第一版最终方案 - -## 正式入口只保留 - -```text -Sign in with Apple -``` - -## 删除这些入口 - -```text -手机号登录 -邮箱登录 -微信登录 -验证码登录 -第三方微信登录 -``` - -## “跳过”要不要保留? - -我建议: - -```text -开发环境可以保留 -正式环境不要明显展示 -``` - -也就是说: - -```swift -#if DEBUG -Button("跳过,进入演示模式") { ... } -#endif -``` - -不要把“跳过”作为正式登录入口,不然后面学习记录、知识库、AI 分析都会涉及匿名用户迁移,很麻烦。 - ---- - -# 登录流程应该这样设计 - -```text -打开 App -↓ -AppSession 检查 Keychain 里有没有 refreshToken -↓ -如果有 token:调用 /auth/refresh 或 /users/me -↓ -成功:进入主界面 -↓ -失败:进入登录页 -↓ -用户点击 Sign in with Apple -↓ -iOS 获取 identityToken / authorizationCode / userIdentifier -↓ -POST /api/auth/apple -↓ -后端返回 accessToken / refreshToken / user -↓ -iOS 把 token 存到 Keychain -↓ -AppSession 更新 currentUser -↓ -判断 onboardingCompleted -↓ -未完成:进入首次引导 / 学习目标设置 -已完成:进入主界面 -``` - ---- - -# iOS 需要实现的文件 - -登录相关最少这些: - -```text -Features/Auth/Views/LoginView.swift -Features/Auth/ViewModels/LoginViewModel.swift - -Core/Services/AuthService.swift -Core/Services/AuthServiceProtocol.swift - -Core/Storage/KeychainStore.swift -Core/Storage/TokenStore.swift - -App/AppSession.swift - -Core/Models/AuthModels.swift -Core/Models/User.swift -``` - ---- - -# 接口请求结构 - -iOS 登录成功后给后端: - -```swift -struct AppleLoginRequest: Encodable { - let identityToken: String - let authorizationCode: String? - let userIdentifier: String - let fullName: AppleFullName? - let email: String? -} - -struct AppleFullName: Encodable { - let givenName: String? - let familyName: String? -} -``` - -后端返回: - -```swift -struct AuthResponse: Decodable { - let accessToken: String - let refreshToken: String - let expiresIn: Int - let user: User -} -``` - -Token 存储: - -```text -accessToken → Keychain -refreshToken → Keychain -不要存 UserDefaults -``` - ---- - -# 给 Trae 的修改指令 - -你可以直接发这段: - -```text -现在调整知习 iOS App 的登录方案。 - -第一版登录方式只保留 Sign in with Apple。 - -请删除登录页中的: -- 手机号登录 -- 邮箱登录 -- 微信登录 -- 其他第三方登录入口 - -正式 UI 只保留: -- Sign in with Apple 按钮 -- 简短产品说明 -- 隐私政策 / 用户协议入口 - -开发环境可以保留一个 DEBUG-only 的“跳过,进入演示模式”按钮,但不能出现在 Release 版本。 - -请实现以下架构: - -1. LoginView -- 只展示 Apple 登录按钮 -- 点击后调用 LoginViewModel.loginWithApple() -- 支持 loading / error 状态 -- 登录失败时展示错误提示 - -2. LoginViewModel -- @MainActor -- ObservableObject -- @Published isLoading -- @Published errorMessage -- 调用 AuthService 处理 Apple 登录 - -3. AuthService -- 集成 ASAuthorizationController -- 获取 identityToken -- 获取 authorizationCode -- 获取 userIdentifier -- 获取 email / fullName,如果 Apple 返回 -- 调用后端 POST /api/auth/apple -- 接收 accessToken / refreshToken / user - -4. TokenStore / KeychainStore -- accessToken 存 Keychain -- refreshToken 存 Keychain -- 支持 save / load / clear - -5. AppSession -- 管理全局登录状态 -- currentUser -- isAuthenticated -- bootstrap() -- loginWithApple() -- logout() -- refreshSession() - -6. App 启动逻辑 -- 启动时先检查 Keychain 中是否存在 refreshToken -- 如果存在,调用后端 refresh 或 /users/me -- 成功后进入主界面 -- 失败则清空 token 并进入登录页 - -7. 登录成功后的跳转 -- 如果 user.onboardingCompleted == false,进入首次使用引导 / 学习目标设置 -- 如果 user.onboardingCompleted == true,进入 MainTabView - -8. 注意 -- 不要再使用 @AppStorage("hasCompletedOnboarding") 单独决定是否进入主界面 -- 登录状态必须由 AppSession + Keychain token 决定 -- 不要把 token 存到 UserDefaults -- 不要在 View 里直接写网络请求 -- 不要在 View 里直接处理 Apple 登录细节 -- 不要改变其他主页面 UI -``` - ---- - -# 登录页内容建议 - -页面可以非常简单: - -```text -知习 - -更懂你,更会学。 - -用 AI 把知识库、主动回忆和间隔复习连接起来, -从“看过”走向“真正学会”。 - -[ Sign in with Apple ] - -登录即代表你同意《用户服务协议》和《隐私政策》 -``` - -就够了。 -第一版登录越简单越好,别再做多登录方式。 diff --git a/AIStudyApp/docs/architecture.md b/AIStudyApp/docs/architecture.md deleted file mode 100644 index 653184c..0000000 --- a/AIStudyApp/docs/architecture.md +++ /dev/null @@ -1,139 +0,0 @@ -# 知习 ZhiXi — 项目架构 - -> 更新时间:2026-05-10 - -## 一、项目结构 - -``` -AIStudyApp/ -├── AIStudyAppApp.swift # 应用入口 + 引导流程路由 -│ ├── OnboardingFlowView # Splash → Welcome → Login → Onboarding → GoalSetup -│ ├── SplashPage # 启动页 -│ ├── WelcomePage # 欢迎页 -│ ├── LoginPage # 登录页 -│ ├── OnboardingPage # 功能引导 -│ └── GoalSetupPage # 学习目标设置 -│ -├── ContentView.swift # 5-Tab 主界面 -│ ├── ZXTabBar # 自定义底部 Tab 栏 -│ ├── ZXAIInputBar # AI 输入栏 -│ ├── ZXScoreBox # 评分组件 -│ └── ZXIconBtn # 图标按钮 -│ -├── Core/ -│ └── DesignSystem/ -│ └── DesignTokens.swift # 颜色/渐变/圆角/间距/字号/排版 -│ -├── Features/ -│ ├── AI/ -│ │ ├── AIHomeView.swift # AI 首页(Tab 1) -│ │ └── DailyThinkingPage.swift # 今日思考 + AIChat + RecallTest + WeakPoints + AIFeedback -│ │ -│ ├── Library/ -│ │ ├── LibraryHomeView.swift # 知识库首页(Tab 2) -│ │ └── LibrarySubpages.swift # Create/Detail/Add/Import/KnowledgeDetail/Edit -│ │ -│ ├── Study/ -│ │ └── StudyHomeView.swift # 学习工作台(Tab 3) -│ │ -│ ├── Analysis/ -│ │ └── AnalysisHomeView.swift # 学习分析(Tab 4) -│ │ -│ └── Profile/ -│ └── ProfileView.swift # 我的(Tab 5) -│ -└── Assets.xcassets/ # 资源文件 -``` - -## 二、导航架构 - -``` -@main AIStudyAppApp -├── hasCompletedOnboarding == false -│ └── OnboardingFlowView -│ ├── step 0: SplashPage ──(2s)──→ step 1 -│ ├── step 1: WelcomePage ──"开始使用"──→ step 2 -│ │ ──"已有账号"──→ hasCompletedOnboarding = true -│ ├── step 2: LoginPage ──"登录"──→ step 3 -│ │ ──"跳过"──→ hasCompletedOnboarding = true -│ ├── step 3: OnboardingPage ──"下一步"──→ step 4 -│ └── step 4: GoalSetupPage ──"开始学习"──→ hasCompletedOnboarding = true -│ -└── hasCompletedOnboarding == true - └── ContentView (5-Tab) - ├── Tab "AI" → NavigationStack { AIHomeView } - │ ├── → DailyThinkingPage → AIFeedbackPageView - │ ├── → RecallTestPage - │ ├── → WeakPointsPage - │ └── → AIChatPage - │ - ├── Tab "知识库" → NavigationStack { LibraryHomeView } - │ ├── → LibraryDetailPage → KnowledgeDetailPage - │ ├── → CreateLibraryPage - │ ├── → AddKnowledgePage - │ ├── → ImportPage - │ └── → EditKnowledgePage - │ - ├── Tab "学习" → NavigationStack { StudyHomeView } - ├── Tab "分析" → NavigationStack { AnalysisHomeView } - └── Tab "我的" → NavigationStack { ProfileView } -``` - -## 三、数据流(当前均为静态 Mock) - -所有页面目前使用 `@State` 管理的本地假数据,尚未接入真实后端: - -| 数据 | 当前状态 | -|------|----------| -| 用户信息 | ProfileView 中硬编码 | -| 知识库列表 | LibraryHomeView 中硬编码 4 个 | -| 学习任务 | StudyHomeView 中硬编码 5 个 | -| AI 分析结果 | 各 AI 页面静态文本 | -| 学习统计 | AnalysisHomeView 中硬编码 | -| 登录状态 | @AppStorage 布尔值控制 | - -## 四、技术栈 - -| 层 | 技术 | 备注 | -|----|------|------| -| 语言 | Swift | — | -| UI 框架 | SwiftUI | iOS 17+ | -| 架构模式 | 当前未分层(View 内聚) | 计划 MVVM + Service + Repository | -| 设计系统 | 自定义 DesignTokens | 从 React 原型 1:1 提取 | -| 构建工具 | Xcode | — | -| 目标平台 | iPhone (iOS 17+) | 未做 iPad/Mac 适配 | - -## 五、与计划架构的差异 - -计划文档(`官网与技术基础.md`)中定义的 iOS 目录结构: - -``` -计划架构 当前实现 -───────────────────────────────── ───────────────── -App/AIStudyApp.swift AIStudyAppApp.swift ✅ -App/AppConfig.swift 未实现 ❌ -App/AppRouter.swift 未实现 ❌ -Core/Network/ 未实现 ❌ -Core/Auth/ 未实现 ❌ -Core/Storage/ 未实现 ❌ -Core/Localization/ 未实现 ❌ -Core/DesignSystem/ DesignTokens.swift ✅ (部分) -Features/*/Views/ Features/*/ ✅ -Features/*/ViewModels/ 未实现 ❌ (View 内聚状态) -Features/*/Models/ 未实现 ❌ (无独立 Model) -Shared/Components/ 分散在各 View 文件中 ⚠️ -Shared/Extensions/ 仅 Color hex 扩展 ✅ -Shared/Utils/ 未实现 ❌ -Shared/Constants/ 未实现 ❌ -Resources/Localizable.xcstrings 未实现 ❌ -Resources/PreviewData/ 未实现 ❌ -``` - -## 六、待重构项 - -1. **View 文件过大**:`AIStudyAppApp.swift` 包含 5 个独立页面,应拆分到各自文件 -2. **无 ViewModel 层**:所有状态和数据逻辑写在 View 中,需要抽离 -3. **无 Model 层**:数据结构(如学习任务、知识库卡片)分散在 View 中用局部变量定义 -4. **共享组件未集中**:`ZXTabBar`、`ZXBackHeader` 等组件散落在不同文件中 -5. **无网络层**:无 API Client、无 Auth Service、无 Storage 层 -6. **无本地化**:所有文案硬编码,未使用 `LocalizedStringKey` diff --git a/AIStudyApp/docs/gap-analysis-1.md b/AIStudyApp/docs/gap-analysis-1.md deleted file mode 100644 index 32c5b98..0000000 --- a/AIStudyApp/docs/gap-analysis-1.md +++ /dev/null @@ -1,157 +0,0 @@ -# AIStudyApp 现状与缺口分析 - 第一篇:现有资源盘点 - -> 生成日期:2026-05-11 -> 后端地址:http://81.70.187.179:3001 - ---- - -## 一、项目文件结构 - -``` -AIStudyApp/ -├── AIStudyAppApp.swift # 应用入口,含 5 步 Onboarding 流程 -├── ContentView.swift # 主 Tab 框架(5 个 Tab + 自定义底部栏) -│ -├── Core/ -│ ├── DesignSystem/DesignTokens.swift # 颜色/渐变/间距/字体全局设计令牌 -│ ├── Models/APIModels.swift # 20+ DTO 数据模型 -│ ├── Network/ -│ │ ├── APIClient.swift # 通用 HTTP 客户端(actor, async/await) -│ │ ├── APIConfig.swift # baseURL 配置 -│ │ └── APIError.swift # 错误枚举(网络/服务端/解码/认证) -│ └── Services/APIService.swift # 8 个服务类,15 个公开方法 -│ -├── Features/ -│ ├── AI/ -│ │ ├── AIHomeView.swift # AI 首页 + ZXQuickAction + ZXAIInteractionRow 组件 -│ │ └── DailyThinkingPage.swift # 每日思考题 + RecallTestPage / WeakPointsPage / -│ │ # AIFeedbackPageView / AIChatPage 子页面 -│ ├── Analysis/ -│ │ └── AnalysisHomeView.swift # 学习分析页 + ZXChartView 折线图 + ZXWeakRow 薄弱点 -│ ├── Library/ -│ │ ├── LibraryHomeView.swift # 知识库列表首页 -│ │ └── LibrarySubpages.swift # CreateLibraryPage / LibraryDetailPage / -│ │ # AddKnowledgePage / KnowledgeDetailPage / -│ │ # ImportPage / EditKnowledgePage -│ ├── Profile/ -│ │ └── ProfileView.swift # 个人中心页 -│ └── Study/ -│ └── StudyHomeView.swift # 学习工作台 + 今日任务 + 周活跃柱状图 -│ -└── Info.plist # 手动管理(ATS例外 / Bundle元数据等) -``` - ---- - -## 二、5 个 Tab 页面清单 - -| Tab | 标签 | SF Symbol | View | -|-----|------|-----------|------| -| 1 | AI | `brain.head.profile` | AIHomeView | -| 2 | 知识库 | `books.vertical.fill` | LibraryHomeView | -| 3 | 学习 | `bolt.fill` | StudyHomeView | -| 4 | 分析 | `chart.bar.fill` | AnalysisHomeView | -| 5 | 我的 | `person.fill` | ProfileView | - ---- - -## 三、所有页面/子页面总览(共 21 个) - -### AI 模块(1 主 + 4 子) - -| 页面 | 数据来源 | 核心功能 | -|------|---------|---------| -| AIHomeView | 🔴硬编码 | API 状态检测、思考题卡片、快捷操作、互动记录、提问输入栏 | -| DailyThinkingPage | 🔴硬编码 | AI 思考题展示 + 回答提交 | -| RecallTestPage | 🔴硬编码 | 回忆测试输入 | -| WeakPointsPage | 🔴硬编码 | 薄弱知识点静态列表 | -| AIFeedbackPageView | 🔴硬编码 | AI 反馈评分 + 操作入口 | -| AIChatPage | 🔴硬编码 | AI 对话气泡界面 | - -### 知识库模块(1 主 + 6 子) - -| 页面 | 数据来源 | 核心功能 | -|------|---------|---------| -| LibraryHomeView | 🔴硬编码 | 知识库列表 + 搜索框 + 创建入口 | -| CreateLibraryPage | 🔴静态 | 创建表单(名称+描述) | -| LibraryDetailPage | 🔴硬编码 | 知识点静态列表 | -| AddKnowledgePage | 🔴静态 | 添加知识点表单 | -| KnowledgeDetailPage | 🔴硬编码 | 知识点详情+标签+复习/费曼入口 | -| ImportPage | 🔴静态 | 导入方式选择(拍照/文件/链接/相册) | -| EditKnowledgePage | 🔴静态 | 编辑知识点表单 | - -### 学习模块(1 主) - -| 页面 | 数据来源 | 核心功能 | -|------|---------|---------| -| StudyHomeView | 🔴硬编码 | 今日进度环、任务列表(5个任务)、本周活跃柱状图 | - -### 分析模块(1 主) - -| 页面 | 数据来源 | 核心功能 | -|------|---------|---------| -| AnalysisHomeView | 🔴硬编码 | 4项统计徽章、掌握度7日折线图、薄弱知识点列表 | - -### 个人中心(1 主) - -| 页面 | 数据来源 | 核心功能 | -|------|---------|---------| -| ProfileView | 🔴硬编码 | 个人卡片、菜单列表、成就徽章 | - -### 启动流程(5 步 Onboarding) - -| 步骤 | 页面 | 功能 | -|------|------|------| -| Step 0 | SplashPage | 品牌开屏,2 秒自动跳转 | -| Step 1 | WelcomePage | 3 大功能介绍 | -| Step 2 | LoginPage | 手机号/邮箱 + 密码表单 + 微信/Apple 登录入口 | -| Step 3 | OnboardingPage | 4 步功能轮播 | -| Step 4 | GoalSetupPage | 学习目标/方法/每日时长选择 | - ---- - -## 四、APIService 已封装方法(15 个) - -| 服务类 | 方法 | 接口 | -|--------|------|------| -| WaitlistService | `join(...)` | POST /waitlist | -| | `stats()` | GET /waitlist/stats | -| AuthService | `appleLogin(...)` | POST /auth/apple | -| | `logout()` | POST /auth/logout | -| UserService | `myProfile()` | GET /users/me | -| | `updateProfile(...)` | PATCH /users/me | -| KnowledgeBaseService | `list()` | GET /knowledge-bases | -| | `create(...)` | POST /knowledge-bases | -| | `detail(id:)` | GET /knowledge-bases/:id | -| KnowledgeItemService | `list(baseId:)` | GET /knowledge-items | -| | `detail(id:)` | GET /knowledge-items/:id | -| | `create(...)` | POST /knowledge-items | -| AIAnalysisService | `analyze(...)` | POST /ai-analysis | -| ActivityService | `summary()` | GET /activity/summary | -| ReviewService | `due()` | GET /reviews/due | -| FocusItemService | `list()` | GET /focus-items | -| FeedbackService | `submit(...)` | POST /feedback | - ---- - -## 五、后端接口 vs App 覆盖对照表 - -| 后端模块 | 接口数 | App 覆盖 | 状态 | -|----------|--------|---------|------| -| System | 3 | 0 | ❌ 无 | -| Auth | 3 | 2(Service 有,View 未接) | 🔶 | -| Users | 3 | 2(Service 有,View 未接) | 🔶 | -| KnowledgeBase | 5 | 3(Service 有,View 未接) | 🔶 | -| KnowledgeItems | 4 | 3(Service 有,View 未接) | 🔶 | -| DocumentImport | 2 | 0 | ❌ 无 | -| LearningSession | 3 | 0 | ❌ 无 | -| ActiveRecall | 2 | 0 | ❌ 无 | -| AIAnalysis | 3 | 1(Service 有,View 未接) | 🔶 | -| FocusItems | 4 | 1(Service 有,View 未接) | 🔶 | -| Review | 2 | 1(Service 有,View 未接) | 🔶 | -| LearningActivity | 2 | 1(Service 有,View 未接) | 🔶 | -| Notifications | 2 | 0 | ❌ 无 | -| Feedback | 4 | 1(Service 有,View 未接) | 🔶 | -| Waitlist | 3 | 2(Service 有,View 未接) | 🔶 | - -> 覆盖率:Service 层 15/48 = 31%,View 层实际接入 0/48 = 0% diff --git a/AIStudyApp/docs/gap-analysis-2.md b/AIStudyApp/docs/gap-analysis-2.md deleted file mode 100644 index 5fa65c6..0000000 --- a/AIStudyApp/docs/gap-analysis-2.md +++ /dev/null @@ -1,267 +0,0 @@ -# AIStudyApp 现状与缺口分析 - 第二篇:缺失功能与实施路线 - -> 接第一篇《现有资源盘点》 -> 生成日期:2026-05-11 - ---- - -## 一、优先级总览 - -``` -P0(核心闭环,本周必须) 4 项 -P1(数据接入,下周) 5 项 -P2(新页面/功能,后续) 5 项 -P3(体验增强,优化期) 5 项 -``` - ---- - -## 二、P0 —— 核心学习闭环(4 项) - -### P0-1:真实 Apple 登录流程 - -**现状:** LoginPage 是静态表单,没有调 API,Token 没有持久化。 - -**需要做:** - -| 子任务 | 涉及文件 | -|--------|---------| -| 集成 `AuthenticationServices`,添加 `ASAuthorizationAppleIDButton` | LoginPage(内嵌在 AIStudyAppApp.swift) | -| 拿到 `identityToken` 后调用 `AuthService.appleLogin(...)` | LoginPage | -| 登录成功后用 `@AppStorage` 或 Keychain 存储 Token | APIClient | -| `@main` 启动时检查已有 Token,跳过 Onboarding | AIStudyAppApp.swift | -| 处理登录失败/网络错误的 UI 提示 | LoginPage | -| 接入 `POST /auth/refresh` Token 自动刷新 | APIClient | - -涉及接口:`POST /auth/apple`、`POST /auth/refresh`、`POST /auth/logout` - ---- - -### P0-2:知识库 + 知识点接入真实 API - -**现状:** LibraryHomeView 硬编码 4 个知识库,子页面表单没有提交。 - -**需要做:** - -| 子任务 | 涉及文件 | -|--------|---------| -| `LibraryHomeView` 的 `.task {}` 中调 `KnowledgeBaseService.list()` | LibraryHomeView.swift | -| 替换硬编码卡片为 `ForEach(bases)` 真实数据 | LibraryHomeView.swift | -| `CreateLibraryPage` 表单提交调 `KnowledgeBaseService.create(...)` | LibrarySubpages.swift | -| `LibraryDetailPage` 加载真实知识点列表 `KnowledgeItemService.list(baseId:)` | LibrarySubpages.swift | -| `AddKnowledgePage` 表单提交调 `KnowledgeItemService.create(...)` | LibrarySubpages.swift | -| `EditKnowledgePage` 提交调 `PATCH /knowledge-items/:id`(APIService 需新增 update 方法) | LibrarySubpages.swift + APIService.swift | -| 增加 loading / empty / error 三种状态处理 | 各 Library 页面 | - -涉及接口:`GET/POST /knowledge-bases`、`GET/POST/PATCH /knowledge-items` - ---- - -### P0-3:学习会话追踪 - -**现状:** StudyHomeView 的"今日任务"是静态列表,没有学习计时,没有调任何接口。 - -**需要做:** - -| 子任务 | 涉及文件 / 新建文件 | -|--------|-------------------| -| 新建 `LearningSessionView.swift`:含计时器(`Timer.publish`)+ 暂停/结束按钮 | **新文件** Features/Study/LearningSessionView.swift | -| 点击 StudyHomeView 任务 → push 到 LearningSessionView | StudyHomeView.swift | -| 入场调 `POST /learning-sessions`(传入 knowledgeBaseId) | LearningSessionView.swift | -| 结束/暂停时调 `POST /learning-sessions/:id/end` | LearningSessionView.swift | -| APIService 新增 `LearningSessionService` | APIService.swift | -| APIModels 新增 `LearningSessionCreateRequest` / `LearningSessionResponse` | APIModels.swift | - -涉及接口:`POST /learning-sessions`、`POST /learning-sessions/:id/end`、`GET /learning-sessions` - ---- - -### P0-4:间隔复习卡片 - -**现状:** 没有复习页面。后端 `GET /reviews/due` + `POST /reviews/:id/submit` 已就绪。 - -**需要做:** - -| 子任务 | 新建文件 | -|--------|---------| -| 新建 `ReviewCardView.swift`:正面问题 → 点击翻转 → 显示答案 → 评分按钮 | **新文件** Features/Study/ReviewCardView.swift | -| 评分按钮:Again(1) / Hard(2) / Good(3) / Easy(4),调 `POST /reviews/:id/submit` | ReviewCardView.swift | -| 复习入口放在 StudyHomeView "今日任务"区域顶部 | StudyHomeView.swift | -| 复习入口放在 AIHomeView 快捷操作中 | AIHomeView.swift | -| 到期卡片数为 0 时显示空状态"🎉 都复习完啦" | ReviewCardView.swift | - -涉及接口:`GET /reviews/due`、`POST /reviews/:id/submit` - ---- - -## 三、P1 —— 数据接入(5 项) - -### P1-1:薄弱点 / AI 分析接真实数据 - -**现状:** AnalysisHomeView / WeakPointsPage 硬编码 3 条数据。 - -**需要做:** - -| 子任务 | 涉及文件 | -|--------|---------| -| AnalysisHomeView `.task {}` 中调 `FocusItemService.list()` | AnalysisHomeView.swift | -| 替换硬编码 ZXWeakRow 为 `ForEach(focusItems)` | AnalysisHomeView.swift | -| RecallTestPage 提交回答时调 `AIAnalysisService.analyze(...)` | DailyThinkingPage.swift | -| AIFeedbackPageView 展示真实分析结果 | DailyThinkingPage.swift | -| APIModels 增补 FocusItem 字段对齐后端 | APIModels.swift | - -涉及接口:`GET /focus-items`、`POST /ai-analysis`、`GET /ai-analysis/:id` - ---- - -### P1-2:StudyHomeView 数据真实化 - -**现状:** 进度环、任务列表、周活跃柱状图全是硬编码。 - -**需要做:** - -| 子任务 | 涉及文件 | -|--------|---------| -| 调 `ActivityService.summary()` 获取真实统计数据 | StudyHomeView.swift | -| 进度环用真实 `totalMinutes` / `streakDays` | StudyHomeView.swift | -| 周活跃图调 `GET /activity/heatmap`(APIService 需新增 heatmap 方法) | StudyHomeView.swift + APIService.swift | -| 今日任务从 `GET /reviews/due` + `GET /focus-items` 拼接 | StudyHomeView.swift | - -涉及接口:`GET /activity/summary`、`GET /activity/heatmap` - ---- - -### P1-3:ProfileView 接入用户资料 - -**现状:** ProfileView 全部静态假数据(昵称"学习者"、假统计)。 - -**需要做:** - -| 子任务 | 涉及文件 | -|--------|---------| -| `.task {}` 调 `UserService.myProfile()` | ProfileView.swift | -| 替换头像(emoji → 真实 avatar URL / 默认头像) | ProfileView.swift | -| 替换昵称、邮箱、统计数字 | ProfileView.swift | -| 菜单项"学习目标设置"跳设置表单页 → `PATCH /users/me/preferences` | ProfileView.swift + 新 SettingsView | - -涉及接口:`GET /users/me`、`PATCH /users/me`、`PATCH /users/me/preferences` - ---- - -### P1-4:通知中心页面 - -**现状:** 完全没有通知页面。 - -**需要做:** - -| 子任务 | 新建/涉及文件 | -|--------|-------------| -| 新建 `NotificationListView.swift` | **新文件** Features/Profile/NotificationListView.swift | -| `.task {}` 调 `GET /notifications` | NotificationListView.swift | -| 列表项点击标记已读 `POST /notifications/:id/read` | NotificationListView.swift | -| ProfileView 右上角铃铛 badge 显示未读数 | ProfileView.swift | -| APIService 新增 `NotificationService` | APIService.swift | - -涉及接口:`GET /notifications`、`POST /notifications/:id/read` - ---- - -### P1-5:反馈提交 - -**现状:** 没有反馈提交入口。 - -**需要做:** - -| 子任务 | 涉及文件 | -|--------|---------| -| ProfileView 菜单加"帮助与反馈" → 跳反馈表单 | ProfileView.swift + 新 FeedbackView | -| 调 `FeedbackService.submit(...)` | 新 FeedbackView | -| 提交后显示"感谢反馈"提示 | 新 FeedbackView | - -涉及接口:`POST /feedback` - ---- - -## 四、P2 —— 新页面/功能(5 项) - -### P2-1:文件导入真实接入 - -**现状:** ImportPage 只有 4 个静态按钮。 - -**需要做:** 接入 `PHPickerViewController`(相册选图)、`UIDocumentPickerViewController`(文件选择)、AVCaptureSession(拍照),上传后调 `POST /imports`,轮询 `GET /imports/:id/status`。APIService 新增 `DocumentImportService`。 - ---- - -### P2-2:全局搜索 - -**现状:** LibraryHomeView 有搜索框但无效。 - -**需要做:** 新建 `SearchView.swift`,调 `GET /knowledge-items?keyword=xxx`,支持搜索知识点/知识库/标签,展示搜索结果列表。 - ---- - -### P2-3:设置页面完善 - -**现状:** ProfileView 5 个菜单项全是假的。 - -**需要做:** 每个菜单项对应一个设置表单页:学习目标、复习提醒时间、学习报告邮件、学习方法偏好(费曼/回忆/间隔/综合)、数据同步状态。 - ---- - -### P2-4:主动回忆(Active Recall)流程 - -**现状:** RecallTestPage 只提交假的 AI 分析,没有调 `GET /active-recalls`。 - -**需要做:** 新建 ActiveRecallView,展示问题卡片 → 输入回答 → 调 `POST /active-recalls/:id/submit`。 - ---- - -### P2-5:Token 自动刷新与登录态管理 - -**现状:** Token 没有持久化,没有 refresh 逻辑。 - -**需要做:** Keychain 存储 accessToken + refreshToken;APIClient 拦截 401 → 自动调 `POST /auth/refresh` → 重试原请求;refresh 也失败 → 清 Token → 跳登录页。 - ---- - -## 五、P3 —— 体验增强(5 项) - -| # | 项目 | 说明 | -|---|------|------| -| P3-1 | 下拉刷新 | 所有列表页 `.refreshable {}` + 页码分页 | -| P3-2 | 加载/空/错误三态 | 每个数据加载页加 ProgressView / 空状态插图+文案 / 错误重试按钮 | -| P3-3 | 离线缓存 | 用 UserDefaults 或本地 JSON 缓存最近数据,断网可展示 | -| P3-4 | 深色模式 | 当前强制 `.dark`,需支持跟随系统 | -| P3-5 | 无障碍 | VoiceOver labels、Dynamic Type 适配、高对比度 | - ---- - -## 六、实施建议顺序 - -``` -第 1 周 ─ P0-1 登录 → P0-2 知识库CRUD → P0-3 学习会话 -第 2 周 ─ P0-4 复习卡片 → P1-1 薄弱点/AI分析 → P1-2 StudyHomeView 真实化 -第 3 周 ─ P1-3 ProfileView → P1-4 通知中心 → P1-5 反馈 -第 4 周 ─ P2-1 文件导入 → P2-2 搜索 → P2-3 设置页 -第 5 周 ─ P2-4 主动回忆 → P2-5 Token刷新 -第 6 周 ─ P3 体验增强 -``` - ---- - -## 七、后端接口未封装清单(需新增 Service 方法) - -| 模块 | 后端口 | 未封装接口 | -|------|--------|----------| -| KnowledgeBase | PATCH/DELETE | update / delete | -| KnowledgeItems | PATCH/DELETE | update / delete | -| LearningSession | POST/GET | start / end / list | -| ActiveRecall | GET/POST | list / submit | -| AIAnalysis | GET | result / job status | -| Activity | GET | heatmap | -| Notifications | GET/POST | list / markRead | -| DocumentImport | POST/GET | create / status | -| Review | POST | submit | -| FocusItems | POST/PATCH | create / update / complete | - -> 需新增约 15 个 Service 方法 + 对应 Request/Response DTO diff --git a/AIStudyApp/docs/pages.md b/AIStudyApp/docs/pages.md deleted file mode 100644 index c40bffa..0000000 --- a/AIStudyApp/docs/pages.md +++ /dev/null @@ -1,235 +0,0 @@ -# 知习 ZhiXi — 页面清单与功能说明 - -> 更新时间:2026-05-10 - -## 项目概述 - -**知习 (ZhiXi)** 是一个 AI-first 系统化学习 iOS App,使用 SwiftUI 构建,深色主题。当前已完成 22 个页面的 UI 层实现,覆盖从引导流程到主界面 5 个 Tab 的完整交互链路。 - ---- - -## 一、引导流程(5 页) - -所有引导页面定义在 `AIStudyAppApp.swift` 的 `OnboardingFlowView` 中,通过 `@AppStorage("hasCompletedOnboarding")` 控制显示。 - -### 1. SplashPage — 启动页 - -- **路由**:`OnboardingFlowView` step 0 -- **功能**:展示品牌 Logo、App 名称"知习"、副标题"AI-first 系统化学习",底部显示加载进度条,2 秒后自动跳转 Welcome -- **视觉**:深色渐变背景 + 紫色/橙色光晕 + 品牌渐变图标 - -### 2. WelcomePage — 欢迎页 - -- **路由**:`OnboardingFlowView` step 1 -- **功能**:展示产品三大核心功能(主动回忆、费曼解释、AI 分析);提供"开始使用"和"已有账号?立即登录"两个入口 -- **UI 组件**:`FeatureRow`(emoji + 标题 + 描述卡片) - -### 3. LoginPage — 登录页 - -- **路由**:`OnboardingFlowView` step 2 -- **功能**:支持手机号(+86)和邮箱两种登录方式切换;密码输入可切换明文/密文;底部提供微信登录和 Apple 登录入口;包含"忘记密码"链接 -- **UI 组件**:`ZXInputField`、`SocialLoginBtn` - -### 4. OnboardingPage — 功能引导页 - -- **路由**:`OnboardingFlowView` step 3 -- **功能**:4 步滑动引导(输入知识 → 主动输出 → AI 分析 → 掌握知识),底部进度指示器,支持跳过 -- **UI 组件**:步进圆点指示器 - -### 5. GoalSetupPage — 学习目标设置页 - -- **路由**:`OnboardingFlowView` step 4 -- **功能**:设置学习目标(备考考试/职业技能/通识学习/自定义)、选择学习方法(间隔回忆/费曼技巧/AI 分析)、选择每日学习时间(15 分钟 ~ 不限制) -- **UI 组件**:目标选项卡片(emoji + 标题 + 描述 + 单选圆点)、方法标签组、时间选择组 - ---- - -## 二、主界面 — 5 Tab 结构 - -`ContentView.swift` 实现底部 5 个 Tab 的导航:AI、知识库、学习、分析、我的。 - -### Tab 栏组件 - -- **ZXTabBar**:自定义底部 TabBar,包含选中态光晕动画、品牌紫色高亮 -- **ZXAIInputBar**:复用的 AI 输入栏(sparkles 图标 + 输入框 + 麦克风 + 发送按钮) -- **ZXIconBtn**:通用图标按钮(支持 branded 紫色渐变样式) -- **ZXScoreBox**:评分展示组件(分数 + 背景色 + 前景色,根据分数区间变色) - ---- - -### Tab 1:AI 助手 — AIHomeView - -- **文件**:`Features/AI/AIHomeView.swift` -- **功能**: - - 今日思考题卡片(展示 AI 生成的思考题,点击进入回答) - - 快捷操作区(生成回忆测试、分析薄弱点、费曼解释练习、今日复习计划) - - 最近 AI 互动列表(费曼复习、薄弱点分析、回忆测试记录,含评分) - - AI 提问建议区(预设问题模板,点击可发送) - - 底部 AI 输入栏 -- **子页面**: - - `DailyThinkingPage` — 今日思考详情(见下方) - - `RecallTestPage` — 回忆测试 - - `WeakPointsPage` — 薄弱点分析 - - `AIChatPage` — AI 对话 -- **UI 组件**:`ZXQuickAction`(emoji + 标签)、`ZXAIInteractionRow`(标签 + 标题 + 时间 + 评分) - -#### AI 子页面(定义在 `Features/AI/DailyThinkingPage.swift`) - -| 页面 | 功能 | -|------|------| -| **DailyThinkingPage** | 展示思考题 + 文本输入框,用户写下回答后提交给 AI 评估 | -| **AIChatPage** | AI 对话页面,围绕当前知识库进行学习问答 | -| **RecallTestPage** | 回忆测试:展示题目,用户回忆并写下理解,提交验证 | -| **WeakPointsPage** | 薄弱知识点列表,每个知识点显示掌握分数、所属知识库、优先级 | -| **AIFeedbackPage** | AI 反馈页,展示 AI 对用户回答的评分、优缺点分析、改进建议 | - -**共享 UI 组件**:`ZXBackHeader` — 带返回按钮、标题、副标题、右侧操作区的通用导航头 - ---- - -### Tab 2:知识库 — LibraryHomeView - -- **文件**:`Features/Library/LibraryHomeView.swift` -- **功能**: - - 知识库列表(机器学习、高等数学、英语词汇、产品设计等),每个卡片展示 emoji、名称、描述、知识点数量、掌握度百分比、标签、最近学习时间 - - 顶部搜索栏 - - 右上角搜索和创建按钮 - - 创建新知识库入口(虚线边框卡片) -- **UI 组件**:`ZLibraryCard`(emoji + 名称 + 描述 + 进度条 + 标签 + 统计) - -#### 知识库子页面(定义在 `Features/Library/LibrarySubpages.swift`) - -| 页面 | 功能 | -|------|------| -| **CreateLibraryPage** | 创建新知识库:填写名称、描述 | -| **LibraryDetailPage** | 知识库详情:展示该知识库下所有知识点列表,每个知识点显示标题、描述、掌握状态(已掌握/学习中/待复习) | -| **AddKnowledgePage** | 添加知识点:填写标题、内容 | -| **KnowledgeDetailPage** | 知识点详情:展示完整内容、标签、复习/费曼解释按钮 | -| **ImportPage** | 导入资料 | -| **EditKnowledgePage** | 编辑知识点 | - -**知识库卡片组件**:`ZXCardRow` — emoji + 标题 + 描述 + 状态标签 - ---- - -### Tab 3:学习工作台 — StudyHomeView - -- **文件**:`Features/Study/StudyHomeView.swift` -- **功能**: - - 日期和问候语("周四,1月16日") - - 连续学习天数徽章(🔥) - - 今日进度卡片:完成任务数/总任务数、进度百分比环形图、进度条、已学时间/剩余时间/掌握积分 - - 今日任务列表(机器学习回忆测试、高数间隔复习、英语词汇复习等),每个任务可勾选完成,显示任务类型标签和预计时长 - - 本周学习活跃柱状图(周一~周日,高亮当天) - - 总计学习时长和日均统计 -- **数据模型**:`ZXSTask`(标题、类型、颜色、时长、完成状态) -- **UI 组件**:`ZXSTaskRow`(勾选框 + 任务信息 + 类型标签 + 时长 + 播放按钮) - ---- - -### Tab 4:学习分析 — AnalysisHomeView - -- **文件**:`Features/Analysis/AnalysisHomeView.swift` -- **功能**: - - 顶部统计卡片行:综合掌握度(65%,+8%)、本周积分(1,240)、待巩固知识点数(23)、连续学习天数(14) - - 掌握度趋势折线图(近 7 天数据) - - 薄弱知识点列表(可导航至 WeakPointsPage) - - AI 学习建议卡片 - - 知识库掌握分布(各知识库掌握度进度条) -- **UI 组件**:`ZXStatBadge`(图标 + 标签 + 数值 + 变化趋势)、`ZXChartView`、`ZXWeakRow` - ---- - -### Tab 5:我的 — ProfileView - -- **文件**:`Features/Profile/ProfileView.swift` -- **功能**: - - 顶部导航栏(标题"我的" + 通知铃铛 + 设置齿轮) - - 个人信息卡片:头像(emoji)、昵称"学习者"、邮箱、连续天数/知识点数/积分统计 - - 设置菜单:学习目标设置、复习提醒、学习报告、学习方法偏好、数据同步与备份 - - 成就展示区(连续 14 天、费曼达人、知识收藏家、速学者) -- **UI 组件**:`ZXProfileStat`、`ZXProfileMenuRow`(emoji + 标题 + 描述 + 箭头)、`ZXAchievementBadge` - ---- - -## 三、设计系统 - -文件:`Core/DesignSystem/DesignTokens.swift` - -### 颜色系统 -| 类别 | Token | 值 | -|------|-------|-----| -| 主背景 | `Color.zxBg0` | `#0F0F1A` | -| 品牌紫 | `Color.zxPurple` | `#7C6EFA` | -| 品牌橙 | `Color.zxOrange` | `#F97316` | -| 文字主色 | `Color.zxF0` | `#F0F0FF` | - -### 渐变系统 (`ZXGradient`) -- `page` — 页面背景渐变 -- `brand` — 品牌紫橙渐变 -- `brandPurple` — 紫色渐变 -- `thinkingCard` — 思考卡片渐变 -- `progressCard` — 进度卡片渐变 -- `feedbackScore` — 反馈评分渐变 -- `profileCard` — 个人信息卡片渐变 -- `ctaButton` / `ctaPurple` — CTA 按钮渐变 - -### 间距系统 (`ZXSpacing`) -- `pageHPadding`: 20 -- `statusBarH`: 44 -- `tabBarH`: 83 - -### 尺寸系统 (`ZXSize`) -- 图标按钮: 36, 头像: 36/64/80 -- 按钮高度: 42/52/56, 快捷操作: 72 - -### 排版系统 (`ZXFont`) -- `titleLarge`: 22pt heavy, -0.5 tracking -- `titleMedium`: 20pt heavy, -0.4 tracking -- `sectionTitle`: 15pt bold -- `body`: 13pt semibold -- `bodySmall`: 12pt medium -- `caption`: 10pt bold - ---- - -## 四、页面状态总览 - -| # | 页面 | Tab | 文件 | 导航方式 | 状态 | -|---|------|-----|------|----------|------| -| 1 | Splash 启动页 | — | AIStudyAppApp.swift | 自动跳转 | ✅ | -| 2 | Welcome 欢迎页 | — | AIStudyAppApp.swift | 按钮跳转 | ✅ | -| 3 | Login 登录页 | — | AIStudyAppApp.swift | 按钮跳转 | ✅ | -| 4 | Onboarding 引导 | — | AIStudyAppApp.swift | 步进/跳过 | ✅ | -| 5 | GoalSetup 目标 | — | AIStudyAppApp.swift | 完成进入主界面 | ✅ | -| 6 | AIHome AI 首页 | AI | AIHomeView.swift | Tab 1 | ✅ | -| 7 | LibraryHome 知识库 | 知识库 | LibraryHomeView.swift | Tab 2 | ✅ | -| 8 | StudyHome 学习 | 学习 | StudyHomeView.swift | Tab 3 | ✅ | -| 9 | AnalysisHome 分析 | 分析 | AnalysisHomeView.swift | Tab 4 | ✅ | -| 10 | Profile 我的 | 我的 | ProfileView.swift | Tab 5 | ✅ | -| 11 | AIChat AI 对话 | AI | DailyThinkingPage.swift | NavigationLink | ✅ | -| 12 | DailyThinking 今日思考 | AI | DailyThinkingPage.swift | NavigationLink | ✅ | -| 13 | RecallTest 回忆测试 | AI | DailyThinkingPage.swift | NavigationLink | ✅ | -| 14 | WeakPoints 薄弱点 | AI | DailyThinkingPage.swift | NavigationLink | ✅ | -| 15 | AIFeedback AI 反馈 | AI | DailyThinkingPage.swift | NavigationLink | ✅ | -| 16 | CreateLibrary 创建知识库 | 知识库 | LibrarySubpages.swift | NavigationLink | ✅ | -| 17 | LibraryDetail 知识库详情 | 知识库 | LibrarySubpages.swift | NavigationLink | ✅ | -| 18 | AddKnowledge 添加知识点 | 知识库 | LibrarySubpages.swift | NavigationLink | ✅ | -| 19 | Import 导入资料 | 知识库 | LibrarySubpages.swift | NavigationLink | ✅ | -| 20 | KnowledgeDetail 知识点详情 | 知识库 | LibrarySubpages.swift | NavigationLink | ✅ | -| 21 | EditKnowledge 编辑知识点 | 知识库 | LibrarySubpages.swift | NavigationLink | ✅ | - ---- - -## 五、当前未实现的功能 - -以下为产品计划中但当前 iOS 项目尚未实现的能力: - -- Sign in with Apple(UI 已做,实际认证逻辑未接入) -- 后端 API 对接(当前为纯本地 UI) -- 真实 AI 分析(当前为静态展示) -- 数据持久化(无本地存储/云端同步) -- 多语言本地化架构 -- Apple IAP 支付 -- 推送通知 -- 崩溃监控/数据埋点 diff --git a/AIStudyApp/docs/plan-ios-requirements.md b/AIStudyApp/docs/plan-ios-requirements.md deleted file mode 100644 index 9d036e7..0000000 --- a/AIStudyApp/docs/plan-ios-requirements.md +++ /dev/null @@ -1,339 +0,0 @@ -# 个人开发者创业 v0.1 — iOS 相关需求整理 - -> 来源:`startup-plan/个人开发者创业 v0.1/` 各文档 -> 整理时间:2026-05-10 - -本文档从 v0.1 创业计划中提取所有与 iOS 客户端直接相关的内容,作为 iOS 开发的参考基线。 - ---- - -## 一、产品定位(来源:`0-项目总纲/项目总纲.md`) - -- 产品长期方向:AI 驱动的系统化学习产品(知识库 + 笔记 + AI 学习教练 + 复习计划) -- 当前只做三件事:确定方向 → 做 14 天验证 Demo → 找第一批真实反馈 -- 平台策略:**只做 iPhone**,不做 Android/iPad/Mac/Web 学习端 -- 不做:完整平台、泛学习大而全、复杂后端、支付 - -### 三个候选方向 - -1. 公考申论 AI 学习教练 -2. AI 工具学习知识库 -3. 程序员/前端面试学习助手 - ---- - -## 二、第一版产品形态(来源:`2-Demo与MVP/Demo与MVP.md`) - -``` -iPhone App + 官网基础页面 + 最小后端 + AI API -``` - -### MVP 核心学习闭环 - -``` -注册/登录 → 选择学习方向 → 进入学习路径 → 阅读知识内容 -→ 主动回忆/写笔记/写答案 → AI 分析 → 生成学习状态 -→ 给出复习和下一步建议 → 进入下一次学习 -``` - -### 第一版页面列表(计划 14 页) - -| 优先级 | 页面 | 当前 iOS 实现 | -|--------|------|---------------| -| **P0** | 登录页 | `LoginPage` ✅ | -| **P0** | 学习方向选择页 | `GoalSetupPage` ✅ (部分) | -| **P0** | 学习路径页 | `LibraryHomeView` + `LibraryDetailPage` ✅ | -| **P0** | 今日学习任务页 | `StudyHomeView` ✅ | -| **P0** | 内容阅读页 | `KnowledgeDetailPage` ✅ | -| **P0** | 主动回忆/笔记输入页 | `DailyThinkingPage` + `RecallTestPage` ✅ | -| **P0** | AI 分析结果页 | `AIFeedbackPage` ✅ | -| **P0** | AI 对话页 | `AIChatPage` ✅ | -| **P0** | 复习计划页 | 未独立实现 ⚠️ (部分在 StudyHomeView) | -| **P1** | 学习进度页 | `AnalysisHomeView` ✅ | -| **P1** | 设置页 | `ProfileView` ✅ | -| **P1** | 反馈页 | 未实现 ❌ | -| **P1** | 启动页/欢迎页 | `SplashPage` + `WelcomePage` ✅ | -| **P1** | 语言与基础偏好页 | 未实现 ❌ | - -### 底部 Tab 设计(计划) - -``` -学习 | 知识库 | AI助手 | 我的 -``` - -当前 iOS 实现为 5 个 Tab:`AI | 知识库 | 学习 | 分析 | 我的`(多了"分析"Tab,将计划的 AI 助手拆分为独立的分析页) - ---- - -## 三、账号体系(来源:`2-Demo与MVP/Demo与MVP.md`) - -- **第一版登录方式**:Sign in with Apple -- **暂不做**:微信登录、手机号登录、邮箱密码登录、Google 登录 - -> ⚠️ 当前 iOS `LoginPage` 包含了手机号/邮箱登录 + 微信/Apple 登录 UI,与计划"A Sign in with Apple"的要求不完全一致。计划强调极简,实际 UI 做了更多登录方式入口。 - -### 用户身份模型(计划) - -``` -User -├── id -├── appleUserId -├── displayName -├── email -├── preferredLanguage -├── createdAt -├── lastLoginAt -└── status -``` - ---- - -## 四、知识库设计(来源:`2-Demo与MVP/Demo与MVP.md`) - -### 数据结构 - -``` -KnowledgeBase → LearningPath → Module → Lesson - ├── 正文内容 - ├── 学习目标 - ├── 重点概念 - ├── 主动回忆问题 - ├── 练习输入 - └── AI 分析规则 -``` - -### 第一版内容范围 - -只做一个小路径,例如"AI 工具入门 7 天路径",而不是大而全的知识库市场。 - ---- - -## 五、AI 能力需求(来源:`2-Demo与MVP/Demo与MVP.md`) - -### AI 三大核心职责 - -1. 分析用户输入 -2. 判断用户当前学习状态 -3. 给出下一步学习建议 - -### AI 分析维度 - -``` -理解程度、要点覆盖、逻辑结构、表达清晰度、错误理解、遗漏内容、下一步建议 -``` - -### AI 输出结构(计划 JSON Schema) - -```json -{ - "masteryScore": 3, - "understandingLevel": "基本理解", - "summary": "用户能说出核心意思,但要点不够完整。", - "strengths": ["能识别主要问题", "表达比较清楚"], - "weakPoints": ["遗漏关键要点", "逻辑层次不够清晰"], - "suggestions": ["补充材料中的第二个要点", "回答时先概括问题,再展开原因"], - "reviewNeeded": true, - "nextAction": "建议明天复习本节,并重新回答主动回忆问题。" -} -``` - -### 掌握度评分(0-5) - -``` -0 = 没有作答/无法判断 -1 = 基本没理解 -2 = 理解较弱 -3 = 基本理解 -4 = 理解较好 -5 = 掌握很好 -``` - -### AI 对话页定位 - -只能围绕当前知识库和学习内容,不能做泛聊天。快捷问题预设: -- 帮我解释这一节 -- 用更简单的话讲 -- 给我举个例子 -- 我哪里理解错了 -- 帮我总结重点 -- 生成一个复习问题 - ---- - -## 六、学习状态模型(来源:`2-Demo与MVP/Demo与MVP.md`) - -### 用户学习画像 - -``` -UserLearningProfile -├── userId -├── currentKnowledgeBaseId -├── currentPathId -├── currentLessonId -├── overallLevel -├── weakPoints -├── strengths -├── recentMistakes -├── reviewQueue -├── learningStreak -└── updatedAt -``` - -### 单次学习记录 - -``` -LearningSession -├── id -├── userId -├── lessonId -├── startedAt -├── endedAt -├── userInput -├── aiAnalysis -├── masteryScore -├── weakPoints -├── nextSuggestion -└── reviewAt -``` - -### 复习任务 - -``` -ReviewTask -├── id -├── userId -├── lessonId -├── sourceSessionId -├── reviewType -├── scheduledAt -├── completedAt -└── status -``` - ---- - -## 七、UI 设计原则(来源:`2-Demo与MVP/Demo与MVP.md`) - -``` -安静、清晰、克制、学习感、低干扰、Apple原生感、卡片式结构、适合长时间阅读 -``` - -- 不做花哨视觉 -- 不做复杂动画 -- 不做社交信息流 -- 不做游戏化过重设计 -- 优先保证阅读体验 -- 优先保证学习任务清晰 -- 优先保证 AI 分析结果可理解 - ---- - -## 八、技术选型(来源:`3-官网与技术基础/官网与技术基础.md`) - -| 项目 | 计划选型 | 当前实现 | -|------|----------|----------| -| UI 框架 | SwiftUI | SwiftUI ✅ | -| 架构模式 | MVVM + Service + Repository | 无分层(View 内聚)⚠️ | -| 设计规范 | Apple HIG | 深色主题 + 自定义 DesignTokens ✅ | -| 动效策略 | 轻量、有意义、服务学习体验 | 最小动效(仅基础过渡)⚠️ | -| 多语言 | 预留架构,中文默认 | 未实现 ❌ | -| 部署 | 4 核 4G 轻量云 + Nginx + Docker | 未接入 ❌ | - -### 目录结构(计划 vs 实际) - -计划定义了完整的分层目录(App/Core/Features/Shared/Resources),当前实现仅有 Features 和 DesignSystem,缺少 Network、Auth、Storage、Localization、ViewModel、Model 等层。 - -### 第一版 iOS 不做(来自计划) - -- 复杂动画系统 -- iPad 专门布局 / Mac Catalyst / Watch App / Widget -- 离线完整知识库 -- 复杂搜索 -- 文件导入 -- 推送通知 -- 支付订阅 -- 复杂自定义控件 - ---- - -## 九、数据实体汇总(来源:`2-Demo与MVP/Demo与MVP.md`) - -``` -User -KnowledgeBase -LearningPath -Lesson -LearningSession -AIAnalysis -ReviewTask -Feedback -WaitlistEntry -``` - ---- - -## 十、核心 API 接口(来源:`3-官网与技术基础/官网与技术基础.md`) - -### POST /ai/analyze-learning-input - -分析用户学习输入,返回掌握度评估。 - -### POST /ai/chat - -AI 对话接口,限于当前知识库上下文。 - -### 后端模块(P0) - -Auth → User → Knowledge → Learning → AI → Review → Feedback → Waitlist - ---- - -## 十一、成功标准(来源:`2-Demo与MVP/Demo与MVP.md`) - -### 产品可用标准 - -- 用户能登录 -- 用户能选择学习路径 -- 用户能完成一节学习 -- 用户能输入内容 -- AI 能返回分析 -- 系统能生成复习建议 -- 用户知道下一步该干什么 - -### 验证成功标准 - -- 至少 10 个用户愿意试用 -- 至少 3 个用户完整走完学习闭环 -- 至少 3 条有效反馈 -- 至少 1 个用户表示愿意继续用 -- 至少 1 个用户表示未来愿意付费 - ---- - -## 十二、暂缓事项(来源:`99-暂缓事项/暂缓事项.md`) - -以下为 v0.1 明确不做、后续解冻的事项: - -| 类别 | 暂缓内容 | 解冻条件 | -|------|----------|----------| -| 商业化 | Apple IAP、订阅、免费试用 | TestFlight 有真实用户 + 有人愿意付费 | -| 运营 | 社群、客服机器人、打卡活动 | 10+ 内测用户持续反馈 | -| 数据 | 完整埋点、留存分析、付费转化 | App Store MVP 准备上线 | -| 合规 | 公司注册、微信/支付宝、备案 | Apple 端稳定收入 | -| 多端 | iPad、Mac、Android、Web | iPhone 核心稳定 + 用户多端需求 | - ---- - -## 十三、当前 iOS 实现与计划的差距 - -| 维度 | 计划要求 | 当前状态 | 差距 | -|------|----------|----------|------| -| 登录 | Sign in with Apple | 多种登录 UI | 需简化或实现 Apple 登录 | -| 架构 | MVVM + Service | View 内聚 | 需重构分层 | -| 多语言 | 架构预留 | 未实现 | 需添加本地化 | -| 后端对接 | REST API | 无 | 需接入 | -| AI 集成 | 真实 AI 分析 | 静态 Mock | 需接入 AI API | -| 数据持久化 | 本地缓存 + Keychain | 无 | 需实现 | -| Tab 设计 | 4 个 Tab | 5 个 Tab | 多了"分析"Tab | -| 反馈页 | P1 优先级 | 未实现 | 需添加 | -| 复习计划页 | P0 优先级 | 部分实现 | 需独立设计 | diff --git a/AIStudyApp/docs/样式规范.md b/AIStudyApp/docs/样式规范.md deleted file mode 100644 index 9c6ca3a..0000000 --- a/AIStudyApp/docs/样式规范.md +++ /dev/null @@ -1,550 +0,0 @@ -# 知习 iOS 样式规范 - -> 基于现有 DesignTokens 与实际页面中反复出现的 UI 模式,归纳形成本规范。 -> 后续创建新页面时,优先从本文档引用的 token 和组件中选择,保持一致的设计语言。 - ---- - -## 一、色彩系统 - -所有颜色定义在 `Core/DesignSystem/DesignTokens.swift`,命名前缀 `zx`(知习)。 - -### 1.1 背景 - -| Token | 色值 | 用途 | -|---|---|---| -| `zxBg0` | `#0F0F1A` | 页面基底(与 zxBg1 组成 page 渐变) | -| `zxBg1` | `#12122A` | page 渐变的第二色 | -| `zxBg2` | `#0A0A14` | 手机外壳装饰用,极少使用 | -| `zxBgSplash` | `#0D0D20` | 启动页专用 | - -### 1.2 文字 - -所有文字色基于 `#F0F0FF`(近白紫调)变化透明度: - -| Token | 透明度 | 用途 | -|---|---|---| -| `zxF0` | 100% | 标题、正文高亮 | -| `zxF007` | 70% | 次重要正文 | -| `zxF006` | 60% | — | -| `zxF05` | 50% | 次要信息 | -| `zxF0045` | 45% | — | -| `zxF04` | 40% | 辅助描述 | -| `zxF035` | 35% | 弱标签、灰色字段名 | -| `zxF03` | 30% | 占位符级别 | -| `zxF02` | 20% | 极弱(如未选中图标边框) | - -### 1.3 品牌/语义色 - -| Token | 色值 | 含义 | -|---|---|---| -| `zxPurple` | `#7C6EFA` | 主品牌,选中态、标签、进度 | -| `zxAccent` | `#A78BFA` | 次要品牌,AI 相关 | -| `zxOrange` | `#F97316` | 热度/连续天数/回忆 | -| `zxTeal` | `#2DD4BF` | 语言/词汇 | -| `zxCyan` | `#4ECDC4` | 进度条渐变 | -| `zxGreen` | `#34D399` | 已掌握、成功 | -| `zxYellow` | `#F59E0B` | 薄弱/警告/待复习 | -| `zxRed` | `#EF4444` | 错误/高优先级 | - -**彩色半透明背景**(用于标签、badge 底衬): - -```swift -zxPurpleBG(0.12) // 紫色 12% 透明 -zxOrangeBG(0.10) // 橙色 10% 透明 -zxGreenBG(0.15) // 绿色 15% 透明 -zxYellowBG(0.15) // 黄色 15% 透明 -zxTealBG(0.10) // 青色 10% 透明 -zxRedBG(0.15) // 红色 15% 透明 -``` - -### 1.4 边框/分割线 - -| Token | 透明度 | 用途 | -|---|---|---| -| `zxBorder015` | 15% | 较明显边框 | -| `zxBorder01` | 10% | 标准边框、虚线框 | -| `zxBorder008` | 8% | 通用卡片边框 | -| `zxBorder006` | 6% | 弱边框、卡片分隔 | -| `zxBorder004` | 4% | 极弱边框 | - -### 1.5 填充(半透明叠层) - -| Token | 透明度 | 用途 | -|---|---|---| -| `zxFill01` | 10% | 图表柱状 | -| `zxFill008` | 8% | 进度条底色 | -| `zxFill006` | 6% | 列表图标底衬 | -| `zxFill005` | 5% | 按钮/选中行底衬 | -| `zxFill004` | 4% | 输入框/面板底色 | -| `zxFill003` | 3% | 卡片底色 | - ---- - -## 二、渐变 - -所有渐变定义在 `ZXGradient` enum。 - -| 渐变 | 颜色 | 方向 | 用途 | -|---|---|---|---| -| `page` | `#0F0F1A → #12122A` | top→bottom | 所有主页面背景 | -| `splash` | `#0D0D20 → #0F0F1A → #130D20` | top→bottom | 启动页背景 | -| `brand` | `#7C6EFA → #F97316` | topLeading→bottomTrailing | CTA 按钮、播放按钮 | -| `brandPurple` | `#7C6EFA → #9B8BFF` | leading→trailing | 发送按钮、AI 气泡 | -| `ctaButton` | `#7C6EFA → #F97316` | topLeading→bottomTrailing | 同 brand,CTA 语义 | -| `ctaPurple` | `#7C6EFA → #9B8BFF` | topLeading→bottomTrailing | 紫色 CTA(创建/保存/提交) | -| `progressBar` | `#7C6EFA → #4ECDC4` | leading→trailing | 进度条 | -| `thinkingCard` | `#7C6EFA 8% → #F97316 4%` | topLeading→bottomTrailing | 思考卡片 | -| `progressCard` | `#7C6EFA 10% → #F97316 5%` | topLeading→bottomTrailing | 进度卡片 | -| `feedbackScore` | `#7C6EFA 12% → #34D399 6%` | topLeading→bottomTrailing | 反馈评分卡片 | -| `profileCard` | `#7C6EFA 15% → #F97316 8%` | topLeading→bottomTrailing | 个人页卡片 | - ---- - -## 三、圆角 - -```swift -ZXRadius.xs = 2 // 进度指示器小圆点 -ZXRadius.sm = 8 // 小图标 -ZXRadius.md = 10 // 标准图标按钮 -ZXRadius.lg = 12 // 标签/徽章 -ZXRadius.xl = 14 // 卡片/输入框/行 -ZXRadius.xl2 = 16 // 大卡片/对话框 -ZXRadius.xl3 = 20 // 主要面板 - -ZXRadius.button = 12 // 标准按钮 -ZXRadius.buttonLg = 18 // 大按钮(CTA) -ZXRadius.icon = 10 // 小图标 -ZXRadius.iconLg = 12 // 中图标 -ZXRadius.avatar = 13 // 头像/emoji 图标 -``` - -**使用原则**: -- 卡片统一 `14`–`20` -- 按钮统 `12`–`18` -- 输入框 `14` -- 标签 `Capsule()`(自动全圆角) - ---- - -## 四、间距 - -```swift -ZXSpacing.ss = 2 // 字间距/tracking 用 -ZXSpacing.xs = 4 -ZXSpacing.sm = 6 -ZXSpacing.md = 8 // 卡片内元素间距 -ZXSpacing.lg = 10 -ZXSpacing.xl = 12 // 行内元素间距 -ZXSpacing.xl2 = 14 -ZXSpacing.xl3 = 16 // 卡片间距 -ZXSpacing.xl4 = 20 // 页面水平内边距 -ZXSpacing.xl5 = 24 -ZXSpacing.xl6 = 28 - -// 专用 -ZXSpacing.pageHPadding = 20 // 所有页面两侧统一留白 -ZXSpacing.statusBarH = 44 // 状态栏 + Dynamic Island -ZXSpacing.tabBarH = 83 // 底部 TabBar 总高 -ZXSpacing.homeIndicatorH = 34 // Home Indicator -``` - -**页面结构公式**: -``` -header top padding = statusBarH + 16 -每个 section 间距 = 12–20 -ScrollView bottom = 120(有 TabBar)/ 80–100(子页面) -``` - ---- - -## 五、尺寸 - -```swift -// 按钮 -ZXSize.iconBtn = 36 // 图标按钮(ZXIconBtn 默认) -ZXSize.buttonH = 42 // 标准按钮高 -ZXSize.buttonLgH = 52 // 大按钮高 -ZXSize.buttonXlH = 56 // CTA 按钮高 -ZXSize.sendBtn = 30 // 发送按钮 - -// 图标 -ZXSize.iconSm = 14 -ZXSize.iconMd = 16 -ZXSize.iconLg = 18 -ZXSize.tabIcon = 22 // TabBar 图标 -ZXSize.listIcon = 40 // 列表图标 -ZXSize.libraryIcon = 44 // 知识库卡片图标 - -// 头像 -ZXSize.avatarSm = 36 -ZXSize.avatarMd = 64 -ZXSize.avatarLg = 80 - -// 其他 -ZXSize.quickActionH = 72 // 快捷操作高度 -ZXSize.inputH = 44 // 输入框高度 -ZXSize.progressH = 5 // 进度条高度 -ZXSize.scoreBox = 36 // 分数方块 -ZXSize.weakBox = 40 // 薄弱点分数方块 -ZXSize.topBar = 3 // 顶部装饰条 -ZXSize.searchIconBtn = 36 // 搜索图标按钮 -``` - ---- - -## 六、字体层级 - -```swift -// 使用方式: .font(.system(size: ZXFont.xxx.size, weight: ZXFont.xxx.weight)) - -titleLarge // 22pt, heavy, -0.5 → 页面主标题 -titleMedium // 20pt, heavy, -0.4 → 二级标题 -sectionTitle // 15pt, bold → 区域标题 -subsectionTitle // 14pt, bold → 子标题 -body // 13pt, semibold, 1.4 → 正文 -bodySmall // 12pt, medium → 辅助信息 -caption // 10pt, bold → 标签加粗 -captionSmall // 10pt, regular → 标签常规 -labelXs // 9pt, regular → 最小标签 -score // 12pt, heavy → 分数 -scoreLarge // 22pt, heavy, 1 → 大分数 -date // 12pt, medium → 日期 -description // 12pt, regular, 0.4 → 描述文字 -``` - -**实际页面中常用的内联声明**(可直接使用,也可用 ZXFont 引用): -- 页面大标题:`.font(.system(size: 22, weight: .heavy)).tracking(-0.5)` `.foregroundColor(.zxF0)` -- 区域标题:`.font(.system(size: 15, weight: .bold)).foregroundColor(.zxF0)` -- 卡片标题:`.font(.system(size: 13, weight: .semibold)).foregroundColor(.zxF0)` -- 辅助文字:`.font(.system(size: 12)).foregroundColor(.zxF04)` -- 标签文字:`.font(.system(size: 10, weight: .semibold))` -- 大数值:`.font(.system(size: 26, weight: .black))` - ---- - -## 七、共享组件目录 - -以下组件散落在各页面文件中,新页面应直接复用,禁止重复实现。 - -### 7.1 导航/布局 - -**ZXTabBar**(`ContentView.swift:58`) -5 个 tab(AI / 知识库 / 学习 / 分析 / 我的),选中态紫色高亮 + 圆形背景扩散。 -```swift -ZXTabBar(active: $selectedTab) -``` - -**ZXBackHeader**(`DailyThinkingPage.swift:52`) -子页面顶部返回栏,含标题、副标题、可选的右侧按钮。 -```swift -ZXBackHeader(title: "标题", subtitle: "副标题") { trailingView } -ZXBackHeader(title: "标题", subtitle: nil, onBack: customBackAction) { ... } -``` - -### 7.2 按钮 - -**ZXIconBtn**(`ContentView.swift:100`) -标准 36pt 圆形图标按钮,可切换品牌渐变样式。 -```swift -ZXIconBtn(icon: "bell", size: 36) { action } -ZXIconBtn(icon: "plus", size: 36, branded: true) { action } // 品牌渐变底 -``` - -**ZXOutlineBtn**(`DailyThinkingPage.swift:167`) -44pt 高描边文字按钮。 -```swift -ZXOutlineBtn(text: "深入提问") -``` - -### 7.3 列表/卡片行 - -**ZXCardRow**(`LibrarySubpages.swift:40`) -带 emoji 图标、标题、描述、状态标签的标准列表行。 -```swift -ZXCardRow(emoji: "📝", title: "标题", desc: "描述", status: "已掌握", c: .zxGreen) -``` - -**ZXImportOption**(`LibrarySubpages.swift:93`) -带大图标 + 标题描述的导入选项行。 - -**ZXProfileMenuRow**(`ProfileView.swift:58`) -Profile 页菜单行,emoji + 标题 + 描述 + 箭头。 - -**ReviewTaskRow**(`ReviewPlanView.swift:82`) -复习任务行,含完成勾选 + 复习类型标签 + 播放按钮。 - -**ZXAIInteractionRow**(`AIHomeView.swift:138`) -AI 互动记录行,含标签 + 时间 + 分数。 - -### 7.4 数据展示 - -**ZXScoreBox**(`ContentView.swift:50`) -36pt 方形分数格。 -```swift -ZXScoreBox(score: 82, bg: .zxGreenBG(0.15), fg: .zxGreen) -``` - -**ZXStatBadge**(`AnalysisHomeView.swift:74`) -统计徽章,图标 + 数值 + 标签 + 趋势。 - -**ZXWeakRow**(`AnalysisHomeView.swift:91`) -薄弱知识点行,分数 + 标题 + 库名 + 优先级。 - -**ZXAchievementBadge**(`ProfileView.swift:61`) -成就徽章,emoji + 标签。 - -**ZXProfileStat**(`ProfileView.swift:55`) -Profile 页三栏统计数字。 - -**ZXChartView**(`AnalysisHomeView.swift:117`) -折线图(掌握度趋势)。 - -### 7.5 输入 - -**ZXAIInputBar**(`ContentView.swift:26`) -AI 对话输入栏,含 sparkles 图标 + 文本框 + 麦克风 + 发送按钮。 - -### 7.6 标签 - -**ZXChip**(`LibrarySubpages.swift:74`) -Capsule 标签,彩色文字 + 半透明底色。 - -**复习类型标签**(`ReviewTaskRow.swift:129`) -4 种:间隔重复(紫) / 费曼(accent) / 回忆(橙) / 薄弱(黄)。 - -### 7.7 卡片装饰 - -**ZXQuickAction**(`AIHomeView.swift:132`) -72pt 高快捷操作按钮,emoji + 文字。 - -**ZLibraryCard**(`LibraryHomeView.swift:32`) -知识库卡片,顶部渐变色条 + emoji + 名称 + 进度 + 标签。 - -### 7.8 状态组件 - -**ZXLoadingView**(`Shared/Components/ZXLoadingView.swift`) -全屏加载指示器,紫色 ProgressView + "加载中…" 文字。 - -**ZXShimmerList**(`Shared/Components/ZXLoadingView.swift`) -骨架屏列表,传入 `count` 生成占位卡片。 - -**ZXErrorView**(`Shared/Components/ZXErrorView.swift`) -全屏错误状态,黄色三角图标 + 消息 + 可选重试按钮。 - -**ZXErrorBanner**(`Shared/Components/ZXErrorView.swift`) -内联错误横幅,黄色背景 + 消息 + 关闭按钮。 - -**ZXEmptyView**(`Shared/Components/ZXEmptyView.swift`) -空状态视图,支持图标 + 标题 + 副标题 + 可选操作按钮。 - -### 7.9 其他 - -**FeatureRow**(`Shared/Components/FeatureRow.swift`) -Welcome 页功能介绍行。 - ---- - -## 八、页面布局模式 - -### 8.1 主 Tab 页(有底部 TabBar) - -```swift -struct SomeHomeView: View { - var body: some View { - ZStack { - ZXGradient.page.ignoresSafeArea() // ① 背景 - - VStack(spacing: 0) { - // ② Header - HStack { - VStack(alignment: .leading, spacing: 2) { - Text("副标题").font(.system(size: 12)).foregroundColor(.zxF04) - Text("主标题").font(.system(size: 22, weight: .heavy)) - .foregroundColor(.zxF0).tracking(-0.5) - } - Spacer() - // 右侧按钮/状态 - } - .padding(.horizontal, 20) - .padding(.top, ZXSpacing.statusBarH + 16) - .padding(.bottom, 12) - - // ③ 可滚动内容 - ScrollView { - VStack(spacing: 16) { - // 卡片/列表... - } - .padding(.horizontal, 20) - .padding(.bottom, 120) // 为 TabBar 留空间 - } - .scrollIndicators(.hidden) - } - } - .navigationBarHidden(true) - .preferredColorScheme(.dark) - } -} -``` - -### 8.2 子页面(有返回按钮,无 TabBar) - -```swift -struct SomeDetailPage: View { - var body: some View { - ZStack { - Color.zxBg0.ignoresSafeArea() // 纯色(非渐变) - - VStack(spacing: 0) { - ZXBackHeader(title: "标题", subtitle: "副标题") { - // 右侧按钮 - } - - ScrollView { - VStack(spacing: 16) { - // 内容 - } - .padding(.horizontal, 20) - .padding(.bottom, 80) - } - .scrollIndicators(.hidden) - } - } - .navigationBarHidden(true) - } -} -``` - -### 8.3 卡片通用写法 - -```swift -VStack(alignment: .leading, spacing: 12) { - // 卡片内容 -} -.padding(16) -.background(Color.zxFill003) // 底色 -.overlay( - RoundedRectangle(cornerRadius: 16) - .stroke(Color.zxBorder006, lineWidth: 1) // 边框 -) -.clipShape(RoundedRectangle(cornerRadius: 16)) // 裁剪 -``` - -渐变背景卡片把 `.background(Color.zxFill003)` 换成对应的 `ZXGradient.xxx`。 - -### 8.4 输入框通用写法 - -```swift -TextField("占位文字", text: $text) - .font(.system(size: 14)) - .tint(.zxPurple) - .padding(.horizontal, 16) - .frame(height: 52) - .background(Color.zxFill004) - .clipShape(RoundedRectangle(cornerRadius: 14)) - .overlay( - RoundedRectangle(cornerRadius: 14) - .stroke(Color.zxBorder008, lineWidth: 1) - ) -``` - -### 8.5 状态标签(Capsule 形) - -```swift -Text("标签文字") - .font(.system(size: 10, weight: .semibold)) - .foregroundColor(semanticColor) - .padding(.horizontal, 8) - .padding(.vertical, 2) - .background(semanticColor.opacity(0.12)) - .clipShape(Capsule()) -``` - ---- - -## 九、设计决策与约束 - -### 9.1 全局 - -- 强制深色模式:`.preferredColorScheme(.dark)` -- 所有页面 `navigationBarHidden(true)`,使用自建导航 -- 禁止使用系统默认蓝色、默认圆角、默认间距 - -### 9.2 颜色 - -- 文字统一用 `#F0F0FF` 加透明度,不要用 `Color.white` -- 不要直接写 `Color(hex: ...)` 内联,优先用现有 token;确需新色值先加 token -- 语义色不要混用——紫色是品牌/AI,橙色是热度/连续,绿色是完成,黄色是警告 - -### 9.3 字体 - -- 不使用系统默认字体大小(如 `.title`、`.headline`),一律显式 `.system(size:weight:)` -- 标题统一 tracking 负值(`-0.5` 或 `-0.4`) -- 中文内容避免使用 `.bold` 以下的极细字体 - -### 9.4 布局 - -- 页面水平留白统一 `20pt` -- 卡片间距 `12–20pt` -- 内容区底部留白至少 `80pt`(子页面)或 `120pt`(有 TabBar) -- 所有 ScrollView 隐藏指示器:`.scrollIndicators(.hidden)` - -### 9.5 组件 - -- 优先复用第七节的共享组件,不要内联重复 UI -- 新组件如通用性足够,应抽到 `Shared/` 目录 - ---- - -## 十、文件引用索引 - -| 规范项 | 定义文件 | -|---|---| -| 颜色/渐变/圆角/间距/尺寸/字体 | `Core/DesignSystem/DesignTokens.swift` | -| ZXTabBar | `Shared/Components/ZXTabBar.swift` | -| ZXIconBtn | `Shared/Components/ZXIconBtn.swift` | -| ZXScoreBox | `Shared/Components/ZXScoreBox.swift` | -| ZXAIInputBar | `Shared/Components/ZXAIInputBar.swift` | -| ZXBackHeader | `Shared/Components/ZXBackHeader.swift` | -| ZXOutlineBtn | `Shared/Components/ZXOutlineBtn.swift` | -| ZXQuickAction | `Shared/Components/ZXQuickAction.swift` | -| ZXAIInteractionRow | `Shared/Components/ZXAIInteractionRow.swift` | -| ZXCardRow | `Shared/Components/ZXCardRow.swift` | -| ZXChip | `Shared/Components/ZXChip.swift` | -| ZXImportOption | `Shared/Components/ZXImportOption.swift` | -| ZXWeakRow | `Shared/Components/ZXWeakRow.swift` | -| ZXStatBadge | `Shared/Components/ZXStatBadge.swift` | -| ZXProfileMenuRow | `Shared/Components/ZXProfileMenuRow.swift` | -| ZXProfileStat | `Shared/Components/ZXProfileStat.swift` | -| ZXAchievementBadge | `Shared/Components/ZXAchievementBadge.swift` | -| ZXChartView | `Shared/Components/ZXChartView.swift` | -| ZXSTaskRow + ZXSTask | `Shared/Components/ZXSTaskRow.swift` | -| FeatureRow | `Shared/Components/FeatureRow.swift` | -| ReviewTaskRow | `Shared/Components/ReviewTaskRow.swift` | -| ZXLoadingView / ZXShimmerList | `Shared/Components/ZXLoadingView.swift` | -| ZXErrorView / ZXErrorBanner | `Shared/Components/ZXErrorView.swift` | -| ZXEmptyView | `Shared/Components/ZXEmptyView.swift` | -| ZXLibraryCard | `Features/Library/LibraryHomeView.swift` | -| AIHomeView | `Features/AI/AIHomeView.swift` | -| DailyThinkingPage | `Features/AI/DailyThinkingPage.swift` | -| RecallTestPage | `Features/AI/RecallTestPage.swift` | -| WeakPointsPage | `Features/AI/WeakPointsPage.swift` | -| AIFeedbackPageView | `Features/AI/AIFeedbackPage.swift` | -| AIChatPage | `Features/AI/AIChatPage.swift` | -| LibraryHomeView | `Features/Library/LibraryHomeView.swift` | -| CreateLibraryPage | `Features/Library/CreateLibraryPage.swift` | -| LibraryDetailPage | `Features/Library/LibraryDetailPage.swift` | -| AddKnowledgePage | `Features/Library/AddKnowledgePage.swift` | -| KnowledgeDetailPage | `Features/Library/KnowledgeDetailPage.swift` | -| ImportPage | `Features/Library/ImportPage.swift` | -| EditKnowledgePage | `Features/Library/EditKnowledgePage.swift` | -| AnalysisHomeView | `Features/Analysis/AnalysisHomeView.swift` | -| ProfileView | `Features/Profile/ProfileView.swift` | -| ReviewPlanView | `Features/Review/ReviewPlanView.swift` | -| StudyHomeView | `Features/Study/StudyHomeView.swift` | -| SplashPage | `Features/Onboarding/SplashPage.swift` | -| WelcomePage | `Features/Onboarding/WelcomePage.swift` | -| OnboardingPage | `Features/Onboarding/OnboardingPage.swift` | -| GoalSetupPage | `Features/Onboarding/GoalSetupPage.swift` | -| AppRootView / OnboardingFlowView | `AIStudyAppApp.swift` | -| LoginView | `Features/Auth/Views/LoginView.swift` | diff --git a/AIStudyApp/docs/缺失项与待补全方向.md b/AIStudyApp/docs/缺失项与待补全方向.md deleted file mode 100644 index 8d56c01..0000000 --- a/AIStudyApp/docs/缺失项与待补全方向.md +++ /dev/null @@ -1,1042 +0,0 @@ -# 缺失项与待补全方向 - -> 基于 v0.1 创业计划文档与当前 iOS 代码对比分析 -> 整理时间:2026-05-10 - -本文档系统性列出知习 iOS App 当前在架构、页面、功能、设计等方面的缺失项,并给出优先级建议。 - ---- - -## 一、架构层缺失 - -### 1.1 MVVM 分层 - -**现状**:全部代码写在 SwiftUI View 中,无任何 ViewModel/ObservableObject/@Published。grep 搜索 ViewModel、ObservableObject、@Published 均为零结果。 - -**缺失**: -- 无 ViewModel 层,业务逻辑、状态管理、数据转换全部堆在 View 里 -- 无 Model 层,数据结构通过 View 内的局部 struct 或硬编码数据隐式定义 -- 代码不可测试,无法单独验证业务逻辑 - -**计划要求**(`官网与技术基础.md` 第 5.3 节): -``` -AIStudyApp/ -├── Features/ -│ ├── Onboarding/ -│ │ ├── Views/ ← 当前有,但无 ViewModel/Model 子目录 -│ │ ├── ViewModels/ ← 缺失 -│ │ └── Models/ ← 缺失 -``` - -### 1.2 Service 层 - -**现状**:无任何 Service 类,AI 分析、学习记录、用户管理等概念没有对应的服务抽象。 - -**缺失**: -| Service | 职责 | 设计文档 | -|---------|------|----------| -| AuthService | Apple 登录、Token 管理、会话维护 | `docs/AI对话.md`(详细设计) | -| LearningService | 学习记录 CRUD、进度追踪 | — | -| AIService | AI 分析请求代理、结果解析 | — | -| ReviewService | 复习任务生成、调度 | — | -| KnowledgeService | 知识库/路径/课程查询 | — | -| FeedbackService | 用户反馈提交 | — | - -**Auth 模块已有详细文件清单**(来自 `docs/AI对话.md`): -``` -Features/Auth/Views/LoginView.swift -Features/Auth/ViewModels/LoginViewModel.swift - -Core/Services/AuthService.swift -Core/Services/AuthServiceProtocol.swift - -Core/Storage/KeychainStore.swift -Core/Storage/TokenStore.swift - -App/AppSession.swift - -Core/Models/AuthModels.swift -Core/Models/User.swift -``` - -### 1.3 Repository 层 - -**现状**:零数据持久化,所有"数据"均为 View 中硬编码的 mock。 - -**缺失**: -- 无数据访问抽象(未来可能切换 CoreData → API,需要 Repository 隔离) -- 无本地缓存层 -- 无网络数据源层 - -### 1.4 网络层 - -**现状**:无任何网络请求代码,无 APIClient,无 URLSession 调用。 - -**缺失**: -- APIClient(封装 URLSession,注入 baseURL、header、token) -- APIEndpoint(枚举化 API 路径,统一请求构建) -- APIError(统一错误模型和处理) -- 请求/响应拦截器(日志、token 刷新) -- Mock 层(本地开发和 UI 预览用) - -### 1.5 依赖注入 - -**现状**:无任何 DI 模式,Service 和 ViewModel 尚未创建,暂时不存在注入问题。但需要在架构搭建时建立模式。 - -**建议**:初期使用构造函数注入 + `@EnvironmentObject`,避免引入第三方 DI 框架。 - ---- - -## 二、核心能力缺失 - -### 2.1 Sign in with Apple(已有详细设计文档) - -**现状**:`LoginPage` 有 UI(手机号/邮箱/微信/Apple 入口),但 `AIStudyAppApp` 仅用 `@AppStorage("hasCompletedOnboarding")` 控制是否进入主界面,无实际认证。 - -**计划要求**:第一版登录方式仅为 Sign in with Apple(`Demo与MVP.md` 第 5.2 节)。 - -**详细设计方案**见 `docs/AI对话.md`,核心结论: - -**登录页只保留一个入口**: -``` -Sign in with Apple -``` - -**删除的入口**:手机号登录、邮箱登录、微信登录、验证码登录 - -**"跳过"按钮处理**: -```swift -#if DEBUG -Button("跳过,进入演示模式") { ... } -#endif -``` -正式环境不展示跳过入口,避免后续匿名用户迁移问题。 - -**登录流程设计**: -``` -App 启动 - ↓ -AppSession 检查 Keychain 是否有 refreshToken - ↓ -有 token → 调用 /auth/refresh 或 /users/me - ↓ -成功 → 进入主界面 -失败 → 清空 token,进入登录页 - ↓ -无 token → 进入登录页 - ↓ -用户点击 Sign in with Apple - ↓ -获取 identityToken / authorizationCode / userIdentifier - ↓ -POST /api/auth/apple - ↓ -后端返回 accessToken / refreshToken / user - ↓ -token 存入 Keychain(不要 UserDefaults) - ↓ -判断 user.onboardingCompleted - ↓ -未完成 → 引导/目标设置 -已完成 → 主界面 -``` - -**登录相关新增文件**: -``` -Features/Auth/Views/LoginView.swift # 仅 Apple 登录按钮 -Features/Auth/ViewModels/LoginViewModel.swift # @MainActor, @Published isLoading/errorMessage - -Core/Services/AuthService.swift -Core/Services/AuthServiceProtocol.swift - -Core/Storage/KeychainStore.swift -Core/Storage/TokenStore.swift - -App/AppSession.swift # 全局登录状态管理 - -Core/Models/AuthModels.swift # AppleLoginRequest, AuthResponse -Core/Models/User.swift -``` - -**API Contract(Auth)**: -```swift -// 请求 -struct AppleLoginRequest: Encodable { - let identityToken: String - let authorizationCode: String? - let userIdentifier: String - let fullName: AppleFullName? - let email: String? -} - -// 响应 -struct AuthResponse: Decodable { - let accessToken: String - let refreshToken: String - let expiresIn: Int - let user: User -} -``` - -**关键约束**: -- 不再用 `@AppStorage("hasCompletedOnboarding")` 单独决定是否进入主界面 -- 登录状态必须由 `AppSession` + Keychain token 决定 -- Token 不存 UserDefaults -- View 里不写网络请求,不直接处理 Apple 登录细节 - -### 2.2 后端 API 对接 - -**现状**:所有页面为静态 UI,无任何网络请求。 - -**计划定义的 P0 API**: -- `POST /ai/analyze-learning-input` — AI 分析用户学习输入 -- `POST /ai/chat` — AI 对话 -- 用户/知识库/学习记录/反馈 CRUD - -### 2.3 真实 AI 集成 - -**现状**:AI 相关页面全为静态文本。 - -**需对接**: -- 后端 AI Provider 抽象层(MiniMax/DeepSeek/OpenAI 等) -- 结构化 JSON 输出解析 -- AI 分析结果展示(掌握度评分、优缺点、建议) -- AI 对话流式响应 - -### 2.4 本地数据持久化 - -**现状**:零持久化实现。 - -**需实现**: -- UserDefaults / @AppStorage(简单偏好) -- Keychain(Token、敏感信息) -- 后续可考虑 CoreData 或 SwiftData(学习记录离线缓存) - -### 2.5 多语言本地化 - -**现状**:所有文案硬编码在 View 中,无 Localizable.xcstrings 文件。 - -**计划要求**(`Demo与MVP.md` 第 6 节): -- 默认简体中文 -- 预留英文 -- App UI 文案使用本地化资源 - -**需实现**: -- 创建 `Localizable.xcstrings` -- 将所有硬编码文案迁移为 `LocalizedStringKey` -- 支持语言切换 - -### 2.6 错误/加载/空状态处理 - -**现状**:无任何错误处理、加载态、空状态 UI。 - -**至少需要**: -- 网络请求 loading 指示器 -- 网络错误提示和重试按钮 -- AI 分析中的等待状态 -- 列表空状态(如知识库为空时的引导) -- 登录失败错误提示 - ---- - -## 三、页面层面差距 - -### 3.1 与计划页面对比 - -| 计划页面 | 计划优先级 | 当前状态 | 说明 | -|----------|-----------|---------|------| -| 启动页/欢迎页 | P1 | ✅ 已实现 | SplashPage + WelcomePage | -| 登录页 | P0 | ✅ 已实现 | 新 LoginView 替换旧 LoginPage,仅 Apple 登录 | -| 语言与偏好页 | P1 | ❌ 未实现 | 无页面 | -| 学习方向选择页 | P0 | ⚠️ 部分实现 | GoalSetupPage 有目标选择,但非学习方向选择 | -| 学习路径页 | P0 | ✅ 已实现 | LibraryDetailPage | -| 今日学习任务页 | P0 | ✅ 已实现 | StudyHomeView | -| 内容阅读页 | P0 | ✅ 已实现 | KnowledgeDetailPage | -| 主动回忆/笔记输入页 | P0 | ✅ 已实现 | DailyThinkingPage + RecallTestPage | -| AI 分析结果页 | P0 | ✅ 已实现 | AIFeedbackPage | -| AI 对话页 | P0 | ✅ 已实现 | AIChatPage | -| 复习计划页 | P0 | ✅ 已实现 | ReviewPlanView,含今天/明天/本周分组 + 复习类型标签 | -| 学习进度页 | P1 | ✅ 已实现 | AnalysisHomeView | -| 设置页 | P1 | ⚠️ 部分实现 | ProfileView 有设置菜单,但功能入口为空 | -| 反馈页 | P1 | ✅ 已实现 | FeedbackView + FeedbackViewModel,分类选择 + 提交确认 | - -### 3.2 复习计划页(P0 ✅) - -**计划描述**:系统生成复习任务,用户查看待复习内容,按推荐时间安排学习。 - -**当前**:已实现 `Features/Review/ReviewPlanView.swift`,含今天/明天/本周三组、复习类型标签(间隔重复/费曼/回忆/薄弱)、完成勾选、播放按钮。数据层使用 `ReviewTask` Model + mock 数据。 - -**待对接**:接入 ReviewService 后端数据。 - -### 3.3 反馈页(P1 ✅) - -**计划描述**:App 内反馈入口,让内测用户提交问题和建议。 - -**当前**:已实现 `Features/Feedback/FeedbackView.swift` + `FeedbackViewModel.swift`,含 4 类反馈分类(Bug/功能建议/内容问题/其他)的图标选择器、文本描述输入、提交通知。入口位于 ProfileView 菜单末项。 - -**待对接**:接入后端 `/feedback` API(FeedbackService)。 - -### 3.4 等待名单入口 - -**计划**:官网 `/waitlist` 页面收集用户,App 内也需要引导用户加入等待名单/申请内测。 - -**需考虑**:是否在 App 内嵌等待名单入口(如 Welcome 页或设置页)。 - ---- - -## 四、设计与交互差距 - -### 4.1 Tab 结构调整 - -**计划设计**:4 个 Tab — 学习 | 知识库 | AI助手 | 我的 - -**当前实现**:5 个 Tab — AI | 知识库 | 学习 | 分析 | 我的 - -**差异分析**: -- 当前把"学习"和"分析"拆成了两个独立 Tab -- 计划把"AI助手"独立为一个 Tab,当前 AI 已是独立 Tab -- "分析"在计划中属于"学习"Tab 下的子页面,不需要顶层 Tab - -**建议**(两种方案): -- **方案 A**:完全对齐计划 → 合并学习和分析为一个 Tab,保持 4 Tab -- **方案 B**:保留 5 Tab 结构 → 更新计划文档,论证"分析"独立为 Tab 的合理性(学习数据可视化、学习进度监控是独立价值) - -### 4.2 登录流程简化(已有详细设计) - -**计划要求**:仅 Sign in with Apple,不做手机号/邮箱/微信登录。 - -**当前 UI**:包含 4 种登录方式入口。 - -**最终方案**(详见 `docs/AI对话.md`): -- 登录页只保留 Sign in with Apple 一个按钮 -- 删除手机号、邮箱、微信、验证码登录 -- 跳过按钮仅限 `#if DEBUG`,Release 不展示 -- 登录页文案极简:品牌 + 一句话价值主张 + Apple 登录按钮 + 协议入口 - -### 4.3 浅色/深色模式双主题(P1 新增)✅ 已完成 - -**实现方式**: - -| 改造项 | 状态 | -|--------|------| -| `Color(light:dark:)` 自适应 helper | ✅ `DesignTokens.swift` 新增基于 `UITraitCollection.userInterfaceStyle` 的动态颜色 | -| 28 个颜色 token 双主题化 | ✅ 背景(4) + 文字(9) + 边框(5) + 填充(6) + 品牌色/彩色半透不变 | -| 渐变自适应 | ✅ `page`/`splash` 渐变改用自适应 Color token | -| 硬编码色值替换 | ✅ 13 处内联 `Color(hex:)` 替换为自适应 token | -| ColorSchemeManager | ✅ `Core/Appearance/ColorSchemeManager.swift`,@AppStorage 持久化,支持系统/浅色/深色 | -| 移除强制深色 | ✅ 移除 4 处 `.preferredColorScheme(.dark)` | -| 设置页切换入口 | ✅ ProfileView 外观行改为可点击,confirmationDialog 三选一 | - -**文件变更**: -- 新增:`Core/Appearance/ColorSchemeManager.swift` -- 修改:`DesignTokens.swift`(颜色全量自适应 + 渐变) -- 修改:`AIStudyAppApp.swift`(根视图用 manager 控制 scheme) -- 修改:`ContentView.swift`、`LoginView.swift`(移除强制暗黑) -- 修改:`ProfileView.swift`(外观切换入口) -- 修改:`SplashPage.swift`、`ZXTabBar.swift`、`ZXAIInteractionRow.swift`、`ZXChartView.swift`、`AIFeedbackPage.swift`、`WelcomePage.swift`、`OnboardingPage.swift`、`GoalSetupPage.swift`、`ZXSTaskRow.swift`、`ZXIconBtn.swift`(内联色值→token) - -### 4.4 语言系统(P1 新增) - -**现状**:所有文案硬编码中文在 SwiftUI View 中,无 Localizable.strings。 - -**要求**:先只支持中文,但搭建好本地化基础设施,后续加语言时只需加翻译文件。 - -**需实现**: - -| 步骤 | 说明 | -|------|------| -| 创建 `Localizable.strings` (Base) | 中文作为 Base 语言,不设 `zh-Hans` | -| 封装 `ZXLocalized` 辅助 | `String(localized:)` + `Text("key")` 的 SwiftUI 原生方式 | -| 迁移硬编码文案 | 逐文件将文案替换为 LocalizedStringKey | -| 设置页语言入口 | 预留语言切换 UI,当前仅显示"中文" | - -### 4.5 无障碍 - -**现状**:未考虑 VoiceOver、Dynamic Type、高对比度等无障碍需求。 - -**至少需做**: -- 关键按钮添加 `.accessibilityLabel` -- 确保 Dynamic Type 下布局不破碎 -- 重点页面 VoiceOver 测试 - -### 4.6 样式规范 - -已于 `docs/样式规范.md` 中梳理完整的样式规范文档,涵盖: -- 色彩系统(背景/文字/品牌语义色/边框/填充) -- 渐变体系(页面、品牌、卡片、进度条、CTA 等 11 组渐变) -- 圆角、间距、尺寸 token -- 字体层级(12 级定义) -- 共享组件目录(20+ 组件,含导航、按钮、卡片行、数据展示、输入、标签等) -- 页面布局模式(主 Tab 页、子页面、卡片、输入框、状态标签的标准写法) -- 设计决策与约束 - -**后续新页面必须遵循 `docs/样式规范.md`**,复用已有组件和 token,禁止随意使用内联颜色/间距/字体。 - -### 4.7 动效 - -**计划要求**(`官网与技术基础.md` 第 6.3 节): -- P0:页面过渡、按钮反馈、加载状态、AI 分析中状态、学习完成反馈 -- P1:今日任务卡片动效、进度条更新、AI 结果分块出现 - -**当前**:仅有基础 SwiftUI 隐式动画(withAnimation),未实现任何计划中的动效。 - ---- - -## 五、数据层缺失 - -### 5.1 Model 定义 - -**现状**:所有数据通过 View 内局部变量或硬编码定义,无独立 Model 文件。 - -**计划中定义的核心实体**(`Demo与MVP.md`): - -``` -User -├── id, appleUserId, displayName, email -├── preferredLanguage, createdAt, lastLoginAt, status - -KnowledgeBase -├── id, title, description, language, targetUser -├── createdAt, updatedAt - -LearningPath -├── id, knowledgeBaseId, title, description -├── estimatedDays, order - -Lesson -├── id, pathId, title, content, objectives -├── keyPoints, recallQuestions, practicePrompt -├── order, estimatedMinutes - -LearningSession -├── id, userId, lessonId -├── startedAt, endedAt, userInput -├── aiAnalysis, masteryScore, weakPoints -├── nextSuggestion, reviewAt - -AIAnalysis -├── id, userId, sessionId -├── inputText, outputJson, masteryScore -├── weakPoints, suggestions -├── modelName, createdAt, costEstimate - -ReviewTask -├── id, userId, lessonId, sourceSessionId -├── reviewType, scheduledAt, completedAt, status - -Feedback -UserLearningProfile -``` - -**需实现**:在 `Features/*/Models/` 下创建对应的 Swift struct(需 Codable、Identifiable)。 - -### 5.2 API Contract - -**现状**:无 API 类型定义。 - -**建议**:参考计划中定义的 JSON 结构,先创建 Swift Model,再定义 API 请求/响应类型(Request/Response struct),实现前后端类型同构。 - -### 5.3 数据流规范 - -**现状**:View 直接持有 @State,无数据流管理。 - -**建议**: -- ViewModel 持有 @Published 状态 -- ViewModel 通过 Service 获取数据 -- Service 通过 Repository 访问数据源 -- View 通过 @StateObject / @ObservedObject 绑定 ViewModel - ---- - -## 六、工程化缺失 - -### 6.1 大文件拆分 ✅ - -**已完成**: - -| 原文件 | 拆分结果 | -|--------|----------| -| `AIStudyAppApp.swift` (~190行) | 保留 App/Root/OnboardingFlowView,页面移入 `Features/Onboarding/` | -| `DailyThinkingPage.swift` (~200行) | 拆为 5 个文件(DailyThinking / RecallTest / WeakPoints / AIFeedback / AIChat) | -| `LibrarySubpages.swift` (~112行) | 已删除,拆为 6 个独立页面文件 | - -### 6.2 共享组件管理 ✅ - -**已完成**:20 个共享组件集中到 `Shared/Components/`,原文件中的定义已移除。 - -``` -Shared/Components/ -├── ZXTabBar.swift ├── ZXBackHeader.swift -├── ZXIconBtn.swift ├── ZXScoreBox.swift -├── ZXAIInputBar.swift ├── ZXOutlineBtn.swift -├── ZXQuickAction.swift ├── ZXAIInteractionRow.swift -├── ZXCardRow.swift ├── ZXChip.swift -├── ZXImportOption.swift ├── ZXWeakRow.swift -├── ZXStatBadge.swift ├── ZXProfileStat.swift -├── ZXProfileMenuRow.swift ├── ZXAchievementBadge.swift -├── ZXChartView.swift ├── ZXSTaskRow.swift -├── FeatureRow.swift ├── ReviewTaskRow.swift -├── ZXLoadingView.swift ├── ZXErrorView.swift -└── ZXEmptyView.swift -``` - -### 6.3 测试 - -**现状**:无任何测试代码。 - -**至少需要**: -- ViewModel 单元测试(当 ViewModel 创建后) -- Service 层单元测试(Mock Repository) -- 关键 UI 流程的 Snapshot 测试 - -### 6.4 CI/CD - -**现状**:无。 - -**建议**(后续): -- GitHub Actions / Xcode Cloud 自动构建 -- TestFlight 自动分发 - -### 6.5 崩溃监控与埋点 - -**现状**:无。 - -**建议**:接入 Firebase Crashlytics 或类似服务,至少在 TestFlight 阶段要有崩溃收集能力。 - ---- - -## 七、优先级建议 - -### P0 — 必须在接后端前完成 - -| 步骤 | 项目 | 理由 | 设计文档 | -|------|------|------|----------| -| ① | 创建 Auth Model(AuthModels + User) | 所有后续步骤的数据基础 | 第十章 步骤 1 ✅ | -| ② | 实现 Keychain 存储层 | Token 安全存储是登录的前提 | 第十章 步骤 2 ✅ | -| ③ | 搭建网络层最小实现(APIClient) | 所有后端交互的唯一通道 | 第十章 步骤 3 ✅ | -| ④ | 实现 AuthService(Apple 登录 + 后端调用) | 用户身份是学习记录的前提 | `docs/AI对话.md`、第十章 步骤 4 ✅ | -| ⑤ | 实现 AppSession(全局登录状态) | 统一的登录态管理 | 第十章 步骤 5 ✅ | -| ⑥ | 实现 LoginView + LoginViewModel | 替换当前过度实现的登录页 | `docs/AI对话.md`、第十章 步骤 6 ✅ | -| ⑦ | 改造 App 入口启动逻辑 | Token 分流替换 @AppStorage | 第十章 步骤 7 ✅ | -| — | 创建 Model 层(其余数据实体) | 是 Service/ViewModel/API 的基础 | 本文档 5.1 节 ✅ | -| — | 实现复习计划独立页 | 计划标记 P0 | ✅ | -| — | 拆分大文件 + 集中共享组件 | 降低后续修改的认知负担 | 本文档 6.1/6.2 节 ✅ | -| — | 添加加载/错误/空状态处理 | 真机使用的基本体验保障 | `Shared/Components/` (ZXLoadingView, ZXErrorView, ZXEmptyView) ✅ | - -### P1 — 与后端对接同步推进 - -| 优先级 | 项目 | 理由 | -|--------|------|------| -| P1 | 浅色/深色模式双主题 | 覆盖所有页面和 DesignTokens,工作量较大 ✅ | -| P1 | 语言系统搭建(中文 Base) | 先建基础设施,后续加语言不返工 ✅ | -| P1 | 搭建 ViewModel 层(逐步迁移) | 架构分层,但不阻塞功能开发 ✅ | -| P1 | 搭建 Service 层 | 随 API 对接自然建立 ✅ | -| P1 | 实现反馈页 | TestFlight 内测必须 ✅ | -| P1 | 实现设置页完整功能 | 外观切换、语言入口、复习提醒等 ✅ | - -### P2 — App Store 前完成 - -| 优先级 | 项目 | 理由 | -|--------|------|------| -| P2 | Repository 层 | 当需要本地缓存 + 网络切换时再做 ✅ | -| P2 | 动效补充 | 体验优化,不阻塞功能 ✅ | -| P2 | 无障碍适配 | App Store 审核加分项 ✅ | -| P2 | 测试 | 用户量增长后需要 ✅ | -| P2 | Tab 结构调整决策 | 需要更多用户反馈来决策 ✅ | - -### Tab 结构分析 - -**当前 5-Tab 结构**: - -| Tab | 页面 | 核心功能 | -|-----|------|----------| -| AI | AIHomeView | AI 对话入口 + 每日思考 + 薄弱点 | -| 知识库 | LibraryHomeView | 知识库浏览 + 导入 + 搜索 | -| 学习 | StudyHomeView | 今日任务 + 进度 + 每周活跃 | -| 分析 | AnalysisHomeView | 学习时长 + 掌握度 + 雷达图 | -| 我的 | ProfileView | 个人信息 + 设置 + 成就 | - -**问题诊断**: -1. **AI 与学习边界模糊** — AI 对话产生学习记录,但学习任务在独立 Tab,用户需要在两个 Tab 间切换 -2. **分析 Tab 内容单薄** — 纯展示仪表盘,无交互深度,与"学习"Tab 的进度卡片有重叠 -3. **知识库入口过重** — 知识库本质是学习的前置步骤,独立 Tab 使其脱离学习流程 - -**可选方案**: - -| 方案 | 结构 | 优点 | 缺点 | -|------|------|------|------| -| A: 保持现状 | 5 Tab 不变 | 无改动成本 | 上述问题持续 | -| B: 合并 AI+学习 | 4 Tab(学习/AI、知识库、分析、我的) | AI 与学习一体化 | 需重设计学习首页 | -| C: 合并分析入学习 | 4 Tab(AI、知识库、学习+分析、我的) | 分析数据有上下文 | 学习页信息密度增加 | -| D: 精简 3 Tab | 3 Tab(学习、知识库、我的) | 最简洁,AI 内嵌学习 | 分析页降级为次级入口 | - -**建议**:MVP 阶段保持方案 A,收集用户反馈后优先尝试方案 C(分析并入学习)。触发条件:分析 Tab 的周活跃用户 < 20%。 - ---- - -## 八、总结 - -当前 iOS 项目完成了 UI 层的全量搭建(21 页),但缺少"能让产品真正运转"的架构底座和数据能力。核心矛盾是: - -> UI 超前,架构滞后。页面能点,但无数据、无认证、无 AI、无服务。 - -### 当前进度(2026-05-10) - -**P0 — 全部完成 ✅**: -1. ✅ Apple 登录 + Auth 体系(9 个文件) -2. ✅ Model 层(10 个数据实体) -3. ✅ 网络层最小实现(APIClient + Endpoint + Error) -4. ✅ App 入口重构(AppSession 驱动路由,替代 @AppStorage) -5. ✅ 复习计划独立页(ReviewPlanView) -6. ✅ 大文件拆分(3 个大文件拆为 15+ 个独立文件) -7. ✅ 共享组件集中管理(`Shared/Components/` 下 20+ 个组件) -8. ✅ 加载/错误/空状态处理(ZXLoadingView / ZXErrorView / ZXEmptyView) - -**P1 — 部分完成**: -- ✅ 浅色/深色模式双主题(DesignTokens 自适应 + ColorSchemeManager + 移除强制暗黑) -- ✅ 语言系统搭建(中文 Base,Localizable.strings + ZXStrings + LanguageManager) -- ✅ 搭建 ViewModel 层(ReviewPlanViewModel + AIChatViewModel + StudyHomeViewModel) -- ✅ 搭建 Service 层(5 个 Service 协议 + 实现 + 20 个 APIEndpoint) -- ✅ 实现反馈页(TestFlight 内测必须) -- ✅ 设置页外观切换(ColorSchemeManager + ProfileView confirmationDialog) -- ✅ 设置页完整功能(5 个子页面 + 外观/语言切换) - -**接下来推荐顺序**: - -``` -1. 语言系统搭建(基础设施优先,避免后续返工) - ├── 创建 Localizable.strings (Base = 中文) - ├── 迁移硬编码文案到 LocalizedStringKey - └── 设置页预留语言入口(当前仅显示中文) - ↓ -2. 浅色/深色模式双主题(体验升级,需全量回归) - ├── DesignTokens 定义 light/dark 双套色值 - ├── 替换所有内联 Color(hex:) 为 token 引用 - ├── 设置页新增外观切换(跟随系统 / 浅色 / 深色) - └── 全页面浅色模式验证 - ↓ -3. 反馈页 + 设置页补全(独立页面,不依赖其他改造) - ↓ -4. ViewModel 层迁移(逐步,不阻塞功能) - ↓ -5. Service 层搭建(随 API 对接自然建立) -``` - ---- - -## 九、AI对话.md 登录方案摘要 - -> `docs/AI对话.md` 是登录模块的详细实现规范。以下为关键决策的结构化提取,便于对照实施。 - -### 9.1 登录入口决策 - -**第一版只保留**: -``` -Sign in with Apple -``` - -**删除这些入口**: -- 手机号登录 / 邮箱登录 / 微信登录 / 验证码登录 - -**"跳过"按钮**: -- `#if DEBUG` 保留,Release 不展示 -- 理由:避免匿名用户后续迁移(学习记录、AI 分析绑定用户身份) - -### 9.2 登录页内容 - -``` -知习 - -更懂你,更会学。 - -用 AI 把知识库、主动回忆和间隔复习连接起来, -从"看过"走向"真正学会"。 - -[ Sign in with Apple ] - -登录即代表你同意《用户服务协议》和《隐私政策》 -``` - -### 9.3 完整登录流程 - -``` -App 启动 - ↓ -AppSession 检查 Keychain 是否有 refreshToken - ↓ -有 token → 调用 /auth/refresh 或 /users/me - ├─ 成功 → 进入主界面 - └─ 失败 → 清空 token,进入登录页 - ↓ -无 token → 进入登录页 - ↓ -用户点击 Sign in with Apple - ↓ -ASAuthorizationController 获取: - · identityToken - · authorizationCode - · userIdentifier - · email / fullName(Apple 可能不返回) - ↓ -POST /api/auth/apple - ↓ -后端返回 { accessToken, refreshToken, expiresIn, user } - ↓ -accessToken / refreshToken 存入 Keychain - ↓ -判断 user.onboardingCompleted - ├─ false → 引导页 / 学习目标设置 - └─ true → 主界面(ContentView) -``` - -### 9.4 需要新增的 9 个文件 - -| 层 | 文件 | 职责 | -|----|------|------| -| Model | `Core/Models/AuthModels.swift` | AppleLoginRequest、AuthResponse 等 Codable struct | -| Model | `Core/Models/User.swift` | 用户实体 | -| Storage | `Core/Storage/KeychainStore.swift` | 通用 Keychain 读写封装 | -| Storage | `Core/Storage/TokenStore.swift` | Token 专用存取(save/load/clear) | -| Service | `Core/Services/AuthServiceProtocol.swift` | AuthService 协议定义 | -| Service | `Core/Services/AuthService.swift` | ASAuthorizationController 集成 + 后端调用 | -| App | `App/AppSession.swift` | @MainActor 全局登录状态 | -| View | `Features/Auth/Views/LoginView.swift` | 纯 Apple 登录按钮 UI | -| ViewModel | `Features/Auth/ViewModels/LoginViewModel.swift` | @Published isLoading/errorMessage | - -### 9.5 API Contract - -```swift -// 请求 → POST /api/auth/apple -struct AppleLoginRequest: Encodable { - let identityToken: String - let authorizationCode: String? - let userIdentifier: String - let fullName: AppleFullName? - let email: String? -} - -struct AppleFullName: Encodable { - let givenName: String? - let familyName: String? -} - -// 响应 -struct AuthResponse: Decodable { - let accessToken: String - let refreshToken: String - let expiresIn: Int - let user: User -} -``` - -### 9.6 关键约束 - -| 约束 | 说明 | -|------|------| -| Token 存 Keychain | 不存 UserDefaults | -| 不用 @AppStorage 控制登录 | 登录状态由 AppSession + Keychain token 决定 | -| View 不写网络请求 | 网络调用在 Service 层 | -| View 不处理 Apple 登录细节 | ASAuthorizationController 逻辑在 AuthService | -| 不改变现有主页面 UI | 只替换入口路由逻辑 | - ---- - -## 十、登录模块可行实施计划 - -以下是按依赖关系排列的 7 个实施步骤。每步独立可验证,后一步依赖前一步完成。 - -### 整体依赖图 - -``` -步骤1: Model ─────────────────────────────────────────┐ - ↓ │ -步骤2: KeychainStore / TokenStore ────────────────────┤ - ↓ │ -步骤4: APIClient / APIEndpoint ─┐ │ - ↓ │ │ -步骤3: AuthService ←────────────┘ │ - ↓ │ -步骤5: AppSession ─────────────────────────────────────┤ - ↓ │ -步骤6: LoginView + LoginViewModel ────────────────────┘ - ↓ -步骤7: 改造 App 入口启动逻辑(AIStudyAppApp.swift) -``` - ---- - -### 步骤 1:创建 Auth Model ✅ 已完成(2026-05-10) - -**产出文件**: -- `Core/Models/AuthModels.swift` -- `Core/Models/User.swift` - -**内容**: -```swift -// AuthModels.swift -struct AppleLoginRequest: Encodable { ... } -struct AppleFullName: Encodable { ... } -struct AuthResponse: Decodable { ... } - -// User.swift -struct User: Codable, Identifiable { - let id: String - let appleUserId: String - let displayName: String? - let email: String? - let preferredLanguage: String - let onboardingCompleted: Bool - let createdAt: String - let lastLoginAt: String? - let status: String -} -``` - -**依赖**:无 - -**验证**:Xcode 编译通过 - ---- - -### 步骤 2:实现 Keychain 存储层 ✅ 已完成(2026-05-10) - -**产出文件**: -- `Core/Storage/KeychainStore.swift` -- `Core/Storage/TokenStore.swift` - -**KeychainStore 职责**:通用 Keychain 读写,封装 `SecItemAdd`/`SecItemCopyMatching`/`SecItemDelete`,支持 save/load/delete 操作。 - -**TokenStore 职责**: -```swift -protocol TokenStoreProtocol { - func saveAccessToken(_ token: String) throws - func getAccessToken() throws -> String? - func saveRefreshToken(_ token: String) throws - func getRefreshToken() throws -> String? - func clearAll() throws -} -``` - -**依赖**:步骤 1(Model 定义,具体来说不需要 Model 依赖,TokenStore 操作的是原始 String) - -**验证**:可写简单单元测试验证存取清除 - ---- - -### 步骤 3:搭建网络层最小实现 ✅ 已完成(2026-05-10) - -> 注意:这一步和 AuthService 互相依赖——AuthService 需要 APIClient 发请求,但可以先建网络层骨架。做的时候步骤 3 和 4 可以部分并行:先建 APIClient 基础,再写 AuthService 时补充 Auth 相关 endpoint。 - -**产出文件**: -- `Core/Network/APIClient.swift` -- `Core/Network/APIEndpoint.swift` -- `Core/Network/APIError.swift` - -**最小接口**: -```swift -// APIClient -class APIClient { - init(baseURL: URL, tokenStore: TokenStoreProtocol?) - func request(_ endpoint: APIEndpoint) async throws -> T - func requestVoid(_ endpoint: APIEndpoint) async throws -} - -// APIEndpoint -enum APIEndpoint { - case appleLogin(AppleLoginRequest) - case refreshToken(String) - case me - // 后续扩展其他 endpoint -} - -// APIError -enum APIError: Error { - case network(Error) - case httpError(Int) - case decoding(Error) - case unauthorized -} -``` - -**依赖**:步骤 1(Model)、步骤 2(TokenStore) - -**验证**:Xcode 编译通过,可以先 mock 一个请求验证 pipeline 跑通 - ---- - -### 步骤 4:实现 AuthService ✅ 已完成(2026-05-10) - -**产出文件**: -- `Core/Services/AuthServiceProtocol.swift` -- `Core/Services/AuthService.swift` - -**AuthServiceProtocol**: -```swift -protocol AuthServiceProtocol { - func loginWithApple() async throws -> AuthResponse - func refreshSession() async throws -> AuthResponse - func logout() async throws - func fetchCurrentUser() async throws -> User -} -``` - -**AuthService 实现要点**: -1. 集成 `ASAuthorizationController`(需 `import AuthenticationServices`) -2. 获取 identityToken、authorizationCode、userIdentifier -3. 调用 `APIClient.request(.appleLogin(request))` -4. 将返回的 token 写入 TokenStore -5. refreshSession:用 refreshToken 换新 token - -**依赖**:步骤 1(AuthModels)、步骤 2(TokenStore)、步骤 3(APIClient) - -**验证**:Xcode 编译通过,可在模拟器点击 Apple 登录(后端未就绪时用 mock) - ---- - -### 步骤 5:实现 AppSession ✅ 已完成(2026-05-10) - -**产出文件**: -- `App/AppSession.swift` - -**关键代码骨架**: -```swift -@MainActor -final class AppSession: ObservableObject { - @Published var currentUser: User? - @Published var isAuthenticated = false - @Published var isLoading = true - @Published var authError: String? - - private let authService: AuthServiceProtocol - private let tokenStore: TokenStoreProtocol - - func bootstrap() async { - // 1. 检查 Keychain 是否有 refreshToken - // 2. 有 → 调用 refreshSession() - // 3. 成功 → isAuthenticated=true, currentUser=user - // 4. 失败 → 清空 token, isAuthenticated=false - // 5. 无 → isAuthenticated=false - // 6. isLoading = false - } - - func loginWithApple() async { ... } - func logout() { ... } -} -``` - -**依赖**:步骤 4(AuthService)、步骤 2(TokenStore) - -**验证**:模拟器启动时可根据 Keychain 状态正确分流 - ---- - -### 步骤 6:实现 LoginView + LoginViewModel ✅ 已完成(2026-05-10) - -**产出文件**: -- `Features/Auth/Views/LoginView.swift` -- `Features/Auth/ViewModels/LoginViewModel.swift` - -**LoginView**: -- 品牌标题"知习" + 副标题 -- Sign in with Apple 按钮(ASAuthorizationAppleIDButton) -- Loading 状态(ProgressView) -- Error 提示 -- `#if DEBUG` 跳过按钮 -- 协议入口链接 - -**LoginViewModel**: -```swift -@MainActor -final class LoginViewModel: ObservableObject { - @Published var isLoading = false - @Published var errorMessage: String? - - func loginWithApple() async { - isLoading = true - errorMessage = nil - do { - try await appSession.loginWithApple() - } catch { - errorMessage = "登录失败:\(error.localizedDescription)" - isLoading = false - } - } -} -``` - -**依赖**:步骤 5(AppSession) - -**验证**:模拟器显示登录页,点击 Apple 登录按钮触发流程,loading 状态可展示 - ---- - -### 步骤 7:改造 App 入口启动逻辑 ✅ 已完成(2026-05-10) - -**修改文件**:`AIStudyAppApp.swift` - -**改动要点**: -1. 注入 `AppSession` 为 `@StateObject` -2. 启动时调用 `appSession.bootstrap()` -3. 用 `appSession.isLoading / isAuthenticated / currentUser?.onboardingCompleted` 替换原来的 `@AppStorage("hasCompletedOnboarding")` -4. 路由逻辑: - ``` - isLoading → Splash(启动加载中) - !isAuthenticated → LoginView - onboardingCompleted == false → OnboardingFlowView - onboardingCompleted == true → ContentView - ``` - -**依赖**:步骤 1-6 全部完成 - -**验证**:完整启动流程测试—— -- 首次启动 → 登录页 → Apple 登录(mock) → 引导页 → 目标设置 → 主界面 -- 二次启动(有有效 token)→ 直接进主界面 -- Token 过期 → 登录页 - ---- - -### 实施俯视图 - -``` -步骤 1 ──→ 步骤 2 ──→ 步骤 3 ──→ 步骤 4 ──→ 步骤 5 ──→ 步骤 6 ──→ 步骤 7 -Model Keychain 网络层 AuthSvc AppSession LoginUI 入口改造 -(0依赖) (无依赖) (依赖1,2) (依赖1-3) (依赖2,4) (依赖5) (依赖1-6) -``` - -每一步均可独立编译验证。后端 API 未就绪时,步骤 4-7 可以用 mock 数据先行开发,后端就绪后仅替换 APIClient 的真实 endpoint。 - -### 文件目录结构(完成后) - -``` -AIStudyApp/ -├── App/ -│ └── AppSession.swift ← 新增 -├── Core/ -│ ├── Models/ -│ │ ├── AuthModels.swift ← 新增 -│ │ └── User.swift ← 新增 -│ ├── Network/ -│ │ ├── APIClient.swift ← 新增 -│ │ ├── APIEndpoint.swift ← 新增 -│ │ └── APIError.swift ← 新增 -│ ├── Services/ -│ │ ├── AuthServiceProtocol.swift ← 新增 -│ │ └── AuthService.swift ← 新增 -│ ├── Storage/ -│ │ ├── KeychainStore.swift ← 新增 -│ │ └── TokenStore.swift ← 新增 -│ └── DesignSystem/ -│ └── DesignTokens.swift (已有,不变) -├── Features/ -│ ├── Auth/ -│ │ ├── Views/ -│ │ │ └── LoginView.swift ← 新增 -│ │ └── ViewModels/ -│ │ └── LoginViewModel.swift ← 新增 -│ ├── AI/ (已有) -│ ├── Library/ (已有) -│ ├── Study/ (已有) -│ ├── Analysis/ (已有) -│ └── Profile/ (已有) -└── AIStudyAppApp.swift ← 修改 -```