/** * 教练端 HTTP API 测试工具 * 支持 HMAC-SHA256 签名 + JWT Bearer Token */ const http = require('http'); const crypto = require('crypto'); const BASE_URL = 'http://192.168.110.64:8084'; const API_BASE = BASE_URL + '/api'; const SIGNATURE_SECRET = 'NovalonManageSystemSecretKey2026'; /** * 生成 HMAC-SHA256 签名头 */ function generateSignatureHeaders(method, path, bodyStr) { const timestamp = Date.now(); const nonce = timestamp.toString(36) + '-' + Math.random().toString(36).substring(2, 8); const stringToSign = [method.toUpperCase(), path, '', bodyStr || '', String(timestamp), nonce].join('\n'); const signature = crypto.createHmac('sha256', SIGNATURE_SECRET).update(stringToSign).digest('base64'); return { 'X-Signature': signature, 'X-Timestamp': String(timestamp), 'X-Nonce': nonce }; } /** * 通用 HTTP 请求 */ function makeRequest(method, url, body, token) { return new Promise((resolve, reject) => { const parsed = new URL(url); const bodyStr = body ? JSON.stringify(body) : ''; const headers = { 'Content-Type': 'application/json', ...generateSignatureHeaders(method, parsed.pathname + parsed.search, bodyStr) }; if (token) { headers['Authorization'] = 'Bearer ' + token; } const options = { hostname: parsed.hostname, port: parsed.port, path: parsed.pathname + parsed.search, method: method, headers: headers, timeout: 15000 }; const req = http.request(options, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { let parsedData; try { parsedData = JSON.parse(data); } catch (e) { parsedData = data; } resolve({ status: res.statusCode, data: parsedData }); }); }); req.on('error', (e) => reject(e)); if (bodyStr) req.write(bodyStr); req.end(); }); } function isSuccess(res) { return res.status >= 200 && res.status < 300; } // ── 教练端 API ── /** 教练登录 */ async function coachLogin(username, password) { console.log(`[API] 教练登录: ${username}`); const res = await makeRequest('POST', `${API_BASE}/auth/login`, { username, password }); console.log(`[API] 登录响应: status=${res.status}`); if (isSuccess(res) && res.data) { return { token: res.data.token, userId: res.data.userId, username: res.data.username }; } return null; } /** 获取教练的团课列表 */ async function getCoachCourses(coachId, token) { console.log(`[API] 获取教练课程: coachId=${coachId}`); const res = await makeRequest('GET', `${API_BASE}/coach/${coachId}/courses`, null, token); console.log(`[API] 课程列表: status=${res.status}`); return res; } /** 获取团课详情 */ async function getCourseDetail(courseId, token) { console.log(`[API] 获取课程详情: courseId=${courseId}`); const res = await makeRequest('GET', `${API_BASE}/groupCourse/${courseId}/detail`, null, token); console.log(`[API] 课程详情: status=${res.status}`); return res; } /** 手动开课 */ async function startCourse(courseId, token) { console.log(`[API] 手动开课: courseId=${courseId}`); const res = await makeRequest('POST', `${API_BASE}/coach/courses/${courseId}/start`, {}, token); console.log(`[API] 开课结果: status=${res.status}`); return res; } /** 手动结课 */ async function endCourse(courseId, token) { console.log(`[API] 手动结课: courseId=${courseId}`); const res = await makeRequest('POST', `${API_BASE}/coach/courses/${courseId}/end`, {}, token); console.log(`[API] 结课结果: status=${res.status}`); return res; } /** 获取课程预约列表 */ async function getCourseBookings(courseId, token) { console.log(`[API] 获取预约列表: courseId=${courseId}`); const res = await makeRequest('GET', `${API_BASE}/groupCourse/bookings/course/${courseId}`, null, token); console.log(`[API] 预约列表: status=${res.status}`); return res; } // ── 品牌定制 API ── /** 获取品牌配置 */ async function getBrandConfig(token) { console.log('[API] 获取品牌配置...'); const res = await makeRequest('GET', `${API_BASE}/brand`, null, token); console.log(`[API] 品牌配置: status=${res.status}`); return res; } // ── 违规记录 API ── /** 获取所有教练违规统计 */ async function getViolationCounts(token) { console.log('[API] 获取违规统计...'); const res = await makeRequest('GET', `${API_BASE}/coach/violation-counts`, null, token); console.log(`[API] 违规统计: status=${res.status}`); return res; } /** 获取指定教练的违规记录 */ async function getCoachViolations(coachId, token) { console.log(`[API] 获取教练违规: coachId=${coachId}`); const res = await makeRequest('GET', `${API_BASE}/coach/${coachId}/violations`, null, token); console.log(`[API] 违规记录: status=${res.status}`); return res; } // ── 通知/消息 API ── /** 获取活跃Banner列表 */ async function getActiveBanners(token) { console.log('[API] 获取活跃Banners...'); const res = await makeRequest('GET', `${API_BASE}/banners/active`, null, token); console.log(`[API] Banners: status=${res.status}`); return res; } /** 获取系统通知列表 */ async function getSystemNotices(token) { console.log('[API] 获取系统通知...'); const res = await makeRequest('GET', `${API_BASE}/notices`, null, token); console.log(`[API] 通知列表: status=${res.status}`); return res; } module.exports = { makeRequest, coachLogin, getCoachCourses, getCourseDetail, startCourse, endCourse, getCourseBookings, getBrandConfig, getViolationCounts, getCoachViolations, getActiveBanners, getSystemNotices, isSuccess, BASE_URL, API_BASE };