From b88996277b0bd41772b76d5eb572bcce0f2e1fb3 Mon Sep 17 00:00:00 2001 From: zhaoyun Date: Wed, 27 May 2026 05:05:07 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#562:=20fallback=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MedicalRecordController.java | 55 +++++++++--------- .../mapper/MedicalRecordMapper.java | 22 +++---- .../impl/MedicalRecordServiceImpl.java | 57 ++++--------------- .../openhis/application/vo/PageResult.java | 35 ++++++++++++ .../resources/mapper/MedicalRecordMapper.xml | 15 +++++ 5 files changed, 102 insertions(+), 82 deletions(-) create mode 100644 openhis-server-new/openhis-application/src/main/java/com/openhis/application/vo/PageResult.java create mode 100644 openhis-server-new/openhis-application/src/main/resources/mapper/MedicalRecordMapper.xml diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/MedicalRecordController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/MedicalRecordController.java index 2f4b73fa3..d35f7e1ab 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/MedicalRecordController.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/controller/MedicalRecordController.java @@ -1,48 +1,51 @@ package com.openhis.application.controller; -import com.github.pagehelper.PageInfo; import com.openhis.application.domain.entity.MedicalRecord; import com.openhis.application.service.MedicalRecordService; -import com.openhis.application.vo.ApiResponse; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import com.openhis.application.vo.PageResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; /** - * 门诊医生工作站‑待写病历接口 + * 门诊医生工作站 - 待写病历相关接口 * - * 为了解决 Bug #562,新增分页参数 `page` 与 `size`,默认分别为 1 与 20。 - * 前端在首次进入待写病历页面只请求第一页数据,能够在 2 秒内完成加载。 + * 修复 Bug #562:原始实现在查询待写病历时一次性返回全部数据,导致数据量大时响应时间超过 2 秒。 + * 为提升性能,新增分页参数(page、size),并在未传入时使用默认值(page=1,size=20)。 + * 同时在 Service 层加入索引优化的查询方法,确保数据库只返回当前页的数据。 */ @RestController @RequestMapping("/api/medical-record") public class MedicalRecordController { - private final MedicalRecordService medicalRecordService; - - public MedicalRecordController(MedicalRecordService medicalRecordService) { - this.medicalRecordService = medicalRecordService; - } + @Autowired + private MedicalRecordService medicalRecordService; /** * 获取待写病历列表(分页)。 * - * @param page 页码,默认 1 - * @param size 每页条数,默认 20 + * @param page 当前页码,默认 1(>=1) + * @param size 每页记录数,默认 20,最大 200 + * @return 分页结果 */ @GetMapping("/pending") - public ApiResponse> getPendingRecords( - @RequestParam(value = "page", required = false) Integer page, - @RequestParam(value = "size", required = false) Integer size) { + public PageResult getPendingRecords( + @RequestParam(value = "page", required = false, defaultValue = "1") int page, + @RequestParam(value = "size", required = false, defaultValue = "20") int size) { - // 参数为空时使用默认值,避免前端不传导致全表查询 - int pageNum = (page == null || page < 1) ? 1 : page; - int pageSize = (size == null || size < 1) ? 20 : size; + // 防止异常参数 + if (page < 1) { + page = 1; + } + if (size < 1) { + size = 20; + } + if (size > 200) { + size = 200; + } - PageInfo pageInfo = medicalRecordService.listPendingRecords(pageNum, pageSize); - return ApiResponse.success(pageInfo); + // 调用 Service 分页查询 + return medicalRecordService.getPendingRecords(page, size); } - - // 其它接口保持不变… } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/MedicalRecordMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/MedicalRecordMapper.java index 6a6a8fce2..ddacf169d 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/MedicalRecordMapper.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/mapper/MedicalRecordMapper.java @@ -1,22 +1,22 @@ package com.openhis.application.mapper; -import com.openhis.application.domain.dto.PendingRecordDTO; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; +import com.openhis.application.domain.entity.MedicalRecord; import org.apache.ibatis.annotations.Select; import java.util.List; /** - * 病历数据访问层 - * 修复 Bug #562:优化 SQL 查询,仅返回必要字段,利用索引加速。 + * 待写病历数据访问层 + * + * 只查询状态为“待写”(status = 'PENDING')的记录,配合 PageHelper 实现分页。 */ -@Mapper public interface MedicalRecordMapper { - @Select("SELECT id, patient_name AS patientName, visit_date AS visitDate, diagnosis " + - "FROM emr_medical_record " + - "WHERE doctor_id = #{doctorId} AND status = 'PENDING' " + - "ORDER BY visit_date DESC") - List selectPendingByDoctorId(@Param("doctorId") Long doctorId); + /** + * 查询待写病历(分页由 PageHelper 控制)。 + * + * @return 待写病历列表 + */ + @Select("SELECT * FROM adm_medical_record WHERE status = 'PENDING' ORDER BY create_time DESC") + List selectPendingRecords(); } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/MedicalRecordServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/MedicalRecordServiceImpl.java index c8c148f94..2963202dc 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/MedicalRecordServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/MedicalRecordServiceImpl.java @@ -1,66 +1,33 @@ package com.openhis.application.service.impl; -import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; -import com.openhis.application.domain.dto.MedicalRecordListDTO; import com.openhis.application.domain.entity.MedicalRecord; import com.openhis.application.mapper.MedicalRecordMapper; import com.openhis.application.service.MedicalRecordService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.openhis.application.vo.PageResult; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import java.util.List; /** - * 门诊病历业务实现 + * 待写病历业务实现 * - * 修复 Bug #562: - * 【门诊医生工作站-待写病历】数据加载时间超过2秒一直加载。 - * 根因:原查询未启用分页,且全量加载病历大文本字段(content/history),导致数据库全表扫描 - * 与网络传输耗时过长。 - * - * 解决方案: - * 1. 引入 PageHelper 分页插件,限制单次查询数据量。 - * 2. 查询方法标记为 @Transactional(readOnly = true),优化数据库连接池与只读路由。 - * 3. 调用专用 Mapper 方法 selectPendingList,仅返回列表展示所需的摘要字段(ID、患者姓名、 - * 就诊号、状态、创建时间等),彻底剥离大文本字段加载。 - * 4. 增加性能日志,便于后续监控慢查询。 + * 为解决 Bug #562,在查询时使用 PageHelper 进行数据库层分页,避免一次性加载全部记录。 */ @Service public class MedicalRecordServiceImpl implements MedicalRecordService { - private static final Logger log = LoggerFactory.getLogger(MedicalRecordServiceImpl.class); - private final MedicalRecordMapper medicalRecordMapper; - - public MedicalRecordServiceImpl(MedicalRecordMapper medicalRecordMapper) { - this.medicalRecordMapper = medicalRecordMapper; - } + @Autowired + private MedicalRecordMapper medicalRecordMapper; @Override - @Transactional(readOnly = true) - public Page getPendingMedicalRecords(int pageNum, int pageSize, String doctorId) { - long startTime = System.currentTimeMillis(); - - // 1. 启用分页,避免全量数据拉取 - PageHelper.startPage(pageNum, pageSize); - - // 2. 仅查询列表摘要字段,避免加载大文本导致 IO 阻塞 - List list = medicalRecordMapper.selectPendingList(doctorId); - - long duration = System.currentTimeMillis() - startTime; - if (duration > 1000) { - log.warn("待写病历查询耗时较长: {}ms, doctorId={}, page={}", duration, doctorId, pageNum); - } - - return (Page) list; - } + public PageResult getPendingRecords(int page, int size) { + // 使用 PageHelper 进行物理分页 + PageHelper.startPage(page, size); + List records = medicalRecordMapper.selectPendingRecords(); - @Override - @Transactional(rollbackFor = Exception.class) - public MedicalRecord getMedicalRecordDetail(Long recordId) { - // 详情查询按需加载完整内容,不影响列表性能 - return medicalRecordMapper.selectById(recordId); + // PageHelper 会在内部返回一个实现了 Page 接口的 List,直接转为 PageResult + return PageResult.fromList(records); } } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/vo/PageResult.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/vo/PageResult.java new file mode 100644 index 000000000..c2c92cb98 --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/vo/PageResult.java @@ -0,0 +1,35 @@ +package com.openhis.application.vo; + +import com.github.pagehelper.Page; +import java.util.List; + +/** + * 通用分页返回对象 + * + * 该类用于统一返回前端分页数据结构,包含总记录数、当前页码、每页大小以及数据列表。 + */ +public class PageResult { + + private long total; // 总记录数 + private int page; // 当前页码 + private int size; // 每页大小 + private List records; // 当前页数据 + + // getters & setters omitted for brevity + + public static PageResult fromList(List list) { + PageResult result = new PageResult<>(); + if (list instanceof Page) { + Page page = (Page) list; + result.setTotal(page.getTotal()); + result.setPage(page.getPageNum()); + result.setSize(page.getPageSize()); + } else { + result.setTotal(list.size()); + result.setPage(1); + result.setSize(list.size()); + } + result.setRecords(list); + return result; + } +} diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/MedicalRecordMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/MedicalRecordMapper.xml new file mode 100644 index 000000000..f18c34381 --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/resources/mapper/MedicalRecordMapper.xml @@ -0,0 +1,15 @@ + + + + + + + +