Fix Bug #480: [住院护士站-医嘱执行] 非耗材类医嘱执行报"耗材库存"错误且全选逻辑联动异常

根因分析:
1. 耗材库存报错:lotNumberMatch() 按 encounterId 查询 ALL 待发放 DeviceDispense,
   不区分是否为本次执行的医嘱。若该就诊存在其他未执行的耗材记录且库存为零,
   整个调用就会失败,导致非耗材类医嘱执行也被拦截。
2. 全选联动异常:toggleRowSelection() 程序化选中会触发 @select 事件,
   handleRowSelect 中调用 selectAllCheckboxesInRow 导致级联全选。

修复方案:
- 后端:lotNumberMatch 新增 requestIdList 可选参数,当传入时通过 DeviceRequest.basedOnId
  过滤仅校验与本次执行医嘱关联的耗材记录,避免其他未执行医嘱干扰
- 前端:handleExecute 传入 selectedRequestIds(仅诊疗类医嘱的 requestId)
- 前端:新增 skipSelectCascade 标志,程序化 toggleRowSelection 时阻止 handleRowSelect
  触发 selectAllCheckboxesInRow,消除级联反馈环

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
关羽
2026-05-14 22:21:16 +08:00
committed by 荀彧
parent f41b86a143
commit 1124b1010d
4 changed files with 54 additions and 11 deletions

View File

@@ -200,9 +200,10 @@ public interface ICommonService {
* 批号匹配
*
* @param encounterIdList 就诊id列表
* @param requestIdList 医嘱请求id列表可选用于限定仅校验与当前执行医嘱关联的耗材
* @return 处理结果
*/
R<?> lotNumberMatch(List<Long> encounterIdList);
R<?> lotNumberMatch(List<Long> encounterIdList, List<Long> requestIdList);
/**
* 根据机构ID获取机构名称

View File

@@ -39,8 +39,10 @@ import com.openhis.web.common.dto.*;
import com.openhis.web.common.mapper.CommonAppMapper;
import com.openhis.web.pharmacymanage.dto.InventoryDetailDto;
import com.openhis.workflow.domain.DeviceDispense;
import com.openhis.workflow.domain.DeviceRequest;
import com.openhis.workflow.domain.InventoryItem;
import com.openhis.workflow.service.IDeviceDispenseService;
import com.openhis.workflow.service.IDeviceRequestService;
import com.openhis.workflow.service.IInventoryItemService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -99,6 +101,9 @@ public class CommonServiceImpl implements ICommonService {
@Resource
private IDeviceDispenseService deviceDispenseService;
@Resource
private IDeviceRequestService deviceRequestService;
/**
* 获取药房列表
*
@@ -678,10 +683,11 @@ public class CommonServiceImpl implements ICommonService {
* 批号匹配
*
* @param encounterIdList 就诊id列表
* @param requestIdList 医嘱请求id列表可选用于限定仅校验与当前执行医嘱关联的耗材
* @return 处理结果
*/
@Override
public R<?> lotNumberMatch(List<Long> encounterIdList) {
public R<?> lotNumberMatch(List<Long> encounterIdList, List<Long> requestIdList) {
// 查询患者待发放的药品信息
List<MedicationDispense> medicationDispenseList = medicationDispenseService
.list(new LambdaQueryWrapper<MedicationDispense>().in(MedicationDispense::getEncounterId, encounterIdList)
@@ -798,10 +804,27 @@ public class CommonServiceImpl implements ICommonService {
}
}
// 查询患者待发放的耗材信息
List<DeviceDispense> deviceDispenseList = deviceDispenseService
.list(new LambdaQueryWrapper<DeviceDispense>().in(DeviceDispense::getEncounterId, encounterIdList)
.eq(DeviceDispense::getStatusEnum, DispenseStatus.PREPARATION.getValue())
.eq(DeviceDispense::getDeleteFlag, DelFlag.NO.getCode()));
LambdaQueryWrapper<DeviceDispense> deviceDispenseQuery = new LambdaQueryWrapper<DeviceDispense>()
.in(DeviceDispense::getEncounterId, encounterIdList)
.eq(DeviceDispense::getStatusEnum, DispenseStatus.PREPARATION.getValue())
.eq(DeviceDispense::getDeleteFlag, DelFlag.NO.getCode());
// 若传入requestIdList则仅查询与指定医嘱请求关联的耗材避免其他未执行医嘱的耗材记录干扰
if (requestIdList != null && !requestIdList.isEmpty()) {
List<Long> deviceReqIds = deviceRequestService
.list(new LambdaQueryWrapper<DeviceRequest>()
.in(DeviceRequest::getBasedOnId, requestIdList)
.eq(DeviceRequest::getBasedOnTable, CommonConstants.TableName.WOR_SERVICE_REQUEST))
.stream()
.map(DeviceRequest::getId)
.collect(java.util.stream.Collectors.toList());
if (!deviceReqIds.isEmpty()) {
deviceDispenseQuery.in(DeviceDispense::getDeviceReqId, deviceReqIds);
} else {
// 无关联的耗材请求,直接跳过耗材校验
deviceDispenseQuery.eq(DeviceDispense::getId, -1L);
}
}
List<DeviceDispense> deviceDispenseList = deviceDispenseService.list(deviceDispenseQuery);
// 耗材批号匹配
if (deviceDispenseList != null && !deviceDispenseList.isEmpty()) {
// 获取待发放的耗材id

View File

@@ -274,10 +274,13 @@ public class CommonAppController {
* 批号匹配
*
* @param encounterIdList 就诊id列表
* @param requestIdList 医嘱请求id列表可选用于限定仅校验与当前执行医嘱关联的耗材
* @return 处理结果
*/
@GetMapping("/lot-number-match")
public R<?> lotNumberMatch(@RequestParam(value = "encounterIdList") List<Long> encounterIdList) {
return commonService.lotNumberMatch(encounterIdList);
public R<?> lotNumberMatch(
@RequestParam(value = "encounterIdList") List<Long> encounterIdList,
@RequestParam(value = "requestIdList", required = false) List<Long> requestIdList) {
return commonService.lotNumberMatch(encounterIdList, requestIdList);
}
}