001project_wildgrowth/ios/WildGrowth/COMPLETION_统一分页_零影响审查报告.md

123 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 完成页「统一分页架构」— 零影响审查报告(禁止应用)
**审查目标**:若应用此方案,确保**其他页面、其他功能、其他逻辑一点也不受影响**。
**结论**:仅审查,不修改仓库内任何文件。下文列出所有受影响点及达成「零影响」的**必要条件**。
---
## 一、方案会动到的文件与接口
| 文件 | 方案中的改动 |
|------|----------------|
| **CompletionView.swift** | 整文件替换:去掉 courseId仅保留 courseTitle、completedLessonCount纯 UI + switchToGrowthTab |
| **VerticalScreenPlayerView.swift** | 数据源改为 allItems (PlayerItem);去掉占位页与 onChangeinit 去掉 navigationPath、isLastNode、courseTitlehandleBack 仅 dismiss()LessonPageView 传参可能变 |
---
## 二、依赖关系与「零影响」条件
### 2.1 谁调用 VerticalScreenPlayerView
| 调用方 | 当前传参 | 方案中 init 若改为 3 参会怎样 |
|--------|----------|------------------------------|
| **GrowthView** (.player) | courseId, nodeId, initialScrollIndex: nil, **navigationPath: $growthPath**, **isLastNode**, **courseTitle** | ❌ 编译失败(多传 3 个参数) |
| **ProfileView** (.player) | 同上navigationPath: $profilePath | ❌ 同上 |
| **DiscoveryView** (.player) | 同上navigationPath: $homePath | ❌ 同上 |
| **NoteTreeView** (.player) | courseId, nodeId, initialScrollIndex无 path / isLastNode / courseTitle | ✅ 仍兼容 3 参 init |
**零影响条件 1**
**VerticalScreenPlayerView 的 init 必须保留现有 6 参签名**courseId, nodeId, initialScrollIndex, navigationPath?, isLastNode?, courseTitle?),且默认值不变。内部可改用 allItems + PlayerItem但对外接口不变这样 GrowthView / ProfileView / DiscoveryView **无需改一行**
---
### 2.2 谁使用 CourseNavigation 与 CompletionView
| 位置 | 当前行为 | 方案若不再 push .completion 会怎样 |
|------|----------|-------------------------------------|
| **GrowthView** | navigationDestination(.completion) → CompletionView(courseId, courseTitle, completedLessonCount) | 从「课程流」进完成页时不再走此分支(完成页在 TabView 内);若保留此分支,深链/通知若 push .completion 仍能展示 |
| **ProfileView** | 同上 | 同上 |
| **DiscoveryView** | 同上 | 同上 |
| **MapView** | 只 append .player不直接 append .completion | ✅ 无影响 |
| **VerticalScreenPlayerView**(当前) | 滑到占位页时 append .completion | 方案中不再 append完成页在 TabView 内 |
**零影响条件 2**
- **保留** `CourseNavigation.completion` 与三处 `.completion` 的 navigationDestination。
- **CompletionView 仍保留三参**courseId, courseTitle, completedLessonCount。这样
- 从课程流进入时,完成页由播放器内 TabView 展示,不经过 navigationDestination
- 若有深链/通知/其他入口直接 push .completion三处 destination 仍能正确展示 CompletionView且接口一致。
---
### 2.3 LessonPageView 的传参
| 当前传参 | 方案中若改为不传 navigationPath / 不传 courseTitle 会怎样 |
|----------|-----------------------------------------------------------|
| courseId, nodeId, currentGlobalNodeId, initialScrollIndex, headerConfig, **courseTitle**, **navigationPath** | LessonPageView 中两者均为可选;不传则 nil。若内部有逻辑依赖 path 或 courseTitle可能受影响。 |
**零影响条件 3**
在「统一分页」的播放器内部,对 **LessonPageView** 的调用仍传入 **courseTitle**、**navigationPath**(用 VerticalScreenPlayerView 持有的 courseTitle、navigationPath与当前一致。即仅改数据源与最后一页渲染方式不减少对 LessonPageView 的传参。
---
### 2.4 播放器内部逻辑(其他功能)
| 当前能力 | 方案中若省略会怎样 |
|----------|--------------------|
| **handleBack** 用 navigationPath.removeLast() 或 dismiss() | 若改为仅 dismiss(),在 NavigationStack 内效果通常等价pop 一层)。为保险起见,建议保留:有 path 且非空时 removeLast(),否则 dismiss()。 |
| **loadError / 错误态 UI** | 方案片段中未写,若删除则错误态消失。 |
| **showToast / toastMessage** | 同上,若删除则 toast 能力消失。 |
| **hideTabBar / showTabBaronAppear / onDisappear** | 若删除则播放器出现时 TabBar 可能仍显示。 |
| **currentPositionProgress**(不含占位页) | 方案中有「进度计算忽略完结页」,逻辑等价即可。 |
| **GeometryReader 等布局** | 若删除可能影响布局,建议保留与当前一致。 |
**零影响条件 4**
播放器内**保留**loadError / 错误态 UI、showToast / toastMessage、hideTabBar / showTabBar、handleBack 的 path 优先逻辑(若保留 navigationPath 参数则一并保留)、以及现有布局与进度计算方式(仅把「占位页」换成虚拟 completion 页,进度仍只按真实小节算)。
---
### 2.5 笔记流NoteTreeView / NoteListView
| 当前 | 说明 |
|------|------|
| 使用 NoteNavigationDestination.player传 courseId, nodeId, initialScrollIndex | 不传 navigationPath、isLastNode、courseTitle当前 init 中这些为可选且带默认值。 |
**零影响条件 5**
保持 VerticalScreenPlayerView 的 init 中 **navigationPath、isLastNode、courseTitle 为可选且默认 nil**。这样 NoteTreeView / NoteListView **无需任何修改**,行为不变(不传 path 则不会 push 完成页;统一分页下完成页在 TabView 内,笔记流仍不涉及 .completion 路由)。
---
### 2.6 其他引用
| 引用 | 影响 |
|------|------|
| **ContentBlockBuilder** 注释「与 VerticalScreenPlayerView 保持一致」 | 仅注释,不依赖接口或类型。 |
| **CourseNavigation** 枚举 | 保留 .map / .player / .completion 三 case见零影响条件 2。 |
| **MapView** 中 append CourseNavigation.player(courseId, nodeId, isLastNode, courseTitle) | 不依赖播放器 init 是否接收这些参数,只要枚举不变即无影响。 |
---
## 三、零影响检查清单(应用前必达)
若要在「其他页面、其他功能、其他逻辑一点也不受影响」的前提下应用统一分页方案,需同时满足:
| # | 条件 | 说明 |
|---|------|------|
| 1 | VerticalScreenPlayerView **init 保持 6 参**courseId, nodeId, initialScrollIndex, navigationPath?, isLastNode?, courseTitle? | GrowthView / ProfileView / DiscoveryView 不改动 |
| 2 | 保留 **CourseNavigation.completion** 及三处 **.completion** 的 navigationDestination | 深链/其他入口 push .completion 仍可用 |
| 3 | **CompletionView 保留三参**courseId, courseTitle, completedLessonCount | 与现有 destination 及枚举一致 |
| 4 | 播放器内对 **LessonPageView** 仍传 **courseTitle**、**navigationPath**(用播放器自身属性) | LessonPageView 行为不变 |
| 5 | 播放器内保留 **loadError、toast、hideTabBar/showTabBar、handleBack(path 优先)** 及现有布局/进度逻辑 | 错误、提示、TabBar、返回、进度均不受影响 |
| 6 | **NoteTreeView / NoteListView** 不修改 | 依赖 init 可选参数,已满足则零影响 |
---
## 四、总结
- **按方案原文直接替换**init 改为 3 参、CompletionView 去掉 courseId、播放器去掉 path/错误/toast/tabBar 等):**会**影响 GrowthView / ProfileView / DiscoveryView编译或行为、以及错误态/toast/TabBar/返回等逻辑。
- **在满足上述 6 条零影响条件的前提下**,再引入 allItems + PlayerItem、TabView 最后一页渲染 CompletionView、不再 push .completion
- 其他页面(含三 Tab、MapView、笔记流**无需改**
- 其他功能错误、toast、TabBar、返回、进度、深链 .completion**不受影响**
- 其他逻辑完课统计、LessonPageView、CourseNavigation**保持一致**。
**未对仓库内任何文件进行修改。**