Fix Bug #566: AI修复

This commit is contained in:
2026-05-27 04:29:39 +08:00
parent 882bb1980a
commit 58514c8ed7
4 changed files with 263 additions and 34 deletions

View File

@@ -0,0 +1,166 @@
<template>
<div class="temperature-chart-container">
<div class="chart-wrapper" ref="chartRef" data-cy="chart-area"></div>
<div class="table-wrapper">
<table class="vitalsign-table" data-cy="vitalsign-table">
<thead>
<tr>
<th>时间</th>
<th>体温()</th>
<th>脉搏(/)</th>
<th>心率(/)</th>
</tr>
</thead>
<tbody>
<tr v-for="row in tableData" :key="row.timeKey">
<td>{{ row.timeLabel }}</td>
<td :data-cy="`table-cell-${row.timeKey}-temp`">{{ row.temp ?? '-' }}</td>
<td :data-cy="`table-cell-${row.timeKey}-pulse`">{{ row.pulse ?? '-' }}</td>
<td :data-cy="`table-cell-${row.timeKey}-hr`">{{ row.hr ?? '-' }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import * as echarts from 'echarts'
import { getVitalSignsByPatient } from '@/api/inpatient/vitalsign'
const props = defineProps({
patientId: { type: String, required: true }
})
const chartRef = ref(null)
let chartInstance = null
const tableData = ref([])
const rawData = ref([])
const fetchData = async () => {
try {
const res = await getVitalSignsByPatient(props.patientId)
rawData.value = res.data || []
processChartData()
processTableData()
} catch (e) {
console.error('Failed to fetch vital signs:', e)
}
}
const processTableData = () => {
const timeSlots = ['02:00', '06:00', '10:00', '14:00', '18:00', '22:00']
const grouped = {}
rawData.value.forEach(item => {
const key = `${item.recordDate} ${item.recordTime}`
grouped[key] = item
})
tableData.value = timeSlots.map(slot => {
const date = rawData.value[0]?.recordDate || new Date().toISOString().split('T')[0]
const fullKey = `${date} ${slot}`
const item = grouped[fullKey] || {}
return {
timeKey: `${date}-${slot.replace(':', '')}`,
timeLabel: `${date.slice(5)} ${slot.slice(0, 2)}`,
temp: item.temperature,
pulse: item.pulse,
hr: item.heartRate
}
})
}
const processChartData = () => {
if (!chartInstance) return
const dates = [...new Set(rawData.value.map(d => d.recordDate))].sort()
const xAxisData = []
const tempData = []
const pulseData = []
const hrData = []
dates.forEach(date => {
['02:00', '06:00', '10:00', '14:00', '18:00', '22:00'].forEach(time => {
xAxisData.push(`${date.slice(5)} ${time.slice(0, 2)}`)
const record = rawData.value.find(r => r.recordDate === date && r.recordTime === time)
tempData.push(record ? record.temperature : null)
pulseData.push(record ? record.pulse : null)
hrData.push(record ? record.heartRate : null)
})
})
const option = {
tooltip: { trigger: 'axis' },
grid: { top: 40, bottom: 40, left: 50, right: 30 },
xAxis: { type: 'category', data: xAxisData, axisLabel: { rotate: 30 } },
yAxis: [
{ type: 'value', name: '体温(℃)', min: 35, max: 42, splitNumber: 7 },
{ type: 'value', name: '脉搏/心率', min: 0, max: 180, splitNumber: 9, position: 'right' }
],
series: [
{
name: '体温',
type: 'line',
yAxisIndex: 0,
data: tempData,
symbol: 'x',
symbolSize: 8,
itemStyle: { color: '#1890ff' },
lineStyle: { color: '#1890ff', width: 2 },
connectNulls: false
},
{
name: '脉搏',
type: 'line',
yAxisIndex: 1,
data: pulseData,
symbol: 'circle',
symbolSize: 8,
itemStyle: { color: '#ff4d4f' },
lineStyle: { color: '#ff4d4f', width: 2 },
connectNulls: false
},
{
name: '心率',
type: 'line',
yAxisIndex: 1,
data: hrData,
symbol: 'emptyCircle',
symbolSize: 8,
itemStyle: { color: '#ff4d4f', borderColor: '#ff4d4f', borderWidth: 2 },
lineStyle: { color: '#ff4d4f', width: 2 },
connectNulls: false
}
]
}
chartInstance.setOption(option, true)
}
const initChart = () => {
if (chartRef.value) {
chartInstance = echarts.init(chartRef.value)
window.addEventListener('resize', chartInstance.resize)
}
}
onMounted(() => {
initChart()
fetchData()
})
onUnmounted(() => {
window.removeEventListener('resize', chartInstance?.resize)
chartInstance?.dispose()
})
defineExpose({ refresh: fetchData })
</script>
<style scoped>
.temperature-chart-container { display: flex; flex-direction: column; gap: 16px; }
.chart-wrapper { height: 400px; width: 100%; }
.vitalsign-table { width: 100%; border-collapse: collapse; }
.vitalsign-table th, .vitalsign-table td { border: 1px solid #ddd; padding: 8px; text-align: center; }
</style>