Compare commits

...

4 Commits

Author SHA1 Message Date
赵云
288f2133ca Fix Bug #470: 住院医生工作站-手术申请单加载手术项目耗时过长,影响医生开单效率
根因:getAdviceBaseInfo 后端接口在查询手术项目时,仍会执行与手术无关的库存查询
(getAdviceInventory)、全表扫描待发放记录(getAdviceDraftInventory)以及药房科室
配置查询(getMedLocationConfig),其中 getAdviceDraftInventory 对
med_medication_dispense 和 wor_device_dispense 做全表扫描,无任何过滤条件,
导致手术/诊疗场景下的额外数据库开销。

修复:在 DoctorStationAdviceAppServiceImpl.getAdviceBaseInfo() 中增加类型判断,
当 adviceTypes 不包含药品(1)或耗材(2)时跳过所有库存相关查询,因为这些查询对手术/
诊疗(3,6)项目无意义,且下游代码仅在药品/耗材处理分支中使用这些变量。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 17:22:13 +08:00
赵云
d60eedf6a8 Fix Bug #400: 门诊医生站点击【完诊】后,triage_queue_item 表 status 字段未按规范更新为 30
完诊API后端要求同时传递 encounterId 和 firstEnum 两个参数:
1. DoctorCallDialog.vue:已有修复只传了 encounterId,缺少 firstEnum,导致后端校验失败
2. patientList.vue:仍传递原始值而非对象,且同样缺少 firstEnum

修复:两处调用均改为传递 { encounterId, firstEnum } 对象,firstEnum 默认值为1

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 17:05:17 +08:00
赵云
15daf26f6d Fix Bug #400: 门诊医生站点击【完诊】后,triage_queue_item 表 status 字段未按规范更新为 30
队列弹窗【完成】按钮调用完诊API时,传递了原始 Long 值而非对象参数,
导致后端 @RequestBody 反序列化时 encounterId 为 null,队列项状态无法更新。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 13:05:59 +08:00
赵云
b05dcab1e3 Fix Bug #492: 【门诊手术安排】关闭"手术计费"主弹窗后,项目字典选择列表依然残留悬浮在界面上
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 12:31:06 +08:00
4 changed files with 46 additions and 24 deletions

View File

