# 超级仓库 SuperVault · 已售统计报告文档 > 参照得卡 DECA `stats/daily_report.py` 移植到新平台 super_vault,适配「自营单商家 + 主播维度」。 > 生成日期:2026/08/14 运行环境:Python 3.12.10 ## 1. 目标信息 - **数据源**:`super_vault_product_record`(已售拼团商品)/ `super_vault_report_record`(拆卡报告) - **数据库**:`crawler @ 100.64.0.25:3306`(读运行目录 `application.yml`) - **数据目标**:产出与得卡同款「已售统计报告」Excel(单 Sheet 分区),字段:销售额 / 成团数 / 参与人数 / 均拼单价 / 人均消费,另出每条组队明细。 - **交付物**: - `stats/super_vault_his_report.py` —— 报告脚本(累计/多口径统计报告) - `stats/super_vault_stats.sql` —— 可在 Navicat 单独跑的等价 SQL - `stats/超级仓库已售统计报告_20251230-20260812.xlsx` —— 本次结果 ## 2. 口径与字段映射(得卡 → 新平台) | 语义 | 得卡 deca | 新平台 super_vault | 说明 | |---|---|---|---| | 商品唯一 id | `product_code` | `pid` | | | 商家 | `merchant_user_id` / `merchant_name` | `anchor_id` / `anchor_username` | **自营,全站算一个商家**,主播仅作二级拆分 | | 团名 | `title` | `title` | | | 系列/类型 | `series_name` / `spec_name` | `type_name`(卡种) / `standard_name`(规格) | | | 单价 | `unit_price` | `sign_price` | | | 已售份数 / 总份数 | `sold_count` / `card_count` | `sold_count` / `count` | | | 团总额 | `team_total_amount` | `total_price` | 团成交总额 | | 成交时间 / 开售时间 | `completed_at` / `sale_start_at` | `completion_time` / `sold_time` / `sell_time` | 完成态才有 `completion_time`;`sold_time`(售罄成交时刻)由更新任务从 `detail.soldTime` 补采 | | 回放 | `replay_url` | `vod_url` | 未入表格列 | | 中卡用户(参与人数) | `report.hit_user_nickname` | `report.user_name` | 去重近似参团人头 | **核心口径**: - 统计范围 = **`sold_count>0` 且 `status NOT IN (0,1,2,3)`**:剔除未开卖(sold=0) 与 status 0/1/2/3(未开始/预售/进行中等未成交态),只留 status 4/6/7/8/9/10/12 等有效成交态。(早期误用 `status=9` 会漏掉待发货团,导致时间只到 07-26,已修正。) - 主播维度**按 `anchor_username` 分组**:同名不同 `anchor_id`(如两个「北京小周」)合并为同一位主播。 - 销售额 = `SUM(sign_price * count)`(单价 × 总份数 = 满仓总价;**随机卡种/未售罄团会高于实收 `total_price`**,如 `pid=2810` 高约 70 万。如需实收改回 `COALESCE(total_price, sold_count*sign_price)`)。 - 成团数 = 该口径下的拼团商品数;参与人数 = 拆卡报告 `user_name` 去重(平台跨全部商品去重,主播按各自商品去重,故各主播逐个相加 ≥ 平台)。 - 均拼单价 = 销售额/成团数;人均消费 = 销售额/参与人数(中卡近似,偏高,仅供参考)。 - 明细「参与人数(本团)」= 该团拆卡报告 `user_name` 去重(中卡近似),口径与汇总一致、拆到单团。 - **成交时间口径** = `COALESCE(completion_time, sold_time, sell_time)`:完成时间(发货完成态才有) → 售罄成交时刻(`sold_time`) → 开售时间 依次兜底。待发货团(status=8)多无 `completion_time` 但有 `sold_time`,故成交时间/售卖时长覆盖率大幅提升(`soldTime` 实测覆盖约 98%,仅个别早期团为空)。 ## 3. 报告结构(单 Sheet 分区) 1. **一、平台汇总(自营·全站累计)**:主播数 + 5 项指标(竖排)。 2. **二、各主播汇总**:每主播一行,按销售额倒序。 3. **三、各主播每条组队明细**:按主播销售额倒序分块,每块内按总金额倒序。明细列(13 列):序号 / 团名 / 编号 / 卡种 / 规格 / 单价 / 总份数 / 进度% / 总金额 / **参与人数(本团)** / 开售时间 / 成交时间 / 售卖时长。 本次结果概览(口径:`sold>0` 且 `status∉{0,1,2,3}`,金额=单价×总份数;成交/开售时间 2025-12-30 ~ 2026-08-14): - 平台:主播数 7 · 销售额 **¥42,337,118.01** · 成团 927 · 参与 2693 人 · 均拼单价 ¥45,671 · 人均消费 ¥15,721。 - 主播销售额排序:郑宇航(1213万) > Jerry(1183万) > 金豆豆(977万) > 刘畅(453万) > Wqi(332万) > 石头哥(72万) > 北京小周(4万)。 ## 4. 与得卡版的差异(因平台结构不同而砍/改) - **去掉**「商家数 / 其他商家汇总 / 重点商家」——自营单商家,改以主播为二级维度。 - **去掉**「魔都真实买家(buy_record)」「进度里程碑(onsale 进度快照)」——新平台无这两张表,参与人数统一用拆卡报告近似。 - **统计口径**:得卡按 `completed_at` 时间窗;新平台按 `sold_count>0 且 status NOT IN(0,1,2,3)` 筛有效成交团,销售额按 单价×总份数,主播按名字合并。 ## 5. 统计窗口开关 脚本顶部 `WIN_MODE`: - `"all"`(默认):有效成交团累计(`sold_count>0` 且 `status NOT IN(0,1,2,3)`)。 - `"daily"`:成交锚点 `COALESCE(completion_time, sold_time, sell_time) ∈ [昨天17:00, 今天03:00]`。 - `"range"`:显式 `STAT_START ~ STAT_END`,锚点同上。 ## 6. 运行方式 ```bash # 从项目根目录运行(cwd=根目录,mysql_pool 读根目录 application.yml) cd D:\work\2026-01-28(cxx_spider) python stats/super_vault_his_report.py # 产物落在 stats/ 目录,文件名带窗口标签(如 超级仓库已售统计报告_20251230-20260812.xlsx) ``` - 定时:`schedule_task()` 每天 09:20 跑一次(当前 `__main__` 走一次性 `main()`)。 - 企微推送:`SEND_WECHAT=False`(本项目暂无 `auto_send_wx_msg` 模块,接入后置 True 复用)。 ## 7. 踩坑记录 - **别拿 status=9 当「已售」**:平台是「售罄成交 → 待发货 → 完成(status=9)」流程,只有走到 9 才回填 `completion_time`。用 `status=9` 会漏掉 8 月已售罄但仍在待发货态的团(时间被卡在 07-26)。本表整表即已售,全表统计即可。 - **金额别用 `sign_price×count` 硬算**:随机卡种团每张卡价不同,`total_price` 才是精算总额;用 `COALESCE(total_price, …)` 优先取 `total_price`。 - **口径收敛过程**:整表 1170 → 剔除 sold=0(占位/预售,195 个)→ 再剔除 status 0/1/2/3(未成交态)→ 最终 **927 个有效成交团**。金额口径也从 `COALESCE(total_price, sold*sign)` 改为 **`sign_price*count`(单价×总份数=满仓货值)**——按主公口径统计"标准货值"而非实收;随机卡种/未售罄团满仓价会高于实收 `total_price`,如需实收改回 COALESCE。 - **completion_time 缺失靠 sold_time 补**:只有 status=9 完成团才回填 `completion_time`,大量待发货团(status=8)已售罄成交但无 `completion_time`。detail 接口的 `soldTime`(售罄成交时刻)几乎都有值(实测 50 抽 49),已在 `super_vault_daily_spider.py` 的更新任务里补采到新列 `sold_time`;报告成交时间用 `COALESCE(completion_time, sold_time, sell_time)`。注意 `soldTime` 不是 detail 顶层就一定有——早期老团(如 2025-12 的 `pid=1639`)为空,这类退回 `sell_time`。 - **INSERT IGNORE 固化 → 加更新任务**:列表接口 `INSERT IGNORE` 只增不改,商品首次预售入库后 `sign_price/sold_count/status/completion_time/sold_time/vod_url` 等即便平台更新也不回写。`super_vault_daily_spider.py` 新增 `update_stale_products`:对 `status!=9` 或缺直播信息/`sold_time` 的团逐个查 `detail` 刷新,每日随爬虫跑。 - **时间字段转文本再写 Excel**:`completion_time/sold_time/sell_time` 为 datetime,写入前统一 `strftime` 转字符串,避免 openpyxl 日期序列/格式错乱。 - **合并同名主播**:`anchor_id=2` 与 `4` 都叫「北京小周」,已改按 `anchor_username` 分组合并为一位主播(注意:若不同人恰好同名会被并到一起,本数据无此情况)。 - **Python 版本按实测写**:同项目老爬虫头部写 3.10.8 是旧值,实测环境为 3.12.10。 ## 8. 举一反三 - 新增维度只需在 `SUMMARY_HEADERS` / `DETAIL_COLS` 加列 + 对应 SQL 取数,样式函数(`_write_summary_block` / `_write_details`)自动复用。 - 若日后平台补上「真实买家/进度快照」表,可仿得卡魔都扩展明细(参与人数真实化 + 进度里程碑列)增强本报告。 - 同一套骨架(连接池 + 分区 Excel + 主播/商家维度)可平移到其它自营/多商家卡牌拼团平台,仅改字段映射与统计口径即可。