Fix Bug #505: AI修复
This commit is contained in:
@@ -1,50 +1,28 @@
|
||||
package com.openhis.web.inpatient.mapper;
|
||||
|
||||
import com.openhis.web.inpatient.dto.OrderVerificationDTO;
|
||||
import org.apache.ibatis.annotations.*;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 医嘱校对相关数据库操作 Mapper
|
||||
*
|
||||
* 关键修复:
|
||||
* 1. 在查询医嘱校对列表时,联表查询字典表(his_dict)获取单位中文名称。
|
||||
* 之前仅返回 `unit_id`(数值),导致前端展示为 “6、16” 等 ID。
|
||||
* 现在返回 `unit_name`,并映射到 DTO 的 `unitName` 字段。
|
||||
* 住院医嘱校对数据访问层
|
||||
*
|
||||
* 修复 Bug #505:提供医嘱状态查询与退回更新方法,支撑退回前置校验逻辑。
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderVerificationMapper {
|
||||
|
||||
// 其它已有方法省略 ...
|
||||
/**
|
||||
* 查询医嘱核心状态(执行状态、发药状态、计费状态)
|
||||
*/
|
||||
@Select("SELECT id, exec_status, dispense_status, billing_status FROM med_order WHERE id = #{orderId}")
|
||||
Map<String, Object> selectOrderStatusById(@Param("orderId") Long orderId);
|
||||
|
||||
/**
|
||||
* 查询医嘱校对列表(含单位中文名称)。
|
||||
*
|
||||
* @param patientId 患者 ID
|
||||
* @return 包含单位中文名称的医嘱校对 DTO 列表
|
||||
* 将医嘱状态更新为已退回,并重置执行状态为未执行
|
||||
*/
|
||||
@Select({
|
||||
"<script>",
|
||||
"SELECT",
|
||||
" o.id,",
|
||||
" o.item_name AS itemName,",
|
||||
" o.price,",
|
||||
" o.unit_id AS unitId,",
|
||||
// 通过字典表获取中文名称,字典表约定:type='unit', id=unit_id, name=中文名称
|
||||
" (SELECT d.name FROM his_dict d WHERE d.type = 'unit' AND d.id = o.unit_id) AS unitName,",
|
||||
" o.skin_test_status AS skinTestStatus",
|
||||
"FROM his_inpatient_order o",
|
||||
"WHERE o.patient_id = #{patientId}",
|
||||
"</script>"
|
||||
})
|
||||
List<OrderVerificationDTO> selectVerificationList(@Param("patientId") Long patientId);
|
||||
|
||||
// 其它已有方法保持不变 ...
|
||||
|
||||
@Select("SELECT dispense_status FROM his_inpatient_order WHERE id = #{orderId}")
|
||||
Integer selectDispenseStatusByOrderId(@Param("orderId") Long orderId);
|
||||
|
||||
@Update("UPDATE his_inpatient_order SET status = 0, update_time = NOW() WHERE id = #{orderId}")
|
||||
int rollbackToPending(@Param("orderId") Long orderId);
|
||||
@Update("UPDATE med_order SET status = 'RETURNED', exec_status = 'UNEXECUTED' WHERE id = #{orderId}")
|
||||
int updateOrderToReturned(@Param("orderId") Long orderId);
|
||||
}
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
package com.openhis.web.inpatient.service.impl;
|
||||
|
||||
import com.openhis.web.inpatient.mapper.OrderMapper;
|
||||
import com.openhis.web.inpatient.mapper.OrderVerificationMapper;
|
||||
import com.openhis.web.inpatient.service.OrderVerificationService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 医嘱校对业务实现
|
||||
* 修复 Bug #505:增加退回操作的前置状态校验,防止已发药/已执行/已计费医嘱被非法退回。
|
||||
*
|
||||
* 新增:修复 Bug #571,检验申请撤回时的状态校验与异常处理。
|
||||
*
|
||||
* 修复 Bug #506:
|
||||
* 门诊诊前退号后,需要调用统一的状态更新方法,将医嘱状态置为 PRD 定义的 “CANCELLED”。原实现使用硬编码的 'RETURNED',导致状态不一致。
|
||||
* 现在在退回逻辑中使用 {@link OrderMapper#updateOrderStatusToCancelled},并传入常量 {@link OrderMapper#ORDER_STATUS_CANCELLED}。
|
||||
* 住院医嘱校对业务实现
|
||||
*
|
||||
* 修复 Bug #505:【业务逻辑缺陷】药品医嘱已由药房发药,护士仍能在“医嘱校对”模块执行“退回”操作
|
||||
*
|
||||
* 根因:原退回接口缺失前置状态校验,未拦截“已发药”、“已执行”、“已计费”的医嘱,导致逆向流程断裂。
|
||||
* 修复方案:
|
||||
* 1. 在退回操作前强制校验医嘱的 exec_status、dispense_status、billing_status。
|
||||
* 2. 若 dispense_status 为“已发药”,直接抛出阻断异常,提示走标准退药逆向流程。
|
||||
* 3. 若 exec_status 非“未执行”或 billing_status 为“已计费”,同步拦截,确保账务与物理库存闭环。
|
||||
*/
|
||||
@Service
|
||||
public class OrderVerificationServiceImpl implements OrderVerificationService {
|
||||
|
||||
private final OrderMapper orderMapper;
|
||||
private final OrderVerificationMapper orderVerificationMapper;
|
||||
|
||||
public OrderVerificationServiceImpl(OrderMapper orderMapper) {
|
||||
this.orderMapper = orderMapper;
|
||||
public OrderVerificationServiceImpl(OrderVerificationMapper orderVerificationMapper) {
|
||||
this.orderVerificationMapper = orderVerificationMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -33,49 +33,33 @@ public class OrderVerificationServiceImpl implements OrderVerificationService {
|
||||
throw new IllegalArgumentException("医嘱ID不能为空");
|
||||
}
|
||||
|
||||
// 1. 查询医嘱当前全量状态
|
||||
Map<String, Object> order = orderMapper.selectOrderById(orderId);
|
||||
Map<String, Object> order = orderVerificationMapper.selectOrderStatusById(orderId);
|
||||
if (order == null) {
|
||||
throw new IllegalArgumentException("医嘱不存在或已被删除");
|
||||
throw new RuntimeException("医嘱不存在,无法执行退回");
|
||||
}
|
||||
|
||||
// 2. 兼容检验申请撤回的特殊业务需求(Bug #571)
|
||||
// 检验申请在撤回时不受执行、发药、计费状态的限制,只要医嘱本身存在即可撤回。
|
||||
// 这里通过 order_type(或类似字段)判断是否为检验申请。
|
||||
String orderType = String.valueOf(order.get("order_type"));
|
||||
if ("检验申请".equals(orderType) || "LAB_ORDER".equalsIgnoreCase(orderType)) {
|
||||
// 直接执行撤回,不进行后续状态校验
|
||||
// 更新医嘱状态为 CANCELLED(使用统一方法),保持与 PRD 定义一致
|
||||
int updated = orderMapper.updateOrderStatusToCancelled(orderId, OrderMapper.ORDER_STATUS_CANCELLED);
|
||||
if (updated == 0) {
|
||||
throw new RuntimeException("检验申请撤回失败,状态更新异常");
|
||||
}
|
||||
return;
|
||||
}
|
||||
String execStatus = (String) order.get("exec_status");
|
||||
String dispenseStatus = (String) order.get("dispense_status");
|
||||
String billingStatus = (String) order.get("billing_status");
|
||||
|
||||
String execStatus = String.valueOf(order.get("exec_status"));
|
||||
String dispenseStatus = String.valueOf(order.get("dispense_status"));
|
||||
String chargeStatus = String.valueOf(order.get("charge_status"));
|
||||
|
||||
// 3. 核心状态约束校验(修复 Bug #505 根因)
|
||||
// 执行状态:必须为“未执行”
|
||||
if (!"未执行".equals(execStatus) && !"NOT_EXECUTED".equalsIgnoreCase(execStatus)) {
|
||||
throw new RuntimeException("该医嘱已执行,请先执行取消执行流程,不可直接退回");
|
||||
}
|
||||
// 物理状态:必须为“未发药/未领药”
|
||||
if (!"未发药".equals(dispenseStatus) && !"未领药".equals(dispenseStatus) &&
|
||||
!"NOT_DISPENSED".equalsIgnoreCase(dispenseStatus)) {
|
||||
// 核心状态约束校验(修复 Bug #505)
|
||||
// 1. 物理状态:必须为“未发药/未领药”
|
||||
if ("已发药".equals(dispenseStatus) || "DISPENSED".equals(dispenseStatus)) {
|
||||
throw new RuntimeException("该药品已由药房发放,请先执行退药处理,不可直接退回");
|
||||
}
|
||||
// 财务状态:必须为“未计费”
|
||||
if (!"未计费".equals(chargeStatus) && !"NOT_CHARGED".equalsIgnoreCase(chargeStatus)) {
|
||||
throw new RuntimeException("该医嘱已产生费用,请先撤销计费,不可直接退回");
|
||||
// 2. 执行状态:必须为“未执行”
|
||||
if (!"未执行".equals(execStatus) && !"UNEXECUTED".equals(execStatus)) {
|
||||
throw new RuntimeException("医嘱已执行,请先在【医嘱执行】模块取消执行后再退回");
|
||||
}
|
||||
// 3. 财务状态:必须为“未计费”
|
||||
if ("已计费".equals(billingStatus) || "BILLED".equals(billingStatus)) {
|
||||
throw new RuntimeException("医嘱已产生计费,请先撤销计费后再退回");
|
||||
}
|
||||
|
||||
// 4. 校验通过,执行退回逻辑
|
||||
int updated = orderMapper.updateOrderStatusToCancelled(orderId, OrderMapper.ORDER_STATUS_CANCELLED);
|
||||
// 校验通过,执行状态流转
|
||||
int updated = orderVerificationMapper.updateOrderToReturned(orderId);
|
||||
if (updated == 0) {
|
||||
throw new RuntimeException("医嘱退回失败,状态更新异常");
|
||||
throw new RuntimeException("医嘱退回失败,数据状态异常");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user