"""yun8 API 客户端门面。 组装司机端 / 管理端 / 第三方(滇运通)三套 BaseHttpClient 会话, 并挂载各业务域 Mixin 的 step01-21 方法。 请求头组装顺序与旧 yun8_sync/client.py._init_session 逐字一致: 1. 角色专属请求头(跳过空值) 2. common_headers 中的 host / accept-language / accept-encoding 无条件覆盖 Usage: from tests.apis.yun8.client import Yun8ApiClient client = Yun8ApiClient(config["yun8_api"]) client.set_driver_auth("Bearer xxx") client.set_admin_auth("Bearer yyy") data = client.step01_query_goods() """ from tests.core.http_client import BaseHttpClient from tests.apis.yun8.driver_api import DriverApi from tests.apis.yun8.accounting_api import AccountingApi from tests.apis.yun8.audit_payment_api import AuditPaymentApi from tests.apis.yun8.receipt_api import ReceiptApi from tests.apis.yun8.third_party_api import ThirdPartyApi class Yun8ApiClient(DriverApi, AccountingApi, AuditPaymentApi, ReceiptApi, ThirdPartyApi): """封装 yun8 全部 API 请求(21 个 step 方法 + 3 套会话)。""" def __init__(self, config: dict): # config 为 test_config.yaml 的 yun8_api section self.base_url = config["base_url"].rstrip("/") self.verify_ssl = config.get("verify_ssl", False) self.timeout = config.get("timeout_seconds", 60) common = config.get("common_headers", {}) # ---- Driver Session ---- self.driver_http = BaseHttpClient( self.base_url, headers=config.get("driver_headers", {}), verify_ssl=self.verify_ssl, timeout=self.timeout, name="yun8-driver") # ---- Admin Session ---- self.admin_http = BaseHttpClient( self.base_url, headers=config.get("admin_headers", {}), verify_ssl=self.verify_ssl, timeout=self.timeout, name="yun8-admin") # 通用请求头无条件覆盖(与旧版一致,即使为空也写入) for http in (self.driver_http, self.admin_http): http.set_header("host", common.get("host", "")) http.set_header("accept-language", common.get("accept-language", "")) http.set_header("accept-encoding", common.get("accept-encoding", "")) # ---- Third-party Session (滇运通,独立 token/host) ---- tp = config.get("dianyuntong", {}) self.tp_enabled = tp.get("enabled", False) self.tp_http = None self.tp_base = "" if self.tp_enabled: self.tp_base = tp.get("base_url", "").rstrip("/") tp_headers = { "host": "yndyt.cxtech.vip", "authorization": tp.get("token", ""), "deviceid": "0000000000", "secret": "GouldAMap=d58bb5f7da1aa1d6b78741ded2450f2d", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36 Edg/149.0.0.0", "accept": "application/json, text/plain, */*", "accept-language": "zh-CN,zh;q=0.9,en;q=0.8", "origin": tp.get("base_url", ""), "referer": f"{tp.get('base_url', '')}/admin/", "cookie": tp.get("cookie", ""), } self.tp_http = BaseHttpClient( self.tp_base, headers=tp_headers, verify_ssl=self.verify_ssl, timeout=self.timeout, name="yun8-tp") # 快捷引用(各域 Mixin 使用) self.dp = config.get("driver_params", {}) self.ac = config.get("accounting", {}) self.pm = config.get("payment", {}) # ------------------------------------------------------------------ def set_driver_auth(self, token: str): self.driver_http.set_header("authorization", token) def set_admin_auth(self, token: str): self.admin_http.set_header("authorization", token) def close(self): """关闭全部会话连接池。""" self.driver_http.close() self.admin_http.close() if self.tp_http: self.tp_http.close()