Fix Bug #566: AI修复
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
package com.openhis.application.mapper;
|
||||
|
||||
import com.openhis.application.domain.entity.VitalSignsRecord;
|
||||
import org.apache.ibatis.annotations.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 体征记录 Mapper
|
||||
* 修复 Bug #566 数据查询层:确保按时间正序返回,且仅查询有效状态数据。
|
||||
*/
|
||||
@Mapper
|
||||
public interface VitalSignsMapper {
|
||||
|
||||
@Insert("INSERT INTO hisdev.vital_signs_record " +
|
||||
"(patient_id, record_time, temperature, heart_rate, pulse, status, create_time) " +
|
||||
"VALUES (#{patientId}, #{recordTime}, #{temperature}, #{heartRate}, #{pulse}, #{status}, #{createTime})")
|
||||
@Options(useGeneratedKeys = true, keyProperty = "id")
|
||||
int insert(VitalSignsRecord record);
|
||||
|
||||
@Select("SELECT id, patient_id, record_time, temperature, heart_rate, pulse, status " +
|
||||
"FROM hisdev.vital_signs_record " +
|
||||
"WHERE patient_id = #{patientId} AND status = '1' " +
|
||||
"ORDER BY record_time ASC")
|
||||
List<VitalSignsRecord> selectByPatientId(@Param("patientId") Long patientId);
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.openhis.application.service.impl;
|
||||
|
||||
import com.openhis.application.domain.dto.VitalSignsChartDto;
|
||||
import com.openhis.application.domain.entity.VitalSignRecord;
|
||||
import com.openhis.application.mapper.VitalSignMapper;
|
||||
import com.openhis.application.domain.dto.VitalSignsDto;
|
||||
import com.openhis.application.domain.entity.VitalSignsRecord;
|
||||
import com.openhis.application.mapper.VitalSignsMapper;
|
||||
import com.openhis.application.service.VitalSignsService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -11,46 +13,59 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 体征数据服务实现
|
||||
* 修复 Bug #566:确保后端返回的数据结构严格对齐前端图表与表格的渲染要求。
|
||||
* 体征数据业务实现
|
||||
*
|
||||
* 修复 Bug #566:
|
||||
* 根因:1. 保存成功后前端未触发图表数据重载;
|
||||
* 2. 后端查询 SQL 未正确按 record_time 排序,且未过滤已删除/无效状态数据;
|
||||
* 3. 返回 DTO 字段映射缺失,导致前端 ECharts 无法识别 null 值断点。
|
||||
* 修复方案:
|
||||
* - 规范 Mapper 查询逻辑,增加 ORDER BY record_time ASC 及有效状态过滤。
|
||||
* - 完善 DTO 转换,确保缺失值显式返回 null 而非 0,触发前端 connectNulls: false 断点逻辑。
|
||||
* - 提供标准列表查询接口供前端图表/表格共用。
|
||||
*/
|
||||
@Service
|
||||
public class VitalSignsServiceImpl implements VitalSignsService {
|
||||
private final VitalSignMapper vitalSignMapper;
|
||||
|
||||
public VitalSignsServiceImpl(VitalSignMapper vitalSignMapper) {
|
||||
this.vitalSignMapper = vitalSignMapper;
|
||||
private static final Logger logger = LoggerFactory.getLogger(VitalSignsServiceImpl.class);
|
||||
private final VitalSignsMapper vitalSignsMapper;
|
||||
|
||||
public VitalSignsServiceImpl(VitalSignsMapper vitalSignsMapper) {
|
||||
this.vitalSignsMapper = vitalSignsMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public VitalSignsChartDto getChartData(String patientId) {
|
||||
// 查询该患者所有已保存的体征记录
|
||||
List<VitalSignRecord> records = vitalSignMapper.selectByPatientId(patientId);
|
||||
|
||||
// 1. 构建图表散点数据(供前端 ECharts 映射)
|
||||
List<VitalSignsChartDto.Point> chartPoints = records.stream().map(r -> {
|
||||
VitalSignsChartDto.Point p = new VitalSignsChartDto.Point();
|
||||
p.setRecordTime(r.getRecordTime());
|
||||
p.setType(r.getSignType()); // TEMP / PULSE / HR
|
||||
p.setValue(r.getValue());
|
||||
return p;
|
||||
}).collect(Collectors.toList());
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean saveRecord(VitalSignsDto dto) {
|
||||
VitalSignsRecord record = new VitalSignsRecord();
|
||||
record.setPatientId(dto.getPatientId());
|
||||
record.setRecordTime(dto.getRecordTime());
|
||||
record.setTemperature(dto.getTemperature());
|
||||
record.setHeartRate(dto.getHeartRate());
|
||||
record.setPulse(dto.getPulse());
|
||||
record.setStatus("1"); // 1: 有效
|
||||
record.setCreateTime(new java.util.Date());
|
||||
int rows = vitalSignsMapper.insert(record);
|
||||
logger.info("体征数据保存成功, patientId={}, rows={}", dto.getPatientId(), rows);
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
// 2. 构建表格行数据(按时间聚合,确保与图表坐标严格对齐)
|
||||
List<VitalSignsChartDto.TableRow> tableRows = records.stream().map(r -> {
|
||||
VitalSignsChartDto.TableRow row = new VitalSignsChartDto.TableRow();
|
||||
row.setTime(r.getRecordTime());
|
||||
// 仅填充当前记录对应的指标,其余置 null 避免错位
|
||||
if ("TEMP".equals(r.getSignType())) row.setTemp(r.getValue());
|
||||
if ("PULSE".equals(r.getSignType())) row.setPulse(r.getValue());
|
||||
if ("HR".equals(r.getSignType())) row.setHr(r.getValue());
|
||||
return row;
|
||||
}).collect(Collectors.toList());
|
||||
@Override
|
||||
public List<VitalSignsDto> listByPatient(Long patientId) {
|
||||
List<VitalSignsRecord> records = vitalSignsMapper.selectByPatientId(patientId);
|
||||
return records.stream().map(this::toDto).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
VitalSignsChartDto dto = new VitalSignsChartDto();
|
||||
dto.setChartPoints(chartPoints);
|
||||
dto.setTableRows(tableRows);
|
||||
private VitalSignsDto toDto(VitalSignsRecord record) {
|
||||
VitalSignsDto dto = new VitalSignsDto();
|
||||
dto.setId(record.getId());
|
||||
dto.setPatientId(record.getPatientId());
|
||||
// 格式化时间轴显示:MM-dd HH:mm
|
||||
dto.setRecordTime(record.getRecordTime() != null ?
|
||||
new java.text.SimpleDateFormat("MM-dd HH:mm").format(record.getRecordTime()) : null);
|
||||
dto.setTemperature(record.getTemperature());
|
||||
dto.setHeartRate(record.getHeartRate());
|
||||
dto.setPulse(record.getPulse());
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user