#!/usr/bin/env python3 """正式服务器全链路验证""" import urllib.request, json, ssl, sys ctx = ssl.create_default_context() BASE = "https://itsupport.servyou.com.cn" def get(path, token=None): req = urllib.request.Request(f"{BASE}{path}", method="GET") if token: req.add_header("Authorization", f"Bearer {token}") try: resp = urllib.request.urlopen(req, context=ctx, timeout=10) raw = resp.read().decode() try: return resp.status, json.loads(raw) except json.JSONDecodeError: return resp.status, {"raw": raw} except urllib.request.HTTPError as e: raw = e.read().decode() try: return e.code, json.loads(raw) except json.JSONDecodeError: return e.code, {"raw": raw} def post(path, data, token=None): req = urllib.request.Request( f"{BASE}{path}", data=json.dumps(data).encode(), method="POST" ) req.add_header("Content-Type", "application/json") if token: req.add_header("Authorization", f"Bearer {token}") try: resp = urllib.request.urlopen(req, context=ctx, timeout=10) return resp.status, json.loads(resp.read().decode()) except urllib.request.HTTPError as e: return e.code, json.loads(e.read().decode()) # ===================== 1. 管理员登录 ===================== print("=" * 60) print("1. 管理员登录 (admin001)") print("=" * 60) code, body = post("/api/agents/login", {"user_id": "admin001", "name": "宋献"}) admin_token = body.get("data", {}).get("token", "") role = body.get("data", {}).get("role", "N/A") print(f" Status: {code}") print(f" Code: {body.get('code')}") print(f" Role: {role}") print(f" Token: {admin_token[:20]}..." if admin_token else " Token: NONE") status_icon = "[OK]" if body.get("code") == 0 and role == "admin" else "[FAIL]" print(f" 结果: {status_icon}") # ===================== 2. 管理后台 - 仪表盘 ===================== print("\n" + "=" * 60) print("2. 管理后台 - 仪表盘 /api/admin/dashboard/overview") print("=" * 60) code, body = get("/api/admin/dashboard/overview", admin_token) print(f" Code: {body.get('code')}") data = body.get("data", {}) if data: print(f" 活跃会话: {data.get('active_conversations', 'N/A')}") print(f" 在线坐席: {data.get('online_agents', 'N/A')}") print(f" 今日消息: {data.get('today_messages', 'N/A')}") print(f" 数据键: {list(data.keys())}") status_icon = "[OK]" if body.get("code") == 0 else "[FAIL]" print(f" 结果: {status_icon}") # ===================== 3. 管理后台 - 集成列表 ===================== print("\n" + "=" * 60) print("3. 管理后台 - 集成配置 /api/admin/integrations") print("=" * 60) code, body = get("/api/admin/integrations", admin_token) print(f" Code: {body.get('code')}") items = body.get("data", {}).get("items", []) if isinstance(body.get("data"), dict) else [] if not items: print(f" Data: {json.dumps(body.get('data'), ensure_ascii=False)[:200]}") for i in items: name = i.get("name", "?") status = i.get("status", "?") config = i.get("config", {}) has_key = True # status check is sufficient icon = "[OK]" if status in ("active", "connected") else "[!!]" print(f" {icon} {name}: status={status}, config_keys={list(config.keys()) if isinstance(config, dict) else 'N/A'}") status_icon = "[OK]" if body.get("code") == 0 else "[FAIL]" print(f" 结果: {status_icon}") # ===================== 4. 企微回调验证 ===================== print("\n" + "=" * 60) print("4. 企微回调 URL 验证 /api/wecom/callback") print("=" * 60) code, body = get("/api/wecom/callback?msg_signature=5903d061959fc604d0b42d54f78ed7e33e7e9b7c×tamp=1750000000&nonce=test&echostr=testechostr") print(f" Status: {code}") msg = body.get("message", body.get("detail", body.get("raw", str(body)[:200]))) print(f" Response: {str(msg)[:200]}") # 企微验证时如果签名不对会返回错误,但说明接口可达 status_icon = "[OK - reachable]" if code == 200 or (isinstance(msg, str) and ("签名" in msg or "echostr" in msg or "error" in msg.lower())) else "[FAIL]" print(f" 结果: {status_icon}") # ===================== 5. H5 Mock 登录 + 会话 ===================== print("\n" + "=" * 60) print("5. H5 用户端 - Mock 登录 + 创建会话") print("=" * 60) code, body = post("/api/h5/mock-login", {"employee_id": "emp001", "employee_name": "测试员工"}) h5_token = body.get("data", {}).get("token", "") print(f" Mock登录: code={body.get('code')}, token={'有' if h5_token else '无'}") status_icon = "[OK]" if body.get("code") == 0 else "[FAIL]" print(f" 结果: {status_icon}") # 获取当前会话 if h5_token: req = urllib.request.Request(f"{BASE}/api/h5/conversations/current") req.add_header("Authorization", f"Bearer {h5_token}") try: resp = urllib.request.urlopen(req, context=ctx, timeout=10) conv_body = json.loads(resp.read().decode()) print(f" 当前会话: code={conv_body.get('code')}, data_type={type(conv_body.get('data')).__name__}") conv_id = conv_body.get("data", {}).get("id") if isinstance(conv_body.get("data"), dict) else None if conv_id: print(f" 会话ID: {conv_id}") except Exception as e: print(f" 当前会话: error={e}") # ===================== 6. 坐席登录 ===================== print("\n" + "=" * 60) print("6. 坐席工作台 - 坐席登录 (sxn)") print("=" * 60) code, body = post("/api/agents/login", {"user_id": "sxn", "name": "宋献"}) agent_token = body.get("data", {}).get("token", "") agent_role = body.get("data", {}).get("role", "N/A") print(f" Status: {code}") print(f" Code: {body.get('code')}") print(f" Role: {agent_role}") print(f" Token: {'有' if agent_token else '无'}") status_icon = "[OK]" if body.get("code") == 0 else "[FAIL]" print(f" 结果: {status_icon}") # 坐席获取会话列表 if agent_token: print("\n --- 坐席获取会话列表 ---") code2, body2 = get("/api/conversations", agent_token) print(f" 会话列表: code={body2.get('code')}, count={len(body2.get('data', [])) if isinstance(body2.get('data'), list) else 'N/A'}") # ===================== 总结 ===================== print("\n" + "=" * 60) print("验证完成") print("=" * 60)