feat: 完善技能树功能架构与逻辑流程文档,新增视频播放与学习进度追踪功能

This commit is contained in:
zhongyidian committed 2026-01-03 17:31:24 +08:00
1 parent 6090abf955
commit e9a1fee27f
42 files changed
+1849 -760

No files matched your search

+429
View File
@@ -0,0 +1,429 @@
# 🔄 技能树功能逻辑关系完整梳理
## 📊 核心状态管理
### 状态变量
```typescript
selectedModuleId: string | null // 当前选中的模块ID(null = 总览模式)
selectedTagId: string | null // 当前选中的标签ID
selectedSubTagId: string | null // 当前选中的子标签ID
expandedTags: Set<string> // 展开的标签集合
search: string // 搜索文本
```
---
## 🎯 功能模块详解
### 1. 模块切换与技能树标题
#### 逻辑流程
```
用户点击模块图标
↓
handleModuleListItemClick(moduleId)
↓
如果点击的是已选中的模块 → 取消选择(回到总览)
如果点击的是新模块 → 选中该模块
↓
更新 selectedModuleId
清空 selectedTagId、selectedSubTagId
清空 expandedTags
↓
技能树标题更新:
- selectedModuleId = null → "技能树总览"
- selectedModuleId = "module-1" → "新手导航"
- selectedModuleId = "module-2" → "vlog发现与记录"
- selectedModuleId = "module-3" → "访谈聆听与对话"
- selectedModuleId = "module-4" → "电影创作与表达"
```
#### 实现位置
- **SkillTree.vue**: `getTreeTitle()` 函数
- **index.vue**: `handleModuleListItemClick()` 函数
---
### 2. 标签点击逻辑(核心)
#### 逻辑分支
```
用户点击技能树标签
↓
handleTagClick(moduleId, tagId)
↓
检查是否有子标签
↓
┌─────────────────────────────────────────────────────────┐
│ 分支A: 有子标签 │
├─────────────────────────────────────────────────────────┤
│ 如果点击的是已选中的标签: │
│ - 已展开 → 折叠(删除 tagId from expandedTags) │
│ - 未展开 → 展开(添加 tagId to expandedTags) │
│ │
│ 如果点击的是新标签: │
│ - 设置 selectedModuleId = moduleId │
│ - 设置 selectedTagId = tagId │
│ - 清空 selectedSubTagId = null │
│ - 自动展开(添加 tagId to expandedTags) │
│ │
│ 结果:展开/折叠子节点,不触发搜索 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 分支B: 无子标签 │
├─────────────────────────────────────────────────────────┤
│ - 设置 selectedModuleId = moduleId │
│ - 设置 selectedTagId = tagId │
│ - 清空 selectedSubTagId = null │
│ - 清空 expandedTags │
│ │
│ 结果:高亮标签 + 触发搜索,其他标签保持可见 │
└─────────────────────────────────────────────────────────┘
```
#### 关键特性
- ✅ 有子标签:只展开/折叠,不搜索
- ✅ 无子标签:高亮并搜索,不隐藏其他标签
- ✅ 其他标签始终可见(不会因为选择而隐藏)
#### 实现位置
- **index.vue**: `handleTagClick()` 函数
---
### 3. 子标签点击逻辑
#### 逻辑流程
```
用户点击子标签
↓
handleSubTagClick(moduleId, tagId, subTagId)
↓
如果点击的是已选中的子标签 → 取消选择
如果点击的是新子标签 → 选中该子标签
↓
更新状态:
- selectedModuleId = moduleId
- selectedTagId = tagId
- selectedSubTagId = subTagId
- 确保父标签展开(添加 tagId to expandedTags)
↓
触发资源过滤(显示该子标签的资源)
```
#### 实现位置
- **index.vue**: `handleSubTagClick()` 函数
---
### 4. 资源过滤逻辑
#### 过滤优先级
```
1. 子标签过滤(最精确)
↓
2. 标签过滤
↓
3. 模块过滤
↓
4. 全部资源(默认)
↓
5. 文本搜索(叠加过滤)
```
#### 详细流程
```typescript
filteredResources = computed(() => {
let resources = []
// 第一步:根据选择获取资源
if (selectedSubTagId) {
resources = getResourcesBySubTag(moduleId, tagId, subTagId)
} else if (selectedTagId) {
resources = getResourcesByTag(moduleId, tagId)
} else if (selectedModuleId) {
resources = getResourcesByModule(moduleId)
} else {
resources = getAllResources()
}
// 第二步:文本搜索(如果有搜索文本)
if (search.trim()) {
resources = resources.filter(
r =>
r.title.includes(search) ||
r.moduleName.includes(search) ||
r.tagName.includes(search) ||
r.description?.includes(search)
)
}
return resources
})
```
#### 搜索字段
- ✅ `title` - 资源标题
- ✅ `moduleName` - 模块名称
- ✅ `tagName` - 标签名称
- ✅ `description` - 资源描述
#### 实现位置
- **index.vue**: `filteredResources` 计算属性
---
### 5. 搜索标签(面包屑)
#### 显示逻辑
```
searchTags = computed(() => {
const tags = []
if (selectedModuleId) {
tags.push({ type: 'module', name: moduleName })
}
if (selectedTagId) {
tags.push({ type: 'tag', name: tagName })
}
if (selectedSubTagId) {
tags.push({ type: 'subTag', name: subTagName })
}
return tags
})
```
#### 标签样式
- **模块标签**:蓝色(`bg-blue-500/80`)
- **标签标签**:橙色(`bg-orange-500/80`)
- **子标签标签**:紫色(`bg-purple-500/80`)
#### 删除功能
```
用户点击标签的 × 按钮
↓
handleRemoveTag(tagType)
↓
根据 tagType 清除对应状态:
- 'subTag' → 清除 selectedSubTagId
- 'tag' → 清除 selectedTagId + selectedSubTagId + expandedTags
- 'module' → 清除所有选择状态
↓
资源列表自动更新
```
#### 实现位置
- **index.vue**: `searchTags` 计算属性, `handleRemoveTag()` 函数
- **SearchTags.vue**: 标签显示和删除按钮
---
### 6. 文本搜索
#### 搜索框行为
```
用户在搜索框输入文本
↓
v-model 绑定到 search 变量
↓
filteredResources 自动重新计算
↓
资源列表实时更新
```
#### 搜索特性
- ✅ 实时搜索(无需点击搜索按钮)
- ✅ 多字段搜索(title、moduleName、tagName、description)
- ✅ 大小写不敏感
- ✅ 叠加过滤(在已选择的基础上进一步过滤)
- ✅ 搜索文本为空时,不影响选择过滤
#### 实现位置
- **index.vue**: 搜索框 `v-model="search"`
---
## 🎨 UI 交互状态
### 标签高亮状态
```typescript
isTagSelected(moduleId, tagId) {
return selectedModuleId === moduleId && selectedTagId === tagId
}
```
### 标签展开状态
```typescript
isTagExpanded(tagId) {
return expandedTags.has(tagId)
}
```
### 子标签选中状态
```typescript
isSubTagSelected(moduleId, tagId, subTagId) {
return selectedModuleId === moduleId &&
selectedTagId === tagId &&
selectedSubTagId === subTagId
}
```
---
## 📈 数据流向图
```
用户操作
↓
┌─────────────────────────────────────────────────────────┐
│ 点击模块图标 → handleModuleListItemClick │
│ 点击标签 → handleTagClick │
│ 点击子标签 → handleSubTagClick │
│ 输入搜索文本 → v-model:search │
│ 删除面包屑标签 → handleRemoveTag │
└─────────────────────────────────────────────────────────┘
↓
更新状态变量
- selectedModuleId
- selectedTagId
- selectedSubTagId
- expandedTags
- search
↓
触发计算属性重新计算
- searchTags(面包屑)
- filteredResources(资源列表)
- displayedTags(技能树标签)
- displayedModules(显示的模块)
↓
UI 自动更新
- 技能树标题
- 标签高亮状态
- 子节点展开/折叠
- 面包屑标签
- 资源列表
```
---
## 🔍 关键场景示例
### 场景1:从总览到具体资源
```
1. 初始状态:总览模式
- selectedModuleId = null
- 显示 "技能树总览"
- 显示所有模块的标签(去重)
2. 点击 "新手导航" 模块
- selectedModuleId = "module-1"
- 显示 "新手导航"
- 只显示新手导航的标签
3. 点击 "视觉素养" 标签(有子标签)
- selectedTagId = "tag-1-1"
- 展开子标签:构图、光线、运镜
- 资源列表显示视觉素养的所有资源
4. 点击 "构图" 子标签
- selectedSubTagId = "subtag-1-1-1"
- 资源列表只显示构图相关资源
- 面包屑:新手导航 > 视觉素养 > 构图
```
### 场景2:搜索功能
```
1. 在搜索框输入 "构图"
- search = "构图"
- 资源列表实时过滤,显示所有包含"构图"的资源
2. 点击面包屑标签的删除按钮
- 清除对应的选择
- 资源列表更新
3. 清空搜索框
- search = ""
- 资源列表恢复到选择过滤的结果
```
### 场景3:标签点击行为
```
有子标签的标签(如"视觉素养"):
- 第一次点击 → 展开子节点
- 第二次点击 → 折叠子节点
- 不触发搜索,其他标签保持可见
无子标签的标签(如"摄影基础"):
- 点击 → 高亮标签 + 过滤资源
- 其他标签保持可见
- 可以继续点击其他标签
```
---
## ✅ 功能清单
### 已实现功能
- ✅ 模块切换(总览 ↔ 具体模块)
- ✅ 技能树标题动态更新
- ✅ 标签点击逻辑(有/无子标签分支)
- ✅ 子标签展开/折叠
- ✅ 标签高亮显示
- ✅ 资源多级过滤(模块 → 标签 → 子标签)
- ✅ 文本搜索(多字段)
- ✅ 面包屑导航
- ✅ 标签删除功能
- ✅ 实时搜索
- ✅ 标签去重(总览模式)
### 核心特性
- 🎯 **智能标签点击**:根据是否有子标签自动选择行为
- 🔍 **多维度搜索**:选择过滤 + 文本搜索
- 🏷️ **面包屑导航**:清晰显示当前位置
- 🗑️ **灵活删除**:可以删除任意层级的选择
- 👁️ **保持可见**:选择标签后其他标签不隐藏
---
## 🎯 总结
这是一个**多层级、多维度的资源浏览和搜索系统**,核心特点:
1. **灵活的导航**:支持模块 → 标签 → 子标签的层级导航
2. **智能的交互**:根据标签类型自动选择展开或搜索
3. **强大的搜索**:选择过滤 + 文本搜索双重过滤
4. **清晰的反馈**:面包屑、高亮、展开状态等多种视觉反馈
5. **用户友好**:可以随时删除选择,标签始终可见
整个系统通过 Vue 的响应式系统自动同步状态和 UI,用户的每个操作都会立即反映在界面上。