微信小程序页面迁移校验之前 P5任务处理之前
This commit is contained in:
218
scripts/ops/_fetch_settlement_data_manual.py
Normal file
218
scripts/ops/_fetch_settlement_data_manual.py
Normal file
@@ -0,0 +1,218 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
手动获取飞球 API 结账数据(2026-02-01 到现在)
|
||||
|
||||
背景:SPI 警告显示结账数据只到 2026-02-14,存在约 2 周数据延迟。
|
||||
需要手动调用 API 获取最新的结账数据,确认是否为 API 数据源问题。
|
||||
|
||||
用法:
|
||||
cd C:/NeoZQYY
|
||||
python scripts/ops/_fetch_settlement_data_manual.py
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime, date
|
||||
from pathlib import Path
|
||||
|
||||
# 添加项目根目录到 Python 路径
|
||||
project_root = Path(__file__).parent.parent.parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
# 加载环境变量
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv(project_root / ".env")
|
||||
|
||||
# 验证必需的环境变量
|
||||
required_vars = ["SYSTEM_LOG_ROOT"]
|
||||
for var in required_vars:
|
||||
if not os.environ.get(var):
|
||||
raise RuntimeError(f"环境变量 {var} 未设置,请检查 .env 文件")
|
||||
|
||||
# 导入 ETL 模块
|
||||
sys.path.insert(0, str(project_root / "apps/etl/connectors/feiqiu"))
|
||||
from api.client import APIClient
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数:调用飞球 API 获取结账数据"""
|
||||
|
||||
# 从环境变量读取 API 配置
|
||||
api_base = os.environ.get("API_BASE")
|
||||
api_token = os.environ.get("API_TOKEN")
|
||||
|
||||
if not api_base or not api_token:
|
||||
# 尝试从 ETL 配置文件读取
|
||||
etl_env_path = project_root / "apps/etl/connectors/feiqiu/.env"
|
||||
if etl_env_path.exists():
|
||||
load_dotenv(etl_env_path)
|
||||
api_base = os.environ.get("API_BASE")
|
||||
api_token = os.environ.get("API_TOKEN")
|
||||
|
||||
if not api_base or not api_token:
|
||||
raise RuntimeError("API_BASE 或 API_TOKEN 未配置,请检查 .env 文件")
|
||||
|
||||
print(f"API Base URL: {api_base}")
|
||||
print(f"API Token: {api_token[:20]}..." if api_token else "API Token: 未设置")
|
||||
|
||||
# 创建 API 客户端
|
||||
client = APIClient(
|
||||
base_url=api_base,
|
||||
token=api_token,
|
||||
timeout=30,
|
||||
retry_max=3
|
||||
)
|
||||
|
||||
# 设置查询参数:2026-02-01 00:00:00 到现在
|
||||
start_time = "2026-02-01 00:00:00"
|
||||
end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
params = {
|
||||
"siteId": 0, # 0 表示所有门店
|
||||
"rangeStartTime": start_time,
|
||||
"rangeEndTime": end_time
|
||||
}
|
||||
|
||||
print(f"\n查询参数:")
|
||||
print(f" 时间范围: {start_time} ~ {end_time}")
|
||||
print(f" 门店ID: {params['siteId']} (0=所有门店)")
|
||||
|
||||
# 调用 API
|
||||
endpoint = "/Site/GetAllOrderSettleList"
|
||||
print(f"\n调用 API: {endpoint}")
|
||||
|
||||
try:
|
||||
# 获取分页数据
|
||||
records, pages_meta = client.get_paginated(
|
||||
endpoint=endpoint,
|
||||
params=params,
|
||||
page_size=200,
|
||||
data_path=("data",),
|
||||
list_key="settleList"
|
||||
)
|
||||
|
||||
print(f"\n✅ API 调用成功")
|
||||
print(f"总页数: {len(pages_meta)}")
|
||||
print(f"总记录数: {len(records)}")
|
||||
|
||||
if records:
|
||||
# 分析数据时间分布
|
||||
pay_times = []
|
||||
for record in records:
|
||||
pay_time = record.get("payTime")
|
||||
if pay_time:
|
||||
pay_times.append(pay_time)
|
||||
|
||||
if pay_times:
|
||||
pay_times.sort()
|
||||
print(f"\n📊 数据时间分布:")
|
||||
print(f" 最早结账时间: {pay_times[0]}")
|
||||
print(f" 最晚结账时间: {pay_times[-1]}")
|
||||
print(f" 有效结账记录: {len(pay_times)}/{len(records)}")
|
||||
|
||||
# 按日期统计
|
||||
date_counts = {}
|
||||
for pay_time in pay_times:
|
||||
try:
|
||||
# 提取日期部分
|
||||
date_str = pay_time.split()[0] # "2026-02-14 10:30:00" -> "2026-02-14"
|
||||
date_counts[date_str] = date_counts.get(date_str, 0) + 1
|
||||
except:
|
||||
continue
|
||||
|
||||
print(f"\n📅 按日期统计 (前10天):")
|
||||
for date_str in sorted(date_counts.keys())[:10]:
|
||||
print(f" {date_str}: {date_counts[date_str]} 条记录")
|
||||
|
||||
if len(date_counts) > 10:
|
||||
print(f" ... (共 {len(date_counts)} 天有数据)")
|
||||
|
||||
# 保存结果到文件
|
||||
output_dir = Path(os.environ["SYSTEM_LOG_ROOT"])
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
output_file = output_dir / f"settlement_manual_fetch_{timestamp}.json"
|
||||
|
||||
result = {
|
||||
"query_time": datetime.now().isoformat(),
|
||||
"params": params,
|
||||
"endpoint": endpoint,
|
||||
"total_pages": len(pages_meta),
|
||||
"total_records": len(records),
|
||||
"records": records,
|
||||
"pages_meta": pages_meta
|
||||
}
|
||||
|
||||
with open(output_file, "w", encoding="utf-8") as f:
|
||||
json.dump(result, f, ensure_ascii=False, indent=2)
|
||||
|
||||
print(f"\n💾 结果已保存到: {output_file}")
|
||||
|
||||
# 生成简要报告
|
||||
report_file = output_dir / f"settlement_analysis_{timestamp}.md"
|
||||
with open(report_file, "w", encoding="utf-8") as f:
|
||||
f.write(f"# 飞球 API 结账数据手动获取报告\n\n")
|
||||
f.write(f"**查询时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
|
||||
f.write(f"**查询范围**: {start_time} ~ {end_time}\n\n")
|
||||
f.write(f"**API 端点**: {endpoint}\n\n")
|
||||
f.write(f"**结果统计**:\n")
|
||||
f.write(f"- 总页数: {len(pages_meta)}\n")
|
||||
f.write(f"- 总记录数: {len(records)}\n")
|
||||
|
||||
if records and pay_times:
|
||||
f.write(f"- 最早结账时间: {pay_times[0]}\n")
|
||||
f.write(f"- 最晚结账时间: {pay_times[-1]}\n")
|
||||
f.write(f"- 有效结账记录: {len(pay_times)}/{len(records)}\n\n")
|
||||
|
||||
f.write(f"**按日期统计**:\n")
|
||||
for date_str in sorted(date_counts.keys()):
|
||||
f.write(f"- {date_str}: {date_counts[date_str]} 条记录\n")
|
||||
|
||||
f.write(f"\n**数据文件**: {output_file.name}\n")
|
||||
|
||||
print(f"📋 分析报告已保存到: {report_file}")
|
||||
|
||||
# 关键发现
|
||||
if records and pay_times:
|
||||
latest_date = pay_times[-1].split()[0]
|
||||
today = date.today().strftime("%Y-%m-%d")
|
||||
|
||||
print(f"\n🔍 关键发现:")
|
||||
print(f" API 最新数据日期: {latest_date}")
|
||||
print(f" 今天日期: {today}")
|
||||
|
||||
if latest_date < today:
|
||||
from datetime import datetime as dt
|
||||
latest_dt = dt.strptime(latest_date, "%Y-%m-%d")
|
||||
today_dt = dt.strptime(today, "%Y-%m-%d")
|
||||
days_behind = (today_dt - latest_dt).days
|
||||
print(f" ⚠️ 数据延迟: {days_behind} 天")
|
||||
else:
|
||||
print(f" ✅ 数据是最新的")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ API 调用失败: {e}")
|
||||
|
||||
# 保存错误信息
|
||||
output_dir = Path(os.environ["SYSTEM_LOG_ROOT"])
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
error_file = output_dir / f"settlement_fetch_error_{timestamp}.txt"
|
||||
|
||||
with open(error_file, "w", encoding="utf-8") as f:
|
||||
f.write(f"飞球 API 结账数据获取失败\n")
|
||||
f.write(f"时间: {datetime.now().isoformat()}\n")
|
||||
f.write(f"端点: {endpoint}\n")
|
||||
f.write(f"参数: {json.dumps(params, ensure_ascii=False, indent=2)}\n")
|
||||
f.write(f"错误: {str(e)}\n")
|
||||
|
||||
print(f"错误信息已保存到: {error_file}")
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user