# -*- coding: utf-8 -*- """票 13 e2e 前置探测:钉断言形态(嵌套表单绑定 / publish 无步骤④ / 统计出参)""" import json, urllib.request, urllib.parse, io, sys sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') API = "http://localhost:8080" ADMIN = "739564171091247104" def post(url, data=None, token=None): body = urllib.parse.urlencode(data or {}).encode() req = urllib.request.Request(url, data=body, method="POST") req.add_header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8") if token: req.add_header("Authorization", "Bearer " + token) try: with urllib.request.urlopen(req, timeout=20) as r: return json.loads(r.read().decode()) except urllib.error.HTTPError as e: return {"http_status": e.code, "body": e.read().decode()[:200]} def get(url, token=None): req = urllib.request.Request(url) if token: req.add_header("Authorization", "Bearer " + token) try: with urllib.request.urlopen(req, timeout=20) as r: return json.loads(r.read().decode()) except urllib.error.HTTPError as e: return {"http_status": e.code, "body": e.read().decode()[:200]} tok = json.loads(urllib.request.urlopen(f"{API}/api/auth/debug/token?userId={ADMIN}", timeout=10).read().decode())["data"] print("== 1. users/stats 出参 ==") d = get(f"{API}/api/system/users/stats", tok) print(json.dumps(d.get("data"), ensure_ascii=False)[:400]) print("\n== 2. users/page username 过滤(新入参)==") d = post(f"{API}/api/system/users/page", {"current": 1, "size": 5, "username": "罗"}, tok) rows = (d.get("data") or {}).get("content", []) print("rows:", len(rows), [r.get("username") for r in rows][:3]) print("\n== 3. roles/stats ==") d = get(f"{API}/api/roles/stats", tok) print(json.dumps(d.get("data"), ensure_ascii=False)) print("\n== 4. push-rule save-draft 嵌套属性路径绑定 ==") d = post(f"{API}/api/rule/opp-push-rule/save-draft", { "ruleName": "e2d-推送规则-探测", "applyScope": 1, "isDefault": 0, "ruleDesc": "probe", "pushConfig.basic.pushNodeName": "方案卡确认", "pushConfig.fieldValidations[0].fieldName": "项目名称", "pushConfig.fieldValidations[0].validateRule": "非空", "pushConfig.fieldMappings[0].fieldName": "客户名称", "pushConfig.fieldMappings[0].targetField": "projectName", "pushConfig.fieldMappings[0].pushMode": "复制", "pushConfig.projectCreation.createMode": "auto", }, tok) print("save-draft:", json.dumps(d, ensure_ascii=False)[:200]) pg = post(f"{API}/api/rule/opp-push-rule/page", {"current": 1, "size": 10, "ruleName": "e2d-推送规则-探测"}, tok) rows = (pg.get("data") or {}).get("content", []) print("page rows:", len(rows), [r.get("id") for r in rows]) if rows: rid = rows[0]["id"] det = get(f"{API}/api/rule/opp-push-rule/detail?id={rid}", tok) pc = (det.get("data") or {}).get("pushConfig") or {} print("detail pushConfig keys:", list(pc.keys()), "basic=", pc.get("basic"), "fv0=", (pc.get("fieldValidations") or [None])[0]) print("\n== 5. publish 无 projectCreation(候选 NPE 缺陷)==") d2 = post(f"{API}/api/rule/opp-push-rule/publish", { "id": rid, "ruleName": "e2d-推送规则-探测", "applyScope": 1, "isDefault": 0, "pushConfig.basic.pushNodeName": "方案卡确认", "pushConfig.basic.schemeTemplateId": "1", }, tok) print("publish basic-only:", json.dumps(d2, ensure_ascii=False)[:300]) print("\n== 6. project-rule/current ==") d = get(f"{API}/api/rule/project-rule/current", tok) data = d.get("data") or {} print("blocks:", list(data.keys()) if isinstance(data, dict) else data) print("\n== 7. 清理探测草稿 ==") if rows: dl = post(f"{API}/api/rule/opp-push-rule/delete", {"id": rows[0]["id"]}, tok) print("delete probe draft:", dl.get("code"), dl.get("message"))