docs: add home github button PRD
This commit is contained in:
527
prd-home-add-github-button.md
Normal file
527
prd-home-add-github-button.md
Normal file
@@ -0,0 +1,527 @@
|
|||||||
|
# Home 页新增 GitHub 按钮与后台可编辑支持 PRD
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
当前 `www.ephron.ren` 的 home 页 Hero 区只有一个“联系我”按钮,点击后弹出联系方式弹窗,仅展示邮箱。用户希望:
|
||||||
|
|
||||||
|
1. 在首页 Hero 区中,**在“联系我”右侧新增一个“GitHub”按钮**。
|
||||||
|
2. 后台管理页也必须支持维护这个 GitHub 按钮对应的内容,不能写死在模板里。
|
||||||
|
3. 该变更需要纳入现有 home 服务的**草稿 / 发布**工作流。
|
||||||
|
|
||||||
|
本 PRD 基于 `origin/main` 源码分析,不基于当前本地工作树。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 现状分析
|
||||||
|
|
||||||
|
### 1. 前台首页按钮结构
|
||||||
|
|
||||||
|
Home 页模板位于:
|
||||||
|
- `home/templates/index.html`
|
||||||
|
|
||||||
|
当前 Hero 区按钮只有一个:
|
||||||
|
- `联系我`
|
||||||
|
- 通过 `onclick="showContactModal()"` 打开联系方式弹窗
|
||||||
|
|
||||||
|
现有结构大致如下:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="hero-actions">
|
||||||
|
<button onclick="showContactModal()" class="btn btn-primary">
|
||||||
|
...
|
||||||
|
联系我
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
这说明:
|
||||||
|
- Hero 操作区已经预留了多按钮容器 `hero-actions`
|
||||||
|
- 新增 GitHub 按钮不需要重构整体布局,只需扩展现有按钮组
|
||||||
|
|
||||||
|
### 2. 前台联系方式数据来源
|
||||||
|
|
||||||
|
当前联系方式弹窗内容来自:
|
||||||
|
- `content.contact.email`
|
||||||
|
|
||||||
|
现有弹窗只渲染邮箱:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<span class="email-text" id="emailText">{{ content.contact.email }}</span>
|
||||||
|
```
|
||||||
|
|
||||||
|
说明当前 `contact` 数据结构只被用于邮箱展示,没有 GitHub 相关字段。
|
||||||
|
|
||||||
|
### 3. 后台编辑页当前只支持邮箱
|
||||||
|
|
||||||
|
后台模板位于:
|
||||||
|
- `home/templates/admin/index.html`
|
||||||
|
|
||||||
|
当前“联系方式”区块只有一个字段:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input type="email" class="form-input" id="contact_email" value="{{ content.contact.email }}">
|
||||||
|
```
|
||||||
|
|
||||||
|
前端提交草稿 / 发布时,`collectFormData()` 也只收集邮箱:
|
||||||
|
|
||||||
|
```js
|
||||||
|
contact: {
|
||||||
|
email: document.getElementById('contact_email').value
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
说明:
|
||||||
|
- 即使只改前台模板,也无法通过后台维护 GitHub 按钮内容
|
||||||
|
- 必须同步修改 admin 表单 + JS 收集逻辑
|
||||||
|
|
||||||
|
### 4. Home 服务确实有独立草稿 / 发布机制
|
||||||
|
|
||||||
|
关键文件:
|
||||||
|
- `home/src/routes/admin.py`
|
||||||
|
- `home/src/services/content.py`
|
||||||
|
|
||||||
|
已确认 Home 服务支持:
|
||||||
|
- `GET /admin`
|
||||||
|
- `POST /admin/save`
|
||||||
|
- `POST /admin/publish`
|
||||||
|
- `POST /admin/discard`
|
||||||
|
|
||||||
|
内容通过 `content_json` 整体提交,并存入 `home_content` 表中的 `content_json` 字段。
|
||||||
|
|
||||||
|
这意味着 GitHub 字段必须进入 Home content schema,才能被草稿保存和发布机制完整承载。
|
||||||
|
|
||||||
|
### 5. 当前默认内容 schema 不包含 GitHub
|
||||||
|
|
||||||
|
默认空内容定义位于:
|
||||||
|
- `home/src/services/content.py` → `_get_empty_content()`
|
||||||
|
|
||||||
|
当前 contact 结构:
|
||||||
|
|
||||||
|
```python
|
||||||
|
"contact": {
|
||||||
|
"email": ""
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
示例内容文件位于:
|
||||||
|
- `home/data/home_content.json`
|
||||||
|
|
||||||
|
当前 contact 示例也仅有:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"contact": {
|
||||||
|
"email": "ephron_ren@163.com"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
说明 schema 目前不支持 GitHub。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 问题定义
|
||||||
|
|
||||||
|
当前实现存在以下缺口:
|
||||||
|
|
||||||
|
1. **首页缺少 GitHub 快捷入口**
|
||||||
|
- Hero 区只有“联系我”,没有直达 GitHub 的显式按钮。
|
||||||
|
|
||||||
|
2. **后台无法维护 GitHub 按钮内容**
|
||||||
|
- 联系方式仅支持邮箱,不支持 GitHub 文案 / URL。
|
||||||
|
|
||||||
|
3. **内容 schema 不完整**
|
||||||
|
- `contact` 结构没有 GitHub 字段,草稿与发布链路无法承载该信息。
|
||||||
|
|
||||||
|
4. **如果只改模板会造成配置写死**
|
||||||
|
- 不符合现有 home 服务“后台可编辑 + 草稿发布”的设计模式。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
|
||||||
|
### 产品目标
|
||||||
|
|
||||||
|
在首页 Hero 区实现双按钮:
|
||||||
|
- 左侧保留“联系我”
|
||||||
|
- 右侧新增“GitHub”
|
||||||
|
|
||||||
|
并且后台支持修改 GitHub 按钮对应的数据,确保:
|
||||||
|
- 可保存草稿
|
||||||
|
- 可发布
|
||||||
|
- 可回显
|
||||||
|
- 无需改代码即可调整 GitHub 链接
|
||||||
|
|
||||||
|
### 技术目标
|
||||||
|
|
||||||
|
将 GitHub 按钮数据纳入 Home content 的统一 JSON schema,而不是写死在模板中。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 方案设计
|
||||||
|
|
||||||
|
## 一、数据结构调整
|
||||||
|
|
||||||
|
### 方案建议
|
||||||
|
|
||||||
|
扩展 `contact` 对象,至少新增 GitHub URL 字段。
|
||||||
|
|
||||||
|
建议结构:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"contact": {
|
||||||
|
"email": "ephron_ren@163.com",
|
||||||
|
"github_url": "https://github.com/ephron-ren"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 可选增强方案
|
||||||
|
|
||||||
|
如果希望按钮文案也可配置,可以进一步扩展为:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"contact": {
|
||||||
|
"email": "ephron_ren@163.com",
|
||||||
|
"github_label": "GitHub",
|
||||||
|
"github_url": "https://github.com/ephron-ren"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 本次建议
|
||||||
|
|
||||||
|
**建议本次至少落 `github_url`,`github_label` 可选。**
|
||||||
|
|
||||||
|
理由:
|
||||||
|
- 用户明确要新增名为“GitHub”的按钮,文案固定即可满足需求
|
||||||
|
- 如果后续想支持“GitHub / 开源主页 / 代码仓库”等不同文案,再加 `github_label` 也不晚
|
||||||
|
- 本次最小闭环是“后台可改 GitHub 链接”
|
||||||
|
|
||||||
|
### 必改位置
|
||||||
|
|
||||||
|
1. `home/src/services/content.py`
|
||||||
|
- 更新 `HomeContent` 对应的 `contact` 结构说明
|
||||||
|
- 更新 `_get_empty_content()` 默认值
|
||||||
|
|
||||||
|
2. `home/data/home_content.json`
|
||||||
|
- 为现有示例数据补上 `github_url`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、后台管理页改造
|
||||||
|
|
||||||
|
### 目标
|
||||||
|
|
||||||
|
在后台“联系方式”区块中新增 GitHub 配置项。
|
||||||
|
|
||||||
|
### 建议 UI
|
||||||
|
|
||||||
|
当前仅有邮箱输入框,新增一项:
|
||||||
|
|
||||||
|
- GitHub 链接(URL)
|
||||||
|
|
||||||
|
建议形式:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">GitHub 链接</label>
|
||||||
|
<input type="url" class="form-input" id="contact_github_url" value="{{ content.contact.github_url }}">
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
如果采用增强方案,也可再加:
|
||||||
|
|
||||||
|
- GitHub 按钮文案
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">GitHub 按钮文案</label>
|
||||||
|
<input type="text" class="form-input" id="contact_github_label" value="{{ content.contact.github_label or 'GitHub' }}">
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 提交逻辑改造
|
||||||
|
|
||||||
|
`home/templates/admin/index.html` 中的 `collectFormData()` 必须同步扩展。
|
||||||
|
|
||||||
|
最低改法:
|
||||||
|
|
||||||
|
```js
|
||||||
|
contact: {
|
||||||
|
email: document.getElementById('contact_email').value,
|
||||||
|
github_url: document.getElementById('contact_github_url').value
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
若支持按钮文案:
|
||||||
|
|
||||||
|
```js
|
||||||
|
contact: {
|
||||||
|
email: document.getElementById('contact_email').value,
|
||||||
|
github_label: document.getElementById('contact_github_label').value,
|
||||||
|
github_url: document.getElementById('contact_github_url').value
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 兼容性要求
|
||||||
|
|
||||||
|
为避免旧数据缺字段导致后台渲染异常:
|
||||||
|
- 模板取值要允许字段不存在
|
||||||
|
- 推荐用兼容写法,例如:
|
||||||
|
- `content.contact.github_url or ''`
|
||||||
|
- `content.contact.github_label or 'GitHub'`
|
||||||
|
|
||||||
|
不要假设线上已有数据一定已经补齐。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、前台首页 Hero 区改造
|
||||||
|
|
||||||
|
### 目标
|
||||||
|
|
||||||
|
在 Hero 区 `.hero-actions` 中,把单按钮扩展为双按钮布局:
|
||||||
|
- 联系我
|
||||||
|
- GitHub
|
||||||
|
|
||||||
|
### 建议实现
|
||||||
|
|
||||||
|
保留现有“联系我”按钮不变,在右侧新增一个锚点按钮:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="hero-actions">
|
||||||
|
<button onclick="showContactModal()" class="btn btn-primary">
|
||||||
|
...
|
||||||
|
联系我
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{% if content.contact.github_url %}
|
||||||
|
<a href="{{ content.contact.github_url }}" target="_blank" rel="noopener noreferrer" class="btn btn-secondary">
|
||||||
|
...
|
||||||
|
GitHub
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 为什么建议条件渲染
|
||||||
|
|
||||||
|
使用:
|
||||||
|
|
||||||
|
```jinja2
|
||||||
|
{% if content.contact.github_url %}
|
||||||
|
```
|
||||||
|
|
||||||
|
原因:
|
||||||
|
- 避免后台未配置 GitHub 时渲染空链接按钮
|
||||||
|
- 保持发布内容的容错性
|
||||||
|
- 符合配置驱动模式
|
||||||
|
|
||||||
|
### 样式建议
|
||||||
|
|
||||||
|
优先复用现有按钮体系:
|
||||||
|
- `btn btn-primary` 给“联系我”
|
||||||
|
- `btn btn-secondary` 给“GitHub”
|
||||||
|
|
||||||
|
这样改动最小,也能保持视觉一致性。
|
||||||
|
|
||||||
|
### 位置要求
|
||||||
|
|
||||||
|
GitHub 按钮必须出现在“联系我”**右侧**,与用户需求一致。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、联系方式弹窗是否需要改
|
||||||
|
|
||||||
|
### 本次建议
|
||||||
|
|
||||||
|
**不强制把 GitHub 塞进联系弹窗。**
|
||||||
|
|
||||||
|
原因:
|
||||||
|
- 用户明确需求是“在联系我右边新增一个按钮 GitHub”
|
||||||
|
- GitHub 是独立入口,放在 Hero 区直接跳转比塞进弹窗更合理
|
||||||
|
- 当前弹窗职责单一:展示邮箱并支持复制,继续保持简单更好
|
||||||
|
|
||||||
|
### 允许的增强项
|
||||||
|
|
||||||
|
如果开发时认为一致性更强,也可以在弹窗底部附加一行 GitHub 链接,但这不是本次必需项。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、后端服务层与兼容策略
|
||||||
|
|
||||||
|
### 现状
|
||||||
|
|
||||||
|
`home/src/services/content.py` 当前直接把 JSON 读出后返回,没有做 schema migration。
|
||||||
|
|
||||||
|
### 风险
|
||||||
|
|
||||||
|
如果线上数据库里已有历史 `content_json`,其中 `contact` 只有:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "email": "..." }
|
||||||
|
```
|
||||||
|
|
||||||
|
那么模板若直接访问 `content.contact.github_url`,可能出现以下问题:
|
||||||
|
- Jinja 取不到字段导致空值
|
||||||
|
- 管理页输入框初始值异常
|
||||||
|
- 前台逻辑不统一
|
||||||
|
|
||||||
|
### 建议
|
||||||
|
|
||||||
|
在内容读取或默认值合并处做轻量兼容,保证旧数据自动补默认字段。
|
||||||
|
|
||||||
|
建议方向二选一:
|
||||||
|
|
||||||
|
#### 方案 A:服务层补默认值(推荐)
|
||||||
|
在 `get_published_content()` / `get_draft_content()` / `get_content_for_edit()` 返回前,对 `contact` 做 schema normalize。
|
||||||
|
|
||||||
|
例如确保返回结构至少包含:
|
||||||
|
|
||||||
|
```python
|
||||||
|
content.setdefault("contact", {})
|
||||||
|
content["contact"].setdefault("email", "")
|
||||||
|
content["contact"].setdefault("github_url", "")
|
||||||
|
```
|
||||||
|
|
||||||
|
若采用增强方案,再补:
|
||||||
|
|
||||||
|
```python
|
||||||
|
content["contact"].setdefault("github_label", "GitHub")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 方案 B:模板层全靠 `or ''`
|
||||||
|
这种能跑,但会把兼容逻辑分散到多个模板,不推荐。
|
||||||
|
|
||||||
|
### 结论
|
||||||
|
|
||||||
|
**推荐在服务层统一做 schema 补齐。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 修改范围
|
||||||
|
|
||||||
|
### 必改文件
|
||||||
|
|
||||||
|
1. `home/templates/index.html`
|
||||||
|
- Hero 区新增 GitHub 按钮
|
||||||
|
- 按配置条件渲染
|
||||||
|
|
||||||
|
2. `home/templates/admin/index.html`
|
||||||
|
- 联系方式区块新增 GitHub 输入项
|
||||||
|
- `collectFormData()` 增加 GitHub 字段收集
|
||||||
|
|
||||||
|
3. `home/src/services/content.py`
|
||||||
|
- 扩展默认 schema
|
||||||
|
- 增加旧数据兼容补齐逻辑
|
||||||
|
|
||||||
|
4. `home/data/home_content.json`
|
||||||
|
- 补充 GitHub 示例字段
|
||||||
|
|
||||||
|
### 可选修改文件
|
||||||
|
|
||||||
|
5. `home/tests/...`
|
||||||
|
- 为 admin 渲染 / 发布内容链路补测试
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 验收标准
|
||||||
|
|
||||||
|
### 前台验收
|
||||||
|
|
||||||
|
1. 首页 Hero 区显示两个按钮:
|
||||||
|
- 联系我
|
||||||
|
- GitHub
|
||||||
|
|
||||||
|
2. GitHub 按钮位于“联系我”右侧。
|
||||||
|
|
||||||
|
3. GitHub 按钮点击后:
|
||||||
|
- 新标签页打开 GitHub 页面
|
||||||
|
- 带 `rel="noopener noreferrer"`
|
||||||
|
|
||||||
|
4. 当后台未填写 GitHub 链接时:
|
||||||
|
- 不显示 GitHub 按钮
|
||||||
|
- 页面不报错
|
||||||
|
|
||||||
|
### 后台验收
|
||||||
|
|
||||||
|
1. 管理页“联系方式”区块新增 GitHub 链接输入框。
|
||||||
|
2. 修改 GitHub 链接后点击“保存草稿”:
|
||||||
|
- 草稿保存成功
|
||||||
|
- 刷新管理页能回显草稿值
|
||||||
|
3. 点击“发布”后:
|
||||||
|
- 首页 GitHub 按钮更新为最新链接
|
||||||
|
4. 点击“丢弃草稿”后:
|
||||||
|
- 未发布的 GitHub 修改被撤销
|
||||||
|
|
||||||
|
### 兼容性验收
|
||||||
|
|
||||||
|
1. 对已有旧数据(无 `github_url` 字段)可正常打开首页。
|
||||||
|
2. 对已有旧数据可正常打开后台管理页。
|
||||||
|
3. 不要求手工清洗历史 `content_json` 才能运行。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 测试建议
|
||||||
|
|
||||||
|
### 手工测试路径
|
||||||
|
|
||||||
|
1. 打开 `/admin`
|
||||||
|
2. 在“联系方式”中填写 GitHub 链接
|
||||||
|
3. 点击“保存草稿”
|
||||||
|
4. 刷新 `/admin`,确认值仍在
|
||||||
|
5. 点击“发布”
|
||||||
|
6. 打开首页 `/`
|
||||||
|
7. 检查“联系我”右侧是否出现 GitHub 按钮
|
||||||
|
8. 点击按钮,确认跳转正确
|
||||||
|
9. 清空 GitHub 链接后重新发布
|
||||||
|
10. 首页应隐藏 GitHub 按钮
|
||||||
|
|
||||||
|
### 自动化测试建议
|
||||||
|
|
||||||
|
至少补以下测试:
|
||||||
|
|
||||||
|
1. **内容兼容测试**
|
||||||
|
- 旧 schema 无 `github_url` 时,服务层返回结果应自动补空值
|
||||||
|
|
||||||
|
2. **后台表单渲染测试**
|
||||||
|
- `/admin` 页面应包含 `contact_github_url`
|
||||||
|
|
||||||
|
3. **前台渲染测试**
|
||||||
|
- 有 `github_url` 时显示按钮
|
||||||
|
- 无 `github_url` 时不显示按钮
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 非目标
|
||||||
|
|
||||||
|
本次 PRD 不包含以下内容:
|
||||||
|
|
||||||
|
1. 不改“联系我”弹窗的交互模式
|
||||||
|
2. 不新增多社交平台矩阵(如 X、LinkedIn、掘金、知乎)
|
||||||
|
3. 不重构 Hero 区整体布局
|
||||||
|
4. 不引入单独的 Home Service API
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 实施建议
|
||||||
|
|
||||||
|
建议按以下顺序开发:
|
||||||
|
|
||||||
|
1. 先改 `content.py` 默认 schema 和兼容补齐
|
||||||
|
2. 再改 admin 表单与 `collectFormData()`
|
||||||
|
3. 最后改首页 Hero 模板渲染
|
||||||
|
4. 补回归测试
|
||||||
|
|
||||||
|
这样能最大限度降低“模板先引用新字段、但后端旧数据没补齐”导致的线上报错风险。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 结论
|
||||||
|
|
||||||
|
这不是一个单纯的模板文案调整,而是一个 **Home 内容模型扩展 + 后台编辑支持 + 前台配置驱动渲染** 的小型功能改造。
|
||||||
|
|
||||||
|
最小闭环必须同时覆盖:
|
||||||
|
- 数据 schema
|
||||||
|
- 后台表单
|
||||||
|
- 提交收集逻辑
|
||||||
|
- 前台模板
|
||||||
|
- 旧数据兼容
|
||||||
|
|
||||||
|
否则会出现“按钮显示了但后台不能改”或“后台能填但前台不渲染”的半更新状态。
|
||||||
Reference in New Issue
Block a user