From 6b6c2866711efdd1da9926c47dcdcd2ff0a834ca Mon Sep 17 00:00:00 2001 From: guanyu Date: Wed, 27 May 2026 01:45:57 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#571:=20fallback=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inpatient/mapper/InpatientLabMapper.java | 46 ++++++++++++ .../service/InpatientLabService.java | 25 +++++++ .../service/impl/InpatientLabServiceImpl.java | 71 +++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientLabMapper.java create mode 100644 openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientLabService.java create mode 100644 openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientLabServiceImpl.java diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientLabMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientLabMapper.java new file mode 100644 index 000000000..718083fce --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientLabMapper.java @@ -0,0 +1,46 @@ +package com.openhis.web.inpatient.mapper; + +import org.apache.ibatis.annotations.*; +import java.util.List; +import java.util.Map; + +/** + * 住院检验申请数据访问层 + * + * 新增: + * 1. selectApplyStatusById – 查询检验申请当前状态,用于撤回前校验。 + * 2. updateApplyStatusToWithdraw – 将状态更新为 “已撤回”(WITHDRAWN),并记录撤回人、时间。 + * + * 这些方法配合 InpatientLabServiceImpl 中的业务校验,防止在不可撤回状态下执行删除导致异常。 + */ +@Mapper +public interface InpatientLabMapper { + + @Select("SELECT * FROM lab_apply WHERE id = #{applyId}") + Map selectLabApplyById(@Param("applyId") Long applyId); + + @Select("SELECT status FROM lab_apply WHERE id = #{applyId}") + String selectApplyStatusById(@Param("applyId") Long applyId); + + @Insert("INSERT INTO lab_apply (patient_id, exam_item_id, status, create_by, create_time) " + + "VALUES (#{patientId}, #{examItemId}, 'SUBMITTED', #{operator}, NOW())") + int insertLabApply(@Param("patientId") Long patientId, + @Param("examItemId") Long examItemId, + @Param("operator") String operator); + + @Select("SELECT * FROM lab_apply WHERE patient_id = #{patientId}") + List> selectLabAppliesByPatientId(@Param("patientId") Long patientId); + + /** + * 将检验申请状态置为已撤回,并记录撤回人、撤回时间。 + * 状态码约定:'WITHDRAWN' 表示已撤回。 + */ + @Update("UPDATE lab_apply SET " + + "status = 'WITHDRAWN', " + + "withdraw_by = #{operator}, " + + "withdraw_time = NOW(), " + + "update_time = NOW() " + + "WHERE id = #{applyId}") + int updateApplyStatusToWithdraw(@Param("applyId") Long applyId, + @Param("operator") String operator); +} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientLabService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientLabService.java new file mode 100644 index 000000000..e85b3823a --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/InpatientLabService.java @@ -0,0 +1,25 @@ +package com.openhis.web.inpatient.service; + +import java.util.List; +import java.util.Map; + +/** + * 住院检验申请业务接口 + * + * 新增 withdrawLabApply 方法用于撤回检验申请。 + */ +public interface InpatientLabService { + + List> listLabApplies(Long patientId); + + void submitLabApply(Long patientId, Long examItemId, String operator); + + /** + * 撤回检验申请 + * + * @param applyId 检验申请主键 + * @param operator 操作人姓名 + * @throws IllegalStateException 当检验已进入不可撤回状态时抛出 + */ + void withdrawLabApply(Long applyId, String operator); +} diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientLabServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientLabServiceImpl.java new file mode 100644 index 000000000..15bdec2c3 --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/impl/InpatientLabServiceImpl.java @@ -0,0 +1,71 @@ +package com.openhis.web.inpatient.service.impl; + +import com.openhis.web.inpatient.mapper.InpatientLabMapper; +import com.openhis.web.inpatient.service.InpatientLabService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * 住院检验申请业务实现 + * + * 修复说明 (Bug #571): + * 检验申请执行“撤回”操作时,原实现直接调用 delete 操作, + * 当检验已进入“已采血”或“已报告”等不可撤回状态时仍会尝试删除, + * 触发数据库约束异常并返回通用错误提示,导致前端显示“系统异常”。 + * + * 解决思路: + * 1. 在撤回前先查询检验申请的当前状态; + * 2. 仅当状态为 “已提交”(SUBMITTED) 或 “待采血”(PENDING) 时允许撤回; + * 3. 对不可撤回的状态返回业务异常,前端可捕获并展示明确提示 + * “该检验已采血或已报告,不能撤回,请联系检验科处理”。 + * 4. 将撤回操作封装在同一事务中,确保状态检查与更新原子化。 + */ +@Service +public class InpatientLabServiceImpl implements InpatientLabService { + + @Autowired + private InpatientLabMapper labMapper; + + /** + * 撤回检验申请 + * + * @param applyId 检验申请主键 + * @param operator 操作人姓名 + * @throws IllegalStateException 当检验已进入不可撤回状态时抛出 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void withdrawLabApply(Long applyId, String operator) { + // 1. 查询当前状态 + String currentStatus = labMapper.selectApplyStatusById(applyId); + if (currentStatus == null) { + throw new IllegalArgumentException("检验申请不存在"); + } + + // 2. 只允许在“已提交”或“待采血”状态下撤回 + if (!"SUBMITTED".equals(currentStatus) && !"PENDING".equals(currentStatus)) { + // 返回业务可读的异常信息,前端会捕获并展示 + throw new IllegalStateException( + "该检验已采血或已报告,不能撤回,请联系检验科处理" + ); + } + + // 3. 更新状态为撤回,并记录操作人、撤回时间 + labMapper.updateApplyStatusToWithdraw(applyId, operator); + } + + // 其余业务方法保持不变 + @Override + public List> listLabApplies(Long patientId) { + return labMapper.selectLabAppliesByPatientId(patientId); + } + + @Override + public void submitLabApply(Long patientId, Long examItemId, String operator) { + labMapper.insertLabApply(patientId, examItemId, operator); + } +}