You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

84 lines
4.3 KiB

# -*- coding: utf-8 -*-
"""票05 首轮 FAIL 根因探针(一次性,验证后删):operation/login/batch 日志真实行 + batch/file·download 正确姿势 + publish 被拒原因"""
import json, urllib.request, urllib.parse, urllib.error, sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
API = "http://localhost:8080"
ADMIN = "739564171091247104"
T = json.loads(urllib.request.urlopen(f"{API}/api/auth/debug/token?userId={ADMIN}", timeout=15).read().decode())["data"]
def post(path, data=None):
req = urllib.request.Request(API + path, urllib.parse.urlencode(data or {}).encode(), method="POST")
req.add_header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
req.add_header("Authorization", "Bearer " + T)
try:
with urllib.request.urlopen(req, timeout=30) as r:
return json.loads(r.read().decode())
except urllib.error.HTTPError as e:
return {"code": -1, "message": f"HTTP {e.code}"}
def raw(path, method="GET", data=None, form_pairs=None):
body = None
if form_pairs:
body = urllib.parse.urlencode(form_pairs).encode()
elif data:
body = urllib.parse.urlencode(data).encode()
req = urllib.request.Request(API + path, body, method=method)
if body: req.add_header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
req.add_header("Authorization", "Bearer " + T)
try:
with urllib.request.urlopen(req, timeout=30) as r:
b = r.read()
return {"status": r.status, "len": len(b), "head": b[:120], "magic": b[:2]}
except urllib.error.HTTPError as e:
return {"status": e.code, "len": -1, "head": e.read()[:120]}
print("== 1. operation/page 最近 30 行(无筛选,看 opType/operatorName/content 真实值)==")
d = post("/api/log/operation/page", {"current": 1, "size": 30})
for r in (d.get("data") or {}).get("content", [])[:30]:
print(json.dumps(r, ensure_ascii=False)[:230])
print("== 2. login/page 最近 15 行(找「退出」行)==")
d = post("/api/log/login/page", {"current": 1, "size": 15})
for r in (d.get("data") or {}).get("content", [])[:15]:
print(json.dumps(r, ensure_ascii=False)[:230])
print("== 3. batch/page 最近 5 行(rowId vs fileId)==")
d = post("/api/log/batch/page", {"current": 1, "size": 5})
rows = (d.get("data") or {}).get("content", [])
for r in rows:
print(json.dumps(r, ensure_ascii=False)[:230])
if rows:
rid = rows[0]["id"]
print(f"== 4. GET batch/file?id={rid}(传日志行主键)==")
print(raw(f"/api/log/batch/file?id={rid}"))
print(f"== 5. POST batch/download ids=[{rid}](单 id)==")
print(raw("/api/log/batch/download", method="POST", form_pairs=[("ids", str(rid))]))
if len(rows) >= 2:
print("== 5b. POST batch/download ids=[两行] ==")
print(raw("/api/log/batch/download", method="POST",
form_pairs=[("ids", str(rows[0]["id"])), ("ids", str(rows[1]["id"]))]))
print("== 6. publish 试探(e2d-绑定数规则-probe,部门专用 admin 部门)==")
d = post("/api/rule/opp-pool-rule/publish", {
"ruleName": "e2d-绑定数规则-probe", "applyScope": 2, "deptIds": "744841292348915712",
"isDefault": 0, "allowManualPool": 1, "autoRecycleEnabled": 0, "allowFreeClaim": 1,
"ruleDesc": "probe 临时"})
print(json.dumps(d, ensure_ascii=False)[:400])
print("== 7. opp-pool-rule/page 最近 20 行(看占用与状态分布)==")
d = post("/api/rule/opp-pool-rule/page", {"current": 1, "size": 20})
for r in (d.get("data") or {}).get("content", [])[:20]:
print(json.dumps(r, ensure_ascii=False)[:200])
print("== 8. saveOrUpdate 角色后立即查「修改」行(验证 resolveOpType 顺序 bug)==")
d = post("/api/roles/saveOrUpdate", {"roleName": "e2d-probe角色-x", "roleCode": "e2d_probe_x", "remark": "probe"})
print("saveOrUpdate:", json.dumps(d, ensure_ascii=False)[:120])
d = post("/api/log/operation/page", {"current": 1, "size": 5})
for r in (d.get("data") or {}).get("content", [])[:5]:
print(json.dumps(r, ensure_ascii=False)[:200])
# 清理 probe 角色
d = post("/api/roles/page", {"current": 1, "size": 10, "roleName": "e2d-probe角色-x"})
for r in (d.get("data") or {}).get("content", []):
print("cleanup role:", post("/api/roles/delete", {"id": str(r["id"])}).get("code"))