221 lines
6.6 KiB
Markdown
221 lines
6.6 KiB
Markdown
# 个人主页 — 需求文档
|
||
|
||
## 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](https://astro.build) | 静态站点生成,原生 `.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)
|
||
|
||
```yaml
|
||
---
|
||
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)
|
||
|
||
```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)
|
||
|
||
```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. 部署
|
||
|
||
```yaml
|
||
# 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 → 静态托管**。
|