Fix Bug #571: fallback修复

This commit is contained in:
2026-05-27 01:45:57 +08:00
parent e901703998
commit 6b6c286671
3 changed files with 142 additions and 0 deletions

View File

@@ -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<String, Object> 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<Map<String, Object>> 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);
}

View File

@@ -0,0 +1,25 @@
package com.openhis.web.inpatient.service;
import java.util.List;
import java.util.Map;
/**
* 住院检验申请业务接口
*
* 新增 withdrawLabApply 方法用于撤回检验申请。
*/
public interface InpatientLabService {
List<Map<String, Object>> listLabApplies(Long patientId);
void submitLabApply(Long patientId, Long examItemId, String operator);
/**
* 撤回检验申请
*
* @param applyId 检验申请主键
* @param operator 操作人姓名
* @throws IllegalStateException 当检验已进入不可撤回状态时抛出
*/
void withdrawLabApply(Long applyId, String operator);
}

View File

@@ -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<Map<String, Object>> listLabApplies(Long patientId) {
return labMapper.selectLabAppliesByPatientId(patientId);
}
@Override
public void submitLabApply(Long patientId, Long examItemId, String operator) {
labMapper.insertLabApply(patientId, examItemId, operator);
}
}