Files
super_video/SKILL_LOGIC_FLOW.md

430 lines
12 KiB
Markdown
Raw Permalink 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.
# 🔄 技能树功能逻辑关系完整梳理
## 📊 核心状态管理
### 状态变量
```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,用户的每个操作都会立即反映在界面上。