personal-homepage/REQUIREMENTS.md

9.1 KiB
Raw Blame History

个人主页 — 需求文档

1. 项目范围

本项目是一个公开静态站点 + 构建时数据同步层

站点运行时仍然是纯静态页面,但在构建阶段由本项目主动向 Gitea / Seafile 拉取所需数据,清洗后生成本地只读数据文件,再交给 Astro 渲染。

也就是说:

  • 运行时:纯静态站点,对外公开访问
  • 构建时:服务端脚本拉取远程数据、生成内容文件

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 文件
  • 首版允许日志继续由手动维护或外部系统写入;日志生成逻辑不要求在本项目内实现

2.3 项目展示(/projects

  • 项目卡片网格布局
  • 每个项目卡片:名称、描述、封面图、标签
  • 点击可展开/跳转详情演示视频如有、Gitea 仓库链接、Seafile 下载链接(如有)
  • 数据来源:构建时从 Gitea / Seafile 拉取并生成的结构化数据文件
  • 页面层只读取最终生成数据,不直接处理上游 API 响应

2.4 Gitea 统计(可嵌入首页或独立页)

  • 贡献热力图
  • 最近活动列表
  • 仓库简要信息(名称、描述、更新时间、链接等)
  • 数据由构建脚本从 Gitea 拉取并清洗
  • 运行时不依赖浏览器直接访问带 token 的私有 API

2.5 Seafile 分享(/shares 或首页侧栏)

  • 文件分享链接列表,每条含:文件名、描述、链接、时间
  • 数据来源:构建时从 Seafile 拉取并生成的结构化数据文件
  • 支持展示特定目录或特定文件(如项目打包产物)
  • 首版优先展示文件元数据与下载链接;如确有需要,可在后续增加“构建时镜像文件到站点静态目录”的能力

3. 功能优先级

P0必须有

  • 首页 Hero 区(个人简介 + 链接)
  • 日志列表 + 详情页Markdown 渲染)
  • 项目展示卡片
  • 构建时 Gitea / Seafile 数据同步入口

P1很重要

  • Gitea 贡献热力图(基于构建期抓取的数据渲染)
  • 仓库摘要信息同步
  • Seafile 分享列表同步
  • 响应式布局

P2锦上添花

  • 日志按标签/时间筛选
  • 项目演示视频嵌入
  • 构建时镜像特定 Seafile 文件到站点静态目录
  • 深色模式

4. 技术选型

选型 理由
框架 Astro 静态站点生成,原生 .md 支持,零 JS 默认 + 可选交互岛
样式 CSS当前 / Tailwind CSS可选 首版以简单直接、低心智负担为主,是否接 Tailwind 以后续实现成本决定
交互组件 Astro 原生 + 按需引入 React 默认静态渲染;只有热力图等确需交互时再引入前端组件
内容存储 文件系统(.md + .json 构建脚本先把远程数据清洗为本地文件,再统一消费
数据同步 Node.js 构建脚本 服务端拉取 Gitea / Seafile 数据,避免浏览器暴露 token
部署 Nginx + Docker 静态文件服务,单容器
构建触发 手动 / 定时任务 / AstrBot npm run content:syncnpm run build → 部署静态产物

5. 数据模型

日志 frontmattersrc/content/logs/*.md

---
title: "personal-homepage 项目初始化"
date: 2026-05-03
repo: "sepcomet/personal-homepage"
tags: [astro, init, setup]
summary: "搭建 Astro 项目骨架,确定目录结构与部署方案"
---
正文内容Markdown — 客观 diff 分析 + 主观动机,由 AstrBot 生成后写入

项目数据(示例:src/data/generated/projects.json

[
  {
    "name": "personal-homepage",
    "description": "个人主页 Dashboard",
    "gitea_repo": "sepcomet/personal-homepage",
    "repo_url": "https://gitea.sepcomet.xyz/sepcomet/personal-homepage",
    "cover_image": "/images/projects/homepage.png",
    "demo_video": "https://...",
    "download_link": "https://seafile.sepcomet.xyz/...",
    "tags": ["astro", "web"],
    "featured": true,
    "updated_at": "2026-05-05T00:00:00Z",
    "source": "gitea+seafile"
  }
]

Gitea 活动数据(示例:src/data/generated/gitea-activity.json

{
  "updatedAt": "2026-05-05T00:00:00Z",
  "days": [
    { "date": "2026-05-01", "count": 3 },
    { "date": "2026-05-02", "count": 0 }
  ],
  "recent": [
    {
      "type": "push",
      "repo": "sepcomet/personal-homepage",
      "message": "更新首页模块结构",
      "url": "https://gitea.sepcomet.xyz/...",
      "time": "2026-05-05T00:00:00Z"
    }
  ]
}

分享 / 下载数据(示例:src/data/generated/shares.json

[
  {
    "name": "personal-homepage-demo.zip",
    "description": "项目打包产物",
    "url": "https://seafile.sepcomet.xyz/...",
    "time": "2026-05-05T00:00:00Z",
    "size": 12345678,
    "source": "seafile"
  }
]

站点配置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 日志内容
│   ├── data/
│   │   └── generated/               # 构建时同步生成的 JSON
│   │       ├── gitea-activity.json
│   │       ├── projects.json
│   │       └── shares.json
│   ├── config.ts
│   └── styles/
│       └── global.css
├── scripts/
│   ├── fetch-gitea.ts
│   ├── fetch-seafile.ts
│   └── sync-content.ts
├── public/
│   ├── images/
│   │   └── avatar.png
│   └── downloads/                   # 可选:构建时镜像的下载文件
│   └── favicon.svg
├── astro.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 生成静态文件
  • Docker 构建阶段:先执行 npm run content:sync,再执行 npm run build
  • 运行阶段Nginx 托管 dist/ 目录
  • 日常更新:定时任务 / AstrBot 触发同步与重建
  • Gitea / Seafile token 只存在于构建环境,不进入前端产物

8. 实施计划

Phase 内容 产出
1 Astro 项目初始化 + 首页/日志/项目/分享骨架 可访问的骨架页面
2 日志系统:列表页 + 详情页 + frontmatter 解析 + 示例内容 日志模块
3 数据同步层Gitea / Seafile 拉取脚本、环境变量、生成文件 构建期数据链路
4 页面改读生成数据 + Gitea 活动真实化 + 仓库摘要接入 统计与项目模块
5 Docker、定时重建、响应式打磨、深色模式、SEO 收尾

9. 不在此项目范围内

  • AstrBot 插件开发(独立项目)
  • 日志 markdown 文件的生成逻辑(可由 AstrBot 或其他系统负责)
  • 自动化部署流程CI/CD可后续补充

本项目负责:构建时拉取远程数据 / 读取本地日志 → 生成站点数据文件 → 渲染为 HTML → 静态托管