yml2213
|
c778ae9a09
|
feat: 账号管理支持按账号名批量选号打标签,并支持复制账号名
|
2026-10-20 17:31:39 +08:00 |
|
yml2213
|
c299f63537
|
fix: 充值核账按绑定账号和角色整组
|
2026-10-19 17:22:51 +08:00 |
|
yml2213
|
3a6649a054
|
feat: 重做协作台账状态机并支持充值核账
|
2026-10-19 16:06:02 +08:00 |
|
yml2213
|
781b27e63a
|
feat: 协作台账支持归档并精简状态列
|
2026-10-19 13:04:27 +08:00 |
|
yml2213
|
375567cbd2
|
feat: 拆分协作台账充值/脚本统计并支持暂停实时同步
|
2026-10-19 12:27:05 +08:00 |
|
yml2213
|
52043adbc1
|
fix: 协作单礼包名分行显示,保留类目前缀
|
2026-10-18 11:24:28 +08:00 |
|
yml2213
|
26066858b6
|
docs: 记一个部署坑 —— 重建镜像后 up -d 不一定换容器
2026-10-18 部署礼包修复时实际踩到:`docker compose build` 出了新镜像
(ID 变了),`docker compose up -d douyu-login` 只打了句 Started,
容器仍是上一版(ps 显示 Up 11 hours,容器里搜不到新函数),差点把
「没生效」报成「部署成功」。
- AGENTS 坑 #10:重建过镜像就 `up -d --force-recreate <服务名>`
(必须带服务名,不带会把 mysql 一起重建),部署后核对镜像 ID 或 grep 容器内新代码。
- 部署清单同步改命令(顺带给 `docker compose run` 补上 -T 与 </dev/null,
同 AGENTS 坑 #5)。
|
2026-10-18 11:02:09 +08:00 |
|
yml2213
|
21f7ee3f3f
|
feat(huya): 礼包名默认空白,改用「常用礼包」备选按钮
新建协作单以前会把「上次选的礼包」自动填进礼包名(localStorage
huya.collab.lastGift)。连开几单同一个礼包是省事,但每开一单都顶着上一次的
选择,稍不留神就按错礼包建单;而且这个自动值会被草稿自动保存吃进去,
下次打开又「恢复」出来。
- 新建弹窗**不再预填礼包名**:删掉 lastGift 的读写,字段默认空白。
- 草稿恢复只带订单号 / 店铺 / CK / 截图 / 备注,礼包名留空;
hasDraftContent() 也不再认「只有礼包名」的草稿(否则被旧逻辑自动填过的
那份草稿会一直弹「已恢复上次未提交的草稿」)。
- 新增 GET /external-orders/gifts/frequent:按台账里的使用次数排序
(次数相同看最近一次使用),新建与补资料弹窗在字段上方渲染最多 6 个按钮,
只显示**当前礼包缓存里还有的**(活动换 SID 后老礼包会整批下架)。
- 新增 5 例测试,并做了 3 次反向验证(去掉次数排序 / 改成升序 / 去掉空名过滤)。
补资料弹窗的初值仍是「这一单自己的礼包」,详情抽屉编辑也不动 —— 那不是
「上次选的」。
|
2026-10-18 10:53:04 +08:00 |
|
yml2213
|
c441b6c663
|
feat(huya): 批量查询拆成「查积分」与「查兑换记录」两个按钮
前端工具栏原来一个按钮同时查两件事,拆开后每次只查一半,所以重点在
「没查的那一半不能被当成没查到」:
- 接口加 scope(both / score / records),默认 both 保持原行为;
只查积分时不产生判定(空串「未判定」,与 unknown「无法判定」分开),
也**不会**自动改业务状态(连判定都没有,凭什么改)。
- 列表的积分与判定各取「最近一条查到过它的」快照:点「查积分」不再把
整页判定徽标冲成未判定,点「查兑换记录」也不再清空积分;但新的
unknown 仍会盖掉旧的 success(抖动结果不许藏)。
- 结果弹窗 / 积分列 Tooltip / 生命周期时间线都按 scope 显示,
不再把「本次没查」显示成「积分 -」「兑换记录 0 条」。
- 新增 12 例测试(TestCollabActivityScopeSplit),并做了 4 次反向验证
(去掉判定分支 / 判定跟随最新 / 积分跟随最新 / 删掉响应字段),全部确认变红。
顺带修掉文档漂移:AGENTS.md 的迁移 head 早就过期(main 实际
20261016_0059、dev 20261008_0053),并补上「两侧已分叉成两个 head、
合并 dev 前必须先 alembic merge」这条;设计文档补 §11.9。
|
2026-10-17 23:32:51 +08:00 |
|
yml2213
|
b47dde47e9
|
build: 缓存 npm/pip/uv/apt 依赖
|
2026-10-17 21:08:52 +08:00 |
|
yml2213
|
f06869c4b1
|
feat(huya): 协作台账补资料与管理员复制 CK
|
2026-10-17 20:47:31 +08:00 |
|
yml2213
|
8fac4a1d04
|
fix(huya): 一键查询统一最新 CK 探针与 HTTP 快速通道
|
2026-10-17 16:45:32 +08:00 |
|
yml2213
|
ef6663beae
|
fix(huya): 查询积分先验 CK 并改用 HTTP 快速通道
|
2026-10-17 16:22:54 +08:00 |
|
yml2213
|
2620023db4
|
fix(huya): 查询角色复用协作台账 CK 探针并标记失效
|
2026-10-17 16:18:28 +08:00 |
|
yml2213
|
fe1f959648
|
fix(huya): 协作台账固定序号并支持表头排序
|
2026-10-17 16:05:11 +08:00 |
|
yml2213
|
fcc2fbdc09
|
feat(huya): 协作台账支持待补资料一键建单与表单暂存
|
2026-10-17 14:21:36 +08:00 |
|
yml2213
|
cad06ae789
|
feat(huya): 协作台账增加 WebSocket 实时同步
- 后端新增进程内事件总线与 /api/huya/external-orders/ws\n- 所有写接口成功后发布轻量失效事件\n- 前端自动重连、静默刷新、断线兜底轮询
|
2026-10-17 13:44:27 +08:00 |
|
yml2213
|
26b8d6b054
|
feat(huya): 协作台账支持皮肤筛选与主页截图拖拽/粘贴上传
- 外部单列表新增礼包/皮肤精确筛选,并提供去重下拉选项
- 主页截图支持拖拽、多选及 Ctrl/Cmd+V 剪贴板粘贴上传
|
2026-10-17 12:49:42 +08:00 |
|
yml2213
|
1dd5c4a279
|
feat(huya): 精英宝典工作台开通数量上限提升至 10000
|
2026-10-17 12:49:29 +08:00 |
|
yml2213
|
82c59bb4af
|
feat(huya): 协作台账勾选导出 CK 到剪贴板(单点权限 + 逐行审计)+ 工具区固定两行
|
2026-10-16 22:24:08 +08:00 |
|
yml2213
|
6ef74c8e45
|
refactor(huya): 协作台账 failed 状态展示名「兑换失败」→「抢购失败」(枚举值不变)
|
2026-10-16 22:09:21 +08:00 |
|
yml2213
|
fdc57752dc
|
refactor(huya): 协作台账 done 状态展示名「已完成」→「抢购成功」(枚举值不变)
|
2026-10-16 22:06:39 +08:00 |
|
yml2213
|
e8abd60734
|
feat(huya): 协作台账状态机新口径(跳步/已确认绑定/兑换失败)+ 账号全生命周期快照(迁移 0059)
|
2026-10-16 22:00:34 +08:00 |
|
yml2213
|
aac264b639
|
feat(huya): 协作台账店铺字典·新建强校验·同买家多单 + uid 放开(迁移 0057/0058)
- 店铺字典(迁移 0057):大按钮点选 + 「新店」自定义自动登记;重命名可级联、
停用/备注;列表行内改、详情、筛选条共用同一个 picker
- 新建强校验:订单编号/店铺/CK/礼包名/主页截图必填;贴 CK 即探针预览,
读不到绑定角色禁止提交;礼包用工作台配置的活动 SID 现拉(浏览器缓存 + 强制刷新)
- 图片:绑定图停用、「绑定斗鱼号」下线(绑定关系改由探针读 bind_game_*),
主页截图改为新建必填(弹窗内先传 OSS 再随表单落库)
- 同买家多单软识别:按「绑定账号 + 绑定角色」整批一次查询,列表「同买家」列 +
详情分组,点单号直接切单
- uid 放开唯一性(迁移 0058):同一份 CK 可服务多单,原 409 冲突改为提示 + 审计
- 列表体验:序号列、搜索扩到 11 个字段、CK 状态列截断、新建弹窗放大并去滚动条
- 验证:pytest 932 passed / 6 skipped;接口冒烟 56 项全绿;tsc+eslint+build 通过
|
2026-10-16 21:29:08 +08:00 |
|
yml2213
|
df8c63b829
|
feat(huya): 外部 CK 协作台账(S1–S6)+ 图片上传能力
协作台账:新表 huya_external_orders 替代 Excel 多人协同表(设计见
docs/设计-虎牙外部CK协作台账.md),一条 CK 一行,所有人共享、改动留痕。
- 前端 pages/HuyaCollabPage.tsx + 菜单「虎牙 → 外部单协作」/huya/collab:
内联编辑(带乐观锁 version)、图片缩略图、详情抽屉(字段表单 + 两个图片槽位 +
操作时间线)、粘贴导入弹窗(带 TSV 预览)、批量/单条验证 CK、页头统计条、筛选
- 两套状态机:业务 pending→bound→recharged→scripted→done(旁路 void)、
凭据 unverified/valid/invalid/disabled;唯一写入口在 services/huya_collab_service.py,
字段级审计 + 整数 version 乐观锁(不用 updated_at:DATETIME 只到秒)
- CK 只读探针 check_user_bind_game_account(真机判据:响应非 None 且 status == 200),
成功即覆盖写绑定快照 bind_game_account/bind_game_role/bind_game_channel(迁移 0056),
失败只改凭据状态、不动业务状态;人工只能停用/恢复(POST /{id}/ck/status)
- 贴/换/重建 CK、TSV 批量导入(SAVEPOINT 单行隔离,部分失败不整体失败)、
权限 huya:collab:view/edit/manage(删除只给运营)
- 孤儿图清理脚本 scripts/cleanup_orphan_file_assets.py(默认 --dry-run)
图片上传(协作台账截图用):OSS/本地双后端 + 缩略图变体 + /api/files 代理回读,
权限 file:upload / file:view。
验证:pytest 880 passed / 6 skipped;ruff format 全绿、ruff check 仅剩既有告警;
前端 tsc -b / eslint / vite build 通过;接口端到端冒烟 29 项全绿(TestClient,探针用假客户端);
探针真机冒烟 3 例(有效 CK=True、别人 uid=False、裸 cookie=False)。
|
2026-10-16 19:38:59 +08:00 |
|
yml2213
|
99e8643d83
|
chore: 版本号 0.3.0 -> 0.4.0
本次包含:虎牙开通充值按份数下单与记住上次选择、精英宝典与其他开通商品分块、一键查询 CK 失效标红、支付码改 qr.alipay.com 扫码内容、开通商品只保留可购买 spu 并清理历史死商品行。
|
2026-10-15 21:01:47 +08:00 |
|
yml2213
|
9a0d59825c
|
fix(huya): 开通商品只保留真正可购买的 spu,并清理历史死商品行
真机 2026-10-15(HAR 10.15-精英徽章两个-1 + 逐个 spu 探测):面板里的「精英徽章 hy-5872824」是积分中心「赠送指定礼物得积分」那排的礼物 spu —— getGoodsInfoV5 仍返回 200+价格,但 listPayChannelV5 返回 401「您的设备环境暂不支持购买该商品」,所以下单必报「当前支付渠道不可用」(与数量无关)。真能买的是 hy-8343549 精英徽章 ¥1 / hy-8343551 精英令 ¥10。
- 内置候选换成可购买的 4 个:hy-8328015 宝典 / hy-8327356 币 / hy-8343549 徽章 / hy-8343551 令
- 刷新商品增加「能买到」闸门:详情 200 后再校验 listPayChannelV5,非 200 或渠道为空即剔除并记录服务端原话
- 下单流程渠道失败时透出服务端消息,只有渠道真不在可用列表才说「当前支付渠道不可用(可用:…)」
- 商品列表只认「最近一次刷新」那一套:原先按账号并集返回,别的账号旧刷新留下的礼物 spu 会和最新一套叠成 7 个选项
- 刷新时清理历史死行:本账号旧行 + 全局默认行(account_id 为空)+ 其它账号里已不在候选中的 spu 行
- 测试:401 商品被剔除、渠道失败透传、列表只认最近一套、刷新清理别处死行
|
2026-10-15 21:01:23 +08:00 |
|
yml2213
|
86ca2ed021
|
feat(huya): 开通充值支持数量与记住上次选择,精英宝典单独一块
- 支持「其他开通商品」按份数下单(payload.count → createOrder 的 item_count),数量上限取商品 buy_limit
- 商品选择/数量写入 localStorage,下次进来还是上次那套
- 精英宝典(限购主商品)从其他开通商品里拆出来单独一块,避免混在一个下拉里选错
- 测试:payload.count=3 进入 run_open_flow 且结果/文案带 x3
|
2026-10-15 21:00:31 +08:00 |
|
yml2213
|
c89df9ae5b
|
feat(huya): 开通支付码多选账号时每个账号各出一个码并排展示
多选账号点「生成开通支付码」只出一个码:create_planned_tasks 把 create_recharge_order 也当成单笔任务(accounts[:1]),前端本来就支持多码并排,是被后端截断的。
- 后端:create_planned_tasks 不再截断 create_recharge_order(refresh_* 仍只建一个,商品快照是全局的),N 个账号 = N 个支付码任务,各自独立下单/监听支付
- 前端:支付码任务的并发取 min(10, max(并发, 账号数)),否则超出并发的码要等前面的码付完/超时才生成
- 前端:支付弹窗改成网格并排展示多个 150px 码,标题显示待扫码数;新增「生成失败(没有二维码)」点名区和「还有 N 个账号在排队生成」提示
- 前端:去掉每个码回包就自动弹支付弹窗的行为(多选时会反复把弹窗顶到最前);不做付完自动跳转
- 测试:多账号生成支付码 → 每账号一个任务,refresh_recharge_goods 仍单任务
|
2026-10-15 20:15:25 +08:00 |
|
yml2213
|
82294aba80
|
feat(huya): 一键查询查不到角色标记 CK 失效并前端标红
外部导入的 CK 过期时,角色走的 webActUI.checkUserBindGameAccount 整包没有 tRsp 回包(真机日志 newdata keys: ['']),而积分中心通道仍能返回 200,于是页面显示绿色「成功」+「角色信息接口无响应」,看不出 CK 已经挂了。
- 后端 _execute_query_all:bind_status is None 时打 result.ck_expired / ck_expired_reason、account.status=ck_expired,message 追加「疑似 CK 已失效,请重新登录或重新导入 Cookie」;业务码非 200(活动已下线等)不算 CK 失效,避免整批误标红
- 前端 HuyaElitePage:状态列红色「CK 失效」(tooltip 带原因)、最近操作消息红色、游戏名空值红色「角色未查到」;HuyaTasksPage 账号状态映射补 ck_expired
- 测试:角色接口无回包 → ck_expired + account.status;业务码非 200 不误标
|
2026-10-15 20:02:28 +08:00 |
|
yml2213
|
bf1e2e9361
|
fix(huya): 支付二维码改用收银台页面里的扫码内容 qr.alipay.com
真机复现(2026-10-15):上一版把二维码内容放成了**收银台页面地址**
(excashier.alipay.com/standard/auth.htm?payOrderId=…),那是 PC 版页面
(页面里写死 qrcodeWidth=150)。有些安卓机是用系统相机/浏览器打开的,就停在
这张 PC 页上——只显示左上角一个很小的二维码,不触发付款。
收银台页面里真正的扫码内容是隐藏字段 `J_qrCode`:
<input name="qrCode" value="https://qr.alipay.com/upx03110ghym9vm37sx7255c" id="J_qrCode"/>
- huya_pay_link 新增 PayTargets / resolve_pay_targets() / extract_pay_qr_code():
跟随网关 302 取收银台页面并解析出 qr.alipay.com 扫码码(约 40 字符)。
- 出码时写入 pay_qr_code,保留 pay_cashier_url 兜底;拿不到扫码码会打 warning。
- 前端二维码优先级:pay_qr_code → pay_cashier_url → 本站短链 → 原始地址。
验证:全量 pytest 772 passed / 6 skipped;用真机那张收银台页面跑解析得到
https://qr.alipay.com/upx03110ghym9vm37sx7255c;typecheck / eslint / ruff 通过。
|
2026-10-15 19:51:51 +08:00 |
|
yml2213
|
0b9a01ab3f
|
feat(huya): 开通支付码复用未支付旧单 + 二维码改用支付宝收银台直达地址
- 限购商品(精英宝典 buy_limit=1)挂着未支付旧单时,真正先失败的是购买权限
校验 checkUserBuyAuth(真机 703「已超过该商品的购买上限,下单失败~」),
createOrderV5 根本不会执行;现在 checkUserBuyAuth 与 createOrderV5 两处失败
都会回退 find_reusable_order,拿同一商品的未支付旧单继续 payOrderSubmitV5。
- 新增支付宝收银台直达地址解析(resolve_pay_entry_url):跟随网关 302 后的
excashier.alipay.com/standard/auth.htm?payOrderId=…(93 字符,原始网关地址
1616 字符)写入结果 pay_cashier_url;解析失败回落本站短链
/api/huya/pay/<task_id>?k=<hmac>,后端跑在 localhost 时客户也扫得开。
- 前端 QRCode 显式 color="#000" bgColor="#fff":antd v6 暗色主题默认
color=token.colorText、bgColor=transparent,白码落在白底容器里根本看不见。
- 支付成功后列表「二维码」列不再展示二维码(qrDoneLabel → 已支付/已开通)。
测试:pytest 767 passed / 6 skipped;typecheck、eslint、ruff 通过。
|
2026-10-15 19:28:26 +08:00 |
|
yml2213
|
f61284e808
|
feat(huya): 开通支付码支持多选批量 + 支付后自动确认开通
多选账号点「生成开通支付码」以前只有弹窗里最后一个码能被看到(每个账号一个
任务,前端只留一个 qrTask),实际只能一个账号一个账号地开。
- 前端:支付码弹窗改成列表 —— 一次列出该批次所有账号的二维码(账号/UID/
商品金额/状态),未支付的排前面,可逐个扫也可一起扫;行点击也会打开对应批次
- 支付成功后自动确认开通:新增 EliteMixin._refresh_elite_open_after_payment,
交付有几秒延迟,tag5 还没翻成 1 时重试(默认 4 次 × 3 秒),顺带取最新积分,
并把 elite_opened/elite_open_time/elite_expire_time 写回账号
- 已支付或已开通的账号二维码自动从弹窗收起,只留一行「已开通」标签
- 开通时间优先用支付回调里的支付时间(比再去翻订单更准,也少一次请求)
- 补 3 条测试:重试到已开通、重试到上限、支付成功后任务结果与账号字段齐全
全量 746 passed / 6 skipped,前端 tsc 通过
|
2026-10-15 17:14:20 +08:00 |
|
yml2213
|
369361a62c
|
style(huya): 精英宝典工作台表格表头与单元格统一居中
列宽按比例分配,所有列(含账号/游戏名/精英宝典/最近操作的双行内容)统一
align: center,积分不再单独右对齐 —— 之前左右跳着看很别扭。
|
2026-10-15 16:58:06 +08:00 |
|
yml2213
|
73536d62c8
|
feat(huya): 工作台补手机号/精英宝典列与一键查询
- 手机号列:外部 CK 的 `----手机号` 本来就落在 huya_accounts.game_phone,
列表一直没展示;现在单独成列,并纳入搜索
- 精英宝典列:显示「已开通/未开通/未查询」+ 开通时间 + 有效期
· 开通状态 = 积分中心 getRedeemNeedGoods 的 tag5(真机对照网页:1=已开通,
0=未开通,此时 tag7 会列出开通套餐),拿不准时为 NULL(显示「未查询」)
· 开通时间 = revenueWebUI.queryUserOrderList 里已支付的宝典订单 pay_time
(按 SPU 白名单 + 订单名含「精英宝典」识别,未支付订单不计,取最近一次)
· 有效期 = PlayMallUI.queryAllocation 页面配置的本赛季节点 tag10/tag11
(2026-10-15 抓包:精英宝典福利季丨Q4,2026-10-09 ~ 2026-12-31 23:59:59),
不写死索引,递归找带 tag10/tag11 的节点
- 新任务 query_all「一键查询」:勾选账号一次跑完角色绑定 + 宝典开通 + 积分,
按部分失败如实汇总(某个接口挂了不影响其它结论),并把宝典状态写回账号
- 迁移 20261015_0053:huya_accounts 新增 elite_opened / elite_open_time /
elite_expire_time(时间存 Unix 秒,与斗鱼 elite_expire_time 同约定)
- 开通商品按页面「赠送指定礼物得积分」那一排对齐成 6 款(去掉页面已不用的
旧版精英宝典 hy-5879340),列表接口只返回账号级快照并按 spu 去重
- 建 WSS 会话失败(积分中心端点静默不回包)时回退 HTTP cdnws,
不再让整批任务判失败
- 列表列宽改按比例分配,避免宽屏下被拉出奇怪的宽度;最近操作不再重复状态
- 新增 tests/test_huya_elite_query.py(10 条);同步迁移头版本断言
真机验证:#65 已开通(10-13 20:41:45,有效期 12-31)、#70 新开通
(10-15 16:37:37)判定与订单/网页一致
|
2026-10-15 16:53:30 +08:00 |
|
yml2213
|
7ca0f7ee28
|
fix(huya): 刷新开通商品不再依赖已下线的活动任务接口
真机(2026-10-15)实测 webActUI.getActTaskDetail(act 25135) 返回
601「活动已下线」,刷新开通商品第一步就失败,下拉框一直为空。
- 商品来源改为内置候选(积分中心页面「赠送指定礼物得积分」那一排,
全部经 getGoodsInfoV5 真机验证 code=200):精英宝典 hy-8328015 ¥30、
精英币 hy-8327356 ¥0.1、精英徽章 hy-5872824 ¥1、精英令 hy-5879346 ¥10、
精英令*10 hy-5874269 ¥100、精英令*100 hy-5874270 ¥1000;
旧版精英宝典 hy-5879340 页面已不再使用,从候选移除
- 活动任务详情降级为可选补充:返回非 200 只记 warning 并写入
result.task_detail_error,不再让整次刷新失败;失败原因以商品详情为准
- 刷新时清掉该账号全部旧商品行(不限 sid),避免同名商品重复
- 列表接口只返回账号级快照并过滤 2026-07-04 的全局种子行,
同一 spu_id 保留最新一行(原先 精英宝典 会出现两次)
- 前端:下拉标签带 spu 便于区分,按内置顺序排序,默认自动选中第一项
- 新增 tests/test_huya_recharge_goods_source.py(6 条):活动下线响应字节
回归、下线不阻断刷新、活动商品仍会并入、失败原因归属、跨 sid 清理、
列表去重与隐藏种子行(均已做反向验证)
真机验证:刷新成功 6 个商品,价格/库存与网页一致
|
2026-10-15 15:57:25 +08:00 |
|
yml2213
|
905a7ef22c
|
fix(huya): 查询积分改走积分中心新接口(含成长等级)
旧活动接口 webActUI.getUserScore 对任何 sid 都返回 603「活动已结束」
(接口已下线,与工作台 SID/活动配置无关),刷新积分只会报错。
- 协议层新增两个 RPC(WSS + HTTP 双侧同签名):
shopMiddleUI.getRedeemNeedGoods(tag2=当前积分、tag3=兑换门槛,
兑换商品号 POINTS_REDEEM_GOODS_NUM=8315982,传错直接 500)
与 GameBizUI.getGrowLevelUserInfo(成长值/成长等级/昵称/头像)
- 新增结构体 GetRedeemNeedGoodsReq / GetGrowLevelUserInfoReq,
与 HuyaEliteWssSession 透传
- 服务层 _execute_query_points 主源改为积分中心接口,结果带
points/redeem_threshold/grow_level/grow_value,并同步 account.points;
接口无响应时才回退旧活动接口并如实报告其 603 返回
- 开通支付成功后的积分刷新同样改走积分中心接口
- 前端任务页积分结果优先读 points(兼容旧记录的 available_score),
并在有成长等级时一并展示
- 新增 tests/test_huya_points_query.py:真机响应字节回归 + 请求参数
字面量断言 + 服务层积分来源/回退语义(已做反向验证)
真机验证:HTTP 通道取到积分 280 / 门槛 20 / 成长等级 3
|
2026-10-15 15:32:46 +08:00 |
|
yml2213
|
b5d8d5b5d8
|
feat(huya): 缺网页设备态的 CK 回退 HTTP cdnws 通道
问题:外部 CK(只带登录态)导入工作台后,任何任务都被「Cookie 缺少网页设备态
(sdid/udb_deviceid/udb_guiddata/udb_anobiztoken)」直接拦下,查询角色/开通都用不了。
实测结论(2026-10-15,同一张外部 CK):
- 这些字段是 WSS 通道的门禁,不是业务必需 —— 同一条 CK 走 HTTP cdnws 可以正常查询
角色、商品,并走完整条开通链路(商品/小店/渠道/协议/返利/试算/同意/购买权限)
- A/B 对照(同一账号只抽掉 sdid):含 sdid 服务端回包,去掉即完全不回包,说明 sdid
是 WSS 的硬门槛,而 HTTP 通道不需要
- 因此改为按能力选通道:设备态齐全走 WSS(行为不变),缺设备态回退 HTTP 并记日志
- http_client:补齐积分中心链路(get_supplier_info / accept_hy_protocol /
calc_order_promotion / play_mall_get_my_promotion / play_mall_query_allocation /
get_user_profile / get_follow_wechat_status);下单与支付参数对齐 2026-10-13 抓包
(appInfo.scene=7、订单 src/orderScene=4、orderType=6、jifencenter 标记、空点击序列、
m-shop.huya.com/points.html 回调),并去掉 orderType 1→10 的重试循环(有重复下单风险)
- huya_runner_core:_activity_client/_shop_client 不再抛 COOKIE_INCOMPLETE,改为
返回 HTTP cdnws 客户端(方法签名与 WSS 会话保持一致,任务侧无感)
验证:tests/test_huya_http_shop_flow.py(下单/支付参数与回调域名)、
tests/test_huya_runner_transport.py(通道选择:缺设备态走 HTTP、齐全仍走 WSS);
真机 HTTP 开通链路 8 步全通(末步服务端返回业务提示「已超过该商品的购买上限」,
说明通道可用而非被丢弃)。反向验证:关掉回退即复现原报错。全量 pytest 717 passed。
|
2026-10-15 15:21:51 +08:00 |
|
yml2213
|
a9d711a7e9
|
fix(huya): 结构体尾部字段容错解析(服务端新增 ZERO 字段不再打挂整个 RPC)
真机现象(2026-10-15,外部 CK 导入后查询角色):checkUserBindGameAccount 响应结构
尾部多了 tag6(ZERO 类型 0x6c),共享的 read_struct 读到非 STRUCT_END 直接抛
「期望 STRUCT_END, 实际 0x0c」,整个 RPC 返回 None —— 工作台「查询角色」永远失败。
- taf_protocol:read_struct 收尾改为按 TAF 语义跳过未建模的尾部字段(上限 32 个,
防止解析错位时无限吞字节);新增 skip_to_struct_end()
- frame_decoder / shop_structs:抽出 decode_struct_bytes 与 ShopRawRsp.from_payload,
WSS 与 HTTP 两条通道共用一份通用解码逻辑(wss_client 同步改用)
验证:tests/test_huya_struct_parse_resilience.py 用真机响应字节回归(含 tag6=ZERO 的
响应能解析出角色「泪雨全是谎言」);按 AGENTS.md 反向验证 —— 注掉
skip_to_struct_end() 即复现线上报错「期望 STRUCT_END, 实际 0x0c」,还原后恢复。
全量 pytest 通过。
|
2026-10-15 15:21:34 +08:00 |
|
yml2213
|
4ce30e5c26
|
feat(huya): 精英宝典工作台支持导入外部 CK
- 新增 POST /api/huya/workbench-accounts/import-cookies(huya:task + huya:import):
外部 CK 复用现有解析入库后直接加入当前用户的工作台集合,导入完即可在工作台执行
「生成开通支付码/绑定二维码/查询角色/刷新积分」等操作
- 新账号自动 assigned_to=导入者:客服的账号列表按归属过滤,不设归属会「导入成功但看不到」
- import_huya_cookies_detailed 返回账号对象供工作台复用,原 import_huya_cookies 行为不变
- 工作台账号卡片新增「导入外部 CK」入口(huya:import 权限控制)与导入弹窗
验证:新增 tests/test_huya_workbench_import_ck.py(入库、归属、工作台集合、重复导入幂等、
全脏数据不建记录);按 AGENTS.md 做了反向验证(关掉归属赋值后该用例变红,还原后恢复)。
前端 tsc -b 与全量 pytest 通过。
|
2026-10-15 14:56:58 +08:00 |
|
yml2213
|
f540dcfc29
|
feat(huya): 对齐积分中心开通链路(2026-10-13 抓包)
按 10.13「开通精英宝典/购买幸运币」抓包(m-shop.huya.com/points.html)对齐商城链路:
- WSS host 改为 launch.queryHttpDns 动态解析(失败回退抓包实测 host);握手 baseinfo
只带 uid/guid/页面 UA/exp,Origin 与页面同源
- wsLaunch 改为带真实 lUid/sGuid;初始化补上 AUTH(0x0A) → getConfig →
UpdateUserExps(0x17),并把 getConfig 下发的版本 map 原样回传(不回传则业务 RPC 无响应)
- 补齐新 RPC:getSupplierInfoV5 / acceptHyProtocolV5 / calcOrderPromotion /
PlayMallUI.getMyPromotion|queryAllocation / wupui.* / huyauserui.getUserProfile
- 下单参数对齐:shopAppInfo.scene=7 与订单 src/orderScene=4 分离、orderType=6、
bizType=5、gameCategoryId=507、extraParam.bizParams 标记 jifencenter、env 仅空点击
序列、支付回调指向 m-shop.huya.com/points.html
- 开通链路抽到 services/huya_shop_flow.py,充值任务改为调用它
验证:新增 tests/test_huya_points_shop_protocol.py 与抓包逐字节比对(心跳、版本回传、
wsLaunch/getConfig/下单/支付帧与新 RPC 参数,共 10 条);按 AGENTS.md 做了反向验证
(把 jifencenter 改成 0 后该用例变红,还原后恢复)。ruff format --check 与全量 pytest 通过。
|
2026-10-15 14:56:30 +08:00 |
|
yml2213
|
ec07e4fc06
|
fix(config): 修复切换充值渠道报错及补齐 peace_enabled 字段声明
- 在 DouyuConfigOut 与 DouyuConfigUpdate 中补齐 peace_enabled 声明与序列化
- 在 update_config 中使用 getattr(req, field, None) 安全读取属性,避免 AttributeError 导致 500
- 在 _config_out 中加入 peace_enabled 输出映射
- 增加切换充值渠道与配置更新的单元测试
|
2026-10-08 11:49:41 +08:00 |
|
yml2213
|
4eef45efe4
|
fix(accounts): 完善手机号必绑与账号注销等登录异常分型识别
- 补充必须绑定手机号与账号注销/封禁/冻结等错误文案的识别规则
- 增加数据修正迁移 20261008_0052,回写历史账号和登录任务的失败分型
- 增加列表查询与导出时根据错误文案自动兜底细化 failure_kind 的逻辑
- 增加并完善相关分型单元测试
|
2026-10-08 11:26:19 +08:00 |
|
yml2213
|
f8ad6e1777
|
perf(assignments): 优化分配管理页面加载性能与角标数量展示
- 前端改造为服务端分页查询 (accountApi.listPaged),避免一次性拉取 1.6 万+ 账号导致页面卡死
- 优化后端 assignments_summary 聚合查询,消除大子查询临时表
- 修复 Badge 默认 99+ 限制,设置 overflowCount 支持展示完整账号数量
- 修复测试用例 test_business_events.py 当前时间跨天断言问题
|
2026-10-08 11:08:41 +08:00 |
|
yml2213
|
f101414f5e
|
feat(accounts): 新增登录异常分型统计、多选/全量导出、筛选记忆及页面组件模块化拆分
- 新增登录失败异常分型统计:支持「必须绑定手机号」、「极验滑块」、「凭证错误」、「邮箱取码失败」、「邮箱配额已满」、「网络异常」分型识别、生命周期联动(待人工)与一键筛选;
- 新增账号名单与明细导出功能:支持勾选多选或按当前筛选条件全选,可导出纯用户名名单 (TXT) 或 UTF-8 BOM 结构化明细报表 (CSV),并支持一键复制到剪贴板;
- 优化筛选条件记忆机制:支持页面切换/返回后自动保留所有筛选与排序状态,新增顶部「重置全部筛选」快捷按钮;
- 模块化拆分 AccountsPage:将 2100+ 行的大文件拆解至 pages/accounts/ 子目录(包含状态卡片、筛选面板、工具栏、操作弹窗与表格构建器),提升可维护性;
- 验证方式:新增 5 个后端自动化单测 (test_account_failure_and_export.py),全量 694 个测试用例通过,前端 TypeScript 编译与 pre-commit 代码规范检查全部通过。
|
2026-10-07 17:23:39 +08:00 |
|
yml2213
|
44b762ea8c
|
fix(overview): 锁定核心高价值套装并修复未查询空值误判
- 高价值套装精确匹配「套装-兔兔白日梦」与「套装-狂战萌兔」,排除头盔/背包/手榴弹散件干扰
- 增加 is_suit_queried_expr,未查询或 NULL 账号严禁误判为双套均可兑换
- 修复前后端序列化空值保持,完善列表与详情页准入状态和判定依据展示
- 新增头盔排除与 NULL 统计防错回归单测,全量通过 689 个用例
|
2026-10-07 15:27:30 +08:00 |
|
yml2213
|
5405d4b1d1
|
fix(overview): 纠正高价值套装以商城 status==1 为最高准入裁判
- 根因:斗鱼官方商城接口 status==1 代表「已达兑换上限」,历史代码误以为商品列表全为全局字段而单纯依赖常被官方清空的 exchange_records,导致已兑换账号被误判为可兑换
- 修复:extract_high_value_goods 结合商城完整列表 status==1 现场判定已兑换,exchange_records 作为历史展示与兜底
- 前端:优化工作台与一键查询展示,明确展示「已达上限 N 个: ...」与「未达上限」,消除反向歧义
- 文档:沉淀坑 #9 到 AGENTS.md,并更正设计-账号一键查询.md
|
2026-10-07 14:51:51 +08:00 |
|
yml2213
|
05b2bf8579
|
docs(agents): 修正分支约定,补上这轮实践买的教训
- **删掉已作废的约定**「推完 main 再 `dev merge --ff-only main`」:
dev 现在与 main 已分叉(上面有未上线的账号自动分配功能),ff-only 必然失败。
改为:`main` = 已发布,新功能从 main 开 `feat/*`;要同步 dev 只能真合并且需显式确认。
- 新增一批实证教训:提交/推送的钩子要求(`pre-commit` 查的是 `ruff format`,
只跑 `ruff check` 会被拦)、测试库 `create_all` 不会 ALTER 已有表(症状
`Unknown column`)、`dev.sh` 会自动应用迁移导致切分支后应用起不来、
生产部署的完整流程与三项前置检查。
- 坑速查 4 → 8 条:新增 `pgrep -f` 自匹配白等、`set -e` + 管道过滤半途静默中止
(曾让镜像库变空)、`ruff check` ≠ 能提交;并补上 REPEATABLE READ 的具体应对。
- 据实补全本地库清单:先 grep 全仓库确认无引用,再查内容,确认
`douyu_login_prodclone` / `douyu_login_rehearsal` 是 S1–S7 演练留下的快照。
- 原有教训一条未删,整体按「干活顺序」重排(60 → 116 行)。
|
2026-10-07 13:20:33 +08:00 |
|
yml2213
|
d11fa1032d
|
feat(login-tasks): 按状态导出 CSV + 登录失败写进账号生命周期
一、失败入账号一生(此前完全缺失)
生产实测:`login_ok` 1,456 条、`relogin_failed` 73 条,但**没有 login_failed**,
而 login_tasks 里 attempt_status='failed' 有 247 条 —— 这 247 次失败在账号时间线上
一条痕迹都没有,「这账号为什么一直登录不上」在账号页上无从回答。
- 新增事件类型 login_failed,在 `_mark_attempt_failed` 里写入
- **被停止 / 被中断不写**:分型把「已停止/中断/服务重启」归到 interrupted,
那不是账号的问题 —— 否则运营按一次停止就能给几十个账号刷满假失败
- 事件带分型(captcha/credential/email_code/email_quota/network),
同时落进 detail.kind,以后可直接按「验证码失败」筛账号
- 幂等键 login_task:{id}:failed:{ts},与成功路径同构
二、失败分型下沉成共用 service
`classify_failure` 原在 automation/jobs/ck_relogin.py,手动登录也要用。
挪到 services/login_failure.py(job 改为 import,`ck_relogin.classify_failure`
这个名字保留,旧调用方与用例不受影响),并提供型别中文标签与
`is_account_fault` 判据 —— 与仓库既有的「service 不该依赖 job」分层一致。
三、按状态导出 CSV
- 新增 GET /api/login/tasks/export:不分页,导出当前筛选的**全部**匹配记录;
列:账号/状态/失败原因/失败分型/批次/最近尝试时间(UTC)/标签/归属客服
- 权限与筛选与列表**完全共用**,客服只导出自己名下账号
- 带 UTF-8 BOM(不加 Excel 打开中文表头是乱码),导出动作写审计
四、修一个口径不一致的真 bug
页面「失败 N」= failed + error 之和,但筛选只认 failed ——
所以截图里「失败 389」点进去只有 386 条(差的就是那几条 error);
「清空失败」同样漏删 error。现在把状态组收敛成一份 `_apply_status_filter`,
列表 / 导出 / 批量删除三处共用。
测试:684 passed, 6 skipped(本次新增 13 个);三条关键断言做了反向验证
(去掉 stopped 判断 / 失败组去掉 error / 去掉 BOM,对应用例均变红)。
|
2026-10-07 12:54:57 +08:00 |
|
yml2213
|
281769b440
|
feat(accounts): 账号列表按归属筛选,批量分配支持按筛选全选
原来只有 assigned_only(已分配),筛不出「未分配」,也看不到账号归谁。
新增 assign_status/assigned_user_id 可与标签、CK、搜索等叠加;
BatchAssign 支持 all_matching,「筛出未分配 → 一键分给某人」不必先勾选。
|
2026-10-07 09:13:54 +08:00 |
|