江苏医保读卡最佳实践建议.md 16 KB

江苏医保社保卡读取最佳实践建议

🎯 智能重置策略(推荐方案)

📋 策略概述

基于用户使用场景(网页点击按钮读卡),采用智能重置策略:

1. 系统启动时 → 初始化一次
2. 患者A → 点击读卡 → 成功
3. 患者B → 点击读卡 → 成功  
4. 患者C → 点击读卡 → 成功
5. 如果连续失败 → 自动重置 → 重新初始化
6. 继续正常读卡...

🔄 核心实现

JavaScript智能读卡函数

let consecutiveFailures = 0;
const MAX_FAILURES = 3; // 连续失败3次后自动重置

async function smartReadCard() {
    try {
        // 调用读卡API
        const response = await fetch('/api/jiangsu/readcard', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({})
        });
        
        const result = await response.json();
        
        if (result.success) {
            consecutiveFailures = 0; // 成功后重置失败计数
            console.log('读卡成功:', result.data);
            return result;
        } else {
            throw new Error(result.message);
        }
    } catch (error) {
        consecutiveFailures++;
        console.log(`读卡失败 ${consecutiveFailures}/${MAX_FAILURES}:`, error.message);
        
        if (consecutiveFailures >= MAX_FAILURES) {
            console.log('连续失败达到阈值,自动重置系统...');
            
            try {
                // 自动重置系统
                await fetch('/api/jiangsu/reset', { method: 'POST' });
                
                // 重新初始化
                const initResponse = await fetch('/api/jiangsu/init', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        ip: "192.168.1.100",
                        port: "8080",
                        timeout: "30000",
                        logPath: "C:\\logs\\jiangsu_medical.log",
                        ecUrl: "https://fuwu.nhsa.gov.cn",
                        orgCode: "H32010000001",
                        deviceNo: "设备编号001",
                        operId: "操作员001",
                        operName: "系统操作员",
                        officeId: "科室001",
                        officeName: "门诊部",
                        machineCode: "终端001"
                    })
                });
                
                if (initResponse.ok) {
                    consecutiveFailures = 0; // 重置成功后清零
                    console.log('系统重置并重新初始化完成');
                    
                    // 重置后再次尝试读卡
                    return await readCardDirect(); // 直接调用读卡,避免递归
                } else {
                    throw new Error('系统重置失败');
                }
            } catch (resetError) {
                console.error('自动重置过程失败:', resetError);
                throw new Error('系统重置失败,请手动重启应用');
            }
        }
        
        throw error; // 未达到重置阈值,直接抛出错误
    }
}

// 直接读卡函数(避免重置逻辑递归)
async function readCardDirect() {
    const response = await fetch('/api/jiangsu/readcard', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({})
    });
    
    const result = await response.json();
    if (!result.success) {
        throw new Error(result.message);
    }
    
    return result;
}

🌐 完整的HTML页面实现

