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.

96 lines
3.0 KiB

2 weeks ago
/**
* common.js 商机模块接口验收公共工具
*
* 用法在各 demo <script src="../common.js"> 引入后直接调用
* const token = await getToken();
* const res = await apiFetch('GET', '/api/opportunity/123');
* renderResult('result', res);
*/
const BASE_URL = 'http://localhost:8080';
const DEBUG_UID = '739564171091247104';
const TOKEN_KEY = 'verify_token';
/** 获取调试 token(优先读 sessionStorage 缓存,避免重复请求) */
async function getToken() {
let t = sessionStorage.getItem(TOKEN_KEY);
if (t) return t;
const r = await fetch(`${BASE_URL}/api/auth/debug/token?userId=${DEBUG_UID}`);
const j = await r.json();
t = j.data;
sessionStorage.setItem(TOKEN_KEY, t);
return t;
}
/**
* 发送带 token HTTP 请求
* @param {string} method - GET / POST / PUT / DELETE
* @param {string} path - /api/ 开头
* @param {object} [body] - JSON bodyGET 时忽略
* @param {object} [query] - URL 查询参数 key-value
* @returns {{ status, ok, data, raw, durationMs }}
*/
async function apiFetch(method, path, body, query) {
const token = await getToken();
let url = BASE_URL + path;
if (query && Object.keys(query).length) {
url += '?' + new URLSearchParams(query).toString();
}
const opts = {
method,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
},
};
if (body && method !== 'GET') {
opts.body = JSON.stringify(body);
}
const t0 = Date.now();
let raw, status, ok;
try {
const resp = await fetch(url, opts);
status = resp.status;
ok = resp.ok;
raw = await resp.text();
} catch (e) {
return { status: 0, ok: false, data: null, raw: String(e), durationMs: Date.now() - t0 };
}
let data = null;
try { data = JSON.parse(raw); } catch (_) { data = raw; }
return { status, ok, data, raw, durationMs: Date.now() - t0 };
}
/**
* 把结果渲染到页面上指定 id <pre> 元素
* @param {string} elementId
* @param {{ status, ok, data, durationMs }} result
*/
function renderResult(elementId, result) {
const el = document.getElementById(elementId);
if (!el) return;
const icon = result.ok ? '✅' : (result.status === 0 ? '🔴' : '⚠️');
const header = `${icon} HTTP ${result.status} (${result.durationMs} ms)\n${'─'.repeat(50)}\n`;
el.textContent = header + (
typeof result.data === 'object'
? JSON.stringify(result.data, null, 2)
: result.raw
);
el.style.color = result.ok ? '#1a7a1a' : '#b00020';
}
/**
* 简单断言辅助写入 <ul id="assertions"> 列表
* @param {string} label - 断言说明
* @param {boolean} pass
* @param {string} [hint] - 失败时显示的附加信息
*/
function assert(label, pass, hint) {
const ul = document.getElementById('assertions');
if (!ul) return;
const li = document.createElement('li');
li.style.color = pass ? '#1a7a1a' : '#b00020';
li.textContent = (pass ? '✅ ' : '❌ ') + label + (hint && !pass ? `${hint}` : '');
ul.appendChild(li);
}