# 应用内公告（无需服务器）

Pho 社区版启动时会读取本仓库里的 `docs/announcement.json`，命中就弹出公告。
托管全部走免费静态通道，不需要买服务器。

## 六条源（客户端并发请求，再挑「最新的那份」）

| 优先级 | URL | 实测 | 说明 |
| --- | --- | --- | --- |
| 1 | `raw.githubusercontent.com/…/main/docs/announcement.json` | 200 · 新鲜 | 延迟约 5 分钟；国内常被 reset |
| 2 | `pho.zenithliteaura.site/announcement.json` | 200 · 新鲜 | **自建镜像**（Cloudflare 代理 GitHub Pages），国内可达性通常更好 |
| 3 | `zenithliteaura.github.io/Pho_Community/announcement.json` | 200 · 新鲜 | Pages：Source = `main` / `/docs`，约 10 分钟生效 |
| 4 | `github.com/ZenithLiteAura/Pho_Community/raw/main/docs/announcement.json` | 200 · 新鲜 | 会 302 到 raw 域名，国内同样不可达 |
| 5 | `gcore.jsdelivr.net/gh/…@main/docs/announcement.json` | 200 · **可能旧** | 国内可达性好，但 `@main` 的分支解析会被缓存 |
| 6 | `cdn.jsdelivr.net/gh/…@main/docs/announcement.json` | 200 · **可能旧** | 国内可达，缓存最长 12 小时 |

**取源规则**：客户端并发请求全部源，然后

- JSON 里带 `updatedAt` 时 → **取 `updatedAt` 最新的那一份**；
- 都没有 `updatedAt` 时 → 退回按上表优先级取第一个可用结果；
- 「最新的那一份是 `enabled:false`」→ 按「没有公告」处理，**不会**回退到更旧的源
  （否则会把已经下线的公告又弹出来）。

> ⚠️ 实测：jsDelivr 的 `@main` 地址会**长时间停在旧提交**。而
> `https://purge.jsdelivr.net/gh/ZenithLiteAura/Pho_Community@main/docs/announcement.json`
> 只能清文件缓存、**清不掉分支解析** —— purge 返回 finished 之后，gcore / cdn 仍然返回旧内容。
> 所以别再把 jsDelivr 当「立即生效」的通道；靠客户端按 `updatedAt` 取最新即可。

### 站点（两条访问路径，内容同一份）

1. 仓库 **Settings → Pages** → **Source** = `Deploy from a branch`；
2. **Branch** = `main`，目录 = `/docs`；构建约 1–2 分钟，CDN 缓存约 10 分钟；
3. **GitHub Pages**：`https://zenithliteaura.github.io/Pho_Community/`；
4. **自建镜像**（Cloudflare 代理 Pages，实时同步）：`https://pho.zenithliteaura.site/`
   —— 公告 JSON `…/announcement.json`，已作为客户端第 2 条源。

`docs/.nojekyll` 已随仓库提供（禁用 Jekyll）。注意：**装了 .nojekyll 后 `.md` 不会被渲染成网页**，
所以落地页必须是 `index.html`。

## 字段说明

| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `enabled` | ✅ | 必须为 `true` 才会弹；平时留 `false` 相当于「没有公告」 |
| `id` | ✅ | 唯一标识。**换 id 才会再次弹出**（`once` 为 true 时） |
| `level` | ❌ | `info`（默认）/ `warning` / `critical`。`critical` 为强制展示：点遮罩与返回键都关不掉，只能点按钮 |
| `title` | ❌ | 标题。可写成 `{"zh":"…","en":"…"}`，也可写成单个字符串 |
| `body` | ❌ | 正文，格式同上；title 与 body 至少有一个非空 |
| `url` | ❌ | 详情/下载链接，弹窗里会显示「前往查看」按钮 |
| `startAt` / `endAt` | ❌ | 生效窗口，ISO 8601 带时区，如 `2026-10-07T00:00:00+08:00`；留空字符串表示不限 |
| `minVersion` / `maxVersion` | ❌ | 只对指定版本区间可见（闭区间），如 `minVersion: "3.4"`；留空表示不限 |
| `once` | ❌ | 默认 `true`：同一 `id` 只弹一次（已读记录存在客户端本地） |
| `updatedAt` | ❌ | 云端最后修改时间，ISO 8601。应用内「公告管理工具」发布时会自动写入；手改 JSON 建议一并更新——客户端据此跨镜像源取最新 |

客户端只在「`enabled=true` + 时间窗口内 + 版本区间内 + 该 id 没读过」时才弹窗；
具体用哪一份内容由上面的「取源规则」决定。

## 典型用法

**重要故障提醒（强制展示）**：`level` 用 `critical`，`once` 保持 `true`——
用户必须点一下「我知道了」才能关掉，同一个 id 不会一直骚扰。

**新版本引导**：配合 Release 使用，`url` 指向
`https://github.com/ZenithLiteAura/Pho_Community/releases`。
（应用还有独立的「检查更新」功能，会直接比对 Releases 的最新 tag，无需在这里重复写版本号。）

**临时维护窗口**：`startAt`/`endAt` 卡住时间段，到点自动消失，不用手动删。

## 用户侧开关

客户端「设置 → 关于 → 高级设置 → 启动时检查公告」可以关闭读取（默认开启）。
