test_huashi_debug_with_logs.html 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>华视读卡器详细调试</title>
  7. <style>
  8. body { font-family: Arial, sans-serif; margin: 20px; line-height: 1.6; }
  9. .container { max-width: 1200px; margin: 0 auto; }
  10. button { background: #007cba; color: white; border: none; padding: 10px 20px; margin: 5px; cursor: pointer; border-radius: 4px; }
  11. button:hover { background: #005a87; }
  12. .result { background: #f5f5f5; border: 1px solid #ccc; padding: 15px; margin: 10px 0; border-radius: 4px; max-height: 300px; overflow-y: auto; }
  13. .error { color: red; }
  14. .success { color: green; }
  15. .info { color: blue; }
  16. .warning { color: orange; }
  17. pre { white-space: pre-wrap; word-wrap: break-word; font-size: 12px; }
  18. .photo-section { border: 2px solid #ddd; padding: 15px; margin: 15px 0; border-radius: 8px; }
  19. .debug-tip { background: #e8f5e8; border: 1px solid #4caf50; padding: 10px; margin: 10px 0; border-radius: 4px; }
  20. </style>
  21. </head>
  22. <body>
  23. <div class="container">
  24. <h1>华视读卡器详细调试 - 照片功能专项测试</h1>
  25. <div class="debug-tip">
  26. <strong>🔍 本次更新内容:</strong><br>
  27. 1. 添加了CVR_Read_Content函数支持<br>
  28. 2. 增强了调试信息输出<br>
  29. 3. 改进了照片获取策略<br>
  30. 4. 添加数据有效性检查
  31. </div>
  32. <div class="test-section">
  33. <h2>测试功能</h2>
  34. <button onclick="testPhotoReading()">🖼️ 专项照片读取测试</button>
  35. <button onclick="testStepByStep()">📋 分步调试测试</button>
  36. <button onclick="clearResults()">🗑️ 清除结果</button>
  37. </div>
  38. <div id="results"></div>
  39. </div>
  40. <script>
  41. function addResult(title, data, type = 'info') {
  42. const results = document.getElementById('results');
  43. const div = document.createElement('div');
  44. div.className = `result ${type}`;
  45. let content = `<h3>${title} <small>${new Date().toLocaleTimeString()}</small></h3>`;
  46. if (typeof data === 'object') {
  47. content += `<pre>${JSON.stringify(data, null, 2)}</pre>`;
  48. } else {
  49. content += `<pre>${data}</pre>`;
  50. }
  51. div.innerHTML = content;
  52. results.appendChild(div);
  53. results.scrollTop = results.scrollHeight;
  54. }
  55. function testPhotoReading() {
  56. addResult('🚀 开始专项照片读取测试', '测试华视读卡器照片功能的多种方法...', 'info');
  57. fetch('http://localhost:8321/readcard/huashi/simple?action=readcard&port=1001', {
  58. method: 'GET',
  59. headers: { 'Content-Type': 'application/json' }
  60. })
  61. .then(response => response.json())
  62. .then(data => {
  63. const type = data.code === 200 ? 'success' : 'error';
  64. addResult('📋 读卡结果', data, type);
  65. // 详细分析照片数据
  66. if (data.data) {
  67. analyzePhotoDataDetailed(data.data);
  68. }
  69. })
  70. .catch(error => {
  71. addResult('❌ 请求错误', error.message, 'error');
  72. });
  73. }
  74. function testStepByStep() {
  75. addResult('📝 开始分步测试', '逐步验证每个环节...', 'info');
  76. // 步骤1:健康检查
  77. fetch('http://localhost:8321/readcard/huashi/health')
  78. .then(response => response.json())
  79. .then(data => {
  80. addResult('1️⃣ 健康检查', data, data.healthy ? 'success' : 'warning');
  81. // 步骤2:设备状态
  82. return fetch('http://localhost:8321/readcard/huashi/status');
  83. })
  84. .then(response => response.json())
  85. .then(data => {
  86. addResult('2️⃣ 设备状态', data, data.connected ? 'success' : 'warning');
  87. // 步骤3:读卡测试
  88. addResult('3️⃣ 开始读卡', '请确保身份证已放置在读卡器上...', 'info');
  89. return fetch('http://localhost:8321/readcard/huashi/simple?action=readcard&port=1001');
  90. })
  91. .then(response => response.json())
  92. .then(data => {
  93. addResult('3️⃣ 读卡完成', data, data.code === 200 ? 'success' : 'error');
  94. if (data.data) {
  95. analyzePhotoDataDetailed(data.data);
  96. }
  97. })
  98. .catch(error => {
  99. addResult('❌ 分步测试错误', error.message, 'error');
  100. });
  101. }
  102. function analyzePhotoDataDetailed(data) {
  103. const photoSection = document.createElement('div');
  104. photoSection.className = 'photo-section';
  105. let analysis = '<h3>🖼️ 照片数据详细分析</h3>';
  106. // 基础信息
  107. analysis += '<h4>📊 基础信息:</h4>';
  108. analysis += `• photoBase64字段存在: ${data.hasOwnProperty('photoBase64')}<br>`;
  109. analysis += `• photoBase64长度: ${data.photoBase64 ? data.photoBase64.length : 0}<br>`;
  110. analysis += `• hasPhoto: ${data.hasPhoto}<br>`;
  111. analysis += `• photoFormat: ${data.photoFormat || '未设置'}<br>`;
  112. analysis += `• photoSize: ${data.photoSize || 0}<br><br>`;
  113. // 数据分析
  114. if (data.photoBase64 && data.photoBase64.length > 0) {
  115. analysis += '<h4>🔍 数据内容分析:</h4>';
  116. const preview = data.photoBase64.substring(0, 100);
  117. analysis += `• 前100字符: "${preview}"<br>`;
  118. // 检查数据特征
  119. if (data.photoBase64.length > 100) {
  120. const uniqueChars = new Set(data.photoBase64.split('')).size;
  121. analysis += `• 字符种类数: ${uniqueChars}<br>`;
  122. if (uniqueChars < 5) {
  123. analysis += `• ⚠️ 警告:字符种类过少,可能是无效数据<br>`;
  124. }
  125. // 检查常见问题
  126. if (data.photoBase64.replace(/A/g, '').length < 10) {
  127. analysis += `• ❌ 检测到:主要是'A'字符,这是空数据<br>`;
  128. } else if (data.photoBase64.replace(/0/g, '').length < 10) {
  129. analysis += `• ❌ 检测到:主要是'0'字符,这是空数据<br>`;
  130. }
  131. }
  132. // BASE64有效性检查
  133. try {
  134. atob(data.photoBase64.substring(0, Math.min(100, data.photoBase64.length)));
  135. analysis += `• ✅ BASE64格式: 有效<br>`;
  136. } catch (e) {
  137. analysis += `• ❌ BASE64格式: 无效 - ${e.message}<br>`;
  138. }
  139. // 图片格式检测
  140. analysis += '<h4>🖼️ 图片格式检测:</h4>';
  141. const firstBytes = data.photoBase64.substring(0, 20);
  142. if (firstBytes.startsWith('/9j/')) {
  143. analysis += '• 🎯 检测到JPEG格式标识<br>';
  144. } else if (firstBytes.startsWith('iVBORw0KGgo')) {
  145. analysis += '• 🎯 检测到PNG格式标识<br>';
  146. } else if (firstBytes.startsWith('Qk') || firstBytes.startsWith('BM')) {
  147. analysis += '• 🎯 检测到BMP格式标识<br>';
  148. } else {
  149. analysis += '• ⚠️ 未识别的图片格式<br>';
  150. }
  151. } else {
  152. analysis += '<h4>❌ 问题诊断:</h4>';
  153. analysis += '• 没有获取到照片数据<br>';
  154. analysis += '• 可能原因:<br>';
  155. analysis += ' - 华视SDK版本不支持照片读取<br>';
  156. analysis += ' - 身份证芯片中没有照片数据<br>';
  157. analysis += ' - 读卡器硬件不支持照片功能<br>';
  158. analysis += ' - SDK函数调用顺序有误<br>';
  159. }
  160. photoSection.innerHTML = analysis;
  161. document.getElementById('results').appendChild(photoSection);
  162. }
  163. function clearResults() {
  164. document.getElementById('results').innerHTML = '';
  165. }
  166. // 页面加载提示
  167. window.onload = function() {
  168. addResult('🎯 华视读卡器照片功能专项调试',
  169. `本页面专门用于调试华视读卡器的照片读取功能。
  170. 🔧 本次更新特性:
  171. • 添加CVR_Read_Content函数支持
  172. • 增强调试信息和错误诊断
  173. • 改进照片获取策略
  174. • 添加详细的数据分析
  175. 🧪 测试建议:
  176. 1. 先进行"专项照片读取测试"查看基本结果
  177. 2. 如有问题,使用"分步调试测试"定位具体环节
  178. 3. 查看详细的照片数据分析报告
  179. 📋 调试信息说明:
  180. 所有调试信息会在程序后台输出,如果需要查看可以:
  181. - 查看ThCardReader程序的控制台输出
  182. - 使用Visual Studio的输出窗口
  183. - 查看系统调试日志`, 'info');
  184. };
  185. </script>
  186. </body>
  187. </html>