101 lines
3.2 KiB
Python
101 lines
3.2 KiB
Python
"""1 号药城加入购物车。"""
|
|
from __future__ import annotations
|
|
|
|
import time
|
|
from typing import Any
|
|
|
|
import requests
|
|
import urllib3
|
|
|
|
from cart_add import KIND_OK, KIND_SYSTEM, AddOutcome, classify_mall_message
|
|
from cart_match import CartOffer
|
|
|
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
|
|
GATEWAY = "https://gateway-b2b.fangkuaiyi.com"
|
|
YAOEX_ADD_URL = f"{GATEWAY}/small/shopCart/addShopCart"
|
|
|
|
|
|
def add_yaoex_cart(auth, offer: CartOffer, qty: int, *, session: requests.Session | None = None) -> AddOutcome:
|
|
ids = _ids(offer)
|
|
if not ids["skuId"] and not ids["spuCode"]:
|
|
return AddOutcome(kind=KIND_SYSTEM, reason="缺少 sku")
|
|
payload = _form(
|
|
auth,
|
|
{
|
|
"skuId": ids["skuId"],
|
|
"spuCode": ids["spuCode"],
|
|
"sellerCode": ids["sellerCode"],
|
|
"amount": int(qty),
|
|
},
|
|
)
|
|
own = session is None
|
|
client = session or requests.Session()
|
|
try:
|
|
response = client.post(
|
|
YAOEX_ADD_URL,
|
|
data=payload,
|
|
headers=_headers(),
|
|
timeout=30,
|
|
verify=False,
|
|
)
|
|
response.raise_for_status()
|
|
return _outcome_from_json(response.json())
|
|
except Exception as exc:
|
|
return AddOutcome(kind=KIND_SYSTEM, reason=str(exc))
|
|
finally:
|
|
if own:
|
|
client.close()
|
|
|
|
|
|
def _ids(offer: CartOffer) -> dict[str, str]:
|
|
raw = offer.extra.get("raw") if isinstance(offer.extra.get("raw"), dict) else offer.extra
|
|
if not isinstance(raw, dict):
|
|
raw = {}
|
|
sku = str(raw.get("skuId") or raw.get("id") or offer.sku_id or "")
|
|
spu = str(raw.get("spuCode") or offer.sku_id or "")
|
|
seller = str(raw.get("sellerCode") or raw.get("vendorCode") or raw.get("shopCode") or "")
|
|
return {"skuId": sku, "spuCode": spu, "sellerCode": seller}
|
|
|
|
|
|
def _form(auth, extra: dict[str, Any]) -> dict[str, Any]:
|
|
payload = {
|
|
"traderName": "yaoex_pc",
|
|
"trader": "pc",
|
|
"closesignature": "yes",
|
|
"signature_method": "md5",
|
|
"signature": "****",
|
|
"timestamp": str(int(time.time() * 1000)),
|
|
"token": auth.token,
|
|
"userToken": auth.token,
|
|
"userId": getattr(auth, "user_id", ""),
|
|
"buyerCode": getattr(auth, "buyer_code", ""),
|
|
}
|
|
payload.update(extra)
|
|
return payload
|
|
|
|
|
|
def _headers() -> dict[str, str]:
|
|
return {
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
"X-Requested-With": "XMLHttpRequest",
|
|
"X-Request-Agent": "Axios",
|
|
"traderName": "yaoex_pc",
|
|
"trader": "pc",
|
|
"Origin": "https://mall.yaoex.com",
|
|
"Referer": "https://mall.yaoex.com/v2/cart/",
|
|
}
|
|
|
|
|
|
def _outcome_from_json(payload: object) -> AddOutcome:
|
|
if not isinstance(payload, dict):
|
|
return AddOutcome(kind=KIND_SYSTEM, reason="加购返回异常")
|
|
msg = str(payload.get("msg") or payload.get("message") or payload.get("errorMsg") or "")
|
|
code = payload.get("code")
|
|
success = payload.get("success")
|
|
if success is True or code in (0, "0", 200, "200"):
|
|
return AddOutcome(kind=KIND_OK)
|
|
if msg:
|
|
return classify_mall_message(msg)
|
|
return AddOutcome(kind=KIND_SYSTEM, reason="加购失败")
|