ai_member_xiaoxi/scripts/verify_disputed_orders.py
2026-06-09 08:00:01 +08:00

169 lines
8.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
争议订单核实 — 回写处理状态到飞书表格
"""
import json, requests, os
CRED_DIR = "/root/.openclaw/credentials/xiaoxi"
WORKSPACE = os.path.dirname(os.path.abspath(__file__)).rsplit('/', 1)[0]
def get_secret(key):
with open(os.path.join(WORKSPACE, "secrets.env")) as f:
for line in f:
if line.startswith(f"{key}="):
return line.strip().split("=", 1)[1].strip("'\"")
def get_fs_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"]
SPREADSHEET_TOKEN = "NoZqsFi47hIOHEt9j8WcfRtbnug"
SHEET_ID = "1jpQNa"
def put_values(token, 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}}
resp = requests.put(url, headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}, json=body, timeout=30)
r = resp.json()
if r.get("code") != 0:
print(f"{range_str}: {r.get('code')} {r.get('msg')}")
return False
return True
# 核实结果: (seq, 处理状态, 备注)
# A类12单: 全部口径OK — DB GSV = 旧表金额
# G类6单: BotQ已匹配DB GSV旧表金额有误
# B类8单: DB零单
# C类7单: 未注册/已注册无订单
# D类6单: 待销售确认C/L
# E类19单: 待确认是否补行
# H类1单: DB GSV=1999 ≠ BotQ=3598
RESULTS = [
# A类
(1, "口径OK", "DB GSV=3598=旧表3598旧表记GSV非GMV非争议"),
(2, "口径OK", "DB GSV=3598=旧表3598旧表记GSV非GMV非争议"),
(3, "口径OK", "DB GSV=3598=旧表3598旧表记GSV非GMV非争议"),
(4, "口径OK", "DB GSV=3598=旧表3598旧表记GSV非GMV非争议"),
(5, "口径OK", "DB GSV=599=旧表599旧表记GSV非GMV非争议"),
(6, "口径OK", "DB GSV=3598=旧表3598旧表记GSV非GMV非争议"),
(7, "口径OK", "DB GSV=3598=旧表3598旧表记GSV非GMV非争议"),
(8, "口径OK", "DB GSV=3598=旧表3598旧表记GSV非GMV非争议"),
(9, "口径OK", "DB GSV=3598=旧表3598旧表记GSV非GMV非争议"),
(10, "口径OK", "DB GSV=1999=旧表1999旧表记GSV非GMV非争议"),
(11, "口径OK", "DB GSV=1999=旧表1999旧表记GSV非GMV非争议"),
(12, "口径OK", "DB GSV=3598=旧表3598旧表记GSV非GMV非争议"),
# G类 — 全部BotQ已匹配DB GSV
(13, "口径OK", "DB GSV=1999=BotQ=1999旧表3598为GMVBot已正确"),
(14, "口径OK", "DB GSV=3598=BotQ=3598旧表1999为部分金额Bot已正确(3笔: 退3598+退1999+正常3598)"),
(15, "口径OK", "DB GSV=7196=BotQ=7196旧表3598为部分金额Bot已正确(2笔各3598)"),
(16, "口径OK", "DB GSV=2098=BotQ=2098旧表599为部分金额Bot已正确(端内599+1499)"),
(17, "口径OK", "DB GSV=3598=BotQ=3598旧表1999为部分金额Bot已正确(1999正常+3598退1999)"),
(18, "口径OK", "DB GSV=7196=BotQ=7196旧表1999为部分金额Bot已正确(2笔各3598)"),
# B类 — 全部DB零单
(19, "DB零单", "UID=17581 DB已注册但无任何订单UID可能录错或虚假"),
(20, "DB零单", "UID=28808 DB已注册但无任何订单UID可能录错或虚假"),
(21, "DB零单", "UID=26398 DB已注册但无任何订单UID可能录错或虚假"),
(22, "DB零单", "UID=19504 DB已注册但无任何订单UID可能录错或虚假"),
(23, "DB零单", "UID=26857 DB已注册但无任何订单UID可能录错或虚假"),
(24, "DB零单", "UID=25717 DB已注册但无任何订单UID可能录错或虚假"),
(25, "DB零单", "UID=18808 DB已注册但无任何订单UID可能录错或虚假"),
(26, "DB零单", "UID=18577 DB已注册但无任何订单UID可能录错或虚假"),
# C类
(27, "未注册", "无UID需补注册/手机号/班主任凭证"),
(28, "未注册", "无UID(E列待补号),需补注册/手机号/班主任凭证"),
(29, "未注册", "无UID(E列空),需补注册/手机号/班主任凭证"),
(30, "未注册", "无UID(E列空)且L<C登记有误需补注册/手机号/班主任凭证"),
(31, "已注册无订单", "UID=27686 已注册(2026-05-18)但DB无订单需核实UID是否正确"),
(32, "未注册", "无UID与#31同人(黄晔-516直播),需补注册/手机号/班主任凭证"),
(33, "未注册", "无UID(E列有手机18611401422),需补注册/手机号/班主任凭证"),
# D类 — 待销售确认C/L
(34, "待销售确认", "进线C=3/20 下单L=3/16L<C需确认以哪个为准"),
(35, "待销售确认", "进线C=5/19 下单L=5/18L<C需确认以哪个为准"),
(36, "待销售确认", "进线C=5/16 下单L=5/15L<C需确认以哪个为准"),
(37, "待销售确认", "进线C=5/31 下单L=4/27L<C且无UID需确认C/L+补UID"),
(38, "待销售确认", "进线C=5/29 下单L=4/26Bot进线C晚于旧表下单L需确认以旧表还是Bot为准"),
(39, "待销售确认", "进线C=4/24 下单L=3/20Bot进线C晚于旧表下单L需确认以旧表还是Bot为准"),
# E类 — 待确认是否补行
(40, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(41, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(42, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(43, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(44, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(45, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(46, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(47, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(48, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(49, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(50, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(51, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(52, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(53, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(54, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(55, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(56, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(57, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
(58, "待确认", "Bot无对应线索行需确认是否补行或旧表脏数据"),
# H类
(59, "待复核", "DB GSV=1999(1笔抖音店铺) ≠ BotQ=3598刷新后仍不一致需核实UID是否对应正确订单"),
]
def main():
token = get_fs_token()
# 写入U列(处理状态)和W列(备注)
# 行号 = seq + 1
u_batch = []
w_batch = []
for seq, status, note in RESULTS:
row = seq + 1
u_batch.append((row, status))
w_batch.append((row, note))
# 按连续行分组写入U列
u_batch.sort()
i = 0
while i < len(u_batch):
j = i
while j + 1 < len(u_batch) and u_batch[j+1][0] == u_batch[j][0] + 1:
j += 1
start_row = u_batch[i][0]
end_row = u_batch[j][0]
vals = [[v[1]] for v in u_batch[i:j+1]]
rng = f"U{start_row}:U{end_row}"
ok = put_values(token, rng, vals)
if ok:
print(f" ✅ U{start_row}:U{end_row} ({len(vals)}行)")
i = j + 1
# 写入W列
w_batch.sort()
i = 0
while i < len(w_batch):
j = i
while j + 1 < len(w_batch) and w_batch[j+1][0] == w_batch[j][0] + 1:
j += 1
start_row = w_batch[i][0]
end_row = w_batch[j][0]
vals = [[v[1]] for v in w_batch[i:j+1]]
rng = f"W{start_row}:W{end_row}"
ok = put_values(token, rng, vals)
if ok:
print(f" ✅ W{start_row}:W{end_row} ({len(vals)}行)")
i = j + 1
print("\n✅ 争议订单核实完成已回写59单处理状态")
if __name__ == "__main__":
main()