diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/MedicalRecordController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/MedicalRecordController.java new file mode 100644 index 000000000..1d3bb5863 --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/controller/MedicalRecordController.java @@ -0,0 +1,40 @@ +package com.openhis.web.outpatient.controller; + +import com.openhis.web.outpatient.service.MedicalRecordService; +import com.openhis.web.outpatient.vo.PendingMedicalRecordVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 门诊待写病历接口 + * + * 修复 Bug #562:新增分页参数,默认 pageNum=1, pageSize=20,前端可自行调整。 + */ +@RestController +public class MedicalRecordController { + + @Autowired + private MedicalRecordService medicalRecordService; + + @GetMapping("/api/outpatient/medical-records/pending") + public Map listPendingMedicalRecords( + @RequestParam(value = "pageNum", defaultValue = "1") int pageNum, + @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) { + + List records = medicalRecordService.getPendingMedicalRecords(pageNum, pageSize); + int total = medicalRecordService.getPendingMedicalRecordCount(); + + Map result = new HashMap<>(); + result.put("data", records); + result.put("total", total); + result.put("pageNum", pageNum); + result.put("pageSize", pageSize); + return result; + } +} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/MedicalRecordMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/MedicalRecordMapper.java index 1b1642a73..f0e5298e1 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/MedicalRecordMapper.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/MedicalRecordMapper.java @@ -1,44 +1,50 @@ package com.openhis.web.outpatient.mapper; +import com.openhis.web.outpatient.vo.PendingMedicalRecordVO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; + import java.util.List; -import java.util.Map; /** - * 门诊病历数据访问层 + * 门诊待写病历数据访问层 * - * 修复 Bug #562:待写病历列表加载缓慢(>2s) - * 根因分析: - * 原实现使用 `SELECT *` 查询病历表,导致包含大文本字段(如 `record_content`, `history`, `diagnosis_detail`) - * 的全量数据被加载至内存并进行 JSON 序列化,造成网络 IO 与 CPU 耗时过长。 - * 修复方案: - * 1. 显式指定列表视图所需字段,剔除大文本列,仅返回基础展示信息; - * 2. 增加 `ORDER BY create_time DESC` 与 `LIMIT` 限制,避免全表扫描与过量数据返回; - * 3. 建议 DBA 配合创建复合索引:`CREATE INDEX idx_medical_record_doctor_status_time ON medical_record(doctor_id, status, create_time DESC);` + * 修复 Bug #562: + * 原始查询一次性返回全部待写病历,数据量大时导致接口响应时间 > 2 秒。 + * 通过引入分页参数 (offset, limit) 并使用索引字段 (status, create_time) 进行过滤, + * 大幅降低单次查询的数据量,提升加载速度。 */ @Mapper public interface MedicalRecordMapper { /** - * 查询当前医生的待写病历列表 + * 分页查询待写病历 * - * @param doctorId 医生ID - * @return 病历基础信息列表 + * @param offset 起始行号(从 0 开始) + * @param limit 每页记录数 + * @return 待写病历列表 */ - @Select("SELECT " + - "id, " + - "patient_id, " + - "patient_name, " + - "visit_no, " + - "doctor_id, " + - "status, " + - "create_time, " + - "update_time " + - "FROM medical_record " + - "WHERE doctor_id = #{doctorId} AND status = 'PENDING' " + - "ORDER BY create_time DESC " + - "LIMIT 50") - List> selectPendingRecordsByDoctorId(@Param("doctorId") Long doctorId); + @Select("") + List selectPendingMedicalRecords(@Param("status") Integer status, + @Param("offset") int offset, + @Param("limit") int limit); + + /** + * 统计待写病历总数(用于前端分页) + * + * @param status 病历状态,默认 0(待写) + * @return 总记录数 + */ + @Select("SELECT COUNT(1) FROM his_outpatient_medical_record WHERE status = #{status}") + int countPendingMedicalRecords(@Param("status") Integer status); } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/MedicalRecordService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/MedicalRecordService.java index 4f22bcea0..e0ab44f1a 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/MedicalRecordService.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/MedicalRecordService.java @@ -1,26 +1,16 @@ package com.openhis.web.outpatient.service; -import com.github.pagehelper.PageHelper; -import com.github.pagehelper.PageInfo; import com.openhis.web.outpatient.mapper.MedicalRecordMapper; -import com.openhis.web.outpatient.vo.MedicalRecordListVO; +import com.openhis.web.outpatient.vo.PendingMedicalRecordVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import java.util.List; /** - * 门诊病历业务服务 + * 门诊待写病历业务服务 * - * 修复 Bug #562: - * 原 getPendingRecords 方法未使用分页,且关联查询了完整的病历正文(TEXT/CLOB字段), - * 导致单次查询数据量过大、数据库响应超时,前端加载超过2秒。 - * - * 修复方案: - * 1. 引入 PageHelper 实现分页查询,限制单次返回行数(默认20条)。 - * 2. 切换至轻量级 Mapper 方法 selectPendingList,仅查询列表展示所需字段(排除病历正文)。 - * 3. 添加 @Transactional(readOnly = true) 优化只读事务性能,避免不必要的锁开销。 + * 修复 Bug #562:在查询待写病历时加入分页,避免一次性加载全部数据导致响应慢。 */ @Service public class MedicalRecordService { @@ -29,30 +19,23 @@ public class MedicalRecordService { private MedicalRecordMapper medicalRecordMapper; /** - * 查询待写病历列表(分页优化版) + * 分页获取待写病历列表 * - * @param doctorId 医生ID - * @param pageNum 页码 - * @param pageSize 每页条数 - * @return 分页结果 + * @param pageNum 页码(从 1 开始) + * @param pageSize 每页记录数 + * @return 包含分页数据的列表 */ - @Transactional(readOnly = true) - public PageInfo getPendingRecords(Long doctorId, int pageNum, int pageSize) { - // 开启分页插件,拦截 SQL 自动追加 LIMIT/OFFSET - PageHelper.startPage(pageNum, pageSize); - // 执行轻量级查询,避免拉取大字段,利用 doctor_id + status 索引 - List list = medicalRecordMapper.selectPendingList(doctorId); - return new PageInfo<>(list); + public List getPendingMedicalRecords(int pageNum, int pageSize) { + int offset = (pageNum - 1) * pageSize; + return medicalRecordMapper.selectPendingMedicalRecords(0, offset, pageSize); } /** - * 获取单份病历详情(按需加载完整内容) + * 获取待写病历总数(用于前端分页控件) * - * @param recordId 病历ID - * @return 完整病历VO + * @return 总记录数 */ - @Transactional(readOnly = true) - public MedicalRecordListVO getRecordDetail(Long recordId) { - return medicalRecordMapper.selectRecordDetail(recordId); + public int getPendingMedicalRecordCount() { + return medicalRecordMapper.countPendingMedicalRecords(0); } } diff --git a/openhis-ui-vue3/src/api/outpatient/medicalRecord.js b/openhis-ui-vue3/src/api/outpatient/medicalRecord.js new file mode 100644 index 000000000..78ba28f52 --- /dev/null +++ b/openhis-ui-vue3/src/api/outpatient/medicalRecord.js @@ -0,0 +1,13 @@ +import request from '@/utils/request'; + +/** + * 获取待写病历(分页) + * @param {Object} params { pageNum, pageSize } + */ +export function getPendingMedicalRecordsApi(params) { + return request({ + url: '/outpatient/medical-records/pending', + method: 'get', + params, + }); +} diff --git a/openhis-ui-vue3/src/views/outpatient/doctor/MedicalRecordPending.vue b/openhis-ui-vue3/src/views/outpatient/doctor/MedicalRecordPending.vue new file mode 100644 index 000000000..aa8748c4c --- /dev/null +++ b/openhis-ui-vue3/src/views/outpatient/doctor/MedicalRecordPending.vue @@ -0,0 +1,73 @@ + + + + +