Refine download controls and simplify project documentation
Build and publish website container / build (push) Successful in 6m48s

This commit is contained in:
KenanZhu committed 2026-11-05 12:49:43 +08:00
1 parent 421c2a9fcc
commit 4861439581
8 files changed
+24 -360

No files matched your search

+11 -74
View File
@@ -1,97 +1,34 @@
# AutoLibrary Website
北京建筑大学图书馆自动化工具的官网、软件下载中心与社区主题市场。
AutoLibrary 官网、软件下载中心与主题市场,使用 Vue 3、TypeScript、Go/Gin、SQLite 和 Casdoor。
- 产品仓库:<https://gitea.kenanzhu.com/KenanZhu/AutoLibrary>
- 用户手册:<https://manuals.autolibrary.kenanzhu.com>
- 发行版本:<https://gitea.kenanzhu.com/KenanZhu/AutoLibrary/releases>
## 架构
前端采用 Vue 3、TypeScript、Vite、Vue Router、Pinia 和 Lucide 图标。所有字体、图标和图片随构建产物提供,无需第三方 CDN。页面使用统一的布局、表单和状态组件,深浅主题由 CSS 语义变量管理。
Go/Gin 前端服务提供构建产物并将 `/api/*` 代理到后端;后端保留 GORM/SQLite、Casdoor 和本地主题文件存储。既可一起启动,也可分别部署。当前面向单实例运行。
```text
frontend/
src/
api/ # 请求、响应、下载和错误处理
components/ # 全站与业务共享组件
composables/ # 画廊等可复用交互逻辑
pages/ # 按路由拆分的页面
stores/ # 账户与外观状态
styles/ # 页面专用样式
site.ts # 项目链接、URL 和日期工具
types.ts # API 数据类型
styles.css # 双主题变量与响应式样式
public/assets/ # 原有品牌标识与实机截图
dist/ # 生产构建产物(生成)
backend/
handlers/themes_handler/ # 认证、查询、上传、更新、审核、下载
services/ # 主题打包、文件存储、事务协调、用户缓存
database/ # SQLite 初始化
models/ # 数据模型
```
[官网](https://www.autolibrary.kenanzhu.com) · [用户手册](https://manuals.autolibrary.kenanzhu.com) · [产品发布](https://gitea.kenanzhu.com/KenanZhu/AutoLibrary/releases)
## 本地开发
需要 Go 1.25.6+ 和 Node.js 22.13+(推荐当前 Node LTS,Vite 要求 Node 22.12+,ESLint 要求 22.13+)。从项目根目录运行:
需要 Go 1.25.6+、Node.js 22.13+ 和支持 CGO 的 C 编译器。
```sh
# 首次配置;已有 config.json 时保留原文件
cp config.example.json config.json
npm --prefix frontend ci
go run . backend
```
在另一个终端启动前端:
```sh
# 在另一个终端启动前端
npm --prefix frontend run dev
```
开发地址为 `http://127.0.0.1:5173`。默认代理到 `http://127.0.0.1:8080`;后端端口不同时,在 `frontend/.env.local` 设置 `API_PROXY_TARGET=http://127.0.0.1:实际端口`。无需在前端添加服务器密钥。
打开 `http://127.0.0.1:5173`。后端默认端口为 `8080`,登录功能需要配置 Casdoor。
登录与注册需要配置并启动 Casdoor。未配置时,浏览下载和主题市场仍可用;账户操作会显示服务未启用。管理员审核统一使用 Casdoor 管理员账户。
## 构建与检查
## 构建与发布
```sh
npm --prefix frontend run typecheck
npm --prefix frontend run check
npm --prefix frontend run build
go test ./...
go build -o webserver .
./webserver start
docker build -t autolibrary-web:local .
bash deploy/smoke-container.sh autolibrary-web:local
```
`build` 已包含类型、ESLint 和 Prettier 检查,产物位于 `frontend/dist`。使用 `npm --prefix frontend run format` 统一前端源码格式。没有增加测试用例或测试工具链。Go 检查用于验证已有包可以编译。
推送 `main` 后,Gitea Actions 构建、测试并发布镜像到 `gitea.kenanzhu.com/autolibrary/website:<提交SHA>`。仓库 Secrets 需配置 `REGISTRY_USERNAME` 和具有软件包写入权限的 `REGISTRY_TOKEN`。
生产环境默认访问 `http://127.0.0.1:3000`,实际地址以 `config.json` 为准。`frontend` 和 `backend` 子命令支持独立启动,均可使用 `--config /absolute/path/config.json`。请将工作目录设置为项目部署目录。
使用 `compose.yaml` 部署,设置 `AUTOLIBRARY_IMAGE`、`AUTOLIBRARY_CONFIG`、`AUTOLIBRARY_DATA_DIR` 和 `AUTOLIBRARY_LOG_DIR`,并按宿主机权限设置 `AUTOLIBRARY_UID`、`AUTOLIBRARY_GID`。前端健康检查端口由 `AUTOLIBRARY_HTTP_PORT` 指定,默认 `3003`。
## 发行与下载数据
版本数据库是官网版本信息的唯一来源。首页通过 `GET /api/download/latest` 获取最新已发布的稳定版(按 `releaseDate`、ID 降序;无稳定版时 `data: null`),下载列表保持原有分页接口。`/api` 前缀由 Go 前端或 Vite 代理移除,直接访问后端时使用 `/download/latest` 等路径。
版本模型新增以下字段,启动时由 GORM 增量添加列,不删除原字段或数据:
| JSON 字段 | 用途 |
| --- | --- |
| `giteaZipUrl` | Gitea Windows 便携包 |
| `giteaInstallerUrl` | Gitea Windows 安装程序 |
| `giteaDmgUrl` | Gitea macOS 安装包 |
| `releaseNotesUrl` | 对应版本的发行说明 |
使用已有受 API Key 保护的 `POST/PUT /download/versions` 接口维护这些字段。提供真实的 Gitea 附件地址;不要仅将历史 GitHub URL 替换域名。新页面没有可用附件地址时,提供 Gitea 发行列表入口,云盘下载照常保留。原 `github*Url` 字段继续供已有 API 调用使用,新页面不再展示 GitHub 下载入口。
独立更新日志已移除,`/changelog` 永久跳转 `/downloads`。发行说明在 Gitea 查看;公告接口及其数据库保留。个人下载历史尚未实现,本次没有扩展该功能。
## 发布与维护
网站源码推送到 Gitea 的 `main` 后,由专用 Runner 构建、验证并发布网站镜像到 Gitea。镜像运行、数据挂载和切换步骤见 [容器部署说明](docs/container-deployment.md)。使用原生 systemd 发布时,见 [Gitea 原生部署](docs/gitea-deployment.md)。
完整部署、备份和回滚步骤见 [Ubuntu 部署说明](docs/migration-to-ubuntu.md)。配置和运行时数据与前端构建分开保存;本地现有数据库、主题文件和 Casdoor 配置不需要重建。
迁移前的静态页面、脚本和混淆工具已保存在项目内 `.legacy/`,不参与构建或运行,可用于核对历史内容。
主题上传支持最大 8 MB 的 `.qss` 和最大 4 MB 的 PNG/JPG 预览图,后端总请求体上限 16 MB。主题和打包文件一起保存;文件、元数据或预览更新后重新进入审核队列。退出时先停止接收请求,再关闭数据库。
配置只读挂载,数据库、主题文件和日志持久化在宿主机。上线前备份数据,更新 Compose 使用的镜像摘要后运行 `docker compose up -d --wait`。
-38
View File
@@ -1,38 +0,0 @@
# 网站容器
镜像在独立构建阶段编译 Vue 和启用 CGO 的 Go 程序。最终镜像运行单个 `webserver` 进程,同时提供静态资源和 API。容器配置、SQLite、上传文件和日志由部署机挂载。
## 构建和验证
需要 Linux Docker Engine 和 Buildx。在源码根目录运行:
```sh
docker build -t autolibrary-web:local .
bash deploy/smoke-container.sh autolibrary-web:local
```
冒烟测试使用临时配置和空数据库,在无外部网络的容器里验证首页、后端健康检查、深层路由、静态资源、SQLite API 和 SIGTERM 退出。
Gitea Actions 在 `main` 和 `container-ci` 推送时执行同一套镜像构建和冒烟测试。专用 Runner `hk-vps-runner-02` 使用 `linux-amd64-docker-small` 标签,作业在 Docker CLI 容器中运行。工作流检查构建 daemon 的 rootless 标志。
冒烟测试通过后,工作流使用仓库 Secrets 中的 `REGISTRY_USERNAME` 和 `REGISTRY_TOKEN`,把镜像推送到 `gitea.kenanzhu.com/autolibrary/website:<提交SHA>`,并在日志中输出镜像摘要。令牌需要对 `AutoLibrary` 组织的软件包有写入权限。生产机按该摘要拉取镜像,生产切换单独执行。
## 使用现网配置
生产机运行 Compose v2。复制 `/home/autolibrary/config.json` 到独立文件,将 `frontend.static.path` 设置为 `./frontend/dist`。数据库路径使用 `./backend/data/` 下的现有相对路径。保留前端端口 `3003`、后端端口 `8080` 和 Casdoor 地址 `http://127.0.0.1:8000`。Compose 使用 Linux 宿主机网络,让 Nginx 和 Casdoor 继续通过原有地址连接。
从部署机设置以下环境变量。镜像可以用提交 SHA 标签或不可变的镜像摘要引用:
```dotenv
AUTOLIBRARY_IMAGE=gitea.kenanzhu.com/autolibrary/website@sha256:<镜像摘要>
AUTOLIBRARY_CONFIG=/绝对路径/网站容器配置.json
AUTOLIBRARY_DATA_DIR=/home/autolibrary/backend/data
AUTOLIBRARY_LOG_DIR=/home/autolibrary/logs
AUTOLIBRARY_UID=996
AUTOLIBRARY_GID=987
AUTOLIBRARY_HTTP_PORT=3003
```
配置文件对容器运行身份可读,数据目录及日志目录可写。Compose 会检查挂载源是否存在。
正式切换前,先用独立端口和数据库副本验证容器,并备份数据库和上传文件。切换时停止占用相同端口的 `autolibrary-webserver.service`,运行 `docker compose up -d --wait`,然后验证 Nginx 入口、登录及上传。若首次切换失败,停止网站容器,再启动原网站服务。后续发布可将 `AUTOLIBRARY_IMAGE` 指回上一个镜像,再运行 `docker compose up -d --wait`。程序回退继续使用同一份持久数据。
-16
View File
@@ -1,16 +0,0 @@
# 页面设计与交互约定
保留 AutoLibrary 的书本标识、绿色强调色、图书馆文案与真实软件截图。首页用紧凑功能带、横向标签与通栏截图、编号资源清单形成不同的信息层次,避免每节重复大标题与卡片网格。
参考 [Paco Coursey](https://paco.me/) 的克制排版与目录组织,以及 [Zed](https://zed.dev/) 对真实产品界面的呈现;不引入其品牌元素或外部素材。
- `ThemeToggle.vue` 以太阳/月亮图标切换当前主题,状态由 `stores/theme.ts` 统一维护并持久保存。首次访问仍跟随系统;图标旋转、淡入和缩放遵守减少动态效果偏好。
- 顶部主题与登录按钮统一为 32px 高;键盘焦点保留清晰轮廓。
- 功能与画廊板块标题共用 `home-section-title`:桌面端 22px、手机端 20px,字重、行高和标题下方间距一致。标题旁不添加辅助说明或装饰圆点。
- `ProductGallery.vue` 管理截图与目录内容;`useGallery.ts` 管理自动播放。画廊至少 20% 可见且页面处于前台时,每 6 秒切换;鼠标悬停和控件获得焦点不暂停,手动选择后重新计时。提供播放/暂停、上一张/下一张和左右方向键操作;用户主动暂停后,手动选择不会重新开启播放。系统要求减少动态效果时默认停止自动播放。
- 画廊样式放在 `styles/home.css`,桌面端标签位于通栏截图上方,手机端改为两列。保留当前标签底部的播放进度条,界面不展示切换间隔文案。第一张截图跟随网站深浅主题,其余保留原始实机截图。
- 验证码始终使用明亮背景、接近原生的 150×50 比例,不反色或滤镜处理;输入框有明确标签,点击图片可刷新。
- 首页与下载页的平台标识共用 `PlatformLogo.vue`。`DownloadSource.vue` 使用原生 `details/summary` 展开 Gitea、云盘资源;桌面悬停展开,也支持点击、键盘和 Escape,手机端点击后在页面内展开。同一时刻只展开一个入口,云盘提取码位于资源链接上方。
- 主按钮悬停与键盘焦点使用独立的背景和文字颜色变量,不整体叠加亮度滤镜,以维持深浅主题下的清晰对比。
维护时运行 `npm --prefix frontend run build` 完成类型、代码风格与生产构建检查。另在浏览器检查双主题、手机宽度、自动轮播与验证码显示,无需新增测试用例。
-95
View File
@@ -1,95 +0,0 @@
# 通过 Gitea Actions 部署原生网站服务
本页用于手动触发原生网站发布。推送触发的镜像构建见 [容器部署说明](container-deployment.md)。在 Gitea Actions 手动运行 `Deploy native AutoLibrary service` 时,任务由具备 `autolibrary-native-deploy` 标签的宿主机 Runner 接收。每次发布生成独立目录,原子切换 `current`,重启 systemd 服务并检查首页和 `/api/health`。检查失败时自动切回上一发布,并将本次任务标记为失败。
## 1. 准备 Ubuntu 部署机
安装 Bash、Git、curl、sudo、`build-essential`、`util-linux`、Go 1.25.6 或更新版本、Node.js 22.13 或更新版本。确认 Runner 的服务环境中能找到 `git`、`node`、`npm`、`go` 和 `gcc`,并能访问 Gitea、GitHub 上固定版本的 checkout Action、npm registry 和 Go 模块代理。
网站继续使用现有的 `autolibrary` 账号。首次接入时创建专用部署账号和发布目录。已有部署账号时复用,并确认组和权限与示例相符。
```sh
sudo useradd --system --user-group --create-home --home-dir /var/lib/autolibrary-runner autolibrary-deploy
sudo chmod 0700 /var/lib/autolibrary-runner
sudo install -d -o root -g autolibrary-deploy -m 1775 /opt/autolibrary
sudo install -d -o autolibrary-deploy -g autolibrary-deploy -m 0755 /opt/autolibrary/releases
sudo install -d -o root -g autolibrary -m 0751 /opt/autolibrary/shared
sudo ln -s /home/autolibrary/logs /opt/autolibrary/shared/logs
```
现网的基础 unit 为 `autolibrary-webserver.service`,运行账号为 `autolibrary`,原程序和配置位于 `/home/autolibrary`。按 [Ubuntu 部署说明](migration-to-ubuntu.md) 备份后,将原配置复制到 `/opt/autolibrary/shared/config.json`,设为 `root:autolibrary`、权限 `0640`。调整副本中的路径:
- 将三个 SQLite 数据库和主题文件目录的路径改为现有 `/home/autolibrary/backend/data/` 下的绝对路径,继续使用原数据。运行用户需要对数据库所在目录和主题文件目录有写权限。
- 将 `frontend.static.path` 改为 `./frontend/dist`,让程序从本次发布目录读取资源。沿用前端 `3003`、后端 `8080` 及现有监听地址。
- 保留现有 API Key 和 `backend.casdoor` 配置。网站通过 `http://127.0.0.1:8000` 使用 Casdoor 处理账户和认证。现网的 `autolibrary-casdoor.service` 独立运行,发布任务只重启 `autolibrary-webserver.service`。
首次接入时,以部署账号创建指向原站的链接,作为首次发布失败时的回退目标。已有 `current` 时,确认链接指向可用的上一版并由部署账号拥有。
```sh
sudo -u autolibrary-deploy ln -s /home/autolibrary /opt/autolibrary/current
```
## 2. 安装网站服务和 Runner
在现有网站 unit 上安装 drop-in,只调整工作目录和启动命令。原 unit 继续提供运行账号、重启策略和 `/home/autolibrary/logs/errors.log` 的 stderr 设置。新服务器可先按 [Ubuntu 部署说明](migration-to-ubuntu.md#4-systemd) 安装基础 unit。已有站点执行 `daemon-reload` 后,覆盖配置会在下一次网站服务启动时生效。
```sh
sudo install -d -m 0755 /etc/systemd/system/autolibrary-webserver.service.d
sudo install -m 0644 deploy/systemd/10-gitea-release.conf /etc/systemd/system/autolibrary-webserver.service.d/10-gitea-release.conf
sudo systemctl daemon-reload
sudo visudo -f /etc/sudoers.d/autolibrary-deploy
```
加入以下精确授权,使 Runner 可以操作网站 unit。
```sudoers
autolibrary-deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart autolibrary-webserver.service, /usr/bin/systemctl stop autolibrary-webserver.service
```
在 Gitea 创建一个空的网站源码仓库,启用仓库的 Actions 功能并保护 `main`。使用该网站仓库的 Runner 注册令牌,在部署机安装 [Gitea Runner](https://docs.gitea.com/runner/),然后以部署账号交互注册:
```sh
sudo -u autolibrary-deploy -H sh -c 'cd "$HOME" && gitea-runner register'
```
输入实例地址和仓库级令牌,使用独立的原生发布 Runner 名称,标签只填写 `autolibrary-native-deploy:host`。以同一账号和工作目录运行 `gitea-runner daemon`。可用下面的 systemd unit 持久运行,将 `ExecStart` 与 `PATH` 调整到实际安装位置。
```ini
[Unit]
Description=AutoLibrary Gitea Runner
Wants=network-online.target
After=network-online.target
[Service]
User=autolibrary-deploy
WorkingDirectory=/var/lib/autolibrary-runner
Environment=PATH=/usr/local/go/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/usr/local/bin/gitea-runner daemon
Restart=on-failure
[Install]
WantedBy=multi-user.target
```
例如保存为 `/etc/systemd/system/autolibrary-runner.service` 后,执行 `sudo systemctl daemon-reload` 和 `sudo systemctl enable --now autolibrary-runner.service`。旧版 Runner 的二进制名可能为 `act_runner`,按实际名称替换。确认仓库设置页中 Runner 在线,并且标签与工作流的 `runs-on` 一致。宿主机任务使用部署账号的权限直接运行,只将这个 Runner 分配给受信任的网站仓库。
## 3. 首次推送
在 Gitea 仓库的 Actions Variables 中将 `AUTOLIBRARY_PORT` 设为生产 `frontend.port`;省略时为 `3003`,若沿用通用示例配置则设置为 `3000`。
在本地网站源码目录绑定新建仓库的克隆地址并推送:
```sh
git remote add origin <Gitea 网站源码仓库的克隆地址>
git push -u origin main
```
在 Gitea 的 Actions 页手动运行 `Deploy native AutoLibrary service`,选择 `main`,然后确认部署任务完成。发布脚本在切换前读取远端 `main`,已过时的任务会跳过部署。生产密钥、数据库、上传目录和 Casdoor 实例数据由部署机保存。
## 排查和回滚
- 任务排队时,检查仓库 Actions 设置、Runner 在线状态和标签。
- 重启或健康检查失败时,检查 Actions 日志、`sudo journalctl -u autolibrary-webserver.service -n 100` 和 `/home/autolibrary/logs/errors.log`。检查端口、共享配置、数据路径和权限。
- 网站发布检查覆盖首页和网站后端。排查账户或登录时,分别查看 `systemctl status autolibrary-casdoor.service` 和 `curl -fsS http://127.0.0.1:8000/.well-known/openid-configuration`。
- 发生业务回归时,用 `git revert` 后推送 `main` 重新构建上一份可用代码。紧急切回已有目录时,先确保 Runner 没有在部署,再按 [Ubuntu 部署说明](migration-to-ubuntu.md#回滚) 切换 `current`。清理历史发布目录前确认其未被 `current` 使用,并至少保留一个可用的上一版。
- 自动回滚切换的是程序和静态文件。涉及数据库结构变化时,上线前备份共享数据,并确认旧版本兼容变更后的结构。
-122
View File
@@ -1,122 +0,0 @@
# AutoLibrary Ubuntu 部署与迁移
日常发布可交给 [Gitea 自动部署](gitea-deployment.md)。本页用于首次迁移、数据备份与人工恢复。
## 部署组成
- Go 服务器:`webserver frontend`、`webserver backend`,或 `webserver start` 同时运行。
- 前端构建:Vue 应用的 `frontend/dist`,部署后无需 Node 服务。
- 运行数据:现有的三个 SQLite 数据库、主题文件目录、Casdoor 数据与配置。
- 入口:Nginx 继续反向代理 Go 前端;Go 将 `/api/*` 去掉 `/api` 前缀后代理到后端。
保留当前实际端口和域名。仓库内 Nginx 示例使用前端 3003、后端 8080,通用配置示例使用前端 3000。以部署机 `config.json` 为准。
## 1. 准备新版本
开发或构建机器需要 Go 1.25.6+ 和 Node.js 22.13+。推荐使用 Node 当前 LTS。
```sh
npm --prefix frontend ci
npm --prefix frontend run build
go test ./...
go build -o webserver .
```
SQLite 驱动使用 CGO;建议在 Ubuntu 上安装 `build-essential` 并在目标平台构建 Go 可执行文件,不要把 Windows 可执行文件直接部署到 Linux。
为每次发布准备单独目录,例如 `/opt/autolibrary/releases/20261016`。目录应包含:
```text
webserver
frontend/dist/
backend/templates/
config.json # 部署机自己的配置,不用示例覆盖
```
保留 `frontend/dist` 中的完整资源目录,包括字体、截图与品牌图标。
## 2. 备份运行数据
停止旧 AutoLibrary 服务,保证 SQLite 备份与主题文件一致,再备份:
- 原部署程序和前端资源。
- `config.json`。
- `versions.db`、`bulletins.db`、`themes.db`,以及存在的 `-wal`、`-shm` 文件。
- 整个 `themes_files` 目录。
- Casdoor 数据库、证书和配置。
本次不重置数据库或 Casdoor。使用部署机既有账户;不要重新导入初始化数据覆盖账户。
## 3. 配置路径
推荐将持久数据放在 `/opt/autolibrary/shared/`,在 `config.json` 中使用绝对路径。例如:
```json
{
"backend": {
"host": "127.0.0.1",
"port": "8080",
"database": {
"versions": { "path": "/opt/autolibrary/shared/versions.db" },
"bulletins": { "path": "/opt/autolibrary/shared/bulletins.db" },
"themes": { "path": "/opt/autolibrary/shared/themes.db" },
"themes_files": { "path": "/opt/autolibrary/shared/themes_files" }
}
},
"frontend": {
"host": "127.0.0.1",
"port": "3003",
"static": { "path": "./frontend/dist" }
}
}
```
以上仅展示需调整的字段;合并至实际完整配置,保留原 API Key、Casdoor client ID、secret 和证书。完整无密钥模板见根目录 `config.example.json`。
旧配置若仍指向 `frontend/public`,服务器在其同级找到 `dist/index.html` 时会使用新构建;仍建议显式改为 `frontend/dist`。
启动会为版本表添加 `gitea_*_url` 和 `release_notes_url` 列,不删除旧字段。历史 GitHub 下载地址不会被盲目改写。通过原版本管理 API 填入真实 Gitea 下载地址;未填写时,新官网引导访问 Gitea 发行页,云盘仍按原数据提供。
## 4. systemd
将 `/opt/autolibrary/current` 指向当前发布目录,并配置:
```ini
[Unit]
Description=AutoLibrary Website
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/autolibrary/current
ExecStart=/opt/autolibrary/current/webserver start --config /opt/autolibrary/shared/config.json
Restart=on-failure
RestartSec=5
TimeoutStopSec=20
[Install]
WantedBy=multi-user.target
```
Go 服务收到 SIGTERM 后先等待请求结束,再关闭数据库。Casdoor 继续使用原独立服务运行;若配置了服务依赖,沿用现有的 Casdoor unit 名称。
Nginx 通常无需更改。检查 `proxy_pass` 指向的端口与当前配置一致。`/changelog` 的永久跳转和页面路由由 Go 处理;不要增加将所有未知资源重写到首页的规则。
## 5. 上线验证
```sh
curl -I http://127.0.0.1:3003/
curl -I http://127.0.0.1:3003/marketplace/profile
curl -I http://127.0.0.1:3003/changelog
curl -i http://127.0.0.1:3003/not-a-real-page
curl http://127.0.0.1:3003/api/download/latest
curl http://127.0.0.1:8080/health
```
应分别得到页面成功、深层页面成功、301 跳转 `/downloads`、404、真实稳定版或空数据、健康状态。检查浏览器中的深浅主题、下载入口、市场筛选、登录、主题上传与管理员审核。
网站不再实时请求 GitHub 或 Gitea API 获取版本。发行说明与源码入口统一使用 Gitea;公告服务仍保留。
## 回滚
如需回滚,停止新服务,将 `current` 指回旧发布目录并恢复原配置,再启动旧程序。新增版本列属于增量改动,旧程序可忽略;若要恢复上线前的数据状态,应在停服后恢复同一批备份的数据库和主题文件。不要只回滚其中一部分。
+3 -3
View File
@@ -50,12 +50,12 @@ async function copyPassword(password: string) {
@keydown.esc.stop.prevent="close"
>
<summary
class="button full-width download-source-trigger"
:class="{ primary: source === 'gitea' }"
class="button download-source-trigger"
:class="{ primary: source === 'cloud', 'full-width': source === 'cloud' }"
>
<Code2 v-if="source === 'gitea'" :size="18" />
<CloudDownload v-else :size="18" />
{{ source === 'gitea' ? 'Gitea 下载' : '云盘下载' }}
{{ source === 'gitea' ? 'Gitea 发布' : '云盘下载' }}
<ChevronDown class="download-source-chevron" :size="16" />
</summary>
<div class="download-source-menu">
+9 -11
View File
@@ -17,9 +17,13 @@ const meta = ref<PageMeta>({ page: 1, per_page: 9, total: 0, total_pages: 0, has
const loading = ref(true),
error = ref(''),
notice = ref('')
const platform = ref<'windows' | 'macos'>(
const preferredPlatform = ref<'windows' | 'macos'>(
/Mac|iPhone|iPad/i.test(navigator.userAgent) ? 'macos' : 'windows',
)
const hasMacOS = computed(() =>
Boolean(safeUrl(selected.value?.giteaDmgUrl) || safeUrl(selected.value?.cloudDmgUrl)),
)
const platform = computed(() => (hasMacOS.value ? preferredPlatform.value : 'windows'))
const cache = new Map<number, { downloads: Version[]; meta: PageMeta }>()
let generation = 0
const downloadSources = computed(() => {
@@ -130,7 +134,7 @@ onMounted(() => load(1, true))
<button
:class="{ active: platform === 'windows' }"
:aria-pressed="platform === 'windows'"
@click="platform = 'windows'"
@click="preferredPlatform = 'windows'"
>
<PlatformLogo platform="windows" decorative />
Windows
@@ -138,7 +142,8 @@ onMounted(() => load(1, true))
<button
:class="{ active: platform === 'macos' }"
:aria-pressed="platform === 'macos'"
@click="platform = 'macos'"
:disabled="!hasMacOS"
@click="preferredPlatform = 'macos'"
>
<PlatformLogo platform="macos" decorative />
macOS
@@ -167,14 +172,7 @@ onMounted(() => load(1, true))
<div class="download-facts">
<span>{{ formatDate(selected.releaseDate) }}</span>
<span v-if="selected.fileSize">{{ selected.fileSize }}</span>
<span v-if="platform === 'windows' && selected.supportOS">{{ selected.supportOS }}</span>
<span
v-else-if="
platform === 'macos' && (downloadSources.gitea.length || downloadSources.cloud.length)
"
>
macOS
</span>
<span v-if="selected.supportOS">{{ selected.supportOS }}</span>
</div>
<div class="download-links">
<DownloadSource
+1 -1
View File
@@ -680,7 +680,7 @@ svg {
}
.download-links {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-columns: max-content minmax(0, 1fr);
gap: 12px;
margin-block: 22px;
}