001project_wildgrowth/ios/WildGrowth/COMPLETION_实现后行为与影响说明.md

130 lines
8.5 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.

# 完成页导航方案 — 实现后行为与影响说明
说明:实现方案后**会变成什么样**、**会不会影响原有逻辑和展示**、**会不会导致其他地方出问题**。不修改代码,仅作说明。
---
## 一、实现后会变成什么样
### 1. 进入完成页(两种方式,二选一或并存)
| 方式 | 当前 | 实现后(若保留占位页 + 加手势) |
|------|------|----------------------------------|
| **左滑到「下一页」** | 最后一节再左滑 → 进入占位页(空白)→ 0.1s 后 push 完成页 | 不变:仍可滑到占位页,再由 `onChange` push |
| **在最后一节左滑** | 无 | 新增:在最后一节直接左滑(手势识别)→ 可设为「切到占位页再 push」或「直接 push 完成页」 |
若方案采用「删除占位页、仅手势」:
- 最后一节左滑 → 直接 push 完成页,**不再出现空白占位页那一屏**。
- TabView 只有真实课程页,不再有「多一页」的占位。
**展示上**:完成页本身 UI 不变(仍是当前 CompletionView 的 3D 卡片、打字机等);变的只是「怎么进」和「怎么回」。
---
### 2. 从完成页返回(核心变化)
| 操作 | 当前 | 实现后 |
|------|------|--------|
| **顶部返回 (chevron)** | `dismiss()` → 回到播放器(最后一节或占位页) | 可保持不变:仍 `dismiss()`,回到播放器 |
| **底部「继续学习」** | `navStore.switchToGrowthTab()` + `dismiss()` | `handleReturnToMap()``navigationPath.removeLast(2)` |
**「继续学习」行为对比**
- **当前**
1. `dismiss()` → 栈 pop 一层,回到 **VerticalScreenPlayerView**(当前 Tab 可能是占位页,`onAppear` 里会切回最后一节)。
2. `switchToGrowthTab()` → 切到「技能」Tab**清空 `growthPath`**`growthPath = NavigationPath()`)。
3. 用户最终看到的是 **技能 Tab 的根界面(课程列表)**,不是地图。
- **实现后**
1. `removeLast(2)` → 一次 pop 掉「完成页」和「播放器」。
2. 栈变成:**[MapView]**(或更短,视当前 path 而定)。
3. **不**调用 `switchToGrowthTab()`,所以**不会清空 path**,也**不一定会切 Tab**。
4. 用户最终看到的是 **当前 Tab 下的地图页**(从哪个 Tab 进的,就还在哪个 Tab
**总结**
- 实现后,点「继续学习」会**直接回到地图**,且**保留在当前 Tab**(发现 / 技能 / 我的)。
- 当前是**回到课程列表**(且强制在技能 Tab。这是**产品行为上的明确变化**。
---
### 3. 三条入口分别会怎样
| 入口 | 当前栈(到完成页时) | 当前「继续学习」后 | 实现后「继续学习」后 |
|------|----------------------|--------------------|------------------------|
| **技能 Tab** | growthPath: [Map, Player, Completion] | 切到技能 Tab + 清空栈 → **课程列表** | 仍技能 Tab栈 [Map] → **地图** |
| **发现 Tab** | homePath: [Map, Player, Completion] | dismiss 回播放器switchToGrowthTab 切到技能并清空 → **课程列表** | 仍发现 Tab栈 [Map] → **地图** |
| **我的 Tab** | profilePath: [Map, Player, Completion] | 同上 → **课程列表** | 仍我的 Tab栈 [Map] → **地图** |
---
## 二、会不会影响原有逻辑和展示
### 1. 会改变的部分(有意为之)
- **底部按钮语义**:「继续学习」从「回课程列表(并切到技能)」变为「回地图(且留在当前 Tab」。
- **是否清空栈**:不再在完成页里清空 `growthPath`,所以不会出现「从完成页一点就回到空白课程列表」。
- **是否切 Tab**:不再强制切到技能 Tab用户会留在发现 / 技能 / 我的中的当前 Tab。
若产品期望就是「完成课后回到地图、留在当前 Tab」则与方案一致若期望是「回到课程列表、且一定在技能 Tab」则与**当前**一致,与**实现后**不一致,需要产品确认。
### 2. 可保持不变的部分
- **完成页 UI**3D 翻转卡片、打字机、顶部返回、按钮样式等都可以不改。
- **顶部返回**:继续用 `dismiss()`,仍回到播放器,逻辑和展示都不变。
- **进入完成页的方式**:若保留占位页,现有「滑到占位页再 push」仍可用只是多了一种「最后一节左滑」的触发方式若加手势
### 3. 依赖「当前行为」的地方
- **NavigationStore.switchToGrowthTab()**:当前只在 CompletionView 的「继续学习」里被调用。实现后 CompletionView 不再调用它,**不会影响其他使用处**(因为别处没有用这个方法)。
- **growthPath 被清空**:当前只有「完成页点继续学习」会清空 growthPath。若没有「从完成页返回后依赖 growthPath 为空」的逻辑,则实现后**不会破坏其它功能**。
---
## 三、会不会导致其他地方出问题
### 1. 三个 Tab 的 navigationDestination必须改
- **GrowthView / ProfileView / DiscoveryView** 里 `.completion` 分支都要给 CompletionView 传 **Binding**
`navigationPath: $navStore.growthPath` / `$navStore.profilePath` / `$navStore.homePath`
- **漏传或错传**
- 漏传 → 编译不通过CompletionView 多了必选参数)。
- 错传(例如发现进的完成页却传了 `growthPath`)→ 点「继续学习」会 pop 错栈,可能白屏或回到错误 Tab。
- **结论**:三处都必须改,且必须传**当前栈对应的 path**,否则会出问题。
### 2. 笔记流NoteTreeView / NoteListView— 不受影响
- 笔记流用的是 **NoteNavigationDestination.player**,打开的是 **VerticalScreenPlayerView**,且**没有传 navigationPath**(或传的是笔记自己的 path
- 在这些地方打开的播放器里,`navigationPath` 为 nil现有逻辑里 `onChange` 里会 `guard let path = navigationPath else { return }`**不会 push CourseNavigation.completion**。
- 因此:从笔记进的播放器,**不会**出现「滑到完成页」的 push除非你后续在笔记流里也接 Course 的 completion
- **结论**:实现完成页方案**不会影响笔记流**,也不会从笔记流误进完成页。
### 3. 从完成页返回时栈深度不足
- 正常流程栈至少为 [Map, Player, Completion]`removeLast(2)` 安全。
- 若将来有「深链、通知、分享」等直接打开 CompletionView栈可能只有 [Completion],此时 `path.count >= 2` 为假,应走兜底 `dismiss()`
- 方案里已建议保留 `if navigationPath.count >= 2 { removeLast(2) } else { dismiss() }`**不会因为栈浅而崩溃**,最多退回单层 pop。
### 4. 手势与 TabView 滑动
- 在最后一节加「左滑进完成页」时,与 TabView 自带的左滑翻页**共用同一方向**,可能冲突(例如:想翻页却触发了完成页,或想进完成页却只翻到占位页)。
- 若用「边缘左滑」或阈值(如 -60pt、防抖可减轻误触需在真机多测。
- **结论**:可能带来**体验上的小问题**(误触/难触),不是逻辑错误,可通过手势参数和测试收敛。
### 5. 其他使用 VerticalScreenPlayerView / CompletionView 的地方
- **VerticalScreenPlayerView**:除 GrowthView / ProfileView / DiscoveryView 外,仅在 **NoteTreeView / NoteListView** 出现,且走的是 NoteNavigationDestination不涉及 CourseNavigation.completion**不受影响**。
- **CompletionView**:只在这三个 Tab 的 `navigationDestination(for: CourseNavigation.self)``.completion` 分支出现,**没有其它调用点**。
- **结论**:只要三处传参正确,**不会导致其它页面逻辑错误**。
---
## 四、简要结论表
| 问题 | 结论 |
|------|------|
| 实现后会变成什么样? | 进入完成页可增加「最后一节左滑」触发;「继续学习」从「回课程列表 + 切技能 Tab」变为「直接回地图 + 保留当前 Tab」可选去掉占位页。 |
| 会不会影响原有逻辑和展示? | 会:底部按钮语义和最终停留页(地图 vs 课程列表)、是否清栈/切 Tab 会变;顶部返回和完成页 UI 可保持不变。 |
| 会不会导致其他地方出问题? | 三处传 Binding 必须正确,否则会 pop 错栈;笔记流、其它使用点不受影响;栈浅时用 dismiss 兜底;手势可能与 TabView 滑动冲突,需真机调参。 |
**建议**:实现前与产品确认「继续学习」的预期是「回地图」还是「回课程列表」;若确认为回地图且保留当前 Tab再按方案改并保证三处 path 传参一致。