# -*- coding: utf-8 -*- """ 获取会员余额变动数据: /MemberProfile/GetMemberCardBalanceChange 时间范围: 2025-11-01 ~ 当前 数据来源说明: - API 端点: /MemberProfile/GetMemberCardBalanceChange - ODS 表: billiards_ods.member_balance_changes - DWD 表: billiards_dwd.dwd_member_balance_change - 数据路径: data.tenantMemberCardLogs """ import os import sys import json from pathlib import Path from datetime import datetime # 添加项目根目录到 path project_root = Path(__file__).resolve().parents[1] etl_billiards_dir = project_root / "etl_billiards" sys.path.insert(0, str(project_root)) sys.path.insert(0, str(etl_billiards_dir)) from api.client import APIClient from config.env_parser import load_env_overrides from config.defaults import DEFAULTS def main(): import argparse parser = argparse.ArgumentParser(description="获取会员余额变动数据") parser.add_argument("--start", default="2025-11-01", help="开始日期 (YYYY-MM-DD)") parser.add_argument("--end", default=None, help="结束日期 (YYYY-MM-DD),默认当前时间") args = parser.parse_args() # 加载配置 cfg = load_env_overrides(DEFAULTS) api_base = cfg.get("api", {}).get("base_url", "https://pc.ficoo.vip/apiprod/admin/v1") token = cfg.get("api", {}).get("token") store_id = cfg.get("app", {}).get("store_id") if not token: print("错误: 未配置 API_TOKEN 或 FICOO_TOKEN 环境变量") print("请在 .env 文件中设置: FICOO_TOKEN=your_token_here") sys.exit(1) if not store_id: print("错误: 未配置 STORE_ID 环境变量") print("请在 .env 文件中设置: STORE_ID=your_store_id") sys.exit(1) print(f"API Base URL: {api_base}") print(f"Store ID: {store_id}") print(f"Token: {token[:20]}..." if len(token) > 20 else f"Token: {token}") # 创建 API 客户端 client = APIClient( base_url=api_base, token=token, timeout=30, retry_max=3, ) # 设置时间范围 start_time = f"{args.start} 00:00:00" end_time = f"{args.end} 23:59:59" if args.end else datetime.now().strftime("%Y-%m-%d %H:%M:%S") print(f"\n时间范围: {start_time} ~ {end_time}") print("-" * 60) # 请求参数 params = { "siteId": int(store_id), "startTime": start_time, "endTime": end_time, } endpoint = "/MemberProfile/GetMemberCardBalanceChange" print(f"正在调用 API: {endpoint}") print(f"参数: {json.dumps(params, ensure_ascii=False, indent=2)}") print("-" * 60) try: # 获取分页数据 records, pages_meta = client.get_paginated( endpoint=endpoint, params=params, page_size=200, data_path=("data",), list_key="tenantMemberCardLogs", ) print(f"\n获取成功!") print(f"总记录数: {len(records)}") print(f"总页数: {len(pages_meta)}") # 输出目录 output_dir = Path(__file__).parent / "output" output_dir.mkdir(exist_ok=True) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") output_file = output_dir / f"member_balance_change_{timestamp}.json" # 保存数据 output_data = { "endpoint": endpoint, "params": { "siteId": int(store_id), "startTime": start_time, "endTime": end_time, }, "fetched_at": datetime.now().isoformat(), "total_records": len(records), "total_pages": len(pages_meta), "data": records, } with open(output_file, "w", encoding="utf-8") as f: json.dump(output_data, f, ensure_ascii=False, indent=2) print(f"\n数据已保存到: {output_file}") # 打印前几条记录预览 if records: print(f"\n前 3 条记录预览:") print("-" * 60) for i, rec in enumerate(records[:3]): print(f"\n记录 {i+1}:") print(json.dumps(rec, ensure_ascii=False, indent=2)) return records except Exception as e: print(f"\n错误: {e}") import traceback traceback.print_exc() sys.exit(1) if __name__ == "__main__": main()