#!/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()