6.6 KiB
6.6 KiB
个人主页 — 需求文档
1. 项目范围
只做 Web 应用本身。 AstrBot 插件、Gitea/Seafile API 接入属于独立项目。
主页是一个公开的静态站点,通过 markdown/JSON 文件驱动内容(这些文件可由 AstrBot 等其他系统写入,但主页本身不关心来源)。
- 域名:
sepcomet.xyz(备案中) - 部署:自有服务器 Docker 环境
- 访问:完全公开,求职时可直接给链接
- 用户背景:Unity 客户端开发,Web 经验不多,怎么方便怎么来
2. 页面与功能
2.1 首页
- Hero 区:头像、名字、一句话简介、社交链接(GitHub/Gitea/Blog 等)
- 开发日志摘要:最新 3-5 条日志的卡片列表
- 精选项目:featured 项目的卡片展示
- Gitea 活动概览:贡献热力图(可选)
2.2 开发日志(/logs)
- 按时间倒序的日志列表
- 每条日志卡片:标题、日期、标签、摘要
- 点击进入日志详情页(/logs/[slug])
- 日志详情:Markdown 全文渲染,关联的仓库名和 commit 链接
- 内容来自
src/content/logs/下的.md文件(文件来源不在本范围内,由 AstrBot 或其他系统写入)
2.3 项目展示(/projects)
- 项目卡片网格布局
- 每个项目卡片:名称、描述、封面图、标签
- 点击可展开/跳转详情:演示视频(如有)、Gitea 仓库链接、Seafile 下载链接(如有)
- 数据来源:
src/content/projects/index.json(手动维护)
2.4 Gitea 统计(可嵌入首页或独立页)
- 贡献热力图(客户端 JS 调 Gitea API 渲染)
- 最近活动列表
- Gitea 地址通过站点配置注入
2.5 Seafile 分享(/shares 或首页侧栏)
- 文件分享链接列表,每条含:文件名、描述、链接、时间
- 数据来源:
src/content/shares/index.json(手动维护)
3. 功能优先级
P0(必须有):
- 首页 Hero 区(个人简介 + 链接)
- 日志列表 + 详情页(Markdown 渲染)
- 项目展示卡片
P1(很重要):
- Gitea 贡献热力图(客户端 API 调用)
- 响应式布局
P2(锦上添花):
- Seafile 分享链接列表
- 日志按标签/时间筛选
- 项目演示视频嵌入
- 深色模式
4. 技术选型
| 层 | 选型 | 理由 |
|---|---|---|
| 框架 | Astro | 静态站点生成,原生 .md 支持,零 JS 默认 + 可选交互岛 |
| 样式 | Tailwind CSS | 原子化 CSS,快速出效果,不需要手写大量样式 |
| 交互组件 | React(按需引入) | 仅 Gitea 热力图等需交互处使用,Astro Islands |
| 内容存储 | 文件系统(.md + .json) |
无需数据库,日志/项目数据直接文件 |
| 部署 | Nginx + Docker | 静态文件服务,单容器 |
| 构建触发 | 内容文件变更后手动/脚本 rebuild | 日志写入 → npm run build → nginx reload |
5. 数据模型
日志 frontmatter(src/content/logs/*.md)
---
title: "personal-homepage 项目初始化"
date: 2026-05-03
repo: "sepcomet/personal-homepage"
tags: [astro, init, setup]
summary: "搭建 Astro 项目骨架,确定目录结构与部署方案"
---
正文内容(Markdown) — 客观 diff 分析 + 主观动机,由 AstrBot 生成后写入
项目数据(src/content/projects/index.json)
[
{
"name": "personal-homepage",
"description": "个人主页 Dashboard",
"gitea_repo": "sepcomet/personal-homepage",
"cover_image": "/images/projects/homepage.png",
"demo_video": "https://...",
"download_link": "https://seafile.sepcomet.xyz/...",
"tags": ["astro", "web"],
"featured": true
}
]
站点配置(src/config.ts)
export const site = {
name: "SepComet",
title: "个人主页",
tagline: "Unity 开发者",
avatar: "/images/avatar.png",
gitea: {
url: "https://gitea.sepcomet.xyz",
username: "sepcomet"
},
links: [
{ name: "Gitea", url: "https://gitea.sepcomet.xyz" },
{ name: "GitHub", url: "https://github.com/sepcomet" }
]
}
6. 目录结构
personal-homepage/
├── src/
│ ├── pages/
│ │ ├── index.astro # 首页
│ │ ├── logs/
│ │ │ ├── index.astro # 日志列表
│ │ │ └── [slug].astro # 日志详情
│ │ ├── projects/
│ │ │ └── index.astro # 项目展示
│ │ └── shares.astro # Seafile 分享
│ ├── components/
│ │ ├── Header.astro
│ │ ├── Footer.astro
│ │ ├── Hero.astro
│ │ ├── LogCard.astro
│ │ ├── ProjectCard.astro
│ │ └── GiteaHeatmap.jsx # React Island
│ ├── content/
│ │ ├── logs/ # *.md(外部系统写入)
│ │ ├── projects/
│ │ │ └── index.json
│ │ └── shares/
│ │ └── index.json
│ ├── config.ts
│ └── styles/
│ └── global.css
├── public/
│ ├── images/
│ │ └── avatar.png
│ └── favicon.svg
├── astro.config.mjs
├── tailwind.config.mjs
├── Dockerfile
├── docker-compose.yml
└── package.json
7. 部署
# docker-compose.yml
services:
homepage:
build: .
ports:
- "8080:80"
volumes:
- ./src/content:/app/src/content # 日志/项目内容热更新
- ./public/images:/app/public/images
restart: unless-stopped
- Docker 构建阶段:
npm run build生成静态文件 - 运行阶段:Nginx 托管
dist/目录 - 更新日志:AstrBot 写入新的
.md→ 触发 rebuild → nginx 热加载
8. 实施计划
| Phase | 内容 | 产出 |
|---|---|---|
| 1 | Astro 项目初始化 + Tailwind + Header/Footer/Hero + Docker | 可访问的骨架页面 |
| 2 | 日志系统:列表页 + 详情页 + frontmatter 解析 + 示例内容 | 日志模块 |
| 3 | 项目展示:卡片组件 + JSON 数据 + 布局 | 项目模块 |
| 4 | Gitea 热力图 React Island + 站点配置 | 统计模块 |
| 5 | Seafile 分享 + 响应式打磨 + 深色模式 + SEO | 收尾 |
9. 不在此项目范围内
- AstrBot 插件开发(独立项目)
- Gitea/Seafile API 的调用与数据拉取(独立脚本或 AstrBot 插件负责)
- 日志 markdown 文件的生成逻辑(AstrBot 负责)
- 自动化部署流程(CI/CD,可后续补充)
主页只负责:读取已有数据文件 → 渲染为 HTML → 静态托管。