jiangsu_test.html 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>江苏医保社保卡读取测试</title>
  5. <meta charset="utf-8">
  6. <style>
  7. body { font-family: Arial, sans-serif; margin: 20px; }
  8. .container { max-width: 1000px; margin: 0 auto; }
  9. .section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
  10. .button { padding: 10px 20px; margin: 5px; background: #007bff; color: white; border: none; border-radius: 3px; cursor: pointer; }
  11. .button:hover { background: #0056b3; }
  12. .result { margin-top: 10px; padding: 10px; background: #f8f9fa; border-radius: 3px; font-family: monospace; white-space: pre-wrap; }
  13. .success { background: #d4edda; color: #155724; }
  14. .error { background: #f8d7da; color: #721c24; }
  15. .config-input { width: 100%; margin: 5px 0; padding: 5px; }
  16. </style>
  17. </head>
  18. <body>
  19. <div class="container">
  20. <h1>江苏医保社保卡读取系统测试</h1>
  21. <p><strong>基于HeaSecReadInfo.dll</strong> - 严格按照江苏医保规范v0.9.9.15实现</p>
  22. <!-- 系统状态 -->
  23. <div class="section">
  24. <h2>1. 系统状态检查</h2>
  25. <button class="button" onclick="checkHealth()">健康检查</button>
  26. <button class="button" onclick="getStatus()">获取状态</button>
  27. <div id="statusResult" class="result"></div>
  28. </div>
  29. <!-- 系统初始化 -->
  30. <div class="section">
  31. <h2>2. 系统初始化</h2>
  32. <h3>配置参数 (JSON格式):</h3>
  33. <div>
  34. <label>IP地址: <input type="text" id="configIP" class="config-input" value="10.61.165.3"></label>
  35. <label>端口: <input type="number" id="configPORT" class="config-input" value="8086"></label>
  36. <label>超时时间(秒): <input type="number" id="configTIMEOUT" class="config-input" value="30"></label>
  37. <label>日志路径: <input type="text" id="configLOG_PATH" class="config-input" value="E:\\huaihaiProject\\readCard\\ThCardReader\\logs\\"></label>
  38. <label>电子凭证URL: <input type="text" id="configEC_URL" class="config-input" value="http://10.61.165.3:8086/localcfc/api/hsecfc/localQrCodeQuery"></label>
  39. <label>卡密码验证方式: <select id="configCARD_PASSTYPE" class="config-input"><option value="1">1-验证卡PIN</option><option value="2" selected>2-验证数据库密码</option></select></label>
  40. <label>API名称: <input type="text" id="configAPI_NAME" class="config-input" value="hssServives"></label>
  41. <label>API版本: <input type="text" id="configAPI_VERSION" class="config-input" value="1.0.0"></label>
  42. <label>访问密钥: <input type="text" id="configACCESS_KEY" class="config-input" value="a94971b5ecee4bb994bce25c9291ccbf"></label>
  43. <label>密钥: <input type="text" id="configSECRETKEY" class="config-input" value="3ni3n+nWhGCsiu6SITGUqNfzvx8="></label>
  44. <label>定点编号: <input type="text" id="configORG_ID" class="config-input" value="H32132200561"></label>
  45. <label>扩展参数: <input type="text" id="configEXT" class="config-input" value="{}"></label>
  46. <label>行政区划代码: <input type="text" id="configAREA_CODE" class="config-input" value="321322"></label>
  47. </div>
  48. <button class="button" onclick="initSystem()">初始化系统</button>
  49. <button class="button" onclick="initSystemSimple()">使用默认配置初始化</button>
  50. <div id="initResult" class="result"></div>
  51. </div>
  52. <!-- 读卡功能 -->
  53. <div class="section">
  54. <h2>3. 社保卡读取功能</h2>
  55. <button class="button" onclick="readCard()">读取社保卡</button>
  56. <button class="button" onclick="readCardWithPIN()">读卡+验证PIN</button>
  57. <button class="button" onclick="readCardURL()">URL方式读卡</button>
  58. <div id="readResult" class="result"></div>
  59. </div>
  60. <!-- PIN码操作 -->
  61. <div class="section">
  62. <h2>4. PIN码操作</h2>
  63. <button class="button" onclick="verifyPIN()">验证PIN码</button>
  64. <button class="button" onclick="changePIN()">修改PIN码</button>
  65. <div id="pinResult" class="result"></div>
  66. </div>
  67. <!-- 四合一介质 -->
  68. <div class="section">
  69. <h2>5. 四合一介质支持</h2>
  70. <select id="mediaType">
  71. <option value="socialcard">社保卡</option>
  72. <option value="idcard">身份证</option>
  73. <option value="electronic">电子凭证</option>
  74. <option value="esocialcard">电子社保卡</option>
  75. </select>
  76. <button class="button" onclick="getPersonInfo()">获取个人信息</button>
  77. <div id="personResult" class="result"></div>
  78. </div>
  79. <!-- 系统管理 -->
  80. <div class="section">
  81. <h2>6. 系统管理</h2>
  82. <button class="button" onclick="resetSystem()">重置系统状态</button>
  83. <button class="button" onclick="checkDllFile()">检查DLL文件</button>
  84. <button class="button" onclick="getHelp()">API帮助</button>
  85. <div id="manageResult" class="result"></div>
  86. </div>
  87. <!-- 智能重置测试 -->
  88. <div class="section">
  89. <h2>7. 智能重置策略测试</h2>
  90. <p>测试连续失败自动重置功能(需要先初始化系统)</p>
  91. <button class="button" onclick="testSmartReset()">模拟连续失败</button>
  92. <div id="smartResetResult" class="result"></div>
  93. </div>
  94. </div>
  95. <script>
  96. const baseUrl = 'http://localhost:8321';
  97. let consecutiveFailures = 0;
  98. const MAX_FAILURES = 3;
  99. // 显示结果
  100. function showResult(elementId, data, isError = false) {
  101. const element = document.getElementById(elementId);
  102. element.className = 'result ' + (isError ? 'error' : 'success');
  103. element.textContent = JSON.stringify(data, null, 2);
  104. }
  105. // 健康检查
  106. async function checkHealth() {
  107. try {
  108. const response = await fetch(`${baseUrl}/readcard/jiangsu/status`);
  109. const data = await response.json();
  110. showResult('statusResult', data, !data.success);
  111. } catch (error) {
  112. showResult('statusResult', { error: error.message }, true);
  113. }
  114. }
  115. // 获取状态
  116. async function getStatus() {
  117. try {
  118. const response = await fetch(`${baseUrl}/readcard/jiangsu/status`);
  119. const data = await response.json();
  120. showResult('statusResult', data, !data.success);
  121. } catch (error) {
  122. showResult('statusResult', { error: error.message }, true);
  123. }
  124. }
  125. // 初始化系统(带配置)
  126. async function initSystem() {
  127. try {
  128. const config = {
  129. action: 'init',
  130. config: {
  131. "IP": document.getElementById('configIP').value,
  132. "PORT": parseInt(document.getElementById('configPORT').value),
  133. "TIMEOUT": parseInt(document.getElementById('configTIMEOUT').value),
  134. "LOG_PATH": document.getElementById('configLOG_PATH').value,
  135. "EC_URL": document.getElementById('configEC_URL').value,
  136. "CARD_PASSTYPE": document.getElementById('configCARD_PASSTYPE').value,
  137. "API_NAME": document.getElementById('configAPI_NAME').value,
  138. "API_VERSION": document.getElementById('configAPI_VERSION').value,
  139. "ACCESS_KEY": document.getElementById('configACCESS_KEY').value,
  140. "SECRETKEY": document.getElementById('configSECRETKEY').value,
  141. "ORG_ID": document.getElementById('configORG_ID').value,
  142. "EXT": document.getElementById('configEXT').value,
  143. "AREA_CODE": document.getElementById('configAREA_CODE').value
  144. }
  145. };
  146. const response = await fetch(`${baseUrl}/readcard/jiangsu`, {
  147. method: 'POST',
  148. headers: { 'Content-Type': 'application/json' },
  149. body: JSON.stringify(config)
  150. });
  151. const data = await response.json();
  152. showResult('initResult', data, !data.success);
  153. } catch (error) {
  154. showResult('initResult', { error: error.message }, true);
  155. }
  156. }
  157. // 使用默认配置初始化
  158. async function initSystemSimple() {
  159. try {
  160. const response = await fetch(`${baseUrl}/readcard/jiangsu/init`);
  161. const data = await response.json();
  162. showResult('initResult', data, !data.success);
  163. } catch (error) {
  164. showResult('initResult', { error: error.message }, true);
  165. }
  166. }
  167. // 读取社保卡
  168. async function readCard() {
  169. try {
  170. const response = await fetch(`${baseUrl}/readcard/jiangsu/readcard`);
  171. const data = await response.json();
  172. consecutiveFailures = data.success ? 0 : consecutiveFailures + 1;
  173. showResult('readResult', data, !data.success);
  174. } catch (error) {
  175. consecutiveFailures++;
  176. showResult('readResult', { error: error.message }, true);
  177. }
  178. }
  179. // 读卡+验证PIN
  180. async function readCardWithPIN() {
  181. try {
  182. const response = await fetch(`${baseUrl}/readcard/jiangsu/readcard_pin`);
  183. const data = await response.json();
  184. consecutiveFailures = data.success ? 0 : consecutiveFailures + 1;
  185. showResult('readResult', data, !data.success);
  186. } catch (error) {
  187. consecutiveFailures++;
  188. showResult('readResult', { error: error.message }, true);
  189. }
  190. }
  191. // URL方式读卡(模拟前端调用)
  192. async function readCardURL() {
  193. try {
  194. const response = await fetch(`${baseUrl}/readcard/entry/jiangsu_readcard`);
  195. const data = await response.json();
  196. showResult('readResult', data, data.code !== 200);
  197. } catch (error) {
  198. showResult('readResult', { error: error.message }, true);
  199. }
  200. }
  201. // 验证PIN
  202. async function verifyPIN() {
  203. try {
  204. const response = await fetch(`${baseUrl}/readcard/jiangsu/verifypin`);
  205. const data = await response.json();
  206. showResult('pinResult', data, !data.success);
  207. } catch (error) {
  208. showResult('pinResult', { error: error.message }, true);
  209. }
  210. }
  211. // 修改PIN
  212. async function changePIN() {
  213. try {
  214. const response = await fetch(`${baseUrl}/readcard/jiangsu/changepin`);
  215. const data = await response.json();
  216. showResult('pinResult', data, !data.success);
  217. } catch (error) {
  218. showResult('pinResult', { error: error.message }, true);
  219. }
  220. }
  221. // 获取个人信息
  222. async function getPersonInfo() {
  223. try {
  224. const mediaType = document.getElementById('mediaType').value;
  225. const response = await fetch(`${baseUrl}/readcard/jiangsu`, {
  226. method: 'POST',
  227. headers: { 'Content-Type': 'application/json' },
  228. body: JSON.stringify({
  229. action: 'getpersoninfo',
  230. mediaType: mediaType,
  231. inputData: ''
  232. })
  233. });
  234. const data = await response.json();
  235. showResult('personResult', data, !data.success);
  236. } catch (error) {
  237. showResult('personResult', { error: error.message }, true);
  238. }
  239. }
  240. // 重置系统
  241. async function resetSystem() {
  242. try {
  243. const response = await fetch(`${baseUrl}/readcard/jiangsu/reset`);
  244. const data = await response.json();
  245. consecutiveFailures = 0; // 重置失败计数
  246. showResult('manageResult', data, !data.success);
  247. } catch (error) {
  248. showResult('manageResult', { error: error.message }, true);
  249. }
  250. }
  251. // 检查DLL文件
  252. async function checkDllFile() {
  253. try {
  254. const response = await fetch(`${baseUrl}/readcard/entry/jiangsu_checkdll`);
  255. const data = await response.json();
  256. showResult('manageResult', data, data.code !== 200);
  257. } catch (error) {
  258. showResult('manageResult', { error: error.message }, true);
  259. }
  260. }
  261. // 获取帮助
  262. async function getHelp() {
  263. try {
  264. const helpInfo = {
  265. "江苏医保API接口": {
  266. "基础URL": "http://localhost:8321/readcard/jiangsu/{action}",
  267. "支持的操作": [
  268. "init - 初始化系统",
  269. "readcard - 读取社保卡",
  270. "readcard_pin - 读卡并验证PIN",
  271. "verifypin - 验证PIN码",
  272. "changepin - 修改PIN码",
  273. "status - 获取设备状态",
  274. "reset - 重置系统状态",
  275. "getpersoninfo - 四合一介质获取个人信息"
  276. ],
  277. "POST接口": "/readcard/jiangsu (支持复杂参数)",
  278. "DLL文件": "HeaSecReadInfo.dll",
  279. "规范版本": "v0.9.9.15"
  280. }
  281. };
  282. showResult('manageResult', helpInfo);
  283. } catch (error) {
  284. showResult('manageResult', { error: error.message }, true);
  285. }
  286. }
  287. // 智能重置策略测试
  288. async function testSmartReset() {
  289. let testResult = { testSteps: [], finalResult: '' };
  290. try {
  291. // 模拟连续失败3次
  292. for (let i = 1; i <= 3; i++) {
  293. try {
  294. // 尝试读卡(假设会失败)
  295. const response = await fetch(`${baseUrl}/readcard/jiangsu/readcard`);
  296. const data = await response.json();
  297. testResult.testSteps.push({
  298. step: i,
  299. action: 'readcard',
  300. success: data.success,
  301. message: data.message
  302. });
  303. if (!data.success) {
  304. consecutiveFailures++;
  305. if (consecutiveFailures >= MAX_FAILURES) {
  306. // 自动重置
  307. testResult.testSteps.push({
  308. step: i + 0.5,
  309. action: 'auto_reset',
  310. message: '连续失败达到阈值,触发自动重置'
  311. });
  312. const resetResponse = await fetch(`${baseUrl}/readcard/jiangsu/reset`);
  313. const resetData = await resetResponse.json();
  314. testResult.testSteps.push({
  315. step: i + 0.6,
  316. action: 'reset',
  317. success: resetData.success,
  318. message: resetData.message
  319. });
  320. // 重新初始化
  321. const initResponse = await fetch(`${baseUrl}/readcard/jiangsu/init`);
  322. const initData = await initResponse.json();
  323. testResult.testSteps.push({
  324. step: i + 0.7,
  325. action: 'reinit',
  326. success: initData.success,
  327. message: initData.message
  328. });
  329. consecutiveFailures = 0;
  330. break;
  331. }
  332. } else {
  333. consecutiveFailures = 0;
  334. break;
  335. }
  336. } catch (error) {
  337. consecutiveFailures++;
  338. testResult.testSteps.push({
  339. step: i,
  340. action: 'readcard',
  341. success: false,
  342. error: error.message
  343. });
  344. }
  345. // 短暂延迟
  346. await new Promise(resolve => setTimeout(resolve, 500));
  347. }
  348. testResult.finalResult = `智能重置策略测试完成。当前连续失败次数: ${consecutiveFailures}`;
  349. showResult('smartResetResult', testResult);
  350. } catch (error) {
  351. testResult.error = error.message;
  352. showResult('smartResetResult', testResult, true);
  353. }
  354. }
  355. // 页面加载完成后检查状态
  356. window.onload = function() {
  357. checkHealth();
  358. };
  359. </script>
  360. </body>
  361. </html>