120 lines
4.3 KiB
Python
120 lines
4.3 KiB
Python
#!/usr/bin/env python3
|
||
"""查询小龙名下 4/21-5/20 落单的订单详情(含手机号和用户ID)"""
|
||
|
||
import json, urllib.request, re, sys
|
||
|
||
APP_ID = 'cli_a92fc074fb5edcb5'
|
||
APP_SECRET = 'jzQ8UoNb06rX8147V52icdWF7XN8Su2K'
|
||
SPREADSHEET_TOKEN = 'ERCFsFo4MhnF0ytGeCrc0Bb8n5f'
|
||
SHEET_FILL = '1RFMqc' # 全量销售填表(含手机号/用户ID)
|
||
SHEET_ORDER = 'e12fb9' # 订单汇总(仅成单字段)
|
||
|
||
def get_token():
|
||
url = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal'
|
||
data = json.dumps({'app_id': APP_ID, 'app_secret': APP_SECRET}).encode()
|
||
req = urllib.request.Request(url, data=data, headers={'Content-Type': 'application/json'})
|
||
with urllib.request.urlopen(req) as resp:
|
||
return json.loads(resp.read())['tenant_access_token']
|
||
|
||
def read_sheet(token, sheet_id, cols_range):
|
||
url = f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/values/{sheet_id}!{cols_range}?valueRenderOption=ToString&dateTimeRenderOption=FormattedString'
|
||
req = urllib.request.Request(url, headers={
|
||
'Authorization': f'Bearer {token}',
|
||
'Content-Type': 'application/json',
|
||
})
|
||
with urllib.request.urlopen(req) as resp:
|
||
result = json.loads(resp.read())
|
||
if result.get('code') != 0:
|
||
return None
|
||
return result['data'].get('valueRange', {}).get('values', [])
|
||
|
||
def parse_date(s):
|
||
if not s:
|
||
return None
|
||
s = str(s).strip()
|
||
m = re.match(r'(\d+)月(\d+)日', s)
|
||
if m:
|
||
return (int(m.group(1)), int(m.group(2)))
|
||
m = re.match(r'(\d{4})[-/](\d{1,2})[-/](\d{1,2})', s)
|
||
if m:
|
||
return (int(m.group(2)), int(m.group(3)))
|
||
return None
|
||
|
||
START, END = (4, 21), (5, 20)
|
||
|
||
token = get_token()
|
||
|
||
# Step 1: Read order summary to get the list of matched orders (for row ordering)
|
||
print("Step 1: Reading order summary...", file=sys.stderr)
|
||
order_rows = read_sheet(token, SHEET_ORDER, 'A:N')
|
||
matched_orders = []
|
||
for i, row in enumerate(order_rows):
|
||
if len(row) < 3:
|
||
continue
|
||
owner = str(row[0]).strip() if row[0] else ''
|
||
if owner != '小龙':
|
||
continue
|
||
d = parse_date(row[2])
|
||
if d and START <= d <= END:
|
||
vals = [str(c) if c else '' for c in row]
|
||
while len(vals) < 14:
|
||
vals.append('')
|
||
matched_orders.append({
|
||
'row': i+1, 'nickname': vals[3], 'order_date': vals[2],
|
||
'vals': vals
|
||
})
|
||
|
||
print(f"Orders: {len(matched_orders)}", file=sys.stderr)
|
||
|
||
# Step 2: Read full fill sheet for 小龙 to get phone and UID
|
||
print("Step 2: Reading fill sheet for phones/UIDs...", file=sys.stderr)
|
||
fill_rows = read_sheet(token, SHEET_FILL, 'A:M') # A-M: 销售归属~退款金额
|
||
|
||
# Build lookup: (nickname, order_date) -> (phone, uid)
|
||
fill_lookup = {}
|
||
for row in fill_rows:
|
||
if len(row) < 3:
|
||
continue
|
||
owner = str(row[0]).strip() if row[0] else ''
|
||
if owner != '小龙':
|
||
continue
|
||
nickname = str(row[3]).strip() if len(row) > 3 and row[3] else ''
|
||
order_date = str(row[2]).strip() if row[2] else ''
|
||
phone = str(row[4]).strip() if len(row) > 4 and row[4] else ''
|
||
uid = str(row[8]).strip() if len(row) > 8 and row[8] else ''
|
||
key = (nickname, order_date)
|
||
if key[1] and (key[1] not in fill_lookup or (phone or uid)):
|
||
fill_lookup[key] = (phone, uid)
|
||
|
||
# Step 3: Merge and output
|
||
print("Step 3: Merging...", file=sys.stderr)
|
||
|
||
# Stats
|
||
total_revenue = 0
|
||
valid_count = 0
|
||
|
||
print(f"## 小龙名下订单详情(落单:2026-04-21 ~ 2026-05-20)\n")
|
||
print(f"共 {len(matched_orders)} 条 · 数据来源:销转客户主表\n")
|
||
|
||
for idx, o in enumerate(matched_orders, 1):
|
||
v = o['vals']
|
||
key = (o['nickname'], o['order_date'])
|
||
phone, uid = fill_lookup.get(key, ('', ''))
|
||
|
||
amount = float(v[6]) if v[6] else 0
|
||
is_valid = "✅" if v[11] == '1' else ("⚠️退" if v[11] == '0' else v[11])
|
||
|
||
total_revenue += amount
|
||
if v[11] == '1':
|
||
valid_count += 1
|
||
|
||
phone_str = f"📱{phone}" if phone else "📱—"
|
||
uid_str = f"🆔{uid}" if uid else "🆔—"
|
||
|
||
amt_str = f"{int(float(v[6])):,}" if v[6] else "0"
|
||
print(f"{idx}. {v[3]} {phone_str} {uid_str}")
|
||
print(f" 进线 {v[1]} 落单 {v[2]} {v[5]} ¥{amt_str} {v[4]} · {v[9]} {is_valid}")
|
||
|
||
print()
|
||
print(f"**汇总:{len(matched_orders)} 单 | 有效 {valid_count} 单 | 总额 ¥{total_revenue:,.0f}**")
|