140 lines
4.1 KiB
JavaScript
140 lines
4.1 KiB
JavaScript
/**
|
|
* 教练端 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;
|
|
}
|
|
|
|
module.exports = {
|
|
makeRequest,
|
|
coachLogin,
|
|
getCoachCourses,
|
|
getCourseDetail,
|
|
startCourse,
|
|
endCourse,
|
|
getCourseBookings,
|
|
isSuccess,
|
|
BASE_URL,
|
|
API_BASE
|
|
};
|