From 908ceb0b3b745fdf3ada65b2a74c7f1e1275392c Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sun, 18 Oct 2026 21:23:45 +0800 Subject: [PATCH] =?UTF-8?q?docs(review):=20=E6=B2=89=E6=B7=80=2010.18=20?= =?UTF-8?q?=E6=8A=A2=E8=B4=AD=E5=AE=9E=E6=88=98=E5=A4=8D=E7=9B=98=E4=B8=8E?= =?UTF-8?q?=E5=AF=B9=E6=AF=94=E4=BC=98=E5=8C=96=E8=B7=AF=E7=BA=BF=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 docs/seckill-analysis-20261018.md:覆盖 5 台机器 23 实例 562 账号全量指标剖析 - 新增 docs/seckill-optimization-roadmap.md:对标 dygou_go 形成四大工作包优化路线图 --- docs/seckill-analysis-20261018.md | 155 +++++++++++++++++++++++++++ docs/seckill-optimization-roadmap.md | 94 ++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 docs/seckill-analysis-20261018.md create mode 100644 docs/seckill-optimization-roadmap.md diff --git a/docs/seckill-analysis-20261018.md b/docs/seckill-analysis-20261018.md new file mode 100644 index 0000000..997c52f --- /dev/null +++ b/docs/seckill-analysis-20261018.md @@ -0,0 +1,155 @@ +# 2026-10-18 抢购实战全量复盘与引擎诊断报告 + +> **数据源**:`/Users/yml/Downloads/logs/10.18`(共 5 台机器 pc-1 ~ pc-5,23 个运行实例,覆盖 562 个账号) +> **活动信息**:sid=2277,开抢时刻 17:00:00,三个目标商品(13433 怪诞乔克 / 13435 天网终结者 / 13443 套装-潮萌小黄鸭) +> **软件版本**:huya-go v0.5.2(实施了双时间校准、首发错峰 300ms、动态提前量、30s 窗口模型) + +--- + +## 一、核心战报总览 + +| 目标商品 | 账号数 | 成功数 | 成功率 | 兑换请求 | 限流(火爆) | 售罄 | 角色伪报错(未绑定) | 首笔成功(虎牙时间) | 最后一笔成功 | +|---|---|---|---|---|---|---|---|---|---| +| **13433 (怪诞乔克礼包)** | 301 | **186** | **61.8%** | 3,135 | 1,939 | 740 | 549 | 17:00:00.226 | 17:00:10.280 (售罄) | +| **13435 (天网终结者)** | 79 | **78** | **98.7%** | 601 | 385 | 0 | 115 | 17:00:00.228 | 17:00:19.361 | +| **13443 (潮萌小黄鸭)** | 182 | **182** | **100.0%** | 1,818 | 1,112 | 0 | 250 | 17:00:00.226 | 17:00:20.476 | +| **全网合计** | **562** | **446** | **79.4%** | **5,554** | **3,436 (61.8%)** | **740** | **914** | **17:00:00.226** | **17:00:20.476** | + +### 关键战报结论 +1. **整体胜率大幅跃升**:562 账号斩获 446 件,总成功率 **79.4%**(比 10.16 的 71% 提高 8.4 个百分点)。小黄鸭 182/182 达成 **100% 满贯**,天网终结者 78/79 达成 **98.7% 满贯**。 +2. **极速秒杀款(乔克)硬碰硬**:在全国高并发争夺下,301 个账号拿下 186 件(**61.8%**),窗口期约 **10 秒**(17:00:00.226 首单放行,17:00:09.335 全网首次报售罄,17:00:10.280 最后一笔成交)。 +3. **0 崩溃 / 0 掉队**:23 个实例全部平稳跑完 30s 窗口,无 panic、无卡死、无 WUP 截断。 + +--- + +## 二、23 个实例运行明细矩阵 + +| 机器 | 实例 | 目标商品 | 账号 | 成功 | 成功率 | 兑换请求 | 限流 | 售罄 | 账号未绑定 | 本机偏差 | RTT | 首笔成功(H虎牙时间) | 末笔成功(H虎牙时间) | +|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +| pc-1 | default | 13433 乔克 | 30 | 18 | 60.0% | 389 | 234 | 83 | 53 | +14ms | 56ms | 17:00:00.226 | 17:00:09.414 | +| pc-1 | instance-2 | 13433 乔克 | 29 | 14 | 48.3% | 424 | 246 | 117 | 47 | +9ms | 75ms | 17:00:00.311 | 17:00:10.266 | +| pc-1 | instance-3 | 13433 乔克 | 30 | 20 | 66.7% | 342 | 213 | 71 | 38 | +14ms | 62ms | 17:00:00.270 | 17:00:09.398 | +| pc-1 | instance-4 | 13433 乔克 | 30 | 22 | 73.3% | 328 | 193 | 58 | 55 | +8ms | 62ms | 17:00:00.286 | 17:00:10.262 | +| pc-1 | instance-5 | 13433 乔克 | 27 | 15 | 55.6% | 341 | 192 | 84 | 49 | +12ms | 75ms | 17:00:00.238 | 17:00:09.375 | +| pc-2 | default | 13435 天网 | 30 | 29 | 96.7% | 219 | 144 | 0 | 44 | -30ms | 65ms | 17:00:00.254 | 17:00:12.335 | +| pc-2 | instance-2 | 13433 乔克 | 27 | 17 | 63.0% | 335 | 195 | 71 | 52 | -36ms | 69ms | 17:00:00.246 | 17:00:10.075 | +| pc-2 | instance-3 | 13435 天网 | 30 | 30 | 100.0% | 233 | 158 | 0 | 45 | -32ms | 73ms | 17:00:00.228 | 17:00:14.526 | +| pc-2 | instance-4 | 13435 天网 | 16 | 16 | 100.0% | 106 | 67 | 0 | 23 | -30ms | 78ms | 17:00:00.267 | 17:00:19.361 | +| pc-2 | instance-5 | 13433 乔克 | 30 | 20 | 66.7% | 344 | 203 | 68 | 52 | -32ms | 78ms | 17:00:00.280 | 17:00:09.404 | +| pc-3 | default | 13433 乔克 | 24 | 15 | 62.5% | 282 | 170 | 51 | 44 | -101ms | 72ms | 17:00:00.264 | 17:00:10.280 | +| pc-3 | instance-2 | 13433 乔克 | 20 | 16 | 80.0% | 191 | 112 | 28 | 34 | -99ms | 69ms | 17:00:00.237 | 17:00:09.409 | +| pc-3 | instance-3 | 13433 乔克 | 20 | 10 | 50.0% | 215 | 130 | 42 | 29 | -98ms | 77ms | 17:00:00.240 | 17:00:09.413 | +| pc-3 | instance-4 | 13435 天网 | 1 | 1 | 100.0% | 10 | 8 | 0 | 1 | -97ms | 68ms | 17:00:11.350 | 17:00:11.350 | +| pc-4 | default | 13443 小黄鸭 | 30 | 30 | 100.0% | 238 | 161 | 0 | 47 | -761ms | 70ms | 17:00:00.239 | 17:00:20.476 | +| pc-4 | instance-2 | 13443 小黄鸭 | 30 | 30 | 100.0% | 201 | 131 | 0 | 40 | -763ms | 67ms | 17:00:00.226 | 17:00:19.394 | +| pc-4 | instance-3 | 13433 乔克 | 30 | 17 | 56.7% | 308 | 190 | 52 | 43 | -764ms | 78ms | 17:00:00.265 | 17:00:09.384 | +| pc-4 | instance-4 | 13435 天网 | 2 | 2 | 100.0% | 8 | 6 | 0 | 0 | -763ms | 72ms | 17:00:00.310 | 17:00:06.408 | +| pc-4 | instance-5 | 13433 乔克 | 4 | 2 | 50.0% | 58 | 35 | 15 | 6 | -762ms | 76ms | 17:00:06.331 | 17:00:08.341 | +| pc-5 | default | 13443 小黄鸭 | 30 | 30 | 100.0% | 249 | 168 | 0 | 51 | -500ms | 72ms | 17:00:00.267 | 17:00:19.445 | +| pc-5 | instance-2 | 13443 小黄鸭 | 30 | 30 | 100.0% | 233 | 156 | 0 | 47 | -498ms | 82ms | 17:00:00.288 | 17:00:14.531 | +| pc-5 | instance-3 | 13443 小黄鸭 | 30 | 30 | 100.0% | 234 | 153 | 0 | 51 | -499ms | 80ms | 17:00:00.264 | 17:00:17.219 | +| pc-5 | instance-4 | 13443 小黄鸭 | 32 | 32 | 100.0% | 266 | 171 | 0 | 63 | -496ms | 65ms | 17:00:00.308 | 17:00:19.301 | + +--- + +## 三、重大实战发现与深度逆向证据 + +### 发现 1:双时间校准机制(H-time)表现堪称完美 +- **证据**: + - pc-1 本机时钟偏快 +14ms; + - pc-2 本机偏慢 -30ms; + - pc-3 本机偏慢 -100ms; + - pc-4 本机偏慢高达 **-763ms**(近 0.8 秒误差); + - pc-5 本机偏慢高达 **-500ms**(0.5 秒误差)。 +- **实测结果**:在动态提前量(`dynamicAdvance = ErrorBound + RTT/2`)换算后,**所有 5 台机器打向虎牙的第一发请求,抵达虎牙服务端的估算时间全部精准收敛在 `H17:00:00.004 ~ H17:00:00.018` 之间!误差 < 15ms!** +- **首单成交时间一致性**:所有实例的首笔成功全部精准定格在 `H17:00:00.226 ~ H17:00:00.311`,没有任何一台机器因为本地时钟偏差而过早白打或过晚落后。 + +### 发现 2:虎牙服务端的微观放量门槛(0~200ms 的硬限流墙) +- **日志切片证据**: + - `H17:00:00.000 ~ 00.200`:第一批抢跑的 42 个请求中,33 个直接被服务端返回「活动太火爆了,请稍后重试」,只有极少数(9个)通过。 + - `H17:00:00.220+`:服务端才真正开闸放水,第一批成交井喷。 + - **结论**:虎牙整点秒杀虽然在 17:00:00 激活,但在 0~200ms 内服务端网关存在初始抗峰/排队限流(或微服务放量延迟)。请求在途 50ms 左右,刚好在 0.22s 触发第二波抢兑。 + +### 发现 3:全网 914 次「账号未绑定!」的真正元凶——角色服务降级伪报错 +- **现象**:日志出现高达 914 次 `category=session_lost msg=账号未绑定!`。 +- **逆向真相(证据)**: + - 账号 `1199668644708`(pc-1 default): + - `17:00:00.309(H17:00:00.323)`:报 `账号未绑定!` + - `17:00:00.769(H17:00:00.783)`:报 `活动太火爆了,请稍后重试` + - `17:00:01.616(H17:00:01.630)`:报 `账号未绑定!` + - `17:00:02.066`:报 `请求太频繁,请稍后重试` + - `17:00:04.462`:报 `账号未绑定!` + - `17:00:09.318(H17:00:09.333)`:**请求成功!积分成功扣除,兑换成功,并查到兑换记录!** + - **数据分布**: + - 270 次发生在 17:00:00 秒,178 次发生在 17:00:01 秒,119 次发生在 17:00:02 秒。 + - 单账号最大连续遇到该提示的次数只有 4 次(387 个账号连续 1 次,48 个账号连续 2 次,8 个连续 3 次,2 个连续 4 次)。 + - **业务结论**: + - 该提示根本**不是虎牙 Cookie 或 Web 登录态失效**! + - 在秒杀洪峰时,虎牙兑换接口需要同步校验用户的「和平精英游戏角色绑定(game_role)」。下游角色绑定系统瞬间过载超时,虎牙兑换接口直接 fallback 抛出「账号未绑定!」。 + - 随着洪峰在 2~3 秒后略微缓解,下游角色校验恢复,该账号立刻正常兑换成功! + +### 发现 4:服务端放量形态分析与 9.5s 的放量脉冲 +- **现象**: + - 17:00:00 ~ 17:00:09 之间,服务端保持每秒 10~20 个的稳定匀速放行。 + - **在 `H17:00:09.5` 这一半秒内,三大商品同时爆发大量成功(乔克 80 个、小黄鸭 59 个、天网 26 个,合计 165 个成功!)** + - 紧接着在 `H17:00:10.0`,乔克立刻全面售罄(17:00:10 报 SoldOut 8 次,10.5 报 17 次,11.0 报 16 次,随后彻底无货)。 +- **推论**: + - 虎牙在秒杀开启后前 9 秒有严格的限流防刷漏斗,在第 9~10 秒网关放宽了限流阈值,瞬间消化了排队和重试的请求,把剩余库存全部释放并打空。 + - 这再次印证了:**持续紧咬 10 秒窗口、不轻言放弃、保持合理退避的引擎策略是极其正确的**(80 个乔克都是在 9.5 秒抢到的!如果像老版本那样 2~3 秒烧光轮次就退出,这 80 个乔克就全丢了)。 + +### 发现 5:TAF/WUP 协议异常完整诊断生效,捕获 5 秒超时异常 +- **日志切片**: + ``` + [pc-2] 2026-10-18 17:00:05.070 [监控][error][账号:1199664503824] loop=1 action=exchange_error category=protocol msg=兑换请求失败 error=协议响应异常: webActUI.scoreExchangePrize 响应缺少 tRsp/tResp(iRet=128 servant=webActUI.scoreExchangePrize status={STATUS_RESULT_DESC=wup request biz execption:-7} keys={(2B)} payload=11B) + ``` +- **价值分析**: + - 之前 10.16 优化项 P2 的诊断字段全部成功落地(抓到 `iRet=128` 与 `status={STATUS_RESULT_DESC=wup request biz execption:-7}`)。 + - 并且定位到了耗时:请求从 17:00:00 发出,在 17:00:05.070 才收到响应(耗时整整 5.07 秒)。 + - 这说明服务端微服务在处理此请求时发生 5s 超时后抛出异常。客户端虽然优雅捕获并重试,但单账号被阻塞了 5 秒,错过了秒杀黄金期。 + +--- + +## 四、对本项目(huya-go)代码的检视与优化建议 + +基于上述证据,我们对照当前代码仓库(`internal/sniper`、`internal/huya`、`internal/gui`)进行审查,发现以下改进空间: + +### 1. 【高优先级】重构「账号未绑定!」的分类与退避语义 +- **现状代码**(`internal/sniper/classify.go:116`): + ```go + case containsAny(text, "账号未绑定", "未绑定账号", "未绑定手机", "登录态", "登录失效", "请先登录", "凭证失效", "token 失效"): + return CategorySessionLost, true + ``` +- **问题**: + 1. 将「账号未绑定」与「登录态已失效」混在一块,划归为 `CategorySessionLost`。 + 2. 虽然 `defaultSessionLostLimit` 调到了 8,但如果某账号连续 8 次遭遇角色服务抖动,仍会被永久判死(`account.done = true`)。 + 3. 在 `retry.go:179` 中,`CategoryTooFrequent` 未包含在 `sessionAliveCategory` 中,导致账号在收到限流时 `sessionStreak` 无法被重置,连续限流中穿插的「未绑定」会产生虚假累加。 + 4. 日志里输出 `[warn] 结局 session_lost ×53(会话失效)` 造成恐慌。 +- **改进方案**: + - 新增独立分类 `CategoryRoleUnbound = "role_unbound"`(角色未绑定 / 角色服务抖动),或归入临时业务重试(类似条件未满足,但不判死)。 + - 「账号未绑定」单独抽出,不计入 `sessionStreak`,不触发 `account.done` 熔断,只执行普通退避(如 200~300ms)。 + - 真正的凭证失效(「请先登录」「登录失效」「token失效」)才保留为 `CategorySessionLost`。 + - 并在 `sessionAliveCategory` 中将 `CategoryTooFrequent` 也加入(能返回限流说明会话健全)。 + +### 2. 【高优先级】缩短单次秒杀请求的 Context 超时阈值(从 15s/10s 压缩至 1.5s~2.0s) +- **现状代码**(`internal/gui/app.go:725` 与 `internal/huya/wss_client.go:99`): + - 默认调用超时长达 10~15 秒。 + - 当服务端某台微服务卡死时,账号会 hang 住 5 秒才返回 `biz exception:-7`。在只有 9 秒生命周期的乔克秒杀中,卡 5 秒等于宣告该账号出局。 +- **改进方案**: + - 在秒杀作战期间(`RunTargets`),为单次 `ScoreExchangePrize` 设置专用的紧凑超时(例如 `1500ms` 或 `2000ms`)。 + - 若 1.5 秒未回包,立刻 `cancel` 并重试下一次,绝不让一个卡死的请求占用账号 5 秒。 + +### 3. 【中优先级】首发错峰与第一波(0~200ms)策略精细化 +- **现状**: + - 首发 300ms 错峰(`spread=300ms`, `step=8ms`)成功分散了 30 个账号。 + - 但 0~200ms 的第一发请求 80% 遭遇了「太火爆」。 +- **改进方向**: + - 第一波被限流后的重试退避:当前 `stageMultiplier` 头 2 秒乘数为 1,退避基准为 300ms。 + - 第一发 0.00s 遇到火爆的账号,在 0.35s 左右刚好打出第二发并成功抢到。 + - 可以保持当前退避节奏,但可将首轮火爆退避稍微加入微抖动(200ms~350ms),让第二波请求在 0.25s~0.50s 之间更均匀地切入放量窗口。 + +### 4. 【低优先级】同机多实例跨进程协调与 IP 限流缓释 +- **现状**: + - pc-1 单机跑了 5 个实例,共 146 个账号全部打乔克,总共发了 1,824 次请求,其中 1,078 次限流(限流比高达 59.1%)。 + - 多个独立进程之间没有共享首发错峰槽位,5 个实例的第 0 个账号在同一毫秒齐射。 +- **优化建议**: + - GUI 启动多实例时,或配置文件中支持为不同实例分配初始偏移(如 instance-1 偏移 0ms,instance-2 偏移 50ms,instance-3 偏移 100ms...),实现跨实例的宏观交错。 diff --git a/docs/seckill-optimization-roadmap.md b/docs/seckill-optimization-roadmap.md new file mode 100644 index 0000000..bd0c80e --- /dev/null +++ b/docs/seckill-optimization-roadmap.md @@ -0,0 +1,94 @@ +# huya-go 全面架构深度分析与优化路线图(对比 dygou_go) + +> **编制日期**:2026-10-18 +> **基线版本**:huya-go v0.5.3 +> **参考对标**:`/Users/yml/codes/dygou_go`(斗鱼自动化抢购系统) +> **实战支撑**:2026-10-18 5台机器 23实例 562账号实战日志 + +--- + +## 一、架构与功能全景对比矩阵 + +| 模块 / 维度 | `dygou_go`(斗鱼项目) | `huya-go`(虎牙现状) | 差距与优化潜力等级 | +|---|---|---|:---:| +| **1. 兑换请求超时控制** | 细粒度超短超时(秒级超时熔断,区分服务端超时与网络超时),单次请求绝不 hang 住 | 透传全局任务 `ctx`,底层网络超时为 10~15 秒;实战中曾出现账号被 hang 整整 5.07 秒 | 🔴 **高危 / 极高优先级** | +| **2. 错误分类与退避精度** | 细分 Transient / InFlight / RateLimited / Throttled / StockOut / Terminal;支付有专门退避阶梯 | 「账号未绑定!」被误判为 `CategorySessionLost`;`TooFrequent` 未纳入存活状态;退避阶梯较粗 | 🔴 **高危 / 极高优先级** | +| **3. 积分基线与刚性扣分对账** | `ScoreBaselineStore`(`scores.json`):抢购前建基线,抢购后自动比对 `余额差值 == 售价`,反查暗中成功单 | 仅抢购成功时单号异步刷新,无基线文件,无全局刚性对账能力,网络闪断或超时导致的暗中成交会漏单 | 🟡 **重要 / 高优先级** | +| **4. 作战战报持久化与导出** | `last_xiaodian_report.json` 保存战报,支持 GUI 一键导出 Excel / CSV,包含每账号、商品、耗时、状态 | 抢购战果仅保存在内存中,界面关闭或刷新即丢失,无 Excel / CSV 导出功能,代抢对账依赖翻日志 | 🟡 **重要 / 高优先级** | +| **5. 备选目标多级轮转 (Fallback)** | 允许配置主目标与备选目标,主目标一旦售罄(StockOut),未完成账号自动无缝切换到备选目标 | `RunTargets` 虽支持多目标,但采用同轮平铺探测,无“优先级与售罄自动降级”机制,GUI 仅能填单 PID | 🟡 **重要 / 高优先级** | +| **6. 成功战报精美长图生成** | 原生 `image/draw` + `freetype` 自动生成战报图片卡片(带标题、成功率、账号列表、耗时),支持一键发群晒单 | 无大图生成功能,用户只能手动截屏或拍照 | 🟢 **体验增强 / 中优先级** | +| **7. 跨实例同机协同错峰** | 跨平台互斥锁;支持实例级错峰参数,避免同机多开在 0.00s 齐射造成本地网卡与单 IP 限流 | 已做实例数据目录隔离,但同机多实例在 0.00s 同步发射,加剧单 IP 限流(10.18 pc-1 限流比达 60%) | 🟢 **微调优化 / 中优先级** | + +--- + +## 二、四大优化工作包详细设计 + +### 📦 工作包 1:抢购引擎核心稳态升级(消灭卡死与误杀) + +#### 1.1 单请求紧凑超时熔断(Per-Request Fast Timeout) +- **问题根源**: + 在 `internal/sniper/exchange.go` 的 `exchangeTarget` 中,调用 `client.ScoreExchangePrize(ctx, ...)` 时直接透传了外部 `ctx`。底层 WSS/HTTP 连接的超时时间长达 10~15 秒。 + 10.18 实战日志证据:账号 `1199664503824` 与 `1199668733274` 在 loop 1 遭遇服务端微服务超时,单次请求足足耗时 **5.07 秒** 才返回 `biz exception:-7`,导致账号在黄金前 5 秒彻底停滞,直接错过抢购。 +- **改进设计**: + 引入秒杀专属请求超时 `RequestTimeout`(建议默认 `1500ms ~ 2000ms`): + ```go + reqCtx, reqCancel := context.WithTimeout(ctx, cfg.RequestTimeout) + exchange, err := client.ScoreExchangePrize(reqCtx, account.UID, account.Cookie, sid, pid) + reqCancel() + ``` + 若在 1.5 秒内未收到完整响应,立刻以超时错误返回并进入短退避重试,绝不阻塞当前账号的抢购节奏。 + +#### 1.2 剥离「账号未绑定!」分类,彻底解绑会话失效 +- **问题根源**: + 在 `internal/sniper/classify.go:116` 中,把「账号未绑定」归入 `CategorySessionLost`。 + 10.18 实战中出现 914 次该提示,实证表明:同一账号在遭遇数次「未绑定」后仍能成功抢到并扣分,这纯属虎牙下游和平精英角色服务超时降级。当前代码若连续遇到 8 次会直接永久判死(`account.done = true`),且界面上频频报警会误导用户。 +- **改进设计**: + 1. 引入独立分类 `CategoryRoleUnbound = "role_unbound"`(角色未绑定 / 服务抖动)。 + 2. `classifyExchangeText` 中,「账号未绑定/未绑定账号」映射到 `CategoryRoleUnbound`,真正的凭证失效(「请先登录/登录失效/token失效」)才保留为 `CategorySessionLost`。 + 3. `CategoryRoleUnbound` 仅触发普通业务重试退避(如 200~300ms),不计入连续会话失效判死阈值(`sessionStreak`)。 + 4. 在 `retry.go:179` 的 `sessionAliveCategory` 中补充 `CategoryTooFrequent`,只要服务端返回限流,说明账号凭证依然有效,避免 `sessionStreak` 在连续限流中虚假累积。 + +--- + +### 📦 工作包 2:积分基线与刚性对账体系(借鉴 dygou_go ScoreBaselineStore) + +- **业务背景**: + 抢购高并发下,常有边缘异常:客户端断网、RPC 超时、信封解析异常,但服务端其实已经扣除了积分并将礼包发放至背包。仅凭客户端是否收到 `category=success` 会发生严重漏单! +- **改进设计**: + 1. 新增 `internal/sniper/score_baseline.go`(或 `internal/score/`): + - 数据文件:`scores.json`(保存在各实例的 `dataDir` 下)。 + - 记录每个账号的基线积分及时间戳:`{"score": 1250, "at": 1729242000}`。 + 2. **基线更新时机**: + - 用户手动点击「查询积分」时批量更新并落盘。 + - 导入/检查 Cookie 时自动更新。 + 3. **刚性对账(Verify / Reconcile)**: + - 抢购结束后(或用户随时点击「对账核对」):全量异步拉取一次所有账号的最新积分。 + - 计算差值:`diff = baseline - current`。 + - 若 `diff == target.Price`(或 `diff > 0`),即判定为“刚性扣分成功”,自动将原本标记为超时/未知的单子翻案为“成功”,补齐战报! + +--- + +### 📦 工作包 3:战报持久化与 Excel / CSV 导出 + +- **业务背景**: + 多账号操作、代抢代换必须给客户或管理员提供清晰的明细表格。当前版本任务一结束、窗口一关,明细就消失了,只能通过日志正则翻查,效率极低。 +- **改进设计**: + 1. 战报存储:每次抢购开始后,在实例数据目录下维护 `last_seckill_report.json`。 + - 字段包含:`AccountUID`、`TargetPID`、`TargetName`、`Price`、`Status`(已抢到/售罄/限流/积分不足等)、`Attempts`、`FirstTime`、`SuccessTime`、`Duration`、`Msg`。 + 2. 导出功能(在 `internal/gui/app.go` 暴露 Wails 绑定方法): + - `ExportSeckillReportCSV() (string, error)` + - `ExportSeckillReportExcel() (string, error)` + 3. 前端界面: + - 在作战表上方或「任务已结束」提示旁增加【导出战报】按钮,一键调出文件保存对话框。 + +--- + +### 📦 工作包 4:主备目标轮转(Priority Fallback)与售罄自动切换 + +- **业务背景**: + 10.18 实战显示,最火爆的怪诞乔克(13433)在 10 秒即彻底售罄,而小黄鸭(13443)和天网(13435)在 15~20 秒依然有充沛库存。目前用户必须人工判断或多开不同实例去分别打。 +- **改进设计**: + 1. 支持配置主目标(Priority 1)与备选目标(Priority 2...)。 + 2. 在 `runAccountRound` 调度中: + - 默认只对主目标发起 `exchangeTarget`。 + - 一旦主目标在当前实例被全量确认为售罄(`CategorySoldOut`),引擎自动标记主目标下线,账号无需停止,后续轮次立即自动无缝打向备选目标,把剩余的 20 秒窗口利用到底!