@@ -231,21 +231,37 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
// 费用定价主表ID集合 // 费用定价主表ID集合
List<Long> chargeItemDefinitionIdList = adviceBaseDtoList.stream().map(AdviceBaseDto::getChargeItemDefinitionId) List<Long> chargeItemDefinitionIdList = adviceBaseDtoList.stream().map(AdviceBaseDto::getChargeItemDefinitionId)
.collect(Collectors.toList()); .collect(Collectors.toList());
// 医嘱库存集合
List<AdviceInventoryDto> adviceInventoryList = doctorStationAdviceAppMapper.getAdviceInventory(locationId, // 判断是否包含药品或耗材类型(只有这些类型才需要库存相关查询)
boolean hasMedOrDevice = adviceTypes != null
&& (adviceTypes.contains(1) || adviceTypes.contains(2));
// 医嘱库存集合 — 仅药品/耗材需要库存查询,手术/诊疗(3,6)无库存概念,跳过以减少数据库开销
List<AdviceInventoryDto> adviceInventoryList;
List<AdviceInventoryDto> adviceDraftInventoryList;
List<AdviceInventoryDto> adviceInventory;
if (hasMedOrDevice) {
adviceInventoryList = doctorStationAdviceAppMapper.getAdviceInventory(locationId,
adviceDefinitionIdList, adviceDefinitionIdList,
CommonConstants.SqlCondition.ABOUT_INVENTORY_TABLE_STR, PublicationStatus.ACTIVE.getValue()); CommonConstants.SqlCondition.ABOUT_INVENTORY_TABLE_STR, PublicationStatus.ACTIVE.getValue());
// 待发放个数信息 // 待发放个数信息
List<AdviceInventoryDto> adviceDraftInventoryList = doctorStationAdviceAppMapper.getAdviceDraftInventory( adviceDraftInventoryList = doctorStationAdviceAppMapper.getAdviceDraftInventory(
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION, CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
DispenseStatus.DRAFT.getValue(), DispenseStatus.PREPARATION.getValue()); DispenseStatus.DRAFT.getValue(), DispenseStatus.PREPARATION.getValue());
// 预减库存 // 预减库存
List<AdviceInventoryDto> adviceInventory = adviceUtils.subtractInventory(adviceInventoryList, adviceInventory = adviceUtils.subtractInventory(adviceInventoryList, adviceDraftInventoryList);
adviceDraftInventoryList); } else {
// 查询取药科室配置 adviceInventoryList = Collections.emptyList();
List<AdviceInventoryDto> medLocationConfig = doctorStationAdviceAppMapper.getMedLocationConfig(organizationId); adviceDraftInventoryList = Collections.emptyList();
adviceInventory = Collections.emptyList();
}
// 查询取药科室配置 — 仅药品开单场景需要
List<AdviceInventoryDto> medLocationConfig;
Map<String, Set<Long>> allowedLocByCategory;
if (hasMedOrDevice) {
medLocationConfig = doctorStationAdviceAppMapper.getMedLocationConfig(organizationId);
// 将配置转为 {categoryCode -> 允许的locationId集合} // 将配置转为 {categoryCode -> 允许的locationId集合}
Map<String, Set<Long>> allowedLocByCategory = new HashMap<>(); allowedLocByCategory = new HashMap<>();
if (medLocationConfig != null && !medLocationConfig.isEmpty()) { if (medLocationConfig != null && !medLocationConfig.isEmpty()) {
for (AdviceInventoryDto cfg : medLocationConfig) { for (AdviceInventoryDto cfg : medLocationConfig) {
if (cfg.getCategoryCode() == null || cfg.getLocationId() == null) { if (cfg.getCategoryCode() == null || cfg.getLocationId() == null) {
@@ -255,6 +271,10 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
.add(cfg.getLocationId()); .add(cfg.getLocationId());
} }
} }
} else {
medLocationConfig = Collections.emptyList();
allowedLocByCategory = Collections.emptyMap();
}
// 费用定价子表信息 - 使用分批处理避免大量参数问题 // 费用定价子表信息 - 使用分批处理避免大量参数问题
List<AdvicePriceDto> childCharge = new ArrayList<>(); List<AdvicePriceDto> childCharge = new ArrayList<>();
if (chargeItemDefinitionIdList != null && !chargeItemDefinitionIdList.isEmpty()) { if (chargeItemDefinitionIdList != null && !chargeItemDefinitionIdList.isEmpty()) {

View File

@@ -375,7 +375,7 @@ const finishCallPatient = async () => {
return; return;
} }
try { try {
await completeEncounter(currentCallPatient.value.encounterId); await completeEncounter({ encounterId: currentCallPatient.value.encounterId, firstEnum: currentCallPatient.value.firstEnum || 1 });
emit('finish'); emit('finish');
emit('update:dialogVisible', false); emit('update:dialogVisible', false);
ElMessage.success('患者已完诊'); ElMessage.success('患者已完诊');

View File

@@ -109,6 +109,7 @@ const props = defineProps({
}); });
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const encounterId = ref(); const encounterId = ref();
const firstEnum = ref(1); // 初复诊标识1=初诊2=复诊
onMounted(() => { onMounted(() => {
getPatientList(); getPatientList();
}); });
@@ -127,6 +128,7 @@ function getPatientList() {
function clickRow(row) { function clickRow(row) {
encounterId.value = row.encounterId; encounterId.value = row.encounterId;
firstEnum.value = row.firstEnum ?? row.first_enum ?? 1;
emits('cellClick', row); emits('cellClick', row);
} }
@@ -182,7 +184,7 @@ function handleComplete() {
} }
proxy.$modal.confirm('是否完成该患者问诊?').then(() => { proxy.$modal.confirm('是否完成该患者问诊?').then(() => {
proxy.$modal.loading(); proxy.$modal.loading();
completeEncounter(encounterId.value).then(() => { completeEncounter({ encounterId: encounterId.value, firstEnum: firstEnum.value }).then(() => {
proxy.$modal.closeLoading(); proxy.$modal.closeLoading();
proxy.$modal.msgSuccess('完成问诊成功'); proxy.$modal.msgSuccess('完成问诊成功');
getPatientList(); getPatientList();

View File

@@ -829,7 +829,7 @@
</el-descriptions> </el-descriptions>
</div> </div>
<div style="padding: 10px"> <div style="padding: 10px">
<prescriptionlist :patientInfo="chargePatientInfo" ref="prescriptionRef" /> <prescriptionlist v-if="showChargeDialog" :patientInfo="chargePatientInfo" ref="prescriptionRef" />
<div class="overlay" v-if="disabled"></div> <div class="overlay" v-if="disabled"></div>
</div> </div>
</div> </div>