chore: 初始化官网白标基座项目(含设计文档)
This commit is contained in:
+32
@@ -0,0 +1,32 @@
|
|||||||
|
# ===== 依赖 =====
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# ===== 构建产物 =====
|
||||||
|
dist/
|
||||||
|
.output/
|
||||||
|
.astro/
|
||||||
|
|
||||||
|
# ===== 日志 =====
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# ===== 环境变量与密钥(含阿里云 AK/SK,切勿提交)=====
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
.ossutilconfig
|
||||||
|
ossutil_config*
|
||||||
|
|
||||||
|
# ===== 客户专属内容(每个客户独立,不入基座仓库)=====
|
||||||
|
clients/*/
|
||||||
|
|
||||||
|
# ===== 系统 =====
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# ===== 编辑器 =====
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Official Site Base · 官网白标基座
|
||||||
|
|
||||||
|
一人公司「[产品线 E · 快速官网](../../一人公司开源项目选型清单.md)」的可复用基座。
|
||||||
|
|
||||||
|
## 一句话
|
||||||
|
|
||||||
|
**Astro + Sveltia CMS + 自建 Gitea + 阿里云 OSS/CDN** —— 客户在 `/admin` 可视化自助改内容、客户侧零服务器、一套基座复制给多客户。
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
|
||||||
|
- 客户在可视化后台自助改内容(公司 / 产品 / 新闻 / 案例 / 招聘 / 下载 / 留言)
|
||||||
|
- 客户侧零服务器(访客访问 OSS + CDN 纯静态站)
|
||||||
|
- 一套基座复制给多客户(换设计 token + 换内容)
|
||||||
|
|
||||||
|
## 文档
|
||||||
|
|
||||||
|
- **设计文档**:[docs/specs/2026-07-23-official-site-cms-design.md](docs/specs/2026-07-23-official-site-cms-design.md)
|
||||||
|
- **上游选型清单**:工作区根《一人公司开源项目选型清单.md》§5 / §9-E
|
||||||
|
|
||||||
|
## 技术栈(全部 MIT / 商业,已原文核实)
|
||||||
|
|
||||||
|
| 层 | 选型 |
|
||||||
|
|----|------|
|
||||||
|
| 官网框架 | Astro(SSG) |
|
||||||
|
| 官网主题 | Astro Wind 起步,逐步沉淀自有主题 |
|
||||||
|
| 自助 CMS | Sveltia CMS |
|
||||||
|
| Git 后端 + CI | 自建 Gitea(+ Gitea Actions) |
|
||||||
|
| 表单后端 | 自研轻量微服务(复用 Gitea 那台轻量云) |
|
||||||
|
| 对象存储 + CDN | 阿里云 OSS + CDN |
|
||||||
|
|
||||||
|
## 实施阶段
|
||||||
|
|
||||||
|
| 阶段 | 目标 |
|
||||||
|
|------|------|
|
||||||
|
| Phase 0 | 技术验证:最小链路跑通(Astro + Sveltia + Gitea → 构建 → OSS) |
|
||||||
|
| Phase 1 | 基座化:沉淀自有主题 + Content Collections + 白标脚本 |
|
||||||
|
| Phase 2 | 首客户上线 |
|
||||||
|
| Phase 3(可选) | 加 Payload 适配器,接富后台客户 |
|
||||||
|
|
||||||
|
## 状态
|
||||||
|
|
||||||
|
📋 设计已确认,待出实施计划(Phase 0 技术验证)。
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
# 官网 + 轻量自助 CMS 白标基座 设计文档
|
||||||
|
|
||||||
|
> **产品线**:一人公司开源项目选型清单 §5「建站(官网)」升级方案(产品线 E)
|
||||||
|
> **日期**:2026-07-23
|
||||||
|
> **状态**:设计已确认,待写实施计划
|
||||||
|
> **关联**:升级自 [一人公司开源项目选型清单](../../../一人公司开源项目选型清单.md) §5 / §9-E
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、背景与目标
|
||||||
|
|
||||||
|
### 1.1 原方案的三个缺口
|
||||||
|
|
||||||
|
一人公司选型清单中,官网搭建(产品线 E)原方案是「Astro + Astro Wind」纯 SSG,存在三个缺口:
|
||||||
|
|
||||||
|
1. **基座复用没落地** —— 文档第③条选型原则「一套基座吃多客户」在官网线未体现,每次都 fork 第三方模板,变成一锤子买卖。
|
||||||
|
2. **缺「官网 + 自助 CMS」混合方案** —— 纯 SSG 客户改内容只能走你,内容代维护变成长期负担,吃掉利润。
|
||||||
|
3. **未覆盖国内部署** —— 文档建议的 Vercel / Cloudflare Pages 在国内访问慢且常被墙,国内客户官网必须备案 + 国内 CDN。
|
||||||
|
|
||||||
|
### 1.2 目标
|
||||||
|
|
||||||
|
打造一套**可复用的官网白标基座**:
|
||||||
|
|
||||||
|
- 客户在可视化后台**自助改内容**(公司 / 产品 / 新闻 / 案例 / 招聘 / 下载 / 留言)
|
||||||
|
- **客户侧零服务器** —— 访客访问的是 OSS + CDN 纯静态站
|
||||||
|
- **一套基座复制给多客户** —— 换设计 token + 换内容即可交付新客户
|
||||||
|
- **国内合规上线** —— ICP 备案 + 阿里云 OSS/CDN
|
||||||
|
|
||||||
|
### 1.3 非目标(YAGNI 边界)
|
||||||
|
|
||||||
|
- ❌ 多语言 i18n(除非客户明确付费要求)
|
||||||
|
- ❌ 电商 / 支付(那是产品线 A,CRMEB)
|
||||||
|
- ❌ 会员 / 工单 / 审批(那是产品线 B,若依 / 低代码)
|
||||||
|
- ❌ 富后台 / 多角色 CMS(预留 Payload 适配器接口,遇到高预算客户再加,不在首期实现)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、已确认的关键决策
|
||||||
|
|
||||||
|
| # | 决策点 | 结论 |
|
||||||
|
|---|--------|------|
|
||||||
|
| 1 | 定位 | 白标基座 + 首客户驱动(先跑通一个真实客户,再沉淀复用资产) |
|
||||||
|
| 2 | Git 后端 + CI | **自建一台 Gitea**(含 Gitea Actions),所有客户共用,多租户 |
|
||||||
|
| 3 | 内容板块 | company / products / news / cases / pages + **jobs(招聘)/ downloads(下载)/ messages(留言表单)** |
|
||||||
|
| 4 | 云厂商 | **阿里云**(OSS + CDN + 域名 + ICP 备案) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、技术栈选型(License 全部原文核实)
|
||||||
|
|
||||||
|
| 层 | 选型 | License | 核实来源 | 选型理由 |
|
||||||
|
|----|------|---------|----------|----------|
|
||||||
|
| 官网框架 | **Astro**(SSG) | ✅ MIT | withastro/astro LICENSE | 零运行时、SEO 满分、Content Collections 类型安全 |
|
||||||
|
| 官网主题 | **Astro Wind** 起步,逐步沉淀**自有主题** | ✅ MIT | onwidget/astrowind LICENSE | 半天换皮;基座化后替换为自有 token 主题 |
|
||||||
|
| 自助 CMS | **Sveltia CMS** | ✅ MIT | sveltia/sveltia-cms `LICENSE.txt` + 官方 FAQ | Decap 的现代替代、原生支持 Gitea、活跃;Keystatic 锁 GitHub 不适合国内 |
|
||||||
|
| Git 后端 + CI | **自建 Gitea**(+ Gitea Actions) | ✅ MIT | go-gitea/gitea LICENSE | 单二进制极轻、被 Sveltia 原生支持、一台服务多客户、完全自控 |
|
||||||
|
| 表单后端 | **自研轻量微服务** | 自研(MIT) | — | 复用 Gitea 那台轻量云,零额外服务器 |
|
||||||
|
| 对象存储 + CDN | **阿里云 OSS + CDN** | 商业 | — | 国内访问快、抗刷、备案友好 |
|
||||||
|
| 域名 / 备案 | 阿里云域名 + ICP 备案 | 商业 | — | 国内合规必须 |
|
||||||
|
|
||||||
|
> **技术验证结论(已查实)**:Sveltia CMS / Decap CMS 都**不原生支持 Gitee**(要走自建 git-gateway + OAuth 代理,复杂且脆);GitHub 国内 OAuth 不稳。**Gitea 是两大 CMS 都原生支持**的国内可用后端,且自带 Actions CI,故选自建 Gitea。
|
||||||
|
|
||||||
|
全部为 🟢 MIT / 商业服务,**无 AGPL / GPL / BSL 传染风险**,白标转售安全。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、整体架构
|
||||||
|
|
||||||
|
```
|
||||||
|
① 客户编辑 ② 构建发布 ③ 访客访问
|
||||||
|
┌────────────┐ 提交 ┌─────────────────┐ 同步 ┌──────────────┐
|
||||||
|
│ Sveltia │────────▶│ 自建 Gitea │────────▶│ 阿里云 │
|
||||||
|
│ /admin │ │ + Gitea Actions │ │ OSS + CDN │
|
||||||
|
│ (可视化) │◀────────│ (构建 Astro) │ │ (纯静态) │
|
||||||
|
└────────────┘ OAuth └─────────────────┘ └──────────────┘
|
||||||
|
│ │
|
||||||
|
│ ┌────────┴────────┐
|
||||||
|
└──────────────┤ 一台轻量云 │
|
||||||
|
表单提交 │ ① Gitea + CI │
|
||||||
|
│ ② 表单微服务 │ ← 服务【所有客户】
|
||||||
|
│ ③ SQLite 留底 │ 多租户共用
|
||||||
|
└─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**三层职责**:
|
||||||
|
|
||||||
|
- **编辑层**:客户在 `https://<客户域名>/admin`(Sveltia CMS 单页应用)可视化编辑,OAuth 登录自建 Gitea。
|
||||||
|
- **构建 / 存储层**:自建 Gitea(一台轻量云)。客户提交 → Gitea Actions 自动构建 Astro → `ossutil` 同步到该客户的 OSS bucket → 刷新 CDN。表单微服务也跑在这台机上。
|
||||||
|
- **访客层**:阿里云 OSS 托管静态站 + CDN 加速,访客全程不碰服务器,快、稳、抗刷。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、内容模型(Astro Content Collections)
|
||||||
|
|
||||||
|
每个集合配 Zod schema 校验,客户在 Sveltia 填错会自动报错。
|
||||||
|
|
||||||
|
| 集合 | 类型 | 字段 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| `company` | 单例 | name / intro / logo / phone / email / address / icp | 全站公共信息(页头页脚) |
|
||||||
|
| `products` | 集合 | title / cover / summary / body / category / sort | 产品或服务 |
|
||||||
|
| `news` | 集合 | title / date / category / cover / body | 新闻动态(带分页 + RSS) |
|
||||||
|
| `cases` | 集合 | client / industry / cover / result / body | 客户案例 |
|
||||||
|
| `pages` | 集合 | slug / title / body / showInNav | 关于我们、联系等静态页 |
|
||||||
|
| `jobs` | 集合 | title / location / department / requirement / body | 招聘岗位 |
|
||||||
|
| `downloads` | 集合 | name / description / fileUrl / category / size | 下载资源(文件存 OSS,见 §七) |
|
||||||
|
| `messages` | 表单 | name / phone / email / message / createdAt | 留言(见 §六,由表单微服务写入) |
|
||||||
|
|
||||||
|
> `messages` 不由客户手动编辑,而是由访客提交的留言表单经微服务写入(通过 Gitea API 落成 Markdown 文件到该集合),客户在 `/admin` 查看,同时收到邮件通知。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、留言表单方案(messages)
|
||||||
|
|
||||||
|
纯静态站(OSS + CDN)无法处理后端逻辑,故**复用 Gitea 那台轻量云**,跑一个自研的极轻表单微服务。
|
||||||
|
|
||||||
|
### 6.1 技术栈
|
||||||
|
|
||||||
|
- **运行时**:Node.js + Hono(或 Express)
|
||||||
|
- **写内容**:通过 Gitea API 把留言写成 Markdown 提交到 `messages` 集合(Git 即留底,无需额外数据库)
|
||||||
|
- **邮件**:nodemailer + 阿里云邮件推送(DirectMail)SMTP,或腾讯企业邮 SMTP
|
||||||
|
- **失败兜底**:Gitea 写失败时记本地日志文件,保证不丢留言
|
||||||
|
- **部署**:systemd 或 docker,跑在 Gitea 同机
|
||||||
|
- **凭据**:微服务持有一个专用 Gitea token,仅对该客户仓库有写权限(最小权限)
|
||||||
|
|
||||||
|
### 6.2 处理流程
|
||||||
|
|
||||||
|
```
|
||||||
|
访客填表 → POST https://forms.<你的服务域名>/api/submit
|
||||||
|
→ ① 蜜罐字段检查(机器人会填隐藏字段 → 丢弃)
|
||||||
|
→ ② IP 限流(每 IP 每分钟 ≤5 次)
|
||||||
|
→ ③ 字段校验(Zod)
|
||||||
|
→ ④ 经 Gitea API 写入 `messages` 集合(Markdown,客户在 /admin 查看)
|
||||||
|
→ ⑤ SMTP 发邮件通知客户(含留言内容)
|
||||||
|
→ 返回成功页
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.3 多租户
|
||||||
|
|
||||||
|
一个微服务服务所有客户:配置文件映射 `form_id → { 客户邮箱, 跳转页 }`。新客户加一行配置即可。前端表单的 `action` 带上该客户的 `form_id`。
|
||||||
|
|
||||||
|
### 6.4 防垃圾
|
||||||
|
|
||||||
|
- 蜜罐字段(必填陷阱)
|
||||||
|
- IP 限流
|
||||||
|
- 可选:阿里云验证码 / hCaptcha(垃圾严重时再加,YAGNI)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、下载文件方案(downloads)
|
||||||
|
|
||||||
|
下载文件(PDF 手册、驱动、视频)**不进 Git 仓库**(大文件不友好),统一存 OSS:
|
||||||
|
|
||||||
|
- 文件手动或脚本上传到该客户 OSS bucket 的 `/downloads/` 目录
|
||||||
|
- `downloads` 内容集合只记录元信息:`name / description / fileUrl(OSS URL)/ category / size`
|
||||||
|
- 客户在 Sveltia 编辑下载项的描述,文件本身由你或客户用 OSS 工具上传(Sveltia 的媒体库只给图片用,不混用)
|
||||||
|
|
||||||
|
> 小文件(<2MB 的 PDF)可直接 Sveltia 上传到 Gitea 仓库;大文件走 OSS。以 OSS 为主,避免仓库膨胀。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、白标复用(新客户上线流程)
|
||||||
|
|
||||||
|
基座 = 一个 Astro 主题仓库(含组件区段 + Content Collections schema + Sveltia 配置模板 + Gitea Action 工作流)。
|
||||||
|
|
||||||
|
新客户交付 = 7 步:
|
||||||
|
|
||||||
|
1. **fork 基座** → 在自建 Gitea 建新仓库(独立组织/权限隔离)
|
||||||
|
2. **改设计 token** → 改一个 CSS 变量文件(主色 / 字体 / 圆角),整站换皮
|
||||||
|
3. **配 Sveltia** `config.ts` → 勾选该客户需要的内容板块(如纯展示型客户去掉 jobs/downloads)
|
||||||
|
4. **客户填内容** → 在 `/admin` 用 Sveltica 录入
|
||||||
|
5. **域名 + 备案** → 阿里云买域名 + ICP 备案(约 7-20 工作日)
|
||||||
|
6. **建 OSS bucket + CDN** → 配静态站托管 + 绑定自定义域名
|
||||||
|
7. **配 Gitea Action** → 构建后 `ossutil` 上传 + 刷新 CDN → 上线,转月度维护续费
|
||||||
|
|
||||||
|
> 每个客户 = 一个 Gitea 仓库 + 一个 OSS bucket + 一个域名 + 一行表单配置;**基座代码复用、配置隔离**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、国内部署(阿里云)
|
||||||
|
|
||||||
|
- [ ] **ICP 备案**:客户域名必须备案,否则 CDN / 解析受阻(备案约 7-20 工作日,提前启动)
|
||||||
|
- [ ] **OSS 静态站托管**:开 bucket 的静态网站托管 + 绑定自定义域名(HTTPS)
|
||||||
|
- [ ] **CDN 加速**:回源 OSS,缓存策略 —— HTML 短缓存(1-5 分钟,便于内容更新生效)、JS/CSS/图片长缓存 + 文件名 hash
|
||||||
|
- [ ] **CI 发布脚本**:Gitea Action 构建后用 `ossutil cp -rf dist/ oss://<bucket>/` 上传 + 调 OpenAPI 刷新 CDN
|
||||||
|
- [ ] **HTTPS**:阿里云免费 SSL 证书(或 Let's Encrypt),绑 OSS / CDN
|
||||||
|
- [ ] ⚠️ **不要用 Vercel / Cloudflare Pages**(国内访问慢 / 常被墙)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、成本测算
|
||||||
|
|
||||||
|
| 项 | 金额 | 说明 |
|
||||||
|
|----|------|------|
|
||||||
|
| 固定:轻量云(Gitea + CI + 表单微服务) | ≈ 60-100 元/月 | **所有客户共用**,2H2G 推荐 |
|
||||||
|
| 每客户:OSS + CDN | ≈ 5-15 元/月 | 按量,企业官网流量小 |
|
||||||
|
| 每客户:域名 | ≈ 55 元/年 | — |
|
||||||
|
| 每客户:备案 | 0 | 阿里云免费备案 |
|
||||||
|
| 每客户:邮件推送 | 极低 | DirectMail 按发信量,几毛/月 |
|
||||||
|
| **客单价**(参考文档 E 线) | **5k-2 万 + 月度维护续费** | 半天换皮、长期续费 |
|
||||||
|
|
||||||
|
**结论**:新增一个客户的边际成本 ≈ 60-100 元/年(域名 + OSS/CDN),客单价 5k 起,毛利极高。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、风险与先验证点(Phase 0 必须跑通)
|
||||||
|
|
||||||
|
| # | 风险 / 验证点 | 应对 |
|
||||||
|
|---|--------------|------|
|
||||||
|
| 1 | Gitea Actions 能否跑 Astro 构建 | 兼容 GitHub Actions 语法,Phase 0 用 node runner 镜像验证 |
|
||||||
|
| 2 | Sveltia + Gitea OAuth 登录 / 提交全链路 | Phase 0 配 Gitea OAuth App 跑通 |
|
||||||
|
| 3 | CDN 刷新延迟 | 秒-分钟级,HTML 配短缓存可接受 |
|
||||||
|
| 4 | 多租户 Gitea 权限隔离 | 每客户独立组织 / 仓库权限 |
|
||||||
|
| 5 | 表单微服务防垃圾 / 可用性 | 蜜罐 + 限流先上,验证码按需 |
|
||||||
|
| 6 | 备案周期长阻塞交付 | 合同里写明备案周期,提前启动或先用临时域名 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十二、实施阶段
|
||||||
|
|
||||||
|
| 阶段 | 目标 | 产出 |
|
||||||
|
|------|------|------|
|
||||||
|
| **Phase 0** 技术验证 | 最小链路跑通:Astro + Sveltia + 自建 Gitea → 构建 → OSS → 访问;表单微服务跑通 | 一个可编辑、可留言的 demo 站 |
|
||||||
|
| **Phase 1** 基座化 | 沉淀自有主题 + Content Collections(7 个集合)+ Sveltia 配置模板 + 白标脚本(换 token / 建 bucket) | 可复用基座仓库 |
|
||||||
|
| **Phase 2** 首客户上线 | 用真实客户驱动,验证商业闭环 + 续费 | 第一个交付 + 月度维护合同 |
|
||||||
|
| **Phase 3**(可选) | 加 Payload 适配器,接富后台 / 多角色高预算客户 | 双档产品线(轻量 / 富后台) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十三、CMS 适配器(预留,兼容未来 Payload)
|
||||||
|
|
||||||
|
把内容获取抽象成统一接口,保护 Astro 层不随 CMS 变化:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// 概念接口
|
||||||
|
interface ContentAdapter {
|
||||||
|
getCollection<T>(name: string): Promise<T[]>;
|
||||||
|
getSingleton<T>(name: string): Promise<T>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **默认实现**:`MarkdownAdapter` —— 读本地 Markdown(Gitea + Sveltia 路线,首期实现)
|
||||||
|
- **预留实现**:`PayloadAdapter` —— 调 Payload REST/GraphQL API(Phase 3,遇到富后台客户再加)
|
||||||
|
|
||||||
|
切换 CMS 只换适配器,Astro 页面层与 Content Collections schema 不变。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十四、交付前检查清单(沿用选型清单 §十)
|
||||||
|
|
||||||
|
每个客户上线前:
|
||||||
|
|
||||||
|
- [ ] 该客户仓库的 LICENSE 文件原文我读了吗?(基座 + 依赖)
|
||||||
|
- [ ] 有没有子目录独立 LICENSE(ee/ / server/ / enterprise/)?
|
||||||
|
- [ ] 我的交付方式(私有部署 / SaaS / 转售)会触发哪个条款?
|
||||||
|
- [ ] Sveltia / Gitea / Astro 的 License 变更记录复查了吗?
|
||||||
|
|
||||||
|
**把 LICENSE 原文 + 近 3 年 license 变更记录存档到客户合同附件。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 参考资料
|
||||||
|
|
||||||
|
- [一人公司开源项目选型清单](../../../一人公司开源项目选型清单.md)
|
||||||
|
- [Astro 官网](https://astro.build/) · [Astro Wind](https://github.com/onwidget/astrowind)
|
||||||
|
- [Sveltia CMS 官网](https://sveltiacms.app/) · [Sveltia CMS Backends 文档](https://sveltiacms.app/en/docs/backends) · [官方 FAQ(MIT)](https://sveltiacms.app/en/docs/faq)
|
||||||
|
- [Gitea 官网](https://gitea.io/) · [Gitea Actions 文档](https://docs.gitea.com/usage/actions/overview)
|
||||||
|
- [阿里云 OSS 静态网站托管](https://help.aliyun.com/product/31815.html) · [阿里云 CDN](https://help.aliyun.com/product/27099.html) · [阿里云邮件推送 DirectMail](https://help.aliyun.com/product/29412.html)
|
||||||
|
- [Decap CMS Backend 概览](https://decapcms.org/docs/backends-overview/)(对照为何选 Sveltia + Gitea 而非 Gitee)
|
||||||
Reference in New Issue
Block a user