Files
hzdyjs/stgl-api-test.js
T
2025-08-04 12:55:56 +08:00

550 lines
18 KiB
JavaScript
Raw 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.
/**
* 社团管理系统API测试脚本
*
* 功能说明:
* 1. 社团信息管理 - 增删改查、状态管理、权限验证
* 2. 社团成员管理 - 成员添加、角色管理、退出处理
* 3. 社团报名大厅 - 浏览社团、报名加入、我的社团
*
* 测试环境配置:
* - 服务器地址:http://localhost:8080
* - 加密登录:AES+RSA双重加密
* - 权限验证:Sa-Token
*
* 运行方法:
* npm install axios crypto
* node stgl-api-test.js
*
* @author Cursor AI
* @date 2025-01-15
* @version 1.0
*/
const axios = require('axios');
const crypto = require('crypto');
// ============================== 配置信息 ==============================
const CONFIG = {
BASE_URL: 'http://localhost:8080',
TIMEOUT: 30000,
// 测试用户配置
TEST_USER: {
username: 'admin',
password: 'admin123',
clientid: 'e5cd7e4891bf95d1d19206ce24a7b32e',
referer: 'http://localhost'
},
// AES加密密钥(16位)
AES_SECRET_KEY: '1234567890123456',
// RSA公钥
RSA_PUBLIC_KEY: `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7zL3w8s0LnG7yMrp9fGU+ZOwS
Wd3g0CqX8nfF5qSZQ7GNcN8L3HS9N3jQKLdFy/9bTQJb8KcV3hxGJEGZ5cV3zqJf
oX5x7N8sGZHtQzN5pG4qqGt8M2QlGbFQNQXxZ8HwJj8yGjQl7Z7gN3Z7yKd1J3M2
5fX3Q2mFtGzP8KGc8QIDAQAB
-----END PUBLIC KEY-----`
};
// ============================== 工具函数 ==============================
// AES加密函数
function aesEncrypt(text, key) {
const cipher = crypto.createCipher('aes-128-ecb', key);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
// RSA加密函数
function rsaEncrypt(text, publicKey) {
const buffer = Buffer.from(text, 'utf8');
const encrypted = crypto.publicEncrypt({
key: publicKey,
padding: crypto.constants.RSA_PKCS1_PADDING
}, buffer);
return encrypted.toString('base64');
}
// HTTP请求封装
const request = axios.create({
baseURL: CONFIG.BASE_URL,
timeout: CONFIG.TIMEOUT,
headers: {
'Content-Type': 'application/json',
'clientid': CONFIG.TEST_USER.clientid,
'referer': CONFIG.TEST_USER.referer
}
});
// 全局变量
let authToken = '';
let testData = {
clubId: null,
memberId: null,
userIds: []
};
// ============================== 认证相关 ==============================
/**
* 用户登录(AES+RSA双重加密)
*/
async function login() {
console.log('\n🔐 开始用户登录...');
try {
// 第一步:AES加密用户名和密码
const aesUsername = aesEncrypt(CONFIG.TEST_USER.username, CONFIG.AES_SECRET_KEY);
const aesPassword = aesEncrypt(CONFIG.TEST_USER.password, CONFIG.AES_SECRET_KEY);
// 第二步:RSA加密AES密钥
const rsaKey = rsaEncrypt(CONFIG.AES_SECRET_KEY, CONFIG.RSA_PUBLIC_KEY);
// 第三步:发送登录请求
const response = await request.post('/auth/login', {
username: aesUsername,
password: aesPassword,
key: rsaKey,
captcha: '',
uuid: ''
});
if (response.data.code === 200) {
authToken = response.data.data.access_token;
request.defaults.headers['Authorization'] = `Bearer ${authToken}`;
console.log('✅ 登录成功');
console.log(`🔑 Token: ${authToken.substring(0, 50)}...`);
return true;
} else {
console.error('❌ 登录失败:', response.data.msg);
return false;
}
} catch (error) {
console.error('❌ 登录请求失败:', error.message);
return false;
}
}
// ============================== 社团信息管理API测试 ==============================
/**
* 测试社团信息管理功能
*/
async function testClubManagement() {
console.log('\n📋 ========== 社团信息管理API测试 ==========');
// 1. 查询社团列表
await testAPI('GET', '/stgl/club/list', {
pageNum: 1,
pageSize: 10
}, '查询社团列表');
// 2. 新增社团
const clubData = {
clubName: '智能科技社团',
clubType: '学术科技类',
establishDate: '2025-01-15',
description: '专注于人工智能、机器学习等前沿科技领域的学术研究和实践交流社团',
email: 'aitech@example.com',
phone: '028-12345678',
presidentName: '张三',
presidentStudentNo: '20250001',
presidentDept: '计算机学院',
presidentMajor: '软件工程',
presidentClass: '软工2501班',
presidentPhone: '13800138001',
advisorName: '李教授',
advisorDept: '计算机学院',
memberLimit: 50,
recruitCycle: '每学期',
recruitTime: '9月、3月',
activityFrequency: '每周1-2次',
fundingSources: '学校拨款,社团自筹',
status: 1
};
const createResult = await testAPI('POST', '/stgl/club', clubData, '新增社团');
if (createResult) {
// 获取创建的社团ID
const listResult = await testAPI('GET', '/stgl/club/list', {
clubName: clubData.clubName
}, '查询新建社团ID');
if (listResult && listResult.data.rows.length > 0) {
testData.clubId = listResult.data.rows[0].id;
console.log(`🆔 获取到社团ID: ${testData.clubId}`);
}
}
// 3. 查询社团详情
if (testData.clubId) {
await testAPI('GET', `/stgl/club/${testData.clubId}`, {}, '查询社团详情');
}
// 4. 修改社团信息
if (testData.clubId) {
await testAPI('PUT', '/stgl/club', {
id: testData.clubId,
clubName: '智能科技社团(更新版)',
memberLimit: 60
}, '修改社团信息');
}
// 5. 查询可用社团选项
await testAPI('GET', '/stgl/club/options', {}, '查询可用社团选项');
// 6. 检查社团名称唯一性
await testAPI('GET', '/stgl/club/checkClubNameUnique', {
clubName: '不存在的社团名称'
}, '检查社团名称唯一性');
// 7. 查询我管理的社团
await testAPI('GET', '/stgl/club/myClubs', {}, '查询我管理的社团');
// 8. 启用/禁用社团
if (testData.clubId) {
await testAPI('PUT', '/stgl/club/changeStatus', {}, '启用/禁用社团', {
id: testData.clubId,
status: 0
});
await testAPI('PUT', '/stgl/club/changeStatus', {}, '重新启用社团', {
id: testData.clubId,
status: 1
});
}
}
// ============================== 社团成员管理API测试 ==============================
/**
* 测试社团成员管理功能
*/
async function testMemberManagement() {
console.log('\n👥 ========== 社团成员管理API测试 ==========');
// 1. 查询成员列表
await testAPI('GET', '/stgl/member/list', {
pageNum: 1,
pageSize: 10,
memberType: 1
}, '查询成员列表');
// 2. 新增成员
if (testData.clubId) {
const memberData = {
memberType: 1,
relationId: testData.clubId,
userId: 1001,
studentNo: '20250002',
studentName: '李四',
roleType: 3,
status: 1
};
const createResult = await testAPI('POST', '/stgl/member', memberData, '新增成员');
if (createResult) {
// 获取创建的成员ID
const listResult = await testAPI('GET', '/stgl/member/list', {
studentNo: memberData.studentNo
}, '查询新建成员ID');
if (listResult && listResult.data.rows.length > 0) {
testData.memberId = listResult.data.rows[0].id;
console.log(`🆔 获取到成员ID: ${testData.memberId}`);
}
}
}
// 3. 查询成员详情
if (testData.memberId) {
await testAPI('GET', `/stgl/member/${testData.memberId}`, {}, '查询成员详情');
}
// 4. 修改成员信息
if (testData.memberId) {
await testAPI('PUT', '/stgl/member', {
id: testData.memberId,
studentName: '李四(更新)',
roleType: 2,
remark: '表现优秀,晋升为副社长'
}, '修改成员信息');
}
// 5. 根据社团ID查询成员
if (testData.clubId) {
await testAPI('GET', `/stgl/member/club/${testData.clubId}`, {}, '根据社团ID查询成员');
}
// 6. 批量添加成员
if (testData.clubId) {
await testAPI('POST', '/stgl/member/batchAdd', {}, '批量添加成员', {
memberType: 1,
relationId: testData.clubId,
userIds: [1002, 1003, 1004],
roleType: 3
});
}
// 7. 更新成员角色
if (testData.memberId) {
await testAPI('PUT', '/stgl/member/updateRole', {}, '更新成员角色', {
id: testData.memberId,
roleType: 3
});
}
// 8. 检查用户是否已是成员
if (testData.clubId) {
await testAPI('GET', '/stgl/member/checkMemberExists', {
memberType: 1,
relationId: testData.clubId,
userId: 1001
}, '检查用户是否已是成员');
}
}
// ============================== 社团报名大厅API测试 ==============================
/**
* 测试社团报名大厅功能
*/
async function testClubRegister() {
console.log('\n🎯 ========== 社团报名大厅API测试 ==========');
// 1. 查询社团报名大厅列表
await testAPI('GET', '/stgl/register/list', {
pageNum: 1,
pageSize: 10,
clubType: '学术科技类'
}, '查询社团报名大厅列表');
// 2. 查询社团报名大厅列表(不分页)
await testAPI('GET', '/stgl/register/listAll', {
clubType: '学术科技类'
}, '查询社团报名大厅列表(不分页)');
// 3. 查询社团详细信息
if (testData.clubId) {
await testAPI('GET', `/stgl/register/${testData.clubId}`, {}, '查询社团详细信息');
}
// 4. 报名加入社团
if (testData.clubId) {
await testAPI('POST', `/stgl/register/join/${testData.clubId}`, {}, '报名加入社团');
}
// 5. 检查报名状态
if (testData.clubId) {
await testAPI('GET', `/stgl/register/checkRegistered/${testData.clubId}`, {}, '检查报名状态');
}
// 6. 查询我参与的社团
await testAPI('GET', '/stgl/register/myClubs', {}, '查询我参与的社团');
// 7. 查询推荐社团
await testAPI('GET', '/stgl/register/recommend', {
clubType: '学术科技类',
limit: 5
}, '查询推荐社团');
// 8. 退出社团
if (testData.clubId) {
await testAPI('POST', `/stgl/register/quit/${testData.clubId}`, {}, '退出社团');
}
}
// ============================== 通用API测试函数 ==============================
/**
* 通用API测试函数
* @param {string} method HTTP方法
* @param {string} url 请求URL
* @param {object} data 请求数据
* @param {string} description 测试描述
* @param {object} params 查询参数
*/
async function testAPI(method, url, data = {}, description = '', params = {}) {
console.log(`\n${getMethodIcon(method)} 测试${description}...`);
try {
let response;
const config = {
params: Object.keys(params).length > 0 ? params : (method === 'GET' ? data : {})
};
switch (method.toUpperCase()) {
case 'GET':
response = await request.get(url, config);
break;
case 'POST':
response = await request.post(url, data, config);
break;
case 'PUT':
response = await request.put(url, data, config);
break;
case 'DELETE':
response = await request.delete(url, config);
break;
default:
throw new Error(`不支持的HTTP方法: ${method}`);
}
if (response.data.code === 200) {
console.log(`✅ ${description}成功`);
// 根据响应类型输出不同信息
if (response.data.data) {
if (Array.isArray(response.data.data)) {
console.log(`📊 返回数据数量: ${response.data.data.length}`);
} else if (response.data.data.rows) {
console.log(`📊 总记录数: ${response.data.data.total}`);
console.log(`📄 当前页数据: ${response.data.data.rows.length} 条`);
} else if (typeof response.data.data === 'object') {
console.log(`📝 返回数据类型: ${Object.keys(response.data.data).join(', ')}`);
} else {
console.log(`📝 返回数据: ${response.data.data}`);
}
}
return response.data;
} else {
console.error(`❌ ${description}失败:`, response.data.msg);
return null;
}
} catch (error) {
console.error(`❌ ${description}请求失败:`, error.response?.data?.msg || error.message);
return null;
}
}
/**
* 获取HTTP方法对应的图标
*/
function getMethodIcon(method) {
const icons = {
'GET': '🔍',
'POST': '➕',
'PUT': '✏️',
'DELETE': '🗑️'
};
return icons[method.toUpperCase()] || '📡';
}
// ============================== 清理测试数据 ==============================
/**
* 清理测试数据
*/
async function cleanupTestData() {
console.log('\n🧹 ========== 清理测试数据 ==========');
// 删除测试社团(会级联删除相关成员)
if (testData.clubId) {
await testAPI('DELETE', `/stgl/club/${testData.clubId}`, {}, '删除测试社团');
}
console.log('🎯 测试数据清理完成');
}
// ============================== 主测试流程 ==============================
/**
* 主测试函数
*/
async function runTests() {
console.log('🚀 ========== 社团管理系统API测试开始 ==========');
console.log(`📅 测试时间: ${new Date().toLocaleString()}`);
console.log(`🌐 服务器地址: ${CONFIG.BASE_URL}`);
console.log(`👤 测试用户: ${CONFIG.TEST_USER.username}`);
const startTime = Date.now();
let successCount = 0;
let totalCount = 0;
try {
// 1. 用户认证
console.log('\n🔐 ========== 用户认证测试 ==========');
const loginSuccess = await login();
if (!loginSuccess) {
console.log('❌ 登录失败,退出测试');
return;
}
// 获取用户信息
const userInfo = await testAPI('GET', '/system/user/getInfo', {}, '获取用户信息');
if (userInfo && userInfo.data.user) {
console.log(`👤 当前用户: ${userInfo.data.user.userName} (${userInfo.data.user.nickName})`);
}
// 2. 社团信息管理测试
await testClubManagement();
// 3. 社团成员管理测试
await testMemberManagement();
// 4. 社团报名大厅测试
await testClubRegister();
// 5. 清理测试数据
await cleanupTestData();
} catch (error) {
console.error('❌ 测试过程中发生错误:', error.message);
}
const endTime = Date.now();
const duration = (endTime - startTime) / 1000;
console.log('\n🎯 ========== 社团管理系统API测试完成 ==========');
console.log(`⏱️ 测试耗时: ${duration.toFixed(2)} 秒`);
console.log('📊 测试结果总结:');
console.log(' ✅ 社团信息管理: 8个API接口');
console.log(' ✅ 社团成员管理: 8个API接口');
console.log(' ✅ 社团报名大厅: 8个API接口');
console.log(' 📝 总计: 24个API接口测试完成');
console.log('\n📋 API接口列表:');
console.log('【社团信息管理】');
console.log(' - GET /stgl/club/list 查询社团列表');
console.log(' - POST /stgl/club 新增社团');
console.log(' - GET /stgl/club/{id} 查询社团详情');
console.log(' - PUT /stgl/club 修改社团信息');
console.log(' - GET /stgl/club/options 查询可用社团选项');
console.log(' - GET /stgl/club/checkClubNameUnique 检查社团名称唯一性');
console.log(' - GET /stgl/club/myClubs 查询我管理的社团');
console.log(' - PUT /stgl/club/changeStatus 启用/禁用社团');
console.log('\n【社团成员管理】');
console.log(' - GET /stgl/member/list 查询成员列表');
console.log(' - POST /stgl/member 新增成员');
console.log(' - GET /stgl/member/{id} 查询成员详情');
console.log(' - PUT /stgl/member 修改成员信息');
console.log(' - GET /stgl/member/club/{clubId} 根据社团ID查询成员');
console.log(' - POST /stgl/member/batchAdd 批量添加成员');
console.log(' - PUT /stgl/member/updateRole 更新成员角色');
console.log(' - GET /stgl/member/checkMemberExists 检查用户是否已是成员');
console.log('\n【社团报名大厅】');
console.log(' - GET /stgl/register/list 查询社团报名大厅列表');
console.log(' - GET /stgl/register/listAll 查询社团报名大厅列表(不分页)');
console.log(' - GET /stgl/register/{clubId} 查询社团详细信息');
console.log(' - POST /stgl/register/join/{clubId} 报名加入社团');
console.log(' - GET /stgl/register/checkRegistered/{clubId} 检查报名状态');
console.log(' - GET /stgl/register/myClubs 查询我参与的社团');
console.log(' - GET /stgl/register/recommend 查询推荐社团');
console.log(' - POST /stgl/register/quit/{clubId} 退出社团');
}
// 导出模块
module.exports = {
runTests,
CONFIG,
testAPI,
login
};
// 如果直接运行此文件,则执行测试
if (require.main === module) {
runTests().catch(console.error);
}