Files
root a1daa040ef s
2026-06-07 18:06:52 +08:00

261 lines
12 KiB
TypeScript
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.
/**
* 课程章节详情配置 - 数字游民主题
*/
const VIDEO_BASE_URL = (process.env.NEXT_PUBLIC_DIGITAL_COURSE_VIDEO_BASE_URL || "").replace(/\/$/, "");
export type LessonDetail = {
name: string;
duration: string;
videoUrl?: string;
markdown: string;
};
type LessonInput = {
key: string;
name: string;
duration: string;
focus: string;
outcomes: string[];
actions: string[];
};
function configuredVideoUrl(key: string): string | undefined {
return VIDEO_BASE_URL ? `${VIDEO_BASE_URL}/${key}.mp4` : undefined;
}
function lessonMarkdown(input: LessonInput): string {
const outcomes = input.outcomes.map((item) => `- ${item}`).join("\n");
const actions = input.actions.map((item, index) => `${index + 1}. ${item}`).join("\n");
return `# ${input.name}
本节聚焦:${input.focus}
## 学习目标
${outcomes}
## 实操步骤
${actions}
## 交付物
- 一份可复用的个人数字游民行动记录
- 一个能在下一节继续迭代的决策或执行清单
- 至少一个可以当天完成的小行动
## 复盘问题
1. 这节内容解决了哪个具体卡点?
2. 哪个步骤可以在 24 小时内完成?
3. 继续推进需要补齐哪些资料、工具或联系人?
`;
}
function createLesson(input: LessonInput): LessonDetail {
return {
name: input.name,
duration: input.duration,
videoUrl: configuredVideoUrl(input.key),
markdown: lessonMarkdown(input),
};
}
/** 扁平化课程数据moduleIndex-lessonIndex 作为 key */
export const LESSONS_MAP: Record<string, LessonDetail> = {
"0-0": createLesson({
key: "0-0",
name: "01 什么是数字游民?你适合吗?",
duration: "11:58",
focus: "判断数字游民是不是逃离通勤,而是一种可持续的远程交付和生活系统。",
outcomes: ["识别数字游民的核心条件", "评估自己的收入、技能和风险承受力", "排除对自由工作的常见误解"],
actions: ["写下当前收入来源和远程交付比例", "给自己的自律、现金流、社交支持打分", "决定先试运行 30 天还是直接规划迁移"],
}),
"0-1": createLesson({
key: "0-1",
name: "02 从朝九晚五到边旅行边赚钱的路径",
duration: "14:32",
focus: "把固定工位迁移到远程工作流,而不是直接辞职旅行。",
outcomes: ["拆解远程转型的三条路线", "制定离职前缓冲区", "建立第一版旅居节奏"],
actions: ["选择远程全职、自由职业或一人公司路线", "计算 6 个月现金缓冲", "把第一站拆成 2 周试住计划"],
}),
"1-0": createLesson({
key: "1-0",
name: "3.1 最适合远程的5大技能方向",
duration: "06:25",
focus: "找到可在线交付、可复用、可持续涨价的技能组合。",
outcomes: ["了解编程、设计、写作、运营、咨询的交付差异", "判断自己的技能迁移成本", "确定一个主技能和一个辅助技能"],
actions: ["列出过去一年被别人付费认可的能力", "给每项能力标注交付周期和可远程程度", "选出最适合 30 天验证的技能方向"],
}),
"1-1": createLesson({
key: "1-1",
name: "3.2 如何打造你的技能组合与作品集",
duration: "07:34",
focus: "用作品证明能力,用案例降低客户或雇主的决策成本。",
outcomes: ["设计作品集结构", "把技能翻译成商业结果", "准备远程岗位或客户沟通材料"],
actions: ["挑 3 个最能体现结果的项目", "为每个项目写背景、行动、结果", "整理一个可公开分享的作品集链接"],
}),
"2-0": createLesson({
key: "2-0",
name: "04 从接单到产品的思维转变",
duration: "04:16",
focus: "从按小时卖时间,转向可以复制交付的产品化服务。",
outcomes: ["识别重复交付场景", "把服务拆成标准套餐", "设置交付边界"],
actions: ["记录最近 5 次重复沟通的问题", "把其中一个问题做成固定报价包", "写清交付范围、周期和验收标准"],
}),
"2-1": createLesson({
key: "2-1",
name: "05 打造你的第一个数字产品",
duration: "06:18",
focus: "用最小版本验证付费意愿,而不是先做复杂产品。",
outcomes: ["定义第一版数字产品", "设计购买理由", "搭建轻量交付流程"],
actions: ["选择模板、课程、咨询或工具包形式", "写一句明确的购买承诺", "找 5 个潜在用户做需求确认"],
}),
"2-2": createLesson({
key: "2-2",
name: "06 海外平台接单与变现",
duration: "02:30",
focus: "用平台建立第一批跨境信任和可追踪收入。",
outcomes: ["选择适合自己的接单平台", "优化个人简介和服务页", "设置首单策略"],
actions: ["选择一个平台完善头像、标题和案例", "写 3 个细分服务描述", "每天发送 5 条高质量提案并记录转化"],
}),
"2-3": createLesson({
key: "2-3",
name: "07 被动收入组合:课程+会员+咨询",
duration: "06:25",
focus: "组合内容、社群和高客单咨询,降低单一收入波动。",
outcomes: ["理解三层收入结构", "设计低中高客单产品", "规划内容到付费的路径"],
actions: ["列出一个免费内容主题", "设计一个中价产品和一个高价服务", "写出用户从关注到购买的 4 步路径"],
}),
"2-4": createLesson({
key: "2-4",
name: "08 如何定价才能既赚又自由",
duration: "03:09",
focus: "用价值、稀缺性和交付成本共同决定价格。",
outcomes: ["区分成本定价和价值定价", "设置最低可接受价格", "避免用低价换取无边界需求"],
actions: ["计算每月目标收入和可售工时", "给核心服务设置 3 档价格", "写下每档价格对应的交付范围"],
}),
"3-0": createLesson({
key: "3-0",
name: "09 数字游民的时间管理心法",
duration: "07:49",
focus: "在地点自由中保留深度工作、交付节奏和恢复时间。",
outcomes: ["建立旅居工作日模板", "识别时区和移动带来的损耗", "减少低质量在线状态"],
actions: ["设计一个 4 小时深度工作窗口", "把会议集中到固定时段", "为移动日设置低负荷任务清单"],
}),
"3-1": createLesson({
key: "3-1",
name: "09-1 独处与社交的平衡",
duration: "01:24",
focus: "避免旅居中的孤独感和过度社交同时拖垮状态。",
outcomes: ["识别自己的社交能量曲线", "建立轻量连接机制", "保留独处恢复空间"],
actions: ["设定每周两次高质量社交", "加入一个本地或线上社群", "给自己安排固定无社交时段"],
}),
"3-2": createLesson({
key: "3-2",
name: "10 如何应对家人的不理解",
duration: "04:07",
focus: "用计划、边界和阶段性结果降低家人的担忧。",
outcomes: ["理解家人反对背后的风险感", "准备可沟通的安全方案", "建立阶段性汇报机制"],
actions: ["写出收入、保险、住宿和返程预案", "把计划拆成 30 天试运行", "和家人约定一次复盘时间"],
}),
"4-0": createLesson({
key: "4-0",
name: "11 签证与长期居留规划",
duration: "04:12",
focus: "把停留时间、工作合法性和税务风险纳入路线设计。",
outcomes: ["区分旅游签、长期签和数字游民签", "记录不同目的地停留约束", "准备基础材料清单"],
actions: ["为 3 个候选目的地记录签证天数", "整理护照、收入证明、保险和住宿材料", "设置到期前 30 天提醒"],
}),
"4-1": createLesson({
key: "4-1",
name: "12 住宿选择短租、民宿、Co-living",
duration: "05:19",
focus: "用工作效率、社区和成本评估住宿,而不只看房间照片。",
outcomes: ["比较三类住宿的适用场景", "检查网络和办公条件", "降低长租踩坑风险"],
actions: ["列出硬性条件:网速、桌椅、噪音、交通", "首站先订 7 到 14 天", "到达后再决定是否续住"],
}),
"4-2": createLesson({
key: "4-2",
name: "13 网络、保险与紧急预案",
duration: "04:11",
focus: "提前准备影响交付和安全的底层保障。",
outcomes: ["建立双网络方案", "选择覆盖远程旅居的保险", "准备紧急联系人和备份文件"],
actions: ["配置本地 SIM 与备用 eSIM", "把护照、签证、保单加密备份", "写一份丢设备或生病时的处理流程"],
}),
"5-0": createLesson({
key: "5-0",
name: "14 巴厘岛数字游民社区探访",
duration: "12:02",
focus: "用社区密度、工作空间和生活成本判断热门目的地。",
outcomes: ["了解社区活跃度的判断方法", "识别热门目的地的隐性成本", "设计探访型旅居计划"],
actions: ["查询当地共享办公和活动频率", "对比旺季与淡季住宿成本", "计划一次本地社群活动参与"],
}),
"5-1": createLesson({
key: "5-1",
name: "15 曼谷/清迈生活成本与体验",
duration: "09:39",
focus: "对比大城市效率和慢生活成本,选择适合自己的泰国基地。",
outcomes: ["建立月预算结构", "比较交通、住宿、社交和签证便利度", "决定短住或长期基地策略"],
actions: ["分别估算曼谷和清迈月预算", "列出生活便利度与工作效率权重", "选择一个城市做 2 周试住"],
}),
"5-2": createLesson({
key: "5-2",
name: "16 欧洲数字游民签证攻略",
duration: "09:04",
focus: "把申签门槛、税务居民规则和生活成本一起比较。",
outcomes: ["理解欧洲数字游民签证常见要求", "识别税务居民风险", "建立候选国家比较表"],
actions: ["记录收入门槛、停留期、保险要求", "查询 183 天规则和本地税务提示", "选出 2 个最适合申请的国家"],
}),
"5-3": createLesson({
key: "5-3",
name: "17 一人公司如何合法合规运营",
duration: "05:12",
focus: "用合同、收款、发票和税务记录支撑长期自由工作。",
outcomes: ["建立基础合同意识", "区分个人收款和公司收款", "保留可追溯经营记录"],
actions: ["准备一份服务合同模板", "整理收款账户和发票流程", "每月固定归档收入、支出和合同"],
}),
"6-0": createLesson({
key: "6-0",
name: "18 从一人到小团队的进化",
duration: "11:25",
focus: "把可重复任务交给协作者,而不是把自己变成管理瓶颈。",
outcomes: ["判断哪些任务适合外包", "设计协作流程", "建立质量验收标准"],
actions: ["列出每周重复且低杠杆的任务", "写一份任务 SOP", "找一个协作者做 7 天试合作"],
}),
"6-1": createLesson({
key: "6-1",
name: "19 建立你的数字游民品牌",
duration: "25:57",
focus: "用长期内容和真实案例建立信任,而不是只展示旅行照片。",
outcomes: ["确定品牌定位", "设计内容栏目", "把个人经历转成可复用资产"],
actions: ["写一句定位:帮助谁解决什么问题", "规划 3 个持续更新的内容栏目", "发布一篇包含结果数据的复盘"],
}),
"6-2": createLesson({
key: "6-2",
name: "20 年度旅居计划与预算规划",
duration: "12:34",
focus: "用年度视角安排目的地、收入周期和恢复期。",
outcomes: ["规划年度目的地节奏", "匹配收入和支出波峰", "预留缓冲和回撤计划"],
actions: ["把一年分为工作冲刺、移动、恢复三类月份", "为每站设置预算上限", "预留至少两个月现金缓冲"],
}),
"6-3": createLesson({
key: "6-3",
name: "21 长期数字游民的可持续之道",
duration: "08:53",
focus: "让自由工作成为长期系统,而不是短期兴奋。",
outcomes: ["建立健康、收入、关系三条底线", "设计季度复盘机制", "决定何时停留或迁移"],
actions: ["写下不可牺牲的三条底线", "每季度复盘收入、健康、关系和成长", "为下一站设置明确迁移理由"],
}),
};
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;
}