146 lines
5.2 KiB
Python
146 lines
5.2 KiB
Python
#!/usr/bin/env python3
|
|
"""同步微伴线索到销售表,去重后追加"""
|
|
import json, requests, os, sys
|
|
from collections import defaultdict
|
|
|
|
CRED_DIR = "/root/.openclaw/credentials/xiaoxi"
|
|
SPREADSHEET_TOKEN = "NoZqsFi47hIOHEt9j8WcfRtbnug"
|
|
WEIBAN_FILE = "/tmp/weiban_20260603.xlsx"
|
|
|
|
# Sheet IDs
|
|
SHEET_IDS = {"小龙": "qJF4I", "吴迪": "f975f0"}
|
|
|
|
# 微伴客服 → 销售映射
|
|
CS_MAP = {"益达老师": "小龙", "吴迪": "吴迪"}
|
|
|
|
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 read_sheet(token, sheet_id, range_str):
|
|
resp = requests.get(
|
|
f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/values/{sheet_id}!{range_str}",
|
|
headers={"Authorization": f"Bearer {token}"}, timeout=30)
|
|
data = resp.json()
|
|
if data.get("code") != 0:
|
|
print(f" Read error: {data}")
|
|
return []
|
|
return data["data"]["valueRange"]["values"]
|
|
|
|
def append_rows(token, sheet_id, rows):
|
|
"""Append rows to sheet using append API"""
|
|
url = f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/values_append"
|
|
body = {"valueRange": {"range": f"{sheet_id}!A:K", "values": rows}}
|
|
resp = requests.post(url, headers={
|
|
"Authorization": f"Bearer {token}",
|
|
"Content-Type": "application/json"
|
|
}, json=body, timeout=30)
|
|
r = resp.json()
|
|
if r.get("code") != 0:
|
|
print(f" Append error: {r}")
|
|
return False
|
|
return True
|
|
|
|
def main():
|
|
token = get_token()
|
|
|
|
# Step 1: Parse 微伴 data
|
|
print("=== Step 1: 解析微伴数据 ===")
|
|
import openpyxl
|
|
wb = openpyxl.load_workbook(WEIBAN_FILE, read_only=True)
|
|
ws = wb['Sheet1']
|
|
|
|
weiban_entries = []
|
|
for row in ws.iter_rows(min_row=6, values_only=True):
|
|
if row[0] is None:
|
|
continue
|
|
add_time = str(row[13]) if row[13] else ''
|
|
if not add_time.startswith('2026-06'):
|
|
continue
|
|
|
|
kefu = row[6] # 所属客服
|
|
sales = CS_MAP.get(kefu)
|
|
if not sales:
|
|
continue
|
|
|
|
# Parse date: "2026-06-01 12:34:56" → "6月1日"
|
|
from datetime import datetime
|
|
try:
|
|
dt = datetime.strptime(add_time, "%Y-%m-%d %H:%M:%S")
|
|
date_str = f"{dt.month}月{dt.day}日"
|
|
except:
|
|
date_str = add_time[:10]
|
|
|
|
name = str(row[0]).strip() if row[0] else ''
|
|
weiban_entries.append({
|
|
"name": name,
|
|
"date": date_str,
|
|
"sales": sales,
|
|
"kefu": kefu,
|
|
})
|
|
|
|
print(f" 微伴6月线索: {len(weiban_entries)} 条")
|
|
|
|
# Count by sales
|
|
by_sales = defaultdict(list)
|
|
for e in weiban_entries:
|
|
by_sales[e["sales"]].append(e)
|
|
for s, entries in by_sales.items():
|
|
print(f" {s}: {len(entries)} 条")
|
|
|
|
# Step 2: Read existing sales sheet data
|
|
print("\n=== Step 2: 读取销售表现有数据 ===")
|
|
existing_names = {"小龙": set(), "吴迪": set()}
|
|
|
|
for sales_name, sheet_id in SHEET_IDS.items():
|
|
data = read_sheet(token, sheet_id, f"A1:K2000")
|
|
for row in data[1:]: # skip header
|
|
if row and len(row) >= 2 and row[1]:
|
|
name = str(row[1]).strip()
|
|
if name:
|
|
existing_names[sales_name].add(name)
|
|
print(f" {sales_name}表已有 {len(existing_names[sales_name])} 条记录")
|
|
|
|
# Step 3: Dedup and prepare new rows
|
|
print("\n=== Step 3: 去重 ===")
|
|
new_rows = {"小龙": [], "吴迪": []}
|
|
|
|
for sales_name, entries in by_sales.items():
|
|
existing = existing_names[sales_name]
|
|
for e in entries:
|
|
if e["name"] not in existing:
|
|
# Format: [销售归属, 微信昵称, 进线日期, 体验节数, 手机号, 用户年级, 课史/跟进, 用户ID, 注册日期, 下载渠道, 是否下单]
|
|
new_rows[sales_name].append([sales_name, e["name"], e["date"], "", "", "", "", "", "", "", ""])
|
|
else:
|
|
print(f" 跳过重复: [{sales_name}] {e['name']}")
|
|
|
|
for s, rows in new_rows.items():
|
|
print(f" {s}新增: {len(rows)} 条")
|
|
|
|
# Step 4: Write to sheets
|
|
print("\n=== Step 4: 写入销售表 ===")
|
|
for sales_name, rows in new_rows.items():
|
|
if not rows:
|
|
print(f" {sales_name}: 无新增,跳过")
|
|
continue
|
|
sheet_id = SHEET_IDS[sales_name]
|
|
ok = append_rows(token, sheet_id, rows)
|
|
if ok:
|
|
print(f" {sales_name}: ✅ 写入 {len(rows)} 条")
|
|
else:
|
|
print(f" {sales_name}: ❌ 写入失败")
|
|
|
|
# Step 5: Summary
|
|
print("\n=== 汇总 ===")
|
|
print(f"微伴6月总量: {len(weiban_entries)} 条")
|
|
print(f"小龙: 微伴{len(by_sales['小龙'])}条 → 新增{len(new_rows['小龙'])}条")
|
|
print(f"吴迪: 微伴{len(by_sales['吴迪'])}条 → 新增{len(new_rows['吴迪'])}条")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|