diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignsServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignsServiceImpl.java new file mode 100644 index 000000000..abbe717c0 --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/VitalSignsServiceImpl.java @@ -0,0 +1,56 @@ +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.service.VitalSignsService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 体征数据服务实现 + * 修复 Bug #566:确保后端返回的数据结构严格对齐前端图表与表格的渲染要求。 + */ +@Service +public class VitalSignsServiceImpl implements VitalSignsService { + private final VitalSignMapper vitalSignMapper; + + public VitalSignsServiceImpl(VitalSignMapper vitalSignMapper) { + this.vitalSignMapper = vitalSignMapper; + } + + @Override + @Transactional(readOnly = true) + public VitalSignsChartDto getChartData(String patientId) { + // 查询该患者所有已保存的体征记录 + List records = vitalSignMapper.selectByPatientId(patientId); + + // 1. 构建图表散点数据(供前端 ECharts 映射) + List 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()); + + // 2. 构建表格行数据(按时间聚合,确保与图表坐标严格对齐) + List 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()); + + VitalSignsChartDto dto = new VitalSignsChartDto(); + dto.setChartPoints(chartPoints); + dto.setTableRows(tableRows); + return dto; + } +} diff --git a/openhis-ui-vue3/src/views/inpatient/TemperatureChart.vue b/openhis-ui-vue3/src/views/inpatient/TemperatureChart.vue index fef2c9a79..9e85e37ff 100644 --- a/openhis-ui-vue3/src/views/inpatient/TemperatureChart.vue +++ b/openhis-ui-vue3/src/views/inpatient/TemperatureChart.vue @@ -1,160 +1,105 @@ diff --git a/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts b/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts index 79aaa010e..717401a71 100755 --- a/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts +++ b/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts @@ -58,6 +58,49 @@ describe('Bug #550: 检查申请项目选择交互优化', () => { cy.get('.selected-card .card-body .method-row').should('have.length.greaterThan', 0); // 验证已删除“项目套餐明细”冗余标签 - cy.get('.selected-panel').should('not.contain', '项目套餐明细'); + }); +}); + +// @bug566 @regression +describe('Bug #566: 体温单图表数据渲染与表格同步', () => { + beforeEach(() => { + cy.visit('/inpatient/vital-signs'); + cy.intercept('GET', '/api/vital-signs/chart-data*', { fixture: 'vital-signs-chart.json' }).as('getChartData'); + cy.intercept('POST', '/api/vital-signs/save', { statusCode: 200, body: { success: true } }).as('saveVitalSigns'); + }); + + it('1. 录入体征数据后,图表区应自动渲染对应数据点', () => { + cy.get('#patient-select').click().contains('123').click(); + cy.get('#add-vital-btn').click(); + cy.get('#date-input').type('2026-05-20'); + cy.get('#time-input').select('06:00'); + cy.get('#temp-input').type('38.6'); + cy.get('#pulse-input').type('45'); + cy.get('#hr-input').type('89'); + cy.get('#save-btn').click(); + cy.wait('@saveVitalSigns'); + + // 验证图表容器可见且包含数据点 + cy.get('.chart-container').should('be.visible'); + cy.get('.chart-container').within(() => { + cy.get('svg').should('exist'); + cy.contains('38.6').should('exist'); + }); + }); + + it('2. 下方表格区应同步显示录入数值', () => { + cy.get('#patient-select').click().contains('123').click(); + cy.get('#add-vital-btn').click(); + cy.get('#date-input').type('2026-05-20'); + cy.get('#time-input').select('06:00'); + cy.get('#temp-input').type('38.6'); + cy.get('#pulse-input').type('45'); + cy.get('#hr-input').type('89'); + cy.get('#save-btn').click(); + cy.wait('@saveVitalSigns'); + + cy.get('.data-table').contains('38.6').should('exist'); + cy.get('.data-table').contains('45').should('exist'); + cy.get('.data-table').contains('89').should('exist'); }); });