# -*- coding: utf-8 -*- """ 把演示草稿(submission 21)摆到"只剩黄色警告"的状态,用来验证浮层的第二个分支。 为什么要用脚本摆而不是在页面上手填: · 页面上填 7 个字段 + 传 2 张图 + 等穿透,一次要两三分钟; · 而这一步要验的是**浮层在"只有警告"时的表现**,不是填表本身。 摆状态用接口最快,浮层那一段仍然在真浏览器里点。 跑法:python scripts/_seed_warn_state.py [submissionId] """ import base64 import hashlib import hmac import io import json import os import re import sys import time import urllib.error import urllib.request import uuid sys.stdout.reconfigure(encoding="utf-8") ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SRC = os.path.join(ROOT, "backend", "xt-server", "src", "main", "resources") UID = 151 TASK = 17 SID = int(sys.argv[1]) if len(sys.argv) > 1 else 21 def read_cfg() -> dict: text = "\n".join(open(os.path.join(SRC, f), encoding="utf-8").read() for f in ("application-dev.yml", "application.yml") if os.path.exists(os.path.join(SRC, f))) out = {} for k, p in [("jwt", r"^\s*secret:\s*(\S+)\s*$"), ("issuer", r"^\s*issuer:\s*(\S+)\s*$")]: m = re.search(p, text, re.M) if not m: raise SystemExit(f"找不到 {k}") out[k] = m.group(1) return out def b64u(b: bytes) -> str: return base64.urlsafe_b64encode(b).rstrip(b"=").decode() def mint(secret: str, issuer: str, uid: int, tenant: int) -> str: key = base64.b64decode(secret) now = int(time.time()) signing = (b64u(json.dumps({"alg": "HS512"}, separators=(",", ":")).encode()) + "." + b64u(json.dumps({"iss": issuer, "sub": str(uid), "tenantId": tenant, "orgIds": [], "roles": ["STUDENT"], "userType": 4, "iat": now, "exp": now + 3600}, separators=(",", ":")).encode())) return signing + "." + b64u(hmac.new(key, signing.encode(), hashlib.sha512).digest()) def call(method, path, token, body=None): h = {"Content-Type": "application/json; charset=utf-8"} if token: h["Authorization"] = f"Bearer {token}" data = json.dumps(body, ensure_ascii=False).encode() if body is not None else None req = urllib.request.Request("http://localhost:8080" + path, data=data, headers=h, method=method) try: with urllib.request.urlopen(req, timeout=90) as x: return json.loads(x.read().decode("utf-8")) except urllib.error.HTTPError as e: try: return json.loads(e.read().decode("utf-8")) except Exception: return {"_http": e.code} def upload(token, sid, code, filename, data): boundary = "----seed" + uuid.uuid4().hex[:12] parts = [] for k, v in [("submissionId", str(sid)), ("materialCode", code)]: parts.append(f'--{boundary}\r\nContent-Disposition: form-data; name="{k}"\r\n\r\n{v}\r\n'.encode()) parts.append(f'--{boundary}\r\nContent-Disposition: form-data; name="file"; filename="{filename}"\r\n' f"Content-Type: image/jpeg\r\n\r\n".encode()) parts.append(data) parts.append(f"\r\n--{boundary}--\r\n".encode()) req = urllib.request.Request( "http://localhost:8080/api/v1/mp/files/upload", data=b"".join(parts), method="POST", headers={"Content-Type": f"multipart/form-data; boundary={boundary}", "Authorization": f"Bearer {token}"}) try: with urllib.request.urlopen(req, timeout=90) as x: return json.loads(x.read().decode("utf-8")) except urllib.error.HTTPError as e: try: return json.loads(e.read().decode("utf-8")) except Exception: return {"_http": e.code} def main() -> int: cfg = read_cfg() tok = mint(cfg["jwt"], cfg["issuer"], UID, 1) # ① 填掉全部必填(key 是 snake_case;is_retake=false 让补考三科不可见 → 不必填) form = {"work_unit": "无", "is_retake": False, "is_student": True, "school": "示范职业学校", "major": "数控技术", "enroll_date": "2023-09-01"} r = call("PUT", f"/api/v1/mp/submissions/{SID}", tok, {"formData": form}) print(f" 填必填字段 code={r.get('code')} msg={r.get('msg')}") if r.get("code") != 0: return 1 # ② 传两张**同内容**的图 → VAL-09 重复文件(黄色警告) from PIL import Image buf = io.BytesIO() Image.new("RGB", (900, 1200), (205, 212, 220)).save(buf, "JPEG", quality=90) img = buf.getvalue() for name in ("身份证正面.jpg", "身份证反面.jpg"): up = upload(tok, SID, "IDCARD", name, img) if up.get("code") != 0: print(f" 上传 {name} 失败:{up}") return 1 pr = call("POST", f"/api/v1/mp/files/{up['data']['id']}/process", tok) d = pr.get("data") or {} print(f" {name} → {d.get('standardName')} {d.get('rawSize')}→{d.get('finalSize')} 字节") # ③ 试提交一次,看看还剩什么 r = call("POST", f"/api/v1/mp/submissions/{SID}/submit", tok, {"confirmWarnings": False}) d = r.get("data") or {} print(f"\n 试提交:code={r.get('code')} submitted={d.get('submitted')} " f"红={d.get('redCount')} 黄={d.get('yellowCount')} 蓝={d.get('infoCount')}") for i in d.get("issues") or []: print(f" [sev{i.get('severity')}] {i.get('ruleCode')} {i.get('title')}") if (d.get("redCount") or 0) > 0: print("\n ✗ 还有红色项 —— 浏览器里只会看到「还不能提交」那一支,验不到黄色分支") return 3 print("\n ok 只剩黄色/蓝色 —— 可以在浏览器里验「提交前请确认」那一支了") return 0 if __name__ == "__main__": raise SystemExit(main())