Files
gitlab-instance-0a899031_cn…/config/digital/lessons.ts
2026-06-07 01:17:46 -05:00

113 lines
5.1 KiB
TypeScript
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.
/**
* 课程章节详情配置 - 数字游民主题(来自 nomadlms
*/
const SAMPLE_VIDEO = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4";
const SAMPLE_MARKDOWN = `# 课程概述
本小节将带你理解数字游民的核心概念,掌握关键技能。
## 学习目标
- 理解数字游民的本质与生活方式
- 掌握远程变现的基础路径
- 完成个人定位与规划
## 核心要点
1. **定义**:数字游民 = 远程工作 + 自由旅行 + 地点独立
2. **技能**:选择可远程交付的技能方向
3. **心态**:自律与自由是相辅相成的
## 行动清单
- [ ] 评估自己的技能是否可远程交付
- [ ] 列出3个你想旅居的城市
- [ ] 设定6个月内的转型目标
### 代码示例
\`\`\`bash
# 安装依赖
pnpm install
# 启动开发
pnpm dev
\`\`\`
行内代码示例:\`npm run build\` 可生成生产版本。
## 注意事项
> 数字游民不是逃避,而是主动选择。建议先有稳定收入再考虑长期旅居。
| 项目 | 说明 |
|------|------|
| 收入 | 建议月收入稳定在 1 万以上 |
| 技能 | 至少 1 项可远程交付 |
| 心态 | 自律与自由平衡 |
`;
export type LessonDetail = {
name: string;
duration: string;
videoUrl: string;
markdown: string;
};
/** 扁平化课程数据moduleIndex-lessonIndex 作为 key */
export const LESSONS_MAP: Record<string, LessonDetail> = {
"0-0": {
name: "01 什么是数字游民?你适合吗?",
duration: "11:58",
videoUrl: SAMPLE_VIDEO,
markdown: SAMPLE_MARKDOWN.replace("本小节", "本节").replace("核心概念", "数字游民的定义与自我评估"),
},
"0-1": {
name: "02 从朝九晚五到边旅行边赚钱的路径",
duration: "14:32",
videoUrl: SAMPLE_VIDEO,
markdown: SAMPLE_MARKDOWN.replace("本小节", "本节").replace("核心概念", "从上班族到数字游民的转型路径"),
},
"1-0": {
name: "3.1 最适合远程的5大技能方向",
duration: "06:25",
videoUrl: SAMPLE_VIDEO,
markdown: SAMPLE_MARKDOWN.replace("本小节", "本节").replace("核心概念", "编程、设计、写作、营销、咨询等远程技能"),
},
"1-1": {
name: "3.2 如何打造你的技能组合与作品集",
duration: "07:34",
videoUrl: SAMPLE_VIDEO,
markdown: SAMPLE_MARKDOWN.replace("本小节", "本节").replace("核心概念", "作品集搭建与个人品牌展示"),
},
"2-0": { name: "04 从接单到产品的思维转变", duration: "04:16", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"2-1": { name: "05 打造你的第一个数字产品", duration: "06:18", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"2-2": { name: "06 海外平台接单与变现", duration: "02:30", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"2-3": { name: "07 被动收入组合:课程+会员+咨询", duration: "06:25", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"2-4": { name: "08 如何定价才能既赚又自由", duration: "03:09", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"3-0": { name: "09 数字游民的时间管理心法", duration: "07:49", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"3-1": { name: "09-1 独处与社交的平衡", duration: "01:24", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"3-2": { name: "10 如何应对家人的不理解", duration: "04:07", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"4-0": { name: "11 签证与长期居留规划", duration: "04:12", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"4-1": { name: "12 住宿选择短租、民宿、Co-living", duration: "05:19", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"4-2": { name: "13 网络、保险与紧急预案", duration: "04:11", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"5-0": { name: "14 巴厘岛数字游民社区探访", duration: "12:02", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"5-1": { name: "15 曼谷/清迈生活成本与体验", duration: "09:39", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"5-2": { name: "16 欧洲数字游民签证攻略", duration: "09:04", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"5-3": { name: "17 一人公司如何合法合规运营", duration: "05:12", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"6-0": { name: "18 从一人到小团队的进化", duration: "11:25", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"6-1": { name: "19 建立你的数字游民品牌", duration: "25:57", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"6-2": { name: "20 年度旅居计划与预算规划", duration: "12:34", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
"6-3": { name: "21 长期数字游民的可持续之道", duration: "08:53", videoUrl: SAMPLE_VIDEO, markdown: SAMPLE_MARKDOWN },
};
export function getLessonKey(moduleIndex: number, lessonIndex: number): string {
return `${moduleIndex}-${lessonIndex}`;
}
export function getLesson(moduleIndex: number, lessonIndex: number): LessonDetail | null {
return LESSONS_MAP[getLessonKey(moduleIndex, lessonIndex)] ?? null;
}