feat(douyu): 高价值套装改用官方 storehome 三态判定

高价值套装的准入判定改为只认官方精英宝典 storehome 里账号级的
status:0=可兑换、1=已达兑换上限,商品缺失/接口异常=unknown。
兑换记录和积分记录只作历史展示,不参与是否拥有的判定。

原来的 high_value_owned(JSON 名单)无法区分「确认可兑换」和
「官方接口没返回商品」,也无法表达部分失败。改为两套独立状态 +
检查时间(迁移 20261106_0065),旧快照保守回填:status 缺失的
一律 unknown,不猜。

CK 判定失效时在数据层作废结论(降为 unknown),不是展示层降级。
官方 status 是账号维度的,但 CK 失效那段时间账号可能被别人手工
登录并兑换(这些号共享给客服),缓存里的「可兑换」就不成立了;
只在展示层降级的话,CK 恢复后那条陈旧的「可换」会重新变绿。
error(查不到)不作废 —— 查不到不等于账号出问题了。

高价值结论有自己的时钟:资料刷新除了看 overview_queried_at,还看
high_value_checked_at。两者会脱钩(商品接口单独失败时资料时间被刷新、
高价值时间停在原地),少了这一条这类账号会永久停在旧结论。作废的
结论按 6 小时慢速重试,但「从来没查到过」不因此重选 —— 那是接口对
该账号稳定失败,每轮都重选只会反复撞墙。

商城商品列表改用精英宝典的 manualID 拉取,不再寄生在电竞手册分支里
(否则没配电竞手册的配置就永远拉不到商城,三态全部停在待确认)。

筛选拆成三类「查不到」:unqueried(未查资料,旧口径不变)、
high_value_never(从未读到商城)、high_value_unknown(查过但结论
未知/过期)。之前第二类无处可寻 —— 它既不满足 unqueried 也不满足
high_value_unknown。
This commit is contained in:
yml2213
2026-11-06 12:25:08 +08:00
parent e7e187cf57
commit 4c1aff47da
23 changed files with 1658 additions and 317 deletions
+54 -2
View File
@@ -86,12 +86,54 @@ CK 本体和健康结果都在账号上:
- `points`、`gold_balance`、`exchange_balance`
- `elite_opened`、`esports_opened`、各作用域绑定状态
- `overview_snapshot`、`overview_queried_at`
- `high_value_owned`
- `high_value_bairimeng_status`、`high_value_mengtu_status`、`high_value_checked_at`
列表只返回 `high_value_owned` 等小字段,不返回整份快照,避免响应体积膨胀。
列表只返回紧凑的三态 `high_value`(`state` + 每套的 `owned`/`available`/`unknown`),
不返回整份快照,避免响应体积膨胀。
一键查询本身是只读聚合,不直接修改生命周期状态;官方兑换记录会以
`source=official_sync` 幂等补入事件流。
## 高价值套装的准入判定
**唯一裁判是官方精英宝典 `storehome` 商品列表里账号级的 `status`**:
- `status=0` → 该账号当前可兑换(`available`);
- `status=1` → 该账号已达兑换上限(`owned`);
- 商品缺失、列表为空、接口异常、部分失败 → `unknown`。
兑换记录和积分记录会被官方清理或暂时查不到,**只作历史展示**,不参与是否拥有的判定。
`unknown` 与超过 7 天的结果(`stale`)在列表、筛选和统计里都显示为「待确认」,
绝不显示成「两个都可兑换」。
本系统兑换成功后立即回查一次 `storehome`;回查失败则以「本次兑换已成功」保守收口
为 `owned`,并记 warning,不带崩已成功的兑换。
商城商品列表用**精英宝典**的 `manualID` 拉取,与电竞手册配置无关 ——
两套活动互不相干,商品列表绝不能寄生在电竞分支里(否则没配电竞手册的
配置就永远拉不到商城,高价值三态全部停在「待确认」)。
**CK 失效会作废高价值结论**:官方 `storehome.status` 是账号维度的,正常只随
这个账号自己的兑换而变;但 CK 失效那段时间账号**可能被别人手工登录并兑换**
(这些号共享给客服),缓存里的「可兑换」就不成立了。作废是**单向**的 ——
两套都降为 `unknown`,等下一次真的读到官方 `storehome` 才写回。
作废发生在**数据层**(CK 检测结论落定处),不是展示层:CK 恢复之后展示层
就不再降级了,只在展示层降级会让陈旧的「可换」重新变绿。
`error`(查不到)不作废 —— 查不到不等于账号出问题了。
### 高价值的三类「查不到」必须分开
这三种都**不是**「可兑换」,但成因不同,排查方式也不同,筛选时不能混成一档:
| 筛选 | 判据 | 含义 |
| --- | --- | --- |
| `unqueried` | `overview_queried_at IS NULL` | 从没跑过一键查询(**旧口径**,保留不变) |
| `high_value_never` | `high_value_checked_at IS NULL` | 从没成功读到官方商城(商城接口失败 / 没配 `manualID`) |
| `high_value_unknown` | `checked_at` 非空,但已过期或状态是 `unknown` | 查过,但当前结论不可信 |
`high_value_never` 必须单独成档:账号可能查过其它资料、只是商城接口对它
稳定失败。它既不满足 `unqueried`(资料查过),也不满足 `high_value_unknown`
(那条要求 `checked_at` 非空)—— 不单独筛的话,这批账号在界面上**无处可寻**。
## 自动化策略
- CK 巡检按账号选行,不按登录历史选行。
@@ -99,6 +141,16 @@ CK 本体和健康结果都在账号上:
- 非鉴权失败计入 `error`,失败率过高时自动暂停作业。
- 资料刷新只处理 `ck_check_status=valid`、允许自动管理且非人工态的账号。
- “从未查询过”的账号优先于“查询结果已过期”的账号。
- **高价值结论有自己的时钟**:资料刷新除了看 `overview_queried_at`,
还看 `high_value_checked_at`。两者会脱钩 —— 一键查询里商品接口单独失败时
资料时间被刷新、高价值时间停在原地,CK 失效那段时间也一样。少了这一条,
这类账号的高价值状态会**永久**停在旧结论。
用的是**同一把尺子**(界面上那个「同一账号多久重检」),不另设窗口。
「从来没查到过高价值结论」不因此重选:那是商品接口对这个账号稳定失败,
每轮都重选只会让同一批账号反复撞墙,挤掉真正有新欠账的账号。
- 结论被**作废**(`unknown`)的账号按 6 小时慢速重试:CK 恢复后必须尽快
重新确认(失效期间可能已被别人兑换),但也不能更密 ——
商品接口对某些账号稳定失败,那类账号会一直是 `unknown`。
## 代码入口