Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Neokoni's OTA Center — 文档

本目录包含 **ota_site** 项目的完整技术文档。

## 文档目录

| 文档 | 描述 |
|------|------|
| [快速入门](./getting-started.md) | 本地开发环境搭建 |
| [项目架构](./architecture.md) | 项目结构与技术架构说明 |
| [添加设备](./adding-devices.md) | 如何添加新设备和 ROM 版本 |
| [OTA JSON 格式](./ota-json-format.md) | 面向刷机工具的 OTA JSON 文件格式说明 |
| [生成 OTA JSON](./generate-ota-json.md) | 使用 `generate_ota_json.py` 脚本生成 OTA JSON |
| [部署](./deployment.md) | CI/CD 与服务器部署说明 |

## 项目简介

**ota_site** 是一个自托管的 OTA(空中升级)信息站点,用于展示 Neokoni ROM 构建的更新记录。用户可以在此站点:

- 浏览所有受支持的设备列表
- 查看每台设备上可用的 ROM 系统及版本
- 阅读各版本的详细更新日志
- 获取 OTA 下载包的 JSON 链接(供刷机工具自动识别)

## 技术栈概览

- **前端框架**:[Vue 3](https://vuejs.org/) + TypeScript
- **构建工具**:[Vite](https://vite.dev/)
- **UI 组件库**:[MDUI 2](https://www.mdui.org/)(Material Design 3)
- **路由**:[Vue Router 4](https://router.vuejs.org/)
- **CI/CD**:GitHub Actions + SSH 部署
169 changes: 169 additions & 0 deletions docs/adding-devices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# 添加设备与 ROM 版本

本文档介绍如何向站点添加新设备、新 ROM 系统或新版本,以及如何更新现有版本的更新日志。

## 数据结构概览

每台设备对应 `src/ota/` 目录下的一个 JSON 文件,格式如下:

```jsonc
{
"codename": "设备代号", // 设备代号(全小写,与文件名一致)
"name": "设备显示名称",
"systems": [
{
"name": "ROM名称", // 例如 "AviumUI"
"description": "简介", // 可选
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里标注 systems[].description 为“可选”,但当前类型定义 src/config/devices.tsSystemConfigdescription 声明为必填 string。为避免新增设备 JSON 时产生困惑,建议文档与类型保持一致:要么把文档改为必填,要么先把 SystemConfig.description 改为可选后再在文档中说明可选。

Suggested change
"description": "简介", // 可选
"description": "简介", // ROM 简介

Copilot uses AI. Check for mistakes.
"versions": [
{
"version": "版本标识", // 例如 "avium-16"
"label": "版本显示名", // 例如 "类原生 AviumUI 16"
"otaUrl": "/AviumUI/avium-16/设备代号/ota.json", // 可选,OTA JSON 路径
"releases": [
{
"date": "YYYY-MM-DD",
"version": "可选,具体版本号",
"changes": [
"更新内容条目1",
"更新内容条目2(支持 HTML,如 <a> <code> <s> 标签)"
]
}
]
}
]
}
]
}
```

> **注意**:`releases` 数组的排序无关紧要,站点会在展示时按日期降序自动排列(最新日期显示在最前)。

## 添加新设备

### 第一步:创建设备 JSON 文件

在 `src/ota/` 目录下新建一个以设备代号命名的 JSON 文件,例如 `src/ota/lisa.json`:

```json
{
"codename": "lisa",
"name": "Xiaomi 11 Lite 5G NE",
"systems": [
{
"name": "AviumUI",
"versions": [
{
"version": "avium-16",
"label": "类原生 AviumUI 16",
"otaUrl": "/AviumUI/avium-16/lisa/ota.json",
"releases": [
{
"date": "2026-03-01",
"changes": [
"初始构建版本"
]
}
]
}
]
}
]
}
```

新文件会被 `src/config/devices.ts` 中的 `import.meta.glob` 自动加载,**无需修改任何其他文件**。

### 第二步(可选):添加 OTA JSON 文件

如果刷机工具需要读取 OTA 信息,在 `public/` 目录下创建对应路径的 `ota.json`:

```
public/AviumUI/avium-16/lisa/ota.json
```

文件格式详见 [OTA JSON 格式](./ota-json-format.md)。可以使用 `scripts/generate_ota_json.py` 脚本自动生成,详见[生成 OTA JSON](./generate-ota-json.md)。

## 添加新 ROM 系统

在现有设备的 JSON 文件中,向 `systems` 数组追加一个新对象即可:

```json
{
"codename": "nabu",
"name": "Xiaomi Pad 5",
"systems": [
{
"name": "AviumUI",
"versions": [ ... ]
},
{
"name": "LineageOS",
"versions": [
{
"version": "lineage-22",
"label": "LineageOS 22.1",
"releases": [
{
"date": "2026-03-01",
"changes": ["初始构建"]
}
]
}
]
}
]
}
```

## 添加新版本

在对应系统的 `versions` 数组中追加一个新版本对象:

```json
{
"version": "avium-17",
"label": "类原生 AviumUI 17",
"otaUrl": "/AviumUI/avium-17/nabu/ota.json",
"releases": [
{
"date": "2026-06-01",
"changes": ["升级至 Android 17 基础版本"]
}
]
}
```

## 更新现有版本的更新日志

直接向对应版本的 `releases` 数组中追加一条新记录即可,例如:

```json
{
"date": "2026-03-10",
"changes": [
"上游代码:",
"1. 更新安全补丁",
"内核:",
"1. 修复已知崩溃问题"
]
}
```

> **技巧**:`changes` 字段支持 HTML 内联标签,例如:
> - `<a href="..." target="_blank">链接文字</a>`
> - `<code>代码片段</code>`
> - `<s>删除线文字</s>`

## 验证

修改完成后,运行开发服务器检查展示效果:

```bash
npm run dev
```

访问对应设备路径,确认更新日志正常显示。如需检查类型,也可运行:

```bash
npm run type-check
```
127 changes: 127 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# 项目架构

## 目录结构

```
ota/
├── public/
│ └── AviumUI/
│ └── avium-16/
│ ├── nabu/
│ │ └── ota.json # 小米平板5 OTA 信息(供刷机工具读取)
│ └── lemonades/
│ └── ota.json # 一加9R OTA 信息(供刷机工具读取)
├── scripts/
│ └── generate_ota_json.py # 自动生成 OTA JSON 的 Python 脚本
├── src/
│ ├── assets/
│ │ └── main.css # 全局样式
│ ├── config/
│ │ ├── devices.ts # 设备数据类型定义与加载逻辑
│ │ └── site.ts # 站点配置(ICP 备案、壁纸 API)
│ ├── ota/
│ │ ├── nabu.json # 小米平板5 更新日志数据
│ │ └── lemonades.json # 一加9R 更新日志数据
│ ├── router/
│ │ └── index.ts # Vue Router 路由定义
│ ├── views/
│ │ ├── HomeView.vue # 首页
│ │ ├── DeviceSelectionView.vue # 设备选择页
│ │ ├── DeviceView.vue # 设备详情页(系统列表)
│ │ ├── SystemView.vue # 系统版本列表页
│ │ ├── ChangelogView.vue # 版本更新日志页
│ │ └── NotFoundView.vue # 404 页面
│ ├── App.vue # 根组件(顶部栏、侧边导航、主题切换)
│ └── main.ts # 应用入口
├── docs/ # 项目文档
├── .github/
│ └── workflows/
│ └── deployment.yml # CI/CD 自动部署工作流
├── index.html # HTML 入口文件
├── vite.config.ts # Vite 配置(含自定义插件)
├── tsconfig.json # TypeScript 配置(根)
├── tsconfig.app.json # TypeScript 配置(应用)
└── tsconfig.node.json # TypeScript 配置(Node 环境)
```

## 技术栈

| 技术 | 版本 | 用途 |
|------|------|------|
| Vue 3 | 3.5.x | 前端框架(Composition API) |
| TypeScript | ~5.9 | 类型系统 |
| Vite | ^7.x | 构建工具与开发服务器 |
| Vue Router 4 | ^4.6 | 客户端路由 |
| MDUI 2 | ^2.1 | Material Design 3 UI 组件库 |
| Roboto / Noto Sans SC | — | 字体(中英文) |

## 路由结构

| 路径 | 组件 | 说明 |
|------|------|------|
| `/` | `HomeView` | 首页(品牌介绍 + 入口按钮) |
| `/devices` | `DeviceSelectionView` | 设备选择列表 |
| `/device/:codename` | `DeviceView` | 设备页(显示可用 ROM 系统) |
| `/device/:codename/:system` | `SystemView` | 系统页(显示可用版本) |
| `/device/:codename/:system/:version` | `ChangelogView` | 版本更新日志 |
| `/:pathMatch(.*)` | `NotFoundView` | 404 页面 |

## 数据流

```
src/ota/*.json
src/config/devices.ts ← import.meta.glob 动态加载所有 JSON
├─ devices[] → DeviceSelectionView / App.vue 侧边导航
├─ getDevice() → DeviceView / ChangelogView
└─ getSystem() → SystemView / ChangelogView
```

所有设备数据来源于 `src/ota/` 目录下的 JSON 文件,`devices.ts` 使用 Vite 的 `import.meta.glob` 在构建时自动加载所有文件,无需手动注册。

## App.vue 根组件功能

- **顶部应用栏**:品牌名称、菜单按钮、主题切换按钮
- **侧边抽屉导航**:首页入口 + 所有设备快捷链接(自动从 `devices` 配置生成)
- **主题模式**:支持 `auto` / `light` / `dark` 三档,偏好保存到 `localStorage`
- **动态配色**:通过必应壁纸 API 提取主色调,调用 MDUI 的 `setColorScheme` 动态换肤

## Vite 自定义插件

`vite.config.ts` 中包含两个自定义 Vite 插件,用于向刷机工具(如 Avium 内置 OTA 检查器)暴露纯文本格式的更新日志:

### `bpPlainTextMiddleware`

- **触发条件**:请求的 `User-Agent` 中包含 `Build/BP`
- **匹配路径**:`/device/:codename/AviumUI/avium-16`
- **响应**:以 `text/plain` 格式返回该设备 AviumUI avium-16 版本的所有更新日志,HTML 标签被自动剥离

### `alwaysPlainTextPagePlugin`

- **匹配路径**:`/plain/device/:codename/AviumUI/avium-16`
- **开发/预览模式**:动态返回纯文本更新日志
- **生产构建**:在 `dist/plain/device/:codename/AviumUI/avium-16/index.txt` 生成静态文本文件

纯文本格式示例:

```
2026-02-26
==================
上游代码:
1. 更新AviumUI 16.2版本(QPR2)
内核:
1. 更新KernelSU

2026-01-16
==================
...
```

## 站点配置

`src/config/site.ts` 导出两项配置:

- **`siteConfig`**:页脚 ICP 备案信息数组,每项包含 `icp`(备案号)和 `icpLink`(链接)
- **`wallpaperConfig`**:壁纸 API 地址,用于动态配色初始化
Loading