Skip to content

Chandler-Song/firefly

Repository files navigation

Firefly - 个人职业形象门户 (Personal Portfolio)

Firefly 是一个基于 React 18 + TypeScript + Vite 构建的高性能个人职业形象门户。它旨在帮助专业人士构建模块化的知识中枢,系统化展示专业价值与思想深度。

🚀 项目架构

项目采用模块化设计,数据与 UI 分离,支持 Markdown/MDX 内容驱动。

.
├── .github/workflows/   # CI/CD 自动化部署配置
├── public/              # 静态资源 (包含 .nojekyll 确保资源加载)
├── src/
│   ├── assets/          # 本地图片、字体等资源
│   ├── components/      # 通用 UI 原子组件
│   ├── content/         # Markdown 内容源 (博客、知识分享)
│   ├── data/            # 结构化 JSON 数据 (简历、工具、社交链接)
│   ├── layouts/         # 页面容器布局
│   ├── pages/           # 核心功能页面 (Resume, Blog, Social 等)
│   ├── types/           # TypeScript 类型定义
│   ├── utils/           # 工具函数 (Markdown 解析等)
│   ├── App.tsx          # 路由配置中心
│   └── main.tsx         # 项目入口
├── tailwind.config.js   # Tailwind CSS 样式配置
├── vite.config.ts       # Vite 构建与部署配置
└── package.json         # 依赖管理与脚本

🛠 快速上手

1. 本地开发

# 安装依赖
npm install

# 启动开发服务器
npm run dev

2. 构建与部署

项目已配置 GitHub Actions,只需推送代码到 main 分支即可自动部署。

git add .
git commit -m "feat: your message"
git push origin main

⚠️ 常见错误与解决方案 (Troubleshooting)

在项目搭建和部署过程中,你可能会遇到以下典型问题:

1. GitHub 推送权限问题

  • 错误信息: remote: Invalid username or token. Password authentication is not supported.
  • 原因: GitHub 禁用了密码认证。
  • 解决: 使用 Personal Access Token (PAT)。确保生成的 Token 勾选了 repoworkflow (修改 Action 脚本需要) 权限。

2. 部署后页面空白 (路由问题)

  • 错误信息: 访问 https://<user>.github.io/firefly/ 却不显示内容。
  • 解决:
    1. vite.config.ts 中设置 base: '/firefly/' (或 ./)。
    2. App.tsx 中为 BrowserRouter 设置 basename="/firefly"

3. 部署后 JS/CSS 404 错误 (Jekyll 干扰)

  • 错误信息: Failed to load resource: the server responded with a status of 404
  • 原因: GitHub Pages 默认使用的 Jekyll 引擎会忽略下划线 _ 开头的文件。
  • 解决: 在 public/ 目录下创建一个空的 .nojekyll 文件,禁用 Jekyll 引擎。

4. 导入路径带后缀错误

  • 错误信息: An import path can only end with a '.tsx' extension when 'allowImportingTsExtensions' is enabled.
  • 解决: 在 TypeScript 项目中,import 本地组件时不要.tsx 后缀。例如:使用 import App from './App' 而不是 import App from './App.tsx'

