diff --git a/memory/2026-06-20-2243.md b/memory/2026-06-20-2243.md new file mode 100644 index 0000000..e78d9af --- /dev/null +++ b/memory/2026-06-20-2243.md @@ -0,0 +1,303 @@ +# Session: 2026-06-20 22:43:26 GMT+8 + +- **Session Key**: agent:main:feishu:direct:ou_7ef247331804edf255f53e3be15963f4 +- **Session ID**: 860ba688-0217-494f-aef4-c94476dee4db +- **Source**: feishu + +## Conversation Summary + +user: [media attached: /root/.openclaw/media/inbound/é_å_çº_ç_-å_å_ç---9526de19-b353-439f-945e-b88538be8c72.xlsx (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet) | /root/.openclaw/media/inbound/é_å_çº_ç_-å_å_ç---9526de19-b353-439f-945e-b88538be8c72.xlsx] +[File: /root/.openclaw/media/inbound/é_å_çº_ç_-å_å_ç---9526de19-b353-439f-945e-b88538be8c72.xlsx] +assistant: 我看到你发了一个 Excel 文件,包含三个 sheet: + +| Sheet | 销售归属 | 数据行数 | 有用户ID的行数 | +|-------|---------|---------|--------------| +| 小龙 | 姜小龙 | 1,678 | 723 | +| 吴迪 | 吴迪 | 805 | 311 | +| Sheet3 | Tom/Bob等 | 2,171 | 798 | + +请问你需要我拿这份数据做什么?比如: + +- 把这些用户ID匹配到数据库,查他们的付费/转化情况? +- 统计各销售的线索转化率? +- 其他分析? +user: [media attached: /root/.openclaw/media/inbound/é_å_çº_ç_-å_ç_ç---cc5df25a-1512-4469-a973-7574105e4471.xlsx (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet) | /root/.openclaw/media/inbound/é_å_çº_ç_-å_ç_ç---cc5df25a-1512-4469-a973-7574105e4471.xlsx] +[File: /root/.openclaw/media/inbound/é_å_çº_ç_-å_ç_ç---cc5df25a-1512-4469-a973-7574105e4471.xlsx] +assistant: 收到了两个文件,我来梳理一下: + +**文件1(线索-小龙-吴迪):** 原始销售线索数据,3个 sheet(小龙 1,678行、吴迪 805行、Sheet3 2,171行),主要是手填的线索信息。 + +**文件2(线索-成都):** 看起来是一个已经部分匹配了数据库的版本,3个 sheet(小龙 2,780行、吴迪 8,218行、成都 2,498行),列结构更完整,包含了用户ID、注册日期、下载渠道、是否下单、GMV、退款、GSV、学习进度等 🤖 自动填充列。 + +不过我注意到文件2中很多行的自动列还是空的(用户ID为 None 或"未注册")。 + +请问你需要我做什么?比如: + +- 把文件2中已有用户ID的行,补充完整的下单/付费/学习数据? +- 把文件1的用户手机号匹配到数据库,生成文件2那样的完整报表? +- 对比两个文件的数据差异? +- 其他分析? +user: 读取这两个表格,整理下销售人员的每月线索数量,并找出这两个表的差异 +assistant: 整理完成,以下是分析结果: + +--- + +## 📊 销售人员每月线索数量 + +### 文件1(线索-小龙-吴迪) + +| Sheet | 销售 | 合计 | 有日期行 | 主要月份分布 | +|-------|------|------|---------|------------| +| 小龙 | 姜小龙 | 1,678 | 162 | 1月69 / 3月56 / 2月26 / 4月10 | +| 吴迪 | 吴迪 | 805 | 730 | 5月347 / 4月218 / 6月165 | +| Sheet3 | Tom/Bob等 | 2,171 | 797 | 4月504 / 3月200 / 5月72 | + +> ⚠️ 小龙 sheet 有 1,516 行(90%)无日期;Sheet3 有 1,374 行(63%)无日期。 + +### 文件2(线索-成都) + +| Sheet | 销售 | 合计 | 有效行 | 主要月份分布 | +|-------|------|------|--------|------------| +| 小龙 | 小龙 | 2,780 | 1,259 | 4月43 / 5月35 / 3月33 | +| 吴迪 | 吴迪 | 8,218 | 751 | 5月42 / 4月15 / 6月12 | +| 成都 | Tom 1,148 / Bob 1,073 | 2,498 | 2,221 | 4月96 / 5月65 / 3月48 | + +> ⚠️ 文件2 小龙和吴迪 sheet 有大量空行(销售归属为空),看起来是预留模板行。 + +--- + +## 🔍 两个文件的核心差异 + +### 1. 列结构完全不同 + +| | 文件1 | 文件2 | +|---|---|---| +| 定位 | 原始线索录入表 | 增强版(含数据库自动填充) | +| 核心列 | 跟进记录、体验进度、用户状态、课史 | 下单数据、GMV/GSV、学习进度、下载渠道 | +| 独有列 | 用户ip、当前状态、体验进度、推荐人、备注 | 是否下单、成交渠道、产品、GMV、退款、GSV、激活课程、学习时长 | + +### 2. 数据量差异 + +| Sheet | 文件1 | 文件2 | 差异 | +|-------|-------|-------|------| +| 小龙 | 1,678 | 2,780 | +1,102(多为空行) | +| 吴迪 | 805 | 8,218 | +7,413(多为空行) | +| Sheet3/成都 | 2,171 | 2,498 | +327 | + +### 3. 手机号 & 用户ID 匹配情况 + +| Sheet | 手机号共有 | 仅文件1 | 仅文件2 | 用户ID共有 | 仅文件1 | 仅文件2 | +|-------|----------|---------|---------|----------|---------|---------| +| 小龙 | 948 | **298** | 5 | 551 | **167** | 40 | +| 吴迪 | 557 | 14 | 14 | 301 | 6 | **85** | +| Sheet3/成都 | 1,618 | 8 | 20 | 743 | 52 | **371** | + +### 4. 文件2 的 🤖 自动填充数据(以小龙为例) + +| 字段 | 有数据行数 | +|------|----------| +| 用户ID | 593 | +| 下载渠道 | 587 | +| 是否下单 | 118 | +| 下单金额(GMV) | 118 | +| 退款金额 | 9 | +| 激活课程 | 108 | +| 学习进度 | 445 | + +--- + +### 总结 + +1. **文件1 是原始线索表**,侧重销售跟进过程(跟进记录、体验状态),但大量行缺日期 +2. **文件2 是增强版**,增加了数据库自动匹配的下单/付费/学习数据,但小龙和吴迪 sheet 充斥大量空模板行 +3. **文件1 小龙 sheet 有 298 个手机号不在文件2 中**,可能是遗漏或已删除的线索 +4. **文件2 成都 sheet 比文件1 Sheet3 多了 371 个用户ID**,说明数据库匹配更完整 +5. 两个文件的日期字段格式不同(文件1 用 `2026.1.7` 文本格式,文件2 用 Excel 日期序列号),导致文件2 大量行日期解析失败 + +需要我进一步处理吗?比如把文件1中遗漏的298个手机号补到文件2,或者用数据库补充缺失的下单/学习数据? +user: 分别统计下两个表里面,各个销售每个月的线索数量 +assistant: 以下是两个表各销售每月线索数量的汇总: + +--- + +## 文件1(线索-小龙-吴迪) + +### 小龙 Sheet(共 1,678 行) + +| 销售 | 2025-12 | 2026-01 | 2026-02 | 2026-03 | 2026-04 | 无日期 | **合计** | +|------|---------|---------|---------|---------|---------|--------|---------| +| 姜小龙 | 1 | 69 | 26 | 56 | 10 | 1,453 | **1,615** | +| 空 | 0 | 0 | 0 | 0 | 0 | 63 | **63** | + +### 吴迪 Sheet(共 805 行) + +| 销售 | 2026-04 | 2026-05 | 2026-06 | 无日期 | **合计** | +|------|---------|---------|---------|--------|---------| +| 吴迪 | 218 | 347 | 165 | 0 | **730** | +| 空 | 0 | 0 | 0 | 75 | **75** | + +### Sheet3(共 2,171 行) + +| 销售 | 2025-08 | 2025-09 | 2025-10 | 2025-11 | 2025-12 | 2026-01 | 2026-02 | 2026-03 | 2026-04 | 2026-05 | 无日期 | **合计** | +|------|---------|---------|---------|---------|---------|---------|---------|---------|---------|---------|--------|---------| +| Bob | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 97 | 67 | 0 | 125 | **291** | +| Tom | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 99 | 84 | 0 | 146 | **331** | +| 已支付 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 67 | 15 | 47 | **130** | +| 明确拒绝 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 12 | 0 | 14 | **27** | +| 微信 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 2 | **3** | +| 重中之重 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 0 | 0 | **3** | +| 在学不回复 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | **1** | +| 空 | 2 | 0 | 2 | 1 | 4 | 7 | 1 | 2 | 270 | 57 | 1,039 | **1,385** | + +--- + +## 文件2(线索-成都) + +### 小龙 Sheet(共 2,779 行,不含表头) + +| 销售 | 2025-09 | 2025-10 | 2026-02 | 2026-03 | 2026-04 | 2026-05 | 2026-06 | 无日期 | **合计** | +|------|---------|---------|---------|---------|---------|---------|---------|--------|---------| +| 小龙 | 1 | 1 | 2 | 33 | 43 | 35 | 13 | 1,131 | **1,259** | +| 空 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1,520 | **1,520** | + +### 吴迪 Sheet(共 8,217 行,不含表头) + +| 销售 | 2025-10 | 2025-12 | 2026-04 | 2026-05 | 2026-06 | 无日期 | **合计** | +|------|---------|---------|---------|---------|---------|--------|---------| +| 吴迪 | 1 | 2 | 15 | 42 | 12 | 679 | **751** | +| 空 | 0 | 0 | 0 | 0 | 0 | 7,466 | **7,466** | + +### 成都 Sheet(共 2,497 行,不含表头) + +| 销售 | 2026-03 | 2026-04 | 2026-05 | 2026-06 | 无日期 | **合计** | +|------|---------|---------|---------|---------|--------|---------| +| Tom | 25 | 46 | 35 | 3 | 1,039 | **1,148** | +| Bob | 23 | 50 | 30 | 2 | 968 | **1,073** | +| 空 | 0 | 0 | 0 | 0 | 276 | **276** | + +--- + +### ⚠️ 说明 + +- 两个文件都有大量"无日期"行,文件1 小龙 sheet 无日期占比高达 90%,文件2 小龙/吴迪 sheet 也有大量空模板行 +- Sheet3 的"销售归属"列存在不规范值(如"已支付""明确拒绝"等被填入了销售归属列),实际有效销售为 Tom 和 Bob +- 文件2 成都 sheet 的销售归属比文件1 Sheet3 规范,仅 Tom/Bob 两人 +user: [media attached: /root/.openclaw/media/inbound/é_å_çº_ç_-å_å_ç---5cf8c6e8-03a3-41d2-aa38-2a9d2e1fa491.xlsx (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet) | /root/.openclaw/media/inbound/é_å_çº_ç_-å_å_ç---5cf8c6e8-03a3-41d2-aa38-2a9d2e1fa491.xlsx] +[File: /root/.openclaw/media/inbound/é_å_çº_ç_-å_å_ç---5cf8c6e8-03a3-41d2-aa38-2a9d2e1fa491.xlsx] +assistant: 好的,这是第三个文件的分析,以及三个文件的对比: + +--- + +## 文件3 — 各销售每月线索数量 + +### 小龙 Sheet(共 1,333 行) + +| 销售 | 2026-03 | 2026-04 | 无日期 | **合计** | +|------|---------|---------|--------|---------| +| 姜小龙 | 47 | 9 | 1,214 | **1,270** | +| 空 | 0 | 0 | 63 | **63** | + +### 吴迪 Sheet(共 805 行) + +| 销售 | 2026-04 | 2026-05 | 2026-06 | 无日期 | **合计** | +|------|---------|---------|---------|--------|---------| +| 吴迪 | 218 | 347 | 165 | 0 | **730** | +| 空 | 0 | 0 | 0 | 75 | **75** | + +### 成都 Sheet(共 2,171 行) + +| 销售 | 2025-08 | 2025-09 | 2025-10 | 2025-11 | 2025-12 | 2026-01 | 2026-02 | 2026-03 | 2026-04 | 2026-05 | 无日期 | **合计** | +|------|---------|---------|---------|---------|---------|---------|---------|---------|---------|---------|--------|---------| +| Tom | 1 | 0 | 2 | 0 | 2 | 2 | 2 | 101 | 249 | 30 | 724 | **1,113** | +| Bob | 1 | 1 | 1 | 1 | 3 | 5 | 0 | 99 | 254 | 42 | 625 | **1,032** | +| 微信 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 2 | **3** | +| 空 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 23 | **23** | + +--- + +## 🔍 三个文件对比 + +### 行数对比 + +| Sheet | 文件1 | 文件2 | 文件3 | +|-------|-------|-------|-------| +| 小龙 | 1,678 | 2,780 | **1,333** | +| 吴迪 | 805 | 8,218 | **805** | +| Sheet3/成都 | 2,171 | 2,498 | **2,171** | + +### 关键差异 + +**文件3 vs 文件1:** + +| 变化点 | 说明 | +|--------|------| +| 小龙 -345行 | 姜小龙从 1,615 → 1,270,丢失了 2025-12、2026-01、2026-02 全部数据,3月少了9条、4月少了1条 | +| 吴迪 完全一致 | 805行,数据无变化 | +| 成都 Sheet 销售归属已清理 | 文件1中"已支付""明确拒绝""重中之重""在学不回复"等异常值被归入 Tom/Bob,空销售从 1,385 → 23 | +| 成都 Sheet 月度分布更完整 | Bob 和 Tom 的线索覆盖了 2025-08 到 2026-05,比文件1多了很多早期数据 | + +**文件3 vs 文件2:** + +| 变化点 | 说明 | +|--------|------| +| 小龙少 1,447行 | 文件2有大量空模板行(1,520行空),文件3更精简 | +| 吴迪少 7,413行 | 同上,文件2的吴迪 sheet 有 7,466 行空模板 | +| 成都少 327行 | 文件2多了部分用户ID匹配数据 | +| 无 🤖 自动填充列 | 文件3和文件1结构一致,没有文件2的下单/GMV/学习数据列 | + +--- + +### 总结 + +- **文件1** = 原始线索表,销售归属列有脏数据 +- **文件2** = 增强版,加了数据库自动匹配列,但充斥大量空模板行 +- **文件3** = 文件1的清理版,销售归属已规范化,但小龙 sheet 丢失了 2025-12 ~ 2026-02 的数据 + +需要我进一步做什么?比如用文件3的数据去数据库匹配付费转化情况? +user: 我重新整理了这个表,看看读取上还有问题不 +assistant: 发现一个问题:**小龙 sheet 的日期格式是 `2026/3.1`(斜杠+点混用)**,导致 1,277 行日期解析失败。让我修复后重新统计: + + +assistant: 修复了日期解析(小龙 sheet 用了 `2026/3.1` 这种混合格式),现在读取正常了。总结: + +--- + +## ✅ 文件3 读取结果 + +| Sheet | 总行数 | 有日期 | 无日期 | 状态 | +|-------|--------|--------|--------|------| +| 小龙 | 1,333 | 58 | 1,275 | ⚠️ 95.6% 无日期 | +| 吴迪 | 805 | 730 | 75 | ✅ 正常 | +| 成都 | 2,171 | 797 | 1,374 | ⚠️ 63.3% 无日期 | + +### 小龙 Sheet — 仅 58 行有日期 + +| 销售 | 2026-03 | 2026-04 | 无日期 | **合计** | +|------|---------|---------|--------|---------| +| 姜小龙 | 49 | 9 | 1,212 | **1,270** | +| 空 | 0 | 0 | 63 | **63** | + +### 吴迪 Sheet — 正常 + +| 销售 | 2026-04 | 2026-05 | 2026-06 | 无日期 | **合计** | +|------|---------|---------|---------|--------|---------| +| 吴迪 | 218 | 347 | 165 | 0 | **730** | +| 空 | 0 | 0 | 0 | 75 | **75** | + +### 成都 Sheet — 销售归属已清理干净 + +| 销售 | 2025-08~2026-02 | 2026-03 | 2026-04 | 2026-05 | 无日期 | **合计** | +|------|-----------------|---------|---------|---------|--------|---------| +| Tom | 9 | 101 | 249 | 30 | 724 | **1,113** | +| Bob | 12 | 99 | 254 | 42 | 625 | **1,032** | +| 微信 | 0 | 0 | 1 | 0 | 2 | **3** | +| 空 | 0 | 0 | 0 | 0 | 23 | **23** | + +--- + +### ⚠️ 仍存在的问题 + +1. **小龙 sheet 大量行缺日期**:1,275 行(95.6%)的"线索进线日期"为空,只有 3-4 月的 58 条有日期。之前的 2025-12 ~ 2026-02 数据确实丢失了 +2. **成都 sheet 超半数无日期**:1,374 行(63.3%)缺进线时间 + +这两个 sheet 的无日期行占比很高,如果要按月统计线索量,需要补充日期数据。需要我做什么处理吗? diff --git a/output/daren_refund_curve.png b/output/daren_refund_curve.png new file mode 100644 index 0000000..1855860 Binary files /dev/null and b/output/daren_refund_curve.png differ diff --git a/scripts/fix_beijing_pilot_finance.py b/scripts/fix_beijing_pilot_finance.py new file mode 100644 index 0000000..84a5237 --- /dev/null +++ b/scripts/fix_beijing_pilot_finance.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +""" +北京试点财务表 4m6Ejm 全表复核修正 +列映射: N=GMV, O=退款金额, P=GSV, X=订单号, Y=有效订单, Z=渠道归属 +""" +import json, time, requests, os + +CRED_DIR = "/root/.openclaw/credentials/xiaoxi" +SPREADSHEET_TOKEN = "NoZqsFi47hIOHEt9j8WcfRtbnug" +SHEET_ID = "4m6Ejm" + +def get_token(): + with open(os.path.join(CRED_DIR, "config.json")) as f: + cfg = json.load(f) + resp = requests.post( + "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", + json={"app_id": cfg["apps"][0]["appId"], "app_secret": cfg["apps"][0]["appSecret"]}, + timeout=15 + ) + return resp.json()["tenant_access_token"] + +def put_values(token, sheet_id, range_str, values): + url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/values" + body = {"valueRange": {"range": f"{sheet_id}!{range_str}", "values": values}} + for attempt in range(3): + r = requests.put(url, headers={ + "Authorization": f"Bearer {token}", + "Content-Type": "application/json" + }, json=body, timeout=30) + result = r.json() + if result.get("code") == 0: + return True + print(f" Retry {attempt+1}: {result.get('msg','')}") + time.sleep(1) + print(f" FAILED {range_str}") + return False + +def main(): + token = get_token() + fixes = [] + + # === 已退费: Y=0, P→0 (GSV=0) === + # r3 陈kelly: status=4, refund=1999 + fixes.append((3, "P", [[0]])) + # r9 xhx: status=4, refund=1999 + fixes.append((9, "P", [[0]])) + # r10 跳跳糖: status=4, refund=1999 + fixes.append((10, "P", [[0]])) + # r25 琪-建筑: status=4, refund=599 + fixes.append((25, "P", [[0]])) + + # === 有效订单: Y=0→1, O→0, P→GSV, 补Z === + # r11 Cathy: status=3, 1999, 直购 + fixes.append((11, "N", [["1999"]])) + fixes.append((11, "O", [[0]])) + fixes.append((11, "P", [["1999"]])) + fixes.append((11, "Y", [[1]])) + fixes.append((11, "Z", [["直购"]])) + + # r12 tingting: status=3, 599, 端内 + fixes.append((12, "N", [["599"]])) + fixes.append((12, "O", [[0]])) + fixes.append((12, "P", [["599"]])) + fixes.append((12, "Y", [[1]])) + fixes.append((12, "Z", [["端内"]])) + + # r17 MIYU: status=3, 1999, 直购 + fixes.append((17, "N", [["1999"]])) + fixes.append((17, "O", [[0]])) + fixes.append((17, "P", [["1999"]])) + fixes.append((17, "Y", [[1]])) + fixes.append((17, "Z", [["直购"]])) + + # r18 💋👩👧💋: status=3, 1999, 端内 (已确认) + fixes.append((18, "O", [[0]])) + fixes.append((18, "Y", [[1]])) + + # r19 心安就好: status=3, 1999, 直购 (已确认) + fixes.append((19, "O", [[0]])) + fixes.append((19, "Y", [[1]])) + + # r20 木木: status=3, 1999, 直购 + fixes.append((20, "N", [["1999"]])) + fixes.append((20, "O", [[0]])) + fixes.append((20, "P", [["1999"]])) + fixes.append((20, "Y", [[1]])) + fixes.append((20, "Z", [["直购"]])) + + # r21 柏文: 2026010422001499951430352915, status=3, 1999, 端内 + fixes.append((21, "N", [["1999"]])) + fixes.append((21, "O", [[0]])) + fixes.append((21, "P", [["1999"]])) + fixes.append((21, "X", [["2026010422001499951430352915"]])) + fixes.append((21, "Y", [[1]])) + fixes.append((21, "Z", [["端内"]])) + + # r22 琉璃仙: status=3, 1999, 直购 + fixes.append((22, "O", [[0]])) + fixes.append((22, "Y", [[1]])) + + # r24 悦宝爱阳光: status=3, 1999, 直购 + fixes.append((24, "O", [[0]])) + fixes.append((24, "Y", [[1]])) + + # r27 coco: status=3, 599, 端内 + fixes.append((27, "N", [["599"]])) + fixes.append((27, "O", [[0]])) + fixes.append((27, "P", [["599"]])) + fixes.append((27, "Y", [[1]])) + fixes.append((27, "Z", [["端内"]])) + + print(f"共 {len(fixes)} 处修正") + for row, col, vals in fixes: + rng = f"{col}{row}:{col}{row}" + if put_values(token, SHEET_ID, rng, vals): + print(f" ✓ {rng} = {vals[0]}") + else: + print(f" ✗ {rng} FAILED") + time.sleep(0.15) + + print("\n=== 修正完成 ===") + print("\n⚠️ r13 笑看风云(UID 11824): 表内 trade_no=4200002979202510051839311872 DB不存在") + print(" 该账号实际: 4200002979202512297931190703(599, 12/29) + 4200003119202604279087832566(1499, 4/27)") + print(" 请确认正确订单号后手动修正") + +if __name__ == "__main__": + main() diff --git a/scripts/refresh_order_summary.py b/scripts/refresh_order_summary.py index 257691f..ecedd90 100644 --- a/scripts/refresh_order_summary.py +++ b/scripts/refresh_order_summary.py @@ -154,14 +154,14 @@ def main(): print(f"[{datetime.now():%Y-%m-%d %H:%M:%S}] 订单汇总全量刷新 启动") token = get_token() - # ── Step 1: 读取销售三表 ── + # ── Step 1: 读取销售三表(含 X/Y 列)── all_rows = [] for sid, name in SALES_SHEETS.items(): print(f"Reading {name}...") - vals = read_sheet(token, sid, "A3:V10000") + vals = read_sheet(token, sid, "A3:Y10000") filtered = [] for i, row in enumerate(vals): - while len(row) < 22: + while len(row) < 25: row.append("") b = str(row[1]).strip() if row[1] else "" e = str(row[4]).strip() if row[4] else "" @@ -169,7 +169,7 @@ def main(): if b or e or h: filtered.append({ "sid": sid, "name": name, "row": i + 3, - "raw": row[:22], # A-V + "raw": row[:25], # A-Y }) print(f" {len(filtered)} non-empty rows") all_rows.extend(filtered) @@ -177,82 +177,51 @@ def main(): print(f"Total rows: {len(all_rows)}") # ── Step 2: 筛选进订单汇总的行 ── - # 条件:K=是 · O>0 · 非全额退(P空或P 10 and raw[10] else "" - if k != "是": - continue - - # O > 0 + # X 列 (index 23) = 1 try: - o_val = float(raw[14]) if len(raw) > 14 and raw[14] not in (None, "") else 0 + x_val = int(float(raw[23])) if len(raw) > 23 and raw[23] not in (None, "") else 0 except (ValueError, TypeError): - o_val = 0 - if o_val <= 0: + x_val = 0 + if x_val != 1: continue - # 非全额退: P空或P 15 and raw[15] not in (None, "") else 0 - except (ValueError, TypeError): - p_val = 0 - if p_val > 0 and p_val >= o_val: - # 全额退 → 不进订单表 - continue - - # L ≥ C (C为空时跳过此检查,如直购用户无进线日期) - c_str = str(raw[2]).strip() if len(raw) > 2 and raw[2] else "" - l_str = str(raw[11]).strip() if len(raw) > 11 and raw[11] else "" - c_date = parse_date(c_str) - l_date = parse_date(l_str) - if c_date is not None and not date_le(c_date, l_date): - continue - - # 通过所有条件 order_rows.append(r) print(f"Order rows after filter: {len(order_rows)}") - # ── Step 2.5: 去重(同一人可能在三表中出现多次)── - # 按 (A销售归属, B微信昵称, O下单金额, P退款金额, L下单日期) 去重 - seen = set() - deduped = [] + # ── Step 2.5: 去重(同 UID 多表出现,保留行号最小)── + uid_best = {} for r in order_rows: raw = r["raw"] - a = str(raw[0]).strip() if raw[0] else "" - b = str(raw[1]).strip() if len(raw) > 1 and raw[1] else "" - o = str(raw[14]).strip() if len(raw) > 14 and raw[14] else "" - p = str(raw[15]).strip() if len(raw) > 15 and raw[15] else "" - l = str(raw[11]).strip() if len(raw) > 11 and raw[11] else "" - key = (a, b, o, p, l) - if key not in seen: - seen.add(key) - deduped.append(r) - dup_count = len(order_rows) - len(deduped) - if dup_count > 0: - print(f" Removed {dup_count} duplicate rows") - order_rows = deduped + uid = str(raw[7]).strip() if len(raw) > 7 and raw[7] not in (None, "") else "" + try: + uid = str(int(float(raw[7]))) + except: + pass + if not uid: + continue + if uid not in uid_best or r["row"] < uid_best[uid][0]: + uid_best[uid] = (r["row"], r) + order_rows = [v[1] for v in uid_best.values()] + print(f" After UID dedup: {len(order_rows)} rows") - # ── Step 3: 按 L 下单日降序 ── - order_rows.sort(key=lambda r: str(r["raw"][11]) if len(r["raw"]) > 11 and r["raw"][11] else "", reverse=True) + # ── Step 3: 按 K 下单日降序 ── + order_rows.sort(key=lambda r: str(r["raw"][10]) if len(r["raw"]) > 10 and r["raw"][10] else "", reverse=True) - # ── Step 4: 构建 A–X 行 ── + # ── Step 4: 构建 A–W 行(A-V 镜像 + W=渠道=三表Y + 无X列)── summary_rows = [] for r in order_rows: raw = r["raw"] - # A–V 原样镜像 + # A–V 原样镜像 (indices 0-21) new_row = list(raw[:22]) - # W: 渠道归属(基于 M 成交渠道) - m_channel = str(raw[12]).strip() if len(raw) > 12 and raw[12] else "" - sales_name = str(raw[0]).strip() if len(raw) > 0 and raw[0] else "" - w = classify_w_channel(m_channel, sales_name) - new_row.append(w) - - # X: 有效成单 = 1 - new_row.append(1) + # W: 渠道归属 = 三表 Y 列 (index 24) + y_val = str(raw[24]).strip() if len(raw) > 24 and raw[24] not in (None, "") else "" + new_row.append(y_val) summary_rows.append(new_row) @@ -262,19 +231,19 @@ def main(): print("Writing to 订单汇总...") writer = FeishuSheetWriter(SPREADSHEET_TOKEN, token) - # 先清空旧数据区(26 列,自动计算批大小 ≤ 4400 格/批) - writer.clear(SUMMARY_SHEET, start_row=3, end_row=2000, cols=26) + # 先清空旧数据区(23 列 A-W,自动计算批大小 ≤ 4400 格/批) + writer.clear(SUMMARY_SHEET, start_row=3, end_row=2000, cols=23) time.sleep(0.5) - # 写入新数据(24 列 A-X,自动分批) + # 写入新数据(23 列 A-W,自动分批) total = len(summary_rows) - writer.write(SUMMARY_SHEET, start_row=3, rows=summary_rows, cols=24) + writer.write(SUMMARY_SHEET, start_row=3, rows=summary_rows, cols=23) # ── Step 6: 清除多余旧行 ── existing = read_sheet(token, SUMMARY_SHEET, "A3:A4000") old_count = len([r for r in existing if r and any(c for c in r if c)]) if old_count > total: - writer.clear(SUMMARY_SHEET, start_row=3 + total, end_row=3 + old_count - 1, cols=24) + writer.clear(SUMMARY_SHEET, start_row=3 + total, end_row=3 + old_count - 1, cols=23) print(f"[{datetime.now():%Y-%m-%d %H:%M:%S}] ✅ 订单汇总刷新完成")