2026-03-13 13:10:20 +08:00
|
|
|
import argparse
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
from project_bitable_common import (
|
2026-03-13 18:19:17 +08:00
|
|
|
get_default_end_date,
|
|
|
|
|
get_default_start_date,
|
2026-03-13 13:10:20 +08:00
|
|
|
get_base_url,
|
2026-03-13 18:19:17 +08:00
|
|
|
get_feishu_chat_id,
|
|
|
|
|
get_feishu_report_image_path,
|
|
|
|
|
get_group_webhook_url,
|
2026-03-13 13:10:20 +08:00
|
|
|
get_mapping_file,
|
2026-03-13 18:19:17 +08:00
|
|
|
get_store_field_name,
|
|
|
|
|
iter_dates,
|
2026-03-13 13:10:20 +08:00
|
|
|
load_dotenv,
|
|
|
|
|
log_step,
|
|
|
|
|
run_gmv_sync,
|
|
|
|
|
run_metric_sync,
|
2026-03-13 18:19:17 +08:00
|
|
|
send_feishu_app_card,
|
|
|
|
|
send_feishu_sync_card,
|
2026-03-16 14:21:12 +08:00
|
|
|
sync_field_groups_for_day,
|
2026-03-13 13:10:20 +08:00
|
|
|
validate_date,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_args() -> argparse.Namespace:
|
|
|
|
|
parser = argparse.ArgumentParser(description="按 销售 -> 退款 -> GMV 顺序执行飞书多维表格同步。")
|
2026-03-13 18:19:17 +08:00
|
|
|
parser.add_argument("--start-date", default=get_default_start_date(), help="开始日期,格式 YYYY-MM-DD")
|
|
|
|
|
parser.add_argument("--end-date", default=get_default_end_date(), help="结束日期,格式 YYYY-MM-DD,默认昨天")
|
2026-03-13 13:10:20 +08:00
|
|
|
parser.add_argument("--base-url", default=get_base_url(), help="飞书多维表格地址")
|
|
|
|
|
parser.add_argument("--mapping-file", default=str(get_mapping_file()), help="店铺映射表 xlsx")
|
2026-03-13 18:19:17 +08:00
|
|
|
parser.add_argument("--store-field-name", default=get_store_field_name(), help="飞书中的店铺字段名")
|
|
|
|
|
parser.add_argument("--chat-id", default=get_feishu_chat_id(), help="飞书群 chat_id")
|
|
|
|
|
parser.add_argument("--report-image-path", default=get_feishu_report_image_path(), help="飞书卡片预览图本地路径")
|
|
|
|
|
parser.add_argument("--group-webhook", default=get_group_webhook_url(), help="飞书群机器人 webhook")
|
2026-03-13 13:10:20 +08:00
|
|
|
parser.add_argument("--table-map-file", default="", help="可选,项目到表名的映射 JSON 文件路径")
|
|
|
|
|
parser.add_argument("--dry-run", action="store_true", help="只输出将要更新的内容,不调用飞书写接口")
|
|
|
|
|
parser.add_argument("--skip-missing-tables", action="store_true", help="找不到对应月份的飞书表时跳过")
|
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main() -> None:
|
|
|
|
|
load_dotenv()
|
|
|
|
|
args = parse_args()
|
|
|
|
|
start_date = validate_date(args.start_date)
|
|
|
|
|
end_date = validate_date(args.end_date)
|
|
|
|
|
if end_date < start_date:
|
|
|
|
|
raise ValueError("end-date 不能早于 start-date")
|
|
|
|
|
|
2026-03-13 18:19:17 +08:00
|
|
|
log_step("流水线开始: 按天执行 销售 -> 退款 -> GMV")
|
|
|
|
|
for stat_date in iter_dates(start_date, end_date):
|
|
|
|
|
log_step(f"开始处理日期: {stat_date.isoformat()}")
|
|
|
|
|
run_metric_sync(
|
|
|
|
|
metric_name="sales",
|
|
|
|
|
start_date=stat_date,
|
|
|
|
|
end_date=stat_date,
|
|
|
|
|
base_url=args.base_url,
|
|
|
|
|
mapping_file=Path(args.mapping_file),
|
|
|
|
|
store_field_name=args.store_field_name,
|
|
|
|
|
table_map_file=args.table_map_file,
|
|
|
|
|
dry_run=args.dry_run,
|
|
|
|
|
skip_missing_tables=args.skip_missing_tables,
|
|
|
|
|
)
|
|
|
|
|
run_metric_sync(
|
|
|
|
|
metric_name="refund",
|
|
|
|
|
start_date=stat_date,
|
|
|
|
|
end_date=stat_date,
|
|
|
|
|
base_url=args.base_url,
|
|
|
|
|
mapping_file=Path(args.mapping_file),
|
|
|
|
|
store_field_name=args.store_field_name,
|
|
|
|
|
table_map_file=args.table_map_file,
|
|
|
|
|
dry_run=args.dry_run,
|
|
|
|
|
skip_missing_tables=args.skip_missing_tables,
|
|
|
|
|
)
|
|
|
|
|
run_gmv_sync(
|
|
|
|
|
start_date=stat_date,
|
|
|
|
|
end_date=stat_date,
|
|
|
|
|
base_url=args.base_url,
|
|
|
|
|
store_field_name=args.store_field_name,
|
|
|
|
|
dry_run=args.dry_run,
|
|
|
|
|
skip_missing_tables=args.skip_missing_tables,
|
|
|
|
|
)
|
2026-03-16 14:21:12 +08:00
|
|
|
sync_field_groups_for_day(
|
|
|
|
|
stat_date=stat_date,
|
|
|
|
|
base_url=args.base_url,
|
|
|
|
|
store_field_name=args.store_field_name,
|
|
|
|
|
table_map_file=args.table_map_file,
|
|
|
|
|
dry_run=args.dry_run,
|
|
|
|
|
skip_missing_tables=args.skip_missing_tables,
|
|
|
|
|
)
|
2026-03-13 18:19:17 +08:00
|
|
|
log_step(f"日期处理完成: {stat_date.isoformat()}")
|
|
|
|
|
if not args.dry_run:
|
|
|
|
|
if args.chat_id:
|
|
|
|
|
send_feishu_app_card(
|
|
|
|
|
chat_id=args.chat_id,
|
|
|
|
|
title="GMV数据同步",
|
|
|
|
|
base_url=args.base_url,
|
|
|
|
|
start_date=start_date,
|
|
|
|
|
end_date=end_date,
|
|
|
|
|
image_path=args.report_image_path,
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
send_feishu_sync_card(
|
|
|
|
|
webhook_url=args.group_webhook,
|
|
|
|
|
title="GMV数据同步",
|
|
|
|
|
base_url=args.base_url,
|
|
|
|
|
start_date=start_date,
|
|
|
|
|
end_date=end_date,
|
|
|
|
|
)
|
2026-03-13 13:10:20 +08:00
|
|
|
log_step("流水线完成")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
main()
|