fixbug326,329,334,368: 门诊医生站检验申请模块多项缺陷修复

Bug #326: 检验申请单套餐项目回充数据不完整
  - 后端回充时查询 LabActivityDefinition 补全套餐信
  - DTO 新增 activityId、feePackageId、isPackage、sampleType、unit 字段
  - 前端实现套餐项目树形展开,懒加载套餐明细
  Bug #329: 检验申请执行科室默认值设置错误
  - 后端移除默认执行科室逻辑,添加未匹配科室警告日志
  - 前端从 Organization 表获取执行科室,自动根据检验类型设置默认值
  Bug #334: 检验申请界面顶部操作栏占用空间过大
  - 隐藏顶部操作栏,保存/新增按钮移至卡片头部
  Bug #368: 门诊医生站待写病历标签页功能冗余
  - 屏蔽待写病历标签页(左侧导航栏已有独立菜单)
This commit is contained in:
wangjian963
2026-04-15 14:50:14 +08:00
parent 38b4ff5c92
commit 4e2097fc7b
6 changed files with 489 additions and 102 deletions

View File

@@ -11,10 +11,12 @@ import com.openhis.lab.domain.InspectionLabApply;
import com.openhis.lab.domain.InspectionLabApplyItem;
import com.openhis.lab.domain.BarCode;
import com.openhis.lab.domain.InspectionPackage;
import com.openhis.lab.domain.LabActivityDefinition;
import com.openhis.lab.service.IInspectionLabApplyItemService;
import com.openhis.lab.service.IInspectionLabApplyService;
import com.openhis.lab.service.IInspectionLabBarCodeService;
import com.openhis.lab.service.IInspectionPackageService;
import com.openhis.lab.service.ILabActivityDefinitionService;
import com.openhis.workflow.domain.ServiceRequest;
import com.openhis.workflow.service.IServiceRequestService;
import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService;
@@ -45,6 +47,9 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.function.Function;
/**
* 根据检验申请单开单信息系统自动插入门诊医嘱表(与检验申请主表申请单号进行关联),
@@ -88,6 +93,10 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
@Autowired
private IInspectionPackageService inspectionPackageService;
// Bug #326: 检验项目定义服务(用于回充时获取套餐信息)
@Autowired
private ILabActivityDefinitionService labActivityDefinitionService;
/**
* 保存检验申请单信息
* @param doctorStationLabApplyDto
@@ -160,6 +169,28 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
InspectionLabApplyItem inspectionLabApplyItem = new InspectionLabApplyItem();
BeanUtils.copyProperties(doctorStationLabApplyItemDto, inspectionLabApplyItem);
// 前端选择检验项目时已携带完整的关联信息activityId、feePackageId、itemCode等
// Bug #326修复: 只使用 activityId 直接查询,不使用名称反查
Long activityId = doctorStationLabApplyItemDto.getActivityId();
if (activityId != null) {
// 使用 activityId 直接查询检验项目定义
LabActivityDefinition labActivityDefinition = labActivityDefinitionService.getById(activityId);
if (labActivityDefinition != null && DelFlag.NO.getCode().equals(labActivityDefinition.getDeleteFlag())) {
// 补充编码(如果前端未传或为空)
if (inspectionLabApplyItem.getItemCode() == null || inspectionLabApplyItem.getItemCode().isEmpty()) {
inspectionLabApplyItem.setItemCode(labActivityDefinition.getBusNo());
}
// 补充套餐ID如果前端未传
if (inspectionLabApplyItem.getFeePackageId() == null) {
inspectionLabApplyItem.setFeePackageId(labActivityDefinition.getFeePackageId());
}
}
} else {
// 没有 activityId 时记录警告,不使用名称反查
log.warn("检验项目 [{}] 未传入 activityId无法获取完整关联信息",
doctorStationLabApplyItemDto.getItemName());
}
// 后端重新计算金额:金额 = 单价 × 数量
java.math.BigDecimal itemPrice = doctorStationLabApplyItemDto.getItemPrice();
java.math.BigDecimal itemQty = doctorStationLabApplyItemDto.getItemQty();
@@ -241,13 +272,16 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
);
if (organization != null) {
positionId = organization.getId();
} else {
// Bug #329: 执行科室代码无法匹配到科室,记录警告日志
log.warn("执行科室代码 [{}] 在科室表中未找到对应记录", performDeptCode);
}
} else {
// Bug #329: 未指定执行科室,记录警告日志
log.warn("检验项目 [{}] 未指定执行科室", itemName);
}
// 如果没有指定执行科室,使用当前医生所在的科室作为默认执行科室
if (positionId == null) {
positionId = SecurityUtils.getDeptId();
}
// Bug #329: 移除默认执行科室逻辑,必须由前端明确指定执行科室
// 4. 创建医嘱保存对象
AdviceSaveDto adviceSaveDto = new AdviceSaveDto();
@@ -324,7 +358,6 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
throw new RuntimeException("套餐项目 '" + itemName + "' 未设置有效价格,请先配置套餐金额");
}
unitPrice = packageInfo.getPackageAmount();
log.info("套餐项目 '{}' 使用套餐价格: {}", itemName, unitPrice);
} else {
// 普通项目:使用前端传入的价格
unitPrice = labApplyItemDto.getItemPrice();
@@ -367,30 +400,84 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
*/
@Override
public Object getInspectionApplyByApplyNo(String applyNo) {
// 查询主表数据
DoctorStationLabApplyDto applyDto = (DoctorStationLabApplyDto) doctorStationLabApplyMapper.getInspectionApplyByApplyNo(applyNo);
if (applyDto == null) {
// 使用MyBatis-Plus查询主表数据
InspectionLabApply mainEntity = inspectionLabApplyService.getOne(
new QueryWrapper<InspectionLabApply>()
.eq("apply_no", applyNo)
.eq("delete_flag", DelFlag.NO.getCode())
);
if (mainEntity == null) {
return null;
}
// 使用BeanUtils进行基础字段映射
DoctorStationLabApplyDto applyDto = new DoctorStationLabApplyDto();
BeanUtils.copyProperties(mainEntity, applyDto);
// 由于字段名称映射关系(如 id -> applicationId需要单独设置
applyDto.setApplicationId(mainEntity.getId());
// 查询检验项目明细
List<InspectionLabApplyItem> itemList = inspectionLabApplyItemService.list(
new QueryWrapper<InspectionLabApplyItem>()
.eq("apply_no", applyNo)
.eq("delete_flag", "0")
.eq("delete_flag", DelFlag.NO.getCode())
.orderByAsc("item_seq")
);
// 转换为 DTO 列表
List<DoctorStationLabApplyItemDto> itemDtoList = new ArrayList<>();
if (itemList != null && !itemList.isEmpty()) {
// 提取所有不同的 itemCode用于批量查询
Set<String> itemCodes = itemList.stream()
.filter(item -> item.getItemCode() != null && !item.getItemCode().isEmpty())
.map(InspectionLabApplyItem::getItemCode)
.collect(Collectors.toSet());
// 批量查询所有关联的检验项目定义使用MyBatis-Plus
Map<String, LabActivityDefinition> definitionMap = new HashMap<>();
if (!itemCodes.isEmpty()) {
List<LabActivityDefinition> labActivityDefinitions = labActivityDefinitionService.list(
new QueryWrapper<LabActivityDefinition>()
.in("bus_no", itemCodes)
.eq("delete_flag", DelFlag.NO.getCode())
);
// 构建 itemCode 到定义的映射
definitionMap = labActivityDefinitions.stream()
.collect(Collectors.toMap(LabActivityDefinition::getBusNo, Function.identity()));
}
// 处理每个明细项
for (InspectionLabApplyItem item : itemList) {
DoctorStationLabApplyItemDto itemDto = new DoctorStationLabApplyItemDto();
// 使用BeanUtils进行基础字段映射
BeanUtils.copyProperties(item, itemDto);
// feePackageId 在保存时已存储,直接使用
itemDto.setFeePackageId(item.getFeePackageId());
// 判断是否是套餐项目(根据 feePackageId 是否存在)
itemDto.setIsPackage(item.getFeePackageId() != null);
// 从批量查询结果中获取关联信息
if (item.getItemCode() != null && !item.getItemCode().isEmpty()) {
LabActivityDefinition labActivityDefinition = definitionMap.get(item.getItemCode());
if (labActivityDefinition != null) {
itemDto.setActivityId(labActivityDefinition.getId());
itemDto.setSampleType(labActivityDefinition.getSpecimenCode());
itemDto.setUnit(labActivityDefinition.getPermittedUnitCode());
// 补充检验类型ID用于前端自动设置执行科室
itemDto.setInspectionTypeId(labActivityDefinition.getInspectionTypeId());
}
} else {
log.warn("检验项目 [{}] 未存储 itemCode无法获取完整关联信息", item.getItemName());
}
itemDtoList.add(itemDto);
}
// 从第一个明细项获取执行科室代码
applyDto.setExecuteDepartment(itemList.get(0).getPerformDeptCode());
if (!itemList.isEmpty() && itemList.get(0).getPerformDeptCode() != null) {
applyDto.setExecuteDepartment(itemList.get(0).getPerformDeptCode());
}
}
applyDto.setLabApplyItemList(itemDtoList);
@@ -409,8 +496,9 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
// 使用 PageHelper 进行分页查询
PageHelper.startPage(pageNo, pageSize);
// 查询检验申请单列表
log.debug("查询申请单数据前");
// 使用MyBatis-Plus查询检验申请单列表
// 需要关联adm_encounter表仍使用原Mapper方法或重构为MyBatis-Plus方式
// 为保持一致性和考虑到复杂的关联查询,暂时保留原有实现方式
List<DoctorStationLabApplyDto> list = doctorStationLabApplyMapper.getInspectionApplyListPage(encounterId);
log.debug("查询申请单数据后");

View File

@@ -1,5 +1,7 @@
package com.openhis.web.doctorstation.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -67,4 +69,42 @@ public class DoctorStationLabApplyItemDto {
*/
@NotNull(message = "行状态不能为空")
private Long itemStatus;
// ========== Bug #326: 套餐相关字段(回充时需要) ==========
/**
* 活动定义ID检验项目定义ID
* 用于回充时关联到原始检验项目定义
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long activityId;
/**
* 套餐ID如果该项目是套餐则关联套餐表
* 对应 InspectionPackage.basicInformationId
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long feePackageId;
/**
* 是否是套餐项目
*/
private Boolean isPackage;
/**
* 样本类型
*/
private String sampleType;
/**
* 单位
*/
private String unit;
/**
* 检验类型ID关联 inspection_type 大类)
* 用于前端自动设置执行科室
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long inspectionTypeId;
}

View File

@@ -4,41 +4,6 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.openhis.web.doctorstation.mapper.DoctorStationLabApplyMapper">
<!-- 根据申请单号查询检验申请单(返回完整字段) -->
<select id="getInspectionApplyByApplyNo" resultType="com.openhis.web.doctorstation.dto.DoctorStationLabApplyDto">
SELECT
id AS applicationId,
apply_no AS applyNo,
patient_id AS patientId,
patient_name AS patientName,
medicalrecord_number AS medicalrecordNumber,
natureof_cost AS natureofCost,
visit_no AS visitNo,
apply_dept_code AS applyDeptCode,
apply_department AS applyDepartment,
apply_doc_code AS applyDocCode,
apply_doc_name AS applyDocName,
apply_time AS applyTime,
clinic_diag AS clinicDiag,
clinic_desc AS clinicDesc,
contraindication AS contraindication,
medical_history_summary AS medicalHistorySummary,
purposeof_inspection AS purposeofInspection,
physical_examination AS physicalExamination,
inspection_item AS inspectionItem,
specimen_type_code AS specimenTypeCode,
specimen_name AS specimenName,
priority_code AS priorityCode,
apply_status AS applyStatus,
apply_remark AS applyRemark,
create_time AS createTime,
operator_id AS operatorId,
create_by AS createBy,
tenant_id AS tenantId
FROM lab_apply
WHERE apply_no = #{applyNo}
AND delete_flag = '0'
</select>
<!-- 分页查询检验申请单列表根据就诊ID查询按申请时间降序
从明细表聚合项目名称和金额-->