RO20250126008-progress-button-test.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. const axios = require('axios');
  2. const colors = require('colors');
  3. // 测试配置
  4. const CONFIG = {
  5. baseURL: 'http://localhost/dev-api',
  6. orderNo: 'RO20250126008',
  7. username: 'zwc007',
  8. password: 'admin123', // 需要根据实际密码调整
  9. timeout: 10000,
  10. };
  11. /**
  12. * 获取Token的通用函数
  13. */
  14. async function getToken(username, password) {
  15. const { getToken } = require('./quick-token-getter');
  16. return await getToken(username, password);
  17. }
  18. /**
  19. * 测试API调用的通用函数
  20. */
  21. async function testAPI(endpoint, data, options = {}) {
  22. try {
  23. const response = await axios({
  24. method: options.method || 'GET',
  25. url: `${CONFIG.baseURL}${endpoint}`,
  26. data: data,
  27. headers: {
  28. 'Content-Type': 'application/json;charset=utf-8',
  29. clientid: 'e5cd7e4891bf95d1d19206ce24a7b32e',
  30. 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
  31. referer: 'http://localhost/login?redirect=%252Findex',
  32. Authorization: options.token ? `Bearer ${options.token}` : undefined,
  33. ...options.headers,
  34. },
  35. timeout: CONFIG.timeout,
  36. });
  37. return {
  38. success: true,
  39. data: response.data,
  40. status: response.status,
  41. };
  42. } catch (error) {
  43. return {
  44. success: false,
  45. error: error.response?.data || error.message,
  46. status: error.response?.status,
  47. };
  48. }
  49. }
  50. /**
  51. * 测试工单RO20250126008的更新进度按钮
  52. */
  53. async function testRO20250126008UpdateProgressButton() {
  54. console.log('\n' + '='.repeat(80));
  55. console.log(colors.cyan.bold(' 工单RO20250126008更新进度按钮测试'));
  56. console.log('='.repeat(80));
  57. console.log(colors.yellow(`测试时间: ${new Date().toLocaleString()}`));
  58. console.log(colors.yellow(`目标工单: ${CONFIG.orderNo}`));
  59. console.log(colors.yellow(`测试用户: ${CONFIG.username}`));
  60. console.log('='.repeat(80));
  61. const results = {
  62. login: null,
  63. userInfo: null,
  64. targetOrder: null,
  65. permissionCheck: null,
  66. buttonDisplayConditions: null,
  67. apiTest: null,
  68. };
  69. try {
  70. // 步骤1:用户登录
  71. console.log(colors.blue('\n【步骤1】用户登录验证'));
  72. console.log('----------------------------------------');
  73. try {
  74. const token = await getToken(CONFIG.username, CONFIG.password);
  75. results.login = { success: true, token: token.substring(0, 50) + '...' };
  76. console.log(colors.green('✓ 登录成功'));
  77. console.log(`Token: ${token.substring(0, 50)}...`);
  78. } catch (error) {
  79. results.login = { success: false, error: error.message };
  80. console.log(colors.red('✗ 登录失败: ' + error.message));
  81. return results;
  82. }
  83. // 步骤2:获取用户信息和权限
  84. console.log(colors.blue('\n【步骤2】用户权限检查'));
  85. console.log('----------------------------------------');
  86. const userInfoResult = await testAPI('/system/user/getInfo', null, {
  87. method: 'GET',
  88. token: await getToken(CONFIG.username, CONFIG.password),
  89. });
  90. if (userInfoResult.success) {
  91. const userInfo = userInfoResult.data.data || userInfoResult.data;
  92. results.userInfo = {
  93. userId: userInfo.user?.userId,
  94. userName: userInfo.user?.userName,
  95. nickName: userInfo.user?.nickName,
  96. roles: userInfo.roles?.map((r) => r.roleKey) || [],
  97. permissions: userInfo.permissions || [],
  98. };
  99. console.log(colors.green('✓ 用户信息获取成功'));
  100. console.log(`用户ID: ${results.userInfo.userId}`);
  101. console.log(`用户名: ${results.userInfo.userName}`);
  102. console.log(`昵称: ${results.userInfo.nickName}`);
  103. // 检查关键权限
  104. const hasMaintenanceRole = results.userInfo.roles.includes('maintenance_worker');
  105. const hasUpdateProgressPerm = results.userInfo.permissions.includes(
  106. 'pm:repairOrder:updateProgress',
  107. );
  108. console.log(
  109. `维修人员角色: ${
  110. hasMaintenanceRole ? colors.green('✓ 已配置') : colors.red('✗ 缺少')
  111. }`,
  112. );
  113. console.log(
  114. `更新进度权限: ${
  115. hasUpdateProgressPerm ? colors.green('✓ 已配置') : colors.red('✗ 缺少')
  116. }`,
  117. );
  118. results.permissionCheck = {
  119. hasMaintenanceRole,
  120. hasUpdateProgressPerm,
  121. };
  122. } else {
  123. console.log(colors.red('✗ 用户信息获取失败: ' + JSON.stringify(userInfoResult.error)));
  124. }
  125. // 步骤3:查找目标工单
  126. console.log(colors.blue('\n【步骤3】查找目标工单RO20250126008'));
  127. console.log('----------------------------------------');
  128. const orderListResult = await testAPI('/pm/repairOrder/list', null, {
  129. method: 'GET',
  130. token: await getToken(CONFIG.username, CONFIG.password),
  131. });
  132. if (orderListResult.success) {
  133. const orderData = orderListResult.data;
  134. const orders = orderData.rows || orderData.data || [];
  135. console.log(colors.green('✓ 工单列表获取成功'));
  136. console.log(`可见工单总数: ${orderData.total || orders.length}`);
  137. // 查找目标工单
  138. const targetOrder = orders.find((order) => order.orderNo === CONFIG.orderNo);
  139. if (targetOrder) {
  140. results.targetOrder = {
  141. id: targetOrder.id,
  142. orderNo: targetOrder.orderNo,
  143. title: targetOrder.title,
  144. orderStatus: targetOrder.orderStatus,
  145. assigneeId: targetOrder.assigneeId,
  146. assigneeName: targetOrder.assigneeName,
  147. repairLocation: targetOrder.repairLocation,
  148. createTime: targetOrder.createTime,
  149. };
  150. console.log(colors.green(`✓ 找到目标工单: ${CONFIG.orderNo}`));
  151. console.log(`工单标题: ${targetOrder.title}`);
  152. console.log(`工单状态: ${getStatusText(targetOrder.orderStatus)}`);
  153. console.log(
  154. `维修负责人: ${targetOrder.assigneeName || '未分派'} (ID: ${
  155. targetOrder.assigneeId || 'null'
  156. })`,
  157. );
  158. console.log(`报修地点: ${targetOrder.repairLocation}`);
  159. // 检查按钮显示条件
  160. const isStatus2 = targetOrder.orderStatus === '2' || targetOrder.orderStatus === 2;
  161. const isAssignedToZwc007 = targetOrder.assigneeId === results.userInfo?.userId;
  162. console.log('\n按钮显示条件检查:');
  163. console.log(
  164. `工单状态为已分派(2): ${
  165. isStatus2 ? colors.green('✓ 满足') : colors.red('✗ 不满足')
  166. } (当前: ${targetOrder.orderStatus})`,
  167. );
  168. console.log(
  169. `zwc007是负责人: ${
  170. isAssignedToZwc007 ? colors.green('✓ 满足') : colors.red('✗ 不满足')
  171. } (负责人ID: ${targetOrder.assigneeId})`,
  172. );
  173. console.log(
  174. `维修人员角色: ${
  175. results.permissionCheck?.hasMaintenanceRole
  176. ? colors.green('✓ 满足')
  177. : colors.red('✗ 不满足')
  178. }`,
  179. );
  180. console.log(
  181. `更新进度权限: ${
  182. results.permissionCheck?.hasUpdateProgressPerm
  183. ? colors.green('✓ 满足')
  184. : colors.red('✗ 不满足')
  185. }`,
  186. );
  187. const allConditionsMet =
  188. isStatus2 &&
  189. isAssignedToZwc007 &&
  190. results.permissionCheck?.hasMaintenanceRole &&
  191. results.permissionCheck?.hasUpdateProgressPerm;
  192. console.log(
  193. `\n更新进度按钮应该显示: ${
  194. allConditionsMet ? colors.green('是 🎉') : colors.red('否 ❌')
  195. }`,
  196. );
  197. results.buttonDisplayConditions = {
  198. isStatus2,
  199. isAssignedToZwc007,
  200. allConditionsMet,
  201. };
  202. } else {
  203. console.log(colors.red(`✗ 未找到工单${CONFIG.orderNo}`));
  204. console.log(colors.yellow('可能原因:'));
  205. console.log(colors.yellow('1. 工单不存在'));
  206. console.log(colors.yellow('2. zwc007没有查看该工单的权限'));
  207. console.log(colors.yellow('3. 数据权限过滤导致工单不可见'));
  208. results.targetOrder = { found: false };
  209. }
  210. } else {
  211. console.log(colors.red('✗ 工单列表获取失败: ' + JSON.stringify(orderListResult.error)));
  212. }
  213. // 步骤4:测试更新进度API(如果工单存在且条件满足)
  214. console.log(colors.blue('\n【步骤4】更新进度API测试'));
  215. console.log('----------------------------------------');
  216. if (results.targetOrder?.found !== false && results.targetOrder?.id) {
  217. console.log(`测试工单: ${results.targetOrder.orderNo} (ID: ${results.targetOrder.id})`);
  218. // 构造测试用的进度数据
  219. const progressData = {
  220. orderId: results.targetOrder.id,
  221. progressType: '5', // 维修进度
  222. progressStatus: '测试进度状态',
  223. progressDetail: `工单${
  224. CONFIG.orderNo
  225. }进度更新测试 - ${new Date().toLocaleString()}`,
  226. progressTime: new Date().toISOString().slice(0, 19).replace('T', ' '),
  227. locationInfo: results.targetOrder.repairLocation || '测试位置',
  228. estimatedDuration: 60,
  229. nextStep: '继续测试验证',
  230. remark: 'API权限验证测试',
  231. };
  232. const apiResult = await testAPI('/pm/repairOrder/updateProgress', progressData, {
  233. method: 'POST',
  234. token: await getToken(CONFIG.username, CONFIG.password),
  235. });
  236. if (apiResult.success) {
  237. console.log(colors.green('✓ 更新进度API调用成功'));
  238. console.log('响应数据:', JSON.stringify(apiResult.data, null, 2));
  239. results.apiTest = {
  240. success: true,
  241. response: apiResult.data,
  242. };
  243. } else {
  244. console.log(colors.red('✗ 更新进度API调用失败'));
  245. console.log('错误信息:', JSON.stringify(apiResult.error, null, 2));
  246. results.apiTest = {
  247. success: false,
  248. error: apiResult.error,
  249. };
  250. }
  251. } else {
  252. console.log(colors.yellow('⚠ 跳过API测试:工单不存在或条件不满足'));
  253. results.apiTest = { skipped: true, reason: '工单不存在或条件不满足' };
  254. }
  255. // 步骤5:生成测试总结
  256. console.log(colors.blue('\n【步骤5】测试结果总结'));
  257. console.log('----------------------------------------');
  258. console.log(colors.cyan('测试结果汇总:'));
  259. console.log(
  260. `1. 用户登录: ${
  261. results.login?.success ? colors.green('✓ 成功') : colors.red('✗ 失败')
  262. }`,
  263. );
  264. console.log(
  265. `2. 权限配置: ${
  266. results.permissionCheck?.hasMaintenanceRole &&
  267. results.permissionCheck?.hasUpdateProgressPerm
  268. ? colors.green('✓ 完整')
  269. : colors.red('✗ 缺失')
  270. }`,
  271. );
  272. console.log(
  273. `3. 目标工单: ${
  274. results.targetOrder?.found !== false
  275. ? colors.green('✓ 找到')
  276. : colors.red('✗ 未找到')
  277. }`,
  278. );
  279. console.log(
  280. `4. 按钮显示: ${
  281. results.buttonDisplayConditions?.allConditionsMet
  282. ? colors.green('✓ 应显示')
  283. : colors.red('✗ 不显示')
  284. }`,
  285. );
  286. console.log(
  287. `5. API权限: ${
  288. results.apiTest?.success
  289. ? colors.green('✓ 正常')
  290. : results.apiTest?.skipped
  291. ? colors.yellow('⚠ 跳过')
  292. : colors.red('✗ 失败')
  293. }`,
  294. );
  295. // 提供修复建议
  296. if (!results.buttonDisplayConditions?.allConditionsMet) {
  297. console.log(colors.yellow('\n修复建议:'));
  298. if (!results.permissionCheck?.hasMaintenanceRole) {
  299. console.log(colors.yellow('- 需要为zwc007分配maintenance_worker角色'));
  300. }
  301. if (!results.permissionCheck?.hasUpdateProgressPerm) {
  302. console.log(
  303. colors.yellow('- 需要为维修人员角色分配pm:repairOrder:updateProgress权限'),
  304. );
  305. }
  306. if (!results.buttonDisplayConditions?.isStatus2) {
  307. console.log(colors.yellow(`- 需要将工单${CONFIG.orderNo}状态设置为已分派(2)`));
  308. }
  309. if (!results.buttonDisplayConditions?.isAssignedToZwc007) {
  310. console.log(colors.yellow(`- 需要将工单${CONFIG.orderNo}分派给zwc007`));
  311. }
  312. console.log(
  313. colors.yellow('- 执行 test/RO20250126008-update-progress-fix.sql 脚本进行修复'),
  314. );
  315. }
  316. } catch (error) {
  317. console.log(colors.red('测试过程中发生错误: ' + error.message));
  318. results.error = error.message;
  319. }
  320. console.log('\n' + '='.repeat(80));
  321. console.log(colors.cyan.bold(' 测试完成'));
  322. console.log('='.repeat(80));
  323. return results;
  324. }
  325. /**
  326. * 获取状态文本
  327. */
  328. function getStatusText(status) {
  329. const statusMap = {
  330. 1: '待分派',
  331. 2: '已分派',
  332. 3: '进行中',
  333. 4: '已完成',
  334. 5: '已评价',
  335. 6: '已归档',
  336. 9: '已取消',
  337. };
  338. return statusMap[status] || `状态${status}`;
  339. }
  340. // 执行测试
  341. if (require.main === module) {
  342. testRO20250126008UpdateProgressButton()
  343. .then((results) => {
  344. console.log('\n测试结果已保存');
  345. // 输出最终结论
  346. const success =
  347. results.buttonDisplayConditions?.allConditionsMet && results.apiTest?.success;
  348. if (success) {
  349. console.log(
  350. colors.green.bold(
  351. '\n🎉 测试通过!工单RO20250126008的更新进度按钮应该可以正常显示和使用。',
  352. ),
  353. );
  354. } else {
  355. console.log(colors.red.bold('\n❌ 测试未通过!需要执行修复脚本解决问题。'));
  356. }
  357. })
  358. .catch((error) => {
  359. console.error(colors.red('测试执行失败:'), error);
  360. });
  361. }
  362. module.exports = {
  363. testRO20250126008UpdateProgressButton,
  364. };