diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/check/controller/ExamApplyController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/check/controller/ExamApplyController.java index 93e95050..4e857d57 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/check/controller/ExamApplyController.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/check/controller/ExamApplyController.java @@ -64,10 +64,29 @@ public class ExamApplyController extends BaseController { * 查询检查申请单列表 */ @GetMapping("/list") - public TableDataInfo list(ExamApply examApply) { + public TableDataInfo list(ExamApply examApply, @RequestParam(value = "encounterId", required = false) Long encounterId) { startPage(); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - if (examApply.getVisitNo() != null) { + + // 优先按本次就诊 encounterId 过滤(通过 wor_service_request 关联) + if (encounterId != null) { + List reqList = serviceRequestService.list(new LambdaQueryWrapper() + .eq(ServiceRequest::getEncounterId, encounterId) + .eq(ServiceRequest::getBasedOnTable, "exam_apply") + .isNotNull(ServiceRequest::getBasedOnId) + ); + List basedOnIds = reqList.stream() + .map(ServiceRequest::getBasedOnId) + .filter(java.util.Objects::nonNull) + .distinct() + .toList(); + // 没有本次就诊的检查申请单时,直接返回空列表 + if (basedOnIds.isEmpty()) { + return getDataTable(java.util.Collections.emptyList()); + } + wrapper.in(ExamApply::getId, basedOnIds); + } else if (examApply.getVisitNo() != null) { + // 兼容旧逻辑:按 visitNo 查询(可能包含历史记录) wrapper.eq(ExamApply::getVisitNo, examApply.getVisitNo()); } wrapper.orderByDesc(ExamApply::getApplyTime); @@ -147,6 +166,8 @@ public class ExamApplyController extends BaseController { examApply.setOperatorId("system"); } examApplyService.save(examApply); + // 业务主键为 apply_no,自增 id 不会随 save 回填;列表接口依赖 wor_service_request.based_on_id=exam_apply.id 关联本次就诊,此处必须回读 id + examApply = examApplyService.getById(applyNo); // ========== 2. 批量保存明细 + 写入门诊医嘱 + 写入费用项 ========== if (dto.getItems() != null && !dto.getItems().isEmpty()) { diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java index 5641fc03..f2769e23 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java @@ -612,13 +612,14 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp || e.getAdviceType() == 4) // 前端耗材类型值为4 .collect(Collectors.toList()); - // 诊疗活动(前端adviceType=3诊疗、adviceType=5会诊、adviceType=6手术、adviceType=23检查 → 都属于诊疗后端分类) + // 诊疗活动(前端adviceType=3诊疗、adviceType=5会诊、adviceType=6手术、adviceType=23检查、adviceType=26护理 → 都属于诊疗后端分类) List activityList = adviceSaveList.stream() .filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType()) || e.getAdviceType() == 3 // 前端诊疗类型值为3 || e.getAdviceType() == 5 // 前端会诊类型值为5 || e.getAdviceType() == 6 // 前端手术类型值为6 || e.getAdviceType() == 23 // 前端检查类型值为23 + || e.getAdviceType() == 26 // 前端护理类型值为26 || ItemType.SURGERY.getValue().equals(e.getAdviceType())) // 后端手术类型值为6 .collect(Collectors.toList()); diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationMainAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationMainAppServiceImpl.java index 75a1010d..353d75a3 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationMainAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationMainAppServiceImpl.java @@ -147,12 +147,19 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer return R.fail("已接诊,请勿重复点击,已为您刷新"); } + // 允许从「待诊/暂离/诊毕」重新接诊(用于队列弹窗的完诊患者重新进入在诊) + Date now = new Date(); int update = encounterMapper.update(null, new LambdaUpdateWrapper().eq(Encounter::getId, encounterId) - .eq(Encounter::getStatusEnum, EncounterStatus.PLANNED.getValue()) // 只更新待诊状态的患者 - .set(Encounter::getReceptionTime, new Date()) + .in(Encounter::getStatusEnum, + EncounterStatus.PLANNED.getValue(), + EncounterStatus.ON_HOLD.getValue(), + EncounterStatus.DISCHARGED.getValue()) + .set(Encounter::getReceptionTime, now) + .set(Encounter::getEndTime, null) .set(Encounter::getStatusEnum, EncounterStatus.IN_PROGRESS.getValue()) - .set(Encounter::getSubjectStatusEnum, EncounterSubjectStatus.RECEIVING_CARE.getValue())); + .set(Encounter::getSubjectStatusEnum, EncounterSubjectStatus.RECEIVING_CARE.getValue()) + .set(Encounter::getUpdateTime, now)); // 如果更新失败,说明状态已被其他医生修改 if (update <= 0) { diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java index 3d0663df..4ef22abb 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java @@ -180,9 +180,11 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService { // 药品 List medicineList = regAdviceSaveList.stream() .filter(e -> ItemType.MEDICINE.getValue().equals(e.getAdviceType())).collect(Collectors.toList()); - // 诊疗活动 + // 诊疗活动(包含护理adviceType=26) List activityList = regAdviceSaveList.stream() - .filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType())).collect(Collectors.toList()); + .filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType()) + || (e.getAdviceType() != null && e.getAdviceType() == 26)) + .collect(Collectors.toList()); // 耗材 🔧 Bug #147 修复 List deviceList = regAdviceSaveList.stream() .filter(e -> ItemType.DEVICE.getValue().equals(e.getAdviceType())).collect(Collectors.toList()); @@ -844,9 +846,11 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService { .filter(e -> ItemType.MEDICINE.getValue().equals(e.getAdviceType())).collect(Collectors.toList()); List medicineRequestIds = medicineList.stream().map(AdviceBatchOpParam::getRequestId).collect(Collectors.toList()); - // 诊疗 + // 诊疗(包含护理adviceType=26) List activityList = paramList.stream() - .filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType())).collect(Collectors.toList()); + .filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType()) + || (e.getAdviceType() != null && e.getAdviceType() == 26)) + .collect(Collectors.toList()); List activityRequestIds = activityList.stream().map(AdviceBatchOpParam::getRequestId).collect(Collectors.toList()); // 查询已完成的药品请求 @@ -902,9 +906,11 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService { .filter(e -> ItemType.MEDICINE.getValue().equals(e.getAdviceType())).collect(Collectors.toList()); List medicineRequestIds = medicineList.stream().map(AdviceBatchOpParam::getRequestId).collect(Collectors.toList()); - // 诊疗 + // 诊疗(包含护理adviceType=26) List activityList = paramList.stream() - .filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType())).collect(Collectors.toList()); + .filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType()) + || (e.getAdviceType() != null && e.getAdviceType() == 26)) + .collect(Collectors.toList()); List activityRequestIds = activityList.stream().map(AdviceBatchOpParam::getRequestId).collect(Collectors.toList()); if (!medicineRequestIds.isEmpty()) { diff --git a/openhis-ui-vue3/src/views/doctorstation/components/examination/examinationApplication.vue b/openhis-ui-vue3/src/views/doctorstation/components/examination/examinationApplication.vue index aba3cc35..80df2adf 100644 --- a/openhis-ui-vue3/src/views/doctorstation/components/examination/examinationApplication.vue +++ b/openhis-ui-vue3/src/views/doctorstation/components/examination/examinationApplication.vue @@ -116,7 +116,29 @@ - + + + + @@ -383,6 +405,11 @@ const activeNames = ref([]); // 当前展开的折叠项 const allMethods = ref([]); +// ====== 科室下拉(来源:科室管理)====== +const orgLoading = ref(false); +const orgOptions = ref([]); // { label, value } +const orgFilteredOptions = ref([]); // 展示用(截断前200条) + // 加载所有检查方法 async function loadAllMethods() { try { @@ -408,10 +435,61 @@ async function loadAllMethods() { } onMounted(async () => { + await loadOrgOptions(); await loadAllMethods(); await loadCategoryList(); }); +async function loadOrgOptions() { + orgLoading.value = true; + try { + const res = await request({ + url: '/base-data-manage/organization/organization', + method: 'get', + }); + const records = res?.data?.records || res?.data || []; + + const flat = []; + const walk = (nodes) => { + if (!Array.isArray(nodes)) return; + for (const n of nodes) { + if (!n) continue; + // 约定:typeEnum=2 为科室;若没有 typeEnum 也兜底收集 + if (n.name && (n.typeEnum === 2 || n.typeEnum === '2' || n.typeEnum == null)) { + flat.push({ label: n.name, value: n.name }); + } + if (Array.isArray(n.children) && n.children.length > 0) walk(n.children); + } + }; + walk(records); + + // 去重 + 排序 + const uniq = Array.from(new Map(flat.map(o => [o.value, o])).values()) + .filter(o => o?.value) + .sort((a, b) => (a.label || '').localeCompare(b.label || '', 'zh-CN')); + + orgOptions.value = uniq; + orgFilteredOptions.value = uniq.slice(0, 200); + } catch (e) { + console.error('加载科室列表失败', e); + orgOptions.value = []; + orgFilteredOptions.value = []; + } finally { + orgLoading.value = false; + } +} + +function handleOrgRemoteSearch(keyword) { + const key = (keyword || '').trim().toLowerCase(); + if (!key) { + orgFilteredOptions.value = orgOptions.value.slice(0, 200); + return; + } + orgFilteredOptions.value = orgOptions.value + .filter((o) => (o.label || '').toLowerCase().includes(key)) + .slice(0, 200); +} + // 动态可用的检查方法(根据已选部位所属的检查类型进行过滤) const normalizeTypeValue = value => String(value ?? '').trim().toLowerCase(); @@ -497,6 +575,8 @@ async function loadCategoryList() { orgType: t.type, // 保存 type 用于后备匹配 typeName: t.name, // 保存 name categoryName: t.name, + // “检查类型管理”里配置的执行科室(图三) + performDeptName: t.department || '', items: [] }); } @@ -591,7 +671,8 @@ function getList() { request({ url: '/exam/apply/list', method: 'get', - params: { visitNo: props.patientInfo?.visitNo || '' } + // 默认只展示本次就诊(encounterId)产生的检查申请单 + params: { encounterId: props.patientInfo?.encounterId || '' } }).then(res => { applicationList.value = res.rows || res.data || []; }).catch(err => console.error('获取申请单列表失败', err)) @@ -705,6 +786,12 @@ function handleItemSelect(checked, item, cat) { nationalCode: item.nationalCode || '', checked: true }); + + // 自动回填执行科室:按检查项目类型 → 检查类型管理里配置的执行科室 + // 仅在未手动选择时自动填充,避免覆盖用户输入 + if (!form.performDeptCode && cat?.performDeptName) { + form.performDeptCode = cat.performDeptName; + } } else { const idx = selectedItems.value.findIndex(s => s.id === item.id); if (idx > -1) selectedItems.value.splice(idx, 1); diff --git a/openhis-ui-vue3/src/views/doctorstation/components/prescription/prescriptionlist.vue b/openhis-ui-vue3/src/views/doctorstation/components/prescription/prescriptionlist.vue index ba2a5f14..f8463ac5 100644 --- a/openhis-ui-vue3/src/views/doctorstation/components/prescription/prescriptionlist.vue +++ b/openhis-ui-vue3/src/views/doctorstation/components/prescription/prescriptionlist.vue @@ -2272,7 +2272,26 @@ function handleNumberClick(item, index, row) { // 选择执行科室处理 function handleOrgChange(value, index, row) { + // 这里的“执行科室”在后端通常以 organizationId / positionId 参与业务校验; + // 列表展示用的是 positionName,因此需要同步写入名称,避免“选了但显示空”的问题。 + row.orgId = value; row.positionId = value; + row.positionName = findOrgNameById(value) || row.positionName || ''; +} + +function findOrgNameById(id) { + if (!id) return ''; + const targetId = String(id); + const stack = Array.isArray(organization.value) ? [...organization.value] : []; + while (stack.length > 0) { + const node = stack.shift(); + if (!node) continue; + if (String(node.id) === targetId) return node.name || ''; + if (Array.isArray(node.children) && node.children.length > 0) { + stack.unshift(...node.children); + } + } + return ''; } /** diff --git a/openhis-ui-vue3/src/views/inHospitalManagement/charge/register/components/accomplishList.vue b/openhis-ui-vue3/src/views/inHospitalManagement/charge/register/components/accomplishList.vue index 0247e2c7..b6e087e1 100644 --- a/openhis-ui-vue3/src/views/inHospitalManagement/charge/register/components/accomplishList.vue +++ b/openhis-ui-vue3/src/views/inHospitalManagement/charge/register/components/accomplishList.vue @@ -67,7 +67,7 @@ { - if (newVal && newVal.length > 0 && !submitForm.medTypeCode) { - submitForm.medTypeCode = newVal[0].value; - } - }, - { immediate: true } -); - const emits = defineEmits([]); const props = defineProps({ patientInfo: { @@ -351,6 +340,17 @@ const submitForm = reactive({ ambDiagnosisName: props.inHospitalInfo.ambDiagnosisName, medTypeCode: '', // 从字典动态获取默认值 }); + +// 监听诊断类别字典加载,默认选择第一项 +watch( + med_type, + (newVal) => { + if (newVal && newVal.length > 0 && !submitForm.medTypeCode) { + submitForm.medTypeCode = newVal[0].value; + } + }, + { immediate: true } +); // /* 科室 病区 */ // watch( // () => submitForm.inDocterWorkGroupCode, diff --git a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/index.vue b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/index.vue index 8ba5f1fb..b0d09dd7 100644 --- a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/index.vue +++ b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/index.vue @@ -833,7 +833,16 @@ function handleSave() { isAdding.value = false; expandOrder.value = []; } - let saveList = prescriptionList.value.filter((item) => { + + const selectedRows = prescriptionRef.value ? prescriptionRef.value.getSelectionRows() : []; + let sourceList = []; + if (selectedRows.length > 0) { + sourceList = selectedRows; + } else { + sourceList = prescriptionList.value; + } + + let saveList = sourceList.filter((item) => { return item.statusEnum == 1; }); @@ -907,7 +916,7 @@ function handleSave() { }) .then((res) => { if (res.code === 200) { - proxy.$modal.msgSuccess('保存成功'); + proxy.$modal.msgSuccess('签发成功'); isSaving.value = false; getListInfo(false); bindMethod.value = {};