📌 注意事项

  1. 部署分支: 请确保在 GitHub 仓库的 Settings -> Pages 中,Source 选择 Deploy from a branch,且分支设置为 gh-pages
  2. 数据更新: 若要修改简历或链接,只需编辑 src/data/*.json 文件,无需修改组件代码。
  3. CI/CD 权限: 在 Settings -> Actions -> General 中,确保 Workflow permissions 设置为 Read and write permissions

🌟 核心功能

  • 个人简历: 结构化展示教育与工作经历。
  • 社交聚合: 聚合 GitHub、LinkedIn 等专业平台。
  • 内容引擎: 支持通过 Markdown 发布博客与知识分享。
  • 响应式设计: 完美适配移动端与暗黑模式。

🔗 社交媒体配置指南 (Social Media Configuration)

项目采用集中式配置管理社交媒体链接,支持通过简单的 JSON 配置实现首页、社交页面等多处统一展示。

1. 配置文件位置

社交媒体链接的配置文件位于:src/data/social.json

2. 配置项字段说明

每个社交平台配置项包含以下字段:

字段 类型 必填 说明
platform String 平台名称(如 GitHub、LinkedIn、WeChat)
url String 链接地址(支持 https://、mailto:、skype: 等协议)
icon String 图标名称(来自 Lucide React 图标库)
showInHomePage Boolean 是否在首页显示(默认 true)
ariaLabel String 无障碍标签(用于屏幕阅读器)
openInNewTab Boolean 是否在新窗口打开(默认 true)

3. 配置示例

标准外部链接配置

{
  "platform": "GitHub",
  "url": "https://github.com/chandler-song",
  "icon": "Github",
  "showInHomePage": true,
  "ariaLabel": "访问 Chandler 的 GitHub",
  "openInNewTab": true
}

邮件链接配置

{
  "platform": "Email",
  "url": "mailto:275737875@qq.com",
  "icon": "Mail",
  "showInHomePage": true,
  "ariaLabel": "发送邮件给 Chandler",
  "openInNewTab": false
}

内部路由链接配置(微信二维码页面)

{
  "platform": "WeChat",
  "url": "/wechat-qrcode",
  "icon": "MessageSquare",
  "showInHomePage": true,
  "ariaLabel": "查看 Chandler 的微信二维码",
  "openInNewTab": false
}

Skype 协议链接配置

{
  "platform": "Skype",
  "url": "skype:chandler.song?chat",
  "icon": "Phone",
  "showInHomePage": true,
  "ariaLabel": "通过 Skype 联系 Chandler",
  "openInNewTab": false
}

4. 图标选择指南

项目使用 Lucide React 图标库,以下是常用社交平台的推荐图标:

平台 推荐图标 说明
GitHub Github 原生支持
LinkedIn Linkedin 原生支持
Twitter/X Twitter 原生支持
YouTube Youtube 原生支持
邮箱 Mail 通用邮件图标
微信 MessageSquare 聊天消息框
Skype Phone 电话/语音通话
CSDN BookOpen 技术博客/文档
微博 Share2 社交分享
掘金 Code2 技术开发平台
知乎 Users 社区/问答
Telegram Send 即时通讯

5. 添加新社交平台

src/data/social.json 文件的数组中添加新配置项即可:

[
  // ... 现有配置 ...
  {
    "platform": "知乎",
    "url": "https://www.zhihu.com/people/chandler-song",
    "icon": "Users",
    "showInHomePage": false,
    "ariaLabel": "访问 Chandler 的知乎主页",
    "openInNewTab": true
  }
]

6. 控制首页显示

通过 showInHomePage 字段灵活控制哪些社交链接在首页展示:

  • 首页显示:设置 "showInHomePage": true
  • 仅在社交页显示:设置 "showInHomePage": false
  • 默认行为:若不设置该字段,默认为 true(显示在首页)

7. 使用场景

配置的社交链接会自动在以下位置展示:

  1. 首页 Hero 区域:仅显示 showInHomePage: true 的链接
  2. 社交页面 (/social):显示所有配置的社交链接
  3. 其他自定义组件:可导入 social.json 在任意位置使用

8. 技术实现说明

  • 配置化管理:所有社交链接集中在 src/data/social.json,遵循 DRY 原则
  • 类型安全:在 src/types/index.ts 中定义了 SocialLink 接口
  • 动态图标:通过 import * as Icons from 'lucide-react' 动态引用图标组件
  • 过滤逻辑:在 Home.tsx 中使用 filter 方法筛选首页显示的链接

9. 常见问题

Q: 如何添加自定义图标?
A: Lucide React 提供了 1600+ 图标。如果找不到合适的,可以使用通用图标如 LinkGlobeAtSign 等。

Q: 能否使用图片作为图标?
A: 当前架构基于 Lucide React 图标库。如需使用自定义图片,需修改 Home.tsxSocial.tsx 组件的渲染逻辑。

Q: 微信链接为什么使用内部路由?
A: 微信没有网页版个人主页,因此创建了 /wechat-qrcode 页面展示二维码,用户需将二维码图片放在 public/wechat-qrcode.png

Q: 如何调整社交图标的顺序?
A: 调整 social.json 中配置项的顺序即可,系统会按数组顺序渲染。

👤 个人头像配置指南 (Avatar Configuration)

项目支持在首页和简历页展示个人头像,通过集中式配置管理实现灵活控制。

1. 功能概述

个人头像功能为页面添加了更具个性化和专业感的视觉元素:

  • 首页展示:头像显示在 Hero 区域顶部,作为个人品牌的视觉焦点
  • 简历页展示:头像与个人信息组成卡片式布局,提升简历的专业性
  • 配置化管理:通过 JSON 配置文件控制头像的显示、路径等属性
  • 响应式设计:自动适配桌面端和移动端,确保在各种设备上的最佳显示效果

2. 配置文件说明

配置文件位置

头像配置文件位于:src/data/profile.json

配置字段详解

字段 类型 必填 说明
name String 个人姓名(用于简历页显示)
title String 职位/头衔(如:前端架构师)
subtitle String 个人简介/副标题
avatar.enabled Boolean 是否启用头像功能
avatar.path String 头像图片路径(相对于 public 目录)
avatar.alt String 图片替代文本(用于无障碍访问)

配置示例

{
  "name": "Chandler",
  "title": "前端架构师",
  "subtitle": "专注于前端开发与架构",
  "avatar": {
    "enabled": true,
    "path": "/avatar.jpg",
    "alt": "Chandler 的头像"
  }
}

3. 样式特性

视觉设计

  • 圆形头像:采用 rounded-full 实现完美的圆形效果
  • 柔和渐变光晕:使用 from-primary/10 via-primary/5 to-transparent 的三级渐变
    • 饱和度低至 5%-10%,确保视觉柔和自然
    • 对角渐变(to-br)提供更丰富的层次感
  • 精细边框:2px 半透明边框(border-border/50),与页面整体风格协调
  • 柔和阴影
    • 首页:shadow-lg(常规)→ shadow-xl(悬停)
    • 简历页:shadow-md(常规)→ shadow-lg(悬停)

响应式尺寸

设备类型 首页尺寸 简历页尺寸
移动端 128×128px 128×128px
桌面端 160×160px 144×144px

交互效果

  • 悬停增强
    • 光晕透明度从 60% 提升至 80%(变化幅度仅 20%,过渡平滑)
    • 边框添加微弱的主题色(border-primary/20
    • 阴影强度轻微增加
  • 过渡动画:所有变化均采用 500ms 缓慢过渡(transition-all duration-500
  • 模糊效果:使用 blur-sm 实现细腻的光晕模糊

4. 页面集成

首页 (Home.tsx)

  • 位置:Hero Section 顶部,主标题上方
  • 布局:垂直居中对齐,作为视觉焦点
  • 特点
    • 独立展示,不与其他元素重叠
    • 光晕效果更明显,强调个人品牌
    • 尺寸较大,确保视觉冲击力

简历页 (Resume.tsx)

  • 位置:页面顶部个人信息卡片区域
  • 布局
    • 桌面端:头像在左,个人信息在右(横向布局)
    • 移动端:头像在上,个人信息在下(纵向布局)
  • 特点
    • 卡片式设计,带渐变背景(from-muted/30 via-muted/10
    • 与姓名、职位、简介信息协调统一
    • 尺寸适中,保持整体平衡

5. 技术实现

TypeScript 类型定义

src/types/index.ts 中定义了 ProfileConfig 接口:

export interface ProfileConfig {
  name: string;
  title: string;
  subtitle: string;
  avatar: {
    enabled: boolean;
    path: string;
    alt: string;
  };
}

错误处理机制

当头像图片加载失败时,系统会自动显示美观的 SVG 占位符:

  • 占位符设计:中性色渐变背景 + 用户图标
  • 颜色方案:使用 muted 色系确保与页面风格一致
  • 自动替换:通过 onError 事件监听实现无感切换

响应式实现

  • Tailwind 断点:使用 md: 前缀区分移动端和桌面端样式
  • 弹性布局:简历页使用 flex-col md:flex-row 实现自适应布局
  • 尺寸适配:通过 w-32 h-32 md:w-40 md:h-40 实现不同设备的尺寸调整

6. 使用指南

步骤 1:准备头像图片

  1. 选择图片

    • 推荐使用正方形照片
    • 建议分辨率:至少 400×400px(支持高清显示)
    • 文件格式:JPG、PNG、WebP 均可
  2. 图片命名

    • 建议使用简洁的名称,如 avatar.jpgprofile.png
    • 避免使用中文或特殊字符

步骤 2:上传图片到项目

将准备好的头像图片放置到 public/ 目录:

cp your-avatar.jpg /path/to/project/public/avatar.jpg

步骤 3:更新配置文件

编辑 src/data/profile.json,确保 avatar.path 指向正确的图片:

{
  "avatar": {
    "enabled": true,
    "path": "/avatar.jpg",  // 确保与实际文件名一致
    "alt": "您的姓名 的头像"
  }
}

步骤 4:验证效果

启动开发服务器查看效果:

npm run dev

访问以下页面验证头像显示:

  • 首页:http://localhost:5173/
  • 简历页:http://localhost:5173/resume

临时禁用头像

如需临时隐藏头像,只需将 enabled 设置为 false

{
  "avatar": {
    "enabled": false,
    "path": "/avatar.jpg",
    "alt": "Chandler 的头像"
  }
}

7. 最佳实践

图片优化建议

优化项 推荐值 说明
分辨率 400×400px - 800×800px 平衡清晰度与加载速度
文件大小 < 200KB 确保快速加载
格式选择 WebP > PNG > JPG WebP 提供最佳压缩率
背景处理 纯色或透明背景 避免复杂背景影响视觉效果

图片命名规范

✅ 推荐命名方式:
- avatar.jpg
- profile.png
- headshot.webp

❌ 不推荐命名方式:
- 我的照片.jpg(包含中文)
- my photo 2024.png(包含空格)
- IMG_1234.JPG(无语义)

视觉建议

  1. 照片质量

    • 使用专业或半专业的照片
    • 确保光线充足,面部清晰
    • 背景简洁,避免杂乱元素
  2. 构图建议

    • 头部和肩部占画面的 60%-80%
    • 保持正面或 3/4 侧面角度
    • 眼神自然,表情亲和
  3. 一致性

    • 与其他平台(LinkedIn、GitHub)使用相同或相似的头像
    • 保持个人品牌形象的连贯性

8. 常见问题

Q: 头像图片不显示怎么办?
A: 请检查以下几点:

  1. 图片文件是否正确放置在 public/ 目录下
  2. profile.json 中的 path 是否与实际文件名一致(包括扩展名)
  3. 图片文件是否损坏,可以尝试在浏览器中直接访问 http://localhost:5173/avatar.jpg
  4. 如果使用了相对路径,确保路径以 / 开头

Q: 如何更换头像?
A: 有两种方式:

  1. 替换文件:直接用新图片替换 public/ 目录下的原头像文件(保持文件名不变)
  2. 更新配置:上传新图片并修改 profile.json 中的 path 字段

Q: 能否使用外部链接的图片?
A: 可以,但不推荐。将 path 设置为完整的 URL 即可:

{
  "avatar": {
    "path": "https://example.com/avatar.jpg"
  }
}

不推荐的原因:

  1. 依赖外部服务的稳定性
  2. 可能影响加载速度
  3. 存在跨域和隐私问题

Q: 如何调整头像大小?
A: 头像尺寸通过 Tailwind CSS 类控制,如需自定义:

  • 修改 Home.tsx 中的 w-32 h-32 md:w-40 md:h-40
  • 修改 Resume.tsx 中的 w-32 h-32 md:w-36 md:h-36
  • 数字表示 Tailwind 单位(1单位 = 0.25rem = 4px)

Q: 头像显示不清晰怎么办?
A: 确保原图分辨率足够高:

  • 移动端显示最大 160px,建议原图至少 320px(2倍)
  • 桌面端显示最大 160px,建议原图至少 400px
  • 支持高 DPI 屏幕(如 Retina),建议提供 800px 的高清图片

Q: 占位符图标能否自定义?
A: 可以修改组件代码中的 SVG 路径,或替换为其他 Lucide React 图标。当前使用的是标准用户图标(User Profile),符合大多数场景需求。

📝 内容管理指南 (CRUD 教程)

本节将详细介绍如何管理项目中的六个核心模块:知识 (Knowledge)、博客 (Blog)、洞察 (Insights)、工具 (Tools)、笔记 (Notes)、成就 (Achievements)

1. 新增内容 (Create)

为模块添加新条目,请遵循以下步骤:

  1. 确定目录:根据模块类型,进入对应的 src/content/ 子目录:
    • src/content/knowledge/
    • src/content/blog/
    • src/content/insights/
    • src/content/tools/
    • src/content/notes/
    • src/content/achievements/
  2. 创建文件:新建一个以 .md 结尾的 Markdown 文件。
    • 命名规则:建议使用小写字母和连字符(kebab-case),例如 my-new-post.md。文件名将作为访问该条目的 slug(即 URL 的一部分)。
  3. 编写 Frontmatter 元数据:在文件最顶部添加 YAML 格式的配置信息。
    ---
    title: "文章标题"
    date: "2026-02-02"
    category: "技术分类"
    summary: "这是内容摘要,将显示在列表页。"
    tags: ["标签1", "标签2"]
    ---
  4. 编写正文:在第二个 --- 之后开始编写 Markdown 内容。

2. 删除内容 (Delete)

  1. 物理删除:直接删除 src/content/[module]/ 目录下对应的 .md 文件即可。
  2. 自动生效:由于系统采用动态加载机制,删除文件后,列表页和详情页将自动不再显示该条目,无需手动清理其他引用。

3. 修改内容 (Update)

  1. 编辑文件:打开对应的 .md 文件。
  2. 更新字段:您可以随时修改 Frontmatter 中的 titledatesummary 等。
  3. 保存验证
    • 开发环境:保存后浏览器会通过 HMR 自动热更新。
    • 生产环境:提交代码并推送至 GitHub,Action 自动部署后生效。

4. 查询与检索 (Read)

  1. 列表页访问:通过导航栏或 URL 直接访问模块主页,例如 /blog
  2. 详情页定位:点击列表项,系统会根据文件名生成路由跳转,格式为 /[module]/[filename-without-ext]。例如访问 blog/my-post.md 的 URL 为 /blog/my-post

5. 技术实现说明

  • 动态加载 (import.meta.glob):在 src/utils/markdown.ts 中,我们使用了 Vite 提供的批量导入功能,它会在构建时自动扫描 src/content/ 目录下的所有文件,避免了手动维护文件索引。
  • 前端解析:为了兼容浏览器环境,我们避开了 Node.js 特有的 Buffer 对象,采用正则表达式手动解析 Frontmatter YAML 块。
  • 路由配置:在 src/App.tsx 中使用了 React Router 的动态参数路由 path="/[module]/:slug",通过 useParams 获取文件名并加载内容。

6. 常见问题排查 (Troubleshooting)

  • "Buffer is not defined"

    • 原因:使用了依赖 Node.js 内置模块的 gray-matter
    • 解决:本项目已在 src/utils/markdown.ts 中切换为纯前端正则解析方案,从源头上规避了此报错。
  • 页面显示“加载中...”且不更新

    • 排查:检查 src/utils/markdown.ts 中的 import.meta.glob 路径;确保 Markdown 文件头部格式正确。
  • 图片无法显示

    • 解决:相对路径引用的图片在子路径部署时易失效。建议将图片存放在 public/assets/ 并使用绝对路径访问。

    🎙️ 对话访谈模块指南 (Interviews Guide)

    项目包含一个功能强大的“对话访谈”模块,支持通过 Markdown 驱动自动生成嘉宾主页与访谈对话。

    1. 快速创建访谈

    1. 新建文件:在 src/content/interviews/ 目录下创建一个新的 .md 文件。
    2. 命名规范:遵循 YYYY-MM-DD-受访者姓名-领域关键词.md 格式。
      • 示例2026-02-04-sarah-chen-ai-agent-field.md
    3. 编写 Frontmatter:这是驱动页面渲染的核心数据。

    2. Frontmatter 字段详解

    字段 类型 说明
    title String 访谈文章标题
    date String 发布日期 (用于排序,最新日期将显示在首页)
    category String 固定为 "Interview"
    summary String 访谈摘要,显示在列表页和首页模块
    guestName String 嘉宾姓名
    guestTitle String 嘉宾职衔 (如:首席科学家)
    guestOrg String 嘉宾所属机构
    guestAvatar URL 嘉宾头像链接
    guestDescription String 嘉宾背景详述
    guestAchievements Array 嘉宾主要成就标签列表
    interviewRecords Array 核心对话流:包含 timestamp, question, answer 对象
    multimedia Array 多媒体画廊:包含 type, url, caption 对象

    3. 配置示例模板

    ---
    title: "访谈标题"
    date: "2026-02-04"
    category: "Interview"
    summary: "这里是访谈摘要..."
    guestName: "张三"
    guestTitle: "技术专家"
    guestOrg: "某某实验室"
    guestAvatar: "https://example.com/avatar.png"
    guestDescription: "详细背景介绍..."
    guestAchievements: ["成就1", "成就2"]
    interviewRecords: [
      {
        "timestamp": "10:00",
        "question": "这里是问题内容?",
        "answer": "这里是回答内容..."
      }
    ]
    multimedia: [
      {
        "type": "image",
        "url": "https://example.com/photo.jpg",
        "caption": "图片说明"
      }
    ]
    ---
    # 更多背景
    这里可以编写 Markdown 格式的访谈侧记或补充资料。

    4. 高级配置说明

    多媒体画廊 (Multimedia)

    • 支持类型image (自动处理网格布局)、video (原生播放器)、audio (带动效的音频播放器)。
    • 网格布局
      • 单张图片:在容器中优雅居中。
      • 多张图片:自动切换为响应式网格布局(桌面端双列,移动端单列),带悬停缩放效果。
    • 容错处理:若图片加载失败,系统会自动显示统一的占位占位图。

    访谈对话流 (QA Stream)

    • 引号自动剥离:解析器会自动移除回答内容前后的多余引号,并使用现代化的引用图标装饰。
    • 交互效果:对话项在悬停时会触发左侧时间轴的动态高亮。

    5. 主页显示逻辑

    • 自动置顶:首页模块会扫描 src/content/interviews/ 下的所有文件,并自动提取 日期最新 的一个进行展示。
    • 跳转逻辑:点击首页访谈模块将直接进入该访谈的详情路由 /interviews/[slug]

    6. 技术实现与故障排查

    • 解析机制:由于 YAML 默认不支持复杂的嵌套 JSON 数组,项目重写了 src/utils/markdown.ts 解析引擎,支持跨行识别未闭合的 JSON 块。
    • TypeError: records.map is not a function
      • 排查:检查 Markdown 文件中 interviewRecords 的 JSON 格式是否正确(特别是引号和括号的闭合)。
      • 解决:确保 JSON 块前后没有多余的空行干扰解析逻辑。

    📜 开发过程记录 (Development History)

    1. 基础环境配置与路由优化

    核心任务:解决 GitHub Pages 部署下的子路径访问问题。

    • 分析:检查 src/main.tsxsrc/App.tsx,确认硬编码的 basename 导致开发环境空白。
    • 动作:通过调研修改配置,引入 import.meta.env.DEV 进行动态环境判断,确保本地开发与生产环境配置隔离。

    2. 六大核心模块架构开发

    核心任务:建立知识、博客、洞察、工具、笔记、成就的详情展示系统。

    • 文件结构
      • 创建 src/content/ 各模块子目录及示例 Markdown 文档。
      • 创建 src/pages/Detail.tsx 通用详情组件,集成 react-markdownremark-gfm
    • 自动化加载:升级 src/utils/markdown.ts,利用 Vite 的 import.meta.glob 实现内容自动扫描与热加载,降低维护成本。

    3. 兼容性与运行时修复

    核心任务:修复控制台 Buffer is not defined 报错及数据加载卡死问题。

    • 报错排查:确认 gray-matter 依赖 Node.js 模块,在浏览器端运行抛出 ReferenceError。
    • 解决方案:彻底移除 gray-matter,在 markdown.ts 中手动实现轻量级正则解析器提取 Frontmatter。同时修正了 import.meta.glob 的相对路径匹配逻辑,解决数据无法读取的问题。
    • 稳定性提升:在各模块页面增加异步捕获与状态恢复逻辑,确保 UI 加载反馈准确。

    4. 个性化定制与内容填充

    核心任务:协助用户完成站点定制化并录入真实荣誉数据。

    • 荣誉文档:在 src/content/achievements/ 录入职场(最佳猎手、Top Biller)与学术(奖学金、优秀毕业生)高质量 Markdown 内容。
    • 定制指引
      • Logo/文本:修改 src/layouts/Layout.tsx 将 "Portal." 更改为个人品牌 "Chandler"。
      • SEO/标题:优化 index.html 中的 Title 与 Meta Description。
      • 个人简介:更新 src/pages/Home.tsx 中的 Hero 核心文案。
      • 主题色彩:调整 src/index.css 中的 HSL 变量以切换视觉风格。

    5. 文档沉淀与管理指南

    核心任务:建立标准化的内容运维体系。

    • 成果:编写了详细的 CRUD 教程,涵盖新增、删除、修改、查询内容的标准流程与技术细节,确保项目的长期可维护性。

    6. 数据可视化系统集成

    核心任务:引入 AntV G2/G6/Infographic 提供全方位的可视化能力。

    • 组件开发
      • G2Chart.tsx: 基于 G2 5.x 封装的声明式统计图表组件。
      • G6Graph.tsx: 基于 G6 5.x 封装的关系图/树图组件,修复了 ESM 模块导出兼容性问题。
      • InfographicChart.tsx: 基于 Infographic 0.2.x 封装的信息图表组件,支持极简 DSL。
    • 渲染引擎:在 Detail.tsx 中扩展 react-markdown 处理器,识别 g2g6infographic 代码块并动态渲染对应组件。
    • 示例库:创建 src/content/visualization/gallery.mdinfographic-gallery.md,提供 15+ 种场景配置。

📊 数据可视化指南 (Visualization Guide)

项目集成了 AntV G2 (统计图表)、G6 (关系图谱) 与 Infographic (信息图表) 库,支持在 Markdown/MDX 中通过代码块直接渲染交互式图表。

1. 快速上手

在任何 Markdown 文件中,使用 g2g6infographic 语言标识的代码块并编写配置:

Infographic 示例

infographic list-row-simple-horizontal-arrow
data
  items
    - label: 步骤1
      desc: 描述1

+### 2. 图表分类索引 + +详细示例请访问项目中的 图表全集。 +

分类 支持类型
G2 统计图表 折线图、柱状图、饼图/玫瑰图、散点气泡图、渐变面积图、甘特图
G6 关系图谱 组织架构图、关系网络图、桑基图、流程图、时间线图
Infographic 流程图、组织架构、思维导图、指标卡片、数据摘要
### 3. 配置参数说明

#### G2 核心参数
- `type`: 图表类型 (`line`, `interval`, `point`, `area` 等)
- `data`: 数据源数组
- `encode`: 字段映射 (`x`, `y`, `color`, `size`)
- `coordinate`: 坐标系配置

#### G6 核心参数
- `data`: 节点 (`nodes`) 与 边 (`edges`) 数据
- `layout`: 布局算法 (`force`, `dagre`, `compactBox`)
- `behaviors`: 交互行为 (`drag-canvas`, `zoom-canvas`, `collapse-expand`)

#### Infographic 核心参数
- `DSL`: 极简的声明式文本描述数据与结构。

### 4. 常见问题 (FAQ)

**Q: 为什么图表没有显示?**  
A: 请检查代码块语言标识是否为 `g2`、`g6` 或 `infographic`;确保配置内容格式正确;检查浏览器控制台是否有语法错误。

**Q: 如何调整图表高度?**  
A: 默认高度由组件统一控制。若需个性化调整,可在对应组件中修改 `height` 配置。

**Q: G6 导出错误 (Uncaught SyntaxError)?**  
A: 项目采用 ESM 规范,必须使用 `import { Graph } from '@antv/g6'` 具名导入方式。

🎬 音视频嵌入指南 (Media Embedding Guide)

项目支持在 Markdown 内容中嵌入音频和视频,提供两种配置方式满足不同场景需求。

1. 方式一:采访模块专用 - multimedia 字段

仅适用于 interviews 模块,通过 Frontmatter 中的 multimedia 数组配置多媒体内容。

配置格式

---
title: "采访标题"
date: "2026-02-07"
guestName: "张三"
guestTitle: "AI 研究员"
guestOrg: "某公司"
guestAvatar: "/avatar.jpg"
guestDescription: "嘉宾简介"
guestAchievements: ["成就1", "成就2"]
multimedia: [
  {"type": "video", "url": "/videos/interview.mp4", "caption": "采访现场"},
  {"type": "audio", "url": "/audio/podcast.mp3", "caption": "播客录音"},
  {"type": "image", "url": "/images/photo.jpg", "caption": "合影留念"}
]
interviewRecords: [
  {"timestamp": "00:00", "question": "问题1", "answer": "回答1"}
]
---

支持的类型

type 说明 渲染效果
video 视频文件 HTML5 video 播放器
audio 音频文件 HTML5 audio 播放器(带动效图标)
image 图片文件 响应式图片展示

布局特性

  • 单张媒体:居中显示,最大宽度限制
  • 多张媒体:响应式网格布局(桌面端双列,移动端单列)
  • 交互效果:悬停时图片轻微放大,带阴影增强

2. 方式二:通用方式 - HTML 标签

由于 Detail.tsx 使用了 rehypeRaw 插件,所有模块都支持直接在 Markdown 中编写 HTML 标签嵌入音视频。

视频嵌入

本地视频文件

<video controls width="100%" style="border-radius: 8px;">
  <source src="/videos/demo.mp4" type="video/mp4">
  您的浏览器不支持视频播放
</video>

外部视频直链

<video controls width="100%">
  <source src="https://example.com/video.mp4" type="video/mp4">
</video>

嵌入第三方平台(B站、YouTube等)

<iframe 
  src="https://player.bilibili.com/player.html?bvid=BV1xx411c7XX" 
  width="100%" 
  height="600" 
  frameborder="0" 
  allowfullscreen>
</iframe>

音频嵌入

本地音频文件

<audio controls style="width:100%; margin: 16px 0;">
  <source src="/audio/podcast.mp3" type="audio/mpeg">
  您的浏览器不支持音频播放
</audio>

外部音频直链

<audio controls style="width:100%;">
  <source src="https://example.com/audio.mp3" type="audio/mpeg">
</audio>

3. 文件存放位置

类型 本地存放路径 URL 引用方式
视频文件 public/videos/demo.mp4 /videos/demo.mp4
音频文件 public/audio/podcast.mp3 /audio/podcast.mp3
外部资源 - 使用完整 URL

4. 完整示例

以下是一个包含音视频的博客文章示例:

---
title: "技术分享:AI 发展趋势"
date: "2026-02-07"
category: "Tech"
summary: "本期视频分享 AI 最新进展"
---

# AI 发展趋势解读

## 视频回顾

<video controls width="100%" style="border-radius: 8px;">
  <source src="/videos/ai-trend-2026.mp4" type="video/mp4">
</video>

## 播客音频版

<audio controls style="width:100%; margin: 16px 0;">
  <source src="/audio/ai-podcast-ep1.mp3" type="audio/mpeg">
</audio>

## 相关内容

这是正文内容...

5. 两种方式对比

特性 multimedia 字段 HTML 标签
适用模块 仅 interviews 所有模块
配置位置 Frontmatter Markdown 正文
布局控制 自动网格布局 手动控制样式
字幕支持 支持 caption 需手动添加
灵活性 结构化配置 完全自定义
推荐场景 采访多媒体画廊 博客/文章内嵌

6. 注意事项

  1. 文件格式

    • 视频推荐:MP4 (H.264 编码)
    • 音频推荐:MP3 或 AAC
    • 确保格式兼容主流浏览器
  2. 文件大小

    • 建议视频压缩至合理大小(< 50MB)
    • 大文件会影响页面加载速度
  3. 路径格式

    • 本地文件路径必须以 / 开头
    • 外部链接使用完整 URL(包含 https://
  4. 跨域问题

    • 外部视频/音频可能受 CORS 限制
    • 建议将重要媒体文件存放在 public/ 目录
  5. 移动端适配

    • 使用 width="100%" 确保响应式显示
    • iOS 设备部分视频需要用户手动播放

7. 常见问题

Q: 视频无法播放怎么办?
A: 检查以下几点:

  1. 文件是否正确放置在 public/ 目录下
  2. 路径是否以 / 开头
  3. 视频格式是否为浏览器支持的格式(推荐 MP4)
  4. 可尝试在浏览器直接访问视频 URL 验证

Q: 如何添加视频封面图?
A: 使用 poster 属性:

<video controls poster="/images/cover.jpg">
  <source src="/videos/demo.mp4" type="video/mp4">
</video>

Q: 能否自动播放视频?
A: 可以添加 autoplay muted 属性,但注意:

  • 大多数浏览器要求自动播放的视频必须静音
  • 自动播放可能影响用户体验,请谨慎使用

Q: B站视频嵌入后无法播放?
A: B站 iframe 嵌入需要使用正确的播放器 URL 格式,并确保视频允许外链播放。

About

Establish a distinguished and influential professional personal brand

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors