基于用户使用场景(网页点击按钮读卡),采用智能重置策略:
1. 系统启动时 → 初始化一次
2. 患者A → 点击读卡 → 成功
3. 患者B → 点击读卡 → 成功
4. 患者C → 点击读卡 → 成功
5. 如果连续失败 → 自动重置 → 重新初始化
6. 继续正常读卡...
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;
}
<!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次 → 自动重置 → 重新初始化 → 继续读卡
策略 | 初始化频率 | 响应速度 | 自动恢复 | 用户体验 | 推荐度 |
---|---|---|---|---|---|
智能重置 | 启动+异常时 | 快速 | ✅ 自动 | 优秀 | ⭐⭐⭐⭐⭐ |
手动重置 | 启动+手动时 | 快速 | ❌ 手动 | 良好 | ⭐⭐⭐⭐ |
每次重置 | 每次读卡 | 慢 | ❌ 无 | 差 | ⭐ |
这种智能重置策略既保证了系统的高效运行,又提供了自动故障恢复能力,是医疗场景下的最佳实践方案。