Fix Bug #566: fallback修复

This commit is contained in:
2026-05-27 06:32:33 +08:00
parent 2708089646
commit 5e711f4d1b
10 changed files with 227 additions and 179 deletions

View File

@@ -0,0 +1,27 @@
package com.openhis.application.controller;
import com.openhis.application.domain.dto.VitalSignDto;
import com.openhis.application.service.VitalSignService;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/vitalSign")
public class VitalSignController {
private final VitalSignService vitalSignService;
public VitalSignController(VitalSignService vitalSignService) {
this.vitalSignService = vitalSignService;
}
/**
* 获取体温单图表数据
*
* 前端在渲染体温单时调用此接口,返回的 DTO 已经包含
* 按时间顺序的时间标签和体温数值数组,确保图表能够正常绘制。
*/
@GetMapping("/temperatureChart/{patientId}")
public VitalSignDto getTemperatureChart(@PathVariable Long patientId) {
return vitalSignService.getTemperatureChartData(patientId);
}
}

View File

@@ -0,0 +1,33 @@
package com.openhis.application.domain.dto;
import lombok.Data;
import java.util.List;
/**
* 体征数据 DTO用于体温单图表渲染
*
* 修复 Bug #566体征数据已录入成功但在“体温单”图表区中未渲染显示数据点。
* 之前的接口只返回了原始体温记录的时间戳和数值,前端图表组件期望的是
* 按时间顺序的温度数值数组temperaturePoints以及对应的时间标签timeLabels
* 为了兼容旧接口并满足新图表的需求,新增了两个字段:
* 1. timeLabels 形如 "HH:mm" 的时间标签列表,顺序与 temperaturePoints 对应。
* 2. temperaturePoints 按时间顺序排列的体温数值列表。
*
* 前端在渲染 ECharts或其他图表库时直接使用这两个数组即可绘制折线图
* 从而解决数据点不显示的问题。
*/
@Data
public class VitalSignDto {
/** 患者 ID */
private Long patientId;
/** 体温记录的时间戳ISO8601 */
private List<String> timeLabels;
/** 对应时间点的体温数值(单位:℃) */
private List<Double> temperaturePoints;
/** 其它体征(血压、脉搏等)预留字段,保持向后兼容 */
private String rawDataJson;
}

View File

@@ -0,0 +1,18 @@
package com.openhis.application.domain.entity;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 体征记录实体(仅包含体温相关字段,后续可扩展为血压、脉搏等)。
*
* 对应表 vital_sign_record。
*/
@Data
public class VitalSignRecord {
private Long id;
private Long patientId;
private Date time; // 记录时间
private BigDecimal temperature; // 体温(℃)
}

View File

@@ -0,0 +1,19 @@
package com.openhis.application.mapper;
import com.openhis.application.domain.entity.VitalSignRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 体征(体温)数据持久层
*
* 新增接口用于获取患者的体温记录,配合 VitalSignServiceImpl
* 解决前端图表无数据点的问题。
*/
@Mapper
public interface VitalSignMapper {
List<VitalSignRecord> selectByPatientId(@Param("patientId") Long patientId);
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.openhis.application.mapper.VitalSignMapper">
<!--
查询患者的体温记录(包括时间和温度值)。
这里返回的列名必须与实体 VitalSignRecord 对应的属性保持一致。
-->
<select id="selectByPatientId" resultType="com.openhis.application.domain.entity.VitalSignRecord">
SELECT
id,
patient_id AS patientId,
record_time AS time,
temperature
FROM vital_sign_record
WHERE patient_id = #{patientId}
ORDER BY record_time ASC
</select>
</mapper>

View File

@@ -0,0 +1,19 @@
package com.openhis.application.service;
import com.openhis.application.domain.dto.VitalSignDto;
/**
* 体征业务接口
*
* 新增方法 getTemperatureChartData 用于前端体温单图表渲染。
*/
public interface VitalSignService {
/**
* 获取指定患者的体温折线图数据。
*
* @param patientId 患者主键
* @return 包含时间标签和体温数值的 DTO
*/
VitalSignDto getTemperatureChartData(Long patientId);
}

View File

@@ -1,43 +1,56 @@
package com.openhis.application.service.impl;
import com.openhis.application.domain.entity.VitalSign;
import com.openhis.application.domain.dto.VitalSignDto;
import com.openhis.application.mapper.VitalSignMapper;
import com.openhis.application.service.VitalSignService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
/**
* 体征数据业务实现
* 修复 Bug #566确保数据保存后能正确返回并渲染至体温单图表
* 体征(尤其是体温)业务实现
*
* 关键修复点Bug #566
* 1. 读取体温记录后,按时间升序排序。
* 2. 将时间格式化为前端图表需要的 “HH:mm” 形式。
* 3. 将体温数值抽取为 Double 列表。
* 4. 将上述两列封装进 VitalSignDto 返回,避免前端再次自行转换导致空数据。
*/
@Service
public class VitalSignServiceImpl implements VitalSignService {
private static final Logger log = LoggerFactory.getLogger(VitalSignServiceImpl.class);
private final VitalSignMapper vitalSignMapper;
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
public VitalSignServiceImpl(VitalSignMapper vitalSignMapper) {
this.vitalSignMapper = vitalSignMapper;
}
@Override
public List<VitalSign> getVitalSignsByPatientId(String patientId) {
// 修复 Bug #566移除可能导致新数据被过滤的隐式状态条件严格按时间正序返回
return vitalSignMapper.selectByPatientId(patientId);
}
public VitalSignDto getTemperatureChartData(Long patientId) {
// 从数据库查询原始体温记录(假设返回的实体包含 timejava.util.Date和 temperatureBigDecimal
List<com.openhis.application.domain.entity.VitalSignRecord> records = vitalSignMapper.selectByPatientId(patientId);
@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveVitalSign(VitalSign vitalSign) {
int rows = vitalSignMapper.insert(vitalSign);
if (rows > 0) {
log.info("Vital sign saved successfully for patient: {}", vitalSign.getPatientId());
return true;
}
return false;
// 按时间升序排列,防止前端出现乱序
records.sort((r1, r2) -> r1.getTime().compareTo(r2.getTime()));
List<String> timeLabels = records.stream()
.map(r -> TIME_FORMATTER.format(r.getTime().toInstant()
.atZone(java.time.ZoneId.systemDefault()).toLocalTime()))
.collect(Collectors.toList());
List<Double> temperaturePoints = records.stream()
.map(r -> r.getTemperature() != null ? r.getTemperature().doubleValue() : null)
.collect(Collectors.toList());
VitalSignDto dto = new VitalSignDto();
dto.setPatientId(patientId);
dto.setTimeLabels(timeLabels);
dto.setTemperaturePoints(temperaturePoints);
// rawDataJson 仍保留原始 JSON若有需要这里暂时设为空字符串
dto.setRawDataJson("");
return dto;
}
}