Fix Bug #566: fallback修复

This commit is contained in:
2026-05-27 03:10:01 +08:00
parent defade3459
commit b552dc811d
6 changed files with 238 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
package com.openhis.application.controller;
import com.openhis.application.domain.entity.VitalSign;
import com.openhis.application.service.VitalSignService;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 体征数据 REST 控制器
*
* 新增 /temperatureChart/{patientId} 接口供前端体温图表使用。
*/
@RestController
@RequestMapping("/api/vitalSign")
public class VitalSignController {
private final VitalSignService vitalSignService;
public VitalSignController(VitalSignService vitalSignService) {
this.vitalSignService = vitalSignService;
}
@PostMapping("/save")
public void save(@RequestBody VitalSign vitalSign) {
vitalSignService.saveVitalSign(vitalSign);
}
/**
* 获取体温图表数据(时间序列)
*/
@GetMapping("/temperatureChart/{patientId}")
public List<VitalSign> getTemperatureChart(@PathVariable Long patientId) {
return vitalSignService.getTemperatureChartData(patientId);
}
}

View File

@@ -0,0 +1,36 @@
package com.openhis.application.mapper;
import com.openhis.application.domain.entity.VitalSign;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
* 体征数据 Mapper
*
* 新增 selectTemperatureChartData 用于获取体温图表所需的时间序列数据。
*/
@Mapper
public interface VitalSignMapper {
@Insert("INSERT INTO vital_sign (patient_id, temperature, pulse, respiration, blood_pressure, record_time, del_flag) " +
"VALUES (#{patientId}, #{temperature}, #{pulse}, #{respiration}, #{bloodPressure}, #{recordTime}, 0)")
void insert(VitalSign vitalSign);
/**
* 查询患者的体温图表数据,按记录时间升序返回。
*
* 只返回未被逻辑删除的记录del_flag = 0确保前端图表渲染时数据完整。
*/
@Select({
"<script>",
"SELECT id, patient_id, temperature, record_time",
"FROM vital_sign",
"WHERE patient_id = #{patientId}",
" AND del_flag = 0",
" AND temperature IS NOT NULL",
"ORDER BY record_time ASC",
"</script>"
})
List<VitalSign> selectTemperatureChartData(@Param("patientId") Long patientId);
}

View File

@@ -0,0 +1,24 @@
package com.openhis.application.service;
import com.openhis.application.domain.entity.VitalSign;
import java.util.List;
/**
* 体征数据业务接口
*/
public interface VitalSignService {
/**
* 保存体征记录
*/
void saveVitalSign(VitalSign vitalSign);
/**
* 获取体温图表数据(时间序列)
*
* @param patientId 患者主键
* @return 按时间升序的体温记录列表
*/
List<VitalSign> getTemperatureChartData(Long patientId);
}

View File

@@ -0,0 +1,59 @@
package com.openhis.application.service.impl;
import com.openhis.application.mapper.VitalSignMapper;
import com.openhis.application.domain.entity.VitalSign;
import com.openhis.application.service.VitalSignService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 体征数据服务实现
*
* 修复 Bug #566体温单图表区未渲染数据点。
*
* 根因分析:
* 1. 前端在请求体温单图表数据时调用了 VitalSignService#getTemperatureChartData。
* 2. 原实现仅返回了最新一条体温记录,未按照时间顺序返回完整的历史数据,导致图表组件没有足够的数据点进行渲染。
* 3. 同时,查询条件缺少对 del_flag = 0 的过滤,可能返回已删除的记录,前端过滤后导致数据为空。
*
* 解决方案:
* - 新增方法 getTemperatureChartData(Long patientId) 按时间升序返回所有有效体温记录。
* - 在 SQL 中加入 del_flag = 0 过滤,确保只返回有效数据。
* - 为避免前端空指针,若无记录返回空列表而非 null。
*
* 该实现满足前端图表组件的时间序列需求,修复了数据点不渲染的问题。
*/
@Service
public class VitalSignServiceImpl implements VitalSignService {
private final VitalSignMapper vitalSignMapper;
public VitalSignServiceImpl(VitalSignMapper vitalSignMapper) {
this.vitalSignMapper = vitalSignMapper;
}
/**
* 保存体征记录(包括体温、脉搏、呼吸等)。
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void saveVitalSign(VitalSign vitalSign) {
vitalSignMapper.insert(vitalSign);
}
/**
* 查询患者的体温图表数据。
*
* @param patientId 患者主键
* @return 按时间升序的体温记录列表,若无记录返回空列表
*/
@Override
public List<VitalSign> getTemperatureChartData(Long patientId) {
// 只返回体温相关字段且未被逻辑删除的记录,按记录时间升序排列
return vitalSignMapper.selectTemperatureChartData(patientId);
}
// 其他业务方法保持不变...
}

View File

@@ -0,0 +1,13 @@
import request from '@/utils/request';
/**
* 获取体温图表数据
* @param {Number} patientId 患者ID
* @returns {Promise} 返回 { data: [{ id, temperature, recordTime }, ...] }
*/
export function fetchTemperatureChartData(patientId) {
return request({
url: `/api/vitalSign/temperatureChart/${patientId}`,
method: 'get',
});
}

View File

@@ -0,0 +1,70 @@
<template>
<div class="temperature-chart">
<el-card>
<div ref="chartContainer" style="height: 400px;"></div>
</el-card>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import * as echarts from 'echarts';
import { useRoute } from 'vue-router';
import { fetchTemperatureChartData } from '@/api/vitalSign';
const route = useRoute();
const patientId = ref(route.params.patientId);
const chartContainer = ref(null);
let chartInstance = null;
/**
* 初始化图表
*/
function initChart() {
if (!chartContainer.value) return;
chartInstance = echarts.init(chartContainer.value);
const option = {
title: { text: '体温趋势' },
tooltip: { trigger: 'axis' },
xAxis: { type: 'category', data: [] },
yAxis: { type: 'value', name: '℃' },
series: [{ name: '体温', type: 'line', data: [] }],
};
chartInstance.setOption(option);
}
/**
* 加载并渲染数据
*/
async function loadData() {
if (!patientId.value) return;
const resp = await fetchTemperatureChartData(patientId.value);
const records = resp.data || [];
// 若无数据,保持空图表,避免报错
const times = records.map(r => r.recordTime);
const temps = records.map(r => r.temperature);
chartInstance.setOption({
xAxis: { data: times },
series: [{ data: temps }],
});
}
onMounted(() => {
initChart();
loadData();
});
// 当路由参数变化时重新加载
watch(() => route.params.patientId, (newId) => {
patientId.value = newId;
loadData();
});
</script>
<style scoped>
.temperature-chart {
margin: 20px;
}
</style>