107 lines
3.0 KiB
Python
107 lines
3.0 KiB
Python
"""订单中心接口服务。本期开放接口 1、3 收件;接口 2 只在 outbound 组装报文。
|
||
|
||
路径:
|
||
- POST /api/oms/v1/sales-goods
|
||
- POST /api/oms/v1/purchase-contracts
|
||
鉴权:X-Oms-Token
|
||
请求里不跑选品、不录合同。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from typing import Annotated, Any
|
||
|
||
from fastapi import Depends, FastAPI, Header
|
||
from fastapi.responses import JSONResponse
|
||
|
||
from .auth import token_ok
|
||
from .local_env import load_local_env
|
||
|
||
load_local_env()
|
||
from .inbound.envelope import EnvelopeError, parse_envelope
|
||
from .inbound.purchase_contract import receive_purchase_contracts
|
||
from .inbound.repo import RepoUnavailable
|
||
from .inbound.sales_goods import receive_sales_goods
|
||
|
||
app = FastAPI(title="洁达 RPA × 订单中心", version="0.1")
|
||
|
||
|
||
def get_repo():
|
||
# 运行时只走 Oracle。单测用 dependency_overrides 注入内存替身。
|
||
from .inbound.oracle_repo import OracleSalesGoodsRepo
|
||
|
||
return OracleSalesGoodsRepo.from_env()
|
||
|
||
|
||
def get_contract_repo():
|
||
from .inbound.oracle_contract_repo import OraclePurchaseContractRepo
|
||
|
||
return OraclePurchaseContractRepo.from_env()
|
||
|
||
|
||
@app.get("/health")
|
||
def health():
|
||
return {"ok": True}
|
||
|
||
|
||
@app.post("/api/oms/v1/sales-goods")
|
||
def post_sales_goods(
|
||
payload: dict[str, Any] | None = None,
|
||
x_oms_token: Annotated[str | None, Header()] = None,
|
||
repo=Depends(get_repo),
|
||
):
|
||
return _post_inbound(
|
||
payload,
|
||
x_oms_token,
|
||
receive=lambda rows: receive_sales_goods(rows, repo),
|
||
)
|
||
|
||
|
||
@app.post("/api/oms/v1/purchase-contracts")
|
||
def post_purchase_contracts(
|
||
payload: dict[str, Any] | None = None,
|
||
x_oms_token: Annotated[str | None, Header()] = None,
|
||
repo=Depends(get_contract_repo),
|
||
):
|
||
return _post_inbound(
|
||
payload,
|
||
x_oms_token,
|
||
receive=lambda rows: receive_purchase_contracts(rows, repo),
|
||
)
|
||
|
||
|
||
def _post_inbound(payload, x_oms_token, receive):
|
||
if not token_ok(x_oms_token):
|
||
return JSONResponse(
|
||
status_code=401,
|
||
content={"code": 401, "msg": "身份认证失败", "results": []},
|
||
)
|
||
try:
|
||
rows = parse_envelope(payload if payload is not None else {})
|
||
except EnvelopeError as exc:
|
||
return JSONResponse(
|
||
status_code=422,
|
||
content={"code": 422, "msg": exc.message, "results": []},
|
||
)
|
||
try:
|
||
results = receive(rows)
|
||
except RepoUnavailable as exc:
|
||
return JSONResponse(
|
||
status_code=503,
|
||
content={"code": 503, "msg": exc.message, "results": []},
|
||
)
|
||
# 逐条有成功/重复/拒绝时 HTTP 仍 200,看 results[].resultCode。
|
||
return {
|
||
"code": 200,
|
||
"msg": _summary(results),
|
||
"results": results,
|
||
}
|
||
|
||
|
||
def _summary(results: list[dict]) -> str:
|
||
codes = {item["resultCode"] for item in results}
|
||
if codes <= {"ACCEPTED"}:
|
||
return "批量接收完成"
|
||
if codes <= {"ACCEPTED", "DUPLICATE"} and "DUPLICATE" in codes:
|
||
return "批量接收完成,存在重复数据"
|
||
return "批量接收完成"
|