Files
Mycontent/scripts/test/soul_api/test_ckb_leads_submitted.py
乘风 bfd7610527 feat: update CKB workspace and testing documentation
- Added new entries for the 存客宝工作台 (CKB Workbench) in the skills and testing documentation, including mappings for join/match/lead types and related development documentation.
- Enhanced the CKBConfigPanel component to improve user experience with clearer labeling and functionality for managing leads.
- Implemented search functionality in the backend for filtering leads based on user input, improving data retrieval efficiency.
- Updated environment configuration for better clarity and consistency across development settings.

This update aims to enhance the usability of the CKB workspace and streamline lead management processes.
2026-05-08 11:06:43 +08:00

164 lines
5.6 KiB
Python
Raw Permalink 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.

# -*- coding: utf-8 -*-
"""
测试 GET /api/db/ckb-leads?mode=submitted 是否返回 phone、wechatId 字段。
背景:存客宝工作台「加入/匹配提交」表格读这两个字段;旧版 API 未返回会导致全程显示「—」。
用法(仓库根目录)::
pip install -r scripts/test/requirements-test.txt
# 任选其一提供管理端 Token
set ADMIN_TOKEN=eyJhbGciOi... # 浏览器 localStorage「admin_token」
# 或不设 ADMIN_TOKEN用账号密码与 scripts/test/config.py 一致)
set SOUL_ADMIN_USERNAME=admin
set SOUL_ADMIN_PASSWORD=admin123
# 可选SOUL_API_BASE=http://127.0.0.1:8080 或 SOUL_TEST_ENV=local
python scripts/test/soul_api/test_ckb_leads_submitted.py
python scripts/test/soul_api/test_ckb_leads_submitted.py --page-size 5
退出码0 表示每条记录均含 phone/wechatId 键值可为空1 表示请求失败或缺少字段。
"""
from __future__ import annotations
import argparse
import json
import os
import sys
from pathlib import Path
import requests
# 复用 scripts/test 下的 config / util
_TEST_ROOT = Path(__file__).resolve().parent.parent
if str(_TEST_ROOT) not in sys.path:
sys.path.insert(0, str(_TEST_ROOT))
from config import ( # noqa: E402
ADMIN_PASSWORD,
ADMIN_USERNAME,
API_BASE,
ENV_LABEL,
get_env_banner,
)
def _admin_token(base_url: str) -> str:
t = os.environ.get("ADMIN_TOKEN", "").strip()
if t:
return t
try:
r = requests.post(
f"{base_url}/api/admin",
json={"username": ADMIN_USERNAME, "password": ADMIN_PASSWORD},
timeout=15,
)
data = r.json()
if data.get("success") and data.get("token"):
return str(data["token"])
except Exception as e:
print(f"[错误] 管理端登录失败: {e}", file=sys.stderr)
return ""
def _headers(token: str) -> dict:
return {"Authorization": f"Bearer {token}", "Accept": "application/json"}
def main() -> int:
parser = argparse.ArgumentParser(description="测试 ckb-leads submitted 接口字段")
parser.add_argument("--page-size", type=int, default=20, help="每页条数,默认 20")
args = parser.parse_args()
base = os.environ.get("SOUL_API_BASE", "").strip().rstrip("/") or API_BASE
print(get_env_banner())
print(f"请求基址: {base}(当前解析环境: {ENV_LABEL}")
token = _admin_token(base)
if not token:
print(
"[错误] 无管理端 Token。请设置环境变量 ADMIN_TOKEN"
"或配置 SOUL_ADMIN_USERNAME / SOUL_ADMIN_PASSWORD 并能 POST /api/admin 登录。",
file=sys.stderr,
)
return 1
url = f"{base}/api/db/ckb-leads"
params = {"mode": "submitted", "page": 1, "pageSize": min(max(1, args.page_size), 100)}
try:
r = requests.get(url, headers=_headers(token), params=params, timeout=20)
except requests.RequestException as e:
print(f"[错误] 请求异常: {e}", file=sys.stderr)
return 1
if r.status_code == 401:
print("[错误] 401 未授权ADMIN_TOKEN 无效或已过期。", file=sys.stderr)
return 1
if r.status_code != 200:
print(f"[错误] HTTP {r.status_code}: {r.text[:500]}", file=sys.stderr)
return 1
try:
data = r.json()
except json.JSONDecodeError:
print(f"[错误] 响应非 JSON: {r.text[:300]}", file=sys.stderr)
return 1
if not data.get("success"):
print(f"[错误] success=false: {data}", file=sys.stderr)
return 1
records = data.get("records") or []
total = data.get("total")
print(f"\n[INFO] submitted 总数约: {total!r},本页记录数: {len(records)}")
if not records:
print("[通过] 无 join/match 记录,跳过字段检查。")
return 0
missing = []
sample_rows = []
for rec in records:
rid = rec.get("id")
uid = rec.get("userId", "")
mtype = rec.get("matchType", "")
has_phone_key = "phone" in rec
has_wechat_key = "wechatId" in rec
if not has_phone_key or not has_wechat_key:
missing.append(
{"id": rid, "userId": uid, "matchType": mtype, "missing": [k for k, ok in [("phone", has_phone_key), ("wechatId", has_wechat_key)] if not ok]}
)
sample_rows.append(
{
"id": rid,
"userId": uid,
"matchType": mtype,
"phone": rec.get("phone", "<无此键>"),
"wechatId": rec.get("wechatId", "<无此键>"),
}
)
print("\n前几条(节选):")
for row in sample_rows[: min(8, len(sample_rows))]:
print(f" id={row['id']} type={row['matchType']} userId={row['userId']!r} "
f"phone={row['phone']!r} wechatId={row['wechatId']!r}")
if missing:
print("\n[失败] 下列记录缺少 API 字段(需部署含 phone/wechatId 的 soul-api:", file=sys.stderr)
for m in missing[:15]:
print(f" {m}", file=sys.stderr)
if len(missing) > 15:
print(f" … 另有 {len(missing) - 15}", file=sys.stderr)
return 1
non_empty_contact = sum(1 for rec in records if (rec.get("phone") or rec.get("wechatId")))
print(f"\n[通过] 本页每条均含 phone、wechatId 键;其中有非空联系方式的条目: {non_empty_contact}/{len(records)}")
print("(值为空仅代表库内该 join/match 行未写入手机/微信,与「工作台是否展示 —」已不是同一类问题)")
return 0
if __name__ == "__main__":
raise SystemExit(main())