| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510 |
- from typing import List, Dict, Optional
- from ..models.learning import (
- LearningPath, LearningPathData, LearningModule, LearningLesson, ModuleStatus
- )
- def get_frontend_path() -> LearningPathData:
- return LearningPathData(
- path=LearningPath.FRONTEND,
- title="前端开发",
- description="从HTML/CSS基础到现代前端框架",
- icon="🎨",
- modules=[
- LearningModule(
- id="fe-html-css",
- title="HTML & CSS 基础",
- description="网页结构与样式入门",
- icon="📝",
- order=1,
- status=ModuleStatus.NOT_STARTED,
- lessons=[
- LearningLesson(
- id="fe-html-01",
- title="HTML文档结构",
- description="DOCTYPE、head、body标签",
- type="theory",
- duration_minutes=15
- ),
- LearningLesson(
- id="fe-html-02",
- title="常用HTML标签",
- description="标题、段落、链接、图片、列表",
- type="theory",
- duration_minutes=20
- ),
- LearningLesson(
- id="fe-css-01",
- title="CSS选择器",
- description="元素、类、ID、属性选择器",
- type="theory",
- duration_minutes=20
- ),
- LearningLesson(
- id="fe-css-02",
- title="盒模型与布局",
- description="margin、padding、border、display",
- type="practice",
- duration_minutes=30
- ),
- LearningLesson(
- id="fe-css-03",
- title="Flexbox布局",
- description="弹性盒子布局完全指南",
- type="practice",
- duration_minutes=40
- ),
- ]
- ),
- LearningModule(
- id="fe-javascript",
- title="JavaScript 核心",
- description="JavaScript语言基础",
- icon="⚡",
- order=2,
- status=ModuleStatus.LOCKED,
- lessons=[
- LearningLesson(
- id="fe-js-01",
- title="变量与数据类型",
- description="let、const、基本类型与引用类型",
- type="theory",
- duration_minutes=25
- ),
- LearningLesson(
- id="fe-js-02",
- title="函数与作用域",
- description="函数声明、箭头函数、闭包",
- type="theory",
- duration_minutes=30
- ),
- LearningLesson(
- id="fe-js-03",
- title="DOM操作",
- description="查询、修改、创建DOM元素",
- type="practice",
- duration_minutes=40
- ),
- LearningLesson(
- id="fe-js-04",
- title="事件处理",
- description="事件监听、事件委托、事件对象",
- type="practice",
- duration_minutes=35
- ),
- ]
- ),
- LearningModule(
- id="fe-vue",
- title="Vue.js 框架",
- description="现代Vue 3开发",
- icon="💚",
- order=3,
- status=ModuleStatus.LOCKED,
- lessons=[
- LearningLesson(
- id="fe-vue-01",
- title="Vue 3 基础",
- description="模板语法、响应式数据、computed",
- type="theory",
- duration_minutes=30
- ),
- LearningLesson(
- id="fe-vue-02",
- title="组件系统",
- description="组件创建、props、events、slots",
- type="theory",
- duration_minutes=35
- ),
- LearningLesson(
- id="fe-vue-03",
- title="组合式API",
- description="setup、ref、reactive、生命周期",
- type="practice",
- duration_minutes=40
- ),
- LearningLesson(
- id="fe-vue-04",
- title="状态管理",
- description="Pinia状态管理实践",
- type="practice",
- duration_minutes=30
- ),
- ]
- ),
- LearningModule(
- id="fe-project",
- title="实战项目",
- description="构建完整的前端应用",
- icon="🚀",
- order=4,
- status=ModuleStatus.LOCKED,
- lessons=[
- LearningLesson(
- id="fe-proj-01",
- title="项目规划",
- description="需求分析、技术选型、架构设计",
- type="theory",
- duration_minutes=30
- ),
- LearningLesson(
- id="fe-proj-02",
- title="核心功能开发",
- description="实现主要功能模块",
- type="project",
- duration_minutes=120
- ),
- LearningLesson(
- id="fe-proj-03",
- title="优化与部署",
- description="性能优化、构建部署",
- type="project",
- duration_minutes=60
- ),
- ]
- ),
- ]
- )
- def get_backend_path() -> LearningPathData:
- return LearningPathData(
- path=LearningPath.BACKEND,
- title="后端开发",
- description="Python后端开发与API设计",
- icon="⚙️",
- modules=[
- LearningModule(
- id="be-python",
- title="Python 基础",
- description="Python语言核心",
- icon="🐍",
- order=1,
- status=ModuleStatus.NOT_STARTED,
- lessons=[
- LearningLesson(
- id="be-py-01",
- title="Python语法基础",
- description="变量、类型、运算符",
- type="theory",
- duration_minutes=20
- ),
- LearningLesson(
- id="be-py-02",
- title="控制流与函数",
- description="条件、循环、函数定义",
- type="theory",
- duration_minutes=25
- ),
- LearningLesson(
- id="be-py-03",
- title="面向对象编程",
- description="类、继承、多态",
- type="theory",
- duration_minutes=30
- ),
- LearningLesson(
- id="be-py-04",
- title="异常处理与文件操作",
- description="try/except、文件读写",
- type="practice",
- duration_minutes=25
- ),
- ]
- ),
- LearningModule(
- id="be-api",
- title="REST API 设计",
- description="FastAPI构建RESTful服务",
- icon="🔌",
- order=2,
- status=ModuleStatus.LOCKED,
- lessons=[
- LearningLesson(
- id="be-api-01",
- title="HTTP协议基础",
- description="请求方法、状态码、头部",
- type="theory",
- duration_minutes=20
- ),
- LearningLesson(
- id="be-api-02",
- title="FastAPI入门",
- description="路由、请求、响应",
- type="theory",
- duration_minutes=30
- ),
- LearningLesson(
- id="be-api-03",
- title="数据验证",
- description="Pydantic模型、请求验证",
- type="practice",
- duration_minutes=35
- ),
- LearningLesson(
- id="be-api-04",
- title="数据库集成",
- description="SQLAlchemy、数据库操作",
- type="practice",
- duration_minutes=45
- ),
- ]
- ),
- LearningModule(
- id="be-system",
- title="系统设计",
- description="架构设计与最佳实践",
- icon="🏗️",
- order=3,
- status=ModuleStatus.LOCKED,
- lessons=[
- LearningLesson(
- id="be-sys-01",
- title="设计模式",
- description="常用设计模式与应用场景",
- type="theory",
- duration_minutes=40
- ),
- LearningLesson(
- id="be-sys-02",
- title="性能优化",
- description="缓存、异步、并发",
- type="theory",
- duration_minutes=35
- ),
- LearningLesson(
- id="be-sys-03",
- title="安全实践",
- description="认证、授权、数据安全",
- type="practice",
- duration_minutes=30
- ),
- ]
- ),
- LearningModule(
- id="be-project",
- title="实战项目",
- description="构建完整的后端服务",
- icon="🚀",
- order=4,
- status=ModuleStatus.LOCKED,
- lessons=[
- LearningLesson(
- id="be-proj-01",
- title="项目架构",
- description="目录结构、配置管理",
- type="theory",
- duration_minutes=25
- ),
- LearningLesson(
- id="be-proj-02",
- title="核心功能实现",
- description="业务逻辑开发",
- type="project",
- duration_minutes=120
- ),
- LearningLesson(
- id="be-proj-03",
- title="测试与部署",
- description="单元测试、集成测试、部署",
- type="project",
- duration_minutes=60
- ),
- ]
- ),
- ]
- )
- def get_fullstack_path() -> LearningPathData:
- return LearningPathData(
- path=LearningPath.FULLSTACK,
- title="全栈开发",
- description="前端+后端全栈技能",
- icon="🌐",
- modules=[
- LearningModule(
- id="fs-web-basics",
- title="Web基础",
- description="HTML/CSS/JS核心",
- icon="🌍",
- order=1,
- status=ModuleStatus.NOT_STARTED,
- lessons=[
- LearningLesson(
- id="fs-web-01",
- title="HTML/CSS基础",
- description="网页结构与样式",
- type="theory",
- duration_minutes=25
- ),
- LearningLesson(
- id="fs-web-02",
- title="JavaScript基础",
- description="JS核心概念",
- type="theory",
- duration_minutes=30
- ),
- LearningLesson(
- id="fs-web-03",
- title="DOM与事件",
- description="页面交互实现",
- type="practice",
- duration_minutes=35
- ),
- ]
- ),
- LearningModule(
- id="fs-frontend",
- title="前端框架",
- description="Vue.js开发",
- icon="💚",
- order=2,
- status=ModuleStatus.LOCKED,
- lessons=[
- LearningLesson(
- id="fs-fe-01",
- title="Vue 3基础",
- description="组件、响应式、生命周期",
- type="theory",
- duration_minutes=30
- ),
- LearningLesson(
- id="fs-fe-02",
- title="路由与状态",
- description="Vue Router、Pinia",
- type="practice",
- duration_minutes=40
- ),
- ]
- ),
- LearningModule(
- id="fs-backend",
- title="后端开发",
- description="Python + FastAPI",
- icon="⚙️",
- order=3,
- status=ModuleStatus.LOCKED,
- lessons=[
- LearningLesson(
- id="fs-be-01",
- title="Python基础",
- description="语法、OOP、异常处理",
- type="theory",
- duration_minutes=30
- ),
- LearningLesson(
- id="fs-be-02",
- title="FastAPI开发",
- description="路由、验证、数据库",
- type="practice",
- duration_minutes=45
- ),
- ]
- ),
- LearningModule(
- id="fs-fullstack",
- title="全栈实战",
- description="构建完整应用",
- icon="🚀",
- order=4,
- status=ModuleStatus.LOCKED,
- lessons=[
- LearningLesson(
- id="fs-fs-01",
- title="前后端联调",
- description="API对接、数据流",
- type="practice",
- duration_minutes=60
- ),
- LearningLesson(
- id="fs-fs-02",
- title="部署上线",
- description="构建、部署、监控",
- type="project",
- duration_minutes=60
- ),
- ]
- ),
- ]
- )
- def _inject_lesson_content(path_data: LearningPathData):
- """为路径中的所有课程注入Markdown内容"""
- from .lesson_content import get_lesson_content
- for module in path_data.modules:
- for lesson in module.lessons:
- if not lesson.content_markdown:
- lesson.content_markdown = get_lesson_content(
- lesson.id, lesson.title, lesson.type, lesson.description
- )
- def get_learning_path(path: LearningPath) -> LearningPathData:
- if path == LearningPath.FRONTEND:
- data = get_frontend_path()
- elif path == LearningPath.BACKEND:
- data = get_backend_path()
- else:
- data = get_fullstack_path()
- _inject_lesson_content(data)
- return data
- def get_all_paths() -> List[LearningPathData]:
- paths = [
- get_frontend_path(),
- get_backend_path(),
- get_fullstack_path()
- ]
- for p in paths:
- _inject_lesson_content(p)
- return paths
- def find_next_lesson(path_type: str, current_lesson_id: str, completed_lessons: List[str]) -> Optional[Dict]:
- """根据当前课程,找到路径中下一个未完成的课程
-
- Args:
- path_type: 路径类型 ('frontend' / 'backend' / 'fullstack')
- current_lesson_id: 当前课程的 lesson_id
- completed_lessons: 已完成的 lesson_id 列表
-
- Returns:
- 下一个课程的 {title, description, id} 或 None
- """
- try:
- path_enum = LearningPath(path_type)
- path_data = get_learning_path(path_enum)
- except Exception:
- return None
- # 扁平化所有课程(保持顺序)
- all_lessons: List[Dict] = []
- for module in path_data.modules:
- for lesson in module.lessons:
- all_lessons.append({
- "id": lesson.id,
- "title": lesson.title,
- "description": lesson.description,
- "module_title": module.title,
- "module_id": module.id,
- })
- # 找到当前课程在列表中的位置
- current_idx = None
- for i, l in enumerate(all_lessons):
- if l["id"] == current_lesson_id:
- current_idx = i
- break
- if current_idx is None:
- return None
- # 从当前课程之后找第一个未完成的
- for i in range(current_idx + 1, len(all_lessons)):
- if all_lessons[i]["id"] not in completed_lessons:
- return all_lessons[i]
- return None
|