Fix Bug #566: AI修复
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<div class="temperature-sheet-container">
|
||||
<div class="chart-wrapper">
|
||||
<div ref="chartRef" class="temperature-chart"></div>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
<el-table :data="tableData" border stripe style="width: 100%" size="small">
|
||||
<el-table-column prop="measureTime" label="测量时间" width="160" align="center" />
|
||||
<el-table-column prop="temperature" label="体温(℃)" width="100" align="center">
|
||||
<template #default="{ row }">{{ row.temperature ? row.temperature.toFixed(1) : '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="pulse" label="脉搏(次/分)" width="110" align="center" />
|
||||
<el-table-column prop="heartRate" label="心率(次/分)" width="110" align="center" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { getPatientVitals } from '@/api/inpatient/vitalsign';
|
||||
|
||||
const props = defineProps({
|
||||
patientId: { type: [String, Number], required: true }
|
||||
});
|
||||
|
||||
const chartRef = ref(null);
|
||||
let chartInstance = null;
|
||||
const tableData = ref([]);
|
||||
|
||||
// 初始化图表
|
||||
const initChart = () => {
|
||||
if (!chartRef.value) return;
|
||||
chartInstance = echarts.init(chartRef.value);
|
||||
window.addEventListener('resize', handleResize);
|
||||
};
|
||||
|
||||
const handleResize = () => chartInstance?.resize();
|
||||
|
||||
// 核心修复:数据拉取与渲染逻辑
|
||||
const refreshData = async () => {
|
||||
try {
|
||||
const res = await getPatientVitals({ patientId: props.patientId });
|
||||
if (res.code === 200 && Array.isArray(res.data)) {
|
||||
// 按时间升序排序
|
||||
const sorted = res.data.sort((a, b) => new Date(a.measureTime) - new Date(b.measureTime));
|
||||
tableData.value = sorted; // 同步表格区
|
||||
renderChart(sorted);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[体温单] 数据加载失败:', err);
|
||||
}
|
||||
};
|
||||
|
||||
// 渲染图表(严格遵循医疗绘图规范)
|
||||
const renderChart = (data) => {
|
||||
if (!chartInstance) return;
|
||||
|
||||
const times = data.map(d => d.measureTime);
|
||||
|
||||
// 处理断点连线:缺失值映射为 null,配合 connectNulls: false 实现自动断开
|
||||
const mapSeries = (key) => data.map(d => (d[key] != null ? d[key] : null));
|
||||
|
||||
const option = {
|
||||
tooltip: { trigger: 'axis', formatter: '{b}<br/>{a}: {c}' },
|
||||
grid: { top: 30, bottom: 30, left: 40, right: 20, containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: times,
|
||||
axisLabel: { rotate: 30, fontSize: 11 }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
min: 35,
|
||||
max: 42,
|
||||
splitNumber: 7,
|
||||
axisLine: { show: false },
|
||||
splitLine: { lineStyle: { type: 'dashed' } }
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '体温',
|
||||
type: 'line',
|
||||
data: mapSeries('temperature'),
|
||||
symbol: 'x',
|
||||
symbolSize: 8,
|
||||
lineStyle: { color: '#1890ff', width: 2 },
|
||||
itemStyle: { color: '#1890ff' },
|
||||
connectNulls: false // 医疗规范:数据缺失必须断开
|
||||
},
|
||||
{
|
||||
name: '脉搏',
|
||||
type: 'line',
|
||||
data: mapSeries('pulse'),
|
||||
symbol: 'circle', // ● 实心圆
|
||||
symbolSize: 8,
|
||||
lineStyle: { color: '#ff4d4f', width: 2 },
|
||||
itemStyle: { color: '#ff4d4f' },
|
||||
connectNulls: false
|
||||
},
|
||||
{
|
||||
name: '心率',
|
||||
type: 'line',
|
||||
data: mapSeries('heartRate'),
|
||||
symbol: 'emptyCircle', // ○ 空心圆
|
||||
symbolSize: 8,
|
||||
lineStyle: { color: '#ff4d4f', width: 2 },
|
||||
itemStyle: { color: '#ff4d4f' },
|
||||
connectNulls: false
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// 重叠处理:ECharts 默认按 series 顺序绘制,心率(空心)在脉搏(实心)之上,符合临床视觉习惯
|
||||
chartInstance.setOption(option, true);
|
||||
};
|
||||
|
||||
// 暴露方法供父组件/弹窗在保存成功后调用
|
||||
defineExpose({ refreshData });
|
||||
|
||||
onMounted(() => {
|
||||
initChart();
|
||||
refreshData();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
chartInstance?.dispose();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.temperature-sheet-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
}
|
||||
.chart-wrapper {
|
||||
flex: 1;
|
||||
min-height: 300px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.temperature-chart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.table-wrapper {
|
||||
height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user