24 个区
一根尺子
每个区都是一颗星,半径代表这个区采到了多少条价格。 悬停任意一颗,看它用什么货币、汇率多少、连回国区的那条线意味着什么。
正在加载区域覆盖数据
三个榜单
One Scroll
向下滚动,下一个世界从下方覆盖上一个 —— 如同连续穿过三道传送门。 三个场景的运动方向分别是 ↓ / · / ↑:折扣在跌、新作刚亮、热度在涨。
八张卡
四个口径
首页只摆八张。口径由你选 —— 折扣最狠的、折后价最低的、在线最多的、 最新上架的。四个口径各查一次库,每次排出来的都是真实名次, 不是从同一批里挑挑拣拣。
正在加载折扣数据
全量一万九千条在 /deals, 支持分页与同样的四种排序。这里的八张只是入口。
库里正在
发生什么
每一行都来自最近一次采集的真实记录 —— 谁在打折、谁在涨、谁刚上架。 没有一行是编的,所以这一栏不会有"2 分钟前"这种假装实时的东西。
采集快照
Live Data还没有采集记录。
视觉可以大胆
底层必须老实
这一页是场景,但支撑它的东西全是硬约束 —— 一台 2 核 1.6G、3Mbps 的机器, 和每天 19:00 到 23:00 必须开着的采集机。
串行采集 · 严格限速 3.0 秒/次
不并发、不上 Scrapy、不上 Selenium。抓得慢是可接受的, 被封 IP 才是灾难 —— 一次封禁意味着整条数据链断掉, 而重建它比重建代码难得多。
多区折合美元同尺比较
24 个区,币种各不相同。先把价格按汇率折成美元,再画到同一根尺子上 —— 否则"₺300"和"¥198"谁便宜,根本没法看。
前端纯静态导出
Next.js 静态导出,服务器只出 JSON 和 HTML,图片一律直连 Steam CDN。 3Mbps 的带宽经不起任何一张被代理的图。
数据新鲜度优先
采集是外部依赖,一定会断。断了要在页面上说出来, 而不是让用户对着一周前的价格做决定 —— 上面那条新鲜度提示就是干这个的。
SQLite + 进程内缓存
2 核 1.6G 的机器上不加 Redis、不加 Postgres。 缓存是进程内字典,数据库是单个文件,备份就是一次 scp。
差多少倍
是算出来的
下面每一行都是库里现成的数据:同一款游戏,最便宜的区和最贵的区, 折合美元后相差几倍。锁区、没采集过的区、汇率缺失的区都不参与计算 —— 把它们当 0 会算出一个假的倍数,那比没有结论更糟。
正在计算价差
点任意一行进多区对比,看这款游戏在所有区的完整条形图与热力矩阵。