test-training-package-flow.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #!/usr/bin/env node
  2. /**
  3. * 测试培训包完整用户流程:
  4. * 1. 凭据检测(从包目录 .env.local 或页面填写)
  5. * 2. 订阅状态检查
  6. * 3. 扫码登录流程
  7. * 4. 工作台与监听启动
  8. */
  9. const http = require('http');
  10. const { spawn } = require('child_process');
  11. const path = require('path');
  12. const TRAINING_DIR = 'D:/qiwei-training';
  13. const DASHBOARD_PORT = 4320;
  14. const FLOW_PORT = 4310;
  15. function request(port, path, method = 'GET', body = null) {
  16. return new Promise((resolve, reject) => {
  17. const options = {
  18. hostname: '127.0.0.1',
  19. port,
  20. path,
  21. method,
  22. headers: body ? { 'Content-Type': 'application/json' } : {}
  23. };
  24. const req = http.request(options, res => {
  25. let data = '';
  26. res.on('data', chunk => data += chunk);
  27. res.on('end', () => {
  28. try {
  29. resolve({ status: res.statusCode, data: JSON.parse(data) });
  30. } catch {
  31. resolve({ status: res.statusCode, data: data });
  32. }
  33. });
  34. });
  35. req.on('error', reject);
  36. if (body) req.write(JSON.stringify(body));
  37. req.end();
  38. });
  39. }
  40. async function sleep(ms) {
  41. return new Promise(resolve => setTimeout(resolve, ms));
  42. }
  43. async function main() {
  44. console.log('=== 企微培训包用户流程测试 ===\n');
  45. // 步骤 1:启动工作台
  46. console.log('步骤 1:启动培训包工作台...');
  47. const workbench = spawn(
  48. path.join(TRAINING_DIR, 'qiwei-workbench.exe'),
  49. ['--no-open'],
  50. {
  51. cwd: TRAINING_DIR,
  52. stdio: 'pipe',
  53. detached: false
  54. }
  55. );
  56. workbench.stdout.on('data', data => {
  57. process.stdout.write(`[工作台] ${data}`);
  58. });
  59. workbench.stderr.on('data', data => {
  60. process.stderr.write(`[工作台错误] ${data}`);
  61. });
  62. await sleep(5000);
  63. // 步骤 2:检查状态接口
  64. console.log('\n步骤 2:检查整体状态...');
  65. try {
  66. const status = await request(DASHBOARD_PORT, '/api/status');
  67. console.log('✓ 状态接口响应:', {
  68. authConfigured: status.data.summary?.authConfigured,
  69. subscribed: status.data.summary?.subscribed,
  70. online: status.data.summary?.online
  71. });
  72. // 步骤 3:Token 检测
  73. if (!status.data.summary?.authConfigured) {
  74. console.log('\n✗ Token 未检测到,需要用户填写');
  75. console.log(' 提示:在页面上粘贴 Fmode r: 会话凭据或 sk- 密钥,或写入 .env.local');
  76. } else {
  77. console.log('\n✓ 凭据已检测到');
  78. }
  79. // 步骤 4:订阅状态
  80. if (!status.data.summary?.subscribed) {
  81. console.log('\n✗ 没有可用席位,需要开通服务');
  82. console.log(' 提示:新账号会先检查 7 天试用;没有试用时访问 http://127.0.0.1:4310 开通席位');
  83. } else {
  84. const sub = status.data.data?.subscription?.data;
  85. console.log(`\n✓ ${sub?.trialActive ? '7 天试用有效' : '服务有效'}:`, {
  86. seats: sub?.seats,
  87. usedSeats: sub?.usedSeats,
  88. expireAt: sub?.expireAt?.slice(0, 10)
  89. });
  90. }
  91. // 步骤 5:登录状态
  92. if (!status.data.summary?.online) {
  93. console.log('\n需要企微扫码登录');
  94. console.log(' 访问工作台会自动引导到登录流程');
  95. } else {
  96. console.log('\n✓ 企微账号已在线');
  97. }
  98. } catch (error) {
  99. console.error('✗ 状态接口失败:', error.message);
  100. }
  101. // 步骤 6:测试登录流程页(如果已开通订阅)
  102. console.log('\n步骤 6:测试登录流程页...');
  103. try {
  104. const flowPage = await request(FLOW_PORT, '/');
  105. if (flowPage.status === 200) {
  106. console.log('✓ 登录流程页可访问 (http://127.0.0.1:4310)');
  107. } else {
  108. console.log(' 登录流程页状态:', flowPage.status);
  109. }
  110. } catch (error) {
  111. console.log(' 登录流程页未启动(订阅未开通时会自动启动)');
  112. }
  113. // 步骤 7:检查监听 Runtime
  114. console.log('\n步骤 7:检查监听 Runtime...');
  115. const statePath = path.join(TRAINING_DIR, 'outputs', 'runtime', 'qiwei-runtime.json');
  116. try {
  117. const fs = require('fs');
  118. const runtimeState = JSON.parse(fs.readFileSync(statePath, 'utf8'));
  119. console.log('✓ 监听 Runtime 运行中:', {
  120. pid: runtimeState.pid,
  121. status: runtimeState.status,
  122. mode: runtimeState.mode
  123. });
  124. } catch {
  125. console.log(' 监听 Runtime 状态文件未找到');
  126. }
  127. console.log('\n=== 测试完成 ===');
  128. console.log('\n现场用户操作顺序:');
  129. console.log(' 1. 双击 qiwei-workbench.exe');
  130. console.log(' 2. 浏览器自动打开工作台页面');
  131. console.log(' 3. 如凭据未检测到,粘贴 Fmode r: 会话凭据或 sk- 密钥');
  132. console.log(' 4. 新账号先使用 7 天试用;试用不可用时再开通席位(跳转付费页)');
  133. console.log(' 5. 扫描企微二维码登录');
  134. console.log(' 6. 添加测试白名单,开启监听');
  135. console.log('\n按 Ctrl+C 停止工作台...');
  136. process.on('SIGINT', () => {
  137. console.log('\n停止工作台...');
  138. workbench.kill();
  139. process.exit(0);
  140. });
  141. }
  142. main().catch(error => {
  143. console.error('测试失败:', error);
  144. process.exit(1);
  145. });