# 📚 Skill 功能架构完整分析 ## 🗂️ 文件结构(已清理) ``` src/views/skill/ ├── index.vue # 主页面 - 技能树资源浏览器 ├── resourceData.ts # 数据层 - 资源数据管理 ├── video.vue # 视频播放页面 └── components/ ├── SkillTree.vue # 技能树可视化组件 ├── SearchTags.vue # 搜索面包屑标签 └── ResourceList.vue # 资源列表展示 ``` --- ## 🎯 核心功能定位 **技能树资源浏览系统** - 一个基于树形结构的学习资源导航和筛选平台 --- ## 📊 数据架构 ### 1. 数据层级结构 ``` 模块 (Module) └─ 标签 (Tag) └─ 子标签 (SubTag) └─ 资源 (Resource) ``` ### 2. 数据实体 #### ResourceItem 接口 ```typescript { id: string // 资源唯一标识 title: string // 资源标题 description?: string // 资源描述 moduleId: string // 所属模块ID moduleName: string // 所属模块名称 tagId: string // 所属标签ID tagName: string // 所属标签名称 subTagId?: string // 所属子标签ID(可选) subTagName?: string // 所属子标签名称(可选) } ``` ### 3. 数据统计 - **4个模块**: 1. module-1: 新手导航 (5个资源) 2. module-2: vlog发现与记录 (6个资源) 3. module-3: 访谈聆听与对话 (3个资源) 4. module-4: 电影创作与表达 (7个资源) - **8种标签类型**: - 视觉素养 (橙色) - 摄影基础 (蓝色) - 剪映基础操作 (紫色) - 内容策划 (橙色) - 拍摄执行 (绿色) - 后期制作 (蓝色) - AI与版权伦理知识 (蓝色) - 思路提点与案例赏析 (蓝色) - **总资源数**:21个学习资源 ### 4. 工具函数 ```typescript getAllResources() // 获取所有资源 getResourcesByModule(moduleId) // 按模块筛选 getResourcesByTag(moduleId, tagId) // 按标签筛选 getResourcesBySubTag(moduleId, tagId, subTagId) // 按子标签筛选 getAllModules() // 获取所有模块 getTagsByModule(moduleId) // 获取模块的标签 getSubTagsByTag(moduleId, tagId) // 获取标签的子标签 getTagResourceCount(moduleId, tagId) // 获取标签的资源数量 ``` --- ## 🎨 UI 布局 ### 页面布局(1920x1080) ``` ┌─────────────────────────────────────────────────────────────┐ │ [搜索框 + 面包屑] [模块1][模块2][模块3][模块4] [X] │ │ │ │ │ │ ┌──────────────┐ ┌──────────────────┐ │ │ │ │ │ │ │ │ │ 资源列表 │ │ 技能树 │ │ │ │ 740x800 │ │ 860x820 │ │ │ │ │ │ │ │ │ │ │ │ [标签节点...] │ │ │ │ [资源卡片] │ │ │ │ │ │ [资源卡片] │ │ 技能树总览 │ │ │ └──────────────┘ └──────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ### 组件定位 1. **搜索框**:左上角 (left-10, top-10, 547x84px) 2. **模块图标**:顶部居中 (left-55%, top-10, 4个141x150px) 3. **资源列表**:左下角 (left-10, bottom-20, 740x800px) 4. **技能树**:右下角 (right-0, bottom-20, 860x820px) 5. **关闭按钮**:右上角 (right-0, top-0) --- ## 🔄 交互逻辑流程 ### 1. 状态管理 ```typescript // 核心状态 selectedModuleId: string | null // 当前选中的模块 selectedTagId: string | null // 当前选中的标签 selectedSubTagId: string | null // 当前选中的子标签 expandedTags: Set // 展开的标签集合 search: string // 搜索文本(待实现) ``` ### 2. 用户交互流程 #### 流程A:模块筛选 ``` 用户点击模块图标 ↓ handleModuleListItemClick(moduleId) ↓ 如果已选中同一模块 → 取消选择(显示所有) 如果选中新模块 → 设置 selectedModuleId ↓ 清空标签和子标签选择 ↓ 技能树只显示该模块的标签 资源列表只显示该模块的资源 ``` #### 流程B:标签筛选 ``` 用户点击技能树标签 ↓ handleTagClick(moduleId, tagId) ↓ 如果已选中同一标签: - 已展开 → 折叠并取消选择 - 未展开 → 展开子标签 如果选中新标签: - 设置 selectedModuleId 和 selectedTagId - 如果有子标签 → 自动展开 ↓ 资源列表显示该标签的所有资源 搜索框显示面包屑:[模块] > [标签] ``` #### 流程C:子标签筛选 ``` 用户点击子标签 ↓ handleSubTagClick(moduleId, tagId, subTagId) ↓ 如果已选中同一子标签 → 取消选择 如果选中新子标签 → 设置 selectedSubTagId ↓ 资源列表显示该子标签的资源 搜索框显示面包屑:[模块] > [标签] > [子标签] ``` ### 3. 计算属性逻辑 #### searchTags(面包屑) ```typescript 根据选择状态生成面包屑数组: - 选中模块 → 添加模块标签(蓝色) - 选中标签 → 添加标签标签(橙色) - 选中子标签 → 添加子标签标签(紫色) ``` #### filteredResources(资源过滤) ```typescript 优先级:子标签 > 标签 > 模块 > 全部 1. 如果选中子标签 → 返回子标签的资源 2. 否则如果选中标签 → 返回标签的资源 3. 否则如果选中模块 → 返回模块的资源 4. 否则 → 返回所有资源 ``` --- ## 🌳 技能树组件详解 ### 1. 核心功能 - **标签去重**:使用 `displayedTags` 计算属性,通过 `moduleId-tagId` 作为唯一键去重 - **位置布局**:14个预定义位置,形成树形分布 - **颜色映射**:根据标签名称返回不同颜色 - **展开/折叠**:有子标签的标签可以展开显示子标签列表 - **数字徽章**:显示每个标签下的资源数量 ### 2. 标签位置分布 ```typescript 14个预定义位置(百分比定位): 顶部区域(树冠): - (8%, 35%) - (12%, 55%) - (18%, 72%) 中上区域: - (28%, 18%) - (32%, 82%) 中部区域: - (42%, 10%) - (45%, 28%) - (48%, 68%) 中下区域: - (58%, 22%) - (62%, 78%) - (68%, 85%) 底部区域(树干): - (75%, 15%) - (78%, 38%) - (82%, 65%) ``` ### 3. 标签样式 ```css 基础样式: - 圆角矩形:rounded-xl - 内边距:px-4 py-2 - 边框:border-2 - 尺寸:min-w-[140px] max-w-[200px] - 阴影:shadow-lg 交互效果: - hover:scale-105 - 选中:橙色背景 + 白色光圈 颜色映射: - 后期制作:蓝色 (bg-blue-500/85) - 拍摄执行:绿色 (bg-green-500/85) - 内容策划:橙色 (bg-orange-500/85) - 视觉素养:橙色 (bg-orange-500/85) - 摄影基础:蓝色 (bg-blue-500/85) - 剪映基础操作:紫色 (bg-purple-500/85) - AI与版权伦理知识:蓝色 (bg-blue-500/85) - 思路提点与案例赏析:蓝色 (bg-blue-500/85) ``` ### 4. 子标签展开 ``` 父标签被点击且有子标签 ↓ 在父标签下方显示子标签列表 ↓ 子标签样式: - 更小的尺寸 (px-3 py-1) - 圆角矩形 (rounded-lg) - 蓝色背景(未选中)/ 橙色背景(选中) - 垂直排列 (space-y-1) ``` --- ## 📋 资源列表组件 ### 功能 - 显示过滤后的资源列表 - 滚动容器(overflow-y-auto) - 空状态提示 ### 资源卡片样式 ```css - 半透明蓝色背景:bg-blue-500/20 - 圆角:rounded - 内边距:p-4 - hover效果:bg-blue-500/30 - 标题:text-2xl font-bold - 描述:text-lg text-gray-300 ``` --- ## 🔍 搜索标签组件 ### 功能 - 显示当前选择路径(面包屑导航) - 不同类型不同颜色 ### 标签样式 ```css - 圆角胶囊:rounded-full - 边框:border border-white/80 - 内边距:px-3 py-1 - 颜色映射: - 模块:蓝色 (bg-blue-500/80) - 标签:橙色 (bg-orange-500/80) - 子标签:紫色 (bg-purple-500/80) ``` --- ## 🎬 视频播放页面 ### 功能 - 播放学习视频 - 全屏视频播放器 - 返回按钮 ### 当前问题 - 硬编码视频路径:`/video/xinshou_jiuzhonggoutufa.mp4` - 未接收路由参数 - 无法动态切换视频 ### 建议改进 ```typescript // 应该接收资源ID参数 const route = useRoute() const resourceId = route.params.id // 根据资源ID获取视频路径 const videoSrc = getVideoByResourceId(resourceId) ``` --- ## 🚀 功能特点 ### ✅ 已实现 1. **多层级筛选**:模块 → 标签 → 子标签 2. **可视化导航**:技能树形式展示 3. **实时过滤**:点击即时更新资源列表 4. **面包屑导航**:清晰显示当前位置 5. **标签去重**:避免重复显示 6. **展开/折叠**:子标签动态显示 7. **资源计数**:显示每个标签的资源数量 8. **响应式交互**:hover、选中等视觉反馈 ### ⚠️ 待完善 1. **搜索功能**:文本搜索未实现 2. **资源详情**:点击资源卡片无响应 3. **视频播放**:未与资源数据关联 4. **学习进度**:无进度追踪 5. **数据持久化**:刷新后状态丢失 --- ## 💡 优化建议 ### 1. 完善搜索功能 ```typescript // 在 filteredResources 中添加文本搜索 const filteredResources = computed(() => { let resources = /* 现有筛选逻辑 */ // 添加文本搜索 if (search.value.trim()) { resources = resources.filter(r => r.title.includes(search.value) || r.description?.includes(search.value) ) } return resources }) ``` ### 2. 资源点击跳转 ```typescript // ResourceList.vue const handleResourceClick = (resource: ResourceItem) => { router.push({ name: 'SkillVideo', params: { id: resource.id } }) } ``` ### 3. 动态视频播放 ```typescript // video.vue const route = useRoute() const resourceId = route.params.id as string const resource = getAllResources().find(r => r.id === resourceId) const videoSrc = `/video/${resource?.videoFile || 'default.mp4'}` ``` ### 4. 学习进度追踪 ```typescript // 添加到 ResourceItem interface ResourceItem { // ... 现有字段 completed?: boolean progress?: number lastViewedAt?: Date } ``` ### 5. 状态持久化 ```typescript // 使用 localStorage 或 Pinia import { useLocalStorage } from '@vueuse/core' const selectedModuleId = useLocalStorage('skill-module', null) const selectedTagId = useLocalStorage('skill-tag', null) ``` --- ## 📈 数据扩展建议 ### 1. 添加视频文件字段 ```typescript interface ResourceItem { // ... 现有字段 videoFile?: string // 视频文件名 duration?: number // 视频时长(秒) difficulty?: 'easy' | 'medium' | 'hard' // 难度 } ``` ### 2. 添加标签元数据 ```typescript interface TagMeta { id: string name: string color: string icon?: string description?: string } ``` ### 3. 添加模块元数据 ```typescript interface ModuleMeta { id: string name: string description: string totalResources: number completedResources: number progress: number } ``` --- ## 🎯 总结 这是一个**结构清晰、功能完整的技能树资源浏览系统**,核心特点: 1. **数据驱动**:基于一维数组的资源数据,通过工具函数灵活查询 2. **层级筛选**:支持模块→标签→子标签的多层级筛选 3. **可视化导航**:技能树形式直观展示资源结构 4. **实时反馈**:点击即时更新,面包屑导航清晰 5. **代码整洁**:已清理冗余代码,结构简洁明了 主要改进方向是完善搜索、资源详情、视频播放和学习进度追踪功能。