# Cursor Rules - API 测试和登录方法 ## 适用范围 - **测试环境**: http://localhost/dev-api - **登录认证**: AES+RSA 双重加密 - **Token 管理**: JWT 认证体系 --- # API 测试和登录方法 ## 1. 🔐 登录方法配置 ### 系统登录接口分析 **接口地址**: `POST http://localhost/dev-api/auth/login` **当前状态**: - ✅ **接口技术实现**: 登录接口正常工作,能够正确处理请求 - ✅ **接口地址确认**: 接口地址 http://localhost/dev-api/auth/login 可正常访问 - ✅ **权限配置问题**: 已解决,admin 用户可以正常登录获取 Token - ✅ **加密登录问题**: 已解决,AES+RSA 双重加密登录正常工作 - ✅ **Token 验证**: Token 有效期 7 天,可正常用于 API 调用 - ✅ **用户权限**: admin 用户具有超级管理员权限 (_:_:\*) ### 🔧 可用的登录方法 #### 方法 1:AES+RSA 加密登录(推荐) ```javascript // 完整的AES+RSA双重加密登录方法 async function encryptedLogin() { const axios = require('axios'); const CryptoJS = require('crypto-js'); const NodeRSA = require('node-rsa'); // 配置信息 const CONFIG = { url: 'http://localhost/dev-api/auth/login', clientId: 'e5cd7e4891bf95d1d19206ce24a7b32e', tenantId: '000000', referer: 'http://localhost/login?redirect=%252Findex', rsaKey: 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==', }; // 生成32位随机AES密钥 function generateAESKey() { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; for (let i = 0; i < 32; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)); } return result; } // AES加密 function aesEncrypt(data, key) { const keyUtf8 = CryptoJS.enc.Utf8.parse(key); return CryptoJS.AES.encrypt(data, keyUtf8, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7, }).toString(); } // RSA加密AES密钥 function rsaEncrypt(aesKey) { const pemKey = `-----BEGIN PUBLIC KEY-----\n${CONFIG.rsaKey}\n-----END PUBLIC KEY-----`; const rsaKey = new NodeRSA(pemKey); rsaKey.setOptions({ encryptionScheme: 'pkcs1' }); const aesKeyBase64 = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(aesKey)); return rsaKey.encrypt(aesKeyBase64, 'base64'); } // 生成AES密钥并加密登录数据 const aesKey = generateAESKey(); const loginData = { tenantId: CONFIG.tenantId, username: 'admin', password: 'admin123', clientId: CONFIG.clientId, grantType: 'password', }; const encryptedData = aesEncrypt(JSON.stringify(loginData), aesKey); const encryptedKey = rsaEncrypt(aesKey); // 设置请求头(按照系统要求的格式) const headers = { 'Content-Type': 'application/json;charset=utf-8', clientid: CONFIG.clientId, // 必需:客户端ID 'encrypt-key': encryptedKey, // 必需:RSA加密的AES密钥 referer: CONFIG.referer, // 必需:来源页面 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', isToken: 'false', isEncrypt: 'true', repeatSubmit: 'false', }; // 发送登录请求 const response = await axios.post(CONFIG.url, encryptedData, { headers: headers, timeout: 10000, }); // 返回Token if (response.data.code === 200 && response.data.data?.access_token) { return response.data.data.access_token; } else { throw new Error(response.data.msg || 'Login failed'); } } ``` #### 方法 2:快速 Token 获取(简化版) ```javascript // 快速获取Token的简化版本 async function getToken(username = 'admin', password = 'admin123') { const { getToken } = require('./test/quick-token-getter'); return await getToken(username, password); } ``` ### 🔧 快速测试工具 #### 使用 test 目录下的测试脚本 ```bash # 在test目录下运行测试 cd test npm install # 安装依赖(axios, crypto-js, node-rsa, colors) # 完整功能版登录测试(推荐) node custom-login-script.js # 快速Token获取测试 node quick-token-getter.js ``` #### 可用的登录脚本 - **`custom-login-script.js`** - 完整功能版,支持 AES+RSA 双重加密 - **`quick-token-getter.js`** - 快速获取版,代码简洁易懂 #### 依赖安装 ```json { "dependencies": { "axios": "^1.7.2", "crypto-js": "^4.2.0", "node-rsa": "^1.1.1", "colors": "^1.4.0" } } ``` #### 🎯 成功获取的 Token 示例 ``` eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJzeXNfdXNlcjoxIiwicm5TdHIiOiJ5MlhvbHRnd1Y2YjUzRnRMVzF4SFR1anRSUERjeGdmYyIsImNsaWVudGlkIjoiZTVjZDdlNDg5MWJmOTVkMWQxOTIwNmNlMjRhN2IzMmUiLCJ0ZW5hbnRJZCI6IjAwMDAwMCIsInVzZXJJZCI6MSwidXNlck5hbWUiOiJhZG1pbiIsImRlcHRJZCI6MTAzLCJkZXB0TmFtZSI6IuaZuuiDveaOp-WItuWtpumZoiIsImRlcHRDYXRlZ29yeSI6IiIsIm5pY2tOYW1lIjoi55ax54uC55qE54uu5a2QTGkifQ.WI6iY3AgwPz7ceI8WDsVy-GaTXZnU-JKUYUTjhQdoKM ``` **Token 解析信息**: - **用户 ID**: 1 - **用户名**: admin - **昵称**: 疯狂狮子 Li - **部门**: 智胜技术开发团队 - **权限**: _:_:\* (超级管理员) - **有效期**: 7 天 - **租户**: 000000 ## 2. ✅ 已解决的问题和解决方案 ### 已解决问题 1:国际化语言头格式问题 - **原问题**: ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1 - **原因**: 服务器端国际化解析器无法正确处理 `'Content-Language': 'zh-cn'` 格式 - **解决方案**: - 使用 `'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8'` 格式 - 或使用标准的 `'Content-Language': 'zh-CN'` 格式 - **状态**: ✅ 已完全解决 ### 已解决问题 2:加密登录技术问题 - **原问题**: AES+RSA 双重加密登录存在技术错误 - **原因**: 加密密钥生成和请求头格式不正确 - **解决方案**: - 使用正确的 32 位随机 AES 密钥生成 - 按照系统要求设置三个关键 Header:clientid、encrypt-key、referer - 使用正确的 RSA-PKCS1 加密方案 - **状态**: ✅ 已完全解决 ### 核心成功要素 1. **必需的 Header 格式**: ```javascript { 'clientid': 'e5cd7e4891bf95d1d19206ce24a7b32e', 'encrypt-key': '[RSA加密的AES密钥]', 'referer': 'http://localhost/login?redirect=%252Findex' } ``` 2. **正确的加密流程**: - 生成 32 位随机 AES 密钥 - 使用 AES-ECB 模式加密登录数据 - 使用 RSA-PKCS1 加密 AES 密钥 - 设置正确的请求头格式 ## 3. 🔍 API 测试最佳实践 ### 测试环境配置 ```javascript const config = { baseURL: 'http://localhost/dev-api', timeout: 10000, headers: { 'Content-Type': 'application/json;charset=utf-8', clientid: 'e5cd7e4891bf95d1d19206ce24a7b32e', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', referer: 'http://localhost/login?redirect=%252Findex', }, }; ``` ### 通用 API 测试方法 ```javascript // 通用API测试方法 async function testAPI(endpoint, data, options = {}) { const axios = require('axios'); try { const response = await axios({ method: options.method || 'POST', url: `http://localhost/dev-api${endpoint}`, data: data, headers: { 'Content-Type': 'application/json;charset=utf-8', clientid: 'e5cd7e4891bf95d1d19206ce24a7b32e', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', referer: 'http://localhost/login?redirect=%252Findex', Authorization: options.token ? `Bearer ${options.token}` : undefined, ...options.headers, }, timeout: 10000, }); return { success: true, data: response.data, status: response.status, }; } catch (error) { return { success: false, error: error.response?.data || error.message, status: error.response?.status, }; } } ``` ### 带 Token 的 API 调用 ```javascript // 带Token的API调用示例 async function callAPIWithToken(token, endpoint, data, method = 'GET') { return await testAPI(endpoint, data, { method: method, token: token, headers: { clientid: 'e5cd7e4891bf95d1d19206ce24a7b32e', referer: 'http://localhost/login?redirect=%252Findex', }, }); } // 使用示例 async function getUserInfo(token) { const result = await callAPIWithToken(token, '/system/user/getInfo', null, 'GET'); return result; } // 调用带参数的API async function getUserList(token, params) { const result = await callAPIWithToken(token, '/system/user/list', params, 'GET'); return result; } ``` ### 分页接口测试 ```javascript // 分页接口测试模板 async function testPaginationAPI(token, endpoint, params = {}) { const defaultParams = { pageNum: 1, pageSize: 10, ...params, }; const result = await callAPIWithToken(token, endpoint, defaultParams, 'GET'); if (result.success) { console.log('分页接口测试成功:'); console.log(`总记录数: ${result.data.total}`); console.log(`当前页数据: ${result.data.rows?.length || 0} 条`); console.log('响应格式正确 ✅'); } else { console.log('分页接口测试失败:', result.error); } return result; } // 使用示例 async function testUserListAPI(token) { return await testPaginationAPI(token, '/system/user/list', { userName: 'admin', status: '0', }); } ``` ### CRUD 接口测试套件 ```javascript // CRUD接口完整测试套件 async function testCRUDAPIs(token, baseEndpoint, testData) { const results = { create: null, read: null, update: null, delete: null, }; try { // 1. 测试创建 (CREATE) console.log('测试创建接口...'); results.create = await callAPIWithToken(token, baseEndpoint, testData, 'POST'); if (results.create.success) { console.log('✅ 创建接口测试通过'); const createdId = results.create.data.data?.id; // 2. 测试读取 (READ) if (createdId) { console.log('测试读取接口...'); results.read = await callAPIWithToken( token, `${baseEndpoint}/${createdId}`, null, 'GET', ); if (results.read.success) { console.log('✅ 读取接口测试通过'); // 3. 测试更新 (UPDATE) console.log('测试更新接口...'); const updateData = { ...testData, id: createdId, name: testData.name + '_updated', }; results.update = await callAPIWithToken(token, baseEndpoint, updateData, 'PUT'); if (results.update.success) { console.log('✅ 更新接口测试通过'); } // 4. 测试删除 (DELETE) console.log('测试删除接口...'); results.delete = await callAPIWithToken( token, `${baseEndpoint}/${createdId}`, null, 'DELETE', ); if (results.delete.success) { console.log('✅ 删除接口测试通过'); } } } } } catch (error) { console.error('CRUD测试出现异常:', error); } return results; } ``` ## 4. 🐍 Python API 测试最佳实践 ### 💡 基于场地预约 API 测试脚本的成功经验 **⚠️ 本规范基于`test/场地预约API测试脚本.py`的开发实践制定,适用于所有新 API 模块测试** #### 🔧 强制加密登录要求 **所有 API 测试脚本必须使用 AES+RSA 双重加密登录,禁止简化登录和无认证访问** ```python # 强制依赖检查 try: from Crypto.Cipher import AES from Crypto.Util.Padding import pad from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 CRYPTO_AVAILABLE = True print("✅ 加密库已加载,将使用AES+RSA双重加密登录") except ImportError: print("❌ 错误:缺少必需的加密库!") print("🔧 请安装加密库:pip install pycryptodome") print("📖 参考文档:.cursor/cursorrules-api-test.md") print("🚫 脚本退出,必须使用加密登录方式") exit(1) ``` #### 📋 标准测试脚本结构 **基于场地预约 API 测试的成功模式**: ```python class [Module]APITest: def __init__(self, base_url="http://localhost/dev-api"): self.base_url = base_url self.session = requests.Session() self.token = None self.user_info = None # API测试配置 - 参考cursorrules-api-test.md self.config = { 'clientId': 'e5cd7e4891bf95d1d19206ce24a7b32e', 'tenantId': '000000', 'referer': 'http://localhost/login?redirect=%252Findex', 'rsaKey': 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==' } # 设置标准Headers self.session.headers.update({ 'Content-Type': 'application/json;charset=utf-8', 'clientid': self.config['clientId'], 'referer': self.config['referer'], 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'isToken': 'false', 'isEncrypt': 'false', 'repeatSubmit': 'false' }) def generate_aes_key(self): """生成32位随机AES密钥""" chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' return ''.join(random.choices(chars, k=32)) def aes_encrypt(self, data, key): """AES加密 - ECB模式""" key_bytes = key.encode('utf-8') data_bytes = data.encode('utf-8') padded_data = pad(data_bytes, AES.block_size) cipher = AES.new(key_bytes, AES.MODE_ECB) encrypted_data = cipher.encrypt(padded_data) return base64.b64encode(encrypted_data).decode('utf-8') def rsa_encrypt(self, aes_key): """RSA加密AES密钥""" pem_key = f"-----BEGIN PUBLIC KEY-----\n{self.config['rsaKey']}\n-----END PUBLIC KEY-----" rsa_key = RSA.import_key(pem_key) aes_key_base64 = base64.b64encode(aes_key.encode('utf-8')).decode('utf-8') cipher = PKCS1_v1_5.new(rsa_key) encrypted_data = cipher.encrypt(aes_key_base64.encode('utf-8')) return base64.b64encode(encrypted_data).decode('utf-8') def login(self, username="admin", password="admin123"): """强制AES+RSA双重加密登录""" self.log("🔐 开始AES+RSA双重加密登录...") try: # 生成AES密钥 aes_key = self.generate_aes_key() # 构造登录数据 login_data = { "tenantId": self.config['tenantId'], "username": username, "password": password, "clientId": self.config['clientId'], "grantType": "password" } # AES加密登录数据 login_json = json.dumps(login_data, separators=(',', ':')) encrypted_data = self.aes_encrypt(login_json, aes_key) # RSA加密AES密钥 encrypted_key = self.rsa_encrypt(aes_key) # 设置加密登录Headers headers = { 'Content-Type': 'application/json;charset=utf-8', 'clientid': self.config['clientId'], 'encrypt-key': encrypted_key, 'referer': self.config['referer'], 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'isToken': 'false', 'isEncrypt': 'true', 'repeatSubmit': 'false' } # 发送登录请求 response = self.session.post( f"{self.base_url}/auth/login", data=encrypted_data, headers=headers, timeout=10 ) if response.status_code == 200: result = response.json() if result.get('code') == 200 and result.get('data'): # 获取Token token_fields = ['access_token', 'token', 'accessToken'] for field in token_fields: if field in result['data']: self.token = result['data'][field] break if self.token: self.user_info = result['data'] # 设置认证header self.session.headers.update({ 'Authorization': f'Bearer {self.token}', 'isToken': 'true', 'isEncrypt': 'false' }) self.log("✅ AES+RSA双重加密登录成功!") return True self.log("❌ AES+RSA双重加密登录失败") return False except Exception as e: self.log(f"❌ 登录异常: {str(e)}") return False def get_server_info(self): """检测服务可用性""" test_endpoints = ["/actuator/health", "/auth/login"] for endpoint in test_endpoints: try: response = self.session.get(f"{self.base_url}{endpoint}", timeout=5) if response.status_code in [200, 401, 403]: self.log(f"✓ 服务可用: {endpoint}") return True except: continue return False def api_request(self, method, url, data=None, params=None): """标准API请求封装""" try: full_url = f"{self.base_url}{url}" if method.upper() == 'GET': response = self.session.get(full_url, params=params) elif method.upper() == 'POST': response = self.session.post(full_url, json=data, params=params) elif method.upper() == 'PUT': response = self.session.put(full_url, json=data) elif method.upper() == 'DELETE': response = self.session.delete(full_url) self.log(f"{method} {url} - HTTP {response.status_code}") if response.status_code == 200: return response.json() else: self.log(f"请求失败: {response.text}") return None except Exception as e: self.log(f"请求异常: {str(e)}") return None def test_entity_management(self): """基础实体管理测试(CRUD)""" # 1. 查询列表 # 2. 新增数据 # 3. 查询详情 # 4. 修改数据 # 5. 删除数据 pass def test_business_features(self): """业务功能测试""" # 特定业务规则和功能测试 pass def test_business_rules(self): """业务规则验证测试""" # 边界条件和异常情况测试 pass def cleanup_test_data(self): """清理测试数据""" # 删除测试过程中创建的数据 pass def run_all_tests(self): """执行完整测试流程""" # 1. 检测服务可用性 if not self.get_server_info(): self.log("后端服务不可用,测试终止") return False # 2. 强制加密登录 if not self.login(): self.log("❌ AES+RSA双重加密登录失败,测试终止") return False try: # 3. 执行各类测试 self.test_entity_management() self.test_business_features() self.test_business_rules() finally: # 4. 清理测试数据 self.cleanup_test_data() return True ``` #### 🚨 强制性要求 **每个新的 API 测试脚本必须遵循**: 1. **强制加密登录**:不得使用简化登录或无认证访问 2. **完整功能覆盖**:测试所有 API 接口(通常 16 个) 3. **业务规则验证**:包含边界条件和异常情况测试 4. **自动数据清理**:测试完成后清理创建的数据 5. **详细日志记录**:每个步骤都有清晰的日志输出 #### 📦 依赖要求 ```bash # 必需的Python包 pip install requests pycryptodome ``` #### 🎯 测试脚本命名规范 ``` test/ ├── [模块名]API测试脚本.py # 主测试脚本 ├── [模块名]API批量测试脚本.py # 批量测试脚本(可选) └── [模块名]API性能测试脚本.py # 性能测试脚本(可选) ``` #### 📊 测试覆盖标准 **基于场地预约 API 的 16 个接口模式**: **基础管理接口(6 个)**: - ✅ 分页查询列表测试 - ✅ 查询详情测试 - ✅ 新增功能测试 - ✅ 修改功能测试 - ✅ 删除功能测试 - ✅ 获取可用选项测试 **业务功能接口(4 个)**: - ✅ 查询我的数据测试 - ✅ 查询待处理数据测试 - ✅ 业务规则检查测试 - ✅ 审批操作测试 **辅助功能接口(6 个)**: - ✅ 导出 Excel 测试 - ✅ 导入 Excel 测试 - ✅ 统计数据测试 - ✅ 批量操作测试 - ✅ 启用操作测试 - ✅ 禁用操作测试 ## 5. 📝 API 测试记录模板 ### 测试结果记录格式 ```markdown ## API 测试记录 - YYYY-MM-DD **测试环境**: http://localhost/dev-api **测试时间**: YYYY-MM-DD HH:mm:ss **测试人员**: [测试人员] ### 登录测试 - **方法**: AES+RSA 双重加密登录 - **结果**: ✅ 登录成功 - **Token**: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9... - **用户信息**: admin / 疯狂狮子 Li / 超级管理员 - **权限**: _:_:\* (完全权限) - **有效期**: 7 天 ### 业务 API 测试 - **接口**: [接口地址] - **方法**: [HTTP 方法] - **权限**: [需要的权限] - **结果**: [测试结果] - **响应时间**: [响应时间 ms] - **状态码**: [HTTP 状态码] ### 成功要素记录 1. **Header 配置**: 正确设置 clientid、encrypt-key、referer 2. **加密机制**: AES+RSA 双重加密正常工作 3. **语言头格式**: 使用 Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 ### 验证结果 - ✅ 登录接口正常工作 - ✅ Token 有效可用于 API 调用 - ✅ 用户权限验证通过 - ✅ 加密解密机制正常 ``` ### 详细测试报告模板 ```markdown # API 接口测试报告 ## 🎯 测试概览 **测试时间**: YYYY-MM-DD HH:mm:ss **测试范围**: [具体测试的 API 模块] **测试环境**: http://localhost/dev-api **测试工具**: Node.js + Axios + 自定义脚本 ## 📁 测试脚本路径 **登录脚本**: `test/custom-login-script.js` **API 测试脚本**: `test/[功能]-api-test.js` ## 🔐 认证测试 ### 登录接口测试 - **接口地址**: POST /auth/login - **加密方式**: AES+RSA 双重加密 - **测试结果**: ✅ 成功 - **Token 获取**: ✅ 正常 - **Token 有效期**: 7 天 ### Token 验证测试 - **Authorization 格式**: Bearer {token} - **必需 Header**: clientid, referer, Accept-Language - **权限验证**: ✅ admin 用户完全权限 ## 🔍 业务接口测试 ### [模块名称]接口测试 #### 列表查询接口 - **接口**: GET /[module]/list - **参数**: pageNum, pageSize, [查询条件] - **响应格式**: {total, rows, code, msg} - **测试结果**: ✅ 通过 - **响应时间**: [x]ms #### 详情查询接口 - **接口**: GET /[module]/{id} - **响应格式**: {code, msg, data} - **测试结果**: ✅ 通过 - **响应时间**: [x]ms #### 新增接口 - **接口**: POST /[module] - **请求格式**: JSON 对象 - **响应格式**: {code, msg, data} - **测试结果**: ✅ 通过 - **响应时间**: [x]ms #### 修改接口 - **接口**: PUT /[module] - **请求格式**: JSON 对象(包含 id) - **响应格式**: {code, msg, data} - **测试结果**: ✅ 通过 - **响应时间**: [x]ms #### 删除接口 - **接口**: DELETE /[module]/{id} - **响应格式**: {code, msg, data} - **测试结果**: ✅ 通过 - **响应时间**: [x]ms ## 📊 测试统计 - **总接口数**: [数量] - **测试通过**: [数量] - **测试失败**: [数量] - **通过率**: [百分比]% ## ⚠️ 问题记录 [记录测试中发现的问题] ## 🎯 结论 [测试结论和建议] --- **测试执行**: 基于 `test/` 目录下的测试脚本 **文档路径**: `docs/测试文档/[模块]/[功能]/[报告名称]-YYYY-MM-DD.md` ``` ## 5. 🎯 开发和测试建议 ### ✅ 已完成的核心功能 1. **登录认证**: AES+RSA 双重加密登录机制完全正常 2. **Token 获取**: 可稳定获取 7 天有效期的 JWT Token 3. **权限验证**: admin 用户具有完全权限 (_:_:\*) 4. **API 调用**: Token 可正常用于所有业务 API 调用 ### 🔧 开发最佳实践 1. **使用标准脚本**: 优先使用 `test/custom-login-script.js` 获取 Token 2. **Header 规范**: 始终包含 clientid、encrypt-key、referer 三个关键 Header 3. **语言头格式**: 使用 `Accept-Language: zh-CN,zh;q=0.9,en;q=0.8` 4. **错误处理**: 实现 Token 过期自动重新获取机制 ### 🚀 后续优化建议 1. **Token 管理**: 实现 Token 自动刷新和缓存机制 2. **环境配置**: 支持开发、测试、生产环境的灵活切换 3. **自动化测试**: 建立基于 Token 的自动化 API 测试流程 4. **性能监控**: 添加 API 响应时间和成功率监控 ### 📚 相关文档和工具 - **成功的登录脚本**: `test/custom-login-script.js` 和 `test/quick-token-getter.js` - **使用指南**: `test/登录脚本使用说明.md` - **API 文档**: `docs/开发文档/API.md` - **变更记录**: `docs/变更管理/code-adjust-record.md` ### 🎯 使用建议 1. **开发阶段**: 使用 `quick-token-getter.js` 快速获取 Token 进行测试 2. **集成测试**: 使用 `custom-login-script.js` 进行完整的登录流程测试 3. **生产环境**: 将加密登录逻辑集成到实际应用中,实现自动 Token 管理 ## 6. 🧪 自动化测试脚本 ### 完整的 API 测试流程 ```javascript // 完整的API自动化测试脚本示例 async function runCompleteAPITest() { console.log('🚀 开始API自动化测试...\n'); try { // 1. 获取Token console.log('1️⃣ 获取登录Token...'); const token = await encryptedLogin(); console.log('✅ Token获取成功\n'); // 2. 测试用户信息接口 console.log('2️⃣ 测试用户信息接口...'); const userInfo = await getUserInfo(token); if (userInfo.success) { console.log('✅ 用户信息接口测试通过'); console.log(`用户: ${userInfo.data.data.user.userName}`); console.log(`权限: ${userInfo.data.data.permissions}\n`); } // 3. 测试分页列表接口 console.log('3️⃣ 测试分页列表接口...'); const userList = await testUserListAPI(token); if (userList.success) { console.log('✅ 分页列表接口测试通过\n'); } // 4. 测试CRUD接口(可选) console.log('4️⃣ 测试CRUD接口...'); // const crudResults = await testCRUDAPIs(token, '/system/dept', testDeptData); console.log('🎉 API自动化测试完成!'); } catch (error) { console.error('❌ 测试失败:', error.message); } } // 执行测试 runCompleteAPITest(); ``` ### 性能测试脚本 ```javascript // API性能测试脚本 async function performanceTest(token, endpoint, concurrent = 10, iterations = 100) { console.log(`开始性能测试: ${endpoint}`); console.log(`并发数: ${concurrent}, 迭代次数: ${iterations}\n`); const startTime = Date.now(); const results = []; for (let i = 0; i < concurrent; i++) { const promises = []; for (let j = 0; j < iterations / concurrent; j++) { promises.push( callAPIWithToken(token, endpoint, null, 'GET') .then((result) => ({ success: result.success, time: Date.now(), })) .catch((error) => ({ success: false, error: error.message, time: Date.now(), })), ); } results.push(...(await Promise.all(promises))); } const endTime = Date.now(); const totalTime = endTime - startTime; const successCount = results.filter((r) => r.success).length; const failCount = results.length - successCount; console.log('📊 性能测试结果:'); console.log(`总请求数: ${results.length}`); console.log(`成功数: ${successCount}`); console.log(`失败数: ${failCount}`); console.log(`成功率: ${((successCount / results.length) * 100).toFixed(2)}%`); console.log(`总耗时: ${totalTime}ms`); console.log(`平均响应时间: ${(totalTime / results.length).toFixed(2)}ms`); console.log(`QPS: ${(results.length / (totalTime / 1000)).toFixed(2)} req/s`); return { total: results.length, success: successCount, fail: failCount, successRate: successCount / results.length, totalTime, avgResponseTime: totalTime / results.length, qps: results.length / (totalTime / 1000), }; } ``` --- **🎉 成功状态**: 登录获取 Token 功能已完全实现并正常工作,可以稳定用于 API 开发和测试。