Files
test-repo/docs/.vitepress/theme/index.js
T
sanbuphy a4b583b13f feat(docs): integrate version2 curriculum and stage-3 updates
概要
- 将 version2 分支的课程结构重构、第三阶段章节新增、示例资源迁移、高级 RAG 文档与 Vercel 部署配置等整合为 main 上的一次汇总提交

内容导航与 README 调整
- 更新 README 的总体介绍文案,引入“第零阶段 + 第一到第三阶段”的完整学习路径描述
- 将原先的“三阶段实战路径”说明替换为新版分阶段描述,突出从小游戏到跨平台复杂应用的学习节奏
- 删除已过时的“第二次更新将在分支 version2 合并到主分支”的提示,改为直接以 main 为主线
- 统一 README 顶部标题和排版风格,保证中英文导航、徽章展示等视觉结构一致

课程结构与章节导航更新
- 调整 docs 目录下的学习阶段导航结构,使 README 中的导航表与各 stage 实际目录对齐
- 补全并创建 stage-3 相关章节入口文件,用于承载高级阶段的课程内容
- 新增或更新以下章节入口:
  - 高级核心技能:
    - docs/stage-3/core-skills/3.1-mcp-claudecode-skills/index.md
    - docs/stage-3/core-skills/3.2-long-running-tasks/index.md
  - 多平台开发:
    - docs/stage-3/cross-platform/3.3-wechat-miniprogram/index.md
    - docs/stage-3/cross-platform/3.4-wechat-miniprogram-backend/index.md
    - docs/stage-3/cross-platform/3.5-android-app/index.md
    - docs/stage-3/cross-platform/3.6-ios-app/index.md
  - 个人品牌:
    - docs/stage-3/personal-brand/3.7-personal-website-blog/index.md
- 保持 stage-0、stage-1、stage-2 既有章节结构不变的前提下,对导航表格进行排版和链接校正,使整体课程地图清晰、可点击

示例与图片资源重组
- 将原先位于 docs/examples/example1/images/ 下的微信小程序示例图片,整体迁移到 stage-3 的正式课程路径中:
  - 目标路径:docs/stage-3/3.3-how-to-build-a-wechat-miniprogram/example1/images/
- 通过 rename 方式保留 git 历史关系,避免图片资源被视为完全新增,从而方便后续追踪
- 为微信小程序示例新增 index 页面:
  - docs/stage-3/3.3-how-to-build-a-wechat-miniprogram/example1/index.md
- 使该示例在“高级三:多平台开发:如何构建微信小程序”章节中有清晰的入口,对应实际实战内容

高级 RAG 与 AI 进阶文档
- 新增一篇系统介绍 RAG 的高级文档:
  - docs/stage-3/ai-advanced/3.a1-rag-introduction/extra5-what-is-rag-and-how-does-it-work-and-future.md
- 覆盖内容包括:RAG 的基本概念、典型架构、工作流程以及未来演进方向,为第三阶段的复杂应用提供知识检索基础
- 配套引入多张插图,帮助读者从架构图和流程视角理解 RAG:
  - docs/stage-3/ai-advanced/3.a1-rag-introduction/images/image1.png ~ image15.png

部署与工程配置
- 新增 vercel.json 配置文件,为项目在 Vercel 上的部署提供基础配置
  - 明确文档构建产物的输出路径和静态站点托管方式
  - 为之后的一键部署和自动化预览打下基础

依赖与锁文件更新
- 调整 package.json 中与新版文档结构和部署相关的配置,保持脚本和依赖与当前课程形态同步
- 更新 package-lock.json,以反映最新的依赖树和版本锁定状态
- 保证在执行 npm install / npm run build 时,依赖环境与 version2 中的实际使用情况一致

兼容性与行为说明
- 该提交通过 npm run build 验证,确保在整合 version2 内容后,VitePress 构建过程正常完成
- main 分支上的历史被压缩为一条有语义的“第二次大更新”提交,详细的开发过程仍保留在 version2 分支,用于后续需要时回溯
2026-01-12 12:25:44 +08:00

120 lines
3.4 KiB
JavaScript
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.
import DefaultTheme from 'vitepress/theme'
import Viewer from 'viewerjs'
import 'viewerjs/dist/viewer.css'
import TypeIt from 'typeit'
import { onMounted, watch, nextTick } from 'vue'
import { useRoute, useData } from 'vitepress'
import './style.css'
export default {
extends: DefaultTheme,
setup() {
const route = useRoute()
const { frontmatter } = useData()
let viewer = null
const initViewer = () => {
// 销毁旧实例
if (viewer) {
viewer.destroy()
viewer = null
}
// 找到文章内容容器
const doc = document.querySelector('.vp-doc')
if (doc) {
// 初始化 Viewer,配置一些常用选项
viewer = new Viewer(doc, {
button: true, // 显示右上角关闭按钮
navbar: true, // 显示底部缩略图导航
title: true, // 显示图片标题(alt 属性)
toolbar: true, // 显示工具栏(缩放、旋转等)
tooltip: true, // 显示缩放百分比
movable: true, // 允许拖拽
zoomable: true, // 允许缩放
rotatable: true, // 允许旋转
scalable: true, // 允许翻转
transition: false, // 禁用自带动画,确保打开瞬间无飞入
fullscreen: true, // 允许全屏播放
shown() {
// 打开完成后,标记为 readyCSS 此时才会介入 transition
document.body.classList.add('viewer-ready')
},
hide() {
// 关闭前移除标记,确保关闭瞬间无动画
document.body.classList.remove('viewer-ready')
},
keyboard: true, // 允许键盘控制
url: 'src', // 图片源
// 过滤掉不想查看的图片(比如表情包等小图标,如果需要的话)
filter(image) {
return !image.classList.contains('no-viewer')
}
})
}
}
const initTypewriter = () => {
const taglineData = frontmatter.value.hero?.tagline
if (Array.isArray(taglineData) && taglineData.length > 0) {
const taglineEl = document.querySelector('.VPHomeHero .tagline')
if (taglineEl) {
taglineEl.innerHTML = ''
const typeIt = new TypeIt(taglineEl, {
speed: 50,
startDelay: 500,
loop: true
})
taglineData.forEach((text) => {
typeIt.type(text).pause(2000).delete().pause(500)
})
typeIt.go()
}
}
}
const optimizeImages = () => {
const images = document.querySelectorAll('.vp-doc img')
images.forEach(img => {
if (img.complete) {
applyImageStyle(img)
} else {
img.onload = () => applyImageStyle(img)
}
})
}
const applyImageStyle = (img) => {
const { naturalWidth, naturalHeight } = img
if (!naturalWidth || !naturalHeight) return
const ratio = naturalHeight / naturalWidth
img.classList.remove('img-tall', 'img-very-tall')
if (ratio > 2) {
img.classList.add('img-very-tall')
} else if (ratio > 1.2) {
img.classList.add('img-tall')
}
}
onMounted(() => {
initViewer()
initTypewriter()
optimizeImages()
})
watch(
() => route.path,
() => nextTick(() => {
initViewer()
initTypewriter()
optimizeImages()
})
)
}
}