Files
cma-management/backend/scripts/verify_decompose_dialog_review.py
T

80 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""budget-decompose-dialog-fix 独立复核:API 级实测 auto-decompose 全链路"""
import json
import sys
import urllib.request
BASE = "http://127.0.0.1:8010"
def post(path, body, token=None, method="POST"):
req = urllib.request.Request(
BASE + path,
data=json.dumps(body).encode("utf-8"),
method=method,
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {token}" if token else "",
},
)
try:
with urllib.request.urlopen(req, timeout=30) as resp:
return resp.status, json.loads(resp.read().decode("utf-8"))
except urllib.error.HTTPError as e:
try:
return e.code, json.loads(e.read().decode("utf-8"))
except Exception:
return e.code, {"detail": e.read().decode("utf-8", "ignore")}
def main():
# 1. 登录(账套模式 entity_id=1
status, login = post("/api/cma/auth/login", {"username": "admin", "password": "admin123", "entity_id": 1})
token = login.get("token") or login.get("access_token")
if status != 200 or not token:
print("FAIL login:", status, login)
sys.exit(1)
print("PASS 登录成功, token 前缀:", token[:12], "...")
# 2. 调用 auto-decomposeequal 均分)
status, r = post("/api/cma/budget/auto-decompose", {"year": 2026, "method": "equal", "version": "v1.0"}, token)
print("auto-decompose status:", status)
if status != 200:
print(" detail:", r.get("detail", r))
print("FAIL auto-decompose 非200(可能该年无年度预算数据)")
sys.exit(2)
print(" message:", r.get("message"))
results = r.get("results") or []
print(" created:", r.get("created"), " results数:", len(results))
for res in results[:5]:
print(" -", res.get("kpi_code"), res.get("kpi_name"),
"annual=", res.get("annual_budget"), "method=", res.get("method"),
"monthly_count=", len(res.get("monthly") or []))
if not results:
print("FAIL results 为空")
sys.exit(3)
# 3. 验证每条结果字段完整(前端表格依赖)
required = ["kpi_code", "kpi_name", "annual_budget", "method", "monthly"]
for res in results:
missing = [k for k in required if k not in res]
if missing:
print("FAIL 结果缺字段:", missing, res)
sys.exit(4)
if not res.get("monthly"):
print("FAIL monthly 为空:", res.get("kpi_code"))
sys.exit(5)
print("PASS 所有结果字段完整(kpi_code/kpi_name/annual_budget/method/monthly")
# 4. 幂等抽查:再调一次,结果一致
status2, r2 = post("/api/cma/budget/auto-decompose", {"year": 2026, "method": "equal", "version": "v1.0"}, token)
snap1 = {res["kpi_id"]: tuple(res.get("monthly") or []) for res in results}
snap2 = {res["kpi_id"]: tuple(res.get("monthly") or []) for res in (r2.get("results") or [])}
print("PASS 二次调用幂等一致" if snap1 == snap2 else "WARN 二次调用结果不同(非幂等)")
print("\nRESULT: API 全链路通过")
if __name__ == "__main__":
main()