v0.5.84: matches origin filter, mobile gate, refresh reliability.

Ship Web refresh cache/lock, mobile demand gate, matches 职业/国服 filter, and related site updates through 0.5.84.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
voson
2026-07-29 18:31:55 +08:00
co-authored by Cursor
parent 7681fdb069
commit b01552ee6e
50 changed files with 3406 additions and 487 deletions
+14 -6
View File
@@ -41,7 +41,8 @@ python web/fetch_stratz_meta.py # STRATZ 周胜率/分路/对位 Top → web
python web/fetch_hero_matches.py # 同英雄近期比赛出装/加点(含购买时间)→ web/data/hero_matches.json
# 既有行补时间:python web/fetch_hero_matches.py --enrich-item-times [--heroes juggernaut]
python web/fetch_pro_matches.py # 明星选手近期联赛/锦标赛 → web/data/pro_matches.json(默认 watchlist
# 指定选手python web/fetch_pro_matches.py --players Ame,Yatoro --limit 12
# 含天梯python web/fetch_pro_matches.py --include-pubs --limit 8
# 指定选手(会整文件覆盖):python web/fetch_pro_matches.py --players Ame,Yatoro --limit 12
python web/fetch_item_shop.py # 官网商店 11 列目录 → web/data/item_shop.json
python web/fetch_items_meta.py # 装备描述 + 机制标签 → web/data/items_meta.json
python web/fetch_hero_abilities.py # 英雄技能 / 驱散汇总 → web/data/hero_abilities.json
@@ -55,7 +56,7 @@ python web/fetch_streamer_live.py # 探测真实在播状态 → is_live/live_p
python web/serve_relations.py # 本地开发服务 http://127.0.0.1:8765(改 JSON 后刷新)
```
Web 站点带 **Hash 路由**`#/heroes/axe/core``#/heroes/axe/trends``#/heroes/axe/matchups``#/heroes/axe/matches``#/trends/legend``#/rankings``#/matches`(明星比赛,可 `#/matches/898754153`)、`#/items/black_king_bar``#/patches/7.41``#/patches` = 最新,`#/rankings` = 中国区);英雄页的定位标签筛选与搜索框也进 URL(`?tags=核心&q=axe`)。刷新保状态、可分享 / 深度链接、浏览器前进后退还原。`python web/export_relations_site.py` 导出的静态站点同样支持深度链接(可部署 GitHub Pages 或 Cloudflare Pages)。
Web 站点带 **Hash 路由**`#/heroes/axe/core``#/heroes/axe/trends``#/heroes/axe/matchups``#/heroes/axe/matches``#/trends/legend``#/rankings``#/matches`(明星比赛,可 `#/matches/898754153``#/matches?origin=china``#/matches?page=2`)、`#/items/black_king_bar``#/patches/7.41``#/patches` = 最新,`#/rankings` = 中国区);英雄页的定位标签筛选与搜索框也进 URL(`?tags=核心&q=axe`)。刷新保状态、可分享 / 深度链接、浏览器前进后退还原。`python web/export_relations_site.py` 导出的静态站点同样支持深度链接(可部署 GitHub Pages 或 Cloudflare Pages)。
### 部署到 Cloudflare Pages
@@ -72,7 +73,7 @@ python web/_cf_status.py # 部署后只读核对(项目 / 部署 / 域名
### 定时刷新(Gitea Actions
仓库 [`.gitea/workflows/`](.gitea/workflows/) 在 **self-hosted** runner(与 `site-traffic-notify` 同一 Mac mini)上分层拉数;`web/refresh_web.py` 对 JSON/图标摘要,**有变更才** `_oss_static_assets.py upload` + `deploy_relations.py`。数据-only 刷新**不** bump `SITE_VERSION``data.json` / `index.html` 已不缓存)。
仓库 [`.gitea/workflows/`](.gitea/workflows/) 在 **self-hosted** runner(与 `site-traffic-notify` 同一 Mac mini)上分层拉数;`web/refresh_web.py` 对 JSON 做忽略纯时间戳的业务摘要,**有业务变更才** `_oss_static_assets.py upload` + `deploy_relations.py``web/refresh_cache.py` 在发布锁内通过 runner 持久目录恢复/保存全部定时数据与补丁状态,Actions cache 另作冷启动备份;daily/weekly 串行,patch 与全量刷新冲突时延后到下一轮。数据-only 刷新**不** bump `SITE_VERSION``data.json` / `index.html` 已不缓存)。
| Workflow | 时间(CST | 档位 | 拉取内容 |
|----------|-------------|------|----------|
@@ -82,6 +83,13 @@ python web/_cf_status.py # 部署后只读核对(项目 / 部署 / 域名
**版本检测:** `--check` 只请求 Valve 版本列表,与本地 `web/data/patches.json``details` 比对,stdout 一行 JSON`has_new` / `new_versions` / `latest`)。无新版本则跳过详情与部署。
**可靠性与验收:** 每次刷新都会把 `REFRESH_SUMMARY` 写入
`web/.refresh/summary.json` 并上传为 Actions artifact,记录步骤、耗时、变更、
部署和 stale 状态。飞书日报同时校验 Actions 摘要、生产 `data.json` 新鲜度及
`/api/live-status`;部署后会验证本次 `refresh_run_id`、英雄数据和 Pages
Function。STRATZ / OpenDota 异常空响应不会覆盖上一份有效缓存,OSS 资产未同步时
也不会继续发布 Pages。
**本机试跑:**
```powershell
@@ -103,14 +111,14 @@ python web/refresh_web.py --tier patch --skip-deploy --skip-oss
| `STRATZ_API_TOKEN` | `web-weekly`(及 daily 内若触发连带时不需要) |
| `OSS_ACCESS_KEY_ID` / `OSS_ACCESS_KEY_SECRET` | 图标变更时上传 OSS |
手工数据(`shared/data/relations.json`、overrides)与技能视频(GB 级)**不**进定时;新英雄仍需本机 `pc/fetch_cdn_templates.py` + `web/fetch_hero_portraits.py`。冒烟:Gitea Actions `web-patch`**Run workflow**
手工数据(`shared/data/relations.json`、overrides)与技能视频(GB 级)**不**进定时;新英雄仍需本机 `pc/fetch_cdn_templates.py` + `web/fetch_hero_portraits.py`。冒烟:先对 `web-daily`、再`web-patch`**Run workflow**;第二次无业务变化时应显示 `deployed=false`,且生产探针无超时项
仿局内选将四列网格(图标来自 [dota2.com/heroes](https://www.dota2.com/heroes) 竖版裁切):点英雄高亮克制 / 被克制 / 搭档,下方显示定位,并以标签页切换 **技能**(可点选魔晶/神杖升级与天赋树)、**核心装备**、**被克装备**、**走势**(STRATZ 优先:勋章条 + 最近 1 周三卡 + 分路 + 近 8 周列表;OpenDota 兜底)、**对位**STRATZ 克制/被克/搭档 Top)、**近期比赛**(终局出装/加点)、**主播**(常玩该英雄的收录主播)、**版本变更**(该英雄近一年各版本改动)。
英雄页上方网格固定高度;点选技能 / 核心装备 / 被克装备后,详情显示在下方(装备含合成,非弹窗)。
顶部另有 **排行** 页:Valve Immortal 四区榜各 Top 100(中国 / 欧洲 / 美洲 / 东南亚);数据来自 `web/data/leaderboards.json``python web/fetch_leaderboards.py`)。
顶部另有 **主播** 页:手工收录直播间/主页(抖音 + B 站)抖音式卡片展示昵称、签名、关注/粉丝/获赞、常用英雄可选精选高光视频(视口分档:远处不拉、近处 metadata、滚入中部 `canplay` 静音自动播放,同时仅 1 路全量缓冲;同名 JPG 封面作占位;有 `live_url` 时点头像进直播间;「直播」角标与动效只在真实探测在播时显示——线上由访客触发的 `/api/live-status` 边缘函数刷新,缓存 5 分钟合并请求;`data.json``fetch_streamer_live.py` daily 探测值兜底);数据来自 `web/data/streamers.json``python web/fetch_streamers.py` 补全;亦由 `web/refresh_web --tier daily` 每日软失败刷新)。视频与封面放 `web/assets/streamer_videos/`gitignore),本地经 `/streamer-video/` 提供,部署前用 `web/_oss_static_assets.py upload` 同步至 OSS `streamer-video/`
顶部另有 **比赛** 页(`#/matches[/account_id]`):明星选手 watchlist 近期联赛/锦标赛对局(出装/加点);名单见 `web/data/pro_player_watchlist.json`,数据由 `python web/fetch_pro_matches.py` 拉取(亦进 daily)。
顶部另有 **主播** 页:手工收录直播间/主页(抖音 + B 站)抖音式卡片布局为头像行(头像 \| 昵称 + 抖音号/获赞/粉丝或 B 站 UID/关注/粉丝 \|「关注」)+ 签名独立全宽行(最长 3 行)+ 常用英雄 + 可选精选高光视频(视口分档:远处不拉、近处 metadata、滚入中部 `canplay` 静音自动播放,同时仅 1 路全量缓冲;同名 JPG 封面作占位;有 `live_url` 时点头像进直播间;在播时粉环 +「直播」角标叠在环底、无间距——线上由访客触发的 `/api/live-status` 边缘函数刷新,缓存 5 分钟合并请求;`data.json``fetch_streamer_live.py` daily 探测值兜底);数据来自 `web/data/streamers.json``python web/fetch_streamers.py` 补全;亦由 `web/refresh_web --tier daily` 每日软失败刷新)。视频与封面放 `web/assets/streamer_videos/`gitignore),本地经 `/streamer-video/` 提供,部署前用 `web/_oss_static_assets.py upload` 同步至 OSS `streamer-video/`
顶部另有 **比赛** 页(`#/matches[/account_id][?origin=pro|china][&page=N]`,默认全部类型、每页 20 场):侧栏可筛职业/国服与选手;明星选手 watchlist 近期联赛/锦标赛与天梯对局(出装/加点;卡片标职业/天梯/国服);名单见 `web/data/pro_player_watchlist.json`,数据由 `python web/fetch_pro_matches.py --include-pubs` 拉取(亦进 daily)。
顶部另有 **走势** 页:近 8 周各段位高胜率 / 上场率榜(`#/trends[/bracket]`STRATZ 周胜率数据)。
顶部另有 **物品** 页:对齐 [官网商店物品](https://www.dota2.com.cn/items/index.htm) 的 **11 列竖排**(基础分类 5 列 + 合成分类 6 列),点选后详情显示在右侧(含合成组件)。目录来自 `web/data/item_shop.json``python web/fetch_item_shop.py`)。
顶部另有 **版本** 页:默认展示最新版本完整改动(综合 / 物品 / 中立物品 / 英雄),下拉切换近一年其它版本;数据来自 `web/data/patches.json``python web/fetch_patches.py`,近一年窗口可用 `--days` / `--since` 调)。