<!DOCTYPE html>
<html>
<head>
    <title>江苏医保读卡系统</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .container { max-width: 800px; margin: 0 auto; }
        .status { padding: 10px; margin: 10px 0; border-radius: 5px; }
        .success { background-color: #d4edda; color: #155724; }
        .error { background-color: #f8d7da; color: #721c24; }
        .warning { background-color: #fff3cd; color: #856404; }
        .info { background-color: #d1ecf1; color: #0c5460; }
        button { padding: 12px 24px; margin: 5px; font-size: 16px; border: none; border-radius: 5px; cursor: pointer; }
        .primary { background-color: #007bff; color: white; }
        .secondary { background-color: #6c757d; color: white; }
        .primary:disabled { background-color: #6c757d; cursor: not-allowed; }
        .result { margin-top: 20px; padding: 15px; border-radius: 5px; background-color: #f8f9fa; }
    </style>
</head>
<body>
    <div class="container">
        <h1>江苏医保社保卡读取系统</h1>
        
        <div id="status" class="status info">系统准备中...</div>
        
        <div>
            <button id="readBtn" class="primary" onclick="handleReadCard()" disabled>读取社保卡</button>
            <button id="manualResetBtn" class="secondary" onclick="manualReset()">手动重置</button>
        </div>
        
        <div id="failureCounter" style="margin-top: 10px; font-size: 14px; color: #666;"></div>
        
        <div id="result" class="result" style="display: none;"></div>
    </div>

    <script>
        let consecutiveFailures = 0;
        const MAX_FAILURES = 3;

        // 页面加载时初始化系统
        window.onload = async function() {
            await initializeSystem();
        };

        // 系统初始化
        async function initializeSystem() {
            const statusDiv = document.getElementById('status');
            const readBtn = document.getElementById('readBtn');
            
            try {
                statusDiv.textContent = '正在初始化系统...';
                statusDiv.className = 'status info';
                
                const response = await fetch('/api/jiangsu/init', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        ip: "192.168.1.100",
                        port: "8080",
                        timeout: "30000",
                        logPath: "C:\\logs\\jiangsu_medical.log",
                        ecUrl: "https://fuwu.nhsa.gov.cn",
                        orgCode: "H32010000001",
                        deviceNo: "设备编号001",
                        operId: "操作员001",
                        operName: "系统操作员",
                        officeId: "科室001",
                        officeName: "门诊部",
                        machineCode: "终端001"
                    })
                });
                
                const result = await response.json();
                
                if (result.success) {
                    statusDiv.textContent = '✅ 系统已就绪,可以开始读卡';
                    statusDiv.className = 'status success';
                    readBtn.disabled = false;
                    consecutiveFailures = 0; // 初始化成功后重置失败计数
                    updateFailureCounter();
                } else {
                    statusDiv.textContent = '❌ 系统初始化失败: ' + result.message;
                    statusDiv.className = 'status error';
                }
            } catch (error) {
                statusDiv.textContent = '❌ 系统初始化错误: ' + error.message;
                statusDiv.className = 'status error';
            }
        }

        // 处理读卡按钮点击
        async function handleReadCard() {
            const resultDiv = document.getElementById('result');
            const readBtn = document.getElementById('readBtn');
            
            readBtn.disabled = true;
            resultDiv.style.display = 'block';
            resultDiv.innerHTML = '<p>🔄 正在读取社保卡...</p>';
            
            try {
                const result = await smartReadCard();
                
                // 显示读卡结果
                resultDiv.innerHTML = `
                    <h3>✅ 读卡成功</h3>
                    <table style="width: 100%; border-collapse: collapse;">
                        <tr><td style="padding: 5px; border: 1px solid #ddd;"><strong>姓名:</strong></td><td style="padding: 5px; border: 1px solid #ddd;">${result.data.name || '未获取'}</td></tr>
                        <tr><td style="padding: 5px; border: 1px solid #ddd;"><strong>身份证号:</strong></td><td style="padding: 5px; border: 1px solid #ddd;">${result.data.idNumber || '未获取'}</td></tr>
                        <tr><td style="padding: 5px; border: 1px solid #ddd;"><strong>社保卡号:</strong></td><td style="padding: 5px; border: 1px solid #ddd;">${result.data.cardNumber || '未获取'}</td></tr>
                        <tr><td style="padding: 5px; border: 1px solid #ddd;"><strong>读取时间:</strong></td><td style="padding: 5px; border: 1px solid #ddd;">${new Date().toLocaleString()}</td></tr>
                    </table>
                `;
                
                updateStatus('✅ 读卡成功', 'success');
            } catch (error) {
                resultDiv.innerHTML = `
                    <h3>❌ 读卡失败</h3>
                    <p style="color: red;">${error.message}</p>
                    <p><small>失败次数: ${consecutiveFailures}/${MAX_FAILURES}</small></p>
                    ${consecutiveFailures >= MAX_FAILURES ? '<p style="color: orange;">⚠️ 已自动重置系统</p>' : ''}
                `;
                
                updateStatus(`❌ 读卡失败: ${error.message}`, 'error');
            } finally {
                readBtn.disabled = false;
                updateFailureCounter();
            }
        }

        // 智能读卡函数
        async function smartReadCard() {
            try {
                const response = await fetch('/api/jiangsu/readcard', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({})
                });
                
                const result = await response.json();
                
                if (result.success) {
                    consecutiveFailures = 0; // 成功后重置失败计数
                    return result;
                } else {
                    throw new Error(result.message);
                }
            } catch (error) {
                consecutiveFailures++;
                
                if (consecutiveFailures >= MAX_FAILURES) {
                    updateStatus('⚠️ 连续失败,正在自动重置系统...', 'warning');
                    
                    try {
                        // 自动重置系统
                        await fetch('/api/jiangsu/reset', { method: 'POST' });
                        
                        // 重新初始化
                        const initResponse = await fetch('/api/jiangsu/init', {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify({
                                ip: "192.168.1.100",
                                port: "8080",
                                timeout: "30000",
                                logPath: "C:\\logs\\jiangsu_medical.log",
                                ecUrl: "https://fuwu.nhsa.gov.cn",
                                orgCode: "H32010000001",
                                deviceNo: "设备编号001",
                                operId: "操作员001",
                                operName: "系统操作员",
                                officeId: "科室001",
                                officeName: "门诊部",
                                machineCode: "终端001"
                            })
                        });
                        
                        if (initResponse.ok) {
                            consecutiveFailures = 0; // 重置成功后清零
                            updateStatus('✅ 系统重置完成,再次尝试读卡', 'success');
                            
                            // 重置后再次尝试读卡
                            return await readCardDirect();
                        } else {
                            throw new Error('系统重置失败');
                        }
                    } catch (resetError) {
                        throw new Error('系统重置失败,请手动重启应用: ' + resetError.message);
                    }
                }
                
                throw error;
            }
        }

        // 直接读卡函数(避免递归)
        async function readCardDirect() {
            const response = await fetch('/api/jiangsu/readcard', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({})
            });
            
            const result = await response.json();
            if (!result.success) {
                throw new Error(result.message);
            }
            
            return result;
        }

        // 手动重置功能
        async function manualReset() {
            if (!confirm('确定要手动重置江苏医保系统吗?')) {
                return;
            }
            
            try {
                updateStatus('🔄 正在手动重置系统...', 'info');
                
                await fetch('/api/jiangsu/reset', { method: 'POST' });
                consecutiveFailures = 0;
                updateFailureCounter();
                
                // 重新初始化
                await initializeSystem();
            } catch (error) {
                updateStatus('❌ 手动重置失败: ' + error.message, 'error');
            }
        }

        // 更新状态显示
        function updateStatus(message, type) {
            const statusDiv = document.getElementById('status');
            statusDiv.textContent = message;
            statusDiv.className = 'status ' + type;
        }

        // 更新失败计数显示
        function updateFailureCounter() {
            const counterDiv = document.getElementById('failureCounter');
            if (consecutiveFailures > 0) {
                counterDiv.textContent = `连续失败次数: ${consecutiveFailures}/${MAX_FAILURES}`;
                counterDiv.style.color = consecutiveFailures >= 2 ? '#dc3545' : '#ffc107';
            } else {
                counterDiv.textContent = '';
            }
        }
    </script>
</body>
</html>

📊 策略特点

优势

  1. 高效率 - 系统启动时初始化一次,避免重复初始化开销
  2. 智能恢复 - 连续失败3次自动重置,无需人工干预
  3. 用户友好 - 自动处理异常,用户体验流畅
  4. 状态可视 - 实时显示失败计数和系统状态
  5. 手动备份 - 提供手动重置选项作为备用方案

🔄 工作流程

正常流程:
启动 → 初始化 → 读卡成功 → 读卡成功 → 读卡成功 → ...

异常恢复:
读卡失败1次 → 读卡失败2次 → 读卡失败3次 → 自动重置 → 重新初始化 → 继续读卡

📈 性能对比

策略 初始化频率 响应速度 自动恢复 用户体验 推荐度
智能重置 启动+异常时 快速 ✅ 自动 优秀 ⭐⭐⭐⭐⭐
手动重置 启动+手动时 快速 ❌ 手动 良好 ⭐⭐⭐⭐
每次重置 每次读卡 ❌ 无

🎯 实施建议

  1. 部署此HTML页面作为读卡界面
  2. 设置失败阈值为3次(可根据实际情况调整)
  3. 配置初始化参数(IP、端口等)
  4. 监控系统日志了解重置频率
  5. 定期维护确保DLL文件正常

这种智能重置策略既保证了系统的高效运行,又提供了自动故障恢复能力,是医疗场景下的最佳实践方案。