ltx 84b7b0f893 feat(website): add competition results and service deployment
- Add the event results page with schedule, rankings, Battle bracket, athletes, records, bilingual labels, and navigation entry.
- Add the read/write competition data service, a complete Excel example, empty public state, and validation smoke tests.
- Handle Furion statusCode/data responses from the production API and retain static fallback for the public page.
- Document Docker sidecar deployment beside test_eventapi, persistent storage, private admin access, Nginx routing, and OSS asset rewriting.

Verification:
- node server/competition-api.smoke.mjs
- node scripts/competition-response-test.mjs
- node scripts/battle-layout-test.mjs
- npm run build -- --base=https://assets.example.test/static/test/
- npm run rewrite:oss -- https://assets.example.test/static/test/
- Production /api/competition/state returned HTTP 200 after the sidecar started.

Deployment note: publish the updated YD-WEB static build before public results can consume the unwrapped API response. The event remains unpublished until an administrator saves and publishes data.
2026-10-20 13:38:23 +08:00

37 lines
1.9 KiB
Markdown

# 在现有后台服务器启动赛事数据服务
适用于 `test_eventapi` 已在 Docker 中运行,而同机尚无赛事数据服务的部署。服务容器共享后台容器的网络命名空间,只监听 `127.0.0.1:8787`。后台现有的默认上游地址因此可直接使用;不需要发布 8787 端口,也不需要改动后台的登录验证。
## 部署
将本目录的 `Dockerfile`、`start-on-event-host.sh`,以及仓库中的 `server/competition-api.mjs`、`public/competition-state.json` 按以下结构上传到服务器的同一个目录:
```text
Dockerfile
start-on-event-host.sh
server/competition-api.mjs
public/competition-state.json
```
在该目录执行:
```sh
sh start-on-event-host.sh
docker exec test_eventapi curl -i --max-time 5 http://127.0.0.1:8787/api/competition/ping
curl -i https://jitsi-web.yuedongsports.com/api/competition/state
```
如果使用交付压缩包,可先通过 MobaXterm 的 SFTP 面板上传 `competition-api-deploy-2026-10-20.tar.gz` 到服务器,然后执行:
```sh
tar -xzf competition-api-deploy-2026-10-20.tar.gz
cd competition-api-deploy-2026-10-20
sh start-on-event-host.sh
```
脚本执行后再运行上方的两条接口验证命令。
脚本会构建单独的 Node 镜像,创建持久化 Docker 卷 `yd-competition-data`,并启动容器 `yd-competition-api`。它不会替换或重启现有后台容器。如果同名服务容器已经存在,脚本会停止并提示人工检查,不会覆盖已有数据。管理页仍需后台登录才能访问;公网不得发布 `/api/competition/admin`。
若后台容器名称不同,在运行脚本前设置 `BACKEND_CONTAINER`。若后续由 Jenkins **重建**后台容器,赛事服务需要随新的后台容器重新建立网络共享;将两者纳入同一部署流程。升级赛事服务前备份 `yd-competition-data` 卷中的 `competition-state.json`。