🤖 每日自动备份 - 2026-06-21 08:00:01

This commit is contained in:
小溪 2026-06-21 08:00:01 +08:00
parent c33d2cd0c3
commit ecd90ae9f9
4 changed files with 464 additions and 65 deletions

303
memory/2026-06-20-2243.md Normal file
View File

@ -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 的无日期行占比很高,如果要按月统计线索量,需要补充日期数据。需要我做什么处理吗?

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

View File

@ -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()

View File

@ -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<O) · L≥C
# 条件:X=1 (gate)
order_rows = []
for r in all_rows:
raw = r["raw"]
k = str(raw[10]).strip() if len(raw) > 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<O
try:
p_val = float(raw[15]) if len(raw) > 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: 构建 AX 行 ──
# ── Step 4: 构建 AW 行A-V 镜像 + W=渠道=三表Y + 无X列──
summary_rows = []
for r in order_rows:
raw = r["raw"]
# AV 原样镜像
# AV 原样镜像 (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}] ✅ 订单汇总刷新完成")