From a1ed8eafb3058d40369af65a3cc6dc1e023cecb1 Mon Sep 17 00:00:00 2001 From: Ranyunqiao <2499115710@qq.com> Date: Wed, 13 May 2026 12:59:03 +0800 Subject: [PATCH] bug 362 428 436 --- .../IDoctorStationAdviceAppService.java | 10 ++ .../DoctorStationAdviceAppServiceImpl.java | 16 +++- .../DoctorStationAdviceController.java | 9 +- .../mapper/DoctorStationAdviceAppMapper.java | 3 +- .../RequestFormManageController.java | 27 ++++++ .../DoctorStationAdviceAppMapper.xml | 6 ++ openhis-ui-vue3/src/api/system/checkType.js | 2 +- .../clinicmanagement/bargain/component/api.js | 13 ++- .../bargain/component/prescriptionlist.vue | 14 ++- .../examination/examinationApplication.vue | 95 ++++++++++++++++++- .../home/components/applicationShow/api.js | 11 +++ .../inOut/components/transferInDialog.vue | 4 + .../src/views/surgicalschedule/index.vue | 22 +++-- 13 files changed, 207 insertions(+), 25 deletions(-) diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java index 9a1201ddd..88468e21d 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java @@ -59,6 +59,16 @@ public interface IDoctorStationAdviceAppService { */ R getRequestBaseInfo(Long encounterId); + /** + * 查询医嘱请求数据(支持按生成来源和来源单据号过滤) + * + * @param encounterId 就诊id + * @param generateSourceEnum 生成来源(可选,如手术计费=6) + * @param sourceBillNo 来源业务单据号(可选) + * @return 医嘱请求数据 + */ + R getRequestBaseInfo(Long encounterId, Integer generateSourceEnum, String sourceBillNo); + /** * 门诊签退医嘱 * 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 ab864629b..b43cc4d7a 100755 --- 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 @@ -1987,13 +1987,25 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp */ @Override public R getRequestBaseInfo(Long encounterId) { + return this.getRequestBaseInfo(encounterId, null, null); + } + + @Override + public R getRequestBaseInfo(Long encounterId, Integer generateSourceEnum, String sourceBillNo) { // 当前账号的参与者id Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId(); + // 未指定generateSourceEnum时,默认只查询医生开立的医嘱 + int sourceEnum = (generateSourceEnum != null) ? generateSourceEnum : GenerateSource.DOCTOR_PRESCRIPTION.getValue(); // 医嘱请求数据 List requestBaseInfo = doctorStationAdviceAppMapper.getRequestBaseInfo(encounterId, null, CommonConstants.TableName.MED_MEDICATION_REQUEST, CommonConstants.TableName.WOR_DEVICE_REQUEST, CommonConstants.TableName.WOR_SERVICE_REQUEST, practitionerId, Whether.NO.getCode(), - GenerateSource.DOCTOR_PRESCRIPTION.getValue()); + sourceEnum, sourceBillNo); + // 手术计费场景:sourceBillNo 不为空时,只保留诊疗请求(3/6),过滤掉药品(1)和耗材(2) + if (sourceBillNo != null && !sourceBillNo.isEmpty()) { + requestBaseInfo.removeIf(dto -> dto.getAdviceType() != null + && (dto.getAdviceType() == 1 || dto.getAdviceType() == 2)); + } for (RequestBaseDto requestBaseDto : requestBaseInfo) { // 请求状态 requestBaseDto @@ -2114,7 +2126,7 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp List requestBaseInfo = doctorStationAdviceAppMapper.getRequestBaseInfo(encounterId, patientId, CommonConstants.TableName.MED_MEDICATION_REQUEST, CommonConstants.TableName.WOR_DEVICE_REQUEST, CommonConstants.TableName.WOR_SERVICE_REQUEST, practitionerId, Whether.YES.getCode(), - GenerateSource.DOCTOR_PRESCRIPTION.getValue()); + GenerateSource.DOCTOR_PRESCRIPTION.getValue(), null); for (RequestBaseDto requestBaseDto : requestBaseInfo) { // 请求状态 requestBaseDto diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/controller/DoctorStationAdviceController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/controller/DoctorStationAdviceController.java index 6aa58de61..3f1a49f3a 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/controller/DoctorStationAdviceController.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/controller/DoctorStationAdviceController.java @@ -112,11 +112,16 @@ public class DoctorStationAdviceController { * 查询医嘱请求数据 * * @param encounterId 就诊id + * @param generateSourceEnum 生成来源(可选,用于按来源过滤,如手术计费=6) + * @param sourceBillNo 来源业务单据号(可选,用于按来源单据过滤) * @return 医嘱请求数据 */ @GetMapping(value = "/request-base-info") - public R getRequestBaseInfo(@RequestParam(required = false) Long encounterId) { - return iDoctorStationAdviceAppService.getRequestBaseInfo(encounterId); + public R getRequestBaseInfo( + @RequestParam(required = false) Long encounterId, + @RequestParam(required = false) Integer generateSourceEnum, + @RequestParam(required = false) String sourceBillNo) { + return iDoctorStationAdviceAppService.getRequestBaseInfo(encounterId, generateSourceEnum, sourceBillNo); } /** diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/mapper/DoctorStationAdviceAppMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/mapper/DoctorStationAdviceAppMapper.java index ddb365b2a..489d98d04 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/mapper/DoctorStationAdviceAppMapper.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/mapper/DoctorStationAdviceAppMapper.java @@ -122,7 +122,8 @@ public interface DoctorStationAdviceAppMapper { @Param("MED_MEDICATION_REQUEST") String MED_MEDICATION_REQUEST, @Param("WOR_DEVICE_REQUEST") String WOR_DEVICE_REQUEST, @Param("WOR_SERVICE_REQUEST") String WOR_SERVICE_REQUEST, @Param("practitionerId") Long practitionerId, - @Param("historyFlag") String historyFlag, @Param("generateSourceEnum") Integer generateSourceEnum); + @Param("historyFlag") String historyFlag, @Param("generateSourceEnum") Integer generateSourceEnum, + @Param("sourceBillNo") String sourceBillNo); /** * 查询就诊费用性质 diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/controller/RequestFormManageController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/controller/RequestFormManageController.java index 5af14f35c..2d45baa9b 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/controller/RequestFormManageController.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/controller/RequestFormManageController.java @@ -16,6 +16,7 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; +import java.time.LocalDate; import java.util.List; /** @@ -142,6 +143,32 @@ public class RequestFormManageController { return R.ok(iRequestFormManageAppService.getRequestForm(encounterId, ActivityDefCategory.PROCEDURE.getCode())); } /** + * 分页查询手术申请单(全局,不需要encounterId,用于门诊手术安排查找弹窗) + * + * @param surgeryNo 手术单号(模糊查询,可选) + * @param applyTimeStart 申请时间起始(可选) + * @param applyTimeEnd 申请时间截止(可选) + * @param mainDoctorId 主刀医生ID(可选) + * @param applyDeptId 申请科室ID(可选) + * @param pageNo 页码,默认1 + * @param pageSize 每页数量,默认10 + * @return 分页手术申请单列表 + */ + @GetMapping(value = "/get-surgery-page") + public R> getSurgeryRequestFormPage( + @RequestParam(required = false) String surgeryNo, + @RequestParam(required = false) LocalDate applyTimeStart, + @RequestParam(required = false) LocalDate applyTimeEnd, + @RequestParam(required = false) Long mainDoctorId, + @RequestParam(required = false) Long applyDeptId, + @RequestParam(defaultValue = "1") Integer pageNo, + @RequestParam(defaultValue = "10") Integer pageSize) { + RequestFormDto dto = new RequestFormDto(surgeryNo, null, applyTimeStart, applyTimeEnd, + mainDoctorId, applyDeptId, pageNo, pageSize); + return R.ok(iRequestFormManageAppService.getRequestFormPage(dto)); + } + + /** * 分页查询申请单 * @return 申请单 */ diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/doctorstation/DoctorStationAdviceAppMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/doctorstation/DoctorStationAdviceAppMapper.xml index feea0f6f6..75df58148 100755 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/doctorstation/DoctorStationAdviceAppMapper.xml +++ b/openhis-server-new/openhis-application/src/main/resources/mapper/doctorstation/DoctorStationAdviceAppMapper.xml @@ -527,6 +527,9 @@ LEFT JOIN cli_condition AS cc ON cc.id = T1.condition_id AND cc.delete_flag = '0' LEFT JOIN cli_condition_definition AS ccd ON ccd.id = cc.definition_id WHERE T1.delete_flag = '0' AND T1.tcm_flag = 0 + + AND T1.generate_source_enum = #{generateSourceEnum} + AND T1.encounter_id = #{encounterId} @@ -695,6 +698,9 @@ -- based_on_table='med_medication_request' → 输液/皮试执行记录,应排除 -- based_on_table='exam_apply'/'lab_apply' → 申请单原始医嘱,应保留 AND (T1.based_on_id IS NULL OR T1.based_on_table IS NULL OR T1.based_on_table NOT IN ('med_medication_request', 'med_medication_dispense')) + + AND T1.prescription_no = #{sourceBillNo} + AND T1.encounter_id = #{encounterId} diff --git a/openhis-ui-vue3/src/api/system/checkType.js b/openhis-ui-vue3/src/api/system/checkType.js index eba269e66..b2694df90 100755 --- a/openhis-ui-vue3/src/api/system/checkType.js +++ b/openhis-ui-vue3/src/api/system/checkType.js @@ -163,7 +163,7 @@ export function updateCheckPart(data) { // 查询检查套餐列表 export function listCheckPackage(query) { return request({ - url: '/system/check-package/list', + url: '/system/package/list', method: 'get', params: query }) diff --git a/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/api.js b/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/api.js index 7a2ac8415..0dbf88de0 100755 --- a/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/api.js +++ b/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/api.js @@ -58,10 +58,17 @@ export function singOut(data) { /** * 获取患者本次就诊处方 */ -export function getPrescriptionList(encounterId) { - // Add timestamp to bypass browser caching and ensure fresh data is loaded +export function getPrescriptionList(encounterId, generateSourceEnum, sourceBillNo) { + let url = '/doctor-station/advice/request-base-info?encounterId=' + encounterId + if (generateSourceEnum != null) { + url += '&generateSourceEnum=' + generateSourceEnum + } + if (sourceBillNo != null) { + url += '&sourceBillNo=' + encodeURIComponent(sourceBillNo) + } + url += '&t=' + Date.now() return request({ - url: '/doctor-station/advice/request-base-info?encounterId=' + encounterId + '&t=' + Date.now(), + url: url, method: 'get', }) } diff --git a/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue b/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue index 40a32dbff..480d9795c 100755 --- a/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue +++ b/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue @@ -381,6 +381,14 @@ const props = defineProps({ activeTab: { type: String, }, + generateSourceEnum: { + type: Number, + default: null, + }, + sourceBillNo: { + type: String, + default: null, + }, }); const isAdding = ref(false); const isSaving = ref(false); // #437 防重复提交锁 @@ -468,7 +476,11 @@ watch( function getListInfo(addNewRow) { isAdding.value = false; - getPrescriptionList(props.patientInfo.encounterId).then((res) => { + getPrescriptionList( + props.patientInfo.encounterId, + props.generateSourceEnum ?? undefined, + props.sourceBillNo ?? undefined, + ).then((res) => { // 为每行数据添加 adviceTypeValue 字段,用于类型下拉框显示 prescriptionList.value = (res.data || []).map(item => { // 根据 adviceType 和 categoryCode 找到对应的 adviceTypeValue 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 6d5d29422..2422c4930 100755 --- a/openhis-ui-vue3/src/views/doctorstation/components/examination/examinationApplication.vue +++ b/openhis-ui-vue3/src/views/doctorstation/components/examination/examinationApplication.vue @@ -402,6 +402,21 @@ ¥{{ method.packagePrice || item.price }} + +
+
+ 套餐明细 - {{ item.selectedMethod.name }} +
+
+ + {{ detail.name }} + 数量: {{ detail.quantity }} ¥{{ detail.price }} + +
+
+
+ 加载套餐明细中... +
@@ -419,7 +434,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'; import { Printer, Delete, ArrowDown, ArrowUp, Close } from '@element-plus/icons-vue'; import useUserStore from '@/store/modules/user'; import request from '@/utils/request'; -import { listCheckMethod, searchCheckMethod } from '@/api/system/checkType'; +import { listCheckMethod, searchCheckMethod, listCheckPackage } from '@/api/system/checkType'; import { getEncounterDiagnosis } from '../api.js'; const props = defineProps({ @@ -445,7 +460,7 @@ async function loadPackageDetails(row, treeNode, resolve) { } try { const res = await request({ - url: `/exam/package/${row.packageId}/details`, + url: `/system/package/${row.packageId}/details`, method: 'get' }); if (res.code === 200 && res.data) { @@ -474,7 +489,7 @@ async function loadPackageDetailsForItem(item) { } try { const res = await request({ - url: `/exam/package/${item.packageId}/details`, + url: `/system/package/${item.packageId}/details`, method: 'get' }); if (res.code === 200 && res.data) { @@ -1250,21 +1265,68 @@ async function toggleItemExpand(item) { } // Bug #384修复: 勾选框选择检查方法(单选逻辑) -function selectMethodCheckbox(checked, item, method) { +async function selectMethodCheckbox(checked, item, method) { if (checked) { item.selectedMethod = method; + // 动态加载该方法对应的套餐明细 + await loadMethodPackageDetails(item, method); } else { item.selectedMethod = null; + item.methodPackageDetails = []; } // 联动更新表单检查方法显示字段 updateMethodDisplay(); - + // #430: 套餐金额实时同步到申请单 nextTick(() => { form.totalAmount = totalAmountCalc.value; }); } +// 根据检查方法的packageName加载对应的套餐明细 +async function loadMethodPackageDetails(item, method) { + item.methodPackageLoading = true; + item.methodPackageDetails = []; + try { + if (!method.packageName) { + item.methodPackageLoading = false; + return; + } + // 通过packageName查询套餐获取packageId + const pkgRes = await listCheckPackage({ packageName: method.packageName }); + let packages = pkgRes?.data || []; + if (!Array.isArray(packages)) { + packages = packages.records || packages.data || []; + } + if (packages.length === 0) { + item.methodPackageLoading = false; + return; + } + const packageId = packages[0].id; + // 查询套餐明细 + const detailRes = await request({ + url: `/system/package/${packageId}/details`, + method: 'get' + }); + if (detailRes.code === 200 && detailRes.data) { + item.methodPackageDetails = detailRes.data.map(d => ({ + id: d.id, + name: d.itemName || d.name, + quantity: d.quantity || 1, + unit: d.unit || '次', + price: d.unitPrice || d.price || 0, + amount: d.amount || d.total || 0, + checked: true // 默认勾选 + })); + } + } catch (err) { + console.error('加载方法套餐明细失败:', err); + item.methodPackageDetails = []; + } finally { + item.methodPackageLoading = false; + } +} + // Bug #384修复: 更新检查方法显示字段(联动) function updateMethodDisplay() { // 找到第一个有选中检查方法的项目 @@ -1670,6 +1732,29 @@ defineExpose({ getList }); margin-left: 8px; } +/* 选中方法后显示的套餐明细 */ +.method-package-details { + margin-top: 4px; + padding: 4px 0; + border-top: 1px dashed #dcdfe6; +} + +.method-package-header { + padding: 2px 0 4px 24px; +} + +.method-package-title { + font-size: 10px; + color: #909399; + font-weight: 500; +} + +.method-package-loading { + padding: 4px 0 4px 24px; + font-size: 10px; + color: #c0c4cc; +} + /* 折叠组件细节 */ :deep(.el-collapse) { border: none; diff --git a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/applicationShow/api.js b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/applicationShow/api.js index 201813ae7..d3d5ee2bc 100755 --- a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/applicationShow/api.js +++ b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/applicationShow/api.js @@ -44,6 +44,17 @@ export function getSurgery(queryParams) { }); } +/** + * 分页查询手术申请单(全局,不需要encounterId,用于门诊手术安排查找弹窗) + */ +export function getSurgeryPage(queryParams) { + return request({ + url: '/reg-doctorstation/request-form/get-surgery-page', + method: 'get', + params: queryParams, + }); +} + /** * 查询护理医嘱信息 */ diff --git a/openhis-ui-vue3/src/views/inpatientNurse/inOut/components/transferInDialog.vue b/openhis-ui-vue3/src/views/inpatientNurse/inOut/components/transferInDialog.vue index c0a702760..4c1c51c32 100755 --- a/openhis-ui-vue3/src/views/inpatientNurse/inOut/components/transferInDialog.vue +++ b/openhis-ui-vue3/src/views/inpatientNurse/inOut/components/transferInDialog.vue @@ -453,6 +453,10 @@ const loadPatientInfo = () => { interventionForm.value.startTime = dayjs(res.data.startTime).format( 'YYYY-MM-DD HH:mm:ss' ); + } else if (res.data.inHosTime) { + interventionForm.value.startTime = dayjs(res.data.inHosTime).format( + 'YYYY-MM-DD HH:mm:ss' + ); } else { interventionForm.value.startTime = dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'); } diff --git a/openhis-ui-vue3/src/views/surgicalschedule/index.vue b/openhis-ui-vue3/src/views/surgicalschedule/index.vue index 68d214d1c..60177f99a 100755 --- a/openhis-ui-vue3/src/views/surgicalschedule/index.vue +++ b/openhis-ui-vue3/src/views/surgicalschedule/index.vue @@ -829,7 +829,9 @@
- +
@@ -877,12 +879,12 @@ import { addSurgerySchedule, updateSurgerySchedule, deleteSurgerySchedule, - getSurgeryScheduleDetail, - getSurgeryApplyList + getSurgeryScheduleDetail } from '@/api/surgicalschedule' import { listUser } from '@/api/system/user' import { deptTreeSelect } from '@/api/system/user' import { listOperatingRoom } from '@/api/operatingroom' +import { getSurgeryPage} from '@/views/inpatientDoctor/home/components/applicationShow/api.js' import { getTenantPage } from '@/api/system/tenant' import { getContract } from '@/views/inpatientDoctor/home/components/api.js' import SurgeryCharge from '../charge/surgerycharge/index.vue' @@ -1394,8 +1396,8 @@ async function handleChargeCharge(row) { orgId: userStore.organizationId || userStore.orgId || userStore.tenantId || 1, // 添加账户ID accountId: accountId, - // 添加手术申请单号用于追溯 - sourceBillNo: row.applyId, + // 添加手术单号用于关联对应的手术医嘱 + sourceBillNo: row.operCode, //添加计费标志手术计费 generateSourceEnum: 6 } @@ -1456,7 +1458,8 @@ function handleMedicalAdvice(row) { role: userStore.roles[0], effectiveOrgId : row.effectiveOrgId, orgId: userStore.orgId, - positionId: userStore.orgId + positionId: userStore.orgId, + applyId: row.applyId // 手术申请单ID,用于过滤关联医嘱 } // 🔧 关键修复:如果已有提交的医嘱数据,并且是同一个患者的就诊,则使用保存的数据 @@ -1754,7 +1757,7 @@ function handleQuoteBilling() { // 重新拉取计费药品数据 if (temporaryPatientInfo.value.visitId) { temporaryMedicalLoading.value = true // 🔧 新增:开始加载 - getPrescriptionList(temporaryPatientInfo.value.visitId).then((res) => { + getPrescriptionList(temporaryPatientInfo.value.visitId, 6, temporaryPatientInfo.value.operCode).then((res) => { if (res.code === 200 && res.data) { // 🔧 修复:先清空旧数据,避免数据累积 temporaryBillingMedicines.value = [] @@ -2029,7 +2032,7 @@ function handleFindApply() { getSurgicalScheduleList() } -// 获取手术申请列表(用于“查找”弹窗) +// 获取手术申请列表(用于”查找”弹窗) function getSurgicalScheduleList() { applyLoading.value = true const params = { ...applyQueryParams } @@ -2038,8 +2041,7 @@ function getSurgicalScheduleList() { params.applyTimeEnd = params.applyTimeRange[1] delete params.applyTimeRange } - getSurgeryApplyList(params).then((res) => { - // Check if data is nested under data.data or directly under data + getSurgeryPage(params).then((res) => { const responseData = res.data.data || res.data applyList.value = responseData.records || [] applyTotal.value = responseData.total || 0