test_businesscode_fix.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>业务代码修复测试页面</title>
  5. <meta charset="utf-8">
  6. <style>
  7. body {
  8. font-family: Arial, sans-serif;
  9. margin: 20px;
  10. background-color: #f5f5f5;
  11. }
  12. .container {
  13. max-width: 1200px;
  14. margin: 0 auto;
  15. background: white;
  16. padding: 20px;
  17. border-radius: 8px;
  18. box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  19. }
  20. .section {
  21. margin: 20px 0;
  22. padding: 15px;
  23. border: 1px solid #ddd;
  24. border-radius: 5px;
  25. background: #f9f9f9;
  26. }
  27. .test-group {
  28. display: flex;
  29. flex-wrap: wrap;
  30. gap: 10px;
  31. margin: 10px 0;
  32. }
  33. .btn {
  34. padding: 8px 16px;
  35. margin: 2px;
  36. background: #007bff;
  37. color: white;
  38. border: none;
  39. border-radius: 4px;
  40. cursor: pointer;
  41. font-size: 12px;
  42. }
  43. .btn:hover { background: #0056b3; }
  44. .btn.success { background: #28a745; }
  45. .btn.warning { background: #ffc107; color: #000; }
  46. .btn.danger { background: #dc3545; }
  47. .result {
  48. margin-top: 10px;
  49. padding: 10px;
  50. background: #fff;
  51. border-radius: 3px;
  52. font-family: monospace;
  53. white-space: pre-wrap;
  54. max-height: 300px;
  55. overflow-y: auto;
  56. font-size: 11px;
  57. border: 1px solid #ddd;
  58. }
  59. .result.success { background: #d4edda; color: #155724; border-color: #c3e6cb; }
  60. .result.error { background: #f8d7da; color: #721c24; border-color: #f5c6cb; }
  61. .test-url {
  62. font-family: monospace;
  63. font-size: 11px;
  64. color: #666;
  65. margin: 5px 0;
  66. word-break: break-all;
  67. }
  68. h1 { color: #333; text-align: center; }
  69. h2 { color: #555; border-bottom: 2px solid #007bff; padding-bottom: 5px; }
  70. h3 { color: #666; margin-top: 15px; }
  71. .status {
  72. padding: 5px 10px;
  73. border-radius: 3px;
  74. font-weight: bold;
  75. text-align: center;
  76. margin: 10px 0;
  77. }
  78. .status.success { background: #d4edda; color: #155724; }
  79. .status.error { background: #f8d7da; color: #721c24; }
  80. </style>
  81. </head>
  82. <body>
  83. <div class="container">
  84. <h1>🔧 业务代码修复测试页面</h1>
  85. <div id="serviceStatus" class="status error">服务状态检查中...</div>
  86. <div class="section">
  87. <h2>📋 修复说明</h2>
  88. <p><strong>问题:</strong>当URL格式为 <code>huashi_01101</code> 或 <code>jiangsu_01101</code> 时,业务代码(01101)被错误地当作操作动作处理。</p>
  89. <p><strong>修复:</strong>添加了 <code>IsBusinessCode()</code> 方法检测5位数字格式,如果是业务代码则自动使用默认的 <code>readcard</code> 操作。</p>
  90. <p><strong>向后兼容:</strong>不影响现有的正确调用方式,如 <code>huashi_readcard</code>、<code>jiangsu_init</code> 等。</p>
  91. </div>
  92. <!-- 华视读卡器测试 -->
  93. <div class="section">
  94. <h2>🆔 华视读卡器测试</h2>
  95. <h3>✅ 正常调用(应该保持正常工作)</h3>
  96. <div class="test-group">
  97. <button class="btn success" onclick="testCall('huashi_readcard', 'huashiNormalResult')">huashi_readcard</button>
  98. <button class="btn" onclick="testCall('huashi_init_1001', 'huashiNormalResult')">huashi_init_1001</button>
  99. <button class="btn" onclick="testCall('huashi_status', 'huashiNormalResult')">huashi_status</button>
  100. <button class="btn" onclick="testCall('huashi_close', 'huashiNormalResult')">huashi_close</button>
  101. </div>
  102. <div class="test-url">正常URL格式:http://localhost:8321/readcard/entry?param=huashi_readcard</div>
  103. <div id="huashiNormalResult" class="result">等待测试...</div>
  104. <h3>🔧 业务代码修复测试(之前会报错,现在应该正常)</h3>
  105. <div class="test-group">
  106. <button class="btn warning" onclick="testCall('huashi_01101', 'huashiFixResult')">huashi_01101</button>
  107. <button class="btn warning" onclick="testCall('huashi_01201', 'huashiFixResult')">huashi_01201</button>
  108. <button class="btn warning" onclick="testCall('huashi_01103', 'huashiFixResult')">huashi_01103</button>
  109. <button class="btn warning" onclick="testCall('huashi_01203', 'huashiFixResult')">huashi_01203</button>
  110. <button class="btn warning" onclick="testCall('huashi_01301', 'huashiFixResult')">huashi_01301</button>
  111. </div>
  112. <div class="test-url">修复的URL格式:http://localhost:8321/readcard/entry?param=huashi_01101 (01101被识别为业务代码,自动转为readcard操作)</div>
  113. <div id="huashiFixResult" class="result">等待测试...</div>
  114. <h3>❌ 错误操作测试(应该报错)</h3>
  115. <div class="test-group">
  116. <button class="btn danger" onclick="testCall('huashi_invalid', 'huashiErrorResult')">huashi_invalid</button>
  117. <button class="btn danger" onclick="testCall('huashi_12345a', 'huashiErrorResult')">huashi_12345a(非纯数字)</button>
  118. <button class="btn danger" onclick="testCall('huashi_123456', 'huashiErrorResult')">huashi_123456(6位数字)</button>
  119. </div>
  120. <div class="test-url">错误URL格式:http://localhost:8321/readcard/entry?param=huashi_invalid</div>
  121. <div id="huashiErrorResult" class="result">等待测试...</div>
  122. </div>
  123. <!-- 江苏医保测试 -->
  124. <div class="section">
  125. <h2>🏥 江苏医保测试</h2>
  126. <h3>✅ 正常调用(应该保持正常工作)</h3>
  127. <div class="test-group">
  128. <button class="btn success" onclick="testCall('jiangsu_readcard', 'jiangsuNormalResult')">jiangsu_readcard</button>
  129. <button class="btn" onclick="testCall('jiangsu_init', 'jiangsuNormalResult')">jiangsu_init</button>
  130. <button class="btn" onclick="testCall('jiangsu_status', 'jiangsuNormalResult')">jiangsu_status</button>
  131. <button class="btn" onclick="testCall('jiangsu_checkdll', 'jiangsuNormalResult')">jiangsu_checkdll</button>
  132. </div>
  133. <div class="test-url">正常URL格式:http://localhost:8321/readcard/entry?param=jiangsu_readcard</div>
  134. <div id="jiangsuNormalResult" class="result">等待测试...</div>
  135. <h3>🔧 业务代码修复测试(之前会报错,现在应该正常)</h3>
  136. <div class="test-group">
  137. <button class="btn warning" onclick="testCall('jiangsu_01101', 'jiangsuFixResult')">jiangsu_01101</button>
  138. <button class="btn warning" onclick="testCall('jiangsu_01201', 'jiangsuFixResult')">jiangsu_01201</button>
  139. <button class="btn warning" onclick="testCall('jiangsu_01103', 'jiangsuFixResult')">jiangsu_01103</button>
  140. <button class="btn warning" onclick="testCall('jiangsu_01203', 'jiangsuFixResult')">jiangsu_01203</button>
  141. <button class="btn warning" onclick="testCall('jiangsu_01301', 'jiangsuFixResult')">jiangsu_01301</button>
  142. </div>
  143. <div class="test-url">修复的URL格式:http://localhost:8321/readcard/entry?param=jiangsu_01101 (01101被识别为业务代码,自动转为readcard操作)</div>
  144. <div id="jiangsuFixResult" class="result">等待测试...</div>
  145. <h3>❌ 错误操作测试(应该报错)</h3>
  146. <div class="test-group">
  147. <button class="btn danger" onclick="testCall('jiangsu_invalid', 'jiangsuErrorResult')">jiangsu_invalid</button>
  148. <button class="btn danger" onclick="testCall('jiangsu_12345a', 'jiangsuErrorResult')">jiangsu_12345a(非纯数字)</button>
  149. <button class="btn danger" onclick="testCall('jiangsu_123456', 'jiangsuErrorResult')">jiangsu_123456(6位数字)</button>
  150. </div>
  151. <div class="test-url">错误URL格式:http://localhost:8321/readcard/entry?param=jiangsu_invalid</div>
  152. <div id="jiangsuErrorResult" class="result">等待测试...</div>
  153. </div>
  154. <!-- 其他功能测试 -->
  155. <div class="section">
  156. <h2>🔍 其他功能完整性测试</h2>
  157. <p>验证修改没有影响现有的其他读卡功能:</p>
  158. <div class="test-group">
  159. <button class="btn" onclick="testCall('sicard', 'otherResult')">sicard(社保卡)</button>
  160. <button class="btn" onclick="testCall('idcard', 'otherResult')">idcard(身份证)</button>
  161. <button class="btn" onclick="testCall('qrcode_01101', 'otherResult')">qrcode_01101(电子凭证)</button>
  162. <button class="btn" onclick="testCall('idcard2_01101', 'otherResult')">idcard2_01101(身份证+业务码)</button>
  163. </div>
  164. <div class="test-url">其他功能URL:http://localhost:8321/readcard/entry?param=sicard</div>
  165. <div id="otherResult" class="result">等待测试...</div>
  166. </div>
  167. <div class="section">
  168. <h2>📊 测试总结</h2>
  169. <div id="testSummary" class="result">
  170. 测试说明:
  171. 1. ✅ 绿色按钮:正常功能,应该保持原有工作状态
  172. 2. 🔧 黄色按钮:修复的功能,之前报错现在应该正常
  173. 3. ❌ 红色按钮:错误测试,应该报错但错误信息要友好
  174. 4. 🔍 蓝色按钮:其他功能,验证没有被破坏
  175. 期望结果:
  176. - huashi_01101 应该等效于 huashi_readcard
  177. - jiangsu_01101 应该等效于 jiangsu_readcard
  178. - 5位数字被识别为业务代码,自动转为默认操作
  179. - 非5位数字或包含字母的仍然作为无效操作处理
  180. </div>
  181. </div>
  182. </div>
  183. <script>
  184. const BASE_URL = 'http://localhost:8321';
  185. // 页面加载时检查服务状态
  186. window.onload = function() {
  187. checkServiceStatus();
  188. };
  189. // 检查服务状态
  190. async function checkServiceStatus() {
  191. try {
  192. const response = await fetch(`${BASE_URL}/readcard/entry?param=sicard`);
  193. const data = await response.json();
  194. if (response.ok) {
  195. showStatus('✅ ThCardReader 服务运行正常', 'success');
  196. } else {
  197. showStatus('⚠️ 服务响应异常', 'error');
  198. }
  199. } catch (error) {
  200. showStatus('❌ 无法连接到 ThCardReader 服务 (http://localhost:8321)', 'error');
  201. }
  202. }
  203. // 显示状态
  204. function showStatus(message, type) {
  205. const statusDiv = document.getElementById('serviceStatus');
  206. statusDiv.textContent = message;
  207. statusDiv.className = `status ${type}`;
  208. }
  209. // 测试调用
  210. async function testCall(param, resultElementId) {
  211. const resultElement = document.getElementById(resultElementId);
  212. const url = `${BASE_URL}/readcard/entry?param=${param}`;
  213. resultElement.textContent = `🔄 正在测试: ${param}\n请求URL: ${url}\n\n请等待...`;
  214. resultElement.className = 'result';
  215. try {
  216. const startTime = Date.now();
  217. const response = await fetch(url);
  218. const data = await response.json();
  219. const endTime = Date.now();
  220. const duration = endTime - startTime;
  221. let resultText = `✅ 测试完成: ${param}\n`;
  222. resultText += `⏱️ 请求时间: ${duration}ms\n`;
  223. resultText += `📡 HTTP状态: ${response.status}\n`;
  224. resultText += `🔗 请求URL: ${url}\n\n`;
  225. resultText += `📄 响应数据:\n${JSON.stringify(data, null, 2)}`;
  226. resultElement.textContent = resultText;
  227. // 根据结果设置样式
  228. if (data.code === 200 || data.success === true) {
  229. resultElement.className = 'result success';
  230. } else {
  231. resultElement.className = 'result error';
  232. }
  233. // 记录到总结中
  234. updateTestSummary(param, data, duration);
  235. } catch (error) {
  236. let errorText = `❌ 测试失败: ${param}\n`;
  237. errorText += `🔗 请求URL: ${url}\n\n`;
  238. errorText += `💥 错误信息: ${error.message}`;
  239. resultElement.textContent = errorText;
  240. resultElement.className = 'result error';
  241. updateTestSummary(param, { error: error.message }, 0);
  242. }
  243. }
  244. // 更新测试总结
  245. function updateTestSummary(param, result, duration) {
  246. const summaryElement = document.getElementById('testSummary');
  247. let status;
  248. if (result.error) {
  249. status = '❌ 网络错误';
  250. } else if (result.code === 200 || result.success === true) {
  251. status = '✅ 成功';
  252. } else {
  253. status = '⚠️ 业务错误';
  254. }
  255. const logEntry = `[${new Date().toLocaleTimeString()}] ${param} - ${status} (${duration}ms)`;
  256. // 添加到现有内容
  257. const currentText = summaryElement.textContent;
  258. const lines = currentText.split('\n');
  259. // 找到测试记录的开始位置
  260. let insertIndex = lines.length;
  261. for (let i = 0; i < lines.length; i++) {
  262. if (lines[i].includes('测试记录:')) {
  263. insertIndex = i + 1;
  264. break;
  265. }
  266. }
  267. // 如果没有找到测试记录标题,添加它
  268. if (insertIndex === lines.length) {
  269. lines.push('', '🔍 测试记录:');
  270. insertIndex = lines.length;
  271. }
  272. lines.splice(insertIndex, 0, logEntry);
  273. summaryElement.textContent = lines.join('\n');
  274. }
  275. // 批量测试
  276. async function runAllTests() {
  277. const tests = [
  278. { param: 'huashi_readcard', result: 'huashiNormalResult' },
  279. { param: 'huashi_01101', result: 'huashiFixResult' },
  280. { param: 'jiangsu_readcard', result: 'jiangsuNormalResult' },
  281. { param: 'jiangsu_01101', result: 'jiangsuFixResult' },
  282. { param: 'sicard', result: 'otherResult' }
  283. ];
  284. for (const test of tests) {
  285. await testCall(test.param, test.result);
  286. await new Promise(resolve => setTimeout(resolve, 500)); // 500ms间隔
  287. }
  288. }
  289. </script>
  290. </body>
  291. </html>