HRV报告
This commit is contained in:
parent
6912cab7f1
commit
a8d28605b1
806
public/HRV-report.html
Normal file
806
public/HRV-report.html
Normal file
@ -0,0 +1,806 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>自主神经系统平衡检查报告</title>
|
||||
<!-- 引入ECharts -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Microsoft YaHei', Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.report-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.report-page {
|
||||
margin-bottom: 40px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
width: 210mm;
|
||||
height: 297mm;
|
||||
margin: 0 auto 40px;
|
||||
position: relative;
|
||||
background: white;
|
||||
padding: 20mm;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 2px solid #333;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.page-header h1 {
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.patient-info-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.patient-info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 15px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-weight: bold;
|
||||
margin-right: 8px;
|
||||
color: #000;
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: #000;
|
||||
border-bottom: 1px solid #000;
|
||||
flex: 1;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.results-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.results-title {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 15px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.data-table th,
|
||||
.data-table td {
|
||||
border: 1px solid #000;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.data-table th {
|
||||
background-color: #f0f0f0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.analysis-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.analysis-table th,
|
||||
.analysis-table td {
|
||||
border: 1px solid #000;
|
||||
padding: 6px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.analysis-table th {
|
||||
background-color: #f0f0f0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.charts-section {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
height: 200px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.bottom-charts {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pie-chart {
|
||||
height: 150px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.radar-chart {
|
||||
height: 150px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
margin-top: 20px;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
.status-normal {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.status-excellent {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.status-poor {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.status-abnormal {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/* 打印样式 */
|
||||
@media print {
|
||||
body {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.report-page {
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 15mm;
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
.chart-container,
|
||||
.pie-chart,
|
||||
.radar-chart {
|
||||
border: 1px solid #000;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loading 遮罩 */
|
||||
.loading-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 9999;
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #3498db;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.debug-info {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
color: white;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
font-size: 12px;
|
||||
max-width: 300px;
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
display: none;
|
||||
z-index: 10000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Loading 遮罩 -->
|
||||
<div id="loading-mask" class="loading-mask">
|
||||
<div class="loading-spinner"></div>
|
||||
<span>正在加载报告数据...</span>
|
||||
</div>
|
||||
|
||||
<!-- 调试信息 -->
|
||||
<div id="debug-info" class="debug-info">
|
||||
<div id="debug-content"></div>
|
||||
</div>
|
||||
|
||||
<div class="report-container">
|
||||
<div class="report-page">
|
||||
<!-- 页面头部 -->
|
||||
<div class="page-header">
|
||||
<h1>自主神经系统平衡检查</h1>
|
||||
</div>
|
||||
|
||||
<!-- 患者信息 -->
|
||||
<div class="patient-info-section">
|
||||
<div class="patient-info-grid">
|
||||
<div class="info-item">
|
||||
<span class="info-label">姓名:</span>
|
||||
<span class="info-value" id="patient-name">郭永生</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">性别:</span>
|
||||
<span class="info-value" id="patient-gender">男</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">年龄:</span>
|
||||
<span class="info-value" id="patient-age">43</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">检查ID:</span>
|
||||
<span class="info-value" id="exam-id">20216991</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 检查结果 -->
|
||||
<div class="results-section">
|
||||
<div class="results-title">检查结果</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<table class="data-table">
|
||||
<tr>
|
||||
<th>SDNN:</th>
|
||||
<td id="sdnn-value">57</td>
|
||||
<th>SDANN:</th>
|
||||
<td id="sdann-value">0</td>
|
||||
<th>rMSSD:</th>
|
||||
<td id="rmssd-value">20</td>
|
||||
<th>SDNNi:</th>
|
||||
<td id="sdnni-value">0</td>
|
||||
<th>pNN50:</th>
|
||||
<td id="pnn50-value">3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>TP</th>
|
||||
<td id="tp-value">5546</td>
|
||||
<th>HFP:</th>
|
||||
<td id="hfp-value">1659</td>
|
||||
<th>LFP:</th>
|
||||
<td id="lfp-value">2453</td>
|
||||
<th>vLFP:</th>
|
||||
<td id="vlfp-value">1434</td>
|
||||
<th>uLFP:</th>
|
||||
<td id="ulfp-value">0.0</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- 分析表格 -->
|
||||
<table class="analysis-table">
|
||||
<tr>
|
||||
<th>编号</th>
|
||||
<th>检查项</th>
|
||||
<th>说明</th>
|
||||
<th>检查结果</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>自主神经系统活性</td>
|
||||
<td>检查自主神经系统整体的活性</td>
|
||||
<td class="status-normal" id="result-1">正常</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2</td>
|
||||
<td>自主神经系统平衡度</td>
|
||||
<td>检查交感&副交感神经的平衡度</td>
|
||||
<td class="status-excellent" id="result-2">优秀</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3</td>
|
||||
<td>自主神经系统稳定性</td>
|
||||
<td>检查自主神经系统的稳定性</td>
|
||||
<td class="status-normal" id="result-3">正常</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4</td>
|
||||
<td>抗压能力</td>
|
||||
<td>检查身体对于环境变化的适应能力</td>
|
||||
<td class="status-excellent" id="result-4">优秀</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>5</td>
|
||||
<td>压力指数</td>
|
||||
<td>检查身体当前所受的压力程度</td>
|
||||
<td class="status-excellent" id="result-5">优秀</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>6</td>
|
||||
<td>疲劳程度</td>
|
||||
<td>检查身体当前所处的疲劳程度</td>
|
||||
<td class="status-normal" id="result-6">正常</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>7</td>
|
||||
<td>心脏稳定性</td>
|
||||
<td>检查心脏的工作稳定性</td>
|
||||
<td class="status-excellent" id="result-7">优秀</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>8</td>
|
||||
<td>焦虑程度</td>
|
||||
<td>检查身体当前所处的焦虑程度</td>
|
||||
<td class="status-poor" id="result-8">不焦虑</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>9</td>
|
||||
<td>抑郁程度</td>
|
||||
<td>检查身体当前所处的抑郁程度</td>
|
||||
<td class="status-poor" id="result-9">不抑郁</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>10</td>
|
||||
<td>睡眠调控指数</td>
|
||||
<td>检查自主神经对于睡眠的调控力</td>
|
||||
<td class="status-excellent" id="result-10">优秀</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>11</td>
|
||||
<td>身心控制指数</td>
|
||||
<td>检查身体当前所处的放松程度</td>
|
||||
<td id="result-11">17次佳</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>12</td>
|
||||
<td>平均心率</td>
|
||||
<td>反应监测过程中平均心率</td>
|
||||
<td id="result-12">66正常</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 图表区域 -->
|
||||
<div class="charts-section">
|
||||
<div class="chart-container" id="bar-chart-1"></div>
|
||||
<div class="chart-container" id="bar-chart-2"></div>
|
||||
</div>
|
||||
|
||||
<div class="bottom-charts">
|
||||
<div class="pie-chart" id="pie-chart"></div>
|
||||
<div class="radar-chart" id="radar-chart"></div>
|
||||
</div>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<div class="footer-text">
|
||||
快速、无创、精准、权威
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 全局变量
|
||||
let reportData = null;
|
||||
let charts = {};
|
||||
|
||||
// 页面加载完成后初始化
|
||||
window.addEventListener('load', function() {
|
||||
// 从sessionStorage中获取数据
|
||||
const storedData = sessionStorage.getItem('hrvReportData');
|
||||
let data = null;
|
||||
|
||||
if (storedData) {
|
||||
try {
|
||||
data = JSON.parse(storedData);
|
||||
showDebugInfo('从sessionStorage获取到数据: ' + JSON.stringify(data).substring(0, 100) + '...');
|
||||
} catch (error) {
|
||||
showDebugInfo('解析sessionStorage数据失败: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
initializeReport(data);
|
||||
});
|
||||
|
||||
// 初始化报告
|
||||
function initializeReport(data) {
|
||||
if (!data) {
|
||||
showDebugInfo('没有接收到数据,使用默认数据');
|
||||
data = getDefaultData();
|
||||
}
|
||||
|
||||
reportData = data;
|
||||
showDebugInfo('开始初始化报告,数据: ' + JSON.stringify(data).substring(0, 100) + '...');
|
||||
|
||||
// 更新患者信息
|
||||
updatePatientInfo(data.patientInfo || {});
|
||||
|
||||
// 更新检查结果数据
|
||||
updateResultsData(data.resultsData || {});
|
||||
|
||||
// 更新分析结果
|
||||
updateAnalysisResults(data.analysisResults || []);
|
||||
|
||||
// 初始化图表
|
||||
initializeCharts(data.chartData || {});
|
||||
|
||||
hideLoading();
|
||||
showDebugInfo('报告初始化完成');
|
||||
}
|
||||
|
||||
// 更新患者信息
|
||||
function updatePatientInfo(patientInfo) {
|
||||
document.getElementById('patient-name').textContent = patientInfo.name || '郭永生';
|
||||
document.getElementById('patient-gender').textContent = patientInfo.gender || '男';
|
||||
document.getElementById('patient-age').textContent = patientInfo.age || '43';
|
||||
document.getElementById('exam-id').textContent = patientInfo.examId || '20216991';
|
||||
}
|
||||
|
||||
// 更新检查结果数据
|
||||
function updateResultsData(resultsData) {
|
||||
document.getElementById('sdnn-value').textContent = resultsData.SDNN || '57';
|
||||
document.getElementById('sdann-value').textContent = resultsData.SDANN || '0';
|
||||
document.getElementById('rmssd-value').textContent = resultsData.rMSSD || '20';
|
||||
document.getElementById('sdnni-value').textContent = resultsData.SDNNi || '0';
|
||||
document.getElementById('pnn50-value').textContent = resultsData.pNN50 || '3';
|
||||
document.getElementById('tp-value').textContent = resultsData.TP || '5546';
|
||||
document.getElementById('hfp-value').textContent = resultsData.HFP || '1659';
|
||||
document.getElementById('lfp-value').textContent = resultsData.LFP || '2453';
|
||||
document.getElementById('vlfp-value').textContent = resultsData.vLFP || '1434';
|
||||
document.getElementById('ulfp-value').textContent = resultsData.uLFP || '0.0';
|
||||
}
|
||||
|
||||
// 更新分析结果
|
||||
function updateAnalysisResults(analysisResults) {
|
||||
const defaultResults = [
|
||||
'正常', '优秀', '正常', '优秀', '优秀', '正常',
|
||||
'优秀', '不焦虑', '不抑郁', '优秀', '17次佳', '66正常'
|
||||
];
|
||||
|
||||
for (let i = 1; i <= 12; i++) {
|
||||
const element = document.getElementById(`result-${i}`);
|
||||
if (element) {
|
||||
element.textContent = analysisResults[i - 1] || defaultResults[i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化图表
|
||||
function initializeCharts(chartData) {
|
||||
// 初始化柱状图1 (TP, VLF, LF, HF)
|
||||
const barChart1 = echarts.init(document.getElementById('bar-chart-1'));
|
||||
const barOption1 = {
|
||||
title: {
|
||||
text: '频域分析',
|
||||
left: 'center',
|
||||
textStyle: { fontSize: 14 }
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['TP', 'VLF', 'LF', 'HF']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [{
|
||||
data: [
|
||||
{ value: chartData.TP || 5546, itemStyle: { color: '#5DADE2' } },
|
||||
{ value: chartData.VLF || 1434, itemStyle: { color: '#EC7063' } },
|
||||
{ value: chartData.LF || 2453, itemStyle: { color: '#58D68D' } },
|
||||
{ value: chartData.HF || 1659, itemStyle: { color: '#F7DC6F' } }
|
||||
],
|
||||
type: 'bar'
|
||||
}]
|
||||
};
|
||||
barChart1.setOption(barOption1);
|
||||
charts.barChart1 = barChart1;
|
||||
|
||||
// 初始化柱状图2 (SDNN, rMSSD, pNN50)
|
||||
const barChart2 = echarts.init(document.getElementById('bar-chart-2'));
|
||||
const barOption2 = {
|
||||
title: {
|
||||
text: '时域分析',
|
||||
left: 'center',
|
||||
textStyle: { fontSize: 14 }
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['SDNN', 'rMSSD', 'pNN50']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [{
|
||||
data: [
|
||||
{ value: chartData.SDNN || 57, itemStyle: { color: '#5DADE2' } },
|
||||
{ value: chartData.rMSSD || 20, itemStyle: { color: '#EC7063' } },
|
||||
{ value: chartData.pNN50 || 3, itemStyle: { color: '#58D68D' } }
|
||||
],
|
||||
type: 'bar'
|
||||
}]
|
||||
};
|
||||
barChart2.setOption(barOption2);
|
||||
charts.barChart2 = barChart2;
|
||||
|
||||
// 初始化饼图 (LF/HF比例)
|
||||
const pieChart = echarts.init(document.getElementById('pie-chart'));
|
||||
const lfValue = chartData.LF || 2453;
|
||||
const hfValue = chartData.HF || 1659;
|
||||
const total = lfValue + hfValue;
|
||||
const lfPercent = ((lfValue / total) * 100).toFixed(1);
|
||||
const hfPercent = ((hfValue / total) * 100).toFixed(1);
|
||||
|
||||
const pieOption = {
|
||||
title: {
|
||||
text: 'LF/HF占比图',
|
||||
left: 'center',
|
||||
textStyle: { fontSize: 14 }
|
||||
},
|
||||
series: [{
|
||||
type: 'pie',
|
||||
radius: '60%',
|
||||
data: [
|
||||
{ value: lfValue, name: `LF: ${lfPercent}%`, itemStyle: { color: '#58D68D' } },
|
||||
{ value: hfValue, name: `HF: ${hfPercent}%`, itemStyle: { color: '#F7DC6F' } }
|
||||
],
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{b}'
|
||||
}
|
||||
}]
|
||||
};
|
||||
pieChart.setOption(pieOption);
|
||||
charts.pieChart = pieChart;
|
||||
|
||||
// 初始化雷达图
|
||||
const radarChart = echarts.init(document.getElementById('radar-chart'));
|
||||
const radarOption = {
|
||||
title: {
|
||||
text: '(1~11)检测结果雷达图',
|
||||
left: 'center',
|
||||
textStyle: { fontSize: 14 }
|
||||
},
|
||||
radar: {
|
||||
indicator: [
|
||||
{ name: '活性', max: 4 },
|
||||
{ name: '平衡', max: 4 },
|
||||
{ name: '稳定', max: 4 },
|
||||
{ name: '抗压', max: 4 },
|
||||
{ name: '压力', max: 4 },
|
||||
{ name: '疲劳', max: 4 },
|
||||
{ name: '心脏', max: 4 },
|
||||
{ name: '焦虑', max: 4 },
|
||||
{ name: '抑郁', max: 4 },
|
||||
{ name: '睡眠', max: 4 },
|
||||
{ name: '身心', max: 4 }
|
||||
],
|
||||
radius: '60%'
|
||||
},
|
||||
series: [{
|
||||
type: 'radar',
|
||||
data: [{
|
||||
value: chartData.radarData || [3, 4, 3, 4, 4, 3, 4, 1, 1, 4, 2],
|
||||
itemStyle: { color: '#5DADE2' },
|
||||
areaStyle: { opacity: 0.3 }
|
||||
}]
|
||||
}]
|
||||
};
|
||||
radarChart.setOption(radarOption);
|
||||
charts.radarChart = radarChart;
|
||||
}
|
||||
|
||||
// 获取默认数据
|
||||
function getDefaultData() {
|
||||
return {
|
||||
patientInfo: {
|
||||
name: '测试患者',
|
||||
gender: '男',
|
||||
age: '43',
|
||||
examId: '691f27c5ba3e4b6fae5960e50eb206f1'
|
||||
},
|
||||
resultsData: {
|
||||
SDNN: '64',
|
||||
SDANN: '38',
|
||||
rMSSD: '28',
|
||||
SDNNi: '34',
|
||||
pNN50: '9',
|
||||
TP: '5200',
|
||||
HFP: '1950',
|
||||
LFP: '2100',
|
||||
vLFP: '1150',
|
||||
uLFP: '0.0'
|
||||
},
|
||||
analysisResults: [
|
||||
'正常', '良好', '正常', '良好', '正常', '轻度疲劳',
|
||||
'良好', '轻度焦虑', '不抑郁', '良好', '15/正常', '68/正常'
|
||||
],
|
||||
chartData: {
|
||||
TP: 5200,
|
||||
VLF: 1150,
|
||||
LF: 2100,
|
||||
HF: 1950,
|
||||
SDNN: 64,
|
||||
rMSSD: 28,
|
||||
pNN50: 9,
|
||||
radarData: [3, 4, 3, 4, 4, 3, 4, 1, 1, 4, 2]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 监听来自父窗口的消息
|
||||
window.addEventListener('message', function(event) {
|
||||
showDebugInfo('接收到消息: ' + JSON.stringify(event.data).substring(0, 100));
|
||||
|
||||
if (event.data && event.data.type === 'HRV_REPORT_DATA') {
|
||||
const receivedData = event.data.data;
|
||||
showDebugInfo('接收到HRV报告数据');
|
||||
showDebugInfo('患者信息存在: ' + (receivedData && receivedData.patientInfo ? '是' : '否'));
|
||||
showDebugInfo('检查结果存在: ' + (receivedData && receivedData.resultsData ? '是' : '否'));
|
||||
|
||||
// 延迟一点时间确保页面完全加载
|
||||
setTimeout(() => {
|
||||
try {
|
||||
// 创建深拷贝,避免引用问题
|
||||
const dataCopy = JSON.parse(JSON.stringify(receivedData));
|
||||
initializeReport(dataCopy);
|
||||
showDebugInfo('报告数据初始化完成');
|
||||
|
||||
// 添加打印按钮
|
||||
addPrintButton();
|
||||
} catch (error) {
|
||||
showDebugInfo('初始化报告数据失败: ' + error.message);
|
||||
console.error('初始化报告数据失败:', error);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
|
||||
// 添加打印按钮
|
||||
function addPrintButton() {
|
||||
// 检查是否已存在打印按钮
|
||||
if (document.getElementById('print-button')) return;
|
||||
|
||||
const printButton = document.createElement('button');
|
||||
printButton.id = 'print-button';
|
||||
printButton.innerHTML = '打印报告';
|
||||
printButton.style.position = 'fixed';
|
||||
printButton.style.top = '20px';
|
||||
printButton.style.right = '20px';
|
||||
printButton.style.zIndex = '9999';
|
||||
printButton.style.padding = '8px 16px';
|
||||
printButton.style.backgroundColor = '#3498db';
|
||||
printButton.style.color = 'white';
|
||||
printButton.style.border = 'none';
|
||||
printButton.style.borderRadius = '4px';
|
||||
printButton.style.cursor = 'pointer';
|
||||
printButton.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)';
|
||||
|
||||
printButton.addEventListener('click', function() {
|
||||
// 隐藏打印按钮和调试信息
|
||||
this.style.display = 'none';
|
||||
const debugInfo = document.getElementById('debug-info');
|
||||
if (debugInfo) debugInfo.style.display = 'none';
|
||||
|
||||
// 短暂延迟确保样式生效
|
||||
setTimeout(() => {
|
||||
window.print();
|
||||
|
||||
// 打印后恢复按钮显示
|
||||
setTimeout(() => {
|
||||
this.style.display = 'block';
|
||||
}, 500);
|
||||
}, 200);
|
||||
});
|
||||
|
||||
document.body.appendChild(printButton);
|
||||
}
|
||||
|
||||
// 显示调试信息到页面
|
||||
function showDebugInfo(message) {
|
||||
const debugInfo = document.getElementById('debug-info');
|
||||
const debugContent = document.getElementById('debug-content');
|
||||
if (debugInfo && debugContent) {
|
||||
debugInfo.style.display = 'block';
|
||||
debugContent.innerHTML += '<div>' + new Date().toLocaleTimeString() + ': ' + message + '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载完成后的初始化
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
showLoading(); // 页面初始显示loading
|
||||
showDebugInfo('页面DOM加载完成');
|
||||
|
||||
// 向父窗口发送加载完成消息
|
||||
if (window.opener) {
|
||||
showDebugInfo('检测到父窗口,发送加载完成消息');
|
||||
window.opener.postMessage({
|
||||
type: 'HRV_TEMPLATE_LOADED'
|
||||
}, '*');
|
||||
} else {
|
||||
// 如果不是从其他窗口打开的,使用默认数据
|
||||
showDebugInfo('独立打开页面,使用默认数据');
|
||||
setTimeout(() => {
|
||||
initializeReport(null);
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
|
||||
// loading 遮罩控制
|
||||
function showLoading() {
|
||||
const mask = document.getElementById('loading-mask');
|
||||
if (mask) mask.style.display = 'flex';
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
function hideLoading() {
|
||||
const mask = document.getElementById('loading-mask');
|
||||
if (mask) mask.style.display = 'none';
|
||||
document.body.style.overflow = '';
|
||||
}
|
||||
|
||||
// 窗口大小改变时重新调整图表
|
||||
window.addEventListener('resize', function() {
|
||||
Object.values(charts).forEach(chart => {
|
||||
if (chart && chart.resize) {
|
||||
chart.resize();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -59,5 +59,10 @@ export const HrvdataApi = {
|
||||
// 导出自主神经系统平衡检查数据 Excel
|
||||
exportHrvdata: async (params) => {
|
||||
return await request.download({ url: `/system/hrvdata/export-excel`, params })
|
||||
},
|
||||
|
||||
//根据examid查询自主神经系统平衡检查数据
|
||||
getHrvdataByExamid: async (examid: string) => {
|
||||
return await request.get({ url: `/system/hrvdata/getByExamid?examid=` + examid })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -576,6 +576,7 @@ import { getUserProfile, ProfileVO } from '@/api/system/user/profile'
|
||||
import { uploadFileInChunks } from '@/utils/upload'
|
||||
import { OrgApi } from '@/api/org'
|
||||
import { HrvApi, HrvVO } from '@/api/hrv'
|
||||
import { HrvdataApi } from '@/api/hrvdata'
|
||||
|
||||
defineOptions({ name: 'AnalysisHRV' })
|
||||
const Profilevo = ref<ProfileVO>({} as ProfileVO) //当前登录人信息
|
||||
@ -1019,7 +1020,94 @@ const resetQuery = () => {
|
||||
|
||||
/** 分析 */
|
||||
const handleAnalysis = async (row) => {
|
||||
// TODO: 实现分析功能
|
||||
try {
|
||||
const examid = row.examid
|
||||
if (!examid) {
|
||||
ElMessage.warning('检查ID不能为空')
|
||||
return
|
||||
}
|
||||
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '正在获取检查数据...',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
})
|
||||
|
||||
try {
|
||||
// 根据examid查询自主神经系统平衡检查数据
|
||||
const res = await HrvdataApi.getHrvdataPage({ examid: examid, pageNo: 1, pageSize: 1 })
|
||||
if (res && res.list && res.list.length > 0) {
|
||||
const hrvData = res.list[0]
|
||||
console.log('获取到的HRV数据:', hrvData)
|
||||
|
||||
// 打开报告页面并传递数据
|
||||
openHrvReport(hrvData, row)
|
||||
ElMessage.success('数据获取成功,正在生成报告')
|
||||
} else {
|
||||
ElMessage.warning('未找到相关检查数据')
|
||||
}
|
||||
} finally {
|
||||
loading.close()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('分析过程中出错:', error)
|
||||
ElMessage.error('分析失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
|
||||
/** 打开HRV报告页面 */
|
||||
const openHrvReport = (hrvData, patientData) => {
|
||||
// 构造报告数据
|
||||
const reportData = {
|
||||
patientInfo: {
|
||||
name: patientData.name || '',
|
||||
gender: patientData.gender === '1' ? '男' : patientData.gender === '2' ? '女' : '未知',
|
||||
age: patientData.age || '',
|
||||
examId: patientData.examid || hrvData.examid || ''
|
||||
},
|
||||
resultsData: {
|
||||
SDNN: String(hrvData.sdnn || '0'),
|
||||
SDANN: String(hrvData.sdann || '0'),
|
||||
rMSSD: String(hrvData.rmssd || '0'),
|
||||
SDNNi: String(hrvData.sdnni || '0'),
|
||||
pNN50: String(hrvData.pnn50 || '0'),
|
||||
TP: String(hrvData.tp || '0'),
|
||||
HFP: String(hrvData.hfp || '0'),
|
||||
LFP: String(hrvData.lfp || '0'),
|
||||
vLFP: String(hrvData.vlfp || '0'),
|
||||
uLFP: String(hrvData.ulfp || '0.0')
|
||||
},
|
||||
analysisResults: [
|
||||
hrvData.ansActivity || '正常',
|
||||
hrvData.ansBalance || '正常',
|
||||
hrvData.ansStability || '正常',
|
||||
hrvData.stressResistance || '正常',
|
||||
hrvData.stressIndex || '正常',
|
||||
hrvData.fatigueLevel || '正常',
|
||||
hrvData.heartStability || '正常',
|
||||
hrvData.anxietyLevel || '正常',
|
||||
hrvData.depressionLevel || '正常',
|
||||
hrvData.sleepControl || '正常',
|
||||
hrvData.bodyMindControl || '正常',
|
||||
hrvData.avgHeartRate || '正常'
|
||||
],
|
||||
chartData: {
|
||||
TP: parseInt(hrvData.tp) || 0,
|
||||
VLF: parseInt(hrvData.vlfp) || 0,
|
||||
LF: parseInt(hrvData.lfp) || 0,
|
||||
HF: parseInt(hrvData.hfp) || 0,
|
||||
SDNN: parseInt(hrvData.sdnn) || 0,
|
||||
rMSSD: parseInt(hrvData.rmssd) || 0,
|
||||
pNN50: parseInt(hrvData.pnn50) || 0
|
||||
}
|
||||
}
|
||||
|
||||
// 将数据存储到sessionStorage中
|
||||
sessionStorage.setItem('hrvReportData', JSON.stringify(reportData))
|
||||
|
||||
// 打开新窗口显示报告
|
||||
const reportUrl = '/HRV-report.html'
|
||||
window.open(reportUrl, '_blank', 'width=1200,height=800,scrollbars=yes,resizable=yes')
|
||||
}
|
||||
|
||||
// 文件浏览器相关方法
|
||||
@ -1372,7 +1460,167 @@ const handleApply = async (row) => {
|
||||
|
||||
/** 查看新报告 */
|
||||
const handleNewReport = async (row) => {
|
||||
// TODO: 实现查看新报告功能
|
||||
try {
|
||||
// 从接口获取HRV数据
|
||||
let hrvData = row
|
||||
try {
|
||||
// 使用API获取最新的HRV数据
|
||||
const response = await HrvdataApi.getHrvdataByExamid(row.examid)
|
||||
|
||||
if (response) {
|
||||
hrvData = response
|
||||
} else {
|
||||
console.warn('API返回数据为空,将使用传入的row数据')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('从API获取HRV数据失败:', error)
|
||||
ElMessage.warning('获取最新数据失败,将使用当前数据展示报告')
|
||||
}
|
||||
|
||||
// 构造报告数据
|
||||
const reportData = {
|
||||
patientInfo: {
|
||||
name: hrvData.name || '未知',
|
||||
gender: hrvData.gender === '1' ? '男' : hrvData.gender === '2' ? '女' : '未知',
|
||||
age: hrvData.age || '未知',
|
||||
examId: hrvData.examid || '未知'
|
||||
},
|
||||
resultsData: {
|
||||
SDNN: hrvData.sdnn || '57',
|
||||
SDANN: hrvData.sdann || '0',
|
||||
rMSSD: hrvData.rmssd || '20',
|
||||
SDNNi: hrvData.sdnni || '0',
|
||||
pNN50: hrvData.pnn50 || '3',
|
||||
TP: hrvData.tp || '5546',
|
||||
HFP: hrvData.hfp || '1659',
|
||||
LFP: hrvData.lfp || '2453',
|
||||
vLFP: hrvData.vlfp || '1434',
|
||||
uLFP: hrvData.ulfp || '0.0'
|
||||
},
|
||||
analysisResults: [
|
||||
hrvData.ansActivity || '正常',
|
||||
hrvData.ansBalance || '优秀',
|
||||
hrvData.ansStability || '正常',
|
||||
hrvData.stressResistance || '优秀',
|
||||
hrvData.stressIndex || '优秀',
|
||||
hrvData.fatigueLevel || '正常',
|
||||
hrvData.heartStability || '优秀',
|
||||
hrvData.anxietyLevel || '不焦虑',
|
||||
hrvData.depressionLevel || '不抑郁',
|
||||
hrvData.sleepControl || '优秀',
|
||||
hrvData.bodyMindControl || '17次佳',
|
||||
hrvData.avgHeartRate || '66正常'
|
||||
],
|
||||
chartData: {
|
||||
TP: parseInt(hrvData.tp) || 5546,
|
||||
VLF: parseInt(hrvData.vlfp) || 1434,
|
||||
LF: parseInt(hrvData.lfp) || 2453,
|
||||
HF: parseInt(hrvData.hfp) || 1659,
|
||||
SDNN: parseInt(hrvData.sdnn) || 57,
|
||||
rMSSD: parseInt(hrvData.rmssd) || 20,
|
||||
pNN50: parseInt(hrvData.pnn50) || 3,
|
||||
radarData: [
|
||||
hrvData.radar1 || 3,
|
||||
hrvData.radar2 || 4,
|
||||
hrvData.radar3 || 3,
|
||||
hrvData.radar4 || 4,
|
||||
hrvData.radar5 || 4,
|
||||
hrvData.radar6 || 3,
|
||||
hrvData.radar7 || 4,
|
||||
hrvData.radar8 || 1,
|
||||
hrvData.radar9 || 1,
|
||||
hrvData.radar10 || 4,
|
||||
hrvData.radar11 || 2
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// 获取报告页面URL
|
||||
const reportUrl = `${window.location.origin}/HRV-report.html`
|
||||
|
||||
// 打开新窗口并全屏展示
|
||||
const reportWindow = window.open(reportUrl, '_blank')
|
||||
|
||||
if (reportWindow) {
|
||||
// 全屏展示
|
||||
reportWindow.moveTo(0, 0)
|
||||
reportWindow.resizeTo(screen.availWidth, screen.availHeight)
|
||||
|
||||
let dataTransferred = false
|
||||
|
||||
// 监听来自报告窗口的消息
|
||||
const messageHandler = (event) => {
|
||||
if (
|
||||
event.source === reportWindow &&
|
||||
event.data?.type === 'HRV_TEMPLATE_LOADED' &&
|
||||
!dataTransferred
|
||||
) {
|
||||
dataTransferred = true
|
||||
// 延迟传递数据,确保页面完全准备好
|
||||
setTimeout(() => {
|
||||
try {
|
||||
// 创建深拷贝,避免引用问题
|
||||
const dataToSend = JSON.parse(JSON.stringify(reportData))
|
||||
reportWindow.postMessage(
|
||||
{
|
||||
type: 'HRV_REPORT_DATA',
|
||||
data: dataToSend
|
||||
},
|
||||
'*'
|
||||
)
|
||||
} catch (error) {
|
||||
console.error('传递数据到报告窗口失败:', error)
|
||||
ElMessage.error('初始化报告数据失败,请重试')
|
||||
}
|
||||
}, 100)
|
||||
|
||||
// 移除事件监听器
|
||||
window.removeEventListener('message', messageHandler)
|
||||
}
|
||||
}
|
||||
|
||||
// 添加消息监听器
|
||||
window.addEventListener('message', messageHandler)
|
||||
|
||||
// 备用方案:如果3秒内没有收到加载完成消息,直接尝试传递数据
|
||||
setTimeout(() => {
|
||||
if (!dataTransferred) {
|
||||
dataTransferred = true
|
||||
try {
|
||||
// 创建深拷贝,避免引用问题
|
||||
const dataToSend = JSON.parse(JSON.stringify(reportData))
|
||||
|
||||
reportWindow.postMessage(
|
||||
{
|
||||
type: 'HRV_REPORT_DATA',
|
||||
data: dataToSend
|
||||
},
|
||||
'*'
|
||||
)
|
||||
} catch (error) {
|
||||
console.error('备用方案传递数据失败:', error)
|
||||
ElMessage.error('初始化报告数据失败,请重试')
|
||||
}
|
||||
window.removeEventListener('message', messageHandler)
|
||||
}
|
||||
}, 3000)
|
||||
|
||||
// 监听窗口关闭,清理事件监听器
|
||||
const checkClosed = setInterval(() => {
|
||||
if (reportWindow.closed) {
|
||||
clearInterval(checkClosed)
|
||||
window.removeEventListener('message', messageHandler)
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
ElMessage.success('正在打开HRV报告...')
|
||||
} else {
|
||||
ElMessage.error('无法打开报告窗口,请检查浏览器弹窗设置')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('打开HRV报告失败:', error)
|
||||
ElMessage.error('打开HRV报告失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
/** 关闭新报告查看弹窗 */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user