#!/usr/bin/env python3 """ yun8 运输流程完整自动化 ======================= 将 Postman Collection (yun8.postman_collection.json) 中 "运输流程" 全部 17 个接口 + SQL 写入实现为 Python 流水线。 阶段 A — 司机端 (步骤 1-5) 查询货源→接单→待运输→装货→卸货 阶段 B — 运费核算 (步骤 6-9) 查询→详情→试算→提交核算 阶段 C — 审核 & 付款 (步骤 10-16) 查询审核→审核通过→司机打款→货主打款 阶段 D — 回单文件 + SQL (步骤 14-16) payNo→打款记录→文件名前缀→INSERT 阶段 E — 上报运单 (步骤 17) reportOrderDetail 用法: # 完整流程 python main.py --auth-driver "Bearer xxx" --auth-admin "Bearer yyy" # 仅跑特定阶段 python main.py --stage driver --auth-driver "Bearer xxx" --auth-admin "Bearer yyy" # 循环执行 10 次,间隔 3 秒 python main.py --repeat 10 --delay 3 # 预览 SQL 不写库 python main.py --dry-run """ import argparse import sys import time import traceback from datetime import datetime from pathlib import Path import yaml from pipeline import Pipeline def load_config(path: str | Path) -> dict: with open(path, "r", encoding="utf-8") as fh: return yaml.safe_load(fh) STAGE_HELP = """阶段选择: all 完整流程 (默认): 司机端 → 核算 → 付款 → 回单SQL → 上报 driver 仅司机端 (步骤 1-5) accounting 仅运费核算 (步骤 6-9) payment 仅审核付款 (步骤 10-16) receipt 仅回单文件+SQL+上报 (步骤 14-17) """ def run_one_cycle(config: dict, stage: str, driver_token: str, admin_token: str, dry_run: bool) -> bool: """执行一次完整流水线,返回 True 表示成功""" pipe = Pipeline(config) pipe.set_auth(driver_token, admin_token) if stage in ("all", "driver"): pipe.run_driver_flow() # reset_order_detail 模式:仅跑司机端,跳过后续全部步骤 dp = config.get("driver_params", {}) if dp.get("reset_order_detail", False): print(f"\n [stop] reset_order_detail=true,跳过步骤 06-21") return True if stage in ("all", "accounting"): pipe.run_accounting_flow() if stage in ("all", "payment"): pipe.run_audit_payment_flow() ac = config.get("accounting", {}) if ac.get("execute_after_audit", True): if stage in ("all", "receipt"): pipe.run_receipt_file_flow(dry_run=dry_run) # ETC 开票 SQL 写入 (步骤 22-23) if stage in ("all", "receipt"): pipe.run_etc_invoice_flow(dry_run=dry_run) else: if stage in ("all", "receipt"): print(f"\n [stop] execute_after_audit=false,跳过 receipt 阶段") return True def main(): parser = argparse.ArgumentParser( description="yun8 运输流程完整自动化", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=STAGE_HELP, ) parser.add_argument("--config", default=None, help="配置文件路径 (默认: 脚本同目录下 config.yaml)") parser.add_argument("--auth-driver", default="", help="司机端 Bearer Token (含 'Bearer ' 前缀)") parser.add_argument("--auth-admin", default="", help="管理端 Bearer Token (含 'Bearer ' 前缀)") parser.add_argument("--stage", default="all", choices=["all", "driver", "accounting", "payment", "receipt"], help="运行阶段 (默认: all)") parser.add_argument("--dry-run", action="store_true", help="仅预览 SQL,不实际写入数据库") parser.add_argument("--repeat", type=int, default=1, help="循环执行次数 (默认: 1)") parser.add_argument("--delay", type=int, default=0, help="每次循环之间的等待秒数 (默认: 0)") args = parser.parse_args() # 加载配置 config_path = args.config or (Path(__file__).parent / "config.yaml") config = load_config(config_path) # 读取 Token driver_token = args.auth_driver or config.get("auth", {}).get("driver_token", "") admin_token = args.auth_admin or config.get("auth", {}).get("admin_token", "") print("=" * 60) print(f" yun8 运输流程自动化") print(f" config: {config_path}") print(f" stage: {args.stage}") print(f" dry-run: {args.dry_run}") print(f" repeat: {args.repeat}") print(f" delay: {args.delay}s") print(f" 开始时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print("=" * 60) ok_count = 0 fail_count = 0 cycle_start = time.time() for i in range(1, args.repeat + 1): if args.repeat > 1: print(f"\n{'#' * 60}") print(f"# 第 {i}/{args.repeat} 次循环") print(f"# 时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print(f"{'#' * 60}") try: run_one_cycle(config, args.stage, driver_token, admin_token, args.dry_run) ok_count += 1 if args.repeat > 1: print(f"\n--- 第 {i}/{args.repeat} 次循环: 成功 ---") except KeyboardInterrupt: print(f"\n 用户中断,已执行 {i-1} 次") fail_count += (args.repeat - i + 1) break except Exception as exc: fail_count += 1 print(f"\n--- 第 {i}/{args.repeat} 次循环: 失败 ---") print(f" 错误: {exc}") traceback.print_exc() # 失败后继续下一次(不中断循环) # 循环间隔 if i < args.repeat and args.delay > 0: print(f" 等待 {args.delay}s 后进入下一次循环...") time.sleep(args.delay) # 汇总 elapsed = time.time() - cycle_start print(f"\n{'=' * 60}") print(f" 全部循环完成") print(f" 成功: {ok_count} 失败: {fail_count} 总计: {args.repeat}") print(f" 耗时: {elapsed:.0f}s") print(f" 结束时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print(f"{'=' * 60}") if fail_count > 0: sys.exit(1) if __name__ == "__main__": main()